summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2022-06-15 21:48:47 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2022-06-15 21:48:47 +0000
commit90114db4381aba9cc6684e35d5354a3441f032d4 (patch)
treefbb5c6be7affbddb9d2a99d5a2da06beae1b4574
parent101cb7e66d6f2d888cd9fa87d3c7ca77a4966c39 (diff)
parent8d446e7b865d66042a94ec8d5daf0970430ebc85 (diff)
downloadLauncher3-aml_tz3_314012010.tar.gz
Change-Id: I01a346e72948146d10ba6183a72b12c341da56b1
-rw-r--r--Android.bp93
-rw-r--r--Android.mk47
-rw-r--r--AndroidManifest-common.xml13
-rw-r--r--AndroidManifest.xml6
-rw-r--r--NOTICE190
-rw-r--r--OWNERS1
-rw-r--r--buglist_with_title.txt24
-rw-r--r--build.gradle9
-rw-r--r--ext_tests/src/com/android/launcher3/testing/DebugTestInformationHandler.java102
-rwxr-xr-xfill_screens.py90
-rw-r--r--go/AndroidManifest-launcher.xml2
-rw-r--r--go/AndroidManifest.xml4
-rw-r--r--go/quickstep/res/layout/overview_actions_container.xml18
-rw-r--r--go/quickstep/res/values-af/strings.xml20
-rw-r--r--go/quickstep/res/values-am/strings.xml20
-rw-r--r--go/quickstep/res/values-ar/strings.xml20
-rw-r--r--go/quickstep/res/values-as/strings.xml20
-rw-r--r--go/quickstep/res/values-az/strings.xml20
-rw-r--r--go/quickstep/res/values-b+sr+Latn/strings.xml20
-rw-r--r--go/quickstep/res/values-be/strings.xml20
-rw-r--r--go/quickstep/res/values-bg/strings.xml20
-rw-r--r--go/quickstep/res/values-bn/strings.xml20
-rw-r--r--go/quickstep/res/values-bs/strings.xml20
-rw-r--r--go/quickstep/res/values-ca/strings.xml20
-rw-r--r--go/quickstep/res/values-cs/strings.xml20
-rw-r--r--go/quickstep/res/values-da/strings.xml20
-rw-r--r--go/quickstep/res/values-de/strings.xml20
-rw-r--r--go/quickstep/res/values-el/strings.xml20
-rw-r--r--go/quickstep/res/values-en-rAU/strings.xml20
-rw-r--r--go/quickstep/res/values-en-rCA/strings.xml20
-rw-r--r--go/quickstep/res/values-en-rGB/strings.xml20
-rw-r--r--go/quickstep/res/values-en-rIN/strings.xml20
-rw-r--r--go/quickstep/res/values-en-rXC/strings.xml20
-rw-r--r--go/quickstep/res/values-es-rUS/strings.xml20
-rw-r--r--go/quickstep/res/values-es/strings.xml20
-rw-r--r--go/quickstep/res/values-et/strings.xml20
-rw-r--r--go/quickstep/res/values-eu/strings.xml20
-rw-r--r--go/quickstep/res/values-fa/strings.xml20
-rw-r--r--go/quickstep/res/values-fi/strings.xml20
-rw-r--r--go/quickstep/res/values-fr-rCA/strings.xml20
-rw-r--r--go/quickstep/res/values-fr/strings.xml20
-rw-r--r--go/quickstep/res/values-gl/strings.xml20
-rw-r--r--go/quickstep/res/values-gu/strings.xml20
-rw-r--r--go/quickstep/res/values-hi/strings.xml20
-rw-r--r--go/quickstep/res/values-hr/strings.xml20
-rw-r--r--go/quickstep/res/values-hu/strings.xml20
-rw-r--r--go/quickstep/res/values-hy/strings.xml20
-rw-r--r--go/quickstep/res/values-in/strings.xml20
-rw-r--r--go/quickstep/res/values-is/strings.xml20
-rw-r--r--go/quickstep/res/values-it/strings.xml20
-rw-r--r--go/quickstep/res/values-iw/strings.xml20
-rw-r--r--go/quickstep/res/values-ja/strings.xml20
-rw-r--r--go/quickstep/res/values-ka/strings.xml20
-rw-r--r--go/quickstep/res/values-kk/strings.xml20
-rw-r--r--go/quickstep/res/values-km/strings.xml20
-rw-r--r--go/quickstep/res/values-kn/strings.xml20
-rw-r--r--go/quickstep/res/values-ko/strings.xml20
-rw-r--r--go/quickstep/res/values-ky/strings.xml20
-rw-r--r--go/quickstep/res/values-lo/strings.xml20
-rw-r--r--go/quickstep/res/values-lt/strings.xml20
-rw-r--r--go/quickstep/res/values-lv/strings.xml20
-rw-r--r--go/quickstep/res/values-mk/strings.xml20
-rw-r--r--go/quickstep/res/values-ml/strings.xml20
-rw-r--r--go/quickstep/res/values-mn/strings.xml20
-rw-r--r--go/quickstep/res/values-mr/strings.xml20
-rw-r--r--go/quickstep/res/values-ms/strings.xml20
-rw-r--r--go/quickstep/res/values-my/strings.xml20
-rw-r--r--go/quickstep/res/values-nb/strings.xml20
-rw-r--r--go/quickstep/res/values-ne/strings.xml20
-rw-r--r--go/quickstep/res/values-nl/strings.xml20
-rw-r--r--go/quickstep/res/values-or/strings.xml20
-rw-r--r--go/quickstep/res/values-pa/strings.xml20
-rw-r--r--go/quickstep/res/values-pl/strings.xml20
-rw-r--r--go/quickstep/res/values-pt-rPT/strings.xml20
-rw-r--r--go/quickstep/res/values-pt/strings.xml20
-rw-r--r--go/quickstep/res/values-ro/strings.xml20
-rw-r--r--go/quickstep/res/values-ru/strings.xml20
-rw-r--r--go/quickstep/res/values-si/strings.xml20
-rw-r--r--go/quickstep/res/values-sk/strings.xml20
-rw-r--r--go/quickstep/res/values-sl/strings.xml20
-rw-r--r--go/quickstep/res/values-sq/strings.xml20
-rw-r--r--go/quickstep/res/values-sr/strings.xml20
-rw-r--r--go/quickstep/res/values-sv/strings.xml20
-rw-r--r--go/quickstep/res/values-sw/strings.xml20
-rw-r--r--go/quickstep/res/values-ta/strings.xml20
-rw-r--r--go/quickstep/res/values-te/strings.xml20
-rw-r--r--go/quickstep/res/values-th/strings.xml20
-rw-r--r--go/quickstep/res/values-tl/strings.xml20
-rw-r--r--go/quickstep/res/values-tr/strings.xml20
-rw-r--r--go/quickstep/res/values-uk/strings.xml20
-rw-r--r--go/quickstep/res/values-ur/strings.xml20
-rw-r--r--go/quickstep/res/values-uz/strings.xml20
-rw-r--r--go/quickstep/res/values-vi/strings.xml20
-rw-r--r--go/quickstep/res/values-zh-rCN/strings.xml20
-rw-r--r--go/quickstep/res/values-zh-rHK/strings.xml20
-rw-r--r--go/quickstep/res/values-zh-rTW/strings.xml20
-rw-r--r--go/quickstep/res/values-zu/strings.xml20
-rw-r--r--go/quickstep/res/values/integers.xml20
-rw-r--r--go/quickstep/res/values/strings.xml4
-rw-r--r--go/quickstep/res/values/styles.xml2
-rw-r--r--go/quickstep/src/com/android/launcher3/AppSharing.java124
-rw-r--r--go/quickstep/src/com/android/launcher3/model/AppShareabilityChecker.java38
-rw-r--r--go/quickstep/src/com/android/launcher3/model/AppShareabilityDatabase.java60
-rw-r--r--go/quickstep/src/com/android/launcher3/model/AppShareabilityJobService.java77
-rw-r--r--go/quickstep/src/com/android/launcher3/model/AppShareabilityManager.java211
-rw-r--r--go/quickstep/src/com/android/launcher3/model/AppShareabilityStatus.java39
-rw-r--r--go/quickstep/src/com/android/quickstep/TaskOverlayFactoryGo.java47
-rw-r--r--go/quickstep/src/com/android/quickstep/views/GoOverviewActionsView.java17
-rw-r--r--go/res/xml/device_profiles.xml2
-rw-r--r--go/src/com/android/launcher3/model/WidgetsModel.java7
-rw-r--r--go/src/com/android/launcher3/util/AbsGridOccupancy.java56
-rw-r--r--gradle.properties1
-rw-r--r--lint-baseline-launcher3.xml21
-rw-r--r--protos/launcher_atom.proto51
-rw-r--r--quickstep/Android.bp22
-rw-r--r--quickstep/AndroidManifest-launcher.xml5
-rw-r--r--quickstep/AndroidManifest.xml25
-rw-r--r--quickstep/ext_tests/src/com/android/quickstep/DebugQuickstepTestInformationHandler.java120
-rw-r--r--quickstep/protos_overrides/launcher_atom_extension.proto36
-rw-r--r--quickstep/res/drawable-v28/gesture_tutorial_action_button_background.xml2
-rw-r--r--quickstep/res/drawable/bg_overview_clear_all_button.xml27
-rw-r--r--quickstep/res/drawable/bg_sandbox_feedback.xml3
-rw-r--r--quickstep/res/drawable/button_taskbar_edu_bordered.xml32
-rw-r--r--quickstep/res/drawable/button_taskbar_edu_colored.xml29
-rw-r--r--quickstep/res/drawable/default_sandbox_app_previous_task_thumbnail.xml (renamed from res/xml/grayscale_icon_map.xml)10
-rw-r--r--quickstep/res/drawable/default_sandbox_mock_launcher.xml21
-rw-r--r--quickstep/res/drawable/gesture_tutorial_action_button_background.xml2
-rw-r--r--quickstep/res/drawable/gesture_tutorial_cancel_button_background.xml2
-rw-r--r--quickstep/res/drawable/gesture_tutorial_finger_dot.xml6
-rw-r--r--quickstep/res/drawable/gesture_tutorial_loop_back.xml2
-rw-r--r--quickstep/res/drawable/gesture_tutorial_loop_home.xml2
-rw-r--r--quickstep/res/drawable/gesture_tutorial_loop_overview.xml2
-rw-r--r--quickstep/res/drawable/gesture_tutorial_motion_back.xml1233
-rw-r--r--quickstep/res/drawable/gesture_tutorial_motion_home_dark_mode.xml1254
-rw-r--r--quickstep/res/drawable/gesture_tutorial_motion_home_light_mode.xml1254
-rw-r--r--quickstep/res/drawable/gesture_tutorial_motion_overview_dark_mode.xml1623
-rw-r--r--quickstep/res/drawable/ic_screenshot.xml23
-rw-r--r--quickstep/res/drawable/ic_sysbar_accessibility_button.xml26
-rw-r--r--quickstep/res/drawable/ic_sysbar_back_kids.xml9
-rw-r--r--quickstep/res/drawable/ic_sysbar_home_kids.xml9
-rw-r--r--quickstep/res/drawable/ic_sysbar_notifications.xml10
-rw-r--r--quickstep/res/drawable/ic_sysbar_quick_settings.xml13
-rw-r--r--quickstep/res/drawable/ic_sysbar_rotate_button_ccw_start_0.xml187
-rw-r--r--quickstep/res/drawable/ic_sysbar_rotate_button_ccw_start_90.xml187
-rw-r--r--quickstep/res/drawable/ic_sysbar_rotate_button_cw_start_0.xml187
-rw-r--r--quickstep/res/drawable/ic_sysbar_rotate_button_cw_start_90.xml187
-rw-r--r--quickstep/res/drawable/mock_conversation.xml212
-rw-r--r--quickstep/res/drawable/mock_conversations_list.xml361
-rw-r--r--quickstep/res/drawable/mock_webpage_dark_mode.xml251
-rw-r--r--quickstep/res/drawable/mock_webpage_light_mode.xml263
-rw-r--r--quickstep/res/drawable/task_menu_item_bg.xml7
-rw-r--r--quickstep/res/drawable/taskbar_edu_splitscreen.pngbin5640 -> 0 bytes
-rw-r--r--quickstep/res/drawable/taskbar_edu_stashing.pngbin5640 -> 0 bytes
-rw-r--r--quickstep/res/drawable/taskbar_edu_switch_apps.pngbin5640 -> 0 bytes
-rw-r--r--quickstep/res/drawable/taskbar_icon_click_feedback_roundrect.xml2
-rw-r--r--quickstep/res/interpolator/app_open_x.xml21
-rw-r--r--quickstep/res/interpolator/three_point_fast_out_extra_slow_in.xml21
-rw-r--r--quickstep/res/layout-land/gesture_tutorial_mock_hotseat.xml80
-rw-r--r--quickstep/res/layout-land/gesture_tutorial_tablet_mock_hotseat.xml123
-rw-r--r--quickstep/res/layout/activity_allset.xml159
-rw-r--r--quickstep/res/layout/fallback_recents_activity.xml3
-rw-r--r--quickstep/res/layout/gesture_tutorial_dialog.xml14
-rw-r--r--quickstep/res/layout/gesture_tutorial_foldable_mock_hotseat.xml122
-rw-r--r--quickstep/res/layout/gesture_tutorial_fragment.xml96
-rw-r--r--quickstep/res/layout/gesture_tutorial_mock_conversation.xml242
-rw-r--r--quickstep/res/layout/gesture_tutorial_mock_conversation_list.xml393
-rw-r--r--quickstep/res/layout/gesture_tutorial_mock_hotseat.xml76
-rw-r--r--quickstep/res/layout/gesture_tutorial_mock_webpage.xml277
-rw-r--r--quickstep/res/layout/gesture_tutorial_tablet_mock_conversation.xml239
-rw-r--r--quickstep/res/layout/gesture_tutorial_tablet_mock_conversation_list.xml396
-rw-r--r--quickstep/res/layout/gesture_tutorial_tablet_mock_hotseat.xml122
-rw-r--r--quickstep/res/layout/gesture_tutorial_tablet_mock_taskbar.xml118
-rw-r--r--quickstep/res/layout/gesture_tutorial_tablet_mock_webpage.xml275
-rw-r--r--quickstep/res/layout/overview_actions_container.xml23
-rw-r--r--quickstep/res/layout/overview_clear_all_button.xml2
-rw-r--r--quickstep/res/layout/overview_panel.xml7
-rw-r--r--quickstep/res/layout/predicted_hotseat_edu.xml2
-rw-r--r--quickstep/res/layout/rotate_suggestion.xml30
-rw-r--r--quickstep/res/layout/task_grouped.xml54
-rw-r--r--quickstep/res/layout/task_menu_with_arrow.xml33
-rw-r--r--quickstep/res/layout/task_view_menu_option.xml2
-rw-r--r--quickstep/res/layout/taskbar.xml62
-rw-r--r--quickstep/res/layout/taskbar_all_apps.xml66
-rw-r--r--quickstep/res/layout/taskbar_contextual_button.xml21
-rw-r--r--quickstep/res/layout/taskbar_edu.xml140
-rw-r--r--quickstep/res/values-af/strings.xml80
-rw-r--r--quickstep/res/values-am/strings.xml82
-rw-r--r--quickstep/res/values-ar/strings.xml84
-rw-r--r--quickstep/res/values-as/strings.xml90
-rw-r--r--quickstep/res/values-az/strings.xml82
-rw-r--r--quickstep/res/values-b+sr+Latn/strings.xml80
-rw-r--r--quickstep/res/values-be/strings.xml82
-rw-r--r--quickstep/res/values-bg/strings.xml82
-rw-r--r--quickstep/res/values-bn/strings.xml80
-rw-r--r--quickstep/res/values-bs/strings.xml82
-rw-r--r--quickstep/res/values-ca/strings.xml82
-rw-r--r--quickstep/res/values-cs/strings.xml86
-rw-r--r--quickstep/res/values-da/strings.xml82
-rw-r--r--quickstep/res/values-de/strings.xml86
-rw-r--r--quickstep/res/values-el/strings.xml82
-rw-r--r--quickstep/res/values-en-rAU/strings.xml80
-rw-r--r--quickstep/res/values-en-rCA/strings.xml109
-rw-r--r--quickstep/res/values-en-rGB/strings.xml80
-rw-r--r--quickstep/res/values-en-rIN/strings.xml80
-rw-r--r--quickstep/res/values-en-rXC/strings.xml109
-rw-r--r--quickstep/res/values-es-rUS/strings.xml82
-rw-r--r--quickstep/res/values-es/strings.xml84
-rw-r--r--quickstep/res/values-et/strings.xml82
-rw-r--r--quickstep/res/values-eu/strings.xml84
-rw-r--r--quickstep/res/values-fa/strings.xml82
-rw-r--r--quickstep/res/values-fi/strings.xml82
-rw-r--r--quickstep/res/values-fr-rCA/strings.xml82
-rw-r--r--quickstep/res/values-fr/strings.xml84
-rw-r--r--quickstep/res/values-gl/strings.xml84
-rw-r--r--quickstep/res/values-gu/strings.xml80
-rw-r--r--quickstep/res/values-hi/strings.xml82
-rw-r--r--quickstep/res/values-hr/strings.xml82
-rw-r--r--quickstep/res/values-hu/strings.xml84
-rw-r--r--quickstep/res/values-hy/strings.xml80
-rw-r--r--quickstep/res/values-in/strings.xml84
-rw-r--r--quickstep/res/values-is/strings.xml82
-rw-r--r--quickstep/res/values-it/strings.xml86
-rw-r--r--quickstep/res/values-iw/strings.xml82
-rw-r--r--quickstep/res/values-ja/strings.xml80
-rw-r--r--quickstep/res/values-ka/strings.xml82
-rw-r--r--quickstep/res/values-kk/strings.xml82
-rw-r--r--quickstep/res/values-km/strings.xml84
-rw-r--r--quickstep/res/values-kn/strings.xml82
-rw-r--r--quickstep/res/values-ko/strings.xml84
-rw-r--r--quickstep/res/values-ky/strings.xml82
-rw-r--r--quickstep/res/values-land/dimens.xml57
-rw-r--r--quickstep/res/values-lo/strings.xml82
-rw-r--r--quickstep/res/values-lt/strings.xml82
-rw-r--r--quickstep/res/values-lv/strings.xml82
-rw-r--r--quickstep/res/values-mk/strings.xml84
-rw-r--r--quickstep/res/values-ml/strings.xml80
-rw-r--r--quickstep/res/values-mn/strings.xml84
-rw-r--r--quickstep/res/values-mr/strings.xml80
-rw-r--r--quickstep/res/values-ms/strings.xml80
-rw-r--r--quickstep/res/values-my/strings.xml86
-rw-r--r--quickstep/res/values-nb/strings.xml82
-rw-r--r--quickstep/res/values-ne/strings.xml92
-rw-r--r--quickstep/res/values-night/colors.xml27
-rw-r--r--quickstep/res/values-night/styles.xml2
-rw-r--r--quickstep/res/values-nl/strings.xml80
-rw-r--r--quickstep/res/values-or/strings.xml82
-rw-r--r--quickstep/res/values-pa/strings.xml82
-rw-r--r--quickstep/res/values-pl/strings.xml82
-rw-r--r--quickstep/res/values-pt-rPT/strings.xml86
-rw-r--r--quickstep/res/values-pt/strings.xml80
-rw-r--r--quickstep/res/values-ro/strings.xml80
-rw-r--r--quickstep/res/values-ru/strings.xml82
-rw-r--r--quickstep/res/values-si/strings.xml82
-rw-r--r--quickstep/res/values-sk/strings.xml82
-rw-r--r--quickstep/res/values-sl/strings.xml82
-rw-r--r--quickstep/res/values-sq/strings.xml84
-rw-r--r--quickstep/res/values-sr/strings.xml80
-rw-r--r--quickstep/res/values-sv/strings.xml82
-rw-r--r--quickstep/res/values-sw/strings.xml80
-rw-r--r--quickstep/res/values-sw600dp-land/dimens.xml20
-rw-r--r--quickstep/res/values-sw600dp/dimens.xml29
-rw-r--r--quickstep/res/values-sw720dp-land/dimens.xml20
-rw-r--r--quickstep/res/values-sw720dp/dimens.xml27
-rw-r--r--quickstep/res/values-sw900dp/dimens.xml23
-rw-r--r--quickstep/res/values-ta/strings.xml80
-rw-r--r--quickstep/res/values-te/strings.xml82
-rw-r--r--quickstep/res/values-th/strings.xml82
-rw-r--r--quickstep/res/values-tl/strings.xml82
-rw-r--r--quickstep/res/values-tr/strings.xml84
-rw-r--r--quickstep/res/values-uk/strings.xml84
-rw-r--r--quickstep/res/values-ur/strings.xml82
-rw-r--r--quickstep/res/values-uz/strings.xml82
-rw-r--r--quickstep/res/values-vi/strings.xml82
-rw-r--r--quickstep/res/values-zh-rCN/strings.xml86
-rw-r--r--quickstep/res/values-zh-rHK/strings.xml82
-rw-r--r--quickstep/res/values-zh-rTW/strings.xml82
-rw-r--r--quickstep/res/values-zu/strings.xml82
-rw-r--r--quickstep/res/values/colors.xml58
-rw-r--r--quickstep/res/values/config.xml7
-rw-r--r--quickstep/res/values/dimens.xml157
-rw-r--r--quickstep/res/values/strings.xml66
-rw-r--r--quickstep/res/values/styles.xml55
-rw-r--r--quickstep/robolectric_tests/src/com/android/launcher3/model/WidgetsPredicationUpdateTaskTest.java (renamed from quickstep/tests/src/com/android/launcher3/model/WidgetsPredicationUpdateTaskTest.java)203
-rw-r--r--quickstep/robolectric_tests/src/com/android/quickstep/OrientationTouchTransformerTest.java (renamed from quickstep/tests/src/com/android/quickstep/OrientationTouchTransformerTest.java)76
-rw-r--r--quickstep/robolectric_tests/src/com/android/quickstep/RecentsActivityTest.java75
-rw-r--r--quickstep/robolectric_tests/src/com/android/quickstep/util/RecentsOrientedStateTest.java (renamed from quickstep/tests/src/com/android/quickstep/util/RecentsOrientedStateTest.java)15
-rw-r--r--quickstep/robolectric_tests/src/com/android/quickstep/util/TaskViewSimulatorTest.java (renamed from quickstep/tests/src/com/android/quickstep/util/TaskViewSimulatorTest.java)142
-rw-r--r--quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java312
-rw-r--r--quickstep/src/com/android/launcher3/LauncherAnimationRunner.java2
-rw-r--r--quickstep/src/com/android/launcher3/LauncherInitListener.java10
-rw-r--r--quickstep/src/com/android/launcher3/QuickstepAccessibilityDelegate.java2
-rw-r--r--quickstep/src/com/android/launcher3/QuickstepTransitionManager.java731
-rw-r--r--quickstep/src/com/android/launcher3/appprediction/AppsDividerView.java77
-rw-r--r--quickstep/src/com/android/launcher3/appprediction/InstantAppItemInfo.java5
-rw-r--r--quickstep/src/com/android/launcher3/appprediction/PredictionRowView.java68
-rw-r--r--quickstep/src/com/android/launcher3/hybridhotseat/HotseatEduActivity.java60
-rw-r--r--quickstep/src/com/android/launcher3/hybridhotseat/HotseatEduController.java68
-rw-r--r--quickstep/src/com/android/launcher3/hybridhotseat/HotseatEduDialog.java22
-rw-r--r--quickstep/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java76
-rw-r--r--quickstep/src/com/android/launcher3/hybridhotseat/HotseatPredictionModel.java74
-rw-r--r--quickstep/src/com/android/launcher3/model/AppEventProducer.java56
-rw-r--r--quickstep/src/com/android/launcher3/model/PredictionHelper.java130
-rw-r--r--quickstep/src/com/android/launcher3/model/PredictionUpdateTask.java18
-rw-r--r--quickstep/src/com/android/launcher3/model/QuickstepModelDelegate.java159
-rw-r--r--quickstep/src/com/android/launcher3/model/WellbeingModel.java13
-rw-r--r--quickstep/src/com/android/launcher3/model/WidgetsPredictionUpdateTask.java7
-rw-r--r--quickstep/src/com/android/launcher3/popup/QuickstepSystemShortcut.java93
-rw-r--r--quickstep/src/com/android/launcher3/proxy/StartActivityParams.java6
-rw-r--r--quickstep/src/com/android/launcher3/statehandlers/BackButtonAlphaHandler.java6
-rw-r--r--quickstep/src/com/android/launcher3/statehandlers/DepthController.java105
-rw-r--r--quickstep/src/com/android/launcher3/taskbar/BaseTaskbarContext.java61
-rw-r--r--quickstep/src/com/android/launcher3/taskbar/ButtonProvider.java80
-rw-r--r--quickstep/src/com/android/launcher3/taskbar/DesktopNavbarButtonsViewController.java65
-rw-r--r--quickstep/src/com/android/launcher3/taskbar/DesktopTaskbarUIController.java48
-rw-r--r--quickstep/src/com/android/launcher3/taskbar/FallbackTaskbarUIController.java88
-rw-r--r--quickstep/src/com/android/launcher3/taskbar/ImeBarView.java77
-rw-r--r--quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java458
-rw-r--r--quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java902
-rw-r--r--quickstep/src/com/android/launcher3/taskbar/RecentsHitboxExtender.java134
-rw-r--r--quickstep/src/com/android/launcher3/taskbar/StashedHandleView.java106
-rw-r--r--quickstep/src/com/android/launcher3/taskbar/StashedHandleViewController.java217
-rw-r--r--quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java746
-rw-r--r--quickstep/src/com/android/launcher3/taskbar/TaskbarAnimationController.java151
-rw-r--r--quickstep/src/com/android/launcher3/taskbar/TaskbarAutohideSuspendController.java85
-rw-r--r--quickstep/src/com/android/launcher3/taskbar/TaskbarBackgroundRenderer.kt75
-rw-r--r--quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java219
-rw-r--r--quickstep/src/com/android/launcher3/taskbar/TaskbarDragController.java513
-rw-r--r--quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayer.java89
-rw-r--r--quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayerController.java189
-rw-r--r--quickstep/src/com/android/launcher3/taskbar/TaskbarDragView.java56
-rw-r--r--quickstep/src/com/android/launcher3/taskbar/TaskbarEduController.java223
-rw-r--r--quickstep/src/com/android/launcher3/taskbar/TaskbarEduPagedView.java79
-rw-r--r--quickstep/src/com/android/launcher3/taskbar/TaskbarEduView.java159
-rw-r--r--quickstep/src/com/android/launcher3/taskbar/TaskbarForceVisibleImmersiveController.java160
-rw-r--r--quickstep/src/com/android/launcher3/taskbar/TaskbarHotseatController.java91
-rw-r--r--quickstep/src/com/android/launcher3/taskbar/TaskbarIconController.java163
-rw-r--r--quickstep/src/com/android/launcher3/taskbar/TaskbarInsetsController.kt163
-rw-r--r--quickstep/src/com/android/launcher3/taskbar/TaskbarKeyguardController.java121
-rw-r--r--quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java521
-rw-r--r--quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java321
-rw-r--r--quickstep/src/com/android/launcher3/taskbar/TaskbarModelCallbacks.java217
-rw-r--r--quickstep/src/com/android/launcher3/taskbar/TaskbarNavButtonController.java240
-rw-r--r--quickstep/src/com/android/launcher3/taskbar/TaskbarPopupController.java289
-rw-r--r--quickstep/src/com/android/launcher3/taskbar/TaskbarScrimView.java72
-rw-r--r--quickstep/src/com/android/launcher3/taskbar/TaskbarScrimViewController.java103
-rw-r--r--quickstep/src/com/android/launcher3/taskbar/TaskbarShortcutMenuAccessibilityDelegate.java115
-rw-r--r--quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java772
-rw-r--r--quickstep/src/com/android/launcher3/taskbar/TaskbarStateHandler.java75
-rw-r--r--quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java78
-rw-r--r--quickstep/src/com/android/launcher3/taskbar/TaskbarUnfoldAnimationController.java105
-rw-r--r--quickstep/src/com/android/launcher3/taskbar/TaskbarView.java473
-rw-r--r--quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java421
-rw-r--r--quickstep/src/com/android/launcher3/taskbar/Utilities.java33
-rw-r--r--quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsContainerView.java53
-rw-r--r--quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsContext.java249
-rw-r--r--quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsController.java257
-rw-r--r--quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsFallbackSearchContainer.java54
-rw-r--r--quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsSlideInView.java153
-rw-r--r--quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsViewController.java94
-rw-r--r--quickstep/src/com/android/launcher3/taskbar/unfold/NonDestroyableScopedUnfoldTransitionProgressProvider.java30
-rw-r--r--quickstep/src/com/android/launcher3/uioverrides/ApiWrapper.java25
-rw-r--r--quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java31
-rw-r--r--quickstep/src/com/android/launcher3/uioverrides/DeviceFlag.java46
-rw-r--r--quickstep/src/com/android/launcher3/uioverrides/PredictedAppIcon.java150
-rw-r--r--quickstep/src/com/android/launcher3/uioverrides/QuickstepInteractionHandler.java16
-rw-r--r--quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java55
-rw-r--r--quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java67
-rw-r--r--quickstep/src/com/android/launcher3/uioverrides/plugins/PluginInitializerImpl.java52
-rw-r--r--quickstep/src/com/android/launcher3/uioverrides/plugins/PluginManagerWrapper.java38
-rw-r--r--quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java59
-rw-r--r--quickstep/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java8
-rw-r--r--quickstep/src/com/android/launcher3/uioverrides/states/OverviewModalTaskState.java2
-rw-r--r--quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java50
-rw-r--r--quickstep/src/com/android/launcher3/uioverrides/states/QuickSwitchState.java17
-rw-r--r--quickstep/src/com/android/launcher3/uioverrides/states/QuickstepAtomicAnimationFactory.java40
-rw-r--r--quickstep/src/com/android/launcher3/uioverrides/states/SplitScreenSelectState.java16
-rw-r--r--quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java24
-rw-r--r--quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonNavbarToOverviewTouchController.java25
-rw-r--r--quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java55
-rw-r--r--quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/PortraitStatesTouchController.java108
-rw-r--r--quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/QuickSwitchTouchController.java9
-rw-r--r--quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/TaskViewTouchController.java59
-rw-r--r--quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java535
-rw-r--r--quickstep/src/com/android/quickstep/AnimatedFloat.java40
-rw-r--r--quickstep/src/com/android/quickstep/BaseActivityInterface.java223
-rw-r--r--quickstep/src/com/android/quickstep/FallbackActivityInterface.java47
-rw-r--r--quickstep/src/com/android/quickstep/FallbackSwipeHandler.java129
-rw-r--r--quickstep/src/com/android/quickstep/GestureState.java41
-rw-r--r--quickstep/src/com/android/quickstep/ImageActionsApi.java13
-rw-r--r--quickstep/src/com/android/quickstep/InputConsumer.java8
-rw-r--r--quickstep/src/com/android/quickstep/KtR.java41
-rw-r--r--quickstep/src/com/android/quickstep/LauncherActivityInterface.java40
-rw-r--r--quickstep/src/com/android/quickstep/LauncherBackAnimationController.java339
-rw-r--r--quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java197
-rw-r--r--quickstep/src/com/android/quickstep/OrientationRectF.java104
-rw-r--r--quickstep/src/com/android/quickstep/OrientationTouchTransformer.java190
-rw-r--r--quickstep/src/com/android/quickstep/OverscrollPluginFactory.java40
-rw-r--r--quickstep/src/com/android/quickstep/OverviewCommandHelper.java43
-rw-r--r--quickstep/src/com/android/quickstep/QuickstepProcessInitializer.java19
-rw-r--r--quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java54
-rw-r--r--quickstep/src/com/android/quickstep/RecentTasksList.java149
-rw-r--r--quickstep/src/com/android/quickstep/RecentsActivity.java81
-rw-r--r--quickstep/src/com/android/quickstep/RecentsAnimationCallbacks.java58
-rw-r--r--quickstep/src/com/android/quickstep/RecentsAnimationController.java40
-rw-r--r--quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java162
-rw-r--r--quickstep/src/com/android/quickstep/RecentsAnimationTargets.java6
-rw-r--r--quickstep/src/com/android/quickstep/RecentsModel.java34
-rw-r--r--quickstep/src/com/android/quickstep/RemoteAnimationTargets.java6
-rw-r--r--quickstep/src/com/android/quickstep/RemoteTargetGluer.java214
-rw-r--r--quickstep/src/com/android/quickstep/RotationTouchHelper.java118
-rw-r--r--quickstep/src/com/android/quickstep/SimpleOrientationTouchTransformer.java54
-rw-r--r--quickstep/src/com/android/quickstep/SwipeUpAnimationLogic.java185
-rw-r--r--quickstep/src/com/android/quickstep/SysUINavigationMode.java202
-rw-r--r--quickstep/src/com/android/quickstep/SystemUiProxy.java413
-rw-r--r--quickstep/src/com/android/quickstep/TaskAnimationManager.java113
-rw-r--r--quickstep/src/com/android/quickstep/TaskIconCache.java42
-rw-r--r--quickstep/src/com/android/quickstep/TaskOverlayFactory.java116
-rw-r--r--quickstep/src/com/android/quickstep/TaskShortcutFactory.java106
-rw-r--r--quickstep/src/com/android/quickstep/TaskThumbnailCache.java9
-rw-r--r--quickstep/src/com/android/quickstep/TaskViewUtils.java535
-rw-r--r--quickstep/src/com/android/quickstep/TopTaskTracker.java271
-rw-r--r--quickstep/src/com/android/quickstep/TouchInteractionService.java334
-rw-r--r--quickstep/src/com/android/quickstep/ViewUtils.java14
-rw-r--r--quickstep/src/com/android/quickstep/fallback/FallbackNavBarTouchController.java6
-rw-r--r--quickstep/src/com/android/quickstep/fallback/FallbackRecentsStateController.java46
-rw-r--r--quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java141
-rw-r--r--quickstep/src/com/android/quickstep/fallback/RecentsState.java23
-rw-r--r--quickstep/src/com/android/quickstep/inputconsumers/AssistantInputConsumer.java4
-rw-r--r--quickstep/src/com/android/quickstep/inputconsumers/DeviceLockedInputConsumer.java4
-rw-r--r--quickstep/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java28
-rw-r--r--quickstep/src/com/android/quickstep/inputconsumers/OverscrollInputConsumer.java287
-rw-r--r--quickstep/src/com/android/quickstep/inputconsumers/OverviewInputConsumer.java7
-rw-r--r--quickstep/src/com/android/quickstep/inputconsumers/ProgressDelegateInputConsumer.java194
-rw-r--r--quickstep/src/com/android/quickstep/inputconsumers/SysUiOverlayInputConsumer.java14
-rw-r--r--quickstep/src/com/android/quickstep/inputconsumers/TaskbarStashInputConsumer.java121
-rw-r--r--quickstep/src/com/android/quickstep/interaction/AllSetActivity.java265
-rw-r--r--quickstep/src/com/android/quickstep/interaction/AnimatedTaskView.java202
-rw-r--r--quickstep/src/com/android/quickstep/interaction/AnimatedTaskbarView.java368
-rw-r--r--quickstep/src/com/android/quickstep/interaction/AssistantGestureTutorialController.java1
-rw-r--r--quickstep/src/com/android/quickstep/interaction/AssistantGestureTutorialFragment.java16
-rw-r--r--quickstep/src/com/android/quickstep/interaction/BackGestureTutorialController.java69
-rw-r--r--quickstep/src/com/android/quickstep/interaction/BackGestureTutorialFragment.java87
-rw-r--r--quickstep/src/com/android/quickstep/interaction/EdgeBackGestureHandler.java8
-rw-r--r--quickstep/src/com/android/quickstep/interaction/EdgeBackGesturePanel.java6
-rw-r--r--quickstep/src/com/android/quickstep/interaction/GestureSandboxActivity.java75
-rw-r--r--quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialController.java39
-rw-r--r--quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialFragment.java82
-rw-r--r--quickstep/src/com/android/quickstep/interaction/NavBarGestureHandler.java23
-rw-r--r--quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialController.java70
-rw-r--r--quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialFragment.java94
-rw-r--r--quickstep/src/com/android/quickstep/interaction/RootSandboxLayout.java11
-rw-r--r--quickstep/src/com/android/quickstep/interaction/SandboxModeTutorialFragment.java15
-rw-r--r--quickstep/src/com/android/quickstep/interaction/SwipeUpGestureTutorialController.java144
-rw-r--r--quickstep/src/com/android/quickstep/interaction/TutorialController.java501
-rw-r--r--quickstep/src/com/android/quickstep/interaction/TutorialFragment.java260
-rw-r--r--quickstep/src/com/android/quickstep/interaction/TutorialStepIndicator.java10
-rw-r--r--quickstep/src/com/android/quickstep/logging/SettingsChangeLogger.java112
-rw-r--r--quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java248
-rw-r--r--quickstep/src/com/android/quickstep/util/ActivityInitListener.java18
-rw-r--r--quickstep/src/com/android/quickstep/util/AnimatorControllerWithResistance.java58
-rw-r--r--quickstep/src/com/android/quickstep/util/AssistantUtilities.java46
-rw-r--r--quickstep/src/com/android/quickstep/util/BaseUnfoldMoveFromCenterAnimator.java112
-rw-r--r--quickstep/src/com/android/quickstep/util/GroupTask.java56
-rw-r--r--quickstep/src/com/android/quickstep/util/ImageActionUtils.java20
-rw-r--r--quickstep/src/com/android/quickstep/util/InputConsumerProxy.java31
-rw-r--r--quickstep/src/com/android/quickstep/util/LauncherUnfoldAnimationController.java165
-rw-r--r--quickstep/src/com/android/quickstep/util/LauncherViewsMoveFromCenterTranslationApplier.java45
-rw-r--r--quickstep/src/com/android/quickstep/util/LayoutUtils.java8
-rw-r--r--quickstep/src/com/android/quickstep/util/MotionPauseDetector.java8
-rw-r--r--quickstep/src/com/android/quickstep/util/NavBarPosition.java10
-rw-r--r--quickstep/src/com/android/quickstep/util/OverviewToHomeAnim.java2
-rw-r--r--quickstep/src/com/android/quickstep/util/ProxyScreenStatusProvider.java51
-rw-r--r--quickstep/src/com/android/quickstep/util/QuickstepOnboardingPrefs.java30
-rw-r--r--quickstep/src/com/android/quickstep/util/RecentsAtomicAnimationFactory.java29
-rw-r--r--quickstep/src/com/android/quickstep/util/RecentsOrientedState.java59
-rw-r--r--quickstep/src/com/android/quickstep/util/RectFSpringAnim.java145
-rw-r--r--quickstep/src/com/android/quickstep/util/RectFSpringAnim2.java370
-rw-r--r--quickstep/src/com/android/quickstep/util/RemoteAnimationProvider.java18
-rw-r--r--quickstep/src/com/android/quickstep/util/SplitSelectStateController.java353
-rw-r--r--quickstep/src/com/android/quickstep/util/StaggeredWorkspaceAnim.java8
-rw-r--r--quickstep/src/com/android/quickstep/util/SurfaceTransactionApplier.java25
-rw-r--r--quickstep/src/com/android/quickstep/util/SwipePipToHomeAnimator.java65
-rw-r--r--quickstep/src/com/android/quickstep/util/SystemWindowManagerProxy.java53
-rw-r--r--quickstep/src/com/android/quickstep/util/TISBindHelper.java145
-rw-r--r--quickstep/src/com/android/quickstep/util/TaskKeyLruCache.java3
-rw-r--r--quickstep/src/com/android/quickstep/util/TaskViewSimulator.java136
-rw-r--r--quickstep/src/com/android/quickstep/util/TransformParams.java4
-rw-r--r--quickstep/src/com/android/quickstep/util/UnfoldMoveFromCenterHotseatAnimator.java55
-rw-r--r--quickstep/src/com/android/quickstep/util/UnfoldMoveFromCenterWorkspaceAnimator.java65
-rw-r--r--quickstep/src/com/android/quickstep/util/WorkspaceRevealAnim.java25
-rw-r--r--quickstep/src/com/android/quickstep/views/AllAppsEduView.java2
-rw-r--r--quickstep/src/com/android/quickstep/views/ClearAllButton.java40
-rw-r--r--quickstep/src/com/android/quickstep/views/DigitalWellBeingToast.java162
-rw-r--r--quickstep/src/com/android/quickstep/views/FloatingTaskThumbnailView.java80
-rw-r--r--quickstep/src/com/android/quickstep/views/FloatingTaskView.java308
-rw-r--r--quickstep/src/com/android/quickstep/views/FloatingWidgetBackgroundView.java10
-rw-r--r--quickstep/src/com/android/quickstep/views/FloatingWidgetView.java10
-rw-r--r--quickstep/src/com/android/quickstep/views/GroupedTaskView.java316
-rw-r--r--quickstep/src/com/android/quickstep/views/IconView.java42
-rw-r--r--quickstep/src/com/android/quickstep/views/LauncherRecentsView.java145
-rw-r--r--quickstep/src/com/android/quickstep/views/OverviewActionsView.java160
-rw-r--r--quickstep/src/com/android/quickstep/views/RecentsExtraViewContainer.java54
-rw-r--r--quickstep/src/com/android/quickstep/views/RecentsView.java2831
-rw-r--r--quickstep/src/com/android/quickstep/views/SplitPlaceholderView.java65
-rw-r--r--quickstep/src/com/android/quickstep/views/TaskMenuView.java97
-rw-r--r--quickstep/src/com/android/quickstep/views/TaskMenuViewWithArrow.kt344
-rw-r--r--quickstep/src/com/android/quickstep/views/TaskThumbnailView.java202
-rw-r--r--quickstep/src/com/android/quickstep/views/TaskView.java892
-rw-r--r--quickstep/tests/src/com/android/launcher3/taskbar/RecentsHitboxExtenderTest.java125
-rw-r--r--quickstep/tests/src/com/android/launcher3/taskbar/TaskbarNavButtonControllerTest.java224
-rw-r--r--quickstep/tests/src/com/android/quickstep/AbstractQuickStepTest.java10
-rw-r--r--quickstep/tests/src/com/android/quickstep/DigitalWellBeingToastTest.java7
-rw-r--r--quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java31
-rw-r--r--quickstep/tests/src/com/android/quickstep/NavigationBarRotationContextTest.java124
-rw-r--r--quickstep/tests/src/com/android/quickstep/NavigationModeSwitchRule.java57
-rw-r--r--quickstep/tests/src/com/android/quickstep/RecentTasksListTest.java60
-rw-r--r--quickstep/tests/src/com/android/quickstep/StartLauncherViaGestureTests.java34
-rw-r--r--quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java169
-rw-r--r--quickstep/tests/src/com/android/quickstep/TaplTestsTaskbar.java160
-rw-r--r--quickstep/tests/src/com/android/quickstep/ViewInflationDuringSwipeUp.java18
-rw-r--r--res/anim-v33/shared_x_axis_activity_close_enter.xml42
-rw-r--r--res/anim-v33/shared_x_axis_activity_close_exit.xml41
-rw-r--r--res/anim-v33/shared_x_axis_activity_open_enter.xml42
-rw-r--r--res/anim-v33/shared_x_axis_activity_open_exit.xml41
-rw-r--r--res/color-night-v31/accent_ripple_color.xml4
-rw-r--r--res/color-night-v31/all_apps_button_color_2.xml20
-rw-r--r--res/color-night-v31/folder_background_dark.xml4
-rw-r--r--res/color-night/accent_ripple_color.xml4
-rw-r--r--res/color-v31/accent_ripple_color.xml4
-rw-r--r--res/color-v31/all_apps_button_bg_color.xml20
-rw-r--r--res/color-v31/all_apps_button_color_1.xml20
-rw-r--r--res/color-v31/all_apps_button_color_2.xml20
-rw-r--r--res/color-v31/all_apps_button_color_3.xml20
-rw-r--r--res/color-v31/all_apps_button_color_4.xml20
-rw-r--r--res/color-v31/folder_background_light.xml2
-rw-r--r--res/color-v31/folder_preview_light.xml20
-rw-r--r--res/color-v31/home_settings_switch_thumb_color.xml27
-rw-r--r--res/color-v31/home_settings_switch_track_color.xml28
-rw-r--r--res/color-v31/overview_scrim.xml2
-rw-r--r--res/color-v31/overview_scrim_dark.xml2
-rw-r--r--res/color-v31/taskbar_background.xml18
-rw-r--r--res/color/accent_ripple_color.xml4
-rw-r--r--res/color/system_shortcut_text.xml19
-rw-r--r--res/drawable-v28/round_rect_folder.xml2
-rw-r--r--res/drawable-v28/widgets_bottom_sheet_background.xml (renamed from res/drawable/bg_widgets_full_sheet.xml)15
-rw-r--r--res/drawable-v31/bg_deferred_app_widget.xml23
-rw-r--r--res/drawable-v31/home_settings_switch_thumb.xml29
-rw-r--r--res/drawable-v31/home_settings_switch_track.xml26
-rw-r--r--res/drawable/all_apps_tabs_background.xml41
-rw-r--r--res/drawable/bg_rounded_corner_bottom_sheet.xml2
-rw-r--r--res/drawable/bg_widgets_picker_handle.xml (renamed from quickstep/res/layout/taskbar_nav_button.xml)23
-rw-r--r--res/drawable/drop_target_frame.xml2
-rw-r--r--res/drawable/gesture_tutorial_motion_overview_light_mode.xml1587
-rw-r--r--res/drawable/gesture_tutorial_ripple.xml (renamed from quickstep/res/drawable/gesture_tutorial_ripple.xml)0
-rw-r--r--res/drawable/gm_edit_24.xml2
-rw-r--r--res/drawable/ic_all_apps_button.xml44
-rw-r--r--res/drawable/ic_split_horizontal.xml9
-rw-r--r--res/drawable/ic_split_left.xml9
-rw-r--r--res/drawable/ic_split_right.xml9
-rw-r--r--res/drawable/ic_split_top.xml9
-rw-r--r--res/drawable/ic_split_vertical.xml9
-rw-r--r--res/drawable/padded_rounded_action_button.xml13
-rw-r--r--res/drawable/personal_work_tabs_ripple.xml (renamed from res/color-night-v31/folder_preview_dark.xml)12
-rw-r--r--res/drawable/round_rect_folder.xml2
-rw-r--r--res/drawable/rounded_action_button.xml5
-rw-r--r--res/drawable/widgets_bottom_sheet_background.xml (renamed from res/drawable/bg_rounded_corner_bottom_sheet_handle.xml)18
-rw-r--r--res/interpolator/back_cancel.xml24
-rw-r--r--res/interpolator/fast_out_extra_slow_in.xml19
-rw-r--r--res/interpolator/standard_accelerate.xml22
-rw-r--r--res/interpolator/standard_decelerate.xml22
-rw-r--r--res/layout-v31/settings_activity.xml69
-rw-r--r--res/layout/add_item_confirmation_activity.xml31
-rw-r--r--res/layout/all_apps.xml13
-rw-r--r--res/layout/all_apps_bottom_sheet_background.xml35
-rw-r--r--res/layout/all_apps_content_layout.xml (renamed from res/layout/search_results_rv_layout.xml)15
-rw-r--r--res/layout/all_apps_fast_scroller.xml6
-rw-r--r--res/layout/all_apps_icon_twoline.xml25
-rw-r--r--res/layout/all_apps_rv_layout.xml1
-rw-r--r--res/layout/all_apps_tabs.xml3
-rw-r--r--res/layout/arrow_toast.xml6
-rw-r--r--res/layout/floating_split_select_view.xml19
-rw-r--r--res/layout/keyboard_drag_and_drop.xml2
-rw-r--r--res/layout/launcher_preview_two_panel_layout.xml57
-rw-r--r--res/layout/notification_content.xml12
-rw-r--r--res/layout/popup_container.xml7
-rw-r--r--res/layout/qsb_preview.xml30
-rw-r--r--res/layout/secondary_launcher.xml13
-rw-r--r--res/layout/system_shortcut.xml29
-rw-r--r--res/layout/system_shortcut_content.xml48
-rw-r--r--res/layout/widget_cell_content.xml10
-rw-r--r--res/layout/widgets_bottom_sheet_content.xml13
-rw-r--r--res/layout/widgets_full_sheet.xml25
-rw-r--r--res/layout/widgets_full_sheet_paged_view.xml85
-rw-r--r--res/layout/widgets_full_sheet_recyclerview.xml57
-rw-r--r--res/layout/widgets_full_sheet_search_and_recommendations.xml61
-rw-r--r--res/layout/widgets_list_row_header.xml11
-rw-r--r--res/layout/widgets_personal_work_tabs.xml53
-rw-r--r--res/layout/widgets_search_bar.xml1
-rw-r--r--res/layout/widgets_table_container.xml3
-rw-r--r--res/layout/work_apps_edu.xml54
-rw-r--r--res/layout/work_apps_paused.xml2
-rw-r--r--res/layout/work_mode_fab.xml6
-rw-r--r--res/raw/all_set_page_bg.json1
-rw-r--r--res/raw/downgrade_schema.json4
-rw-r--r--res/values-af/strings.xml85
-rw-r--r--res/values-am/strings.xml84
-rw-r--r--res/values-ar/strings.xml99
-rw-r--r--res/values-as/strings.xml101
-rw-r--r--res/values-az/strings.xml88
-rw-r--r--res/values-b+sr+Latn/strings.xml108
-rw-r--r--res/values-be/strings.xml93
-rw-r--r--res/values-bg/strings.xml87
-rw-r--r--res/values-bn/strings.xml88
-rw-r--r--res/values-bs/strings.xml91
-rw-r--r--res/values-ca/strings.xml92
-rw-r--r--res/values-cs/strings.xml89
-rw-r--r--res/values-da/strings.xml93
-rw-r--r--res/values-de/strings.xml89
-rw-r--r--res/values-el/strings.xml86
-rw-r--r--res/values-en-rAU/strings.xml84
-rw-r--r--res/values-en-rCA/strings.xml170
-rw-r--r--res/values-en-rGB/strings.xml84
-rw-r--r--res/values-en-rIN/strings.xml84
-rw-r--r--res/values-en-rXC/strings.xml170
-rw-r--r--res/values-es-rUS/strings.xml89
-rw-r--r--res/values-es/strings.xml91
-rw-r--r--res/values-et/strings.xml87
-rw-r--r--res/values-eu/strings.xml90
-rw-r--r--res/values-fa/strings.xml89
-rw-r--r--res/values-fi/strings.xml93
-rw-r--r--res/values-fr-rCA/strings.xml89
-rw-r--r--res/values-fr/strings.xml88
-rw-r--r--res/values-gl/strings.xml94
-rw-r--r--res/values-gu/strings.xml116
-rw-r--r--res/values-hi/strings.xml92
-rw-r--r--res/values-hr/strings.xml89
-rw-r--r--res/values-hu/strings.xml89
-rw-r--r--res/values-hy/strings.xml96
-rw-r--r--res/values-in/strings.xml90
-rw-r--r--res/values-is/strings.xml87
-rw-r--r--res/values-it/strings.xml87
-rw-r--r--res/values-iw/strings.xml149
-rw-r--r--res/values-ja/strings.xml89
-rw-r--r--res/values-ka/strings.xml85
-rw-r--r--res/values-kk/strings.xml87
-rw-r--r--res/values-km/strings.xml88
-rw-r--r--res/values-kn/strings.xml84
-rw-r--r--res/values-ko/strings.xml85
-rw-r--r--res/values-ky/strings.xml100
-rw-r--r--res/values-land/dimens.xml14
-rw-r--r--res/values-lo/strings.xml89
-rw-r--r--res/values-lt/strings.xml87
-rw-r--r--res/values-lv/strings.xml86
-rw-r--r--res/values-mk/strings.xml90
-rw-r--r--res/values-ml/strings.xml89
-rw-r--r--res/values-mn/strings.xml93
-rw-r--r--res/values-mr/strings.xml97
-rw-r--r--res/values-ms/strings.xml85
-rw-r--r--res/values-my/strings.xml96
-rw-r--r--res/values-nb/strings.xml85
-rw-r--r--res/values-ne/strings.xml127
-rw-r--r--res/values-night-v31/colors.xml32
-rw-r--r--res/values-night/colors.xml25
-rw-r--r--res/values-nl/strings.xml101
-rw-r--r--res/values-or/strings.xml107
-rw-r--r--res/values-pa/strings.xml97
-rw-r--r--res/values-pl/strings.xml99
-rw-r--r--res/values-pt-rPT/strings.xml106
-rw-r--r--res/values-pt/strings.xml90
-rw-r--r--res/values-ro/strings.xml85
-rw-r--r--res/values-ru/strings.xml91
-rw-r--r--res/values-si/strings.xml85
-rw-r--r--res/values-sk/strings.xml88
-rw-r--r--res/values-sl/strings.xml93
-rw-r--r--res/values-sq/strings.xml92
-rw-r--r--res/values-sr/strings.xml108
-rw-r--r--res/values-sv/strings.xml85
-rw-r--r--res/values-sw/strings.xml90
-rw-r--r--res/values-sw600dp-land/dimens.xml35
-rw-r--r--res/values-sw600dp/config.xml21
-rw-r--r--res/values-sw600dp/dimens.xml35
-rw-r--r--res/values-sw720dp-land/dimens.xml40
-rw-r--r--res/values-sw720dp/dimens.xml46
-rw-r--r--res/values-ta/strings.xml108
-rw-r--r--res/values-te/strings.xml130
-rw-r--r--res/values-th/strings.xml88
-rw-r--r--res/values-tl/strings.xml85
-rw-r--r--res/values-tr/strings.xml89
-rw-r--r--res/values-uk/strings.xml87
-rw-r--r--res/values-ur/strings.xml85
-rw-r--r--res/values-uz/strings.xml95
-rw-r--r--res/values-v31/colors.xml14
-rw-r--r--res/values-v31/config.xml20
-rw-r--r--res/values-v31/styles.xml97
-rw-r--r--res/values-v33/style.xml40
-rw-r--r--res/values-vi/strings.xml95
-rw-r--r--res/values-zh-rCN/strings.xml89
-rw-r--r--res/values-zh-rHK/strings.xml89
-rw-r--r--res/values-zh-rTW/strings.xml101
-rw-r--r--res/values-zu/strings.xml86
-rw-r--r--res/values/attrs.xml227
-rw-r--r--res/values/colors.xml20
-rw-r--r--res/values/config.xml96
-rw-r--r--res/values/dimens.xml180
-rw-r--r--res/values/id.xml18
-rw-r--r--res/values/strings.xml98
-rw-r--r--res/values/styles.xml30
-rw-r--r--res/xml/backupscheme.xml5
-rw-r--r--res/xml/default_test_workspace.xml29
-rw-r--r--res/xml/default_workspace_5x5.xml1
-rw-r--r--res/xml/default_workspace_6x5.xml76
-rw-r--r--res/xml/device_profiles.xml78
-rw-r--r--res/xml/launcher_preferences.xml2
-rw-r--r--res/xml/paddings_6x5.xml76
-rw-r--r--res/xml/size_limits_80x104.xml114
-rw-r--r--res/xml/widget_sections.xml25
-rw-r--r--robolectric_tests/Android.bp63
-rw-r--r--robolectric_tests/res/values/overlayable_icons_test.xml36
-rw-r--r--robolectric_tests/resources/cache_data_updated_task_data.txt (renamed from tests/res/raw/cache_data_updated_task_data.txt)0
-rw-r--r--robolectric_tests/resources/db_schema_v10.json (renamed from tests/res/raw/db_schema_v10.json)0
-rw-r--r--robolectric_tests/resources/package_install_state_change_task_data.txt (renamed from tests/res/raw/package_install_state_change_task_data.txt)0
-rw-r--r--robolectric_tests/resources/robolectric.properties15
-rw-r--r--robolectric_tests/resources/widgets_predication_update_task_data.txt (renamed from tests/res/raw/widgets_predication_update_task_data.txt)0
-rw-r--r--robolectric_tests/src/com/android/launcher3/folder/FolderNameProviderTest.java (renamed from tests/src/com/android/launcher3/folder/FolderNameProviderTest.java)16
-rw-r--r--robolectric_tests/src/com/android/launcher3/logging/FileLogTest.java (renamed from tests/src/com/android/launcher3/logging/FileLogTest.java)15
-rw-r--r--robolectric_tests/src/com/android/launcher3/model/AddWorkspaceItemsTaskTest.java195
-rw-r--r--robolectric_tests/src/com/android/launcher3/model/BackupRestoreTest.java (renamed from tests/src/com/android/launcher3/model/BackupRestoreTest.java)111
-rw-r--r--robolectric_tests/src/com/android/launcher3/model/CacheDataUpdatedTaskTest.java (renamed from tests/src/com/android/launcher3/model/CacheDataUpdatedTaskTest.java)20
-rw-r--r--robolectric_tests/src/com/android/launcher3/model/DbDowngradeHelperTest.java (renamed from tests/src/com/android/launcher3/model/DbDowngradeHelperTest.java)20
-rw-r--r--robolectric_tests/src/com/android/launcher3/model/DefaultLayoutProviderTest.java (renamed from tests/src/com/android/launcher3/model/DefaultLayoutProviderTest.java)45
-rw-r--r--robolectric_tests/src/com/android/launcher3/model/GridBackupTableTest.java135
-rw-r--r--robolectric_tests/src/com/android/launcher3/model/GridSizeMigrationTaskTest.java373
-rw-r--r--robolectric_tests/src/com/android/launcher3/model/GridSizeMigrationTaskV2Test.java286
-rw-r--r--robolectric_tests/src/com/android/launcher3/model/LoaderCursorTest.java (renamed from tests/src/com/android/launcher3/model/LoaderCursorTest.java)32
-rw-r--r--robolectric_tests/src/com/android/launcher3/model/ModelMultiCallbacksTest.java (renamed from tests/src/com/android/launcher3/model/ModelMultiCallbacksTest.java)156
-rw-r--r--robolectric_tests/src/com/android/launcher3/model/PackageInstallStateChangedTaskTest.java (renamed from tests/src/com/android/launcher3/model/PackageInstallStateChangedTaskTest.java)20
-rw-r--r--robolectric_tests/src/com/android/launcher3/popup/PopupPopulatorTest.java (renamed from tests/src/com/android/launcher3/popup/PopupPopulatorTest.java)12
-rw-r--r--robolectric_tests/src/com/android/launcher3/provider/RestoreDbTaskTest.java (renamed from tests/src/com/android/launcher3/provider/RestoreDbTaskTest.java)62
-rw-r--r--robolectric_tests/src/com/android/launcher3/secondarydisplay/SDWorkModeTest.java125
-rw-r--r--robolectric_tests/src/com/android/launcher3/settings/SettingsActivityTest.java (renamed from tests/src/com/android/launcher3/settings/SettingsActivityTest.java)7
-rw-r--r--robolectric_tests/src/com/android/launcher3/shadows/LShadowAppPredictionManager.java38
-rw-r--r--robolectric_tests/src/com/android/launcher3/shadows/LShadowAppWidgetManager.java48
-rw-r--r--robolectric_tests/src/com/android/launcher3/shadows/LShadowBackupManager.java45
-rw-r--r--robolectric_tests/src/com/android/launcher3/shadows/LShadowDisplay.java54
-rw-r--r--robolectric_tests/src/com/android/launcher3/shadows/LShadowLauncherApps.java136
-rw-r--r--robolectric_tests/src/com/android/launcher3/shadows/ShadowDeviceFlag.java62
-rw-r--r--robolectric_tests/src/com/android/launcher3/shadows/ShadowLooperExecutor.java63
-rw-r--r--robolectric_tests/src/com/android/launcher3/shadows/ShadowMainThreadInitializedObject.java61
-rw-r--r--robolectric_tests/src/com/android/launcher3/shadows/ShadowOverrides.java61
-rw-r--r--robolectric_tests/src/com/android/launcher3/shadows/ShadowSurfaceTransactionApplier.java42
-rw-r--r--robolectric_tests/src/com/android/launcher3/testing/TestActivity.java46
-rw-r--r--robolectric_tests/src/com/android/launcher3/ui/LauncherUIScrollTest.java181
-rw-r--r--robolectric_tests/src/com/android/launcher3/util/GridOccupancyTest.java (renamed from tests/src/com/android/launcher3/util/GridOccupancyTest.java)7
-rw-r--r--robolectric_tests/src/com/android/launcher3/util/IntArrayTest.java (renamed from tests/src/com/android/launcher3/util/IntArrayTest.java)9
-rw-r--r--robolectric_tests/src/com/android/launcher3/util/IntSetTest.java (renamed from tests/src/com/android/launcher3/util/IntSetTest.java)9
-rw-r--r--robolectric_tests/src/com/android/launcher3/util/LauncherLayoutBuilder.java (renamed from tests/src/com/android/launcher3/util/LauncherLayoutBuilder.java)0
-rw-r--r--robolectric_tests/src/com/android/launcher3/util/LauncherModelHelper.java (renamed from tests/src/com/android/launcher3/util/LauncherModelHelper.java)293
-rw-r--r--robolectric_tests/src/com/android/launcher3/util/LauncherTestApplication.java50
-rw-r--r--robolectric_tests/src/com/android/launcher3/util/LauncherUIHelper.java101
-rw-r--r--robolectric_tests/src/com/android/launcher3/widget/CachingWidgetPreviewLoaderTest.java409
-rw-r--r--robolectric_tests/src/com/android/launcher3/widget/LauncherAppWidgetProviderInfoTest.java (renamed from tests/src/com/android/launcher3/widget/LauncherAppWidgetProviderInfoTest.java)21
-rw-r--r--robolectric_tests/src/com/android/launcher3/widget/picker/WidgetsDiffReporterTest.java (renamed from tests/src/com/android/launcher3/widget/picker/WidgetsDiffReporterTest.java)25
-rw-r--r--robolectric_tests/src/com/android/launcher3/widget/picker/WidgetsListAdapterTest.java (renamed from tests/src/com/android/launcher3/widget/picker/WidgetsListAdapterTest.java)81
-rw-r--r--robolectric_tests/src/com/android/launcher3/widget/picker/WidgetsListHeaderViewHolderBinderTest.java (renamed from tests/src/com/android/launcher3/widget/picker/WidgetsListHeaderViewHolderBinderTest.java)74
-rw-r--r--robolectric_tests/src/com/android/launcher3/widget/picker/WidgetsListSearchHeaderViewHolderBinderTest.java (renamed from tests/src/com/android/launcher3/widget/picker/WidgetsListSearchHeaderViewHolderBinderTest.java)73
-rw-r--r--robolectric_tests/src/com/android/launcher3/widget/picker/WidgetsListTableViewHolderBinderTest.java (renamed from tests/src/com/android/launcher3/widget/picker/WidgetsListTableViewHolderBinderTest.java)80
-rw-r--r--robolectric_tests/src/com/android/launcher3/widget/picker/model/WidgetsListContentEntryTest.java (renamed from tests/src/com/android/launcher3/widget/picker/model/WidgetsListContentEntryTest.java)34
-rw-r--r--robolectric_tests/src/com/android/launcher3/widget/picker/search/SimpleWidgetsSearchAlgorithmTest.java (renamed from tests/src/com/android/launcher3/widget/picker/search/SimpleWidgetsSearchAlgorithmTest.java)37
-rw-r--r--robolectric_tests/src/com/android/launcher3/widget/picker/search/WidgetsSearchBarControllerTest.java (renamed from tests/src/com/android/launcher3/widget/picker/search/WidgetsSearchBarControllerTest.java)29
-rw-r--r--robolectric_tests/src/com/android/launcher3/widget/picker/util/WidgetsTableUtilsTest.java (renamed from tests/src/com/android/launcher3/widget/picker/util/WidgetsTableUtilsTest.java)66
-rw-r--r--robolectric_tests/unstaged/SettingsCacheTest.java115
-rw-r--r--src/com/android/launcher3/AbstractFloatingView.java40
-rw-r--r--src/com/android/launcher3/AppWidgetResizeFrame.java130
-rw-r--r--src/com/android/launcher3/AutoInstallsLayout.java4
-rw-r--r--src/com/android/launcher3/BaseActivity.java49
-rw-r--r--src/com/android/launcher3/BaseDraggingActivity.java148
-rw-r--r--src/com/android/launcher3/BaseRecyclerView.java (renamed from src/com/android/launcher3/FastScrollRecyclerView.java)20
-rw-r--r--src/com/android/launcher3/BubbleTextView.java296
-rw-r--r--src/com/android/launcher3/ButtonDropTarget.java95
-rw-r--r--src/com/android/launcher3/CellLayout.java286
-rw-r--r--src/com/android/launcher3/DefaultLayoutParser.java37
-rw-r--r--src/com/android/launcher3/DeleteDropTarget.java21
-rw-r--r--src/com/android/launcher3/DevicePaddings.java10
-rw-r--r--src/com/android/launcher3/DeviceProfile.java935
-rw-r--r--src/com/android/launcher3/DropTargetBar.java253
-rw-r--r--src/com/android/launcher3/ExtendedEditText.java15
-rw-r--r--src/com/android/launcher3/FirstFrameAnimatorHelper.java2
-rw-r--r--src/com/android/launcher3/GestureNavContract.java56
-rw-r--r--src/com/android/launcher3/Hotseat.java74
-rw-r--r--src/com/android/launcher3/InvariantDeviceProfile.java779
-rw-r--r--src/com/android/launcher3/Launcher.java684
-rw-r--r--src/com/android/launcher3/LauncherAnimUtils.java20
-rw-r--r--src/com/android/launcher3/LauncherAppState.java34
-rw-r--r--src/com/android/launcher3/LauncherBackupAgent.java18
-rw-r--r--src/com/android/launcher3/LauncherFiles.java15
-rw-r--r--src/com/android/launcher3/LauncherModel.java56
-rw-r--r--src/com/android/launcher3/LauncherProvider.java148
-rw-r--r--src/com/android/launcher3/LauncherRootView.java14
-rw-r--r--src/com/android/launcher3/LauncherSettings.java13
-rw-r--r--src/com/android/launcher3/LauncherState.java77
-rw-r--r--src/com/android/launcher3/PagedView.java416
-rw-r--r--src/com/android/launcher3/Partner.java2
-rw-r--r--src/com/android/launcher3/ResourceUtils.java7
-rw-r--r--src/com/android/launcher3/SecondaryDropTarget.java60
-rw-r--r--src/com/android/launcher3/SessionCommitReceiver.java17
-rw-r--r--src/com/android/launcher3/ShortcutAndWidgetContainer.java44
-rw-r--r--src/com/android/launcher3/Utilities.java213
-rw-r--r--src/com/android/launcher3/Workspace.java846
-rw-r--r--src/com/android/launcher3/WorkspaceLayoutManager.java13
-rw-r--r--src/com/android/launcher3/WorkspaceStateTransitionAnimation.java78
-rw-r--r--src/com/android/launcher3/accessibility/BaseAccessibilityDelegate.java199
-rw-r--r--src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java334
-rw-r--r--src/com/android/launcher3/accessibility/ShortcutMenuAccessibilityDelegate.java11
-rw-r--r--src/com/android/launcher3/accessibility/WorkspaceAccessibilityHelper.java2
-rw-r--r--src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java306
-rw-r--r--src/com/android/launcher3/allapps/AllAppsContainerView.java820
-rw-r--r--src/com/android/launcher3/allapps/AllAppsFastScrollHelper.java4
-rw-r--r--src/com/android/launcher3/allapps/AllAppsGridAdapter.java338
-rw-r--r--src/com/android/launcher3/allapps/AllAppsPagedView.java8
-rw-r--r--src/com/android/launcher3/allapps/AllAppsRecyclerView.java129
-rw-r--r--src/com/android/launcher3/allapps/AllAppsTransitionController.java132
-rw-r--r--src/com/android/launcher3/allapps/AlphabeticalAppsList.java293
-rw-r--r--src/com/android/launcher3/allapps/AppInfoComparator.java4
-rw-r--r--src/com/android/launcher3/allapps/BaseAllAppsAdapter.java303
-rw-r--r--src/com/android/launcher3/allapps/BaseAllAppsContainerView.java850
-rw-r--r--src/com/android/launcher3/allapps/DecorationInfo.java (renamed from quickstep/src/com/android/launcher3/taskbar/TaskbarSharedState.java)13
-rw-r--r--src/com/android/launcher3/allapps/FloatingHeaderRow.java2
-rw-r--r--src/com/android/launcher3/allapps/FloatingHeaderView.java168
-rw-r--r--src/com/android/launcher3/allapps/LauncherAllAppsContainerView.java37
-rw-r--r--src/com/android/launcher3/allapps/SearchRecyclerView.java60
-rw-r--r--src/com/android/launcher3/allapps/SearchUiManager.java23
-rw-r--r--src/com/android/launcher3/allapps/SecondaryLauncherAllAppsContainerView.java45
-rw-r--r--src/com/android/launcher3/allapps/WorkAdapterProvider.java76
-rw-r--r--src/com/android/launcher3/allapps/WorkEduCard.java19
-rw-r--r--src/com/android/launcher3/allapps/WorkModeSwitch.java129
-rw-r--r--src/com/android/launcher3/allapps/WorkPausedCard.java11
-rw-r--r--src/com/android/launcher3/allapps/WorkProfileManager.java204
-rw-r--r--src/com/android/launcher3/allapps/search/AllAppsSearchBarController.java38
-rw-r--r--src/com/android/launcher3/allapps/search/AppsSearchContainerLayout.java44
-rw-r--r--src/com/android/launcher3/allapps/search/DefaultAppSearchAlgorithm.java5
-rw-r--r--src/com/android/launcher3/allapps/search/DefaultSearchAdapterProvider.java12
-rw-r--r--src/com/android/launcher3/allapps/search/SearchAdapterProvider.java11
-rw-r--r--src/com/android/launcher3/anim/AnimatedPropertySetter.java144
-rw-r--r--src/com/android/launcher3/anim/AnimatorPlaybackController.java2
-rw-r--r--src/com/android/launcher3/anim/FlingSpringAnim.java12
-rw-r--r--src/com/android/launcher3/anim/Interpolators.java68
-rw-r--r--src/com/android/launcher3/anim/KeyboardInsetAnimationCallback.java27
-rw-r--r--src/com/android/launcher3/anim/PendingAnimation.java108
-rw-r--r--src/com/android/launcher3/anim/PropertySetter.java55
-rw-r--r--src/com/android/launcher3/anim/RevealOutlineAnimation.java22
-rw-r--r--src/com/android/launcher3/anim/SpringAnimationBuilder.java4
-rw-r--r--src/com/android/launcher3/compat/AccessibilityManagerCompat.java23
-rw-r--r--src/com/android/launcher3/compat/AlphabeticIndexCompat.java4
-rw-r--r--src/com/android/launcher3/config/FeatureFlags.java151
-rw-r--r--src/com/android/launcher3/dragndrop/AddItemActivity.java20
-rw-r--r--src/com/android/launcher3/dragndrop/DragController.java36
-rw-r--r--src/com/android/launcher3/dragndrop/DragDriver.java15
-rw-r--r--src/com/android/launcher3/dragndrop/DragLayer.java188
-rw-r--r--src/com/android/launcher3/dragndrop/DragView.java162
-rw-r--r--src/com/android/launcher3/dragndrop/FolderAdaptiveIcon.java190
-rw-r--r--src/com/android/launcher3/dragndrop/LauncherDragController.java9
-rw-r--r--src/com/android/launcher3/dragndrop/LauncherDragView.java70
-rw-r--r--src/com/android/launcher3/dragndrop/PinItemDragListener.java9
-rw-r--r--src/com/android/launcher3/dragndrop/PinShortcutRequestActivityInfo.java3
-rw-r--r--src/com/android/launcher3/dragndrop/SpringLoadedDragController.java2
-rw-r--r--src/com/android/launcher3/folder/Folder.java69
-rw-r--r--src/com/android/launcher3/folder/FolderAnimationManager.java17
-rw-r--r--src/com/android/launcher3/folder/FolderIcon.java67
-rw-r--r--src/com/android/launcher3/folder/FolderNameEditText.java13
-rw-r--r--src/com/android/launcher3/folder/FolderNameProvider.java25
-rw-r--r--src/com/android/launcher3/folder/FolderPagedView.java4
-rw-r--r--src/com/android/launcher3/folder/LauncherDelegate.java31
-rw-r--r--src/com/android/launcher3/folder/PreviewBackground.java23
-rw-r--r--src/com/android/launcher3/folder/PreviewItemManager.java3
-rw-r--r--src/com/android/launcher3/graphics/DragPreviewProvider.java8
-rw-r--r--src/com/android/launcher3/graphics/GridCustomizationsProvider.java38
-rw-r--r--src/com/android/launcher3/graphics/IconPalette.java11
-rw-r--r--src/com/android/launcher3/graphics/LauncherPreviewRenderer.java219
-rw-r--r--src/com/android/launcher3/graphics/PreloadIconDrawable.java15
-rw-r--r--src/com/android/launcher3/graphics/PreviewSurfaceRenderer.java38
-rw-r--r--src/com/android/launcher3/graphics/ShiftedBitmapDrawable.java105
-rw-r--r--src/com/android/launcher3/icons/ComponentWithLabelAndIcon.java3
-rw-r--r--src/com/android/launcher3/icons/IconCache.java250
-rw-r--r--src/com/android/launcher3/icons/LauncherActivityCachingLogic.java3
-rw-r--r--src/com/android/launcher3/icons/LauncherIconProvider.java104
-rw-r--r--src/com/android/launcher3/icons/LauncherIcons.java19
-rw-r--r--src/com/android/launcher3/icons/ShortcutCachingLogic.java4
-rw-r--r--src/com/android/launcher3/logging/InstanceId.java4
-rw-r--r--src/com/android/launcher3/logging/StatsLogManager.java199
-rw-r--r--src/com/android/launcher3/model/AddWorkspaceItemsTask.java135
-rw-r--r--src/com/android/launcher3/model/AllAppsList.java53
-rw-r--r--src/com/android/launcher3/model/BaseLoaderResults.java144
-rw-r--r--src/com/android/launcher3/model/BaseModelUpdateTask.java11
-rw-r--r--src/com/android/launcher3/model/BgDataModel.java85
-rw-r--r--src/com/android/launcher3/model/DeviceGridState.java159
-rw-r--r--src/com/android/launcher3/model/FirstScreenBroadcast.java30
-rw-r--r--src/com/android/launcher3/model/GridBackupTable.java45
-rw-r--r--src/com/android/launcher3/model/GridSizeMigrationTask.java1098
-rw-r--r--src/com/android/launcher3/model/GridSizeMigrationTaskV2.java120
-rw-r--r--src/com/android/launcher3/model/ItemInstallQueue.java17
-rw-r--r--src/com/android/launcher3/model/LoaderCursor.java81
-rw-r--r--src/com/android/launcher3/model/LoaderMemoryLogger.java91
-rw-r--r--src/com/android/launcher3/model/LoaderTask.java146
-rw-r--r--src/com/android/launcher3/model/ModelDelegate.java30
-rw-r--r--src/com/android/launcher3/model/ModelUtils.java48
-rw-r--r--src/com/android/launcher3/model/ModelWriter.java88
-rw-r--r--src/com/android/launcher3/model/PackageInstallStateChangedTask.java9
-rw-r--r--src/com/android/launcher3/model/PackageUpdatedTask.java32
-rw-r--r--src/com/android/launcher3/model/ReloadStringCacheTask.java39
-rw-r--r--src/com/android/launcher3/model/ShortcutsChangedTask.java3
-rw-r--r--src/com/android/launcher3/model/StringCache.java254
-rw-r--r--src/com/android/launcher3/model/UserLockStateChangedTask.java4
-rw-r--r--src/com/android/launcher3/model/UserManagerState.java2
-rw-r--r--src/com/android/launcher3/model/WorkspaceItemSpaceFinder.java115
-rw-r--r--src/com/android/launcher3/model/data/AppInfo.java10
-rw-r--r--src/com/android/launcher3/model/data/FolderInfo.java2
-rw-r--r--src/com/android/launcher3/model/data/IconRequestInfo.java117
-rw-r--r--src/com/android/launcher3/model/data/ItemInfo.java14
-rw-r--r--src/com/android/launcher3/model/data/ItemInfoWithIcon.java29
-rw-r--r--src/com/android/launcher3/model/data/LauncherAppWidgetInfo.java2
-rw-r--r--src/com/android/launcher3/model/data/PackageItemInfo.java34
-rw-r--r--src/com/android/launcher3/model/data/SearchActionItemInfo.java73
-rw-r--r--src/com/android/launcher3/model/data/WorkspaceItemFactory.java29
-rw-r--r--src/com/android/launcher3/model/data/WorkspaceItemInfo.java23
-rw-r--r--src/com/android/launcher3/notification/NotificationContainer.java283
-rw-r--r--src/com/android/launcher3/notification/NotificationInfo.java18
-rw-r--r--src/com/android/launcher3/notification/NotificationItemView.java179
-rw-r--r--src/com/android/launcher3/notification/NotificationListener.java68
-rw-r--r--src/com/android/launcher3/notification/NotificationMainView.java245
-rw-r--r--src/com/android/launcher3/pageindicators/PageIndicator.java21
-rw-r--r--src/com/android/launcher3/pageindicators/PageIndicatorDots.java15
-rw-r--r--src/com/android/launcher3/pageindicators/WorkspacePageIndicator.java7
-rw-r--r--src/com/android/launcher3/pm/InstallSessionHelper.java54
-rw-r--r--src/com/android/launcher3/pm/InstallSessionTracker.java103
-rw-r--r--src/com/android/launcher3/pm/PackageInstallInfo.java24
-rw-r--r--src/com/android/launcher3/pm/UserCache.java5
-rw-r--r--src/com/android/launcher3/popup/ArrowPopup.java267
-rw-r--r--src/com/android/launcher3/popup/LauncherPopupLiveUpdateHandler.java95
-rw-r--r--src/com/android/launcher3/popup/PopupContainerWithArrow.java262
-rw-r--r--src/com/android/launcher3/popup/PopupDataProvider.java10
-rw-r--r--src/com/android/launcher3/popup/PopupLiveUpdateHandler.java111
-rw-r--r--src/com/android/launcher3/popup/PopupPopulator.java16
-rw-r--r--src/com/android/launcher3/popup/RemoteActionShortcut.java4
-rw-r--r--src/com/android/launcher3/popup/RoundedArrowDrawable.java26
-rw-r--r--src/com/android/launcher3/popup/SystemShortcut.java131
-rw-r--r--src/com/android/launcher3/provider/ImportDataTask.java438
-rw-r--r--src/com/android/launcher3/provider/LauncherDbUtils.java71
-rw-r--r--src/com/android/launcher3/provider/LossyScreenMigrationTask.java98
-rw-r--r--src/com/android/launcher3/provider/RestoreDbTask.java85
-rw-r--r--src/com/android/launcher3/recyclerview/ViewHolderBinder.java16
-rw-r--r--src/com/android/launcher3/search/SearchAlgorithm.java7
-rw-r--r--src/com/android/launcher3/search/SearchCallback.java7
-rw-r--r--src/com/android/launcher3/secondarydisplay/PinnedAppsAdapter.java9
-rw-r--r--src/com/android/launcher3/secondarydisplay/SecondaryDisplayLauncher.java86
-rw-r--r--src/com/android/launcher3/secondarydisplay/SecondaryDragLayer.java34
-rw-r--r--src/com/android/launcher3/settings/DeveloperOptionsFragment.java38
-rw-r--r--src/com/android/launcher3/settings/NotificationDotsPreference.java1
-rw-r--r--src/com/android/launcher3/settings/SettingsActivity.java19
-rw-r--r--src/com/android/launcher3/shortcuts/DeepShortcutView.java1
-rw-r--r--src/com/android/launcher3/shortcuts/ShortcutDragPreviewProvider.java13
-rw-r--r--src/com/android/launcher3/shortcuts/ShortcutKey.java12
-rw-r--r--src/com/android/launcher3/statemanager/BaseState.java4
-rw-r--r--src/com/android/launcher3/statemanager/StateManager.java15
-rw-r--r--src/com/android/launcher3/statemanager/StatefulActivity.java9
-rw-r--r--src/com/android/launcher3/states/HintState.java2
-rw-r--r--src/com/android/launcher3/states/RotationHelper.java28
-rw-r--r--src/com/android/launcher3/states/SpringLoadedState.java31
-rw-r--r--src/com/android/launcher3/states/StateAnimationConfig.java6
-rw-r--r--src/com/android/launcher3/testing/TestInformationHandler.java113
-rw-r--r--src/com/android/launcher3/testing/TestInformationProvider.java2
-rw-r--r--src/com/android/launcher3/testing/TestInformationRequest.java29
-rw-r--r--src/com/android/launcher3/testing/TestLogging.java18
-rw-r--r--src/com/android/launcher3/testing/TestProtocol.java46
-rw-r--r--src/com/android/launcher3/testing/WorkspaceCellCenterRequest.java138
-rw-r--r--src/com/android/launcher3/touch/AbstractStateChangeTouchController.java29
-rw-r--r--src/com/android/launcher3/touch/AllAppsSwipeController.java117
-rw-r--r--src/com/android/launcher3/touch/BaseSwipeDetector.java17
-rw-r--r--src/com/android/launcher3/touch/BothAxesSwipeDetector.java9
-rw-r--r--src/com/android/launcher3/touch/ItemClickHandler.java67
-rw-r--r--src/com/android/launcher3/touch/ItemLongClickListener.java8
-rw-r--r--src/com/android/launcher3/touch/LandscapePagedViewHandler.java291
-rw-r--r--src/com/android/launcher3/touch/PagedOrientationHandler.java113
-rw-r--r--src/com/android/launcher3/touch/PortraitPagedViewHandler.java491
-rw-r--r--src/com/android/launcher3/touch/SeascapePagedViewHandler.java130
-rw-r--r--src/com/android/launcher3/touch/SingleAxisSwipeDetector.java10
-rw-r--r--src/com/android/launcher3/touch/WorkspaceTouchListener.java31
-rw-r--r--src/com/android/launcher3/util/ActivityLifecycleCallbacksAdapter.java29
-rw-r--r--src/com/android/launcher3/util/DisplayController.java315
-rw-r--r--src/com/android/launcher3/util/Executors.java16
-rw-r--r--src/com/android/launcher3/util/FlagOp.java16
-rw-r--r--src/com/android/launcher3/util/FlingAnimation.java44
-rw-r--r--src/com/android/launcher3/util/GridOccupancy.java21
-rw-r--r--src/com/android/launcher3/util/HorizontalInsettableView.java35
-rw-r--r--src/com/android/launcher3/util/IntArray.java29
-rw-r--r--src/com/android/launcher3/util/IntSet.java52
-rw-r--r--src/com/android/launcher3/util/ItemInfoMatcher.java82
-rw-r--r--src/com/android/launcher3/util/LauncherBindableItemsContainer.java113
-rw-r--r--src/com/android/launcher3/util/LogConfig.java5
-rw-r--r--src/com/android/launcher3/util/MainThreadInitializedObject.java90
-rw-r--r--src/com/android/launcher3/util/MultiAdditivePropertyFactory.java115
-rw-r--r--src/com/android/launcher3/util/MultiScalePropertyFactory.java125
-rw-r--r--src/com/android/launcher3/util/MultiValueAlpha.java28
-rw-r--r--src/com/android/launcher3/util/OnboardingPrefs.java49
-rw-r--r--src/com/android/launcher3/util/PackageManagerHelper.java3
-rw-r--r--src/com/android/launcher3/util/PackageUserKey.java34
-rw-r--r--src/com/android/launcher3/util/PluralMessageFormat.java45
-rw-r--r--src/com/android/launcher3/util/RotationUtils.java75
-rw-r--r--src/com/android/launcher3/util/SettingsCache.java8
-rw-r--r--src/com/android/launcher3/util/SimpleBroadcastReceiver.java9
-rw-r--r--src/com/android/launcher3/util/SplitConfigurationOptions.java100
-rw-r--r--src/com/android/launcher3/util/UiThreadHelper.java26
-rw-r--r--src/com/android/launcher3/util/VibratorWrapper.java (renamed from quickstep/src/com/android/quickstep/util/VibratorWrapper.java)38
-rw-r--r--src/com/android/launcher3/util/ViewCache.java18
-rw-r--r--src/com/android/launcher3/util/ViewOnDrawExecutor.java61
-rw-r--r--src/com/android/launcher3/util/WallpaperOffsetInterpolator.java90
-rw-r--r--src/com/android/launcher3/util/WindowBounds.java10
-rw-r--r--src/com/android/launcher3/util/WindowManagerCompat.java107
-rw-r--r--src/com/android/launcher3/util/window/CachedDisplayInfo.java92
-rw-r--r--src/com/android/launcher3/util/window/RefreshRateTracker.java83
-rw-r--r--src/com/android/launcher3/util/window/WindowManagerProxy.java365
-rw-r--r--src/com/android/launcher3/views/AbstractSlideInView.java43
-rw-r--r--src/com/android/launcher3/views/ActivityContext.java96
-rw-r--r--src/com/android/launcher3/views/AllAppsButton.java49
-rw-r--r--src/com/android/launcher3/views/AppLauncher.java213
-rw-r--r--src/com/android/launcher3/views/ArrowTipView.java76
-rw-r--r--src/com/android/launcher3/views/BaseDragLayer.java33
-rw-r--r--src/com/android/launcher3/views/BubbleTextHolder.java12
-rw-r--r--src/com/android/launcher3/views/ClipIconView.java27
-rw-r--r--src/com/android/launcher3/views/FloatingIconView.java140
-rw-r--r--src/com/android/launcher3/views/FloatingSurfaceView.java27
-rw-r--r--src/com/android/launcher3/views/OptionsPopupView.java65
-rw-r--r--src/com/android/launcher3/views/RecyclerViewFastScroller.java41
-rw-r--r--src/com/android/launcher3/views/Snackbar.java65
-rw-r--r--src/com/android/launcher3/views/TopRoundedCornerView.java61
-rw-r--r--src/com/android/launcher3/widget/AddItemWidgetsBottomSheet.java49
-rw-r--r--src/com/android/launcher3/widget/BaseLauncherAppWidgetHostView.java119
-rw-r--r--src/com/android/launcher3/widget/BaseWidgetSheet.java96
-rw-r--r--src/com/android/launcher3/widget/CachingWidgetPreviewLoader.java289
-rw-r--r--src/com/android/launcher3/widget/DatabaseWidgetPreviewLoader.java711
-rw-r--r--src/com/android/launcher3/widget/DeferredAppWidgetHostView.java13
-rw-r--r--src/com/android/launcher3/widget/LauncherAppWidgetHostView.java310
-rw-r--r--src/com/android/launcher3/widget/LauncherAppWidgetProviderInfo.java20
-rw-r--r--src/com/android/launcher3/widget/LocalColorExtractor.java50
-rw-r--r--src/com/android/launcher3/widget/NavigableAppWidgetHostView.java14
-rw-r--r--src/com/android/launcher3/widget/PendingAddWidgetInfo.java2
-rw-r--r--src/com/android/launcher3/widget/PendingAppWidgetHostView.java20
-rw-r--r--src/com/android/launcher3/widget/PendingItemDragHelper.java39
-rw-r--r--src/com/android/launcher3/widget/WidgetCell.java322
-rw-r--r--src/com/android/launcher3/widget/WidgetPreviewLoader.java47
-rw-r--r--src/com/android/launcher3/widget/WidgetSections.java134
-rw-r--r--src/com/android/launcher3/widget/WidgetsBottomSheet.java62
-rw-r--r--src/com/android/launcher3/widget/custom/CustomWidgetManager.java6
-rw-r--r--src/com/android/launcher3/widget/dragndrop/AppWidgetHostViewDragListener.java11
-rw-r--r--src/com/android/launcher3/widget/model/WidgetListSpaceEntry.java41
-rw-r--r--src/com/android/launcher3/widget/model/WidgetsListBaseEntry.java10
-rw-r--r--src/com/android/launcher3/widget/picker/OnHeaderClickListener.java2
-rw-r--r--src/com/android/launcher3/widget/picker/SearchAndRecommendationsScrollController.java412
-rw-r--r--src/com/android/launcher3/widget/picker/WidgetsFullSheet.java250
-rw-r--r--src/com/android/launcher3/widget/picker/WidgetsListAdapter.java191
-rw-r--r--src/com/android/launcher3/widget/picker/WidgetsListHeader.java28
-rw-r--r--src/com/android/launcher3/widget/picker/WidgetsListHeaderViewHolderBinder.java19
-rw-r--r--src/com/android/launcher3/widget/picker/WidgetsListLayoutManager.java51
-rw-r--r--src/com/android/launcher3/widget/picker/WidgetsListSearchHeaderViewHolderBinder.java15
-rw-r--r--src/com/android/launcher3/widget/picker/WidgetsListTableViewHolderBinder.java65
-rw-r--r--src/com/android/launcher3/widget/picker/WidgetsRecommendationTableLayout.java14
-rw-r--r--src/com/android/launcher3/widget/picker/WidgetsRecyclerView.java46
-rw-r--r--src/com/android/launcher3/widget/picker/WidgetsRowViewHolder.java10
-rw-r--r--src/com/android/launcher3/widget/picker/WidgetsSpaceViewHolderBinder.java115
-rw-r--r--src/com/android/launcher3/widget/picker/search/WidgetsSearchBarController.java5
-rw-r--r--src/com/android/launcher3/widget/util/WidgetSizes.java24
-rw-r--r--src/com/android/launcher3/widget/util/WidgetsTableUtils.java20
-rw-r--r--src_build_config/com/android/launcher3/BuildConfig.java9
-rw-r--r--src_plugins/com/android/systemui/plugins/OneSearch.java56
-rw-r--r--src_plugins/com/android/systemui/plugins/OverlayPlugin.java (renamed from src_plugins/com/android/systemui/plugins/LauncherOverlayPlugin.java)4
-rw-r--r--src_plugins/com/android/systemui/plugins/OverscrollPlugin.java75
-rw-r--r--src_plugins/com/android/systemui/plugins/OverviewScreenshotActions.java41
-rw-r--r--src_plugins/com/android/systemui/plugins/RecentsExtraCard.java42
-rw-r--r--src_shortcuts_overrides/com/android/launcher3/model/WidgetsModel.java109
-rw-r--r--src_shortcuts_overrides/com/android/launcher3/util/AbsGridOccupancy.java55
-rw-r--r--src_ui_overrides/com/android/launcher3/uioverrides/ApiWrapper.java8
-rw-r--r--src_ui_overrides/com/android/launcher3/uioverrides/states/AllAppsState.java47
-rw-r--r--src_ui_overrides/com/android/launcher3/uioverrides/states/OverviewState.java2
-rw-r--r--tests/Android.bp93
-rw-r--r--tests/Android.mk54
-rw-r--r--tests/AndroidManifest-common.xml89
-rw-r--r--tests/dummy_app/Android.bp29
-rw-r--r--tests/dummy_app/Android.mk21
-rw-r--r--tests/res/drawable/test_theme_icon.xml29
-rw-r--r--tests/res/raw/devices.json45
-rw-r--r--tests/src/com/android/launcher3/DeviceProfileBaseTest.kt136
-rw-r--r--tests/src/com/android/launcher3/DeviceProfileGridDimensionsTest.kt128
-rw-r--r--tests/src/com/android/launcher3/HotseatShownIconsTest.kt212
-rw-r--r--tests/src/com/android/launcher3/InlineQsbTest.kt103
-rw-r--r--tests/src/com/android/launcher3/compat/PromiseIconUiTest.java21
-rw-r--r--tests/src/com/android/launcher3/deviceemulator/DisplayEmulator.java95
-rw-r--r--tests/src/com/android/launcher3/deviceemulator/TestWindowManagerProxy.java80
-rw-r--r--tests/src/com/android/launcher3/deviceemulator/models/DeviceEmulationData.java154
-rw-r--r--tests/src/com/android/launcher3/model/AbstractWorkspaceModelTest.kt162
-rw-r--r--tests/src/com/android/launcher3/model/AddWorkspaceItemsTaskTest.kt245
-rw-r--r--tests/src/com/android/launcher3/model/GridSizeMigrationTaskV2Test.kt510
-rw-r--r--tests/src/com/android/launcher3/model/WorkspaceItemSpaceFinderTest.kt171
-rw-r--r--tests/src/com/android/launcher3/secondarydisplay/SDLauncherTest.java53
-rw-r--r--tests/src/com/android/launcher3/testcomponent/OtherBaseTestingActivity.java22
-rw-r--r--tests/src/com/android/launcher3/touch/SingleAxisSwipeDetectorTest.java27
-rw-r--r--tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java139
-rw-r--r--tests/src/com/android/launcher3/ui/ActivityLeakTracker.java90
-rw-r--r--tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java245
-rw-r--r--tests/src/com/android/launcher3/ui/WorkProfileTest.java178
-rw-r--r--tests/src/com/android/launcher3/ui/widget/AddConfigWidgetTest.java56
-rw-r--r--tests/src/com/android/launcher3/ui/widget/AddWidgetTest.java10
-rw-r--r--tests/src/com/android/launcher3/ui/widget/BindWidgetTest.java2
-rw-r--r--tests/src/com/android/launcher3/ui/widget/RequestPinItemTest.java14
-rw-r--r--tests/src/com/android/launcher3/ui/workspace/ThemeIconsTest.java128
-rw-r--r--tests/src/com/android/launcher3/ui/workspace/TwoPanelWorkspaceTest.java342
-rw-r--r--tests/src/com/android/launcher3/util/ActivityContextWrapper.java62
-rw-r--r--tests/src/com/android/launcher3/util/KotlinMockitoHelpers.kt117
-rw-r--r--tests/src/com/android/launcher3/util/MultiAdditivePropertyTest.kt66
-rw-r--r--tests/src/com/android/launcher3/util/MultiScalePropertyTest.kt109
-rw-r--r--tests/src/com/android/launcher3/util/PackageUserKeyTest.java162
-rw-r--r--tests/src/com/android/launcher3/util/ReflectionHelpers.java58
-rw-r--r--tests/src/com/android/launcher3/util/Wait.java2
-rw-r--r--tests/src/com/android/launcher3/util/rule/FailureWatcher.java93
-rw-r--r--tests/src/com/android/launcher3/util/rule/LauncherActivityRule.java2
-rw-r--r--tests/src/com/android/launcher3/util/rule/SamplerRule.java129
-rw-r--r--tests/src/com/android/launcher3/util/rule/ShellCommandRule.java3
-rw-r--r--tests/src/com/android/launcher3/util/rule/TestStabilityRule.java4
-rw-r--r--tests/src_common/README.md1
-rw-r--r--tests/src_common/com/android/launcher3/common/WidgetUtils.java (renamed from tests/src/com/android/launcher3/util/WidgetUtils.java)23
-rw-r--r--tests/src_disabled/WorkTabTest.java236
-rw-r--r--tests/tapl/com/android/launcher3/tapl/AddToHomeScreenPrompt.java19
-rw-r--r--tests/tapl/com/android/launcher3/tapl/AllApps.java95
-rw-r--r--tests/tapl/com/android/launcher3/tapl/AllAppsAppIcon.java38
-rw-r--r--tests/tapl/com/android/launcher3/tapl/AllAppsFromOverview.java67
-rw-r--r--tests/tapl/com/android/launcher3/tapl/AllAppsFromTaskbar.java51
-rw-r--r--tests/tapl/com/android/launcher3/tapl/AppIcon.java28
-rw-r--r--tests/tapl/com/android/launcher3/tapl/AppIconMenu.java19
-rw-r--r--tests/tapl/com/android/launcher3/tapl/AppIconMenuItem.java6
-rw-r--r--tests/tapl/com/android/launcher3/tapl/Background.java246
-rw-r--r--tests/tapl/com/android/launcher3/tapl/BaseOverview.java135
-rw-r--r--tests/tapl/com/android/launcher3/tapl/Folder.java76
-rw-r--r--tests/tapl/com/android/launcher3/tapl/FolderDragTarget.java28
-rw-r--r--tests/tapl/com/android/launcher3/tapl/FolderIcon.java66
-rw-r--r--tests/tapl/com/android/launcher3/tapl/Home.java4
-rw-r--r--tests/tapl/com/android/launcher3/tapl/HomeAllApps.java48
-rw-r--r--tests/tapl/com/android/launcher3/tapl/HomeAppIcon.java142
-rw-r--r--tests/tapl/com/android/launcher3/tapl/HomeAppIconMenu.java39
-rw-r--r--tests/tapl/com/android/launcher3/tapl/HomeAppIconMenuItem.java35
-rw-r--r--tests/tapl/com/android/launcher3/tapl/HomeQsb.java45
-rw-r--r--tests/tapl/com/android/launcher3/tapl/Launchable.java130
-rw-r--r--tests/tapl/com/android/launcher3/tapl/LaunchedAppState.java156
-rw-r--r--tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java658
-rw-r--r--tests/tapl/com/android/launcher3/tapl/OptionsPopupMenu.java41
-rw-r--r--tests/tapl/com/android/launcher3/tapl/OptionsPopupMenuItem.java51
-rw-r--r--tests/tapl/com/android/launcher3/tapl/Overview.java38
-rw-r--r--tests/tapl/com/android/launcher3/tapl/OverviewActions.java52
-rw-r--r--tests/tapl/com/android/launcher3/tapl/OverviewTask.java81
-rw-r--r--tests/tapl/com/android/launcher3/tapl/SearchResultFromQsb.java50
-rw-r--r--tests/tapl/com/android/launcher3/tapl/SplitscreenDragSource.java39
-rw-r--r--tests/tapl/com/android/launcher3/tapl/Taskbar.java123
-rw-r--r--tests/tapl/com/android/launcher3/tapl/TaskbarAppIcon.java52
-rw-r--r--tests/tapl/com/android/launcher3/tapl/TaskbarAppIconMenu.java38
-rw-r--r--tests/tapl/com/android/launcher3/tapl/TaskbarAppIconMenuItem.java57
-rw-r--r--tests/tapl/com/android/launcher3/tapl/Widget.java68
-rw-r--r--tests/tapl/com/android/launcher3/tapl/WidgetResizeFrame.java37
-rw-r--r--tests/tapl/com/android/launcher3/tapl/Widgets.java11
-rw-r--r--tests/tapl/com/android/launcher3/tapl/Workspace.java356
-rw-r--r--tests/tapl/com/android/launcher3/tapl/WorkspaceAppIcon.java43
-rw-r--r--tests/tapl/com/android/launcher3/tapl/WorkspaceDragSource.java52
1168 files changed, 35672 insertions, 70757 deletions
diff --git a/Android.bp b/Android.bp
index 0a55675d43..1b6ffe42b7 100644
--- a/Android.bp
+++ b/Android.bp
@@ -13,17 +13,26 @@
// limitations under the License.
package {
- // See: http://go/android-license-faq
- default_applicable_licenses: ["Android-Apache-2.0"],
+ default_applicable_licenses: ["packages_apps_Launcher3_license"],
}
min_launcher3_sdk_version = "26"
+// Added automatically by a large-scale-change
+// See: http://go/android-license-faq
+license {
+ name: "packages_apps_Launcher3_license",
+ visibility: [":__subpackages__"],
+ license_kinds: [
+ "SPDX-license-identifier-Apache-2.0",
+ ],
+ license_text: [
+ "NOTICE",
+ ],
+}
+
android_library {
name: "launcher-aosp-tapl",
- libs: [
- "framework-statsd",
- ],
static_libs: [
"androidx.annotation_annotation",
"androidx.test.runner",
@@ -31,13 +40,11 @@ android_library {
"androidx.test.uiautomator_uiautomator",
"androidx.preference_preference",
"SystemUISharedLib",
- "SystemUIAnimationLib",
],
srcs: [
"tests/tapl/**/*.java",
"src/com/android/launcher3/ResourceUtils.java",
"src/com/android/launcher3/testing/TestProtocol.java",
- "src/com/android/launcher3/testing/*Request.java",
],
resource_dirs: [ ],
manifest: "tests/tapl/AndroidManifest.xml",
@@ -105,7 +112,6 @@ android_library {
"androidx.preference_preference",
"androidx.slice_slice-view",
"androidx.cardview_cardview",
- "com.google.android.material_material",
"iconloader_base",
],
manifest: "AndroidManifest-common.xml",
@@ -142,13 +148,9 @@ android_app {
],
srcs: [
"src/**/*.java",
- "src/**/*.kt",
"src_shortcuts_overrides/**/*.java",
- "src_shortcuts_overrides/**/*.kt",
"src_ui_overrides/**/*.java",
- "src_ui_overrides/**/*.kt",
"ext_tests/src/**/*.java",
- "ext_tests/src/**/*.kt",
],
resource_dirs: [
"ext_tests/res",
@@ -189,15 +191,10 @@ android_library {
resource_dirs: [
"quickstep/res",
],
- libs: [
- "framework-statsd",
- ],
static_libs: [
"Launcher3ResLib",
- "lottie",
"SystemUISharedLib",
"SystemUI-statsd",
- "SystemUIAnimationLib",
],
manifest: "quickstep/AndroidManifest.xml",
min_sdk_version: "current",
@@ -207,12 +204,7 @@ android_library {
// Source code used for test helpers
filegroup {
name: "launcher-src-ext-tests",
- srcs: [
- "ext_tests/src/**/*.java",
- "ext_tests/src/**/*.kt",
- "quickstep/ext_tests/src/**/*.java",
- "quickstep/ext_tests/src/**/*.kt",
- ],
+ srcs: ["ext_tests/src/**/*.java"],
}
// Common source files used to build launcher
@@ -220,24 +212,8 @@ filegroup {
name: "launcher-src-no-build-config",
srcs: [
"src/**/*.java",
- "src/**/*.kt",
"src_shortcuts_overrides/**/*.java",
- "src_shortcuts_overrides/**/*.kt",
"quickstep/src/**/*.java",
- "quickstep/src/**/*.kt",
- ],
-}
-
-// Common source files used to build go launcher except go/src files
-filegroup {
- name: "launcher-go-src-no-build-config",
- srcs: [
- "src/**/*.java",
- "src/**/*.kt",
- "quickstep/src/**/*.java",
- "quickstep/src/**/*.kt",
- "go/quickstep/src/**/*.java",
- "go/quickstep/src/**/*.kt",
],
}
@@ -247,33 +223,24 @@ filegroup {
srcs: ["proguard.flags"],
}
+
// Library with all the dependencies for building Launcher Go
android_library {
name: "LauncherGoResLib",
srcs: [
"src/**/*.java",
- "src/**/*.kt",
"quickstep/src/**/*.java",
- "quickstep/src/**/*.kt",
"go/src/**/*.java",
- "go/src/**/*.kt",
"go/quickstep/src/**/*.java",
- "go/quickstep/src/**/*.kt",
],
resource_dirs: [
"go/res",
"go/quickstep/res",
],
- // Note the ordering here is important when it comes to resource
- // overriding. We want the most specific resource overrides defined
- // in QuickstepResLib to take precendece, so it should be the final
- // dependency. See b/205278434 for how this can go wrong.
static_libs: [
"Launcher3CommonDepsLib",
"QuickstepResLib",
- "androidx.room_room-runtime",
],
- plugins: ["androidx.room_room-compiler-plugin"],
manifest: "quickstep/AndroidManifest-launcher.xml",
additional_manifests: [
"go/AndroidManifest.xml",
@@ -285,31 +252,3 @@ android_library {
},
}
-// Build rule for Quickstep library
-android_library {
- name: "Launcher3QuickStepLib",
- srcs: [
- ":launcher-src-no-build-config",
- ],
- resource_dirs: [],
- libs: [
- "framework-statsd",
- ],
- // Note the ordering here is important when it comes to resource
- // overriding. We want the most specific resource overrides defined
- // in QuickstepResLib to take precendece, so it should be the final
- // dependency. See b/208647810 for how this can go wrong.
- static_libs: [
- "SystemUI-statsd",
- "SystemUISharedLib",
- "Launcher3CommonDepsLib",
- "QuickstepResLib",
- "SystemUIAnimationLib",
- ],
- manifest: "quickstep/AndroidManifest.xml",
- platform_apis: true,
- min_sdk_version: "current",
- lint: {
- baseline_filename: "lint-baseline-launcher3.xml",
- },
-}
diff --git a/Android.mk b/Android.mk
index 1bc8b283c7..c222f24afa 100644
--- a/Android.mk
+++ b/Android.mk
@@ -49,11 +49,46 @@ LOCAL_MANIFEST_FILE := go/AndroidManifest.xml
LOCAL_JACK_COVERAGE_INCLUDE_FILTER := com.android.launcher3.*
LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
LOCAL_LICENSE_CONDITIONS := notice
-LOCAL_LICENSE_PACKAGE_NAME := Android Launcher3
-LOCAL_NOTICE_FILE := build/soong/licenses/LICENSE
+LOCAL_NOTICE_FILE := $(LOCAL_PATH)/NOTICE
include $(BUILD_PACKAGE)
#
+# Build rule for Quickstep library.
+#
+include $(CLEAR_VARS)
+LOCAL_USE_AAPT2 := true
+LOCAL_AAPT2_ONLY := true
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_STATIC_JAVA_LIBRARIES := \
+ SystemUI-statsd \
+ SystemUISharedLib
+ifneq (,$(wildcard frameworks/base))
+ LOCAL_PRIVATE_PLATFORM_APIS := true
+else
+ LOCAL_SDK_VERSION := system_current
+ LOCAL_MIN_SDK_VERSION := 26
+endif
+LOCAL_MODULE := Launcher3QuickStepLib
+LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
+LOCAL_LICENSE_CONDITIONS := notice
+LOCAL_NOTICE_FILE := $(LOCAL_PATH)/NOTICE
+LOCAL_PRIVILEGED_MODULE := true
+LOCAL_STATIC_ANDROID_LIBRARIES := Launcher3CommonDepsLib
+
+LOCAL_SRC_FILES := \
+ $(call all-java-files-under, src) \
+ $(call all-java-files-under, quickstep/src) \
+ $(call all-java-files-under, src_shortcuts_overrides)
+
+LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/quickstep/res
+LOCAL_PROGUARD_ENABLED := disabled
+
+
+LOCAL_MANIFEST_FILE := quickstep/AndroidManifest.xml
+include $(BUILD_STATIC_JAVA_LIBRARY)
+
+#
# Build rule for Quickstep app.
#
include $(CLEAR_VARS)
@@ -86,8 +121,7 @@ LOCAL_JACK_COVERAGE_INCLUDE_FILTER := com.android.launcher3.*
LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
LOCAL_LICENSE_CONDITIONS := notice
-LOCAL_LICENSE_PACKAGE_NAME := Android Launcher3
-LOCAL_NOTICE_FILE := build/soong/licenses/LICENSE
+LOCAL_NOTICE_FILE := $(LOCAL_PATH)/NOTICE
include $(BUILD_PACKAGE)
@@ -107,7 +141,7 @@ else
LOCAL_SDK_VERSION := system_current
LOCAL_MIN_SDK_VERSION := 26
endif
-LOCAL_STATIC_ANDROID_LIBRARIES := LauncherGoResLib
+LOCAL_STATIC_ANDROID_LIBRARIES := Launcher3CommonDepsLib
LOCAL_SRC_FILES := \
$(call all-java-files-under, src) \
@@ -138,8 +172,7 @@ LOCAL_MANIFEST_FILE := quickstep/AndroidManifest.xml
LOCAL_JACK_COVERAGE_INCLUDE_FILTER := com.android.launcher3.*
LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
LOCAL_LICENSE_CONDITIONS := notice
-LOCAL_LICENSE_PACKAGE_NAME := Android Launcher3
-LOCAL_NOTICE_FILE := build/soong/licenses/LICENSE
+LOCAL_NOTICE_FILE := $(LOCAL_PATH)/NOTICE
include $(BUILD_PACKAGE)
diff --git a/AndroidManifest-common.xml b/AndroidManifest-common.xml
index 02b83fe889..d725a16f80 100644
--- a/AndroidManifest-common.xml
+++ b/AndroidManifest-common.xml
@@ -19,7 +19,6 @@
-->
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
package="com.android.launcher3">
<!--
@@ -31,6 +30,7 @@
with some minor changed based on the derivative app.
-->
+ <uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.SET_WALLPAPER" />
<uses-permission android:name="android.permission.SET_WALLPAPER_HINTS" />
@@ -42,7 +42,6 @@
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
<!-- for rotating surface by arbitrary degree -->
<uses-permission android:name="android.permission.ROTATE_SURFACE_FLINGER" />
- <uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<!--
Permissions required for read/write access to the workspace data. These permission name
@@ -51,11 +50,13 @@
-->
<permission
android:name="${packageName}.permission.READ_SETTINGS"
+ android:permissionGroup="android.permission-group.SYSTEM_TOOLS"
android:protectionLevel="signatureOrSystem"
android:label="@string/permlab_read_settings"
android:description="@string/permdesc_read_settings"/>
<permission
android:name="${packageName}.permission.WRITE_SETTINGS"
+ android:permissionGroup="android.permission-group.SYSTEM_TOOLS"
android:protectionLevel="signatureOrSystem"
android:label="@string/permlab_write_settings"
android:description="@string/permdesc_write_settings"/>
@@ -143,7 +144,7 @@
<activity
android:name="com.android.launcher3.settings.SettingsActivity"
android:label="@string/settings_button_text"
- android:theme="@style/HomeSettings.Theme"
+ android:theme="@style/HomeSettingsTheme"
android:exported="true"
android:autoRemoveFromRecents="true">
<intent-filter>
@@ -175,11 +176,5 @@
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
-
- <!-- [b/197780098] Disable eager initialization of Jetpack libraries. -->
- <provider
- android:name="androidx.startup.InitializationProvider"
- android:authorities="${applicationId}.androidx-startup"
- tools:node="remove" />
</application>
</manifest>
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 4f580e0bd6..8066816e89 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -20,7 +20,7 @@
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.launcher3">
- <uses-sdk android:targetSdkVersion="33" android:minSdkVersion="26"/>
+ <uses-sdk android:targetSdkVersion="29" android:minSdkVersion="26"/>
<!--
Manifest entries specific to Launcher3. This is merged with AndroidManifest-common.xml.
Refer comments around specific entries on how to extend individual components.
@@ -31,7 +31,6 @@
android:fullBackupOnly="true"
android:fullBackupContent="@xml/backupscheme"
android:hardwareAccelerated="true"
- android:debuggable="true"
android:icon="@drawable/ic_launcher_home"
android:label="@string/derived_app_name"
android:theme="@style/AppTheme"
@@ -50,7 +49,7 @@
android:stateNotNeeded="true"
android:windowSoftInputMode="adjustPan"
android:screenOrientation="unspecified"
- android:configChanges="keyboard|keyboardHidden|mcc|mnc|navigation|orientation|screenSize|screenLayout|smallestScreenSize"
+ android:configChanges="keyboard|keyboardHidden|mcc|mnc|navigation|orientation|screenSize|screenLayout|smallestScreenSize|density"
android:resizeableActivity="true"
android:resumeWhilePausing="true"
android:taskAffinity=""
@@ -58,7 +57,6 @@
android:enabled="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
- <action android:name="android.intent.action.SHOW_WORK_APPS" />
<category android:name="android.intent.category.HOME" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.MONKEY"/>
diff --git a/NOTICE b/NOTICE
new file mode 100644
index 0000000000..c5b1efa7aa
--- /dev/null
+++ b/NOTICE
@@ -0,0 +1,190 @@
+
+ Copyright (c) 2005-2008, 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.
+
+ 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.
+
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
diff --git a/OWNERS b/OWNERS
index 7f98ea6a78..05fa502b34 100644
--- a/OWNERS
+++ b/OWNERS
@@ -39,7 +39,6 @@ peanutbutter@google.com
xuqiu@google.com
sreyasr@google.com
thiruram@google.com
-brianji@google.com
per-file FeatureFlags.java, globs = set noparent
per-file FeatureFlags.java = sunnygoyal@google.com, winsonc@google.com, zakcohen@google.com, mrcasey@google.com, adamcohen@google.com, hyunyoungs@google.com
diff --git a/buglist_with_title.txt b/buglist_with_title.txt
new file mode 100644
index 0000000000..aa8b413284
--- /dev/null
+++ b/buglist_with_title.txt
@@ -0,0 +1,24 @@
+144170434 twickham P1 FIXED Improve Overview -> Home transition ----
+149934536 twickham P2 FIXED Update gesture nav pullback logic ----
+154951045 peanutbutter P1 FIXED Odd animation occuring at times when swiping to home ----
+154964045 awickham P2 FIXED "Clear all" text is not in the middle of app's window vertically ----
+158701272 twickham P4 FIXED Discontinuities when long-swiping to home ----
+160361464 tracyzhou P2 FIXED Place launcher above the target app in live tile mode ----
+160568387 twickham P2 FIXED Can't get to app switcher by swiping up (motion pause not detected) ----
+160718310 xuqiu P1 FIXED With "Select" overview action selected, App icon is missing in other overview apps after orientation change ----
+160748731 sunnygoyal P2 ASSIGNED Unify prediction model with Launcher model ----
+160759508 twickham P2 FIXED Swipe up cannot back to home screen in overview. ----
+161273376 xuqiu P2 FIXED [Overview Actions] Add logging and helpful messages ----
+161536946 twickham P2 FIXED Haptics don't indicate snap-to in overview, ----
+161685099 winsonc P2 FIXED Screen still stay at the quick settings/notification when I swipe up with 3 finger to check the all apps. ----
+161801331 hyunyoungs P2 FIXED Change AllAppsSearch plugin to support only data fetch ----
+161901771 xuqiu P1 FIXED Overlapping layer of highlights with app layout getting darker when keep rotating the device from "Feedback" viewpoint in split screen ----
+161939759 sunnygoyal P2 FIXED RD1A: Going to overview in landscape mode clips the screen content ----
+162012217 perumaal P2 ASSIGNED Leaked Activity Caused by Gleams ----
+162454040 bookatz P2 ASSIGNED Create multiuser test that checks that opening an app works properly ----
+162480567 sfufa P4 FIXED Enable Item Decorations for search items ----
+162564471 tracyzhou P2 FIXED [Live tile] Handle tapping overview actions in live tile mode ----
+162623012 zakcohen P1 ASSIGNED Enable chips flag ----
+162812884 winsonc P2 ASSIGNED [R]The color have not changed in some page after turning on the dark theme. ----
+162861289 hyunyoungs P2 FIXED Add FocusIndicator support to DEVICE_SEARCH feature in S ----
+162871508 sfufa P2 ASSIGNED Introduce support for Hero app section ----
diff --git a/build.gradle b/build.gradle
index 68ed73d60a..a7eef13a3d 100644
--- a/build.gradle
+++ b/build.gradle
@@ -2,6 +2,7 @@ buildscript {
repositories {
mavenCentral()
google()
+ jcenter()
}
dependencies {
classpath GRADLE_CLASS_PATH
@@ -20,8 +21,8 @@ android {
buildToolsVersion BUILD_TOOLS_VERSION
defaultConfig {
- minSdkVersion 26
- targetSdkVersion 30
+ minSdkVersion 25
+ targetSdkVersion 28
versionCode 1
versionName "1.0"
@@ -163,14 +164,12 @@ dependencies {
androidTestImplementation 'com.android.support.test:rules:1.0.0'
androidTestImplementation 'com.android.support.test.uiautomator:uiautomator-v18:2.1.2'
androidTestImplementation "androidx.annotation:annotation:${ANDROID_X_VERSION}"
-
- api 'com.airbnb.android:lottie:3.3.0'
}
protobuf {
// Configure the protoc executable
protoc {
- artifact = "com.google.protobuf:protoc:${protocVersion}${PROTO_ARCH_SUFFIX}"
+ artifact = "com.google.protobuf:protoc:${protocVersion}"
}
generateProtoTasks {
all().each { task ->
diff --git a/ext_tests/src/com/android/launcher3/testing/DebugTestInformationHandler.java b/ext_tests/src/com/android/launcher3/testing/DebugTestInformationHandler.java
index d16e12c9b8..72b8d3fcae 100644
--- a/ext_tests/src/com/android/launcher3/testing/DebugTestInformationHandler.java
+++ b/ext_tests/src/com/android/launcher3/testing/DebugTestInformationHandler.java
@@ -18,8 +18,6 @@ package com.android.launcher3.testing;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
-import android.app.Activity;
-import android.app.Application;
import android.content.Context;
import android.os.Binder;
import android.os.Bundle;
@@ -27,19 +25,13 @@ import android.system.Os;
import android.view.View;
import androidx.annotation.Keep;
-import androidx.annotation.Nullable;
-import com.android.launcher3.BubbleTextView;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.LauncherSettings;
-import com.android.launcher3.ShortcutAndWidgetContainer;
import java.util.ArrayList;
import java.util.Collection;
-import java.util.Collections;
import java.util.LinkedList;
-import java.util.Map;
-import java.util.WeakHashMap;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
@@ -49,48 +41,9 @@ import java.util.concurrent.TimeUnit;
public class DebugTestInformationHandler extends TestInformationHandler {
private static LinkedList sLeaks;
private static Collection<String> sEvents;
- private static Application.ActivityLifecycleCallbacks sActivityLifecycleCallbacks;
- private static final Map<Activity, Boolean> sActivities =
- Collections.synchronizedMap(new WeakHashMap<>());
- private static int sActivitiesCreatedCount = 0;
public DebugTestInformationHandler(Context context) {
init(context);
- if (sActivityLifecycleCallbacks == null) {
- sActivityLifecycleCallbacks = new Application.ActivityLifecycleCallbacks() {
- @Override
- public void onActivityCreated(Activity activity, Bundle bundle) {
- sActivities.put(activity, true);
- ++sActivitiesCreatedCount;
- }
-
- @Override
- public void onActivityStarted(Activity activity) {
- }
-
- @Override
- public void onActivityResumed(Activity activity) {
- }
-
- @Override
- public void onActivityPaused(Activity activity) {
- }
-
- @Override
- public void onActivityStopped(Activity activity) {
- }
-
- @Override
- public void onActivitySaveInstanceState(Activity activity, Bundle bundle) {
- }
-
- @Override
- public void onActivityDestroyed(Activity activity) {
- }
- };
- ((Application) context.getApplicationContext())
- .registerActivityLifecycleCallbacks(sActivityLifecycleCallbacks);
- }
}
private static void runGcAndFinalizersSync() {
@@ -127,7 +80,7 @@ public class DebugTestInformationHandler extends TestInformationHandler {
}
@Override
- public Bundle call(String method, String arg, @Nullable Bundle extras) {
+ public Bundle call(String method) {
final Bundle response = new Bundle();
switch (method) {
case TestProtocol.REQUEST_APP_LIST_FREEZE_FLAGS: {
@@ -207,59 +160,8 @@ public class DebugTestInformationHandler extends TestInformationHandler {
}
}
- case TestProtocol.REQUEST_USE_TEST_WORKSPACE_LAYOUT: {
- useTestWorkspaceLayout(true);
- return response;
- }
-
- case TestProtocol.REQUEST_USE_DEFAULT_WORKSPACE_LAYOUT: {
- useTestWorkspaceLayout(false);
- return response;
- }
-
- case TestProtocol.REQUEST_HOTSEAT_ICON_NAMES: {
- return getLauncherUIProperty(Bundle::putStringArrayList, l -> {
- ShortcutAndWidgetContainer hotseatIconsContainer =
- l.getHotseat().getShortcutsAndWidgets();
- ArrayList<String> hotseatIconNames = new ArrayList<>();
-
- for (int i = 0; i < hotseatIconsContainer.getChildCount(); i++) {
- // Use unchecked cast to catch changes in hotseat layout
- BubbleTextView icon = (BubbleTextView) hotseatIconsContainer.getChildAt(i);
- hotseatIconNames.add((String) icon.getText());
- }
-
- return hotseatIconNames;
- });
- }
-
- case TestProtocol.REQUEST_GET_ACTIVITIES_CREATED_COUNT: {
- response.putInt(TestProtocol.TEST_INFO_RESPONSE_FIELD, sActivitiesCreatedCount);
- return response;
- }
-
- case TestProtocol.REQUEST_GET_ACTIVITIES: {
- response.putStringArray(TestProtocol.TEST_INFO_RESPONSE_FIELD,
- sActivities.keySet().stream().map(
- a -> a.getClass().getSimpleName() + " ("
- + (a.isDestroyed() ? "destroyed" : "current") + ")")
- .toArray(String[]::new));
- return response;
- }
-
default:
- return super.call(method, arg, extras);
- }
- }
-
- private void useTestWorkspaceLayout(boolean useTestWorkspaceLayout) {
- final long identity = Binder.clearCallingIdentity();
- try {
- LauncherSettings.Settings.call(mContext.getContentResolver(), useTestWorkspaceLayout
- ? LauncherSettings.Settings.METHOD_SET_USE_TEST_WORKSPACE_LAYOUT_FLAG
- : LauncherSettings.Settings.METHOD_CLEAR_USE_TEST_WORKSPACE_LAYOUT_FLAG);
- } finally {
- Binder.restoreCallingIdentity(identity);
+ return super.call(method);
}
}
}
diff --git a/fill_screens.py b/fill_screens.py
new file mode 100755
index 0000000000..a88779261e
--- /dev/null
+++ b/fill_screens.py
@@ -0,0 +1,90 @@
+#!/usr/bin/env python2.5
+
+import cgi
+import os
+import shutil
+import sys
+import sqlite3
+
+SCREENS = 5
+COLUMNS = 4
+ROWS = 4
+CELL_SIZE = 110
+
+DIR = "db_files"
+AUTO_FILE = "launcher.db"
+
+APPLICATION_COMPONENTS = [
+ "com.android.calculator2/com.android.calculator2.Calculator",
+ "com.android.providers.downloads.ui/com.android.providers.downloads.ui.DownloadList",
+ "com.android.settings/com.android.settings.Settings",
+ "com.android.mms/com.android.mms.ui.ConversationList",
+ "com.android.contacts/com.android.contacts.activities.PeopleActivity",
+ "com.android.dialer/com.android.dialer.DialtactsActivity"
+]
+
+def usage():
+ print "usage: fill_screens.py -- fills up the launcher db"
+
+
+def make_dir():
+ shutil.rmtree(DIR, True)
+ os.makedirs(DIR)
+
+def pull_file(fn):
+ print "pull_file: " + fn
+ rv = os.system("adb pull"
+ + " /data/data/com.android.launcher/databases/launcher.db"
+ + " " + fn);
+ if rv != 0:
+ print "adb pull failed"
+ sys.exit(1)
+
+def push_file(fn):
+ print "push_file: " + fn
+ rv = os.system("adb push"
+ + " " + fn
+ + " /data/data/com.android.launcher/databases/launcher.db")
+ if rv != 0:
+ print "adb push failed"
+ sys.exit(1)
+
+def process_file(fn):
+ print "process_file: " + fn
+ conn = sqlite3.connect(fn)
+ c = conn.cursor()
+ c.execute("DELETE FROM favorites")
+
+ intentFormat = "#Intent;action=android.intent.action.MAIN;category=android.intent.category.LAUNCHER;launchFlags=0x10200000;component=%s;end"
+
+ id = 0;
+ for s in range(SCREENS):
+ for x in range(ROWS):
+ for y in range(COLUMNS):
+ id += 1
+ insert = "INSERT into favorites (_id, title, intent, container, screen, cellX, cellY, spanX, spanY, itemType, appWidgetId, iconType) VALUES (%d, '%s', '%s', %d, %d, %d, %d, %d, %d, %d, %d, %d)"
+ insert = insert % (id, "title", "", -100, s, x, y, 1, 1, 2, -1, 0)
+ c.execute(insert)
+ folder_id = id
+
+ for z in range(15):
+ id += 1
+ intent = intentFormat % (APPLICATION_COMPONENTS[id % len(APPLICATION_COMPONENTS)])
+ insert = "INSERT into favorites (_id, title, intent, container, screen, cellX, cellY, spanX, spanY, itemType, appWidgetId, iconType) VALUES (%d, '%s', '%s', %d, %d, %d, %d, %d, %d, %d, %d, %d)"
+ insert = insert % (id, "title", intent, folder_id, 0, 0, 0, 1, 1, 0, -1, 0)
+ c.execute(insert)
+
+ conn.commit()
+ c.close()
+
+def main(argv):
+ if len(argv) == 1:
+ make_dir()
+ pull_file(AUTO_FILE)
+ process_file(AUTO_FILE)
+ push_file(AUTO_FILE)
+ else:
+ usage()
+
+if __name__=="__main__":
+ main(sys.argv)
diff --git a/go/AndroidManifest-launcher.xml b/go/AndroidManifest-launcher.xml
index 2223036a7a..6a8f715bb2 100644
--- a/go/AndroidManifest-launcher.xml
+++ b/go/AndroidManifest-launcher.xml
@@ -49,7 +49,7 @@
android:stateNotNeeded="true"
android:windowSoftInputMode="adjustPan"
android:screenOrientation="unspecified"
- android:configChanges="keyboard|keyboardHidden|mcc|mnc|navigation|orientation|screenSize|screenLayout|smallestScreenSize|uiMode"
+ android:configChanges="keyboard|keyboardHidden|mcc|mnc|navigation|orientation|screenSize|screenLayout|smallestScreenSize|density|uiMode"
android:resizeableActivity="true"
android:resumeWhilePausing="true"
android:taskAffinity=""
diff --git a/go/AndroidManifest.xml b/go/AndroidManifest.xml
index 728b3262f0..2671604f94 100644
--- a/go/AndroidManifest.xml
+++ b/go/AndroidManifest.xml
@@ -54,10 +54,6 @@
android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE"
android:enabled="false"
tools:node="replace" />
-
- <service
- android:name="com.android.launcher3.model.AppShareabilityJobService"
- android:permission="android.permission.BIND_JOB_SERVICE" />
</application>
</manifest>
diff --git a/go/quickstep/res/layout/overview_actions_container.xml b/go/quickstep/res/layout/overview_actions_container.xml
index 196541f0a9..0e718ca08d 100644
--- a/go/quickstep/res/layout/overview_actions_container.xml
+++ b/go/quickstep/res/layout/overview_actions_container.xml
@@ -14,11 +14,12 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
+<!-- NOTE! don't add dimensions for margins / gravity to root view in this file, they need to be
+ loaded at runtime. -->
<com.android.quickstep.views.GoOverviewActionsView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_gravity="center_horizontal|bottom">
+ android:layout_height="wrap_content">
<LinearLayout
android:id="@+id/action_buttons"
@@ -105,21 +106,14 @@
<!-- Unused. Included only for compatibility with parent class. -->
<Button
- android:id="@+id/action_split"
+ android:id="@+id/action_share"
style="@style/GoOverviewActionButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:drawableStart="@drawable/ic_split_screen"
- android:text="@string/action_split"
+ android:drawableStart="@drawable/ic_share"
+ android:text="@string/action_share"
android:theme="@style/ThemeControlHighlightWorkspaceColor"
android:visibility="gone" />
-
- <Space
- android:id="@+id/action_split_space"
- android:layout_width="0dp"
- android:layout_height="1dp"
- android:layout_weight="1"
- android:visibility="gone" />
</LinearLayout>
</com.android.quickstep.views.GoOverviewActionsView> \ No newline at end of file
diff --git a/go/quickstep/res/values-af/strings.xml b/go/quickstep/res/values-af/strings.xml
deleted file mode 100644
index 501d297a8d..0000000000
--- a/go/quickstep/res/values-af/strings.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_share_drop_target_label" msgid="5804774105974539508">"Deel program"</string>
- <string name="action_listen" msgid="2370304050784689486">"Luister"</string>
- <string name="action_translate" msgid="8028378961867277746">"Vertaal"</string>
- <string name="action_search" msgid="6269564710943755464">"Lens"</string>
- <string name="dialog_acknowledge" msgid="2804025517675853172">"HET DIT"</string>
- <string name="dialog_cancel" msgid="6464336969134856366">"KANSELLEER"</string>
- <string name="dialog_settings" msgid="6564397136021186148">"INSTELLINGS"</string>
- <string name="niu_actions_confirmation_title" msgid="3863451714863526143">"Vertaal of luister na teks op skerm"</string>
- <string name="niu_actions_confirmation_text" msgid="2105271481950866089">"Inligting soos teks op jou skerm, webadresse en skermskote kan met Google gedeel word.\n\nGaan na "<b>"Instellings &gt; Programme &gt; Verstekprogramme &gt; Digitale Assistent-program"</b>" om te verander watter inligting jy deel."</string>
- <string name="assistant_not_selected_title" msgid="5017072974603345228">"Kies \'n assistent om hierdie kenmerk te gebruik"</string>
- <string name="assistant_not_selected_text" msgid="3244613673884359276">"Kies \'n digitalebystandprogram in Instellings om na teks op jou skerm te luister of dit te vertaal"</string>
- <string name="assistant_not_supported_title" msgid="1675788067597484142">"Verander jou assistent om hierdie kenmerk te gebruik"</string>
- <string name="assistant_not_supported_text" msgid="1708031078549268884">"Verander jou digitalebystandprogram in Instellings om na teks op jou skerm te luister of dit te vertaal"</string>
- <string name="tooltip_listen" msgid="7634466447860989102">"Tik hier om na teks op hierdie skerm te luister"</string>
- <string name="tooltip_translate" msgid="4184845868901542567">"Tik hier om teks op hierdie skerm te vertaal"</string>
- <string name="toast_p2p_app_not_shareable" msgid="7229739094132131536">"Hierdie program kan nie gedeel word nie"</string>
-</resources>
diff --git a/go/quickstep/res/values-am/strings.xml b/go/quickstep/res/values-am/strings.xml
deleted file mode 100644
index 1bfaf66b99..0000000000
--- a/go/quickstep/res/values-am/strings.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_share_drop_target_label" msgid="5804774105974539508">"መተግበሪያን አጋራ"</string>
- <string name="action_listen" msgid="2370304050784689486">"ያዳምጡ"</string>
- <string name="action_translate" msgid="8028378961867277746">"ተርጉም"</string>
- <string name="action_search" msgid="6269564710943755464">"ሌንስ"</string>
- <string name="dialog_acknowledge" msgid="2804025517675853172">"ገባኝ"</string>
- <string name="dialog_cancel" msgid="6464336969134856366">"ይቅር"</string>
- <string name="dialog_settings" msgid="6564397136021186148">"ቅንብሮች"</string>
- <string name="niu_actions_confirmation_title" msgid="3863451714863526143">"በማያ ገጹ ላይ ጽሑፍን ይተረጉሙ ወይም ያዳምጡ"</string>
- <string name="niu_actions_confirmation_text" msgid="2105271481950866089">"እንደ በማያ ገጽዎ ላይ ያለ ጽሑፍ፣ የድር አድራሻዎች እና ቅጽበታዊ ገጽ እይታዎች ያሉ መረጃዎች ለGoogle ሊጋሩ ይችላሉ።\n\nምን መረጃ እንደሚያጋሩ ለመቀየር ወደ "<b>"ቅንብሮች &gt; መተግበሪያዎች &gt; ነባሪ መተግበሪያዎች &gt; ዲጂታል ረዳት መተግበሪያ"</b>" ይሂዱ።"</string>
- <string name="assistant_not_selected_title" msgid="5017072974603345228">"ይህንን ባህሪ ለመጠቀም ረዳት ይምረጡ"</string>
- <string name="assistant_not_selected_text" msgid="3244613673884359276">"በማያ ገጽዎ ላይ ጽሑፍን ለማዳመጥ ወይም ለመተርጎም በቅንብሮች ውስጥ የዲጂታል ረዳት መተግበሪያን ይምረጡ"</string>
- <string name="assistant_not_supported_title" msgid="1675788067597484142">"ይህንን ባህሪ ለመጠቀም ረዳትዎን ይቀይሩ"</string>
- <string name="assistant_not_supported_text" msgid="1708031078549268884">"በማያ ገጽዎ ላይ ጽሑፍን ለማዳመጥ ወይም ለመተርጎም በቅንብሮች ውስጥ የዲጂታል ረዳት መተግበሪያዎን ይቀይሩ"</string>
- <string name="tooltip_listen" msgid="7634466447860989102">"በዚህ ማያ ገጽ ላይ ጽሑፍ ለማዳመጥ እዚህ መታ ያድርጉ"</string>
- <string name="tooltip_translate" msgid="4184845868901542567">"በዚህ ማያ ገጽ ላይ ጽሑፍ ለመተርጎም እዚህ መታ ያድርጉ"</string>
- <string name="toast_p2p_app_not_shareable" msgid="7229739094132131536">"ይህ መተግበሪያ ሊጋራ አይችልም"</string>
-</resources>
diff --git a/go/quickstep/res/values-ar/strings.xml b/go/quickstep/res/values-ar/strings.xml
deleted file mode 100644
index e05ee5eda2..0000000000
--- a/go/quickstep/res/values-ar/strings.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_share_drop_target_label" msgid="5804774105974539508">"مشاركة التطبيق"</string>
- <string name="action_listen" msgid="2370304050784689486">"استماع"</string>
- <string name="action_translate" msgid="8028378961867277746">"‏ترجمة Google"</string>
- <string name="action_search" msgid="6269564710943755464">"‏عدسة Google"</string>
- <string name="dialog_acknowledge" msgid="2804025517675853172">"حسنًا"</string>
- <string name="dialog_cancel" msgid="6464336969134856366">"إلغاء"</string>
- <string name="dialog_settings" msgid="6564397136021186148">"الإعدادات"</string>
- <string name="niu_actions_confirmation_title" msgid="3863451714863526143">"ترجمة النص الظاهر على الشاشة أو الاستماع إليه"</string>
- <string name="niu_actions_confirmation_text" msgid="2105271481950866089">"‏قد تتم مشاركة معلومات مثل النص الظاهر على الشاشة وعناوين الويب ولقطات الشاشة مع Google.\n\nلتغيير المعلومات التي تتم مشاركتها، انتقِل إلى "<b>"الإعدادات &gt; التطبيقات &gt; التطبيقات التلقائية &gt; تطبيق المساعد الرقمي"</b>"."</string>
- <string name="assistant_not_selected_title" msgid="5017072974603345228">"اختيار مساعد لاستخدام هذه الميزة"</string>
- <string name="assistant_not_selected_text" msgid="3244613673884359276">"للاستماع للنص الظاهر على الشاشة أو ترجمته، اختَر تطبيق مساعد رقمي في الإعدادات."</string>
- <string name="assistant_not_supported_title" msgid="1675788067597484142">"تغيير المساعد لاستخدام هذه الميزة"</string>
- <string name="assistant_not_supported_text" msgid="1708031078549268884">"للاستماع للنص الظاهر على الشاشة أو ترجمته، عليك تغيير تطبيق المساعد الرقمي في الإعدادات."</string>
- <string name="tooltip_listen" msgid="7634466447860989102">"انقر هنا للاستماع للنص الظاهر على هذه الشاشة."</string>
- <string name="tooltip_translate" msgid="4184845868901542567">"انقر هنا لترجمة النص الظاهر على هذه الشاشة."</string>
- <string name="toast_p2p_app_not_shareable" msgid="7229739094132131536">"لا يمكن مشاركة هذا التطبيق."</string>
-</resources>
diff --git a/go/quickstep/res/values-as/strings.xml b/go/quickstep/res/values-as/strings.xml
deleted file mode 100644
index 8bf83efcd1..0000000000
--- a/go/quickstep/res/values-as/strings.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_share_drop_target_label" msgid="5804774105974539508">"এপ্‌ শ্বেয়াৰ কৰক"</string>
- <string name="action_listen" msgid="2370304050784689486">"শুনক"</string>
- <string name="action_translate" msgid="8028378961867277746">"অনুবাদ কৰক"</string>
- <string name="action_search" msgid="6269564710943755464">"লেন্স"</string>
- <string name="dialog_acknowledge" msgid="2804025517675853172">"বুজি পালোঁ"</string>
- <string name="dialog_cancel" msgid="6464336969134856366">"বাতিল কৰক"</string>
- <string name="dialog_settings" msgid="6564397136021186148">"ছেটিং"</string>
- <string name="niu_actions_confirmation_title" msgid="3863451714863526143">"স্ক্ৰীনত থকা পাঠ অনুবাদ কৰক অথবা শুনক"</string>
- <string name="niu_actions_confirmation_text" msgid="2105271481950866089">"আপোনাৰ স্ক্ৰীনত থকা পাঠ, ৱেব ঠিকনা আৰু স্ক্ৰীনশ্বটৰ দৰে তথ্য Googleৰ সৈতে হয়তো শ্বেয়াৰ কৰা হ’ব।\n\nআপুনি কোনসমুহ তথ্য শ্বেয়াৰ কৰিব সেয়া সলনি কৰিবলৈ, "<b>"ছেটিং &gt; এপ্‌ &gt; ডিফ’ল্ট এপ্‌ &gt; ডিজিটেল সহায়ক এপ"</b>"লৈ যাওক।"</string>
- <string name="assistant_not_selected_title" msgid="5017072974603345228">"এই সুবিধাটো ব্যৱহাৰ কৰিবলৈ এটা সহায়ক বাছনি কৰক"</string>
- <string name="assistant_not_selected_text" msgid="3244613673884359276">"আপোনাৰ স্ক্ৰীনত থকা পাঠ শুনিবলৈ অথবা সেই পাঠৰ অনুবাদ কৰিবলৈ, ছেটিঙত এটা ডিজিটেল সহায়ক এপ্‌ বাছনি কৰক"</string>
- <string name="assistant_not_supported_title" msgid="1675788067597484142">"এই সুবিধাটো ব্যৱহাৰ কৰিবলৈ আপোনাৰ সহায়ক সলনি কৰক"</string>
- <string name="assistant_not_supported_text" msgid="1708031078549268884">"আপোনাৰ স্ক্ৰীনত থকা পাঠ শুনিবলৈ অথবা সেই পাঠৰ অনুবাদ কৰিবলৈ, ছেটিঙত আপোনাৰ ডিজিটেল সহায়ক এপ্‌টো সলনি কৰক"</string>
- <string name="tooltip_listen" msgid="7634466447860989102">"এই স্ক্ৰীনখনত থকা পাঠ শুনিবলৈ ইয়াত টিপক"</string>
- <string name="tooltip_translate" msgid="4184845868901542567">"এই স্ক্ৰীনখনত থকা পাঠৰ অনুবাদ কৰিবলৈ ইয়াত টিপক"</string>
- <string name="toast_p2p_app_not_shareable" msgid="7229739094132131536">"এই এপ্‌টো শ্বেয়াৰ কৰিব নোৱাৰি"</string>
-</resources>
diff --git a/go/quickstep/res/values-az/strings.xml b/go/quickstep/res/values-az/strings.xml
deleted file mode 100644
index 2b03b1609f..0000000000
--- a/go/quickstep/res/values-az/strings.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_share_drop_target_label" msgid="5804774105974539508">"Tətbiqi paylaşın"</string>
- <string name="action_listen" msgid="2370304050784689486">"Dinləyin"</string>
- <string name="action_translate" msgid="8028378961867277746">"Tərcümə"</string>
- <string name="action_search" msgid="6269564710943755464">"Linza"</string>
- <string name="dialog_acknowledge" msgid="2804025517675853172">"ANLADIM"</string>
- <string name="dialog_cancel" msgid="6464336969134856366">"LƏĞV EDİN"</string>
- <string name="dialog_settings" msgid="6564397136021186148">"AYARLAR"</string>
- <string name="niu_actions_confirmation_title" msgid="3863451714863526143">"Ekrandakı mətni tərcümə edin və ya dinləyin"</string>
- <string name="niu_actions_confirmation_text" msgid="2105271481950866089">"Ekrandakı mətn, veb ünvanlar və ekran görüntüləri kimi məlumatlar Google ilə paylaşıla bilər.\n\nHansı məlumatların paylaşılmasını dəyişmək üçün "<b>"Ayarlar &gt; Tətbiqlər &gt; Defolt tətbiqlər &gt; Rəqəmsal assistent tətbiqi"</b>" bölməsinə keçin."</string>
- <string name="assistant_not_selected_title" msgid="5017072974603345228">"Bu funksiyadan istifadə etmək üçün assistenti seçin"</string>
- <string name="assistant_not_selected_text" msgid="3244613673884359276">"Ekrandakı mətni dinləmək və ya tərcümə etmək üçün Ayarlarda rəqəmsal assistent tətbiqini seçin"</string>
- <string name="assistant_not_supported_title" msgid="1675788067597484142">"Bu funksiyadan istifadə etmək üçün assistenti dəyişin"</string>
- <string name="assistant_not_supported_text" msgid="1708031078549268884">"Ekrandakı mətni dinləmək və ya tərcümə etmək üçün Ayarlarda rəqəmsal assistent tətbiqini dəyişin"</string>
- <string name="tooltip_listen" msgid="7634466447860989102">"Bu ekrandakı mətni dinləmək üçün buraya toxunun"</string>
- <string name="tooltip_translate" msgid="4184845868901542567">"Bu ekrandakı mətni tərcümə etmək üçün buraya toxunun"</string>
- <string name="toast_p2p_app_not_shareable" msgid="7229739094132131536">"Bu tətbiqi paylaşmaq mümkün deyil"</string>
-</resources>
diff --git a/go/quickstep/res/values-b+sr+Latn/strings.xml b/go/quickstep/res/values-b+sr+Latn/strings.xml
deleted file mode 100644
index 263f0118b0..0000000000
--- a/go/quickstep/res/values-b+sr+Latn/strings.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_share_drop_target_label" msgid="5804774105974539508">"Deli aplikaciju"</string>
- <string name="action_listen" msgid="2370304050784689486">"Pusti"</string>
- <string name="action_translate" msgid="8028378961867277746">"Prevedi"</string>
- <string name="action_search" msgid="6269564710943755464">"Objektiv"</string>
- <string name="dialog_acknowledge" msgid="2804025517675853172">"VAŽI"</string>
- <string name="dialog_cancel" msgid="6464336969134856366">"OTKAŽI"</string>
- <string name="dialog_settings" msgid="6564397136021186148">"PODEŠAVANJA"</string>
- <string name="niu_actions_confirmation_title" msgid="3863451714863526143">"Prevodite ili slušajte tekst na ekranu"</string>
- <string name="niu_actions_confirmation_text" msgid="2105271481950866089">"Informacije poput teksta na ekranu, veb-adresa i snimaka ekrana mogu da se dele sa Google-om.\n\nDa biste promenili informacije koje delite, idite u "<b>"Podešavanja &gt; Aplikacije &gt; Podrazumevane aplikacije &gt; Aplikacija digitalnog pomoćnika"</b>"."</string>
- <string name="assistant_not_selected_title" msgid="5017072974603345228">"Odaberite pomoćnika da biste koristili ovu funkciju"</string>
- <string name="assistant_not_selected_text" msgid="3244613673884359276">"Da biste čuli tekst sa ekrana ili ga preveli, odaberite aplikaciju digitalnog pomoćnika u Podešavanjima"</string>
- <string name="assistant_not_supported_title" msgid="1675788067597484142">"Promenite pomoćnika da biste koristili ovu funkciju"</string>
- <string name="assistant_not_supported_text" msgid="1708031078549268884">"Da biste čuli tekst sa ekrana ili ga preveli, promenite aplikaciju digitalnog pomoćnika u Podešavanjima"</string>
- <string name="tooltip_listen" msgid="7634466447860989102">"Dodirnite ovde da biste čuli tekst sa ovog ekrana"</string>
- <string name="tooltip_translate" msgid="4184845868901542567">"Dodirnite ovde da biste preveli tekst sa ovog ekrana"</string>
- <string name="toast_p2p_app_not_shareable" msgid="7229739094132131536">"Ova aplikacija ne može da se deli"</string>
-</resources>
diff --git a/go/quickstep/res/values-be/strings.xml b/go/quickstep/res/values-be/strings.xml
deleted file mode 100644
index 83374bb397..0000000000
--- a/go/quickstep/res/values-be/strings.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_share_drop_target_label" msgid="5804774105974539508">"Абагуліць праграму"</string>
- <string name="action_listen" msgid="2370304050784689486">"Праслухаць"</string>
- <string name="action_translate" msgid="8028378961867277746">"Перакласці"</string>
- <string name="action_search" msgid="6269564710943755464">"Аб\'ектыў"</string>
- <string name="dialog_acknowledge" msgid="2804025517675853172">"ЗРАЗУМЕЛА"</string>
- <string name="dialog_cancel" msgid="6464336969134856366">"СКАСАВАЦЬ"</string>
- <string name="dialog_settings" msgid="6564397136021186148">"НАЛАДЫ"</string>
- <string name="niu_actions_confirmation_title" msgid="3863451714863526143">"Перакласці ці праслухаць тэкст на экране"</string>
- <string name="niu_actions_confirmation_text" msgid="2105271481950866089">"Такая інфармацыя з вашага экрана, як тэксты, вэб-адрасы і здымкі экрана, можа абагульвацца з Google.\n\nКаб змяніць тып інфармацыі для абагульвання, адкрыйце "<b>"Налады &gt; Праграмы &gt; Стандартныя праграмы &gt; Лічбавы памочнік"</b>"."</string>
- <string name="assistant_not_selected_title" msgid="5017072974603345228">"Для карыстання гэтай функцыяй выберыце памочніка"</string>
- <string name="assistant_not_selected_text" msgid="3244613673884359276">"Каб праслухаць або перакласці тэкст на экране, выберыце ў Наладах лічбавага памочніка"</string>
- <string name="assistant_not_supported_title" msgid="1675788067597484142">"Для карыстання гэтай функцыяй змяніце памочніка"</string>
- <string name="assistant_not_supported_text" msgid="1708031078549268884">"Каб праслухаць ці перакласці тэкст на экране, змяніце ў Наладах лічбавага памочніка"</string>
- <string name="tooltip_listen" msgid="7634466447860989102">"Націсніце тут, каб праслухаць тэкст на экране"</string>
- <string name="tooltip_translate" msgid="4184845868901542567">"Націсніце тут, каб перакласці тэкст на экране"</string>
- <string name="toast_p2p_app_not_shareable" msgid="7229739094132131536">"Не ўдалося абагуліць гэту праграму"</string>
-</resources>
diff --git a/go/quickstep/res/values-bg/strings.xml b/go/quickstep/res/values-bg/strings.xml
deleted file mode 100644
index 594189893e..0000000000
--- a/go/quickstep/res/values-bg/strings.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_share_drop_target_label" msgid="5804774105974539508">"Споделяне на прилож."</string>
- <string name="action_listen" msgid="2370304050784689486">"Слушане"</string>
- <string name="action_translate" msgid="8028378961867277746">"Превод"</string>
- <string name="action_search" msgid="6269564710943755464">"Обектив"</string>
- <string name="dialog_acknowledge" msgid="2804025517675853172">"РАЗБРАХ"</string>
- <string name="dialog_cancel" msgid="6464336969134856366">"ОТКАЗ"</string>
- <string name="dialog_settings" msgid="6564397136021186148">"НАСТРОЙКИ"</string>
- <string name="niu_actions_confirmation_title" msgid="3863451714863526143">"Превеждане или четене на текста на екрана"</string>
- <string name="niu_actions_confirmation_text" msgid="2105271481950866089">"Определена информация може да бъде споделена с Google, като например текстът на екрана ви, уеб адресите и екранните снимки.\n\nЗа да промените информацията, която споделяте, отворете "<b>"„Настройки“ &gt; „Приложения“ &gt; „Приложения по подразбиране“ &gt; „Приложение за дигитален асистент“"</b>"."</string>
- <string name="assistant_not_selected_title" msgid="5017072974603345228">"Изберете приложение за асистент, за да използвате тази функция"</string>
- <string name="assistant_not_selected_text" msgid="3244613673884359276">"За да слушате или превеждате текст на екрана си, от настройките изберете приложение за дигитален асистент"</string>
- <string name="assistant_not_supported_title" msgid="1675788067597484142">"Изберете приложение за асистент, за да използвате тази функция"</string>
- <string name="assistant_not_supported_text" msgid="1708031078549268884">"За да слушате или превеждате текст на екрана си, от настройките променете приложението си за дигитален асистент"</string>
- <string name="tooltip_listen" msgid="7634466447860989102">"Докоснете тук, за да слушате текста на този екран"</string>
- <string name="tooltip_translate" msgid="4184845868901542567">"Докоснете тук, за да преведете текста на този екран"</string>
- <string name="toast_p2p_app_not_shareable" msgid="7229739094132131536">"Това приложение не може да бъде споделено"</string>
-</resources>
diff --git a/go/quickstep/res/values-bn/strings.xml b/go/quickstep/res/values-bn/strings.xml
deleted file mode 100644
index 60671912c8..0000000000
--- a/go/quickstep/res/values-bn/strings.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_share_drop_target_label" msgid="5804774105974539508">"অ্যাপ শেয়ার করুন"</string>
- <string name="action_listen" msgid="2370304050784689486">"শুনুন"</string>
- <string name="action_translate" msgid="8028378961867277746">"অনুবাদ করুন"</string>
- <string name="action_search" msgid="6269564710943755464">"লেন্স"</string>
- <string name="dialog_acknowledge" msgid="2804025517675853172">"বুঝেছি"</string>
- <string name="dialog_cancel" msgid="6464336969134856366">"বাতিল করুন"</string>
- <string name="dialog_settings" msgid="6564397136021186148">"সেটিংস"</string>
- <string name="niu_actions_confirmation_title" msgid="3863451714863526143">"অনুবাদ করুন বা স্ক্রিনে দেখানো টেক্সট শুনুন"</string>
- <string name="niu_actions_confirmation_text" msgid="2105271481950866089">"আপনার স্ক্রিনে থাকা তথ্য যেমন ওয়েব ঠিকানা এবং স্ক্রিনশট Google-এর সাথে শেয়ার করা হতে পারে।\n\nকোন কোন তথ্য শেয়ার করবেন তা বেছে নিতে, "<b>"সেটিংস &gt; অ্যাপ &gt; ডিফল্ট অ্যাপ &gt; ডিজিটাল অ্যাসিস্ট্যান্ট অ্যাপ"</b>" বিকল্পগুলি বেছে নিন।"</string>
- <string name="assistant_not_selected_title" msgid="5017072974603345228">"এই ফিচার ব্যবহার করতে অ্যাসিস্ট্যান্ট বেছে নিন"</string>
- <string name="assistant_not_selected_text" msgid="3244613673884359276">"আপনার স্ক্রিনে থাকা টেক্সট শুনতে বা অনুবাদ করতে, সেটিংস থেকে ডিজিটাল অ্যাসিস্ট্যান্ট অ্যাপ বেছে নিন"</string>
- <string name="assistant_not_supported_title" msgid="1675788067597484142">"এই ফিচার ব্যবহার করতে অ্যাসিস্ট্যান্ট পরিবর্তন করুন"</string>
- <string name="assistant_not_supported_text" msgid="1708031078549268884">"আপনার স্ক্রিনে থাকা টেক্সট শুনতে বা অনুবাদ করতে, সেটিংস থেকে ডিজিটাল অ্যাসিস্ট্যান্ট অ্যাপ পরিবর্তন করুন"</string>
- <string name="tooltip_listen" msgid="7634466447860989102">"স্ক্রিনে থাকা টেক্সট শুনতে এখানে ট্যাপ করুন"</string>
- <string name="tooltip_translate" msgid="4184845868901542567">"স্ক্রিনে থাকা টেক্সট অনুবাদ করতে এখানে ট্যাপ করুন"</string>
- <string name="toast_p2p_app_not_shareable" msgid="7229739094132131536">"এই অ্যাপ শেয়ার করা যাবে না"</string>
-</resources>
diff --git a/go/quickstep/res/values-bs/strings.xml b/go/quickstep/res/values-bs/strings.xml
deleted file mode 100644
index 7db34ae921..0000000000
--- a/go/quickstep/res/values-bs/strings.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_share_drop_target_label" msgid="5804774105974539508">"Dijeli aplikaciju"</string>
- <string name="action_listen" msgid="2370304050784689486">"Poslušajte"</string>
- <string name="action_translate" msgid="8028378961867277746">"Prevedi"</string>
- <string name="action_search" msgid="6269564710943755464">"Objektiv"</string>
- <string name="dialog_acknowledge" msgid="2804025517675853172">"RAZUMIJEM"</string>
- <string name="dialog_cancel" msgid="6464336969134856366">"OTKAŽI"</string>
- <string name="dialog_settings" msgid="6564397136021186148">"POSTAVKE"</string>
- <string name="niu_actions_confirmation_title" msgid="3863451714863526143">"Prevedite ili slušajte tekst na ekranu"</string>
- <string name="niu_actions_confirmation_text" msgid="2105271481950866089">"Informacije kao što su tekst na ekranu, web adrese i snimci ekrana mogu se dijeliti s Googleom.\n\nDa promijenite koje informacije dijelite, idite u "<b>"Postavke &gt; Aplikacije &gt; Zadane aplikacije &gt; Aplikacija digitalnog asistenta"</b>"."</string>
- <string name="assistant_not_selected_title" msgid="5017072974603345228">"Odaberite asistenta da koristite ovu funkciju"</string>
- <string name="assistant_not_selected_text" msgid="3244613673884359276">"Da slušate ili prevedete tekst na ekranu, odaberite aplikaciju digitalnog asistenta u Postavkama"</string>
- <string name="assistant_not_supported_title" msgid="1675788067597484142">"Promijenite asistenta da koristite ovu funkciju"</string>
- <string name="assistant_not_supported_text" msgid="1708031078549268884">"Da slušate ili prevedete tekst na ekranu, promijenite aplikaciju digitalnog asistenta u Postavkama"</string>
- <string name="tooltip_listen" msgid="7634466447860989102">"Dodirnite ovdje da slušate tekst na ovom ekranu"</string>
- <string name="tooltip_translate" msgid="4184845868901542567">"Dodirnite ovdje da prevedete tekst na ovom ekranu"</string>
- <string name="toast_p2p_app_not_shareable" msgid="7229739094132131536">"Nije moguće dijeliti ovu aplikaciju"</string>
-</resources>
diff --git a/go/quickstep/res/values-ca/strings.xml b/go/quickstep/res/values-ca/strings.xml
deleted file mode 100644
index 889f50eec0..0000000000
--- a/go/quickstep/res/values-ca/strings.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_share_drop_target_label" msgid="5804774105974539508">"Comparteix aplicació"</string>
- <string name="action_listen" msgid="2370304050784689486">"Escolta"</string>
- <string name="action_translate" msgid="8028378961867277746">"Tradueix"</string>
- <string name="action_search" msgid="6269564710943755464">"Lens"</string>
- <string name="dialog_acknowledge" msgid="2804025517675853172">"ENTESOS"</string>
- <string name="dialog_cancel" msgid="6464336969134856366">"CANCEL·LA"</string>
- <string name="dialog_settings" msgid="6564397136021186148">"CONFIGURACIÓ"</string>
- <string name="niu_actions_confirmation_title" msgid="3863451714863526143">"Tradueix o escolta el text en pantalla"</string>
- <string name="niu_actions_confirmation_text" msgid="2105271481950866089">"És possible que determinada informació es comparteixi amb Google, com ara el text en pantalla, les adreces web i les captures de pantalla.\n\nPer canviar quina informació comparteixes, ves a "<b>"Configuració &gt; Aplicacions &gt; Aplicacions predeterminades &gt; Aplicació de l\'assistent digital"</b>"."</string>
- <string name="assistant_not_selected_title" msgid="5017072974603345228">"Tria un assistent per utilitzar aquesta funció"</string>
- <string name="assistant_not_selected_text" msgid="3244613673884359276">"Per escoltar o traduir text en pantalla, tria una aplicació d\'assistent digital a Configuració"</string>
- <string name="assistant_not_supported_title" msgid="1675788067597484142">"Canvia l\'assistent per utilitzar aquesta funció"</string>
- <string name="assistant_not_supported_text" msgid="1708031078549268884">"Per escoltar o traduir text en pantalla, canvia l\'aplicació d\'assistent digital a Configuració"</string>
- <string name="tooltip_listen" msgid="7634466447860989102">"Toca aquí per escoltar text en pantalla"</string>
- <string name="tooltip_translate" msgid="4184845868901542567">"Toca aquí per traduir text en pantalla"</string>
- <string name="toast_p2p_app_not_shareable" msgid="7229739094132131536">"Aquesta aplicació o es pot compartir"</string>
-</resources>
diff --git a/go/quickstep/res/values-cs/strings.xml b/go/quickstep/res/values-cs/strings.xml
deleted file mode 100644
index b569dfcaaa..0000000000
--- a/go/quickstep/res/values-cs/strings.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_share_drop_target_label" msgid="5804774105974539508">"Sdílet aplikaci"</string>
- <string name="action_listen" msgid="2370304050784689486">"Poslechnout"</string>
- <string name="action_translate" msgid="8028378961867277746">"Přeložit"</string>
- <string name="action_search" msgid="6269564710943755464">"Lens"</string>
- <string name="dialog_acknowledge" msgid="2804025517675853172">"ROZUMÍM"</string>
- <string name="dialog_cancel" msgid="6464336969134856366">"ZRUŠIT"</string>
- <string name="dialog_settings" msgid="6564397136021186148">"NASTAVENÍ"</string>
- <string name="niu_actions_confirmation_title" msgid="3863451714863526143">"Překládejte nebo poslouchejte text na obrazovce"</string>
- <string name="niu_actions_confirmation_text" msgid="2105271481950866089">"S Googlem mohou být sdílena data, jako je text na obrazovce, webové adresy a snímky obrazovky.\n\nSdílená data můžete upřesnit v "<b>"Nastavení &gt; Aplikace &gt; Výchozí aplikace &gt; Aplikace digitálního asistenta"</b>"."</string>
- <string name="assistant_not_selected_title" msgid="5017072974603345228">"Pokud chcete použít tuto funkci, vyberte asistenta"</string>
- <string name="assistant_not_selected_text" msgid="3244613673884359276">"Pokud si chcete poslechnout nebo přeložit text na obrazovce, v Nastavení vyberte aplikaci digitálního asistenta"</string>
- <string name="assistant_not_supported_title" msgid="1675788067597484142">"Pokud chcete použít tuto funkci, změňte asistenta"</string>
- <string name="assistant_not_supported_text" msgid="1708031078549268884">"Pokud si chcete poslechnout nebo přeložit text na obrazovce, v Nastavení změňte aplikaci digitálního asistenta"</string>
- <string name="tooltip_listen" msgid="7634466447860989102">"Klepnutím sem si poslechnete text na této obrazovce"</string>
- <string name="tooltip_translate" msgid="4184845868901542567">"Klepnutím sem přeložíte text na této obrazovce"</string>
- <string name="toast_p2p_app_not_shareable" msgid="7229739094132131536">"Tuto aplikaci nelze sdílet"</string>
-</resources>
diff --git a/go/quickstep/res/values-da/strings.xml b/go/quickstep/res/values-da/strings.xml
deleted file mode 100644
index 8f2055bf81..0000000000
--- a/go/quickstep/res/values-da/strings.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_share_drop_target_label" msgid="5804774105974539508">"Del app"</string>
- <string name="action_listen" msgid="2370304050784689486">"Lyt"</string>
- <string name="action_translate" msgid="8028378961867277746">"Oversæt"</string>
- <string name="action_search" msgid="6269564710943755464">"Lens"</string>
- <string name="dialog_acknowledge" msgid="2804025517675853172">"OK"</string>
- <string name="dialog_cancel" msgid="6464336969134856366">"ANNULLER"</string>
- <string name="dialog_settings" msgid="6564397136021186148">"INDSTILLINGER"</string>
- <string name="niu_actions_confirmation_title" msgid="3863451714863526143">"Oversæt eller hør tekst på skærmen"</string>
- <string name="niu_actions_confirmation_text" msgid="2105271481950866089">"Oplysninger såsom tekst på din skærm, webadresser og screenshots deles muligvis med Google.\n\nHvis du vil ændre, hvilke oplysninger du deler, kan du gå til "<b>"Indstillinger &gt; Apps &gt; Standardapps &gt; App for digital assistent"</b>"."</string>
- <string name="assistant_not_selected_title" msgid="5017072974603345228">"Vælg en assistent for at bruge denne funktion"</string>
- <string name="assistant_not_selected_text" msgid="3244613673884359276">"Hvis du vil høre eller oversætte tekst på din skærm, skal du vælge en digital assistent i Indstillinger"</string>
- <string name="assistant_not_supported_title" msgid="1675788067597484142">"Skift assistent for at bruge denne funktion"</string>
- <string name="assistant_not_supported_text" msgid="1708031078549268884">"Hvis du vil høre eller oversætte tekst på din skærm, skal du ændre din digitale assistent i Indstillinger"</string>
- <string name="tooltip_listen" msgid="7634466447860989102">"Tryk her for at høre teksten på denne skærm"</string>
- <string name="tooltip_translate" msgid="4184845868901542567">"Tryk her for at oversætte teksten på denne skærm"</string>
- <string name="toast_p2p_app_not_shareable" msgid="7229739094132131536">"Denne app kan ikke deles"</string>
-</resources>
diff --git a/go/quickstep/res/values-de/strings.xml b/go/quickstep/res/values-de/strings.xml
deleted file mode 100644
index efc11c94be..0000000000
--- a/go/quickstep/res/values-de/strings.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_share_drop_target_label" msgid="5804774105974539508">"App teilen"</string>
- <string name="action_listen" msgid="2370304050784689486">"Anhören"</string>
- <string name="action_translate" msgid="8028378961867277746">"Übersetzen"</string>
- <string name="action_search" msgid="6269564710943755464">"Lens"</string>
- <string name="dialog_acknowledge" msgid="2804025517675853172">"OK"</string>
- <string name="dialog_cancel" msgid="6464336969134856366">"ABBRECHEN"</string>
- <string name="dialog_settings" msgid="6564397136021186148">"EINSTELLUNGEN"</string>
- <string name="niu_actions_confirmation_title" msgid="3863451714863526143">"Text auf dem Bildschirm übersetzen oder anhören"</string>
- <string name="niu_actions_confirmation_text" msgid="2105271481950866089">"Informationen, wie Text auf deinem Bildschirm, Webadressen und Screenshots, werden möglicherweise an Google weitergegeben.\n\nWenn du ändern möchtest, welche Informationen weitergegeben werden, gehe zu "<b>"Einstellungen &gt; Apps &gt; Standard-Apps &gt; App für digitalen Assistenten"</b>"."</string>
- <string name="assistant_not_selected_title" msgid="5017072974603345228">"Assistenten auswählen, um diese Funktion zu nutzen"</string>
- <string name="assistant_not_selected_text" msgid="3244613673884359276">"Wenn du dir auf deinem Display Text anhören oder übersetzen lassen möchtest, wähle in den Einstellungen eine App für einen digitalen Assistenten"</string>
- <string name="assistant_not_supported_title" msgid="1675788067597484142">"Assistenten ändern, um diese Funktion zu nutzen"</string>
- <string name="assistant_not_supported_text" msgid="1708031078549268884">"Wenn du dir auf deinem Display Text anhören oder übersetzen lassen möchtest, ändere in den Einstellungen deine App für den digitalen Assistenten"</string>
- <string name="tooltip_listen" msgid="7634466447860989102">"Hier tippen, um dir Text auf diesem Display anzuhören"</string>
- <string name="tooltip_translate" msgid="4184845868901542567">"Hier tippen, um dir Text auf diesem Display übersetzen zu lassen"</string>
- <string name="toast_p2p_app_not_shareable" msgid="7229739094132131536">"Diese App kann nicht gemeinsam genutzt werden"</string>
-</resources>
diff --git a/go/quickstep/res/values-el/strings.xml b/go/quickstep/res/values-el/strings.xml
deleted file mode 100644
index 9a67420f30..0000000000
--- a/go/quickstep/res/values-el/strings.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_share_drop_target_label" msgid="5804774105974539508">"Κοινή χρήση εφαρμογ."</string>
- <string name="action_listen" msgid="2370304050784689486">"Ακρόαση"</string>
- <string name="action_translate" msgid="8028378961867277746">"Μετάφραση"</string>
- <string name="action_search" msgid="6269564710943755464">"Lens"</string>
- <string name="dialog_acknowledge" msgid="2804025517675853172">"ΤΟ ΚΑΤΑΛΑΒΑ"</string>
- <string name="dialog_cancel" msgid="6464336969134856366">"ΑΚΥΡΩΣΗ"</string>
- <string name="dialog_settings" msgid="6564397136021186148">"ΡΥΘΜΙΣΕΙΣ"</string>
- <string name="niu_actions_confirmation_title" msgid="3863451714863526143">"Μετάφραση ή ακρόαση του κειμένου στην οθόνη"</string>
- <string name="niu_actions_confirmation_text" msgid="2105271481950866089">"Πληροφορίες όπως είναι το κείμενο στην οθόνη, οι διευθύνσεις ιστού και τα στιγμιότυπα οθόνης, ενδέχεται να κοινοποιηθούν στην Google.\n\nΓια να αλλάξετε τις πληροφορίες που κοινοποιείτε, μεταβείτε στις "<b>"Ρυθμίσεις &gt; Εφαρμογές &gt; Προεπιλεγμένες εφαρμογές &gt; Εφαρμογή ψηφιακού βοηθού"</b>"."</string>
- <string name="assistant_not_selected_title" msgid="5017072974603345228">"Επιλέξτε έναν βοηθό για να χρησιμοποιήσετε αυτήν τη λειτουργία"</string>
- <string name="assistant_not_selected_text" msgid="3244613673884359276">"Για να ακούσετε ή να μεταφράσετε κείμενο στην οθόνη σας, επιλέξτε μια εφαρμογή ψηφιακού βοηθού στις Ρυθμίσεις."</string>
- <string name="assistant_not_supported_title" msgid="1675788067597484142">"Αλλάξτε τον βοηθό σας για να χρησιμοποιήσετε αυτήν τη λειτουργία"</string>
- <string name="assistant_not_supported_text" msgid="1708031078549268884">"Για να ακούσετε ή να μεταφράσετε κείμενο στην οθόνη σας, αλλάξτε την εφαρμογή ψηφιακού βοηθού στις Ρυθμίσεις."</string>
- <string name="tooltip_listen" msgid="7634466447860989102">"Πατήστε εδώ για να ακούσετε το κείμενο σε αυτήν την οθόνη"</string>
- <string name="tooltip_translate" msgid="4184845868901542567">"Πατήστε εδώ για να μεταφράσετε το κείμενο σε αυτήν την οθόνη"</string>
- <string name="toast_p2p_app_not_shareable" msgid="7229739094132131536">"Δεν είναι δυνατή η κοινή χρήση της εφαρμογής"</string>
-</resources>
diff --git a/go/quickstep/res/values-en-rAU/strings.xml b/go/quickstep/res/values-en-rAU/strings.xml
deleted file mode 100644
index 676ac43284..0000000000
--- a/go/quickstep/res/values-en-rAU/strings.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_share_drop_target_label" msgid="5804774105974539508">"Share app"</string>
- <string name="action_listen" msgid="2370304050784689486">"Listen"</string>
- <string name="action_translate" msgid="8028378961867277746">"Translate"</string>
- <string name="action_search" msgid="6269564710943755464">"Lens"</string>
- <string name="dialog_acknowledge" msgid="2804025517675853172">"OK"</string>
- <string name="dialog_cancel" msgid="6464336969134856366">"CANCEL"</string>
- <string name="dialog_settings" msgid="6564397136021186148">"SETTINGS"</string>
- <string name="niu_actions_confirmation_title" msgid="3863451714863526143">"Translate or listen to text on screen"</string>
- <string name="niu_actions_confirmation_text" msgid="2105271481950866089">"Information such as text on your screen, web addresses and screenshots may be shared with Google.\n\nTo change what information you share, go to "<b>"Settings &gt; Apps &gt; Default apps &gt; Digital assistant app"</b>"."</string>
- <string name="assistant_not_selected_title" msgid="5017072974603345228">"Choose an assistant to use this feature"</string>
- <string name="assistant_not_selected_text" msgid="3244613673884359276">"To listen to or translate text on your screen, choose a digital assistant app in settings"</string>
- <string name="assistant_not_supported_title" msgid="1675788067597484142">"Change your assistant to use this feature"</string>
- <string name="assistant_not_supported_text" msgid="1708031078549268884">"To listen to or translate text on your screen, change your digital assistant app in settings"</string>
- <string name="tooltip_listen" msgid="7634466447860989102">"Tap here to listen to text on this screen"</string>
- <string name="tooltip_translate" msgid="4184845868901542567">"Tap here to translate text on this screen"</string>
- <string name="toast_p2p_app_not_shareable" msgid="7229739094132131536">"This app can’t be shared"</string>
-</resources>
diff --git a/go/quickstep/res/values-en-rCA/strings.xml b/go/quickstep/res/values-en-rCA/strings.xml
deleted file mode 100644
index 676ac43284..0000000000
--- a/go/quickstep/res/values-en-rCA/strings.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_share_drop_target_label" msgid="5804774105974539508">"Share app"</string>
- <string name="action_listen" msgid="2370304050784689486">"Listen"</string>
- <string name="action_translate" msgid="8028378961867277746">"Translate"</string>
- <string name="action_search" msgid="6269564710943755464">"Lens"</string>
- <string name="dialog_acknowledge" msgid="2804025517675853172">"OK"</string>
- <string name="dialog_cancel" msgid="6464336969134856366">"CANCEL"</string>
- <string name="dialog_settings" msgid="6564397136021186148">"SETTINGS"</string>
- <string name="niu_actions_confirmation_title" msgid="3863451714863526143">"Translate or listen to text on screen"</string>
- <string name="niu_actions_confirmation_text" msgid="2105271481950866089">"Information such as text on your screen, web addresses and screenshots may be shared with Google.\n\nTo change what information you share, go to "<b>"Settings &gt; Apps &gt; Default apps &gt; Digital assistant app"</b>"."</string>
- <string name="assistant_not_selected_title" msgid="5017072974603345228">"Choose an assistant to use this feature"</string>
- <string name="assistant_not_selected_text" msgid="3244613673884359276">"To listen to or translate text on your screen, choose a digital assistant app in settings"</string>
- <string name="assistant_not_supported_title" msgid="1675788067597484142">"Change your assistant to use this feature"</string>
- <string name="assistant_not_supported_text" msgid="1708031078549268884">"To listen to or translate text on your screen, change your digital assistant app in settings"</string>
- <string name="tooltip_listen" msgid="7634466447860989102">"Tap here to listen to text on this screen"</string>
- <string name="tooltip_translate" msgid="4184845868901542567">"Tap here to translate text on this screen"</string>
- <string name="toast_p2p_app_not_shareable" msgid="7229739094132131536">"This app can’t be shared"</string>
-</resources>
diff --git a/go/quickstep/res/values-en-rGB/strings.xml b/go/quickstep/res/values-en-rGB/strings.xml
deleted file mode 100644
index 676ac43284..0000000000
--- a/go/quickstep/res/values-en-rGB/strings.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_share_drop_target_label" msgid="5804774105974539508">"Share app"</string>
- <string name="action_listen" msgid="2370304050784689486">"Listen"</string>
- <string name="action_translate" msgid="8028378961867277746">"Translate"</string>
- <string name="action_search" msgid="6269564710943755464">"Lens"</string>
- <string name="dialog_acknowledge" msgid="2804025517675853172">"OK"</string>
- <string name="dialog_cancel" msgid="6464336969134856366">"CANCEL"</string>
- <string name="dialog_settings" msgid="6564397136021186148">"SETTINGS"</string>
- <string name="niu_actions_confirmation_title" msgid="3863451714863526143">"Translate or listen to text on screen"</string>
- <string name="niu_actions_confirmation_text" msgid="2105271481950866089">"Information such as text on your screen, web addresses and screenshots may be shared with Google.\n\nTo change what information you share, go to "<b>"Settings &gt; Apps &gt; Default apps &gt; Digital assistant app"</b>"."</string>
- <string name="assistant_not_selected_title" msgid="5017072974603345228">"Choose an assistant to use this feature"</string>
- <string name="assistant_not_selected_text" msgid="3244613673884359276">"To listen to or translate text on your screen, choose a digital assistant app in settings"</string>
- <string name="assistant_not_supported_title" msgid="1675788067597484142">"Change your assistant to use this feature"</string>
- <string name="assistant_not_supported_text" msgid="1708031078549268884">"To listen to or translate text on your screen, change your digital assistant app in settings"</string>
- <string name="tooltip_listen" msgid="7634466447860989102">"Tap here to listen to text on this screen"</string>
- <string name="tooltip_translate" msgid="4184845868901542567">"Tap here to translate text on this screen"</string>
- <string name="toast_p2p_app_not_shareable" msgid="7229739094132131536">"This app can’t be shared"</string>
-</resources>
diff --git a/go/quickstep/res/values-en-rIN/strings.xml b/go/quickstep/res/values-en-rIN/strings.xml
deleted file mode 100644
index 676ac43284..0000000000
--- a/go/quickstep/res/values-en-rIN/strings.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_share_drop_target_label" msgid="5804774105974539508">"Share app"</string>
- <string name="action_listen" msgid="2370304050784689486">"Listen"</string>
- <string name="action_translate" msgid="8028378961867277746">"Translate"</string>
- <string name="action_search" msgid="6269564710943755464">"Lens"</string>
- <string name="dialog_acknowledge" msgid="2804025517675853172">"OK"</string>
- <string name="dialog_cancel" msgid="6464336969134856366">"CANCEL"</string>
- <string name="dialog_settings" msgid="6564397136021186148">"SETTINGS"</string>
- <string name="niu_actions_confirmation_title" msgid="3863451714863526143">"Translate or listen to text on screen"</string>
- <string name="niu_actions_confirmation_text" msgid="2105271481950866089">"Information such as text on your screen, web addresses and screenshots may be shared with Google.\n\nTo change what information you share, go to "<b>"Settings &gt; Apps &gt; Default apps &gt; Digital assistant app"</b>"."</string>
- <string name="assistant_not_selected_title" msgid="5017072974603345228">"Choose an assistant to use this feature"</string>
- <string name="assistant_not_selected_text" msgid="3244613673884359276">"To listen to or translate text on your screen, choose a digital assistant app in settings"</string>
- <string name="assistant_not_supported_title" msgid="1675788067597484142">"Change your assistant to use this feature"</string>
- <string name="assistant_not_supported_text" msgid="1708031078549268884">"To listen to or translate text on your screen, change your digital assistant app in settings"</string>
- <string name="tooltip_listen" msgid="7634466447860989102">"Tap here to listen to text on this screen"</string>
- <string name="tooltip_translate" msgid="4184845868901542567">"Tap here to translate text on this screen"</string>
- <string name="toast_p2p_app_not_shareable" msgid="7229739094132131536">"This app can’t be shared"</string>
-</resources>
diff --git a/go/quickstep/res/values-en-rXC/strings.xml b/go/quickstep/res/values-en-rXC/strings.xml
deleted file mode 100644
index b6a4021af9..0000000000
--- a/go/quickstep/res/values-en-rXC/strings.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_share_drop_target_label" msgid="5804774105974539508">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‎‏‎‎‎‎‏‎‎‎‏‏‏‎‏‎‏‏‎‎‏‏‎‏‎‎‏‎‏‏‎‏‎‏‏‎‏‏‏‏‏‏‏‏‏‏‏‎‎‎‎‏‎‎‏‏‏‏‎‏‎‎‎Share App‎‏‎‎‏‎"</string>
- <string name="action_listen" msgid="2370304050784689486">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‎‎‎‎‎‏‏‏‎‎‏‎‏‎‎‎‎‎‎‏‎‏‏‏‏‏‎‎‏‏‏‎‎‏‏‎‎‏‎‏‏‎‎‎‎‏‏‎‏‏‏‎‏‎‏‎‎‏‏‏‎‎Listen‎‏‎‎‏‎"</string>
- <string name="action_translate" msgid="8028378961867277746">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‏‎‏‏‏‏‎‏‏‎‏‎‏‎‏‎‎‎‏‎‎‎‎‎‏‎‎‎‎‏‎‎‏‏‎‎‎‎‎‏‎‏‎‎‎‏‏‎‎‎‎‏‎‏‏‎‏‏‎‎‏‎‎Translate‎‏‎‎‏‎"</string>
- <string name="action_search" msgid="6269564710943755464">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‎‏‎‏‏‏‎‎‎‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‏‎‎‎‏‏‎‎‎‏‎‏‎‎‎‎‏‎‎‎‎‎‏‎‎‎‏‏‎‎‏‏‎‎‏‎‎‎‎Lens‎‏‎‎‏‎"</string>
- <string name="dialog_acknowledge" msgid="2804025517675853172">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‎‎‏‏‎‏‏‏‎‏‎‎‏‏‏‏‎‎‏‏‎‎‏‎‏‏‎‏‎‎‎‎‏‏‎‏‎‎‎‏‏‎‎‏‏‎‎‏‏‎‏‎‏‎‏‏‏‎‏‎‎‎GOT IT‎‏‎‎‏‎"</string>
- <string name="dialog_cancel" msgid="6464336969134856366">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‎‏‏‎‎‏‏‎‏‏‎‏‎‏‏‏‏‏‎‎‎‎‎‎‏‏‏‎‎‏‎‏‎‏‎‎‎‏‏‎‏‏‎‏‎‏‎‏‎‏‏‎‎‎‏‎‏‎‏‏‏‎‎CANCEL‎‏‎‎‏‎"</string>
- <string name="dialog_settings" msgid="6564397136021186148">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‎‏‏‎‏‏‎‎‎‏‏‎‎‏‎‏‏‎‏‏‎‎‎‏‏‎‏‎‏‎‎‏‏‎‎‎‎‏‎‎‏‎‎‎‏‎‎‏‏‎‎‏‏‎‎‏‏‎‎‏‎‎‎SETTINGS‎‏‎‎‏‎"</string>
- <string name="niu_actions_confirmation_title" msgid="3863451714863526143">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‏‎‏‎‏‏‎‎‏‏‏‎‏‏‎‏‏‏‏‎‎‏‏‎‏‏‏‎‏‎‏‏‏‏‏‏‏‎‏‎‏‎‎‎‎‎‏‏‏‎‎‎‎‏‏‏‏‏‏‏‏‎Translate or listen to text on screen‎‏‎‎‏‎"</string>
- <string name="niu_actions_confirmation_text" msgid="2105271481950866089">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‎‏‏‏‏‎‏‎‎‏‏‎‏‏‏‎‏‏‎‏‏‎‏‎‏‎‎‎‎‏‎‎‎‏‏‎‏‎‏‎‏‏‏‎‎‎‏‎‎‎‎‏‎‏‎‏‎‏‎‏‎‎‏‎Information such as text on your screen, web addresses, and screenshots may be shared with Google.‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎To change what information you share, go to ‎‏‎‎‏‏‎"<b>"‎‏‎‎‏‏‏‎Settings &gt; Apps &gt; Default apps &gt; Digital assistant app‎‏‎‎‏‏‎"</b>"‎‏‎‎‏‏‏‎.‎‏‎‎‏‎"</string>
- <string name="assistant_not_selected_title" msgid="5017072974603345228">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‎‎‎‏‎‏‏‎‏‎‎‎‎‎‎‎‏‏‏‎‎‏‎‏‎‎‏‎‎‏‏‏‏‎‏‏‏‏‎‏‏‏‎‎‎‏‏‏‎‏‏‏‎‏‎‏‎‎‏‏‎‎‎Choose an assistant to use this feature‎‏‎‎‏‎"</string>
- <string name="assistant_not_selected_text" msgid="3244613673884359276">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‎‏‏‎‏‎‎‎‎‎‏‏‏‎‎‏‎‏‏‏‎‏‏‏‏‎‎‏‎‎‎‎‏‏‎‎‏‎‏‎‎‎‎‎‎‏‎‎‏‏‎‏‎‎‏‏‎‏‏‎‎‎To listen to or translate text on your screen, choose a digital assistant app in Settings‎‏‎‎‏‎"</string>
- <string name="assistant_not_supported_title" msgid="1675788067597484142">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‎‏‏‎‏‏‏‎‏‎‎‎‎‎‏‏‎‎‏‏‎‎‎‎‏‎‏‏‏‏‎‎‏‏‎‎‏‏‏‏‏‏‏‏‏‎‎‏‎‎‎‎‎‎‎‎‏‏‎‏‏‏‎‎Change your assistant to use this feature‎‏‎‎‏‎"</string>
- <string name="assistant_not_supported_text" msgid="1708031078549268884">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‎‏‏‎‏‏‏‏‎‏‏‎‏‎‎‎‎‏‎‎‏‎‏‎‎‏‏‎‏‏‏‎‏‏‎‎‏‏‎‎‏‎‎‎‎‎‏‏‎‏‎‏‎‎‏‏‎‎‏‎‏‎‎‎To listen to or translate text on your screen, change your digital assistant app in Settings‎‏‎‎‏‎"</string>
- <string name="tooltip_listen" msgid="7634466447860989102">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‏‎‏‎‎‏‏‏‏‏‎‎‏‏‎‎‎‏‎‎‏‎‏‏‎‎‏‎‎‏‎‎‎‎‎‎‏‎‎‏‏‎‎‏‎‎‎‏‏‏‏‏‎‎‏‎‏‎‏‏‏‎‎Tap here to listen to text on this screen‎‏‎‎‏‎"</string>
- <string name="tooltip_translate" msgid="4184845868901542567">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‏‏‎‏‎‎‎‎‏‎‎‏‏‏‎‎‎‏‏‏‏‎‎‏‎‎‏‎‏‎‎‏‏‏‏‏‏‏‎‏‎‎‎‏‏‎‎‏‎‏‎‏‎‏‎‏‎‎‏‏‏‎Tap here to translate text on this screen‎‏‎‎‏‎"</string>
- <string name="toast_p2p_app_not_shareable" msgid="7229739094132131536">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‏‎‎‏‎‎‎‏‎‏‎‏‎‏‎‎‏‏‎‎‎‏‎‏‏‎‎‏‏‎‏‎‏‏‏‏‎‎‏‎‎‎‎‎‎‎‎‎‎‎‎‏‏‎‏‏‎‏‎‎‎‎‎This app can’t be shared‎‏‎‎‏‎"</string>
-</resources>
diff --git a/go/quickstep/res/values-es-rUS/strings.xml b/go/quickstep/res/values-es-rUS/strings.xml
deleted file mode 100644
index 0f53967144..0000000000
--- a/go/quickstep/res/values-es-rUS/strings.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_share_drop_target_label" msgid="5804774105974539508">"Compartir app"</string>
- <string name="action_listen" msgid="2370304050784689486">"Escuchar"</string>
- <string name="action_translate" msgid="8028378961867277746">"Traducir"</string>
- <string name="action_search" msgid="6269564710943755464">"Lens"</string>
- <string name="dialog_acknowledge" msgid="2804025517675853172">"ENTENDIDO"</string>
- <string name="dialog_cancel" msgid="6464336969134856366">"CANCELAR"</string>
- <string name="dialog_settings" msgid="6564397136021186148">"CONFIGURACIÓN"</string>
- <string name="niu_actions_confirmation_title" msgid="3863451714863526143">"Traduce o escucha el texto que aparece en la pantalla"</string>
- <string name="niu_actions_confirmation_text" msgid="2105271481950866089">"Es posible que se comparta información con Google, como el texto de la pantalla, direcciones web y capturas de pantalla.\n\nPara cambiar la información que se comparte, ve a "<b>"Configuración &gt; Apps &gt; Apps predeterminadas &gt; App de asistente digital"</b>"."</string>
- <string name="assistant_not_selected_title" msgid="5017072974603345228">"Elige un asistente para usar esta función"</string>
- <string name="assistant_not_selected_text" msgid="3244613673884359276">"Para escuchar o traducir texto en la pantalla, elige una app de asistente digital en Configuración"</string>
- <string name="assistant_not_supported_title" msgid="1675788067597484142">"Cambia el asistente para usar esta función"</string>
- <string name="assistant_not_supported_text" msgid="1708031078549268884">"Para escuchar o traducir texto en la pantalla, cambia la app de asistente digital en Configuración"</string>
- <string name="tooltip_listen" msgid="7634466447860989102">"Presiona aquí para escuchar texto en esta pantalla"</string>
- <string name="tooltip_translate" msgid="4184845868901542567">"Presiona aquí para traducir texto en esta pantalla"</string>
- <string name="toast_p2p_app_not_shareable" msgid="7229739094132131536">"No se puede compartir esta app"</string>
-</resources>
diff --git a/go/quickstep/res/values-es/strings.xml b/go/quickstep/res/values-es/strings.xml
deleted file mode 100644
index fcd0fb81f8..0000000000
--- a/go/quickstep/res/values-es/strings.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_share_drop_target_label" msgid="5804774105974539508">"Compartir aplicación"</string>
- <string name="action_listen" msgid="2370304050784689486">"Escuchar"</string>
- <string name="action_translate" msgid="8028378961867277746">"Traducir"</string>
- <string name="action_search" msgid="6269564710943755464">"Lens"</string>
- <string name="dialog_acknowledge" msgid="2804025517675853172">"ENTENDIDO"</string>
- <string name="dialog_cancel" msgid="6464336969134856366">"CANCELAR"</string>
- <string name="dialog_settings" msgid="6564397136021186148">"AJUSTES"</string>
- <string name="niu_actions_confirmation_title" msgid="3863451714863526143">"Traduce o escucha texto que haya en pantalla"</string>
- <string name="niu_actions_confirmation_text" msgid="2105271481950866089">"Se puede compartir con Google cierta información, como el texto que aparece en pantalla, direcciones web o capturas de pantalla.\n\nPara cambiar la información que compartes, ve a "<b>"Ajustes &gt; Aplicaciones &gt; Aplicaciones predeterminadas &gt; Asistente digital"</b>"."</string>
- <string name="assistant_not_selected_title" msgid="5017072974603345228">"Elige un asistente para usar esta función"</string>
- <string name="assistant_not_selected_text" msgid="3244613673884359276">"Para escuchar o traducir texto que haya en tu pantalla, elige una aplicación de asistente digital en Ajustes"</string>
- <string name="assistant_not_supported_title" msgid="1675788067597484142">"Cambia tu asistente para usar esta función"</string>
- <string name="assistant_not_supported_text" msgid="1708031078549268884">"Para escuchar o traducir texto que haya en tu pantalla, cambia tu aplicación de asistente digital en Ajustes"</string>
- <string name="tooltip_listen" msgid="7634466447860989102">"Toca aquí para escuchar el texto que hay en esta pantalla"</string>
- <string name="tooltip_translate" msgid="4184845868901542567">"Toca aquí para traducir el texto que hay en esta pantalla"</string>
- <string name="toast_p2p_app_not_shareable" msgid="7229739094132131536">"Esta aplicación no se puede compartir"</string>
-</resources>
diff --git a/go/quickstep/res/values-et/strings.xml b/go/quickstep/res/values-et/strings.xml
deleted file mode 100644
index 2fffdd8395..0000000000
--- a/go/quickstep/res/values-et/strings.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_share_drop_target_label" msgid="5804774105974539508">"Jaga rakendust"</string>
- <string name="action_listen" msgid="2370304050784689486">"Kuula"</string>
- <string name="action_translate" msgid="8028378961867277746">"Tõlge"</string>
- <string name="action_search" msgid="6269564710943755464">"Lens"</string>
- <string name="dialog_acknowledge" msgid="2804025517675853172">"SELGE"</string>
- <string name="dialog_cancel" msgid="6464336969134856366">"TÜHISTA"</string>
- <string name="dialog_settings" msgid="6564397136021186148">"SEADED"</string>
- <string name="niu_actions_confirmation_title" msgid="3863451714863526143">"Ekraanil oleva teksti tõlkimine või kuulamine"</string>
- <string name="niu_actions_confirmation_text" msgid="2105271481950866089">"Teavet, nagu teie ekraanil olev tekst, veebiaadressid ja ekraanipildid, võidakse jagada Google\'iga.\n\nKui soovite muuta, millist teavet jagate, avage "<b>"Seaded &gt; Rakendused &gt; Vaikerakendused &gt; Digitaalse assistendi rakendus"</b>"."</string>
- <string name="assistant_not_selected_title" msgid="5017072974603345228">"Valige selle funktsiooni kasutamiseks assistent"</string>
- <string name="assistant_not_selected_text" msgid="3244613673884359276">"Ekraanil kuvatud teksti kuulamiseks või tõlkimiseks valige seadetes digitaalse assistendi rakendus"</string>
- <string name="assistant_not_supported_title" msgid="1675788067597484142">"Vahetage selle funktsiooni kasutamiseks assistenti"</string>
- <string name="assistant_not_supported_text" msgid="1708031078549268884">"Ekraanil kuvatud teksti kuulamiseks või tõlkimiseks vahetage seadetes digitaalse assistendi rakendust"</string>
- <string name="tooltip_listen" msgid="7634466447860989102">"Puudutage siin, et ekraanil kuvatud teksti kuulda"</string>
- <string name="tooltip_translate" msgid="4184845868901542567">"Puudutage siin, et ekraanil kuvatud tekst tõlkida"</string>
- <string name="toast_p2p_app_not_shareable" msgid="7229739094132131536">"Seda rakendust ei saa jagada"</string>
-</resources>
diff --git a/go/quickstep/res/values-eu/strings.xml b/go/quickstep/res/values-eu/strings.xml
deleted file mode 100644
index 75ddb46c71..0000000000
--- a/go/quickstep/res/values-eu/strings.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_share_drop_target_label" msgid="5804774105974539508">"Partekatu aplikazioa"</string>
- <string name="action_listen" msgid="2370304050784689486">"Entzun"</string>
- <string name="action_translate" msgid="8028378961867277746">"Itzuli"</string>
- <string name="action_search" msgid="6269564710943755464">"Lens"</string>
- <string name="dialog_acknowledge" msgid="2804025517675853172">"ADOS"</string>
- <string name="dialog_cancel" msgid="6464336969134856366">"UTZI"</string>
- <string name="dialog_settings" msgid="6564397136021186148">"EZARPENAK"</string>
- <string name="niu_actions_confirmation_title" msgid="3863451714863526143">"Itzuli edo entzun pantailako testua"</string>
- <string name="niu_actions_confirmation_text" msgid="2105271481950866089">"Agian pantailako testua, web-helbideak, pantaila-argazkiak eta antzeko informazioa partekatuko duzu Google-rekin.\n\nPartekatzen duzun informazioa aldatzeko, joan hona: "<b>"Ezarpenak &gt; Aplikazioak &gt; Aplikazio lehenetsiak &gt; Laguntzaile digitalaren aplikazioa"</b>"."</string>
- <string name="assistant_not_selected_title" msgid="5017072974603345228">"Hautatu laguntzaile bat eginbidea erabiltzeko"</string>
- <string name="assistant_not_selected_text" msgid="3244613673884359276">"Pantailako testua entzun edo itzultzeko, aukeratu laguntzaile digitalaren aplikazio bat Ezarpenak atalean"</string>
- <string name="assistant_not_supported_title" msgid="1675788067597484142">"Aldatu laguntzailea eginbidea erabiltzeko"</string>
- <string name="assistant_not_supported_text" msgid="1708031078549268884">"Pantailako testua entzun edo itzultzeko, aldatu laguntzaile digitalaren aplikazioa Ezarpenak atalean"</string>
- <string name="tooltip_listen" msgid="7634466447860989102">"Sakatu hau pantailako testua entzuteko"</string>
- <string name="tooltip_translate" msgid="4184845868901542567">"Sakatu hau pantailako testua itzultzeko"</string>
- <string name="toast_p2p_app_not_shareable" msgid="7229739094132131536">"Ezin da partekatu aplikazioa"</string>
-</resources>
diff --git a/go/quickstep/res/values-fa/strings.xml b/go/quickstep/res/values-fa/strings.xml
deleted file mode 100644
index 47786e92eb..0000000000
--- a/go/quickstep/res/values-fa/strings.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_share_drop_target_label" msgid="5804774105974539508">"هم‌رسانی برنامه"</string>
- <string name="action_listen" msgid="2370304050784689486">"گوش دادن"</string>
- <string name="action_translate" msgid="8028378961867277746">"ترجمه"</string>
- <string name="action_search" msgid="6269564710943755464">"لنز"</string>
- <string name="dialog_acknowledge" msgid="2804025517675853172">"متوجه‌ام"</string>
- <string name="dialog_cancel" msgid="6464336969134856366">"لغو"</string>
- <string name="dialog_settings" msgid="6564397136021186148">"تنظیمات"</string>
- <string name="niu_actions_confirmation_title" msgid="3863451714863526143">"ترجمه نوشتار روی صفحه‌نمایش یا گوش دادن به آن"</string>
- <string name="niu_actions_confirmation_text" msgid="2105271481950866089">"‏ممکن است اطلاعاتی مثل نوشتار روی صفحه‌نمایش، نشانی‌های وب، و نماگرفت‌ها با Google هم‌رسانی شود.\n\nبرای تغییر اطلاعاتی که هم‌رسانی می‌کنید، به "<b>"تنظیمات &lt; برنامه‌ها &lt; برنامه‌های پیش‌فرض &lt; برنامه دستیار دیجیتال"</b>" بروید."</string>
- <string name="assistant_not_selected_title" msgid="5017072974603345228">"برای استفاده از این ویژگی، دستیاری انتخاب کنید"</string>
- <string name="assistant_not_selected_text" msgid="3244613673884359276">"برای گوش کردن به نوشتار در صفحه‌نمایش‌تان یا ترجمه کردن آن، یکی از برنامه‌های دستیار دیجیتالی را در «تنظیمات» انتخاب کنید"</string>
- <string name="assistant_not_supported_title" msgid="1675788067597484142">"برای استفاده از این ویژگی، دستیارتان را تغییر دهید"</string>
- <string name="assistant_not_supported_text" msgid="1708031078549268884">"برای گوش کردن به نوشتار در صفحه‌نمایش‌تان یا ترجمه کردن آن، برنامه دستیار دیجیتالی‌تان را در «تنظیمات» تغییر دهید"</string>
- <string name="tooltip_listen" msgid="7634466447860989102">"برای گوش کردن به نوشتار در این صفحه، اینجا ضربه بزنید"</string>
- <string name="tooltip_translate" msgid="4184845868901542567">"برای ترجمه نوشتار در این صفحه، اینجا ضربه بزنید"</string>
- <string name="toast_p2p_app_not_shareable" msgid="7229739094132131536">"نمی‌توان این برنامه را هم‌رسانی کرد"</string>
-</resources>
diff --git a/go/quickstep/res/values-fi/strings.xml b/go/quickstep/res/values-fi/strings.xml
deleted file mode 100644
index bab635f3e8..0000000000
--- a/go/quickstep/res/values-fi/strings.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_share_drop_target_label" msgid="5804774105974539508">"Jaa sovellus"</string>
- <string name="action_listen" msgid="2370304050784689486">"Kuuntele"</string>
- <string name="action_translate" msgid="8028378961867277746">"Käännä"</string>
- <string name="action_search" msgid="6269564710943755464">"Lens"</string>
- <string name="dialog_acknowledge" msgid="2804025517675853172">"OK"</string>
- <string name="dialog_cancel" msgid="6464336969134856366">"PERU"</string>
- <string name="dialog_settings" msgid="6564397136021186148">"ASETUKSET"</string>
- <string name="niu_actions_confirmation_title" msgid="3863451714863526143">"Käännä tai kuuntele näytöllä oleva teksti"</string>
- <string name="niu_actions_confirmation_text" msgid="2105271481950866089">"Googlelle saatetaan jakaa näytöllä olevaa tekstiä, verkko-osoitteita, kuvakaappauksia ja muita tietoja.\n\nVoit valita jaettavat tiedot valitsemalla "<b>"Asetukset &gt; Sovellukset &gt; Oletussovellukset &gt; Digiavustajasovellus"</b>"."</string>
- <string name="assistant_not_selected_title" msgid="5017072974603345228">"Valitse avustaja tämän ominaisuuden käyttöön"</string>
- <string name="assistant_not_selected_text" msgid="3244613673884359276">"Jos haluat kuunnella tai kääntää näytöllä näkyvää tekstiä, valitse digiavustajasovellus asetuksista"</string>
- <string name="assistant_not_supported_title" msgid="1675788067597484142">"Vaihda avustaja tämän ominaisuuden käyttöä varten"</string>
- <string name="assistant_not_supported_text" msgid="1708031078549268884">"Jos haluat kuunnella tai kääntää näytöllä näkyvää tekstiä, vaihda digiavustajasovellus asetuksista"</string>
- <string name="tooltip_listen" msgid="7634466447860989102">"Kuuntele näytöllä näkyvä teksti napauttamalla tästä"</string>
- <string name="tooltip_translate" msgid="4184845868901542567">"Käännä näytöllä näkyvä teksti napauttamalla tästä"</string>
- <string name="toast_p2p_app_not_shareable" msgid="7229739094132131536">"Tätä sovellusta ei voi jakaa"</string>
-</resources>
diff --git a/go/quickstep/res/values-fr-rCA/strings.xml b/go/quickstep/res/values-fr-rCA/strings.xml
deleted file mode 100644
index 2cc9d8fe7c..0000000000
--- a/go/quickstep/res/values-fr-rCA/strings.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_share_drop_target_label" msgid="5804774105974539508">"Partager application"</string>
- <string name="action_listen" msgid="2370304050784689486">"Écouter"</string>
- <string name="action_translate" msgid="8028378961867277746">"Traduire"</string>
- <string name="action_search" msgid="6269564710943755464">"Lentille"</string>
- <string name="dialog_acknowledge" msgid="2804025517675853172">"OK"</string>
- <string name="dialog_cancel" msgid="6464336969134856366">"ANNULER"</string>
- <string name="dialog_settings" msgid="6564397136021186148">"PARAMÈTRES"</string>
- <string name="niu_actions_confirmation_title" msgid="3863451714863526143">"Traduire ou écouter le texte à l\'écran"</string>
- <string name="niu_actions_confirmation_text" msgid="2105271481950866089">"Des renseignements comme du texte sur votre écran, des adresses Web et des captures d\'écran peuvent être partagés avec Google.\n\nPour modifier les renseignements que vous partagez, accédez à "<b>"Paramètres &gt; Applications &gt; Applications par défaut &gt; Application d\'assistant numérique"</b>"."</string>
- <string name="assistant_not_selected_title" msgid="5017072974603345228">"Choisir un assistant pour utiliser cette fonctionnalité"</string>
- <string name="assistant_not_selected_text" msgid="3244613673884359276">"Pour écouter ou traduire le texte affiché sur votre écran, choisissez l\'application d\'un assistant numérique dans les paramètres"</string>
- <string name="assistant_not_supported_title" msgid="1675788067597484142">"Modifier votre assistant pour utiliser cette fonctionnalité"</string>
- <string name="assistant_not_supported_text" msgid="1708031078549268884">"Pour écouter ou traduire le texte affiché sur votre écran, modifiez l\'application de votre assistant numérique dans les paramètres"</string>
- <string name="tooltip_listen" msgid="7634466447860989102">"Touchez ce bouton pour écouter le texte affiché sur cet écran"</string>
- <string name="tooltip_translate" msgid="4184845868901542567">"Touchez ce bouton pour traduire le texte affiché sur cet écran"</string>
- <string name="toast_p2p_app_not_shareable" msgid="7229739094132131536">"Cette application ne peut pas être partagée"</string>
-</resources>
diff --git a/go/quickstep/res/values-fr/strings.xml b/go/quickstep/res/values-fr/strings.xml
deleted file mode 100644
index fded0af535..0000000000
--- a/go/quickstep/res/values-fr/strings.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_share_drop_target_label" msgid="5804774105974539508">"Partager l\'appli"</string>
- <string name="action_listen" msgid="2370304050784689486">"Écouter"</string>
- <string name="action_translate" msgid="8028378961867277746">"Traduire"</string>
- <string name="action_search" msgid="6269564710943755464">"Lens"</string>
- <string name="dialog_acknowledge" msgid="2804025517675853172">"OK"</string>
- <string name="dialog_cancel" msgid="6464336969134856366">"ANNULER"</string>
- <string name="dialog_settings" msgid="6564397136021186148">"PARAMÈTRES"</string>
- <string name="niu_actions_confirmation_title" msgid="3863451714863526143">"Traduire ou écouter le texte à l\'écran"</string>
- <string name="niu_actions_confirmation_text" msgid="2105271481950866089">"Des informations comme le texte sur votre écran, des adresses Web et des captures d\'écran peuvent être partagées avec Google.\n\nPour modifier les types d\'informations que vous partagez, accédez à "<b>"Paramètres &gt; Applis &gt; Applis par défaut &gt; Appli d\'assistant numérique"</b>"."</string>
- <string name="assistant_not_selected_title" msgid="5017072974603345228">"Sélectionnez un assistant pour utiliser cette fonctionnalité"</string>
- <string name="assistant_not_selected_text" msgid="3244613673884359276">"Pour écouter ou traduire le texte à l\'écran, sélectionnez une appli d\'assistant numérique dans \"Paramètres\""</string>
- <string name="assistant_not_supported_title" msgid="1675788067597484142">"Changez d\'assistant pour utiliser cette fonctionnalité"</string>
- <string name="assistant_not_supported_text" msgid="1708031078549268884">"Pour écouter ou traduire le texte à l\'écran, modifiez l\'appli d\'assistant numérique dans \"Paramètres\""</string>
- <string name="tooltip_listen" msgid="7634466447860989102">"Appuyez ici pour écouter le texte à l\'écran"</string>
- <string name="tooltip_translate" msgid="4184845868901542567">"Appuyez ici pour traduire le texte à l\'écran"</string>
- <string name="toast_p2p_app_not_shareable" msgid="7229739094132131536">"Impossible de partager cette appli"</string>
-</resources>
diff --git a/go/quickstep/res/values-gl/strings.xml b/go/quickstep/res/values-gl/strings.xml
deleted file mode 100644
index 86c6a57166..0000000000
--- a/go/quickstep/res/values-gl/strings.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_share_drop_target_label" msgid="5804774105974539508">"Compartir aplicación"</string>
- <string name="action_listen" msgid="2370304050784689486">"Escoitar"</string>
- <string name="action_translate" msgid="8028378961867277746">"Traducir"</string>
- <string name="action_search" msgid="6269564710943755464">"Lens"</string>
- <string name="dialog_acknowledge" msgid="2804025517675853172">"ENTENDIDO"</string>
- <string name="dialog_cancel" msgid="6464336969134856366">"CANCELAR"</string>
- <string name="dialog_settings" msgid="6564397136021186148">"CONFIGURACIÓN"</string>
- <string name="niu_actions_confirmation_title" msgid="3863451714863526143">"Traducir ou escoitar o texto que aparece na pantalla"</string>
- <string name="niu_actions_confirmation_text" msgid="2105271481950866089">"É posible que se comparta con Google información como o texto que aparece na pantalla, os enderezos web e as capturas de pantalla.\n\nPara cambiar os datos que se comparten, vai a "<b>"Configuración &gt; Aplicacións &gt; Aplicacións predeterminadas &gt; Aplicación de asistente dixital"</b>"."</string>
- <string name="assistant_not_selected_title" msgid="5017072974603345228">"Escolle un asistente para utilizar esta función"</string>
- <string name="assistant_not_selected_text" msgid="3244613673884359276">"Para escoitar ou traducir o texto da pantalla, escolle unha aplicación de asistente dixital en Configuración"</string>
- <string name="assistant_not_supported_title" msgid="1675788067597484142">"Cambia o asistente para utilizar esta función"</string>
- <string name="assistant_not_supported_text" msgid="1708031078549268884">"Para escoitar ou traducir o texto da pantalla, cambia a aplicación de asistente dixital en Configuración"</string>
- <string name="tooltip_listen" msgid="7634466447860989102">"Tocar aquí para escoitar o texto desta pantalla"</string>
- <string name="tooltip_translate" msgid="4184845868901542567">"Tocar aquí para traducir o texto desta pantalla"</string>
- <string name="toast_p2p_app_not_shareable" msgid="7229739094132131536">"Non se pode compartir esta aplicación"</string>
-</resources>
diff --git a/go/quickstep/res/values-gu/strings.xml b/go/quickstep/res/values-gu/strings.xml
deleted file mode 100644
index faa66fcc40..0000000000
--- a/go/quickstep/res/values-gu/strings.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_share_drop_target_label" msgid="5804774105974539508">"ઍપ શેર કરો"</string>
- <string name="action_listen" msgid="2370304050784689486">"સાંભળો"</string>
- <string name="action_translate" msgid="8028378961867277746">"અનુવાદ કરો"</string>
- <string name="action_search" msgid="6269564710943755464">"લેન્સ"</string>
- <string name="dialog_acknowledge" msgid="2804025517675853172">"સમજાઈ ગયું"</string>
- <string name="dialog_cancel" msgid="6464336969134856366">"રદ કરો"</string>
- <string name="dialog_settings" msgid="6564397136021186148">"સેટિંગ"</string>
- <string name="niu_actions_confirmation_title" msgid="3863451714863526143">"સ્ક્રીન પરની ટેક્સ્ટનો અનુવાદ કરો અથવા સાંભળો"</string>
- <string name="niu_actions_confirmation_text" msgid="2105271481950866089">"તમારી સ્ક્રીન પરની ટેક્સ્ટ, વેબ ઍડ્રેસ અને સ્ક્રીનશૉટ જેવી માહિતી Google સાથે શેર કરવામાં આવી શકે છે.\n\nતમે શેર કરતા હો તેવી માહિતીમાં ફેરફાર કરવા માટે, "<b>"સેટિંગ &gt; ઍપ &gt; ડિફૉલ્ટ ઍપ &gt; ડિજિટલ આસિસ્ટંટ ઍપ"</b>" પર જાઓ."</string>
- <string name="assistant_not_selected_title" msgid="5017072974603345228">"આ સુવિધાનો ઉપયોગ કરવા માટે આસિસ્ટંટ પસંદ કરો"</string>
- <string name="assistant_not_selected_text" msgid="3244613673884359276">"તમારી સ્ક્રીન પર ટેક્સ્ટ સાંભળવા માટે અથવા તેનો અનુવાદ કરવા માટે, સેટિંગમાં જઈને ડિજિટલ આસિસ્ટંટ ઍપ પસંદ કરો"</string>
- <string name="assistant_not_supported_title" msgid="1675788067597484142">"આ સુવિધાનો ઉપયોગ કરવા માટે તમારું આસિસ્ટંટ બદલો"</string>
- <string name="assistant_not_supported_text" msgid="1708031078549268884">"તમારી સ્ક્રીન પર ટેક્સ્ટ સાંભળવા માટે અથવા તેનો અનુવાદ કરવા માટે, સેટિંગમાં જઈને તમારી ડિજિટલ આસિસ્ટંટ ઍપ બદલો"</string>
- <string name="tooltip_listen" msgid="7634466447860989102">"આ સ્ક્રીન પર ટેક્સ્ટ સાંભળવા માટે અહીં ટૅપ કરો"</string>
- <string name="tooltip_translate" msgid="4184845868901542567">"આ સ્ક્રીન પર ટેક્સ્ટનો અનુવાદ કરવા માટે અહીં ટૅપ કરો"</string>
- <string name="toast_p2p_app_not_shareable" msgid="7229739094132131536">"આ ઍપ શેર કરી શકાતી નથી"</string>
-</resources>
diff --git a/go/quickstep/res/values-hi/strings.xml b/go/quickstep/res/values-hi/strings.xml
deleted file mode 100644
index ecf0cfb8a6..0000000000
--- a/go/quickstep/res/values-hi/strings.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_share_drop_target_label" msgid="5804774105974539508">"ऐप्लिकेशन शेयर करें"</string>
- <string name="action_listen" msgid="2370304050784689486">"सुनें"</string>
- <string name="action_translate" msgid="8028378961867277746">"अनुवाद करें"</string>
- <string name="action_search" msgid="6269564710943755464">"Google Lens"</string>
- <string name="dialog_acknowledge" msgid="2804025517675853172">"ठीक है"</string>
- <string name="dialog_cancel" msgid="6464336969134856366">"रद्द करें"</string>
- <string name="dialog_settings" msgid="6564397136021186148">"सेटिंग"</string>
- <string name="niu_actions_confirmation_title" msgid="3863451714863526143">"स्क्रीन पर मौजूद टेक्स्ट का अनुवाद पाएं या उसे सुनें"</string>
- <string name="niu_actions_confirmation_text" msgid="2105271481950866089">"आपकी स्क्रीन पर मौजूद टेक्स्ट, वेब पते, और स्क्रीनशॉट जैसी जानकारी Google के साथ शेयर की जा सकती है.\n\nआप Google के साथ किस जानकारी को शेयर करते हैं, इसे कंट्रोल करने के लिए "<b>"सेटिंग &gt; ऐप्लिकेशन &gt; डिफ़ॉल्ट ऐप्लिकेशन &gt; डिजिटल असिस्टेंट ऐप्लिकेशन"</b>" पर जाएं."</string>
- <string name="assistant_not_selected_title" msgid="5017072974603345228">"इस सुविधा का इस्तेमाल करने के लिए, कोई डिजिटल असिस्टेंट ऐप्लिकेशन चुनें"</string>
- <string name="assistant_not_selected_text" msgid="3244613673884359276">"स्क्रीन पर मौजूद टेक्स्ट का अनुवाद करने या उसे सुनने के लिए, \'सेटिंग\' में जाकर कोई डिजिटल असिस्टेंट ऐप्लिकेशन चुनें"</string>
- <string name="assistant_not_supported_title" msgid="1675788067597484142">"इस सुविधा का इस्तेमाल करने के लिए, अपना डिजिटल असिस्टेंट ऐप्लिकेशन बदलें"</string>
- <string name="assistant_not_supported_text" msgid="1708031078549268884">"स्क्रीन पर मौजूद टेक्स्ट का अनुवाद करने या उसे सुनने के लिए, \'सेटिंग\' में जाकर अपना डिजिटल असिस्टेंट ऐप्लिकेशन बदलें"</string>
- <string name="tooltip_listen" msgid="7634466447860989102">"स्क्रीन पर मौजूद टेक्स्ट को सुनने के लिए, यहां टैप करें"</string>
- <string name="tooltip_translate" msgid="4184845868901542567">"स्क्रीन पर मौजूद टेक्स्ट का अनुवाद करने के लिए, यहां टैप करें"</string>
- <string name="toast_p2p_app_not_shareable" msgid="7229739094132131536">"इस ऐप्लिकेशन को शेयर नहीं किया जा सकता"</string>
-</resources>
diff --git a/go/quickstep/res/values-hr/strings.xml b/go/quickstep/res/values-hr/strings.xml
deleted file mode 100644
index 137472d20c..0000000000
--- a/go/quickstep/res/values-hr/strings.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_share_drop_target_label" msgid="5804774105974539508">"Dijeli aplikaciju"</string>
- <string name="action_listen" msgid="2370304050784689486">"Slušajte"</string>
- <string name="action_translate" msgid="8028378961867277746">"Prevedi"</string>
- <string name="action_search" msgid="6269564710943755464">"Objektiv"</string>
- <string name="dialog_acknowledge" msgid="2804025517675853172">"SHVAĆAM"</string>
- <string name="dialog_cancel" msgid="6464336969134856366">"ODUSTANI"</string>
- <string name="dialog_settings" msgid="6564397136021186148">"POSTAVKE"</string>
- <string name="niu_actions_confirmation_title" msgid="3863451714863526143">"Prevedite ili slušajte tekst na zaslonu"</string>
- <string name="niu_actions_confirmation_text" msgid="2105271481950866089">"Informacije kao što su tekst na vašem zaslonu, web-adrese i snimke zaslona mogu se dijeliti s Googleom.\n\nDa biste promijenili informacije koje dijelite, otvorite "<b>"Postavke &gt; Aplikacije &gt; Zadane aplikacije &gt; Aplikacija digitalnog asistenta"</b>"."</string>
- <string name="assistant_not_selected_title" msgid="5017072974603345228">"Odaberite asistenta za upotrebu te značajke"</string>
- <string name="assistant_not_selected_text" msgid="3244613673884359276">"Da biste poslušali ili preveli tekst na zaslonu, odaberite aplikaciju digitalnog asistenta u postavkama"</string>
- <string name="assistant_not_supported_title" msgid="1675788067597484142">"Promijenite asistenta da biste koristili tu značajku"</string>
- <string name="assistant_not_supported_text" msgid="1708031078549268884">"Da biste poslušali ili preveli tekst na zaslonu, promijenite aplikaciju digitalnog asistenta u postavkama"</string>
- <string name="tooltip_listen" msgid="7634466447860989102">"Dodirnite ovdje da biste poslušali tekst na ovom zaslonu"</string>
- <string name="tooltip_translate" msgid="4184845868901542567">"Dodirnite ovdje da biste preveli tekst na ovom zaslonu"</string>
- <string name="toast_p2p_app_not_shareable" msgid="7229739094132131536">"Ovu aplikaciju ne možete dijeliti"</string>
-</resources>
diff --git a/go/quickstep/res/values-hu/strings.xml b/go/quickstep/res/values-hu/strings.xml
deleted file mode 100644
index d94e6b72a7..0000000000
--- a/go/quickstep/res/values-hu/strings.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_share_drop_target_label" msgid="5804774105974539508">"App megosztása"</string>
- <string name="action_listen" msgid="2370304050784689486">"Lejátszás"</string>
- <string name="action_translate" msgid="8028378961867277746">"Fordítás"</string>
- <string name="action_search" msgid="6269564710943755464">"Lens"</string>
- <string name="dialog_acknowledge" msgid="2804025517675853172">"ÉRTEM"</string>
- <string name="dialog_cancel" msgid="6464336969134856366">"MÉGSE"</string>
- <string name="dialog_settings" msgid="6564397136021186148">"BEÁLLÍTÁSOK"</string>
- <string name="niu_actions_confirmation_title" msgid="3863451714863526143">"Képernyőn megjelenő szöveg fordítása és hallgatása"</string>
- <string name="niu_actions_confirmation_text" msgid="2105271481950866089">"Előfordulhat, hogy a rendszer megoszt bizonyos adatokat (például képernyőn megjelenő szöveget, internetcímeket és képernyőképeket) a Google-lal.\n\nHa módosítani szeretné, hogy milyen adatokat oszt meg, lépjen a "<b>"Beállítások és alkalmazások; Alapértelmezett alkalmazások; Digitális asszisztens app"</b>" menüpontra."</string>
- <string name="assistant_not_selected_title" msgid="5017072974603345228">"Válasszon asszisztenst a funkció használatához"</string>
- <string name="assistant_not_selected_text" msgid="3244613673884359276">"A képernyőn megjelenő szöveg meghallgatásához vagy lefordításához válasszon digitálisasszisztens-alkalmazást a Beállítások menüben"</string>
- <string name="assistant_not_supported_title" msgid="1675788067597484142">"Módosítsa az asszisztenst a funkció használatához"</string>
- <string name="assistant_not_supported_text" msgid="1708031078549268884">"A képernyőn megjelenő szöveg meghallgatásához vagy lefordításához módosítsa a digitálisasszisztens-alkalmazást a Beállítások menüben"</string>
- <string name="tooltip_listen" msgid="7634466447860989102">"Koppintson ide a jelenleg képernyőn lévő szöveg meghallgatásához"</string>
- <string name="tooltip_translate" msgid="4184845868901542567">"Koppintson ide a jelenleg képernyőn lévő szöveg lefordításához"</string>
- <string name="toast_p2p_app_not_shareable" msgid="7229739094132131536">"Ezt az alkalmazást nem lehet megosztani"</string>
-</resources>
diff --git a/go/quickstep/res/values-hy/strings.xml b/go/quickstep/res/values-hy/strings.xml
deleted file mode 100644
index c6352c9387..0000000000
--- a/go/quickstep/res/values-hy/strings.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_share_drop_target_label" msgid="5804774105974539508">"Կիսվել հավելվածով"</string>
- <string name="action_listen" msgid="2370304050784689486">"Լսել"</string>
- <string name="action_translate" msgid="8028378961867277746">"Թարգմանել"</string>
- <string name="action_search" msgid="6269564710943755464">"Տեսապակի"</string>
- <string name="dialog_acknowledge" msgid="2804025517675853172">"ԵՂԱՎ"</string>
- <string name="dialog_cancel" msgid="6464336969134856366">"ՉԵՂԱՐԿԵԼ"</string>
- <string name="dialog_settings" msgid="6564397136021186148">"ԿԱՐԳԱՎՈՐՈՒՄՆԵՐ"</string>
- <string name="niu_actions_confirmation_title" msgid="3863451714863526143">"Էկրանի տեքստի թարգմանություն կամ ունկնդրում"</string>
- <string name="niu_actions_confirmation_text" msgid="2105271481950866089">"Որոշակի տեղեկություններ (օր․՝ էկրանի տեքստը, վեբ հասցեները և սքրինշոթները) կարող են ուղարկվել Google-ին։\n\nՏեղեկությունները, որոնցով դուք կիսվում եք, կարող եք փոխել՝ անցնելով "<b>"Կարգավորումներ &gt; Հավելվածներ &gt; Կանխադրված հավելվածներ &gt; Թվային օգնականի հավելված"</b>"։"</string>
- <string name="assistant_not_selected_title" msgid="5017072974603345228">"Այս գործառույթն օգտագործելու համար ընտրեք օգնական"</string>
- <string name="assistant_not_selected_text" msgid="3244613673884359276">"Էկրանի տեքստը լսելու կամ թարգմանելու համար կարգավորումներում ընտրեք թվային օգնականի հավելված։"</string>
- <string name="assistant_not_supported_title" msgid="1675788067597484142">"Այս գործառույթն օգտագործելու համար փոխեք ձեր օգնականը"</string>
- <string name="assistant_not_supported_text" msgid="1708031078549268884">"Էկրանի տեքստը լսելու կամ թարգմանելու համար կարգավորումներում փոխեք ձեր թվային օգնականի հավելվածը։"</string>
- <string name="tooltip_listen" msgid="7634466447860989102">"Հպեք այստեղ՝ այս էկրանի տեքստը լսելու համար"</string>
- <string name="tooltip_translate" msgid="4184845868901542567">"Հպեք այստեղ` այս էկրանի տեքստը թարգմանելու համար"</string>
- <string name="toast_p2p_app_not_shareable" msgid="7229739094132131536">"Հնարավոր չէ կիսվել այս հավելվածով"</string>
-</resources>
diff --git a/go/quickstep/res/values-in/strings.xml b/go/quickstep/res/values-in/strings.xml
deleted file mode 100644
index 692bedc57f..0000000000
--- a/go/quickstep/res/values-in/strings.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_share_drop_target_label" msgid="5804774105974539508">"Bagikan Aplikasi"</string>
- <string name="action_listen" msgid="2370304050784689486">"Dengarkan"</string>
- <string name="action_translate" msgid="8028378961867277746">"Terjemahkan"</string>
- <string name="action_search" msgid="6269564710943755464">"Lens"</string>
- <string name="dialog_acknowledge" msgid="2804025517675853172">"OKE"</string>
- <string name="dialog_cancel" msgid="6464336969134856366">"BATAL"</string>
- <string name="dialog_settings" msgid="6564397136021186148">"SETELAN"</string>
- <string name="niu_actions_confirmation_title" msgid="3863451714863526143">"Terjemahkan atau dengarkan teks di layar"</string>
- <string name="niu_actions_confirmation_text" msgid="2105271481950866089">"Informasi seperti teks di layar, alamat web, dan screenshot dapat dibagikan ke Google.\n\nUntuk mengubah informasi yang Anda bagikan, buka "<b>"Setelan &gt; Aplikasi &gt; Aplikasi default &gt; Aplikasi asisten digital"</b>"."</string>
- <string name="assistant_not_selected_title" msgid="5017072974603345228">"Pilih asisten untuk menggunakan fitur ini"</string>
- <string name="assistant_not_selected_text" msgid="3244613673884359276">"Untuk mendengarkan atau menerjemahkan teks di layar, pilih aplikasi asisten digital di Setelan"</string>
- <string name="assistant_not_supported_title" msgid="1675788067597484142">"Ubah asisten untuk menggunakan fitur ini"</string>
- <string name="assistant_not_supported_text" msgid="1708031078549268884">"Untuk mendengarkan atau menerjemahkan teks di layar, ubah aplikasi asisten digital Anda di Setelan"</string>
- <string name="tooltip_listen" msgid="7634466447860989102">"Ketuk di sini untuk mendengarkan teks di layar ini"</string>
- <string name="tooltip_translate" msgid="4184845868901542567">"Ketuk di sini untuk menerjemahkan teks di layar ini"</string>
- <string name="toast_p2p_app_not_shareable" msgid="7229739094132131536">"Aplikasi ini tidak dapat dibagikan"</string>
-</resources>
diff --git a/go/quickstep/res/values-is/strings.xml b/go/quickstep/res/values-is/strings.xml
deleted file mode 100644
index 25a96dd4ba..0000000000
--- a/go/quickstep/res/values-is/strings.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_share_drop_target_label" msgid="5804774105974539508">"Deila forriti"</string>
- <string name="action_listen" msgid="2370304050784689486">"Hlusta"</string>
- <string name="action_translate" msgid="8028378961867277746">"Þýða"</string>
- <string name="action_search" msgid="6269564710943755464">"Linsa"</string>
- <string name="dialog_acknowledge" msgid="2804025517675853172">"ÉG SKIL"</string>
- <string name="dialog_cancel" msgid="6464336969134856366">"HÆTTA VIÐ"</string>
- <string name="dialog_settings" msgid="6564397136021186148">"STILLINGAR"</string>
- <string name="niu_actions_confirmation_title" msgid="3863451714863526143">"Þýða eða hlusta á texta á skjánum"</string>
- <string name="niu_actions_confirmation_text" msgid="2105271481950866089">"Mögulegt er að upplýsingum á borð við texta á skjánum, vefslóðum og skjámyndum verði deilt með Google.\n\nTil að breyta því hvaða upplýsingum þú deilir skaltu opna "<b>"Stillingar &gt; Forrit &gt; Sjálfgefin forrit &gt; Forrit stafræns hjálpara"</b>"."</string>
- <string name="assistant_not_selected_title" msgid="5017072974603345228">"Veldu hjálpara til að nota þennan eiginleika"</string>
- <string name="assistant_not_selected_text" msgid="3244613673884359276">"Veldu stafrænan hjálpara í stillingum til að hlusta á eða þýða texta á skjánum"</string>
- <string name="assistant_not_supported_title" msgid="1675788067597484142">"Breyttu hjálparanum til að nota þennan eiginleika"</string>
- <string name="assistant_not_supported_text" msgid="1708031078549268884">"Breyttu forriti stafræna hjálparans í stillingum til að hlusta á eða þýða texta"</string>
- <string name="tooltip_listen" msgid="7634466447860989102">"Ýttu hér til að hlusta á texta á þessum skjá"</string>
- <string name="tooltip_translate" msgid="4184845868901542567">"Ýttu hér til að þýða texta á þessum skjá"</string>
- <string name="toast_p2p_app_not_shareable" msgid="7229739094132131536">"Ekki er hægt að deila þessu forriti"</string>
-</resources>
diff --git a/go/quickstep/res/values-it/strings.xml b/go/quickstep/res/values-it/strings.xml
deleted file mode 100644
index ebdea202fa..0000000000
--- a/go/quickstep/res/values-it/strings.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_share_drop_target_label" msgid="5804774105974539508">"Condividi l\'app"</string>
- <string name="action_listen" msgid="2370304050784689486">"Ascolta"</string>
- <string name="action_translate" msgid="8028378961867277746">"Traduttore"</string>
- <string name="action_search" msgid="6269564710943755464">"Lens"</string>
- <string name="dialog_acknowledge" msgid="2804025517675853172">"OK"</string>
- <string name="dialog_cancel" msgid="6464336969134856366">"ANNULLA"</string>
- <string name="dialog_settings" msgid="6564397136021186148">"IMPOSTAZIONI"</string>
- <string name="niu_actions_confirmation_title" msgid="3863451714863526143">"Traduci o ascolta il testo sullo schermo"</string>
- <string name="niu_actions_confirmation_text" msgid="2105271481950866089">"Alcune informazioni, come il testo sullo schermo, gli indirizzi web e gli screenshot, potrebbero essere condivise con Google.\n\nPer modificare quali informazioni condividere, vai a "<b>"Impostazioni &gt; App &gt; App predefinite &gt; App assistente digitale"</b>"."</string>
- <string name="assistant_not_selected_title" msgid="5017072974603345228">"Scegli un assistente per usare questa funzionalità"</string>
- <string name="assistant_not_selected_text" msgid="3244613673884359276">"Per ascoltare o tradurre il testo mostrato sullo schermo, scegli l\'app di un assistente digitale nelle Impostazioni"</string>
- <string name="assistant_not_supported_title" msgid="1675788067597484142">"Cambia l\'assistente per usare questa funzionalità"</string>
- <string name="assistant_not_supported_text" msgid="1708031078549268884">"Per ascoltare o tradurre il testo mostrato sullo schermo, cambia l\'app dell\'assistente digitale nelle Impostazioni"</string>
- <string name="tooltip_listen" msgid="7634466447860989102">"Tocca qui per ascoltare il testo mostrato in questa schermata"</string>
- <string name="tooltip_translate" msgid="4184845868901542567">"Tocca qui per tradurre il testo mostrato in questa schermata"</string>
- <string name="toast_p2p_app_not_shareable" msgid="7229739094132131536">"Impossibile condividere questa app"</string>
-</resources>
diff --git a/go/quickstep/res/values-iw/strings.xml b/go/quickstep/res/values-iw/strings.xml
deleted file mode 100644
index ddb8ddd9a9..0000000000
--- a/go/quickstep/res/values-iw/strings.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_share_drop_target_label" msgid="5804774105974539508">"לשיתוף האפליקציה"</string>
- <string name="action_listen" msgid="2370304050784689486">"האזנה"</string>
- <string name="action_translate" msgid="8028378961867277746">"תרגום"</string>
- <string name="action_search" msgid="6269564710943755464">"Lens"</string>
- <string name="dialog_acknowledge" msgid="2804025517675853172">"הבנתי"</string>
- <string name="dialog_cancel" msgid="6464336969134856366">"ביטול"</string>
- <string name="dialog_settings" msgid="6564397136021186148">"הגדרות"</string>
- <string name="niu_actions_confirmation_title" msgid="3863451714863526143">"תרגום טקסט שמוצג במסך או האזנה לו"</string>
- <string name="niu_actions_confirmation_text" msgid="2105271481950866089">"‏ייתכן שישותף עם Google מידע כגון טקסט שמוצג במסך, כתובות אינטרנט וצילומי מסך.\n\nכדי לקבוע איזה מידע ישותף, יש לעבור אל "<b>"הגדרות &gt; אפליקציות &amp;gt אפליקציות ברירת מחדל &gt; אפליקציית עוזר דיגיטלי"</b>"."</string>
- <string name="assistant_not_selected_title" msgid="5017072974603345228">"יש לבחור עוזר דיגיטלי כדי להשתמש בתכונה הזו"</string>
- <string name="assistant_not_selected_text" msgid="3244613673884359276">"כדי להאזין לטקסט שבמסך או לתרגם אותו, צריך לבחור אפליקציית עוזר דיגיטלי ב\'הגדרות\'"</string>
- <string name="assistant_not_supported_title" msgid="1675788067597484142">"צריך לשנות את העוזר הדיגיטלי כדי להשתמש בתכונה הזו"</string>
- <string name="assistant_not_supported_text" msgid="1708031078549268884">"כדי להאזין לטקסט שבמסך או לתרגם אותו, צריך לשנות את אפליקציית העוזר הדיגיטלי ב\'הגדרות\'"</string>
- <string name="tooltip_listen" msgid="7634466447860989102">"צריך להקיש כאן כדי להאזין לטקסט שבמסך הזה"</string>
- <string name="tooltip_translate" msgid="4184845868901542567">"צריך להקיש כאן כדי לתרגם את הטקסט שבמסך הזה"</string>
- <string name="toast_p2p_app_not_shareable" msgid="7229739094132131536">"אי אפשר לשתף את האפליקציה הזו"</string>
-</resources>
diff --git a/go/quickstep/res/values-ja/strings.xml b/go/quickstep/res/values-ja/strings.xml
deleted file mode 100644
index 3ce87f7145..0000000000
--- a/go/quickstep/res/values-ja/strings.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_share_drop_target_label" msgid="5804774105974539508">"アプリを共有"</string>
- <string name="action_listen" msgid="2370304050784689486">"聴く"</string>
- <string name="action_translate" msgid="8028378961867277746">"翻訳"</string>
- <string name="action_search" msgid="6269564710943755464">"レンズ"</string>
- <string name="dialog_acknowledge" msgid="2804025517675853172">"OK"</string>
- <string name="dialog_cancel" msgid="6464336969134856366">"キャンセル"</string>
- <string name="dialog_settings" msgid="6564397136021186148">"設定"</string>
- <string name="niu_actions_confirmation_title" msgid="3863451714863526143">"画面上のテキストを翻訳または聞く"</string>
- <string name="niu_actions_confirmation_text" msgid="2105271481950866089">"画面上のテキスト、ウェブアドレス、スクリーンショットなどの情報が Google と共有される場合があります。\n\n共有される情報を変更するには、"<b>"[設定] &gt; [アプリ] &gt; [デフォルトのアプリ] &gt; [デジタル アシスタント アプリ]"</b>" に移動してください。"</string>
- <string name="assistant_not_selected_title" msgid="5017072974603345228">"この機能を使用するにはアシスタントを選択してください"</string>
- <string name="assistant_not_selected_text" msgid="3244613673884359276">"画面上のテキストを翻訳するかまたは聞くには、[設定] でデジタル アシスタント アプリを選択してください"</string>
- <string name="assistant_not_supported_title" msgid="1675788067597484142">"この機能を使用するにはアシスタントを変更してください"</string>
- <string name="assistant_not_supported_text" msgid="1708031078549268884">"画面上のテキストを翻訳するかまたは聞くには、[設定] でデジタル アシスタント アプリを変更してください"</string>
- <string name="tooltip_listen" msgid="7634466447860989102">"この画面上のテキストを聞くには、ここをタップしてください"</string>
- <string name="tooltip_translate" msgid="4184845868901542567">"この画面上のテキストを翻訳するには、ここをタップしてください"</string>
- <string name="toast_p2p_app_not_shareable" msgid="7229739094132131536">"このアプリは共有できません"</string>
-</resources>
diff --git a/go/quickstep/res/values-ka/strings.xml b/go/quickstep/res/values-ka/strings.xml
deleted file mode 100644
index 0f7381040b..0000000000
--- a/go/quickstep/res/values-ka/strings.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_share_drop_target_label" msgid="5804774105974539508">"აპის გაზიარება"</string>
- <string name="action_listen" msgid="2370304050784689486">"მოსმენა"</string>
- <string name="action_translate" msgid="8028378961867277746">"თარგმნა"</string>
- <string name="action_search" msgid="6269564710943755464">"Lens"</string>
- <string name="dialog_acknowledge" msgid="2804025517675853172">"გასაგებია"</string>
- <string name="dialog_cancel" msgid="6464336969134856366">"გაუქმება"</string>
- <string name="dialog_settings" msgid="6564397136021186148">"პარამეტრები"</string>
- <string name="niu_actions_confirmation_title" msgid="3863451714863526143">"თარგმნეთ ან მოისმინეთ ეკრანზე ნაჩვენები ტექსტი"</string>
- <string name="niu_actions_confirmation_text" msgid="2105271481950866089">"ისეთი ინფორმაცია, როგორიც არის ტექსტი თქვენს ეკრანზე, ვებ-მისამართები და ეკრანის ანაბეჭდები შეიძლება გაზიარდეს Google-თან.\n\nთუ გსურთ, შეცვალოთ, რა ინფორმაციას აზიარებთ, გადადით: "<b>"პარამეტრები &gt; აპები &gt; ნაგულისხმევი აპები &gt; ციფრული ასისტენტის აპი"</b>"."</string>
- <string name="assistant_not_selected_title" msgid="5017072974603345228">"ამ ფუნქციით სარგებლობისთვის აირჩიეთ ასისტენტი"</string>
- <string name="assistant_not_selected_text" msgid="3244613673884359276">"თქვენს ეკრანზე ნაჩვენები ტექსტის მოსასმენად ან სათარგმნად, აირჩიეთ ციფრული ასისტენტის აპი პარამეტრებიდან"</string>
- <string name="assistant_not_supported_title" msgid="1675788067597484142">"ამ ფუნქციით სარგებლობისთვის შეცვალეთ ასისტენტი"</string>
- <string name="assistant_not_supported_text" msgid="1708031078549268884">"თქვენს ეკრანზე ნაჩვენები ტექსტის მოსასმენად ან სათარგმნად, შეცვალეთ ციფრული ასისტენტის აპი პარამეტრებიდან"</string>
- <string name="tooltip_listen" msgid="7634466447860989102">"შეეხეთ აქ ამ ეკრანზე ნაჩვენები ტექსტის მოსასმენად"</string>
- <string name="tooltip_translate" msgid="4184845868901542567">"შეეხეთ აქ ამ ეკრანზე ნაჩვენები ტექსტის სათარგმნად"</string>
- <string name="toast_p2p_app_not_shareable" msgid="7229739094132131536">"ამ აპის გაზიარება შეუძლებელია"</string>
-</resources>
diff --git a/go/quickstep/res/values-kk/strings.xml b/go/quickstep/res/values-kk/strings.xml
deleted file mode 100644
index 2361cbb619..0000000000
--- a/go/quickstep/res/values-kk/strings.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_share_drop_target_label" msgid="5804774105974539508">"Қолданбаны бөлісу"</string>
- <string name="action_listen" msgid="2370304050784689486">"Тыңдау"</string>
- <string name="action_translate" msgid="8028378961867277746">"Аудару"</string>
- <string name="action_search" msgid="6269564710943755464">"Объектив"</string>
- <string name="dialog_acknowledge" msgid="2804025517675853172">"ТҮСІНІКТІ"</string>
- <string name="dialog_cancel" msgid="6464336969134856366">"БАС ТАРТУ"</string>
- <string name="dialog_settings" msgid="6564397136021186148">"ПАРАМЕТРЛЕР"</string>
- <string name="niu_actions_confirmation_title" msgid="3863451714863526143">"Экрандағы мәтінді аудару немесе тыңдау"</string>
- <string name="niu_actions_confirmation_text" msgid="2105271481950866089">"Экрандағы мәтін, веб-мекенжайлар мен скриншоттар сияқты ақпарат Google-мен бөлісілуі мүмкін.\n\nБөлісілетін ақпаратты өзгерту үшін "<b>"Параметрлер &gt; Қолданбалар &gt; Әдепкі қолданбалар &gt; Цифрлық көмекші қолданбасы"</b>" тармағына өтіңіз."</string>
- <string name="assistant_not_selected_title" msgid="5017072974603345228">"Осы функцияны пайдалану үшін көмекшіні таңдау"</string>
- <string name="assistant_not_selected_text" msgid="3244613673884359276">"Экрандағы мәтінді тыңдау немесе аудару үшін параметрлерден цифрлық көмекшіні таңдаңыз."</string>
- <string name="assistant_not_supported_title" msgid="1675788067597484142">"Осы функцияны пайдалану үшін көмекшіні өзгерту"</string>
- <string name="assistant_not_supported_text" msgid="1708031078549268884">"Экрандағы мәтінді тыңдау немесе аудару үшін параметрлерден цифрлық көмекшіні өзгертіңіз."</string>
- <string name="tooltip_listen" msgid="7634466447860989102">"Экрандағы мәтінді тыңдау үшін осы жерде түртіңіз."</string>
- <string name="tooltip_translate" msgid="4184845868901542567">"Экрандағы мәтінді аудару үшін осы жерде түртіңіз."</string>
- <string name="toast_p2p_app_not_shareable" msgid="7229739094132131536">"Бұл қолданбаны бөлісу мүмкін емес."</string>
-</resources>
diff --git a/go/quickstep/res/values-km/strings.xml b/go/quickstep/res/values-km/strings.xml
deleted file mode 100644
index cec764668f..0000000000
--- a/go/quickstep/res/values-km/strings.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_share_drop_target_label" msgid="5804774105974539508">"ចែក​រំលែក​កម្មវិធី"</string>
- <string name="action_listen" msgid="2370304050784689486">"ស្តាប់"</string>
- <string name="action_translate" msgid="8028378961867277746">"បកប្រែ"</string>
- <string name="action_search" msgid="6269564710943755464">"Lens"</string>
- <string name="dialog_acknowledge" msgid="2804025517675853172">"យល់ហើយ"</string>
- <string name="dialog_cancel" msgid="6464336969134856366">"បោះបង់"</string>
- <string name="dialog_settings" msgid="6564397136021186148">"ការកំណត់"</string>
- <string name="niu_actions_confirmation_title" msgid="3863451714863526143">"បកប្រែ ឬស្ដាប់អត្ថបទ​នៅលើអេក្រង់"</string>
- <string name="niu_actions_confirmation_text" msgid="2105271481950866089">"ព័ត៌មានដូចជា អត្ថបទនៅលើ​អេក្រង់របស់អ្នក អាសយដ្ឋានទំព័រ និងរូបថតអេក្រង់​​អាចនឹងត្រូវបានចែក​រំលែកជាមួយ Google។\n\nដើម្បីប្ដូរព័ត៌មាន​ដែលអ្នកចែករំលែក សូមចូលទៅកាន់"<b>"ការកំណត់ &gt; កម្មវិធី &gt; កម្មវិធីលំនាំដើម &gt; កម្មវិធីជំនួយការឌីជីថល"</b>"។"</string>
- <string name="assistant_not_selected_title" msgid="5017072974603345228">"ជ្រើសរើស​ជំនួយការ ដើម្បីប្រើ​មុខងារនេះ"</string>
- <string name="assistant_not_selected_text" msgid="3244613673884359276">"ដើម្បីស្ដាប់ ឬបកប្រែ​អត្ថបទ​នៅលើ​អេក្រង់របស់អ្នក សូមជ្រើសរើស​កម្មវិធី​ជំនួយការឌីជីថល​នៅក្នុង​ការកំណត់"</string>
- <string name="assistant_not_supported_title" msgid="1675788067597484142">"ប្ដូរជំនួយការ​របស់អ្នក ដើម្បីប្រើ​មុខងារនេះ"</string>
- <string name="assistant_not_supported_text" msgid="1708031078549268884">"ដើម្បីស្ដាប់ ឬបកប្រែ​អត្ថបទ​នៅលើ​អេក្រង់របស់អ្នក សូមប្ដូរ​កម្មវិធី​ជំនួយការឌីជីថល​របស់អ្នក​នៅក្នុង​ការកំណត់"</string>
- <string name="tooltip_listen" msgid="7634466447860989102">"ចុចត្រង់នេះ ដើម្បីស្ដាប់​អត្ថបទ​នៅលើ​អេក្រង់នេះ"</string>
- <string name="tooltip_translate" msgid="4184845868901542567">"ចុចត្រង់នេះ ដើម្បីបកប្រែ​អត្ថបទ​នៅលើ​អេក្រង់នេះ"</string>
- <string name="toast_p2p_app_not_shareable" msgid="7229739094132131536">"មិនអាចចែករំលែកកម្មវិធីនេះបានទេ"</string>
-</resources>
diff --git a/go/quickstep/res/values-kn/strings.xml b/go/quickstep/res/values-kn/strings.xml
deleted file mode 100644
index 28ba66b1ee..0000000000
--- a/go/quickstep/res/values-kn/strings.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_share_drop_target_label" msgid="5804774105974539508">"ಆ್ಯಪ್ ಹಂಚಿಕೊಳ್ಳಿ"</string>
- <string name="action_listen" msgid="2370304050784689486">"ಆಲಿಸಿ"</string>
- <string name="action_translate" msgid="8028378961867277746">"ಅನುವಾದಿಸಿ"</string>
- <string name="action_search" msgid="6269564710943755464">"Lens"</string>
- <string name="dialog_acknowledge" msgid="2804025517675853172">"ಅರ್ಥವಾಯಿತು"</string>
- <string name="dialog_cancel" msgid="6464336969134856366">"ರದ್ದುಗೊಳಿಸಿ"</string>
- <string name="dialog_settings" msgid="6564397136021186148">"ಸೆಟ್ಟಿಂಗ್‌ಗಳು"</string>
- <string name="niu_actions_confirmation_title" msgid="3863451714863526143">"ಸ್ಕ್ರೀನ್ ಮೇಲಿರುವ ಪಠ್ಯವನ್ನು ಅನುವಾದಿಸಿ ಅಥವಾ ಆಲಿಸಿ"</string>
- <string name="niu_actions_confirmation_text" msgid="2105271481950866089">"ನಿಮ್ಮ ಸ್ಕ್ರೀನ್ ಮೇಲಿರುವ ಪಠ್ಯ, ವೆಬ್ ವಿಳಾಸಗಳು, ಮತ್ತು ಸ್ಕ್ರೀನ್‌ಶಾಟ್‌ಗಳಂತಹ ಮಾಹಿತಿಯನ್ನು Google ಜೊತೆಗೆ ಹಂಚಿಕೊಳ್ಳಬಹುದು.\n\nನೀವು ಯಾವ ಮಾಹಿತಿಯನ್ನು ಹಂಚಿಕೊಳ್ಳುತ್ತೀರಿ ಎಂಬುದನ್ನು ಬದಲಾಯಿಸಲು, "<b>"ಸೆಟ್ಟಿಂಗ್‌ಗಳು, ಆ್ಯಪ್‌ಗಳು ಮತ್ತು ಡೀಫಾಲ್ಟ್ ಆ್ಯಪ್‌ಗಳು, ಡಿಜಿಟಲ್ ಅಸಿಸ್ಟೆಂಟ್ ಆ್ಯಪ್ ಎಂಬಲ್ಲಿ ಹೋಗಿ"</b>"."</string>
- <string name="assistant_not_selected_title" msgid="5017072974603345228">"ಈ ವೈಶಿಷ್ಟ್ಯವನ್ನು ಬಳಸಲು ಅಸಿಸ್ಟಂಟ್ ಅನ್ನು ಆಯ್ಕೆಮಾಡಿ"</string>
- <string name="assistant_not_selected_text" msgid="3244613673884359276">"ನಿಮ್ಮ ಸ್ಕ್ರೀನ್‌ನಲ್ಲಿರುವ ಪಠ್ಯವನ್ನು ಆಲಿಸಲು ಅಥವಾ ಅನುವಾದಿಸಲು ಸೆಟ್ಟಿಂಗ್‌ಗಳಲ್ಲಿ ಡಿಜಿಟಲ್ ಅಸಿಸ್ಟೆಂಟ್ ಆ್ಯಪ್ ಅನ್ನು ಆಯ್ಕೆಮಾಡಿ"</string>
- <string name="assistant_not_supported_title" msgid="1675788067597484142">"ಈ ವೈಶಿಷ್ಟ್ಯವನ್ನು ಬಳಸಲು ನಿಮ್ಮ ಅಸಿಸ್ಟಂಟ್ ಅನ್ನು ಬದಲಾಯಿಸಿ"</string>
- <string name="assistant_not_supported_text" msgid="1708031078549268884">"ನಿಮ್ಮ ಸ್ಕ್ರೀನ್‌ನಲ್ಲಿರುವ ಪಠ್ಯವನ್ನು ಆಲಿಸಲು ಅಥವಾ ಅನುವಾದಿಸಲು ಸೆಟ್ಟಿಂಗ್‌ಗಳಲ್ಲಿ ನಿಮ್ಮ ಡಿಜಿಟಲ್ ಅಸಿಸ್ಟೆಂಟ್ ಆ್ಯಪ್ ಅನ್ನು ಬದಲಾಯಿಸಿ"</string>
- <string name="tooltip_listen" msgid="7634466447860989102">"ಈ ಸ್ಕ್ರೀನ್‌ನಲ್ಲಿರುವ ಪಠ್ಯವನ್ನು ಆಲಿಸಲು ಇಲ್ಲಿ ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
- <string name="tooltip_translate" msgid="4184845868901542567">"ಈ ಸ್ಕ್ರೀನ್‌ನಲ್ಲಿರುವ ಪಠ್ಯವನ್ನು ಅನುವಾದಿಸಲು ಇಲ್ಲಿ ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
- <string name="toast_p2p_app_not_shareable" msgid="7229739094132131536">"ಈ ಆ್ಯಪ್ ಅನ್ನು ಹಂಚಿಕೊಳ್ಳಲು ಸಾಧ್ಯವಿಲ್ಲ"</string>
-</resources>
diff --git a/go/quickstep/res/values-ko/strings.xml b/go/quickstep/res/values-ko/strings.xml
deleted file mode 100644
index 97ccfefb7a..0000000000
--- a/go/quickstep/res/values-ko/strings.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_share_drop_target_label" msgid="5804774105974539508">"앱 공유"</string>
- <string name="action_listen" msgid="2370304050784689486">"듣기"</string>
- <string name="action_translate" msgid="8028378961867277746">"번역"</string>
- <string name="action_search" msgid="6269564710943755464">"렌즈"</string>
- <string name="dialog_acknowledge" msgid="2804025517675853172">"확인"</string>
- <string name="dialog_cancel" msgid="6464336969134856366">"취소"</string>
- <string name="dialog_settings" msgid="6564397136021186148">"설정"</string>
- <string name="niu_actions_confirmation_title" msgid="3863451714863526143">"화면의 텍스트 번역 또는 듣기"</string>
- <string name="niu_actions_confirmation_text" msgid="2105271481950866089">"화면의 텍스트, 웹 주소, 스크린샷과 같은 정보가 Google과 공유될 수 있습니다.\n\n공유되는 정보를 변경하려면 "<b>"설정 &gt; 앱 &gt; 기본 앱 &gt; 디지털 어시스턴트 앱"</b>"으로 이동하세요."</string>
- <string name="assistant_not_selected_title" msgid="5017072974603345228">"이 기능을 사용하려면 어시스턴트를 선택하세요."</string>
- <string name="assistant_not_selected_text" msgid="3244613673884359276">"화면에서 텍스트를 듣거나 번역하려면 설정에서 디지털 어시스턴트 앱을 선택하세요."</string>
- <string name="assistant_not_supported_title" msgid="1675788067597484142">"어시스턴트가 이 기능을 사용하도록 변경하세요."</string>
- <string name="assistant_not_supported_text" msgid="1708031078549268884">"화면에서 텍스트를 듣거나 번역하려면 설정에서 디지털 어시스턴트 앱을 변경하세요."</string>
- <string name="tooltip_listen" msgid="7634466447860989102">"화면에서 텍스트를 들으려면 여기를 탭하세요."</string>
- <string name="tooltip_translate" msgid="4184845868901542567">"화면에서 텍스트를 번역하려면 여기를 탭하세요."</string>
- <string name="toast_p2p_app_not_shareable" msgid="7229739094132131536">"공유할 수 없는 앱입니다."</string>
-</resources>
diff --git a/go/quickstep/res/values-ky/strings.xml b/go/quickstep/res/values-ky/strings.xml
deleted file mode 100644
index e4a2474669..0000000000
--- a/go/quickstep/res/values-ky/strings.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_share_drop_target_label" msgid="5804774105974539508">"Колдонмону бөлүшүү"</string>
- <string name="action_listen" msgid="2370304050784689486">"Угуу"</string>
- <string name="action_translate" msgid="8028378961867277746">"Которуу"</string>
- <string name="action_search" msgid="6269564710943755464">"Lens"</string>
- <string name="dialog_acknowledge" msgid="2804025517675853172">"ТҮШҮНДҮМ"</string>
- <string name="dialog_cancel" msgid="6464336969134856366">"ЖОККО ЧЫГАРУУ"</string>
- <string name="dialog_settings" msgid="6564397136021186148">"ЖӨНДӨӨЛӨР"</string>
- <string name="niu_actions_confirmation_title" msgid="3863451714863526143">"Экрандагы текстти которуу же угуу"</string>
- <string name="niu_actions_confirmation_text" msgid="2105271481950866089">"Экрандагы текст, веб-даректер жана скриншоттор сыяктуу маалымат Google менен бөлүшүлүшү мүмкүн.\n\nБөлүшүлгөн маалыматты өзгөртүү үчүн"<b>"Жөндөөлөр &gt; Колдонмолор &gt; Демейки колдонмолор &gt; Санариптик жардамчы колдонмосуна өтүңүз"</b>"."</string>
- <string name="assistant_not_selected_title" msgid="5017072974603345228">"Бул функцияны колдонуу үчүн жардамчыны тандаңыз"</string>
- <string name="assistant_not_selected_text" msgid="3244613673884359276">"Экраныңыздагы текстти угуу же которуу үчүн Жөндөөлөрдөн санариптик жардамчы колдонмосун тандаңыз"</string>
- <string name="assistant_not_supported_title" msgid="1675788067597484142">"Бул функцияны колдонуу үчүн жардамчыңызды өзгөртүңүз"</string>
- <string name="assistant_not_supported_text" msgid="1708031078549268884">"Экраныңыздагы текстти угуу же которуу үчүн Жөндөөлөрдөн санариптик жардамчы колдонмосун өзгөртүңүз"</string>
- <string name="tooltip_listen" msgid="7634466447860989102">"Бул экрандагы текстти угуу үчүн бул жерди басыңыз"</string>
- <string name="tooltip_translate" msgid="4184845868901542567">"Бул экрандагы текстти которуу үчүн бул жерди басыңыз"</string>
- <string name="toast_p2p_app_not_shareable" msgid="7229739094132131536">"Бул колдонмону бөлүшүүгө болбойт"</string>
-</resources>
diff --git a/go/quickstep/res/values-lo/strings.xml b/go/quickstep/res/values-lo/strings.xml
deleted file mode 100644
index b6f7b076ba..0000000000
--- a/go/quickstep/res/values-lo/strings.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_share_drop_target_label" msgid="5804774105974539508">"ແບ່ງປັນແອັບ"</string>
- <string name="action_listen" msgid="2370304050784689486">"ຟັງ"</string>
- <string name="action_translate" msgid="8028378961867277746">"ແປພາສາ"</string>
- <string name="action_search" msgid="6269564710943755464">"Lens"</string>
- <string name="dialog_acknowledge" msgid="2804025517675853172">"ເຂົ້າໃຈແລ້ວ"</string>
- <string name="dialog_cancel" msgid="6464336969134856366">"ຍົກເລີກ"</string>
- <string name="dialog_settings" msgid="6564397136021186148">"ການຕັ້ງຄ່າ"</string>
- <string name="niu_actions_confirmation_title" msgid="3863451714863526143">"ແປພາສາ ຫຼື ຟັງຂໍ້ຄວາມຢູ່ໜ້າຈໍ"</string>
- <string name="niu_actions_confirmation_text" msgid="2105271481950866089">"ຂໍ້ມູນ ເຊັ່ນ: ຂໍ້ຄວາມຢູ່ໜ້າຈໍຂອງທ່ານ, ທີ່ຢູ່ເວັບ ແລະ ຮູບໜ້າຈໍອາດຖືກແບ່ງປັນໃຫ້ກັບ Google.\n\nເພື່ອປ່ຽນແປງຂໍ້ມູນທີ່ທ່ານແບ່ງປັນ, ໃຫ້ເຂົ້າໄປ "<b>"ການຕັ້ງຄ່າ &gt; ແອັບ &gt; ແອັບເລີ່ມຕົ້ນ &gt; ແອັບຜູ້ຊ່ວຍດິຈິຕອນ"</b>"."</string>
- <string name="assistant_not_selected_title" msgid="5017072974603345228">"ເລືອກຜູ້ຊ່ວຍເພື່ອໃຊ້ຄຸນສົມບັດນີ້"</string>
- <string name="assistant_not_selected_text" msgid="3244613673884359276">"ເພື່ອຟັງ ຫຼື ແປຂໍ້ຄວາມຢູ່ໜ້າຈໍຂອງທ່ານ, ໃຫ້ເລືອກຜູ້ຊ່ວຍດິຈິຕອນໃດໜຶ່ງໃນການຕັ້ງຄ່າ"</string>
- <string name="assistant_not_supported_title" msgid="1675788067597484142">"ປ່ຽນຜູ້ຊ່ວຍຂອງທ່ານເພື່ອໃຊ້ຄຸນສົມບັດນີ້"</string>
- <string name="assistant_not_supported_text" msgid="1708031078549268884">"ເພື່ອຟັງ ຫຼື ແປຂໍ້ຄວາມຢູ່ໜ້າຈໍຂອງທ່ານ, ໃຫ້ປ່ຽນຜູ້ຊ່ວຍດິຈິຕອນຂອງທ່ານໃນການຕັ້ງຄ່າ"</string>
- <string name="tooltip_listen" msgid="7634466447860989102">"ແຕະບ່ອນນີ້ເພື່ອຟັງຂໍ້ຄວາມຢູ່ໜ້າຈໍນີ້"</string>
- <string name="tooltip_translate" msgid="4184845868901542567">"ແຕະບ່ອນນີ້ເພື່ອແປຂໍ້ຄວາມຢູ່ໜ້າຈໍນີ້"</string>
- <string name="toast_p2p_app_not_shareable" msgid="7229739094132131536">"ບໍ່ສາມາດແບ່ງປັນແອັບນີ້ໄດ້"</string>
-</resources>
diff --git a/go/quickstep/res/values-lt/strings.xml b/go/quickstep/res/values-lt/strings.xml
deleted file mode 100644
index dffe34f689..0000000000
--- a/go/quickstep/res/values-lt/strings.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_share_drop_target_label" msgid="5804774105974539508">"Bendrinti programą"</string>
- <string name="action_listen" msgid="2370304050784689486">"Klausyti"</string>
- <string name="action_translate" msgid="8028378961867277746">"Išversti"</string>
- <string name="action_search" msgid="6269564710943755464">"Lens"</string>
- <string name="dialog_acknowledge" msgid="2804025517675853172">"SUPRATAU"</string>
- <string name="dialog_cancel" msgid="6464336969134856366">"ATŠAUKTI"</string>
- <string name="dialog_settings" msgid="6564397136021186148">"NUSTATYMAI"</string>
- <string name="niu_actions_confirmation_title" msgid="3863451714863526143">"Ekrane esančio teksto vertimas arba klausymas"</string>
- <string name="niu_actions_confirmation_text" msgid="2105271481950866089">"Tam tikra informacija, pvz., ekrane esantis tekstas, žiniatinklio adresai ir ekrano kopijos, gali būti bendrinama su „Google“.\n\nJei norite pakeisti, kokia informacija gali būti bendrinama, eikite į "<b>"„Nustatymai“ &gt; „Programos“ &gt; „Numatytosios programos“ &gt; „Skaitmeninio pagelbiklio programa“"</b>"."</string>
- <string name="assistant_not_selected_title" msgid="5017072974603345228">"Norint naudoti šią funkciją, reikia pasirinkti pagelbiklį"</string>
- <string name="assistant_not_selected_text" msgid="3244613673884359276">"Jei norite klausyti teksto ekrane ar jį išversti, pasirinkite skaitmeninio pagelbiklio programą „Nustatymų“ skiltyje"</string>
- <string name="assistant_not_supported_title" msgid="1675788067597484142">"Norint naudoti šią funkciją, reikia pakeisti pagelbiklį"</string>
- <string name="assistant_not_supported_text" msgid="1708031078549268884">"Jei norite klausyti teksto ekrane ar jį išversti, pakeiskite skaitmeninio pagelbiklio programą „Nustatymų“ skiltyje"</string>
- <string name="tooltip_listen" msgid="7634466447860989102">"Palieskite čia, jei norite klausyti teksto šiame ekrane"</string>
- <string name="tooltip_translate" msgid="4184845868901542567">"Palieskite čia, jei norite išversti tekstą šiame ekrane"</string>
- <string name="toast_p2p_app_not_shareable" msgid="7229739094132131536">"Šios programos negalima bendrinti"</string>
-</resources>
diff --git a/go/quickstep/res/values-lv/strings.xml b/go/quickstep/res/values-lv/strings.xml
deleted file mode 100644
index faf3274bda..0000000000
--- a/go/quickstep/res/values-lv/strings.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_share_drop_target_label" msgid="5804774105974539508">"Kopīgot lietotni"</string>
- <string name="action_listen" msgid="2370304050784689486">"Klausīties"</string>
- <string name="action_translate" msgid="8028378961867277746">"Tulkot"</string>
- <string name="action_search" msgid="6269564710943755464">"Lens"</string>
- <string name="dialog_acknowledge" msgid="2804025517675853172">"LABI"</string>
- <string name="dialog_cancel" msgid="6464336969134856366">"ATCELT"</string>
- <string name="dialog_settings" msgid="6564397136021186148">"IESTATĪJUMI"</string>
- <string name="niu_actions_confirmation_title" msgid="3863451714863526143">"Ekrānā redzamā teksta atskaņošana vai tulkošana"</string>
- <string name="niu_actions_confirmation_text" msgid="2105271481950866089">"Ar uzņēmumu Google var tikt kopīgota noteikta informācija, piemēram, ekrānā redzamais teksts, tīmekļa adreses un ekrānuzņēmumi.\n\nLai mainītu kopīgotās informācijas veidu, atveriet sadaļu "<b>"Iestatījumi &gt; Lietotnes &gt; Noklusējuma lietotnes &gt; Digitālā asistenta lietotne"</b>"."</string>
- <string name="assistant_not_selected_title" msgid="5017072974603345228">"Lai izmantotu šo funkciju, izvēlieties asistentu"</string>
- <string name="assistant_not_selected_text" msgid="3244613673884359276">"Lai klausītos vai tulkotu ekrānā parādīto tekstu, iestatījumos izvēlieties digitālā asistenta lietotni"</string>
- <string name="assistant_not_supported_title" msgid="1675788067597484142">"Lai izmantotu šo funkciju, mainiet asistentu"</string>
- <string name="assistant_not_supported_text" msgid="1708031078549268884">"Lai klausītos vai tulkotu ekrānā parādīto tekstu, iestatījumos mainiet digitālā asistenta lietotni"</string>
- <string name="tooltip_listen" msgid="7634466447860989102">"Lai klausītos ekrānā parādīto tekstu, pieskarieties šeit"</string>
- <string name="tooltip_translate" msgid="4184845868901542567">"Lai tulkotu ekrānā parādīto tekstu, pieskarieties šeit"</string>
- <string name="toast_p2p_app_not_shareable" msgid="7229739094132131536">"Šo lietotni nevar kopīgot."</string>
-</resources>
diff --git a/go/quickstep/res/values-mk/strings.xml b/go/quickstep/res/values-mk/strings.xml
deleted file mode 100644
index 7e8cecf0f6..0000000000
--- a/go/quickstep/res/values-mk/strings.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_share_drop_target_label" msgid="5804774105974539508">"Сподели апликација"</string>
- <string name="action_listen" msgid="2370304050784689486">"Слушај"</string>
- <string name="action_translate" msgid="8028378961867277746">"Преведи"</string>
- <string name="action_search" msgid="6269564710943755464">"Lens"</string>
- <string name="dialog_acknowledge" msgid="2804025517675853172">"СФАТИВ"</string>
- <string name="dialog_cancel" msgid="6464336969134856366">"ОТКАЖИ"</string>
- <string name="dialog_settings" msgid="6564397136021186148">"ПОСТАВКИ"</string>
- <string name="niu_actions_confirmation_title" msgid="3863451714863526143">"Преведете или слушајте текст на екранот"</string>
- <string name="niu_actions_confirmation_text" msgid="2105271481950866089">"Информациите како текст на екранот, интернет-адреси и слики од екранот може да се споделуваат со Google.\n\nЗа да промените кои информации ќе се споделуваат, одете во "<b>"Поставки &gt; Апликации &gt; Стандардни апликации &gt; Апликација за дигитален помошник"</b>"."</string>
- <string name="assistant_not_selected_title" msgid="5017072974603345228">"Изберете помошник за да ја користите функцијава"</string>
- <string name="assistant_not_selected_text" msgid="3244613673884359276">"За да го слушнете или преведете текстот од екранот, изберете ја апликацијата за дигитален помошник во „Поставки“"</string>
- <string name="assistant_not_supported_title" msgid="1675788067597484142">"Променете го помошникот за да ја користите функцијава"</string>
- <string name="assistant_not_supported_text" msgid="1708031078549268884">"За да го слушнете или преведете текстот од екранот, променете ја апликацијата за дигитален помошник во „Поставки“"</string>
- <string name="tooltip_listen" msgid="7634466447860989102">"Допрете тука за да го слушнете текстот од екранов"</string>
- <string name="tooltip_translate" msgid="4184845868901542567">"Допрете тука за да го преведете текстот од екранов"</string>
- <string name="toast_p2p_app_not_shareable" msgid="7229739094132131536">"Апликацијава не може да се сподели"</string>
-</resources>
diff --git a/go/quickstep/res/values-ml/strings.xml b/go/quickstep/res/values-ml/strings.xml
deleted file mode 100644
index 19d0b75a5e..0000000000
--- a/go/quickstep/res/values-ml/strings.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_share_drop_target_label" msgid="5804774105974539508">"ആപ്പ് പങ്കിടുക"</string>
- <string name="action_listen" msgid="2370304050784689486">"കേൾക്കുക"</string>
- <string name="action_translate" msgid="8028378961867277746">"വിവർത്തനം ചെയ്യുക"</string>
- <string name="action_search" msgid="6269564710943755464">"ലെൻസ്"</string>
- <string name="dialog_acknowledge" msgid="2804025517675853172">"മനസ്സിലായി"</string>
- <string name="dialog_cancel" msgid="6464336969134856366">"റദ്ദാക്കുക"</string>
- <string name="dialog_settings" msgid="6564397136021186148">"ക്രമീകരണം"</string>
- <string name="niu_actions_confirmation_title" msgid="3863451714863526143">"സ്ക്രീനിലെ ടെക്സ്റ്റ് വിവർത്തനം ചെയ്യുകയോ കേൾക്കുകയോ ചെയ്യുക"</string>
- <string name="niu_actions_confirmation_text" msgid="2105271481950866089">"നിങ്ങളുടെ സ്ക്രീനിലെ ടെക്സ്റ്റ്, വെബ് വിലാസങ്ങൾ, സ്ക്രീൻഷോട്ടുകൾ എന്നിവ പോലുള്ള വിവരങ്ങൾ Google-മായി പങ്കിട്ടേക്കാം.\n\nനിങ്ങൾ പങ്കിടുന്ന വിവരങ്ങൾ മാറ്റാൻ, "<b>"ക്രമീകരണ &gt; ആപ്പുകൾ &gt; ഡിഫോൾട്ട് ആപ്പുകൾ &gt; ഡിജിറ്റൽ അസിസ്‌റ്റന്റ് ആപ്പ്"</b>" എന്നതിലേക്ക് പോകുക."</string>
- <string name="assistant_not_selected_title" msgid="5017072974603345228">"ഈ ഫീച്ചർ ഉപയോഗിക്കാൻ, ഒരു അസിസ്‌റ്റന്റ് തിരഞ്ഞെടുക്കുക"</string>
- <string name="assistant_not_selected_text" msgid="3244613673884359276">"നിങ്ങളുടെ സ്ക്രീനിലുള്ള ടെക്‌സ്‌റ്റ് കേൾക്കാനോ വിവർത്തനം ചെയ്യാനോ, ക്രമീകരണത്തിൽ നിന്ന് ഒരു ഡിജിറ്റൽ അസിസ്‌റ്റന്റ് ആപ്പ് തിരഞ്ഞെടുക്കുക"</string>
- <string name="assistant_not_supported_title" msgid="1675788067597484142">"ഈ ഫീച്ചർ ഉപയോഗിക്കാൻ, നിങ്ങളുടെ അസിസ്‌റ്റന്റ് മാറ്റുക"</string>
- <string name="assistant_not_supported_text" msgid="1708031078549268884">"നിങ്ങളുടെ സ്ക്രീനിലുള്ള ടെക്‌സ്‌റ്റ് കേൾക്കാനോ വിവർത്തനം ചെയ്യാനോ, ക്രമീകരണത്തിലെ നിങ്ങളുടെ ഡിജിറ്റൽ അസിസ്‌റ്റന്റ് ആപ്പ് മാറ്റുക"</string>
- <string name="tooltip_listen" msgid="7634466447860989102">"ഈ സ്ക്രീനിലെ ടെക്‌സ്‌റ്റ് കേൾക്കാൻ, ഇവിടെ ടാപ്പ് ചെയ്യുക"</string>
- <string name="tooltip_translate" msgid="4184845868901542567">"ഈ സ്ക്രീനിലെ ടെക്‌സ്‌റ്റ് വിവർത്തനം ചെയ്യാൻ, ഇവിടെ ടാപ്പ് ചെയ്യുക"</string>
- <string name="toast_p2p_app_not_shareable" msgid="7229739094132131536">"ഈ ആപ്പ് പങ്കിടാനാകില്ല"</string>
-</resources>
diff --git a/go/quickstep/res/values-mn/strings.xml b/go/quickstep/res/values-mn/strings.xml
deleted file mode 100644
index 2eb3c98979..0000000000
--- a/go/quickstep/res/values-mn/strings.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_share_drop_target_label" msgid="5804774105974539508">"Аппыг хуваалцах"</string>
- <string name="action_listen" msgid="2370304050784689486">"Сонсох"</string>
- <string name="action_translate" msgid="8028378961867277746">"Орчуулах"</string>
- <string name="action_search" msgid="6269564710943755464">"Дуран"</string>
- <string name="dialog_acknowledge" msgid="2804025517675853172">"ОЙЛГОЛОО"</string>
- <string name="dialog_cancel" msgid="6464336969134856366">"ЦУЦЛАХ"</string>
- <string name="dialog_settings" msgid="6564397136021186148">"ТОХИРГОО"</string>
- <string name="niu_actions_confirmation_title" msgid="3863451714863526143">"Дэлгэц дээрх текстийг орчуулах эсвэл сонсох"</string>
- <string name="niu_actions_confirmation_text" msgid="2105271481950866089">"Таны дэлгэц дээрх текст, веб хаяг, дэлгэцийн агшин зэрэг мэдээллийг Google-тэй хуваалцаж болзошгүй.\n\nТа ямар мэдээлэл хуваалцахаа өөрчлөхийн тулд "<b>"Тохиргоо &gt; Апп &gt; Өгөгдмөл апп &gt; Дижитал туслах апп"</b>" руу очно уу."</string>
- <string name="assistant_not_selected_title" msgid="5017072974603345228">"Энэ онцлогийг ашиглахын тулд туслах сонгоно уу"</string>
- <string name="assistant_not_selected_text" msgid="3244613673884359276">"Дэлгэц дээрээ текст сонсох эсвэл орчуулахын тулд Тохиргоо хэсэгт дижитал туслах аппыг сонгоно уу"</string>
- <string name="assistant_not_supported_title" msgid="1675788067597484142">"Энэ онцлогийг ашиглахын тулд туслахаа өөрчилнө үү"</string>
- <string name="assistant_not_supported_text" msgid="1708031078549268884">"Дэлгэц дээрээ текст сонсох эсвэл орчуулахын тулд Тохиргоо хэсэгт дижитал туслах аппаа өөрчилнө үү"</string>
- <string name="tooltip_listen" msgid="7634466447860989102">"Энэ дэлгэц дээр текст сонсохын тулд энд товшино уу"</string>
- <string name="tooltip_translate" msgid="4184845868901542567">"Энэ дэлгэц дээр текст орчуулахын тулд энд товшино уу"</string>
- <string name="toast_p2p_app_not_shareable" msgid="7229739094132131536">"Энэ аппыг хуваалцах боломжгүй"</string>
-</resources>
diff --git a/go/quickstep/res/values-mr/strings.xml b/go/quickstep/res/values-mr/strings.xml
deleted file mode 100644
index d3dff929d0..0000000000
--- a/go/quickstep/res/values-mr/strings.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_share_drop_target_label" msgid="5804774105974539508">"अ‍ॅप शेअर करा"</string>
- <string name="action_listen" msgid="2370304050784689486">"ऐका"</string>
- <string name="action_translate" msgid="8028378961867277746">"भाषांतर करा"</string>
- <string name="action_search" msgid="6269564710943755464">"Lens"</string>
- <string name="dialog_acknowledge" msgid="2804025517675853172">"समजले"</string>
- <string name="dialog_cancel" msgid="6464336969134856366">"रद्द करा"</string>
- <string name="dialog_settings" msgid="6564397136021186148">"सेटिंग्ज"</string>
- <string name="niu_actions_confirmation_title" msgid="3863451714863526143">"स्क्रीनवरील मजकूर भाषांतरित करा किंवा ऐका"</string>
- <string name="niu_actions_confirmation_text" msgid="2105271481950866089">"तुमच्या स्क्रीनवरील मजकूर, वेब अ‍ॅड्रेस आणि स्क्रीनशॉट यांसारखी माहिती Google सह शेअर केली जाऊ शकते.\n\nतुम्ही कोणती माहिती शेअर करता हे बदलण्यासाठी "<b>"सेटिंग्ज &gt; ॲप्स &gt; डीफॉल्ट ॲप्स &gt; डिजिटल असिस्टंट ॲपवर जा"</b>"."</string>
- <string name="assistant_not_selected_title" msgid="5017072974603345228">"हे वैशिष्ट्य वापरण्यासाठी तुमचे असिस्टंट निवडा"</string>
- <string name="assistant_not_selected_text" msgid="3244613673884359276">"तुमच्या स्क्रीनवरील मजकूर ऐकण्यासाठी किंवा भाषांतर करण्यासाठी, सेटिंग्ज मध्ये तुमचे डिजिटल असिस्टंट अ‍ॅप निवडा"</string>
- <string name="assistant_not_supported_title" msgid="1675788067597484142">"हे वैशिष्ट्य वापरण्यासाठी असिस्टंट बदला"</string>
- <string name="assistant_not_supported_text" msgid="1708031078549268884">"तुमच्या स्क्रीनवरील मजकूर ऐकण्यासाठी किंवा भाषांतर करण्यासाठी, सेटिंग्ज मध्ये तुमचे डिजिटल असिस्टंट अ‍ॅप बदला"</string>
- <string name="tooltip_listen" msgid="7634466447860989102">"या स्क्रीनवरील मजकूर ऐकण्यासाठी येथे टॅप करा"</string>
- <string name="tooltip_translate" msgid="4184845868901542567">"या स्क्रीनवरील मजकुराचे भाषांतर करण्यासाठी येथे टॅप करा"</string>
- <string name="toast_p2p_app_not_shareable" msgid="7229739094132131536">"हे ॲप शेअर केले जाऊ शकत नाही"</string>
-</resources>
diff --git a/go/quickstep/res/values-ms/strings.xml b/go/quickstep/res/values-ms/strings.xml
deleted file mode 100644
index 36e167878a..0000000000
--- a/go/quickstep/res/values-ms/strings.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_share_drop_target_label" msgid="5804774105974539508">"Kongsi Apl"</string>
- <string name="action_listen" msgid="2370304050784689486">"Dengar"</string>
- <string name="action_translate" msgid="8028378961867277746">"Terjemah"</string>
- <string name="action_search" msgid="6269564710943755464">"Kanta"</string>
- <string name="dialog_acknowledge" msgid="2804025517675853172">"OK"</string>
- <string name="dialog_cancel" msgid="6464336969134856366">"BATAL"</string>
- <string name="dialog_settings" msgid="6564397136021186148">"TETAPAN"</string>
- <string name="niu_actions_confirmation_title" msgid="3863451714863526143">"Terjemahkan atau dengar teks pada skrin"</string>
- <string name="niu_actions_confirmation_text" msgid="2105271481950866089">"Maklumat seperti teks pada skrin anda, alamat web dan tangkapan skrin boleh dikongsi dengan Google.\n\nUntuk menukar maklumat yang anda kongsi, pergi ke "<b>"Tetapan &gt; Apl &gt; Apl lalai &gt; Apl pembantu digital"</b>"."</string>
- <string name="assistant_not_selected_title" msgid="5017072974603345228">"Pilih pembantu untuk menggunakan ciri ini"</string>
- <string name="assistant_not_selected_text" msgid="3244613673884359276">"Untuk mendengar atau menterjemahkan teks pada skrin anda, pilih apl pembantu digital dalam Tetapan"</string>
- <string name="assistant_not_supported_title" msgid="1675788067597484142">"Tukar pembantu anda untuk menggunakan ciri ini"</string>
- <string name="assistant_not_supported_text" msgid="1708031078549268884">"Untuk mendengar atau menterjemahkan teks pada skrin anda, tukar apl pembantu digital anda dalam Tetapan"</string>
- <string name="tooltip_listen" msgid="7634466447860989102">"Ketik di sini untuk mendengar teks pada skrin ini"</string>
- <string name="tooltip_translate" msgid="4184845868901542567">"Ketik di sini untuk menterjemahkan teks pada skrin ini"</string>
- <string name="toast_p2p_app_not_shareable" msgid="7229739094132131536">"Apl ini tidak boleh dikongsi"</string>
-</resources>
diff --git a/go/quickstep/res/values-my/strings.xml b/go/quickstep/res/values-my/strings.xml
deleted file mode 100644
index 0ca0e9c0bf..0000000000
--- a/go/quickstep/res/values-my/strings.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_share_drop_target_label" msgid="5804774105974539508">"အက်ပ် မျှဝေရန်"</string>
- <string name="action_listen" msgid="2370304050784689486">"နားထောင်ရန်"</string>
- <string name="action_translate" msgid="8028378961867277746">"ဘာသာပြန်ရန်"</string>
- <string name="action_search" msgid="6269564710943755464">"Lens"</string>
- <string name="dialog_acknowledge" msgid="2804025517675853172">"ရပြီ"</string>
- <string name="dialog_cancel" msgid="6464336969134856366">"မလုပ်တော့"</string>
- <string name="dialog_settings" msgid="6564397136021186148">"ဆက်တင်များ"</string>
- <string name="niu_actions_confirmation_title" msgid="3863451714863526143">"ဖန်သားပြင်ပေါ်ရှိ စာသားကို ဘာသာပြန်ပါ (သို့) နားထောင်ပါ"</string>
- <string name="niu_actions_confirmation_text" msgid="2105271481950866089">"သင့်ဖန်သားပြင်ပေါ်ရှိ စာသား၊ ဝဘ်လိပ်စာနှင့် ဖန်သားပြင်ဓာတ်ပုံများကဲ့သို့ အချက်အလက်များကို Google နှင့် မျှဝေနိုင်သည်။\n\nသင်မျှဝေသည့် အချက်အလက်များကို ပြောင်းရန် "<b>"ဆက်တင်များ &gt; အက်ပ်များ &gt; မူရင်းအက်ပ်များ &gt; ဒစ်ဂျစ်တယ် Assistant အက်ပ်"</b>" သို့ သွားပါ။"</string>
- <string name="assistant_not_selected_title" msgid="5017072974603345228">"ဤဝန်ဆောင်မှုကို အသုံးပြုရန် assistant ရွေးပါ"</string>
- <string name="assistant_not_selected_text" msgid="3244613673884359276">"ဖန်သားပြင်ပေါ်ရှိ စာသားကို နားထောင်ရန် (သို့) ဘာသာပြန်ဆိုရန် ‘ဆက်တင်များ’ တွင် ဒစ်ဂျစ်တယ် assistant အက်ပ် ရွေးပါ"</string>
- <string name="assistant_not_supported_title" msgid="1675788067597484142">"ဤဝန်ဆောင်မှုကို သုံးရန် assistant ကို ပြောင်းပါ"</string>
- <string name="assistant_not_supported_text" msgid="1708031078549268884">"ဖန်သားပြင်ပေါ်ရှိ စာသားကို နားထောင်ရန် (သို့) ဘာသာပြန်ဆိုရန် ‘ဆက်တင်များ’ တွင် ဒစ်ဂျစ်တယ် assistant အက်ပ်ကို ပြောင်းပါ"</string>
- <string name="tooltip_listen" msgid="7634466447860989102">"ဤဖန်သားပြင်ပေါ်ရှိ စာသားကို နားထောင်ရန် ဤနေရာကို တို့ပါ"</string>
- <string name="tooltip_translate" msgid="4184845868901542567">"ဤဖန်သားပြင်ပေါ်ရှိ စာသားကို ဘာသာပြန်ဆိုရန် ဤနေရာကို တို့ပါ"</string>
- <string name="toast_p2p_app_not_shareable" msgid="7229739094132131536">"ဤအက်ပ်ကို မျှဝေ၍မရပါ"</string>
-</resources>
diff --git a/go/quickstep/res/values-nb/strings.xml b/go/quickstep/res/values-nb/strings.xml
deleted file mode 100644
index 662b544fd3..0000000000
--- a/go/quickstep/res/values-nb/strings.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_share_drop_target_label" msgid="5804774105974539508">"Del appen"</string>
- <string name="action_listen" msgid="2370304050784689486">"Lytt"</string>
- <string name="action_translate" msgid="8028378961867277746">"Oversett"</string>
- <string name="action_search" msgid="6269564710943755464">"Lens"</string>
- <string name="dialog_acknowledge" msgid="2804025517675853172">"GREIT"</string>
- <string name="dialog_cancel" msgid="6464336969134856366">"AVBRYT"</string>
- <string name="dialog_settings" msgid="6564397136021186148">"INNSTILLINGER"</string>
- <string name="niu_actions_confirmation_title" msgid="3863451714863526143">"Oversett eller lytt til tekst på skjermen"</string>
- <string name="niu_actions_confirmation_text" msgid="2105271481950866089">"Informasjon som tekst på skjermen, nettadresser og skjermdumper kan deles med Google.\n\nFor å endre hvilken informasjon du deler, gå til "<b>"Innstillinger &gt; Apper &gt; Standardapper &gt; Digital assistent-app"</b>"."</string>
- <string name="assistant_not_selected_title" msgid="5017072974603345228">"Velg en assistent for å bruke denne funksjonen"</string>
- <string name="assistant_not_selected_text" msgid="3244613673884359276">"For å høre eller oversette tekst på skjermen, velg en digital assistent-app i innstillingene"</string>
- <string name="assistant_not_supported_title" msgid="1675788067597484142">"Endre assistenten for å bruke denne funksjonen"</string>
- <string name="assistant_not_supported_text" msgid="1708031078549268884">"For å høre eller oversette tekst på skjermen, endre digital assistent-appen i innstillingene"</string>
- <string name="tooltip_listen" msgid="7634466447860989102">"Trykk her for å høre teksten på denne skjermen"</string>
- <string name="tooltip_translate" msgid="4184845868901542567">"Trykk her for å oversette teksten på denne skjermen"</string>
- <string name="toast_p2p_app_not_shareable" msgid="7229739094132131536">"Denne appen kan ikke deles"</string>
-</resources>
diff --git a/go/quickstep/res/values-ne/strings.xml b/go/quickstep/res/values-ne/strings.xml
deleted file mode 100644
index 11a70dd74a..0000000000
--- a/go/quickstep/res/values-ne/strings.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_share_drop_target_label" msgid="5804774105974539508">"एप सेयर गर्नुहोस्"</string>
- <string name="action_listen" msgid="2370304050784689486">"सुन्नुहोस्"</string>
- <string name="action_translate" msgid="8028378961867277746">"अनुवाद गर्नुहोस्"</string>
- <string name="action_search" msgid="6269564710943755464">"लेन्स"</string>
- <string name="dialog_acknowledge" msgid="2804025517675853172">"बुझेँ"</string>
- <string name="dialog_cancel" msgid="6464336969134856366">"रद्द गर्नुहोस्"</string>
- <string name="dialog_settings" msgid="6564397136021186148">"सेटिङ"</string>
- <string name="niu_actions_confirmation_title" msgid="3863451714863526143">"स्क्रिनमा देखिने पाठ अनुवाद गरियोस् वा पढेर सुनाइयोस्"</string>
- <string name="niu_actions_confirmation_text" msgid="2105271481950866089">"तपाईंको स्क्रिनमा देखिने पाठ, वेब ठेगाना र स्क्रिनसटलगायतका जानकारी Google सँग सेयर गर्न सकिन्छ।\n\nकुन कुन जानकारी सेयर गर्न दिने भन्ने सेटिङ बदल्न "<b>"सेटिङ &gt; एप &gt; डिफल्ट एप &gt; डिजिटल सहायक एप"</b>" मा जानुहोस्।"</string>
- <string name="assistant_not_selected_title" msgid="5017072974603345228">"तपाईं यो सुविधा चलाउन चाहनुहुन्छ भने कुनै सहायक छनौट गर्नुहोस्"</string>
- <string name="assistant_not_selected_text" msgid="3244613673884359276">"तपाईं आफ्नो स्क्रिनमा देखिने पाठ सुन्न वा अनुवाद गर्न चाहनुहुन्छ भने सेटिङमा गई कुनै डिजिटल सहायक एप छनौट गर्नुहोस्"</string>
- <string name="assistant_not_supported_title" msgid="1675788067597484142">"तपाईं यो सुविधा चलाउन चाहनुहुन्छ भने आफ्नो सहायक परिवर्तन गर्नुहोस्"</string>
- <string name="assistant_not_supported_text" msgid="1708031078549268884">"तपाईं आफ्नो स्क्रिनमा देखिने पाठ सुन्न वा अनुवाद गर्न चाहनुहुन्छ भने सेटिङमा गई कुनै डिजिटल सहायक एप परिर्वर्तन गर्नुहोस्"</string>
- <string name="tooltip_listen" msgid="7634466447860989102">"तपाईं यो स्क्रिनमा देखिने पाठ सुन्न चाहनुहुन्छ यहाँ ट्याप गर्नुहोस्"</string>
- <string name="tooltip_translate" msgid="4184845868901542567">"तपाईं यो स्क्रिनमा देखिने पाठ अनुवाद गर्न चाहनुहुन्छ यहाँ ट्याप गर्नुहोस्"</string>
- <string name="toast_p2p_app_not_shareable" msgid="7229739094132131536">"यो एप अरूलाई चलाउन दिन मिल्दैन"</string>
-</resources>
diff --git a/go/quickstep/res/values-nl/strings.xml b/go/quickstep/res/values-nl/strings.xml
deleted file mode 100644
index 2d4c6e260b..0000000000
--- a/go/quickstep/res/values-nl/strings.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_share_drop_target_label" msgid="5804774105974539508">"App delen"</string>
- <string name="action_listen" msgid="2370304050784689486">"Luisteren"</string>
- <string name="action_translate" msgid="8028378961867277746">"Vertalen"</string>
- <string name="action_search" msgid="6269564710943755464">"Lens"</string>
- <string name="dialog_acknowledge" msgid="2804025517675853172">"OK"</string>
- <string name="dialog_cancel" msgid="6464336969134856366">"ANNULEREN"</string>
- <string name="dialog_settings" msgid="6564397136021186148">"INSTELLINGEN"</string>
- <string name="niu_actions_confirmation_title" msgid="3863451714863526143">"Tekst op het scherm vertalen of beluisteren"</string>
- <string name="niu_actions_confirmation_text" msgid="2105271481950866089">"Informatie zoals tekst op je scherm, webadressen en screenshots kan met Google worden gedeeld.\n\nAls je wilt aanpassen welke informatie je deelt, ga je naar "<b>"Instellingen &gt; Apps &gt; Standaard-apps &gt; Digitale-assistent-app"</b>"."</string>
- <string name="assistant_not_selected_title" msgid="5017072974603345228">"Kies een assistent om deze functie te gebruiken"</string>
- <string name="assistant_not_selected_text" msgid="3244613673884359276">"Als je tekst op je scherm wilt beluisteren of vertalen, kies je een digitale-assistent-app in Instellingen"</string>
- <string name="assistant_not_supported_title" msgid="1675788067597484142">"Wijzig de assistent om deze functie te gebruiken"</string>
- <string name="assistant_not_supported_text" msgid="1708031078549268884">"Als je tekst op je scherm wilt beluisteren of vertalen, wijzig je de digitale-assistent-app in Instellingen"</string>
- <string name="tooltip_listen" msgid="7634466447860989102">"Tik hier om tekst op dit scherm te beluisteren"</string>
- <string name="tooltip_translate" msgid="4184845868901542567">"Tik hier om tekst op dit scherm te vertalen"</string>
- <string name="toast_p2p_app_not_shareable" msgid="7229739094132131536">"Deze app kan niet worden gedeeld"</string>
-</resources>
diff --git a/go/quickstep/res/values-or/strings.xml b/go/quickstep/res/values-or/strings.xml
deleted file mode 100644
index 36204a32ce..0000000000
--- a/go/quickstep/res/values-or/strings.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_share_drop_target_label" msgid="5804774105974539508">"ଆପ୍ ସେୟାର୍ କରନ୍ତୁ"</string>
- <string name="action_listen" msgid="2370304050784689486">"ଶୁଣନ୍ତୁ"</string>
- <string name="action_translate" msgid="8028378961867277746">"ଅନୁବାଦ କରନ୍ତୁ"</string>
- <string name="action_search" msgid="6269564710943755464">"Lens"</string>
- <string name="dialog_acknowledge" msgid="2804025517675853172">"ବୁଝିଗଲି"</string>
- <string name="dialog_cancel" msgid="6464336969134856366">"ବାତିଲ୍ କରନ୍ତୁ"</string>
- <string name="dialog_settings" msgid="6564397136021186148">"ସେଟିଂସ୍"</string>
- <string name="niu_actions_confirmation_title" msgid="3863451714863526143">"ସ୍କିନରେ ଥିବା ଟେକ୍ସଟକୁ ଅନୁବାଦ କରନ୍ତୁ କିମ୍ବା ଶୁଣନ୍ତୁ"</string>
- <string name="niu_actions_confirmation_text" msgid="2105271481950866089">"ଆପଣଙ୍କ ସ୍କ୍ରିନରେ ଟେକ୍ସଟ୍, ୱେବ୍ ଠିକଣା ଏବଂ ସ୍କ୍ରିନସଟଗୁଡ଼ିକ ପରି ସୂଚନାକୁ Google ସହ ସେୟାର୍ କରାଯାଇପାରେ।\n\nଆପଣ କେଉଁ ସୂଚନା ସେୟାର୍ କରନ୍ତି ତାହା ପରିବର୍ତ୍ତନ କରିବାକୁ, "<b>"ସେଟିଂସ୍ &gt; ଆପ୍ସ &gt; ଡିଫଲ୍ଟ ଆପ୍ସ &gt; ଡିଜିଟାଲ୍ ଆସିଷ୍ଟାଣ୍ଟ ଆପ"</b>"କୁ ଯାଆନ୍ତୁ।"</string>
- <string name="assistant_not_selected_title" msgid="5017072974603345228">"ଏହି ଫିଚର୍ ବ୍ୟବହାର କରିବାକୁ ଏକ ଆସିଷ୍ଟାଣ୍ଟ ବାଛନ୍ତୁ"</string>
- <string name="assistant_not_selected_text" msgid="3244613673884359276">"ଆପଣଙ୍କ ସ୍କ୍ରିନରେ ଥିବା ଟେକ୍ସଟକୁ ଶୁଣିବା ପାଇଁ କିମ୍ବା ଅନୁବାଦ କରିବାକୁ, ସେଟିଂସରେ ଏକ ଡିଜିଟାଲ୍ ଆସିଷ୍ଟାଣ୍ଟ ଆପ୍ ଚୟନ କରନ୍ତୁ"</string>
- <string name="assistant_not_supported_title" msgid="1675788067597484142">"ଏହି ଫିଚର୍ ବ୍ୟବହାର କରିବା ପାଇଁ ଆପଣଙ୍କ ଆସିଷ୍ଟାଣ୍ଟକୁ ବଦଳାନ୍ତୁ"</string>
- <string name="assistant_not_supported_text" msgid="1708031078549268884">"ଆପଣଙ୍କ ସ୍କ୍ରିନରେ ଥିବା ଟେକ୍ସଟକୁ ଶୁଣିବା ପାଇଁ କିମ୍ବା ଅନୁବାଦ କରିବାକୁ, ସେଟିଂସରେ ଆପଣଙ୍କ ଡିଜିଟାଲ୍ ଆସିଷ୍ଟାଣ୍ଟ ଆପକୁ ବଦଳାନ୍ତୁ"</string>
- <string name="tooltip_listen" msgid="7634466447860989102">"ଏହି ସ୍କ୍ରିନରେ ଥିବା ଟେକ୍ସଟକୁ ଶୁଣିବା ପାଇଁ ଏଠାରେ ଟାପ୍ କରନ୍ତୁ"</string>
- <string name="tooltip_translate" msgid="4184845868901542567">"ଏହି ସ୍କ୍ରିନରେ ଥିବା ଟେକ୍ସଟକୁ ଅନୁବାଦ କରିବା ପାଇଁ ଏଠାରେ ଟାପ୍ କରନ୍ତୁ"</string>
- <string name="toast_p2p_app_not_shareable" msgid="7229739094132131536">"ଏହି ଆପ ସେୟାର କରାଯାଇପାରିବ ନାହିଁ"</string>
-</resources>
diff --git a/go/quickstep/res/values-pa/strings.xml b/go/quickstep/res/values-pa/strings.xml
deleted file mode 100644
index 8549b586c1..0000000000
--- a/go/quickstep/res/values-pa/strings.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_share_drop_target_label" msgid="5804774105974539508">"ਐਪ ਨੂੰ ਸਾਂਝਾ ਕਰੋ"</string>
- <string name="action_listen" msgid="2370304050784689486">"ਸੁਣੋ"</string>
- <string name="action_translate" msgid="8028378961867277746">"ਅਨੁਵਾਦ ਕਰੋ"</string>
- <string name="action_search" msgid="6269564710943755464">"Lens"</string>
- <string name="dialog_acknowledge" msgid="2804025517675853172">"ਸਮਝ ਲਿਆ"</string>
- <string name="dialog_cancel" msgid="6464336969134856366">"ਰੱਦ ਕਰੋ"</string>
- <string name="dialog_settings" msgid="6564397136021186148">"ਸੈਟਿੰਗਾਂ"</string>
- <string name="niu_actions_confirmation_title" msgid="3863451714863526143">"ਸਕ੍ਰੀਨ \'ਤੇ ਦਿੱਤੀ ਲਿਖਤ ਦਾ ਅਨੁਵਾਦ ਕਰੋ ਜਾਂ ਉਸਨੂੰ ਸੁਣੋ"</string>
- <string name="niu_actions_confirmation_text" msgid="2105271481950866089">"ਤੁਹਾਡੀ ਸਕ੍ਰੀਨ \'ਤੇ ਦਿੱਤੀ ਲਿਖਤ, ਵੈੱਬ ਪਤਿਆਂ ਅਤੇ ਸਕ੍ਰੀਨਸ਼ਾਟਾਂ ਵਰਗੀ ਜਾਣਕਾਰੀ ਨੂੰ Google ਨਾਲ ਸਾਂਝਾ ਕੀਤਾ ਜਾ ਸਕਦਾ ਹੈ।\n\nਤੁਹਾਡੇ ਵੱਲੋਂ ਸਾਂਝੀ ਕੀਤੀ ਜਾਣਕਾਰੀ ਨੂੰ ਬਦਲਣ ਲਈ, "<b>"ਸੈਟਿੰਗਾਂ &gt; ਐਪਾਂ &gt; ਪੂਰਵ-ਨਿਰਧਾਰਿਤ ਐਪਾਂ &gt; ਡਿਜੀਟਲ ਸਹਾਇਕ ਐਪ"</b>" \'ਤੇ ਜਾਓ।"</string>
- <string name="assistant_not_selected_title" msgid="5017072974603345228">"ਇਸ ਵਿਸ਼ੇਸ਼ਤਾ ਨੂੰ ਵਰਤਣ ਲਈ ਸਹਾਇਕ ਐਪ ਚੁਣੋ"</string>
- <string name="assistant_not_selected_text" msgid="3244613673884359276">"ਆਪਣੀ ਸਕ੍ਰੀਨ \'ਤੇ ਲਿਖਤ ਨੂੰ ਸੁਣਨ ਅਤੇ ਉਸਦਾ ਅਨੁਵਾਦ ਕਰਨ ਲਈ, ਸੈਟਿੰਗਾਂ ਵਿੱਚ ਡਿਜੀਟਲ ਸਹਾਇਕ ਐਪ ਚੁਣੋ"</string>
- <string name="assistant_not_supported_title" msgid="1675788067597484142">"ਇਸ ਵਿਸ਼ੇਸ਼ਤਾ ਨੂੰ ਵਰਤਣ ਲਈ ਆਪਣੀ ਸਹਾਇਕ ਐਪ ਬਦਲੋ"</string>
- <string name="assistant_not_supported_text" msgid="1708031078549268884">"ਆਪਣੀ ਸਕ੍ਰੀਨ \'ਤੇ ਲਿਖਤ ਨੂੰ ਸੁਣਨ ਅਤੇ ਉਸਦਾ ਅਨੁਵਾਦ ਕਰਨ ਲਈ, ਸੈਟਿੰਗਾਂ ਵਿੱਚ ਆਪਣੀ ਡਿਜੀਟਲ ਸਹਾਇਕ ਐਪ ਬਦਲੋ"</string>
- <string name="tooltip_listen" msgid="7634466447860989102">"ਇਸ ਸਕ੍ਰੀਨ \'ਤੇ ਲਿਖਤ ਨੂੰ ਸੁਣਨ ਲਈ ਇੱਥੇ ਟੈਪ ਕਰੋ"</string>
- <string name="tooltip_translate" msgid="4184845868901542567">"ਇਸ ਸਕ੍ਰੀਨ \'ਤੇ ਲਿਖਤ ਦਾ ਅਨੁਵਾਦ ਕਰਨ ਲਈ ਇੱਥੇ ਟੈਪ ਕਰੋ"</string>
- <string name="toast_p2p_app_not_shareable" msgid="7229739094132131536">"ਇਸ ਐਪ ਨੂੰ ਸਾਂਝਾ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ"</string>
-</resources>
diff --git a/go/quickstep/res/values-pl/strings.xml b/go/quickstep/res/values-pl/strings.xml
deleted file mode 100644
index 5dc66f538b..0000000000
--- a/go/quickstep/res/values-pl/strings.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_share_drop_target_label" msgid="5804774105974539508">"Udostępnij aplikację"</string>
- <string name="action_listen" msgid="2370304050784689486">"Posłuchaj"</string>
- <string name="action_translate" msgid="8028378961867277746">"Przetłumacz"</string>
- <string name="action_search" msgid="6269564710943755464">"Obiektyw"</string>
- <string name="dialog_acknowledge" msgid="2804025517675853172">"OK"</string>
- <string name="dialog_cancel" msgid="6464336969134856366">"ANULUJ"</string>
- <string name="dialog_settings" msgid="6564397136021186148">"USTAWIENIA"</string>
- <string name="niu_actions_confirmation_title" msgid="3863451714863526143">"Przetłumacz lub odsłuchaj tekst na ekranie"</string>
- <string name="niu_actions_confirmation_text" msgid="2105271481950866089">"Informacje takie jak tekst na ekranie, adresy internetowe i zrzuty ekranu mogą być udostępniane Google.\n\nAby zmienić zakres udostępnianych informacji, kliknij "<b>"Ustawienia &gt; Aplikacje &gt; Aplikacje domyślne &gt; Asystent cyfrowy"</b>"."</string>
- <string name="assistant_not_selected_title" msgid="5017072974603345228">"Aby użyć tej funkcji, wybierz asystenta"</string>
- <string name="assistant_not_selected_text" msgid="3244613673884359276">"Aby odsłuchać lub przetłumaczyć tekst widoczny na ekranie, wybierz w Ustawieniach aplikację asystenta cyfrowego"</string>
- <string name="assistant_not_supported_title" msgid="1675788067597484142">"Aby użyć tej funkcji, zmień asystenta"</string>
- <string name="assistant_not_supported_text" msgid="1708031078549268884">"Aby odsłuchać lub przetłumaczyć tekst widoczny na ekranie, zmień w Ustawieniach aplikację asystenta cyfrowego"</string>
- <string name="tooltip_listen" msgid="7634466447860989102">"Kliknij tutaj, aby odsłuchać tekst widoczny na ekranie"</string>
- <string name="tooltip_translate" msgid="4184845868901542567">"Kliknij tutaj, aby przetłumaczyć tekst widoczny na ekranie"</string>
- <string name="toast_p2p_app_not_shareable" msgid="7229739094132131536">"Tej aplikacji nie można udostępnić"</string>
-</resources>
diff --git a/go/quickstep/res/values-pt-rPT/strings.xml b/go/quickstep/res/values-pt-rPT/strings.xml
deleted file mode 100644
index 7041f4145e..0000000000
--- a/go/quickstep/res/values-pt-rPT/strings.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_share_drop_target_label" msgid="5804774105974539508">"Partilhar app"</string>
- <string name="action_listen" msgid="2370304050784689486">"Ouvir"</string>
- <string name="action_translate" msgid="8028378961867277746">"Traduzir"</string>
- <string name="action_search" msgid="6269564710943755464">"Lens"</string>
- <string name="dialog_acknowledge" msgid="2804025517675853172">"OK"</string>
- <string name="dialog_cancel" msgid="6464336969134856366">"CANCELAR"</string>
- <string name="dialog_settings" msgid="6564397136021186148">"DEFINIÇÕES"</string>
- <string name="niu_actions_confirmation_title" msgid="3863451714863526143">"Traduza ou ouça o texto no ecrã"</string>
- <string name="niu_actions_confirmation_text" msgid="2105271481950866089">"Informações como o texto no ecrã, endereços Web e capturas de ecrã podem ser partilhadas com a Google.\n\nPara alterar as informações que partilha, aceda a "<b>"Definições &gt; Apps &gt; App predefinidas &gt; App de assistente digital"</b>"."</string>
- <string name="assistant_not_selected_title" msgid="5017072974603345228">"Escolha um assistente para utilizar esta funcionalidade"</string>
- <string name="assistant_not_selected_text" msgid="3244613673884359276">"Para ouvir ou traduzir o texto no ecrã, escolha uma app de assistente digital nas Definições"</string>
- <string name="assistant_not_supported_title" msgid="1675788067597484142">"Mude de assistente para utilizar esta funcionalidade"</string>
- <string name="assistant_not_supported_text" msgid="1708031078549268884">"Para ouvir ou traduzir o texto no ecrã, mude de app de assistente digital nas Definições"</string>
- <string name="tooltip_listen" msgid="7634466447860989102">"Toque aqui para ouvir o texto neste ecrã"</string>
- <string name="tooltip_translate" msgid="4184845868901542567">"Toque aqui para traduzir o texto neste ecrã"</string>
- <string name="toast_p2p_app_not_shareable" msgid="7229739094132131536">"Não é possível partilhar esta app"</string>
-</resources>
diff --git a/go/quickstep/res/values-pt/strings.xml b/go/quickstep/res/values-pt/strings.xml
deleted file mode 100644
index ba59231989..0000000000
--- a/go/quickstep/res/values-pt/strings.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_share_drop_target_label" msgid="5804774105974539508">"Compartilhar app"</string>
- <string name="action_listen" msgid="2370304050784689486">"Ouvir"</string>
- <string name="action_translate" msgid="8028378961867277746">"Traduzir"</string>
- <string name="action_search" msgid="6269564710943755464">"Lens"</string>
- <string name="dialog_acknowledge" msgid="2804025517675853172">"OK"</string>
- <string name="dialog_cancel" msgid="6464336969134856366">"CANCELAR"</string>
- <string name="dialog_settings" msgid="6564397136021186148">"CONFIGURAÇÕES"</string>
- <string name="niu_actions_confirmation_title" msgid="3863451714863526143">"Traduzir ou ouvir o texto na tela"</string>
- <string name="niu_actions_confirmation_text" msgid="2105271481950866089">"Informações como o texto exibido, endereços da Web e capturas de tela poderão ser compartilhadas com o Google.\n\nPara mudar quais dados são compartilhados, acesse "<b>"Configurações &gt; Apps &gt; Apps padrão &gt; App assistente digital"</b>"."</string>
- <string name="assistant_not_selected_title" msgid="5017072974603345228">"Escolha um assistente para usar esse recurso"</string>
- <string name="assistant_not_selected_text" msgid="3244613673884359276">"Para ouvir ou traduzir o texto exibido na tela, escolha um app assistente digital nas Configurações"</string>
- <string name="assistant_not_supported_title" msgid="1675788067597484142">"Mude seu assistente para usar esse recurso"</string>
- <string name="assistant_not_supported_text" msgid="1708031078549268884">"Para ouvir ou traduzir o texto exibido na tela, mude seu app assistente digital nas Configurações"</string>
- <string name="tooltip_listen" msgid="7634466447860989102">"Toque aqui para ouvir o texto exibido na tela"</string>
- <string name="tooltip_translate" msgid="4184845868901542567">"Toque aqui para traduzir o texto exibido na tela"</string>
- <string name="toast_p2p_app_not_shareable" msgid="7229739094132131536">"Não é possível compartilhar o app"</string>
-</resources>
diff --git a/go/quickstep/res/values-ro/strings.xml b/go/quickstep/res/values-ro/strings.xml
deleted file mode 100644
index 0be8cce7fe..0000000000
--- a/go/quickstep/res/values-ro/strings.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_share_drop_target_label" msgid="5804774105974539508">"Trimiteți aplicația"</string>
- <string name="action_listen" msgid="2370304050784689486">"Ascultați"</string>
- <string name="action_translate" msgid="8028378961867277746">"Traduceți"</string>
- <string name="action_search" msgid="6269564710943755464">"Lens"</string>
- <string name="dialog_acknowledge" msgid="2804025517675853172">"OK"</string>
- <string name="dialog_cancel" msgid="6464336969134856366">"ANULAȚI"</string>
- <string name="dialog_settings" msgid="6564397136021186148">"SETĂRI"</string>
- <string name="niu_actions_confirmation_title" msgid="3863451714863526143">"Traduceți sau ascultați textul de pe ecran"</string>
- <string name="niu_actions_confirmation_text" msgid="2105271481950866089">"Informații precum textul de pe ecran, adresele web și capturile de ecran pot fi trimise la Google.\n\nCa să schimbați informațiile trimise, accesați "<b>"Setări &gt; Aplicații &gt; Aplicații prestabilite &gt; Aplicația asistent digital"</b>"."</string>
- <string name="assistant_not_selected_title" msgid="5017072974603345228">"Alegeți un asistent pentru a folosi această funcție"</string>
- <string name="assistant_not_selected_text" msgid="3244613673884359276">"Pentru a asculta sau a traduce text de pe ecran, alegeți o aplicație asistent digital în Setări"</string>
- <string name="assistant_not_supported_title" msgid="1675788067597484142">"Schimbați asistentul pentru a folosi această funcție"</string>
- <string name="assistant_not_supported_text" msgid="1708031078549268884">"Pentru a asculta sau a traduce text de pe ecran, schimbați aplicația asistent digital în Setări"</string>
- <string name="tooltip_listen" msgid="7634466447860989102">"Atingeți aici pentru a asculta text de pe ecran"</string>
- <string name="tooltip_translate" msgid="4184845868901542567">"Atingeți aici pentru a traduce text de pe ecran"</string>
- <string name="toast_p2p_app_not_shareable" msgid="7229739094132131536">"Aplicația nu poate fi distribuită"</string>
-</resources>
diff --git a/go/quickstep/res/values-ru/strings.xml b/go/quickstep/res/values-ru/strings.xml
deleted file mode 100644
index d845c354d2..0000000000
--- a/go/quickstep/res/values-ru/strings.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_share_drop_target_label" msgid="5804774105974539508">"Поделиться"</string>
- <string name="action_listen" msgid="2370304050784689486">"Слушать"</string>
- <string name="action_translate" msgid="8028378961867277746">"Перевести"</string>
- <string name="action_search" msgid="6269564710943755464">"Объектив"</string>
- <string name="dialog_acknowledge" msgid="2804025517675853172">"ОК"</string>
- <string name="dialog_cancel" msgid="6464336969134856366">"ОТМЕНА"</string>
- <string name="dialog_settings" msgid="6564397136021186148">"ОТКРЫТЬ НАСТРОЙКИ"</string>
- <string name="niu_actions_confirmation_title" msgid="3863451714863526143">"Перевод или прослушивание текста на экране"</string>
- <string name="niu_actions_confirmation_text" msgid="2105271481950866089">"Определенные сведения (например, текст на экране, веб-адреса и скриншоты) могут быть отправлены в Google.\n\nИзменить информацию, которой вы делитесь, можно в меню "<b>"Настройки &gt; Приложения &gt; Приложения по умолчанию &gt; Цифровой помощник"</b>"."</string>
- <string name="assistant_not_selected_title" msgid="5017072974603345228">"Выберите помощника, чтобы пользоваться этой функцией"</string>
- <string name="assistant_not_selected_text" msgid="3244613673884359276">"Чтобы слушать или переводить текст на экране, укажите цифрового помощника в настройках."</string>
- <string name="assistant_not_supported_title" msgid="1675788067597484142">"Смените помощника, чтобы пользоваться этой функцией"</string>
- <string name="assistant_not_supported_text" msgid="1708031078549268884">"Чтобы слушать или переводить текст на экране, выберите другого цифрового помощника в настройках."</string>
- <string name="tooltip_listen" msgid="7634466447860989102">"Нажмите, чтобы прослушать текст на этой странице"</string>
- <string name="tooltip_translate" msgid="4184845868901542567">"Нажмите, чтобы перевести текст на этой странице"</string>
- <string name="toast_p2p_app_not_shareable" msgid="7229739094132131536">"Невозможно предоставить доступ к этому приложению."</string>
-</resources>
diff --git a/go/quickstep/res/values-si/strings.xml b/go/quickstep/res/values-si/strings.xml
deleted file mode 100644
index 52718f2d8f..0000000000
--- a/go/quickstep/res/values-si/strings.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_share_drop_target_label" msgid="5804774105974539508">"යෙදුම බෙදා ගන්න"</string>
- <string name="action_listen" msgid="2370304050784689486">"සවන් දෙන්න"</string>
- <string name="action_translate" msgid="8028378961867277746">"පරිවර්තනය කරන්න"</string>
- <string name="action_search" msgid="6269564710943755464">"Lens"</string>
- <string name="dialog_acknowledge" msgid="2804025517675853172">"තේරුණා"</string>
- <string name="dialog_cancel" msgid="6464336969134856366">"අවලංගු කරන්න"</string>
- <string name="dialog_settings" msgid="6564397136021186148">"සැකසීම්"</string>
- <string name="niu_actions_confirmation_title" msgid="3863451714863526143">"තිරය මත පෙළ පරිවර්තනය කරන්න හෝ එයට සවන් දෙන්න"</string>
- <string name="niu_actions_confirmation_text" msgid="2105271481950866089">"ඔබගේ තිරයේ ඇති පෙළ, වෙබ් ලිපින සහ තිර රූ වැනි තොරතුරු Google සමඟ බෙදා ගත හැකිය.\n\nඔබ බෙදා ගන්නා තොරතුරු වෙනස් කිරීමට, "<b>"සැකසීම් &gt; යෙදුම් &gt; පෙරනිමි යෙදුම් &gt; ඩිජිටල් සහායක යෙදුම"</b>" වෙත යන්න."</string>
- <string name="assistant_not_selected_title" msgid="5017072974603345228">"මෙම විශේෂාංගය භාවිත කිරීමට සහායකයකු තෝරන්න"</string>
- <string name="assistant_not_selected_text" msgid="3244613673884359276">"ඔබගේ තිරයේ පෙළ සවන් දීමට හෝ පරිවර්තනය කිරීමට, සැකසීම්වල ඩිජිටල් සහායක යෙදුමක් තෝරන්න"</string>
- <string name="assistant_not_supported_title" msgid="1675788067597484142">"මෙම විශේෂාංගය භාවිත කිරීමට ඔබගේ සහායක වෙනස් කරන්න"</string>
- <string name="assistant_not_supported_text" msgid="1708031078549268884">"ඔබගේ තිරයේ පෙළට සවන් දීමට හෝ පරිවර්තනය කිරීමට, සැකසීම් තුළ ඔබගේ ඩිජිටල් සහායක යෙදුම වෙනස් කරන්න"</string>
- <string name="tooltip_listen" msgid="7634466447860989102">"මෙම තිරයේ පෙළට සවන් දීමට මෙහි තට්ටු කරන්න"</string>
- <string name="tooltip_translate" msgid="4184845868901542567">"මෙම තිරයේ පෙළ පරිවර්තනය කිරීමට මෙහි තට්ටු කරන්න"</string>
- <string name="toast_p2p_app_not_shareable" msgid="7229739094132131536">"මෙම යෙදුම බෙදා ගත නොහැකිය"</string>
-</resources>
diff --git a/go/quickstep/res/values-sk/strings.xml b/go/quickstep/res/values-sk/strings.xml
deleted file mode 100644
index 89291af0f5..0000000000
--- a/go/quickstep/res/values-sk/strings.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_share_drop_target_label" msgid="5804774105974539508">"Zdieľať aplikáciu"</string>
- <string name="action_listen" msgid="2370304050784689486">"Počúvať"</string>
- <string name="action_translate" msgid="8028378961867277746">"Preložiť"</string>
- <string name="action_search" msgid="6269564710943755464">"Lens"</string>
- <string name="dialog_acknowledge" msgid="2804025517675853172">"DOBRE"</string>
- <string name="dialog_cancel" msgid="6464336969134856366">"ZRUŠIŤ"</string>
- <string name="dialog_settings" msgid="6564397136021186148">"NASTAVENIA"</string>
- <string name="niu_actions_confirmation_title" msgid="3863451714863526143">"Prekladajte alebo počúvajte text na obrazovke"</string>
- <string name="niu_actions_confirmation_text" msgid="2105271481950866089">"Údaje, napríklad text na obrazovke, webové adresy a snímky obrazovky, môžu byť zdieľané s Googlom.\n\nAk chcete zmeniť, ktoré údaje zdieľate, prejdite do sekcie "<b>"Nastavenia &gt; Aplikácie &gt; Predvolené aplikácie &gt; Digitálny asistent"</b>"."</string>
- <string name="assistant_not_selected_title" msgid="5017072974603345228">"Ak chcete používať túto funkciu, vyberte asistenta"</string>
- <string name="assistant_not_selected_text" msgid="3244613673884359276">"Ak si chcete vypočuť alebo nechať preložiť text na obrazovke, vyberte v Nastaveniach aplikáciu digitálneho asistenta"</string>
- <string name="assistant_not_supported_title" msgid="1675788067597484142">"Ak chcete použígvať túto funkciu, zmeňte svojho asistenta"</string>
- <string name="assistant_not_supported_text" msgid="1708031078549268884">"Ak si chcete vypočuť alebo nechať preložiť text na obrazovke, zmeňte v Nastaveniach aplikáciu digitálneho asistenta"</string>
- <string name="tooltip_listen" msgid="7634466447860989102">"Klepnutím tu si vypočujte text na tejto obrazovke"</string>
- <string name="tooltip_translate" msgid="4184845868901542567">"Klepnutím tu si nechajte preložiť text na tejto obrazovke"</string>
- <string name="toast_p2p_app_not_shareable" msgid="7229739094132131536">"Táto aplikácia sa nedá zdieľať"</string>
-</resources>
diff --git a/go/quickstep/res/values-sl/strings.xml b/go/quickstep/res/values-sl/strings.xml
deleted file mode 100644
index afa674e058..0000000000
--- a/go/quickstep/res/values-sl/strings.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_share_drop_target_label" msgid="5804774105974539508">"Deli aplikacijo"</string>
- <string name="action_listen" msgid="2370304050784689486">"Poslušanje"</string>
- <string name="action_translate" msgid="8028378961867277746">"Prevedi"</string>
- <string name="action_search" msgid="6269564710943755464">"Lens"</string>
- <string name="dialog_acknowledge" msgid="2804025517675853172">"RAZUMEM"</string>
- <string name="dialog_cancel" msgid="6464336969134856366">"PREKLIČI"</string>
- <string name="dialog_settings" msgid="6564397136021186148">"NASTAVITVE"</string>
- <string name="niu_actions_confirmation_title" msgid="3863451714863526143">"Prevod ali poslušanje besedila na zaslonu"</string>
- <string name="niu_actions_confirmation_text" msgid="2105271481950866089">"Podatki, kot so besedilo na zaslonu, spletni naslovi in posnetki zaslonov, bodo morda deljeni z Googlom.\n\nČe želite spremeniti, katere podatke delite, odprite "<b>"Nastavitve &gt; Aplikacije &gt; Privzete aplikacije &gt; Digitalni pomočnik"</b>"."</string>
- <string name="assistant_not_selected_title" msgid="5017072974603345228">"Za uporabo te funkcije izberite pomočnika"</string>
- <string name="assistant_not_selected_text" msgid="3244613673884359276">"Za poslušanje ali prevod besedila na zaslonu v nastavitvah izberite digitalnega pomočnika."</string>
- <string name="assistant_not_supported_title" msgid="1675788067597484142">"Za uporabo te funkcije izberite drugega pomočnika"</string>
- <string name="assistant_not_supported_text" msgid="1708031078549268884">"Za poslušanje ali prevod besedila na zaslonu v nastavitvah izberite drugega digitalnega pomočnika."</string>
- <string name="tooltip_listen" msgid="7634466447860989102">"Dotaknite se tukaj za poslušanje besedila na zaslonu."</string>
- <string name="tooltip_translate" msgid="4184845868901542567">"Dotaknite se tukaj za prevod besedila na zaslonu."</string>
- <string name="toast_p2p_app_not_shareable" msgid="7229739094132131536">"Te aplikacije ni mogoče deliti z drugimi."</string>
-</resources>
diff --git a/go/quickstep/res/values-sq/strings.xml b/go/quickstep/res/values-sq/strings.xml
deleted file mode 100644
index 123ca39669..0000000000
--- a/go/quickstep/res/values-sq/strings.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_share_drop_target_label" msgid="5804774105974539508">"Ndaj aplikacionin"</string>
- <string name="action_listen" msgid="2370304050784689486">"Dëgjo"</string>
- <string name="action_translate" msgid="8028378961867277746">"Përkthe"</string>
- <string name="action_search" msgid="6269564710943755464">"Lentja"</string>
- <string name="dialog_acknowledge" msgid="2804025517675853172">"E KUPTOVA"</string>
- <string name="dialog_cancel" msgid="6464336969134856366">"ANULO"</string>
- <string name="dialog_settings" msgid="6564397136021186148">"CILËSIMET"</string>
- <string name="niu_actions_confirmation_title" msgid="3863451714863526143">"Përkthe ose dëgjo tekstin në ekran"</string>
- <string name="niu_actions_confirmation_text" msgid="2105271481950866089">"Informacionet si teksti në ekranin tënd, adresat e uebit dhe pamjet e ekranit mund të ndahen me Google.\n\nPër të ndryshuar se çfarë informacionesh ndahen, shko te "<b>"Cilësimet &gt; Aplikacionet &gt; Aplikacionet e parazgjedhura &gt; Aplikacioni i asistentit dixhital"</b>"."</string>
- <string name="assistant_not_selected_title" msgid="5017072974603345228">"Zgjidh një asistent për të përdorur këtë veçori"</string>
- <string name="assistant_not_selected_text" msgid="3244613673884359276">"Për të dëgjuar ose përkthyer tekstin në ekran, zgjidh një aplikacion të asistentit dixhital te \"Cilësimet\""</string>
- <string name="assistant_not_supported_title" msgid="1675788067597484142">"Ndrysho asistentin për të përdorur këtë veçori"</string>
- <string name="assistant_not_supported_text" msgid="1708031078549268884">"Për të dëgjuar ose përkthyer tekstin në ekran, ndrysho aplikacionin e asistentit dixhital te \"Cilësimet\""</string>
- <string name="tooltip_listen" msgid="7634466447860989102">"Trokit këtu për të dëgjuar tekstin në këtë ekran"</string>
- <string name="tooltip_translate" msgid="4184845868901542567">"Trokit këtu për të përkthyer tekstin në këtë ekran"</string>
- <string name="toast_p2p_app_not_shareable" msgid="7229739094132131536">"Ky aplikacion nuk mund të ndahet"</string>
-</resources>
diff --git a/go/quickstep/res/values-sr/strings.xml b/go/quickstep/res/values-sr/strings.xml
deleted file mode 100644
index 749fc0ece3..0000000000
--- a/go/quickstep/res/values-sr/strings.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_share_drop_target_label" msgid="5804774105974539508">"Дели апликацију"</string>
- <string name="action_listen" msgid="2370304050784689486">"Пусти"</string>
- <string name="action_translate" msgid="8028378961867277746">"Преведи"</string>
- <string name="action_search" msgid="6269564710943755464">"Објектив"</string>
- <string name="dialog_acknowledge" msgid="2804025517675853172">"ВАЖИ"</string>
- <string name="dialog_cancel" msgid="6464336969134856366">"ОТКАЖИ"</string>
- <string name="dialog_settings" msgid="6564397136021186148">"ПОДЕШАВАЊА"</string>
- <string name="niu_actions_confirmation_title" msgid="3863451714863526143">"Преводите или слушајте текст на екрану"</string>
- <string name="niu_actions_confirmation_text" msgid="2105271481950866089">"Информације попут текста на екрану, веб-адреса и снимака екрана могу да се деле са Google-ом.\n\nДа бисте променили информације које делите, идите у "<b>"Подешавања &gt; Апликације &gt; Подразумеване апликације &gt; Апликација дигиталног помоћника"</b>"."</string>
- <string name="assistant_not_selected_title" msgid="5017072974603345228">"Одаберите помоћника да бисте користили ову функцију"</string>
- <string name="assistant_not_selected_text" msgid="3244613673884359276">"Да бисте чули текст са екрана или га превели, одаберите апликацију дигиталног помоћника у Подешавањима"</string>
- <string name="assistant_not_supported_title" msgid="1675788067597484142">"Промените помоћника да бисте користили ову функцију"</string>
- <string name="assistant_not_supported_text" msgid="1708031078549268884">"Да бисте чули текст са екрана или га превели, промените апликацију дигиталног помоћника у Подешавањима"</string>
- <string name="tooltip_listen" msgid="7634466447860989102">"Додирните овде да бисте чули текст са овог екрана"</string>
- <string name="tooltip_translate" msgid="4184845868901542567">"Додирните овде да бисте превели текст са овог екрана"</string>
- <string name="toast_p2p_app_not_shareable" msgid="7229739094132131536">"Ова апликација не може да се дели"</string>
-</resources>
diff --git a/go/quickstep/res/values-sv/strings.xml b/go/quickstep/res/values-sv/strings.xml
deleted file mode 100644
index e76fe7f7c9..0000000000
--- a/go/quickstep/res/values-sv/strings.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_share_drop_target_label" msgid="5804774105974539508">"Dela app"</string>
- <string name="action_listen" msgid="2370304050784689486">"Lyssna"</string>
- <string name="action_translate" msgid="8028378961867277746">"Översätt"</string>
- <string name="action_search" msgid="6269564710943755464">"Lens"</string>
- <string name="dialog_acknowledge" msgid="2804025517675853172">"OK"</string>
- <string name="dialog_cancel" msgid="6464336969134856366">"AVBRYT"</string>
- <string name="dialog_settings" msgid="6564397136021186148">"INSTÄLLNINGAR"</string>
- <string name="niu_actions_confirmation_title" msgid="3863451714863526143">"Översätt eller lyssna på texten på skärmen"</string>
- <string name="niu_actions_confirmation_text" msgid="2105271481950866089">"Information som text på skärmen, webbadresser och skärmbilder kan delas med Google.\n\nFör att ändra vilken information du delar öppnar du "<b>"Inställningar &gt; Appar &gt; Standardappar &gt; Digital assistentapp"</b>"."</string>
- <string name="assistant_not_selected_title" msgid="5017072974603345228">"Välj en assistent om du vill använda den här funktionen"</string>
- <string name="assistant_not_selected_text" msgid="3244613673884359276">"Välj en digital assistentapp i Inställningar om du vill lyssna på eller översätta text på skärmen"</string>
- <string name="assistant_not_supported_title" msgid="1675788067597484142">"Byt assistent om du vill använda den här funktionen"</string>
- <string name="assistant_not_supported_text" msgid="1708031078549268884">"Byt digital assistentapp i Inställningar om du vill lyssna på eller översätta text på skärmen"</string>
- <string name="tooltip_listen" msgid="7634466447860989102">"Tryck här för att lyssna på texten på skärmen"</string>
- <string name="tooltip_translate" msgid="4184845868901542567">"Tryck här för att översätta texten på skärmen"</string>
- <string name="toast_p2p_app_not_shareable" msgid="7229739094132131536">"Den här appen kan inte delas"</string>
-</resources>
diff --git a/go/quickstep/res/values-sw/strings.xml b/go/quickstep/res/values-sw/strings.xml
deleted file mode 100644
index 5a25702192..0000000000
--- a/go/quickstep/res/values-sw/strings.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_share_drop_target_label" msgid="5804774105974539508">"Shiriki Programu"</string>
- <string name="action_listen" msgid="2370304050784689486">"Sikiliza"</string>
- <string name="action_translate" msgid="8028378961867277746">"Tafsiri"</string>
- <string name="action_search" msgid="6269564710943755464">"Lenzi"</string>
- <string name="dialog_acknowledge" msgid="2804025517675853172">"NIMEELEWA"</string>
- <string name="dialog_cancel" msgid="6464336969134856366">"GHAIRI"</string>
- <string name="dialog_settings" msgid="6564397136021186148">"MIPANGILIO"</string>
- <string name="niu_actions_confirmation_title" msgid="3863451714863526143">"Tafsiri au usikilize maandishi kwenye skrini"</string>
- <string name="niu_actions_confirmation_text" msgid="2105271481950866089">"Maelezo kama vile maandishi kwenye skrini yako, anwani za wavuti na picha za skrini yanaweza kushirikiwa na Google.\n\nIli ubadilishe maelezo unayoshiriki, nenda kwenye "<b>"Mipangilio &gt; Programu &gt; Programu chaguomsingi &gt; Programu ya mratibu dijitali"</b>"."</string>
- <string name="assistant_not_selected_title" msgid="5017072974603345228">"Chagua programu ya mratibu ili utumie kipengele hiki"</string>
- <string name="assistant_not_selected_text" msgid="3244613673884359276">"Ili usikilize au utafsiri maandishi kwenye skrini yako, chagua programu ya mratibu dijitali katika Mipangilio"</string>
- <string name="assistant_not_supported_title" msgid="1675788067597484142">"Badilisha programu yako ya mratibu ili utumie kipengele hiki"</string>
- <string name="assistant_not_supported_text" msgid="1708031078549268884">"Ili usikilize au utafsiri maandishi kwenye skrini yako, badilisha programu yako ya mratibu dijitali katika Mipangilio"</string>
- <string name="tooltip_listen" msgid="7634466447860989102">"Gusa hapa ili usikilize maandishi kwenye skrini hii"</string>
- <string name="tooltip_translate" msgid="4184845868901542567">"Gusa hapa ili utafsiri maandishi kwenye skrini hii"</string>
- <string name="toast_p2p_app_not_shareable" msgid="7229739094132131536">"Huwezi kushiriki programu hii"</string>
-</resources>
diff --git a/go/quickstep/res/values-ta/strings.xml b/go/quickstep/res/values-ta/strings.xml
deleted file mode 100644
index 9d04e9a72c..0000000000
--- a/go/quickstep/res/values-ta/strings.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_share_drop_target_label" msgid="5804774105974539508">"ஆப்ஸைப் பகிருங்கள்"</string>
- <string name="action_listen" msgid="2370304050784689486">"கேளுங்கள்"</string>
- <string name="action_translate" msgid="8028378961867277746">"மொழிபெயர்"</string>
- <string name="action_search" msgid="6269564710943755464">"லென்ஸ்"</string>
- <string name="dialog_acknowledge" msgid="2804025517675853172">"சரி"</string>
- <string name="dialog_cancel" msgid="6464336969134856366">"ரத்துசெய்"</string>
- <string name="dialog_settings" msgid="6564397136021186148">"அமைப்புகள்"</string>
- <string name="niu_actions_confirmation_title" msgid="3863451714863526143">"திரையிலுள்ள உரையை மொழிபெயருங்கள் அல்லது கேளுங்கள்"</string>
- <string name="niu_actions_confirmation_text" msgid="2105271481950866089">"உங்கள் திரையிலுள்ள உரை, வலை முகவரிகள், ஸ்கிரீன்ஷாட்டுகள் போன்ற தகவல்கள் Googleளுடன் பகிரப்படலாம்.\n\nஎந்தத் தகவல்கள் பகிரப்படலாம் என்பதை மாற்ற, "<b>"அமைப்புகள் &gt; ஆப்ஸ் &gt; இயல்பு ஆப்ஸ் &gt; டிஜிட்டல் அசிஸ்டண்ட் ஆப்ஸ்"</b>" என்பதற்குச் செல்லுங்கள்."</string>
- <string name="assistant_not_selected_title" msgid="5017072974603345228">"இந்த அம்சத்தைப் பயன்படுத்த அசிஸ்டண்ட்டைத் தேர்வுசெய்யவும்"</string>
- <string name="assistant_not_selected_text" msgid="3244613673884359276">"திரையில் தோன்றும் வார்த்தைகளைக் கேட்கவோ மொழிபெயர்க்கவோ அமைப்புகளில் டிஜிட்டல் அசிஸ்டண்ட் ஆப்ஸைத் தேர்வுசெய்யவும்"</string>
- <string name="assistant_not_supported_title" msgid="1675788067597484142">"இந்த அம்சத்தைப் பயன்படுத்த அசிஸ்டண்ட்டை மாற்றவும்"</string>
- <string name="assistant_not_supported_text" msgid="1708031078549268884">"திரையில் தோன்றும் வார்த்தைகளைக் கேட்கவோ மொழிபெயர்க்கவோ அமைப்புகளில் டிஜிட்டல் அசிஸ்டண்ட் ஆப்ஸை மாற்றவும்"</string>
- <string name="tooltip_listen" msgid="7634466447860989102">"இந்தத் திரையில் தோன்றும் வார்த்தைகளைக் கேட்க இங்கே தட்டவும்"</string>
- <string name="tooltip_translate" msgid="4184845868901542567">"இந்தத் திரையில் தோன்றும் வார்த்தைகளை மொழிபெயர்க்க இங்கே தட்டவும்"</string>
- <string name="toast_p2p_app_not_shareable" msgid="7229739094132131536">"இந்த ஆப்ஸைப் பகிர முடியாது"</string>
-</resources>
diff --git a/go/quickstep/res/values-te/strings.xml b/go/quickstep/res/values-te/strings.xml
deleted file mode 100644
index 656adf687b..0000000000
--- a/go/quickstep/res/values-te/strings.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_share_drop_target_label" msgid="5804774105974539508">"యాప్‌ను షేర్ చేయండి"</string>
- <string name="action_listen" msgid="2370304050784689486">"వినండి"</string>
- <string name="action_translate" msgid="8028378961867277746">"అనువదించండి"</string>
- <string name="action_search" msgid="6269564710943755464">"Lens"</string>
- <string name="dialog_acknowledge" msgid="2804025517675853172">"అర్థమైంది"</string>
- <string name="dialog_cancel" msgid="6464336969134856366">"రద్దు చేయండి"</string>
- <string name="dialog_settings" msgid="6564397136021186148">"సెట్టింగ్‌లు"</string>
- <string name="niu_actions_confirmation_title" msgid="3863451714863526143">"స్క్రీన్‌పై టెక్స్ట్ అనువదించండి లేదా వినండి"</string>
- <string name="niu_actions_confirmation_text" msgid="2105271481950866089">"మీ స్క్రీన్‌పై టెక్స్ట్, వెబ్ అడ్రస్‌లు, అలాగే స్క్రీన్‌షాట్‌ల వంటి సమాచారం Googleతో షేర్ చేయడం జరగవచ్చు.\n\nమీరు ఏ సమాచారాన్ని షేర్ చేసుకుంటారో మార్చడానికి "<b>"సెట్టింగ్‌లు &gt; యాప్‌లు &gt; ఆటోమేటిక్ సెట్టింగ్ యాప్‌లు &gt; డిజిటల్ అసిస్టెంట్ యాప్‌ల"</b>"‌కు వెళ్లండి."</string>
- <string name="assistant_not_selected_title" msgid="5017072974603345228">"ఈ ఫీచర్‌ను ఉపయోగించడానికి అసిస్టెంట్‌ను ఎంచుకోండి"</string>
- <string name="assistant_not_selected_text" msgid="3244613673884359276">"మీ స్క్రీన్‌పై ఉన్న టెక్స్ట్‌ను వినడానికి లేదా అనువదించడానికి, సెట్టింగ్‌లలో డిజిటల్ అసిస్టెంట్ యాప్‌ను ఎంచుకోండి"</string>
- <string name="assistant_not_supported_title" msgid="1675788067597484142">"ఈ ఫీచర్‌ను ఉపయోగించడానికి మీ అసిస్టెంట్‌ను మార్చండి"</string>
- <string name="assistant_not_supported_text" msgid="1708031078549268884">"మీ స్క్రీన్‌పై ఉన్న టెక్స్ట్‌ను వినడానికి లేదా అనువదించడానికి, సెట్టింగ్‌లలో మీ డిజిటల్ అసిస్టెంట్ యాప్‌ను మార్చండి"</string>
- <string name="tooltip_listen" msgid="7634466447860989102">"ఈ స్క్రీన్‌పై ఉన్న టెక్స్ట్‌ను వినడానికి ఇక్కడ ట్యాప్ చేయండి"</string>
- <string name="tooltip_translate" msgid="4184845868901542567">"ఈ స్క్రీన్‌పై ఉన్న టెక్స్ట్‌ను అనువదించడానికి ఇక్కడ ట్యాప్ చేయండి"</string>
- <string name="toast_p2p_app_not_shareable" msgid="7229739094132131536">"ఈ యాప్‌ను షేర్ చేయడం సాధ్యపడదు"</string>
-</resources>
diff --git a/go/quickstep/res/values-th/strings.xml b/go/quickstep/res/values-th/strings.xml
deleted file mode 100644
index 8ce2ffc764..0000000000
--- a/go/quickstep/res/values-th/strings.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_share_drop_target_label" msgid="5804774105974539508">"แชร์แอป"</string>
- <string name="action_listen" msgid="2370304050784689486">"ฟัง"</string>
- <string name="action_translate" msgid="8028378961867277746">"แปลภาษา"</string>
- <string name="action_search" msgid="6269564710943755464">"Lens"</string>
- <string name="dialog_acknowledge" msgid="2804025517675853172">"รับทราบ"</string>
- <string name="dialog_cancel" msgid="6464336969134856366">"ยกเลิก"</string>
- <string name="dialog_settings" msgid="6564397136021186148">"การตั้งค่า"</string>
- <string name="niu_actions_confirmation_title" msgid="3863451714863526143">"แปลหรือฟังข้อความบนหน้าจอ"</string>
- <string name="niu_actions_confirmation_text" msgid="2105271481950866089">"อาจมีการแชร์ข้อมูลอย่างเช่น ข้อความบนหน้าจอ ที่อยู่เว็บ และภาพหน้าจอกับ Google\n\nหากต้องการเปลี่ยนประเภทข้อมูลที่คุณแชร์ ให้ไปที่"<b>"การตั้งค่า &gt; แอป &gt; แอปเริ่มต้น &gt; แอปผู้ช่วยดิจิทัล"</b></string>
- <string name="assistant_not_selected_title" msgid="5017072974603345228">"เลือกผู้ช่วยเพื่อใช้ฟีเจอร์นี้"</string>
- <string name="assistant_not_selected_text" msgid="3244613673884359276">"เลือกแอปผู้ช่วยดิจิทัลในการตั้งค่าเพื่อฟังหรือแปลข้อความบนหน้าจอ"</string>
- <string name="assistant_not_supported_title" msgid="1675788067597484142">"เปลี่ยนผู้ช่วยเพื่อใช้ฟีเจอร์นี้"</string>
- <string name="assistant_not_supported_text" msgid="1708031078549268884">"เปลี่ยนแอปผู้ช่วยดิจิทัลในการตั้งค่าเพื่อฟังหรือแปลข้อความบนหน้าจอ"</string>
- <string name="tooltip_listen" msgid="7634466447860989102">"แตะที่นี่เพื่อฟังข้อความบนหน้าจอนี้"</string>
- <string name="tooltip_translate" msgid="4184845868901542567">"แตะที่นี่เพื่อแปลข้อความบนหน้าจอนี้"</string>
- <string name="toast_p2p_app_not_shareable" msgid="7229739094132131536">"แชร์แอปนี้ไม่ได้"</string>
-</resources>
diff --git a/go/quickstep/res/values-tl/strings.xml b/go/quickstep/res/values-tl/strings.xml
deleted file mode 100644
index 2da5f59a40..0000000000
--- a/go/quickstep/res/values-tl/strings.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_share_drop_target_label" msgid="5804774105974539508">"Ibahagi ang App"</string>
- <string name="action_listen" msgid="2370304050784689486">"Makinig"</string>
- <string name="action_translate" msgid="8028378961867277746">"Isalin"</string>
- <string name="action_search" msgid="6269564710943755464">"Lens"</string>
- <string name="dialog_acknowledge" msgid="2804025517675853172">"OK"</string>
- <string name="dialog_cancel" msgid="6464336969134856366">"KANSELAHIN"</string>
- <string name="dialog_settings" msgid="6564397136021186148">"MGA SETTING"</string>
- <string name="niu_actions_confirmation_title" msgid="3863451714863526143">"I-translate o pakinggan ang text sa screen"</string>
- <string name="niu_actions_confirmation_text" msgid="2105271481950866089">"Posibleng ibahagi sa Google ang impormasyong gaya ng text sa iyong screen, mga web address, at screenshot.\n\nPara baguhin kung anong impormasyon ang ibinabahagi mo, pumunta sa "<b>"Mga Setting &gt; Mga App &gt; Mga default na app &gt; Digital assistant app"</b>"."</string>
- <string name="assistant_not_selected_title" msgid="5017072974603345228">"Pumili ng assistant para magamit ang feature na ito"</string>
- <string name="assistant_not_selected_text" msgid="3244613673884359276">"Para pakinggan o isalin ang text sa iyong screen, pumili ng app ng digital na assistant sa Mga Setting"</string>
- <string name="assistant_not_supported_title" msgid="1675788067597484142">"Palitan ang iyong assistant para magamit ang feature na ito"</string>
- <string name="assistant_not_supported_text" msgid="1708031078549268884">"Para pakinggan o isalin ang text sa iyong screen, palitan ang iyong app ng digital na assistant sa Mga Setting"</string>
- <string name="tooltip_listen" msgid="7634466447860989102">"Mag-tap dito para pakinggan ang text sa screen na ito"</string>
- <string name="tooltip_translate" msgid="4184845868901542567">"Mag-tap dito para isalin ang text sa screen na ito"</string>
- <string name="toast_p2p_app_not_shareable" msgid="7229739094132131536">"Hindi maibabahagi ang app na ito"</string>
-</resources>
diff --git a/go/quickstep/res/values-tr/strings.xml b/go/quickstep/res/values-tr/strings.xml
deleted file mode 100644
index dd2e9077b9..0000000000
--- a/go/quickstep/res/values-tr/strings.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_share_drop_target_label" msgid="5804774105974539508">"Uygulamayı paylaş"</string>
- <string name="action_listen" msgid="2370304050784689486">"Dinle"</string>
- <string name="action_translate" msgid="8028378961867277746">"Çevir"</string>
- <string name="action_search" msgid="6269564710943755464">"Lens"</string>
- <string name="dialog_acknowledge" msgid="2804025517675853172">"ANLADIM"</string>
- <string name="dialog_cancel" msgid="6464336969134856366">"İPTAL"</string>
- <string name="dialog_settings" msgid="6564397136021186148">"AYARLAR"</string>
- <string name="niu_actions_confirmation_title" msgid="3863451714863526143">"Ekrandaki metni çevirin veya dinleyin"</string>
- <string name="niu_actions_confirmation_text" msgid="2105271481950866089">"Ekranınızdaki metin, web adresleri ve ekran görüntüleri gibi bilgiler Google ile paylaşılabilir.\n\nPaylaştığınız bilgileri değiştirmek için "<b>"Ayarlar &gt; Uygulamalar &gt; Varsayılan uygulamalar &gt; Dijital asistan uygulamasına gidin"</b>"."</string>
- <string name="assistant_not_selected_title" msgid="5017072974603345228">"Bu özelliği kullanmak için bir asistan seçin"</string>
- <string name="assistant_not_selected_text" msgid="3244613673884359276">"Ekranınızdaki metni dinlemek veya çevirmek için Ayarlar\'dan bir dijital asistan uygulaması seçin"</string>
- <string name="assistant_not_supported_title" msgid="1675788067597484142">"Bu özelliği kullanmak için asistanınızı değiştirin"</string>
- <string name="assistant_not_supported_text" msgid="1708031078549268884">"Ekranınızdaki metni dinlemek veya çevirmek için Ayarlar\'dan dijital asistan uygulamanızı değiştirin"</string>
- <string name="tooltip_listen" msgid="7634466447860989102">"Bu ekrandaki metni dinlemek için buraya dokunun"</string>
- <string name="tooltip_translate" msgid="4184845868901542567">"Bu ekrandaki metni çevirmek için buraya dokunun"</string>
- <string name="toast_p2p_app_not_shareable" msgid="7229739094132131536">"Bu uygulama paylaşılamaz"</string>
-</resources>
diff --git a/go/quickstep/res/values-uk/strings.xml b/go/quickstep/res/values-uk/strings.xml
deleted file mode 100644
index c59b3bf059..0000000000
--- a/go/quickstep/res/values-uk/strings.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_share_drop_target_label" msgid="5804774105974539508">"Поділитися додатком"</string>
- <string name="action_listen" msgid="2370304050784689486">"Слухати"</string>
- <string name="action_translate" msgid="8028378961867277746">"Перекласти"</string>
- <string name="action_search" msgid="6269564710943755464">"Об’єктив"</string>
- <string name="dialog_acknowledge" msgid="2804025517675853172">"OK"</string>
- <string name="dialog_cancel" msgid="6464336969134856366">"СКАСУВАТИ"</string>
- <string name="dialog_settings" msgid="6564397136021186148">"НАЛАШТУВАННЯ"</string>
- <string name="niu_actions_confirmation_title" msgid="3863451714863526143">"Перекласти або прослухати текст на екрані"</string>
- <string name="niu_actions_confirmation_text" msgid="2105271481950866089">"Певна інформація (наприклад, текст на екрані, веб-адреси, знімки екрана) може надсилатися на сервери Google.\n\nЩоб змінити типи даних, які надсилаються, відкрийте "<b>"Налаштування &gt; Додатки &gt; Додатки за умовчанням &gt; Цифровий помічник"</b>"."</string>
- <string name="assistant_not_selected_title" msgid="5017072974603345228">"Щоб користуватися цією функцією, виберіть помічника"</string>
- <string name="assistant_not_selected_text" msgid="3244613673884359276">"Щоб прослухати чи перекласти текст на екрані, виберіть цифрового помічника в налаштуваннях"</string>
- <string name="assistant_not_supported_title" msgid="1675788067597484142">"Змініть помічника, щоб користуватися цією функцією"</string>
- <string name="assistant_not_supported_text" msgid="1708031078549268884">"Щоб прослухати чи перекласти текст на екрані, змініть цифрового помічника в налаштуваннях"</string>
- <string name="tooltip_listen" msgid="7634466447860989102">"Натисніть тут, щоб прослухати текст на цьому екрані"</string>
- <string name="tooltip_translate" msgid="4184845868901542567">"Натисніть тут, щоб перекласти текст на цьому екрані"</string>
- <string name="toast_p2p_app_not_shareable" msgid="7229739094132131536">"Цим додатком не можна поділитися"</string>
-</resources>
diff --git a/go/quickstep/res/values-ur/strings.xml b/go/quickstep/res/values-ur/strings.xml
deleted file mode 100644
index dd6c2cccad..0000000000
--- a/go/quickstep/res/values-ur/strings.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_share_drop_target_label" msgid="5804774105974539508">"ایپ کا اشتراک کریں"</string>
- <string name="action_listen" msgid="2370304050784689486">"سنیں"</string>
- <string name="action_translate" msgid="8028378961867277746">"‏Google ترجمہ"</string>
- <string name="action_search" msgid="6269564710943755464">"‏Google لینز"</string>
- <string name="dialog_acknowledge" msgid="2804025517675853172">"سمجھ آ گئی"</string>
- <string name="dialog_cancel" msgid="6464336969134856366">"منسوخ کریں"</string>
- <string name="dialog_settings" msgid="6564397136021186148">"ترتیبات"</string>
- <string name="niu_actions_confirmation_title" msgid="3863451714863526143">"اسکرین پر موجود ٹیکسٹ کو سنیں یا ترجمہ کریں"</string>
- <string name="niu_actions_confirmation_text" msgid="2105271481950866089">"‏آپ کی اسکرین پر ٹیکسٹ، ویب پتے اور اسکرین شاٹس جیسی معلومات کا اشتراک Google کے ساتھ کیا جا سکتا ہے۔\n\nآپ جس معلومات کا اشتراک کرتے ہیں اسے تبدیل کرنے کیلئے "<b>"ترتیبات ‎&gt;‎ ایپس ‎&gt;‎ ڈیفالٹ ایپس ‎&gt;‎ ڈیجیٹل اسسٹنٹ ایپ"</b>" پر جائیں۔"</string>
- <string name="assistant_not_selected_title" msgid="5017072974603345228">"اس خصوصیت کا استعمال کرنے کے لیے اسسٹنٹ کا انتخاب کریں"</string>
- <string name="assistant_not_selected_text" msgid="3244613673884359276">"اپنی اسکرین پر موجود ٹیکسٹ کو سننے یا اس کا ترجمہ کرنے کیلئے ترتیبات میں ڈیجیٹل اسسٹنٹ ایپ کا انتخاب کریں"</string>
- <string name="assistant_not_supported_title" msgid="1675788067597484142">"اس خصوصیت کا استعمال کرنے کے لیے اپنی اسسٹنٹ کا استعمال کریں"</string>
- <string name="assistant_not_supported_text" msgid="1708031078549268884">"اپنی اسکرین پر موجود ٹیکسٹ کو سننے یا اس کا ترجمہ کرنے کیلئے ترتیبات میں اپنی ڈیجیٹل اسسٹنٹ ایپ کو تبدیل کریں"</string>
- <string name="tooltip_listen" msgid="7634466447860989102">"اس اسکرین پر موجود ٹیکسٹ کو سننے کے لیے یہاں تھپتھپائیں"</string>
- <string name="tooltip_translate" msgid="4184845868901542567">"اس اسکرین پر موجود ٹیکسٹ کا ترجمہ کرنے کے لیے یہاں تھپتھپائیں"</string>
- <string name="toast_p2p_app_not_shareable" msgid="7229739094132131536">"اس ایپ کا اشتراک نہیں کیا جا سکتا"</string>
-</resources>
diff --git a/go/quickstep/res/values-uz/strings.xml b/go/quickstep/res/values-uz/strings.xml
deleted file mode 100644
index cb6b9e0c49..0000000000
--- a/go/quickstep/res/values-uz/strings.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_share_drop_target_label" msgid="5804774105974539508">"Ilovani ulashish"</string>
- <string name="action_listen" msgid="2370304050784689486">"Tinglash"</string>
- <string name="action_translate" msgid="8028378961867277746">"Tarjima"</string>
- <string name="action_search" msgid="6269564710943755464">"Lens"</string>
- <string name="dialog_acknowledge" msgid="2804025517675853172">"OK"</string>
- <string name="dialog_cancel" msgid="6464336969134856366">"BEKOR QILISH"</string>
- <string name="dialog_settings" msgid="6564397136021186148">"SOZLAMALAR"</string>
- <string name="niu_actions_confirmation_title" msgid="3863451714863526143">"Ekrandagi matnni tarjima qilish yoki tinglash"</string>
- <string name="niu_actions_confirmation_text" msgid="2105271481950866089">"Ekraningizdagi matn, veb-manzillar va skrinshot kabilar Googlega yuborilishi mumkin.\n\nQanday maʼlumotlarni ulashishni tanlash uchun "<b>"Sozlamalar &gt; Ilovalar &gt; Standart ilovalar &gt; Raqamli assistent"</b>" ilovasini oching."</string>
- <string name="assistant_not_selected_title" msgid="5017072974603345228">"Bu funksiyadan foydalanish uchun assistentni tanlang"</string>
- <string name="assistant_not_selected_text" msgid="3244613673884359276">"Ekrandagi matnni eshittirish yoki tarjima qilish uchun Sozlamalar orqali raqamli assistent ilovasini tanlang"</string>
- <string name="assistant_not_supported_title" msgid="1675788067597484142">"Bu funksiyadan foydalanish uchun assistentni almashtiring"</string>
- <string name="assistant_not_supported_text" msgid="1708031078549268884">"Ekrandagi matnni eshittirish yoki tarjima qilish uchun Sozlamalar orqali raqamli assistent ilovasini almashtiring"</string>
- <string name="tooltip_listen" msgid="7634466447860989102">"Ekrandagi matnni eshittirish uchun bosing"</string>
- <string name="tooltip_translate" msgid="4184845868901542567">"Ekrandagi matnni tarjima qilish uchun bosing"</string>
- <string name="toast_p2p_app_not_shareable" msgid="7229739094132131536">"Bu ilova ulashilmaydi"</string>
-</resources>
diff --git a/go/quickstep/res/values-vi/strings.xml b/go/quickstep/res/values-vi/strings.xml
deleted file mode 100644
index 0bca1688b9..0000000000
--- a/go/quickstep/res/values-vi/strings.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_share_drop_target_label" msgid="5804774105974539508">"Chia sẻ ứng dụng"</string>
- <string name="action_listen" msgid="2370304050784689486">"Nghe"</string>
- <string name="action_translate" msgid="8028378961867277746">"Dịch"</string>
- <string name="action_search" msgid="6269564710943755464">"Ống kính"</string>
- <string name="dialog_acknowledge" msgid="2804025517675853172">"OK"</string>
- <string name="dialog_cancel" msgid="6464336969134856366">"HỦY"</string>
- <string name="dialog_settings" msgid="6564397136021186148">"CÀI ĐẶT"</string>
- <string name="niu_actions_confirmation_title" msgid="3863451714863526143">"Dịch hoặc nghe văn bản trên màn hình"</string>
- <string name="niu_actions_confirmation_text" msgid="2105271481950866089">"Những thông tin như văn bản trên màn hình, địa chỉ web và ảnh chụp màn hình có thể được chia sẻ với Google.\n\nĐể thay đổi những thông tin mà bạn chia sẻ, hãy chuyển đến phần "<b>"Cài đặt &gt; Ứng dụng &gt; Ứng dụng mặc định &gt; Ứng dụng trợ lý kỹ thuật số"</b>"."</string>
- <string name="assistant_not_selected_title" msgid="5017072974603345228">"Chọn một ứng dụng trợ lý để dùng tính năng này"</string>
- <string name="assistant_not_selected_text" msgid="3244613673884359276">"Để nghe hoặc dịch văn bản trên màn hình, hãy chọn một ứng dụng trợ lý kỹ thuật số trong phần Cài đặt"</string>
- <string name="assistant_not_supported_title" msgid="1675788067597484142">"Thay đổi ứng dụng trợ lý để dùng tính năng này"</string>
- <string name="assistant_not_supported_text" msgid="1708031078549268884">"Để nghe hoặc dịch văn bản trên màn hình, hãy thay đổi ứng dụng trợ lý kỹ thuật số trong phần Cài đặt"</string>
- <string name="tooltip_listen" msgid="7634466447860989102">"Nhấn vào đây để nghe văn bản trên màn hình này"</string>
- <string name="tooltip_translate" msgid="4184845868901542567">"Nhấn vào đây để dịch văn bản trên màn hình này"</string>
- <string name="toast_p2p_app_not_shareable" msgid="7229739094132131536">"Bạn không thể chia sẻ ứng dụng này"</string>
-</resources>
diff --git a/go/quickstep/res/values-zh-rCN/strings.xml b/go/quickstep/res/values-zh-rCN/strings.xml
deleted file mode 100644
index 27bde298f6..0000000000
--- a/go/quickstep/res/values-zh-rCN/strings.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_share_drop_target_label" msgid="5804774105974539508">"分享应用"</string>
- <string name="action_listen" msgid="2370304050784689486">"聆听"</string>
- <string name="action_translate" msgid="8028378961867277746">"翻译"</string>
- <string name="action_search" msgid="6269564710943755464">"智能镜头"</string>
- <string name="dialog_acknowledge" msgid="2804025517675853172">"知道了"</string>
- <string name="dialog_cancel" msgid="6464336969134856366">"取消"</string>
- <string name="dialog_settings" msgid="6564397136021186148">"设置"</string>
- <string name="niu_actions_confirmation_title" msgid="3863451714863526143">"翻译或聆听屏幕上的文字"</string>
- <string name="niu_actions_confirmation_text" msgid="2105271481950866089">"系统可能会将屏幕上的文字、网址和屏幕截图等信息分享给 Google。\n\n如需更改要分享哪些信息,请依次转到"<b>"设置 &gt; 应用 &gt; 默认应用 &gt; 数字助理应用"</b>"。"</string>
- <string name="assistant_not_selected_title" msgid="5017072974603345228">"需选择一款助理应用,才能使用此功能"</string>
- <string name="assistant_not_selected_text" msgid="3244613673884359276">"如需收听或翻译屏幕上的文字,请在“设置”部分选择一款数字助理应用"</string>
- <string name="assistant_not_supported_title" msgid="1675788067597484142">"需更改助理应用,才能使用此功能"</string>
- <string name="assistant_not_supported_text" msgid="1708031078549268884">"如需收听或翻译屏幕上的文字,请在“设置”部分更改数字助理应用"</string>
- <string name="tooltip_listen" msgid="7634466447860989102">"点按此处即可收听屏幕上的文字"</string>
- <string name="tooltip_translate" msgid="4184845868901542567">"点按此处即可翻译屏幕上的文字"</string>
- <string name="toast_p2p_app_not_shareable" msgid="7229739094132131536">"无法分享此应用"</string>
-</resources>
diff --git a/go/quickstep/res/values-zh-rHK/strings.xml b/go/quickstep/res/values-zh-rHK/strings.xml
deleted file mode 100644
index 07cc125279..0000000000
--- a/go/quickstep/res/values-zh-rHK/strings.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_share_drop_target_label" msgid="5804774105974539508">"分享應用程式"</string>
- <string name="action_listen" msgid="2370304050784689486">"聆聽"</string>
- <string name="action_translate" msgid="8028378961867277746">"翻譯"</string>
- <string name="action_search" msgid="6269564710943755464">"智能鏡頭"</string>
- <string name="dialog_acknowledge" msgid="2804025517675853172">"知道了"</string>
- <string name="dialog_cancel" msgid="6464336969134856366">"取消"</string>
- <string name="dialog_settings" msgid="6564397136021186148">"設定"</string>
- <string name="niu_actions_confirmation_title" msgid="3863451714863526143">"翻譯或聆聽畫面上的文字"</string>
- <string name="niu_actions_confirmation_text" msgid="2105271481950866089">"可能會與 Google 分享螢幕上的文字、網址和螢幕截圖等資料。\n\n如要變更分享的資料,請前往 "<b>"[設定] &gt; [應用程式] &gt; [預設應用程式] &gt; [數碼助理應用程式]"</b>"。"</string>
- <string name="assistant_not_selected_title" msgid="5017072974603345228">"必須選擇數碼助理才可使用此功能"</string>
- <string name="assistant_not_selected_text" msgid="3244613673884359276">"如要聆聽或翻譯畫面上的文字,請在「設定」中選擇數碼助理應用程式"</string>
- <string name="assistant_not_supported_title" msgid="1675788067597484142">"必須變更數碼助理才可使用此功能"</string>
- <string name="assistant_not_supported_text" msgid="1708031078549268884">"如要聆聽或翻譯畫面上的文字,請在「設定」中變更數碼助理應用程式"</string>
- <string name="tooltip_listen" msgid="7634466447860989102">"輕按這裡即可聆聽此畫面上的文字"</string>
- <string name="tooltip_translate" msgid="4184845868901542567">"輕按這裡即可翻譯此畫面上的文字"</string>
- <string name="toast_p2p_app_not_shareable" msgid="7229739094132131536">"無法分享此應用程式"</string>
-</resources>
diff --git a/go/quickstep/res/values-zh-rTW/strings.xml b/go/quickstep/res/values-zh-rTW/strings.xml
deleted file mode 100644
index 41fd8b1244..0000000000
--- a/go/quickstep/res/values-zh-rTW/strings.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_share_drop_target_label" msgid="5804774105974539508">"分享應用程式"</string>
- <string name="action_listen" msgid="2370304050784689486">"聆聽"</string>
- <string name="action_translate" msgid="8028378961867277746">"翻譯"</string>
- <string name="action_search" msgid="6269564710943755464">"智慧鏡頭"</string>
- <string name="dialog_acknowledge" msgid="2804025517675853172">"我知道了"</string>
- <string name="dialog_cancel" msgid="6464336969134856366">"取消"</string>
- <string name="dialog_settings" msgid="6564397136021186148">"設定"</string>
- <string name="niu_actions_confirmation_title" msgid="3863451714863526143">"翻譯或朗讀畫面上的文字"</string>
- <string name="niu_actions_confirmation_text" msgid="2105271481950866089">"系統可能會將畫面上的文字、網址和螢幕截圖等資訊分享給 Google。\n\n如要變更分享的資訊類型,請前往 [設定] &gt; [應用程式] &gt; [預設應用程式] &gt; [數位助理應用程式]"<b></b>"。"</string>
- <string name="assistant_not_selected_title" msgid="5017072974603345228">"必須選擇數位助理應用程式才能使用這項功能"</string>
- <string name="assistant_not_selected_text" msgid="3244613673884359276">"如要聽取或翻譯畫面上的文字,請前往「設定」選擇數位助理應用程式"</string>
- <string name="assistant_not_supported_title" msgid="1675788067597484142">"必須變更數位助理應用程式才能使用這項功能"</string>
- <string name="assistant_not_supported_text" msgid="1708031078549268884">"如要聽取或翻譯畫面上的文字,請前往「設定」變更數位助理應用程式"</string>
- <string name="tooltip_listen" msgid="7634466447860989102">"輕觸這裡即可聽取這個畫面上的文字"</string>
- <string name="tooltip_translate" msgid="4184845868901542567">"輕觸這裡即可翻譯這個畫面上的文字"</string>
- <string name="toast_p2p_app_not_shareable" msgid="7229739094132131536">"無法分享這個應用程式"</string>
-</resources>
diff --git a/go/quickstep/res/values-zu/strings.xml b/go/quickstep/res/values-zu/strings.xml
deleted file mode 100644
index d496b6442d..0000000000
--- a/go/quickstep/res/values-zu/strings.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_share_drop_target_label" msgid="5804774105974539508">"Yabelana nge-App"</string>
- <string name="action_listen" msgid="2370304050784689486">"Lalela"</string>
- <string name="action_translate" msgid="8028378961867277746">"Humusha"</string>
- <string name="action_search" msgid="6269564710943755464">"Ilensi"</string>
- <string name="dialog_acknowledge" msgid="2804025517675853172">"NGIYITHOLILE"</string>
- <string name="dialog_cancel" msgid="6464336969134856366">"KHANSELA"</string>
- <string name="dialog_settings" msgid="6564397136021186148">"AMASETHINGI"</string>
- <string name="niu_actions_confirmation_title" msgid="3863451714863526143">"Humusha noma ulalele umbhalo osesikrinini"</string>
- <string name="niu_actions_confirmation_text" msgid="2105271481950866089">"Imininingwane efana nombhalo esikrinini sakho, amakheli wewebhu, nezithombe-skrini kungabiwa ne-Google.\n\nUkuze ushintshe ukuthi yiluphi ulwazi olwabayo, yiya kokuthi "<b>"Amasethingi &gt; ama-App &gt; Ama-app azenzekelayo &gt; Umsizi we-app odijithali"</b>"."</string>
- <string name="assistant_not_selected_title" msgid="5017072974603345228">"Khetha umsizi ukuze usebenzise lesi sakhi"</string>
- <string name="assistant_not_selected_text" msgid="3244613673884359276">"Ukuze ulalele noma uhumushe umbhalo kusikrini sakho, khetha i-app yomsizi odijithali kokuthi Amasethingi"</string>
- <string name="assistant_not_supported_title" msgid="1675788067597484142">"Shintsha umsizi wakho ukuze usebenzise lesi sakhi"</string>
- <string name="assistant_not_supported_text" msgid="1708031078549268884">"Ukuze ulalele noma uhumushe umbhalo kusikrini sakho, shintsha i-app yomsizi wakho odijithali kokuthi Amasethingi"</string>
- <string name="tooltip_listen" msgid="7634466447860989102">"Thepha lapha ukuze ulalele umbhalo kusikrini"</string>
- <string name="tooltip_translate" msgid="4184845868901542567">"Thepha lapha ukuze uhumushe umbhalo kulesi sikrini"</string>
- <string name="toast_p2p_app_not_shareable" msgid="7229739094132131536">"Le app ayikwazi ukwabiwa"</string>
-</resources>
diff --git a/go/quickstep/res/values/integers.xml b/go/quickstep/res/values/integers.xml
deleted file mode 100644
index e6e8111eab..0000000000
--- a/go/quickstep/res/values/integers.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2021 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.
- -->
-<resources>
- <!-- Job IDs must be integers unique within their package -->
- <integer name="app_shareability_job_id">200</integer>
-</resources> \ No newline at end of file
diff --git a/go/quickstep/res/values/strings.xml b/go/quickstep/res/values/strings.xml
index 42f4702141..8429f6a7f2 100644
--- a/go/quickstep/res/values/strings.xml
+++ b/go/quickstep/res/values/strings.xml
@@ -41,8 +41,4 @@
<string name="tooltip_listen">Tap here to listen to text on this screen</string>
<!-- Tooltip to highlight and explain the Translate button -->
<string name="tooltip_translate">Tap here to translate text on this screen</string>
-
- <!-- ******* Toast Messages ******* -->
- <!-- Toast to indicate that an app cannot be shared -->
- <string name="toast_p2p_app_not_shareable">This app can’t be shared</string>
</resources>
diff --git a/go/quickstep/res/values/styles.xml b/go/quickstep/res/values/styles.xml
index c659331bde..442c41375d 100644
--- a/go/quickstep/res/values/styles.xml
+++ b/go/quickstep/res/values/styles.xml
@@ -73,7 +73,7 @@
<style name="ModalDialogText">
<item name="android:fontFamily">sans-serif-medium</item>
<item name="android:textSize">16sp</item>
- <item name="android:textColor">?android:attr/textColorTertiary</item>
+ <item name="android:textColor">?android:attr/textColorSecondary</item>
<item name="android:lineHeight">24dp</item>
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">wrap_content</item>
diff --git a/go/quickstep/src/com/android/launcher3/AppSharing.java b/go/quickstep/src/com/android/launcher3/AppSharing.java
index cb1f1c7625..b72e71c2b5 100644
--- a/go/quickstep/src/com/android/launcher3/AppSharing.java
+++ b/go/quickstep/src/com/android/launcher3/AppSharing.java
@@ -16,32 +16,20 @@
package com.android.launcher3;
-import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_SYSTEM_SHORTCUT_APP_SHARE_TAP;
-
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.net.Uri;
-import android.os.Process;
-import android.os.UserHandle;
-import android.os.UserManager;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
-import android.widget.Toast;
import androidx.core.content.FileProvider;
-import com.android.launcher3.model.AppShareabilityChecker;
-import com.android.launcher3.model.AppShareabilityJobService;
-import com.android.launcher3.model.AppShareabilityManager;
-import com.android.launcher3.model.AppShareabilityManager.ShareabilityStatus;
import com.android.launcher3.model.data.ItemInfo;
-import com.android.launcher3.popup.PopupDataProvider;
import com.android.launcher3.popup.SystemShortcut;
-import com.android.launcher3.views.ActivityContext;
import java.io.File;
@@ -56,11 +44,6 @@ public final class AppSharing {
* because it is unique to Go and not toggleable at runtime.
*/
public static final boolean ENABLE_APP_SHARING = true;
- /**
- * With this flag enabled, the Share App button will be dynamically enabled/disabled based
- * on each app's shareability status.
- */
- public static final boolean ENABLE_SHAREABILITY_CHECK = true;
private static final String TAG = "AppSharing";
private static final String FILE_PROVIDER_SUFFIX = ".overview.fileprovider";
@@ -68,70 +51,46 @@ public final class AppSharing {
private static final String APP_MIME_TYPE = "application/application";
private final String mSharingComponent;
- private AppShareabilityManager mShareabilityMgr;
private AppSharing(Launcher launcher) {
mSharingComponent = launcher.getText(R.string.app_sharing_component).toString();
}
+ private boolean canShare(ItemInfo info) {
+ /**
+ * TODO: Implement once b/168831749 has been resolved
+ * The implementation should check the validity of the app.
+ * It should also check whether the app is free or paid, returning false in the latter case.
+ * For now, all checks occur in the sharing app.
+ * So, we simply check whether the sharing app is defined.
+ */
+ return !TextUtils.isEmpty(mSharingComponent);
+ }
+
private Uri getShareableUri(Context context, String path, String displayName) {
String authority = BuildConfig.APPLICATION_ID + FILE_PROVIDER_SUFFIX;
File pathFile = new File(path);
return FileProvider.getUriForFile(context, authority, pathFile, displayName);
}
- private SystemShortcut<Launcher> getShortcut(Launcher launcher, ItemInfo info,
- View originalView) {
- if (TextUtils.isEmpty(mSharingComponent)) {
+ private SystemShortcut<Launcher> getShortcut(Launcher launcher, ItemInfo info) {
+ if (!canShare(info)) {
return null;
}
- return new Share(launcher, info, originalView);
- }
- /**
- * Instantiates AppShareabilityManager, which then reads app shareability data from disk
- * Also schedules a job to update those data
- * @param context The application context
- * @param checker An implementation of AppShareabilityChecker to perform the actual checks
- * when updating the data
- */
- public static void setUpShareabilityCache(Context context, AppShareabilityChecker checker) {
- AppShareabilityManager shareMgr = AppShareabilityManager.INSTANCE.get(context);
- shareMgr.setShareabilityChecker(checker);
- AppShareabilityJobService.schedule(context);
+ return new Share(launcher, info);
}
/**
* The Share App system shortcut, used to initiate p2p sharing of a given app
*/
public final class Share extends SystemShortcut<Launcher> {
- private final PopupDataProvider mPopupDataProvider;
- private final boolean mSharingEnabledForUser;
-
- public Share(Launcher target, ItemInfo itemInfo, View originalView) {
- super(R.drawable.ic_share, R.string.app_share_drop_target_label, target, itemInfo,
- originalView);
- mPopupDataProvider = target.getPopupDataProvider();
-
- mSharingEnabledForUser = bluetoothSharingEnabled(target);
- if (!mSharingEnabledForUser) {
- setEnabled(false);
- } else if (ENABLE_SHAREABILITY_CHECK) {
- mShareabilityMgr =
- AppShareabilityManager.INSTANCE.get(target.getApplicationContext());
- checkShareability(/* requestUpdateIfUnknown */ true);
- }
+ public Share(Launcher target, ItemInfo itemInfo) {
+ super(R.drawable.ic_share, R.string.app_share_drop_target_label, target, itemInfo);
}
@Override
public void onClick(View view) {
- ActivityContext.lookupContext(view.getContext())
- .getStatsLogManager().logger().log(LAUNCHER_SYSTEM_SHORTCUT_APP_SHARE_TAP);
- if (!isEnabled()) {
- showCannotShareToast(view.getContext());
- return;
- }
-
Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
@@ -159,60 +118,15 @@ public final class AppSharing {
sendIntent.setType(APP_MIME_TYPE);
sendIntent.setComponent(ComponentName.unflattenFromString(mSharingComponent));
- UserHandle user = mItemInfo.user;
- if (user != null && !user.equals(Process.myUserHandle())) {
- mTarget.startActivityAsUser(sendIntent, user);
- } else {
- mTarget.startActivitySafely(view, sendIntent, mItemInfo);
- }
+ mTarget.startActivitySafely(view, sendIntent, mItemInfo);
AbstractFloatingView.closeAllOpenViews(mTarget);
}
-
- private void onStatusUpdated(boolean success) {
- if (!success) {
- // Something went wrong. Specific error logged in AppShareabilityManager.
- return;
- }
- checkShareability(/* requestUpdateIfUnknown */ false);
- mTarget.runOnUiThread(() -> {
- mPopupDataProvider.redrawSystemShortcuts();
- });
- }
-
- private void checkShareability(boolean requestUpdateIfUnknown) {
- String packageName = mItemInfo.getTargetComponent().getPackageName();
- @ShareabilityStatus int status = mShareabilityMgr.getStatus(packageName);
- setEnabled(status == ShareabilityStatus.SHAREABLE);
-
- if (requestUpdateIfUnknown && status == ShareabilityStatus.UNKNOWN) {
- mShareabilityMgr.requestAppStatusUpdate(packageName, this::onStatusUpdated);
- }
- }
-
- private boolean bluetoothSharingEnabled(Context context) {
- return !context.getSystemService(UserManager.class)
- .hasUserRestriction(UserManager.DISALLOW_BLUETOOTH_SHARING, mItemInfo.user);
- }
-
- private void showCannotShareToast(Context context) {
- ActivityContext activityContext = ActivityContext.lookupContext(context);
- String blockedByMessage = activityContext.getStringCache() != null
- ? activityContext.getStringCache().disabledByAdminMessage
- : context.getString(R.string.blocked_by_policy);
-
- CharSequence text = (mSharingEnabledForUser)
- ? context.getText(R.string.toast_p2p_app_not_shareable)
- : blockedByMessage;
- int duration = Toast.LENGTH_SHORT;
- Toast.makeText(context, text, duration).show();
- }
}
/**
* Shortcut factory for generating the Share App button
*/
- public static final SystemShortcut.Factory<Launcher> SHORTCUT_FACTORY =
- (launcher, itemInfo, originalView) ->
- (new AppSharing(launcher)).getShortcut(launcher, itemInfo, originalView);
+ public static final SystemShortcut.Factory<Launcher> SHORTCUT_FACTORY = (launcher, itemInfo) ->
+ (new AppSharing(launcher)).getShortcut(launcher, itemInfo);
}
diff --git a/go/quickstep/src/com/android/launcher3/model/AppShareabilityChecker.java b/go/quickstep/src/com/android/launcher3/model/AppShareabilityChecker.java
deleted file mode 100644
index 0a82904670..0000000000
--- a/go/quickstep/src/com/android/launcher3/model/AppShareabilityChecker.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2021 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.launcher3.model;
-
-import androidx.annotation.Nullable;
-
-import java.util.List;
-import java.util.function.Consumer;
-
-/**
- * Interface for checking apps' shareability. Implementations need to be able to determine whether
- * apps are shareable given their package names.
- */
-public interface AppShareabilityChecker {
- /**
- * Checks the shareability of the provided apps. Once the check is complete, updates the
- * provided manager with the results and calls the (optionally) provided callback.
- * @param packageNames The apps to check
- * @param shareMgr The manager to receive the results
- * @param callback Optional callback to be invoked when the check is finished
- */
- void checkApps(List<String> packageNames, AppShareabilityManager shareMgr,
- @Nullable Consumer<Boolean> callback);
-}
diff --git a/go/quickstep/src/com/android/launcher3/model/AppShareabilityDatabase.java b/go/quickstep/src/com/android/launcher3/model/AppShareabilityDatabase.java
deleted file mode 100644
index 03eed7eccc..0000000000
--- a/go/quickstep/src/com/android/launcher3/model/AppShareabilityDatabase.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2021 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.launcher3.model;
-
-import androidx.room.Dao;
-import androidx.room.Database;
-import androidx.room.Insert;
-import androidx.room.OnConflictStrategy;
-import androidx.room.Query;
-import androidx.room.RoomDatabase;
-import androidx.room.Update;
-
-import java.util.List;
-
-/**
- * This database maintains a collection of AppShareabilityStatus items
- * In its intended use case, there will be one entry for each app installed on the device
- */
-@Database(entities = {AppShareabilityStatus.class}, exportSchema = false, version = 1)
-public abstract class AppShareabilityDatabase extends RoomDatabase {
- /**
- * Data Access Object for this database
- */
- @Dao
- public interface ShareabilityDao {
- /** Add an AppShareabilityStatus to the database */
- @Insert(onConflict = OnConflictStrategy.REPLACE)
- void insertAppStatus(AppShareabilityStatus status);
-
- /** Add a collection of AppShareabilityStatus objects to the database */
- @Insert(onConflict = OnConflictStrategy.REPLACE)
- void insertAppStatuses(AppShareabilityStatus... statuses);
-
- /**
- * Update an AppShareabilityStatus in the database
- * @return The number of entries successfully updated
- */
- @Update
- int updateAppStatus(AppShareabilityStatus status);
-
- /** Retrieve all entries from the database */
- @Query("SELECT * FROM AppShareabilityStatus")
- List<AppShareabilityStatus> getAllEntries();
- }
-
- protected abstract ShareabilityDao shareabilityDao();
-}
diff --git a/go/quickstep/src/com/android/launcher3/model/AppShareabilityJobService.java b/go/quickstep/src/com/android/launcher3/model/AppShareabilityJobService.java
deleted file mode 100644
index 60bea53c70..0000000000
--- a/go/quickstep/src/com/android/launcher3/model/AppShareabilityJobService.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) 2021 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.launcher3.model;
-
-import android.app.job.JobInfo;
-import android.app.job.JobParameters;
-import android.app.job.JobScheduler;
-import android.app.job.JobService;
-import android.content.ComponentName;
-import android.content.Context;
-import android.util.Log;
-
-import com.android.launcher3.R;
-
-/**
- * A job to request AppShareabilityManager to update its shareability data
- * The shareability status of an app is not expected to change often, so this job is only
- * run periodically.
- */
-public final class AppShareabilityJobService extends JobService {
-
- private static final String TAG = "AppShareabilityJobService";
- // Run this job once a week
- private static final int RECURRENCE_INTERVAL_MILLIS = 604800000;
-
- @Override
- public boolean onStartJob(final JobParameters params) {
- Context context = getApplicationContext();
- AppShareabilityManager.INSTANCE.get(context).requestFullUpdate();
- return false; // Job is finished
- }
-
- @Override
- public boolean onStopJob(final JobParameters params) {
- Log.d(TAG, "App shareability data update job stopped; id=" + params.getJobId()
- + ", reason="
- + JobParameters.getInternalReasonCodeDescription(params.getStopReason()));
- return true; // Reschedule the job
- }
-
- /**
- * Creates and schedules the job.
- * Does not schedule a duplicate job if one is already pending.
- * @param context The application context
- */
- public static void schedule(Context context) {
- final JobScheduler jobScheduler = context.getSystemService(JobScheduler.class);
-
- final JobInfo pendingJob = jobScheduler.getPendingJob(R.integer.app_shareability_job_id);
- if (pendingJob != null) {
- // Don't schedule duplicate jobs
- return;
- }
-
- final JobInfo newJob = new JobInfo.Builder(R.integer.app_shareability_job_id,
- new ComponentName(context, AppShareabilityJobService.class))
- .setPeriodic(RECURRENCE_INTERVAL_MILLIS)
- .setPersisted(true)
- .setRequiresBatteryNotLow(true)
- .build();
- jobScheduler.schedule(newJob);
- }
-}
diff --git a/go/quickstep/src/com/android/launcher3/model/AppShareabilityManager.java b/go/quickstep/src/com/android/launcher3/model/AppShareabilityManager.java
deleted file mode 100644
index 0d0f700b39..0000000000
--- a/go/quickstep/src/com/android/launcher3/model/AppShareabilityManager.java
+++ /dev/null
@@ -1,211 +0,0 @@
-/*
- * Copyright (C) 2021 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.launcher3.model;
-
-import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
-
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-import android.content.Context;
-import android.content.pm.LauncherActivityInfo;
-import android.content.pm.LauncherApps;
-import android.os.Process;
-import android.util.ArrayMap;
-import android.util.Log;
-
-import androidx.annotation.IntDef;
-import androidx.annotation.Nullable;
-import androidx.annotation.WorkerThread;
-import androidx.room.Room;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.launcher3.model.AppShareabilityDatabase.ShareabilityDao;
-import com.android.launcher3.util.MainThreadInitializedObject;
-
-import java.lang.annotation.Retention;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.function.Consumer;
-
-/**
- * This class maintains the shareability status of installed apps.
- * Each app's status is retrieved from the Play Store's API. Statuses are cached in order
- * to limit extraneous calls to that API (which can be time-consuming).
- */
-public class AppShareabilityManager {
- @Retention(SOURCE)
- @IntDef({
- ShareabilityStatus.UNKNOWN,
- ShareabilityStatus.NOT_SHAREABLE,
- ShareabilityStatus.SHAREABLE
- })
- public @interface ShareabilityStatus {
- int UNKNOWN = 0;
- int NOT_SHAREABLE = 1;
- int SHAREABLE = 2;
- }
-
- private static final String TAG = "AppShareabilityManager";
- private static final String DB_NAME = "shareabilityDatabase";
- public static MainThreadInitializedObject<AppShareabilityManager> INSTANCE =
- new MainThreadInitializedObject<>(AppShareabilityManager::new);
-
- private final Context mContext;
- // Local map to store the data in memory for quick access
- private final Map<String, Integer> mDataMap;
- // Database to persist the data across reboots
- private AppShareabilityDatabase mDatabase;
- // Data Access Object for the database
- private ShareabilityDao mDao;
- // Class to perform shareability checks
- private AppShareabilityChecker mShareChecker;
-
- private AppShareabilityManager(Context context) {
- mContext = context;
- mDataMap = new ArrayMap<>();
- mDatabase = Room.databaseBuilder(mContext, AppShareabilityDatabase.class, DB_NAME).build();
- mDao = mDatabase.shareabilityDao();
- MODEL_EXECUTOR.post(this::readFromDB);
- }
-
- /**
- * Set the shareability checker. The checker determines whether given apps are shareable.
- * This must be set before the manager can update its data.
- * @param checker Implementation of AppShareabilityChecker to perform the checks
- */
- public void setShareabilityChecker(AppShareabilityChecker checker) {
- mShareChecker = checker;
- }
-
- /**
- * Retrieve the ShareabilityStatus of an app from the local map
- * This does not interact with the saved database
- * @param packageName The app's package name
- * @return The status as a ShareabilityStatus integer
- */
- public synchronized @ShareabilityStatus int getStatus(String packageName) {
- @ShareabilityStatus int status = ShareabilityStatus.UNKNOWN;
- if (mDataMap.containsKey(packageName)) {
- status = mDataMap.get(packageName);
- }
- return status;
- }
-
- /**
- * Set the status of a given app. This updates the local map as well as the saved database.
- */
- public synchronized void setStatus(String packageName, @ShareabilityStatus int status) {
- mDataMap.put(packageName, status);
-
- // Write to the database on a separate thread
- MODEL_EXECUTOR.post(() ->
- mDao.insertAppStatus(new AppShareabilityStatus(packageName, status)));
- }
-
- /**
- * Set the statuses of given apps. This updates the local map as well as the saved database.
- */
- public synchronized void setStatuses(List<AppShareabilityStatus> statuses) {
- for (int i = 0, size = statuses.size(); i < size; i++) {
- AppShareabilityStatus entry = statuses.get(i);
- mDataMap.put(entry.packageName, entry.status);
- }
-
- // Write to the database on a separate thread
- MODEL_EXECUTOR.post(() ->
- mDao.insertAppStatuses(statuses.toArray(new AppShareabilityStatus[0])));
- }
-
- /**
- * Request a status update for a specific app
- * @param packageName The app's package name
- * @param callback Optional callback to be called when the update is complete. The received
- * Boolean denotes whether the update was successful.
- */
- public void requestAppStatusUpdate(String packageName, @Nullable Consumer<Boolean> callback) {
- MODEL_EXECUTOR.post(() -> updateCache(packageName, callback));
- }
-
- /**
- * Request a status update for all apps
- */
- public void requestFullUpdate() {
- MODEL_EXECUTOR.post(this::updateCache);
- }
-
- /**
- * Update the cached shareability data for all installed apps
- */
- @WorkerThread
- private void updateCache() {
- updateCache(/* packageName */ null, /* callback */ null);
- }
-
- /**
- * Update the cached shareability data
- * @param packageName A specific package to update. If null, all installed apps will be updated.
- * @param callback Optional callback to be called when the update is complete. The received
- * Boolean denotes whether the update was successful.
- */
- @WorkerThread
- private void updateCache(@Nullable String packageName, @Nullable Consumer<Boolean> callback) {
- if (mShareChecker == null) {
- Log.e(TAG, "AppShareabilityChecker not set");
- return;
- }
-
- List<String> packageNames = new ArrayList<>();
- if (packageName != null) {
- packageNames.add(packageName);
- } else {
- LauncherApps launcherApps = mContext.getSystemService(LauncherApps.class);
- List<LauncherActivityInfo> installedApps =
- launcherApps.getActivityList(/* packageName */ null, Process.myUserHandle());
- for (int i = 0, size = installedApps.size(); i < size; i++) {
- packageNames.add(installedApps.get(i).getApplicationInfo().packageName);
- }
- }
-
- mShareChecker.checkApps(packageNames, this, callback);
- }
-
- @WorkerThread
- private synchronized void readFromDB() {
- mDataMap.clear();
- List<AppShareabilityStatus> entries = mDao.getAllEntries();
- for (int i = 0, size = entries.size(); i < size; i++) {
- AppShareabilityStatus entry = entries.get(i);
- mDataMap.put(entry.packageName, entry.status);
- }
- }
-
- /**
- * Provides a testable instance of this class
- * This instance allows database queries on the main thread
- * @hide */
- @VisibleForTesting
- public static AppShareabilityManager getTestInstance(Context context) {
- AppShareabilityManager manager = new AppShareabilityManager(context);
- manager.mDatabase.close();
- manager.mDatabase = Room.inMemoryDatabaseBuilder(context, AppShareabilityDatabase.class)
- .allowMainThreadQueries()
- .build();
- manager.mDao = manager.mDatabase.shareabilityDao();
- return manager;
- }
-}
diff --git a/go/quickstep/src/com/android/launcher3/model/AppShareabilityStatus.java b/go/quickstep/src/com/android/launcher3/model/AppShareabilityStatus.java
deleted file mode 100644
index 61018c6b25..0000000000
--- a/go/quickstep/src/com/android/launcher3/model/AppShareabilityStatus.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2021 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.launcher3.model;
-
-import androidx.annotation.NonNull;
-import androidx.room.Entity;
-import androidx.room.PrimaryKey;
-
-import com.android.launcher3.model.AppShareabilityManager.ShareabilityStatus;
-
-/**
- * Database entry to hold the shareability status of a single app
- */
-@Entity
-public class AppShareabilityStatus {
- @PrimaryKey
- @NonNull
- public String packageName;
-
- public @ShareabilityStatus int status;
-
- public AppShareabilityStatus(@NonNull String packageName, @ShareabilityStatus int status) {
- this.packageName = packageName;
- this.status = status;
- }
-}
diff --git a/go/quickstep/src/com/android/quickstep/TaskOverlayFactoryGo.java b/go/quickstep/src/com/android/quickstep/TaskOverlayFactoryGo.java
index c997e52dbd..91cab3cbd6 100644
--- a/go/quickstep/src/com/android/quickstep/TaskOverlayFactoryGo.java
+++ b/go/quickstep/src/com/android/quickstep/TaskOverlayFactoryGo.java
@@ -50,9 +50,9 @@ import androidx.annotation.IntDef;
import androidx.annotation.VisibleForTesting;
import com.android.launcher3.BaseActivity;
+import com.android.launcher3.BaseDraggingActivity;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
-import com.android.launcher3.views.ArrowTipView;
import com.android.quickstep.util.AssistContentRequester;
import com.android.quickstep.util.RecentsOrientedState;
import com.android.quickstep.views.GoOverviewActionsView;
@@ -75,7 +75,7 @@ public final class TaskOverlayFactoryGo extends TaskOverlayFactory {
public static final String ACTIONS_ERROR_CODE = "niu_actions_app_error_code";
public static final int ERROR_PERMISSIONS_STRUCTURE = 1;
public static final int ERROR_PERMISSIONS_SCREENSHOT = 2;
- public static final String NIU_ACTIONS_CONFIRMED = "launcher_go.niu_actions_confirmed";
+ private static final String NIU_ACTIONS_CONFIRMED = "launcher_go.niu_actions_confirmed";
private static final String ASSIST_SETTINGS_ARGS_BUNDLE = ":settings:show_fragment_args";
private static final String ASSIST_SETTINGS_ARGS_KEY = ":settings:fragment_args_key";
private static final String ASSIST_SETTINGS_PREFERENCE_KEY = "default_assist";
@@ -86,11 +86,10 @@ public final class TaskOverlayFactoryGo extends TaskOverlayFactory {
@Retention(SOURCE)
@IntDef({PRIVACY_CONFIRMATION, ASSISTANT_NOT_SELECTED, ASSISTANT_NOT_SUPPORTED})
- @VisibleForTesting
- public @interface DialogType{}
- public static final int PRIVACY_CONFIRMATION = 0;
- public static final int ASSISTANT_NOT_SELECTED = 1;
- public static final int ASSISTANT_NOT_SUPPORTED = 2;
+ private @interface DialogType{}
+ private static final int PRIVACY_CONFIRMATION = 0;
+ private static final int ASSISTANT_NOT_SELECTED = 1;
+ private static final int ASSISTANT_NOT_SUPPORTED = 2;
private AssistContentRequester mContentRequester;
@@ -118,7 +117,6 @@ public final class TaskOverlayFactoryGo extends TaskOverlayFactory {
private AssistContentRequester mFactoryContentRequester;
private SharedPreferences mSharedPreferences;
private OverlayDialogGo mDialog;
- private ArrowTipView mArrowTipView;
private TaskOverlayGo(TaskThumbnailView taskThumbnailView,
AssistContentRequester assistContentRequester) {
@@ -186,9 +184,6 @@ public final class TaskOverlayFactoryGo extends TaskOverlayFactory {
public void reset() {
super.reset();
mWebUrl = null;
- if (mDialog != null && mDialog.isShowing()) {
- mDialog.dismiss();
- }
}
@Override
@@ -214,8 +209,7 @@ public final class TaskOverlayFactoryGo extends TaskOverlayFactory {
Intent intent = createNIUIntent(actionType);
// Only add and send the image if the appropriate permissions are held
if (mAssistStructurePermitted && mAssistScreenshotPermitted) {
- mImageApi.shareAsDataWithExplicitIntent(/* crop */ null, intent,
- () -> showDialog(actionType, ASSISTANT_NOT_SUPPORTED));
+ mImageApi.shareAsDataWithExplicitIntent(/* crop */ null, intent);
} else {
// If both permissions are disabled, the structure error code takes priority
// The user must enable that one before they can enable screenshots
@@ -259,11 +253,7 @@ public final class TaskOverlayFactoryGo extends TaskOverlayFactory {
String assistantPackage =
Settings.Secure.getString(contentResolver, Settings.Secure.ASSISTANT);
- if (!TextUtils.isEmpty(assistantPackage)) {
- mNIUPackageName = assistantPackage.split("/", 2)[0];
- } else {
- mNIUPackageName = "";
- }
+ mNIUPackageName = assistantPackage.split("/", 2)[0];
}
protected class OverlayUICallbacksGoImpl extends OverlayUICallbacksImpl
@@ -305,6 +295,7 @@ public final class TaskOverlayFactoryGo extends TaskOverlayFactory {
mImageApi = imageActionsApi;
}
+ // TODO (b/192406446): Test that these dialogs are shown at the appropriate times
private void showDialog(String action, @DialogType int type) {
switch (type) {
case PRIVACY_CONFIRMATION:
@@ -337,7 +328,7 @@ public final class TaskOverlayFactoryGo extends TaskOverlayFactory {
int bodyTextID, int button1TextID,
View.OnClickListener button1Callback, int button2TextID,
View.OnClickListener button2Callback) {
- BaseActivity activity = BaseActivity.fromContext(getActionsView().getContext());
+ BaseDraggingActivity activity = BaseActivity.fromContext(getActionsView().getContext());
LayoutInflater inflater = LayoutInflater.from(activity);
View view = inflater.inflate(R.layout.niu_actions_dialog, /* root */ null);
@@ -371,11 +362,6 @@ public final class TaskOverlayFactoryGo extends TaskOverlayFactory {
mDialog.cancel();
}
- @VisibleForTesting
- public OverlayDialogGo getDialog() {
- return mDialog;
- }
-
private void onDialogClickSettings(View v) {
mDialog.dismiss();
@@ -396,24 +382,17 @@ public final class TaskOverlayFactoryGo extends TaskOverlayFactory {
* Order of tooltips are translate and then listen
*/
private void showTooltipsIfUnseen() {
- if (mArrowTipView != null && mArrowTipView.isOpen()) {
- return;
- }
if (!mSharedPreferences.getBoolean(TRANSLATE_TOOL_TIP_SEEN, false)) {
- mArrowTipView = ((GoOverviewActionsView) getActionsView()).showTranslateToolTip();
+ ((GoOverviewActionsView) getActionsView()).showTranslateToolTip();
mSharedPreferences.edit().putBoolean(TRANSLATE_TOOL_TIP_SEEN, true).apply();
} else if (!mSharedPreferences.getBoolean(LISTEN_TOOL_TIP_SEEN, false)) {
- mArrowTipView = ((GoOverviewActionsView) getActionsView()).showListenToolTip();
+ ((GoOverviewActionsView) getActionsView()).showListenToolTip();
mSharedPreferences.edit().putBoolean(LISTEN_TOOL_TIP_SEEN, true).apply();
}
}
}
- /**
- * Basic modal dialog for various user prompts
- */
- @VisibleForTesting
- public static final class OverlayDialogGo extends AlertDialog {
+ private static final class OverlayDialogGo extends AlertDialog {
private final String mAction;
private final @DialogType int mType;
diff --git a/go/quickstep/src/com/android/quickstep/views/GoOverviewActionsView.java b/go/quickstep/src/com/android/quickstep/views/GoOverviewActionsView.java
index 4e0aec3732..97ba5905e0 100644
--- a/go/quickstep/src/com/android/quickstep/views/GoOverviewActionsView.java
+++ b/go/quickstep/src/com/android/quickstep/views/GoOverviewActionsView.java
@@ -35,7 +35,6 @@ import com.android.quickstep.util.RecentsOrientedState;
*/
public class GoOverviewActionsView extends OverviewActionsView<OverlayUICallbacksGo> {
- @Nullable
private ArrowTipView mArrowTipView;
public GoOverviewActionsView(Context context) {
@@ -85,33 +84,31 @@ public class GoOverviewActionsView extends OverviewActionsView<OverlayUICallback
/**
* Shows Tooltip for action icons
*/
- private ArrowTipView showToolTip(int viewId, int textResourceId) {
+ private void showToolTip(int viewId, int textResourceId) {
int[] location = new int[2];
@Px int topMargin = getResources().getDimensionPixelSize(R.dimen.tooltip_top_margin);
findViewById(viewId).getLocationOnScreen(location);
mArrowTipView = new ArrowTipView(getContext(), /* isPointingUp= */ false)
.showAtLocation(getResources().getString(textResourceId),
/* arrowXCoord= */ location[0] + findViewById(viewId).getWidth() / 2,
- /* yCoord= */ location[1] - topMargin,
- /* shouldAutoClose= */ false);
+ /* yCoord= */ location[1] - topMargin);
mArrowTipView.bringToFront();
- return mArrowTipView;
}
/**
* Shows Tooltip for listen action icon
*/
- public ArrowTipView showListenToolTip() {
- return showToolTip(/* viewId= */ R.id.action_listen,
+ public void showListenToolTip() {
+ showToolTip(/* viewId= */ R.id.action_listen,
/* textResourceId= */ R.string.tooltip_listen);
}
/**
* Shows Tooltip for translate action icon
*/
- public ArrowTipView showTranslateToolTip() {
- return showToolTip(/* viewId= */ R.id.action_translate,
+ public void showTranslateToolTip() {
+ showToolTip(/* viewId= */ R.id.action_translate,
/* textResourceId= */ R.string.tooltip_translate);
}
@@ -120,7 +117,7 @@ public class GoOverviewActionsView extends OverviewActionsView<OverlayUICallback
*/
public void updateOrientationState(RecentsOrientedState orientedState) {
// dismiss tooltip
- boolean canLauncherRotate = orientedState.isRecentsActivityRotationAllowed();
+ boolean canLauncherRotate = orientedState.canRecentsActivityRotate();
if (mArrowTipView != null && !canLauncherRotate) {
mArrowTipView.close(/* animate= */ false);
}
diff --git a/go/res/xml/device_profiles.xml b/go/res/xml/device_profiles.xml
index 7c3a160d37..0c7eba31bd 100644
--- a/go/res/xml/device_profiles.xml
+++ b/go/res/xml/device_profiles.xml
@@ -33,8 +33,6 @@
launcher:minHeightDps="491.33"
launcher:iconImageSize="60"
launcher:iconTextSize="14.0"
- launcher:allAppsBorderSpace="16"
- launcher:allAppsCellHeight="104"
launcher:canBeDefault="true" />
</grid-option>
diff --git a/go/src/com/android/launcher3/model/WidgetsModel.java b/go/src/com/android/launcher3/model/WidgetsModel.java
index 1aa5d03f6d..f8448daf3d 100644
--- a/go/src/com/android/launcher3/model/WidgetsModel.java
+++ b/go/src/com/android/launcher3/model/WidgetsModel.java
@@ -79,13 +79,12 @@ public class WidgetsModel {
}
public WidgetItem getWidgetProviderInfoByProviderName(
- ComponentName providerName, UserHandle user) {
+ ComponentName providerName) {
return null;
}
/** Returns {@link PackageItemInfo} of a pending widget. */
- public static PackageItemInfo newPendingItemInfo(
- Context context, ComponentName provider, UserHandle userHandle) {
- return new PackageItemInfo(provider.getPackageName(), userHandle);
+ public static PackageItemInfo newPendingItemInfo(ComponentName provider) {
+ return new PackageItemInfo(provider.getPackageName());
}
} \ No newline at end of file
diff --git a/go/src/com/android/launcher3/util/AbsGridOccupancy.java b/go/src/com/android/launcher3/util/AbsGridOccupancy.java
deleted file mode 100644
index 4a46bd193f..0000000000
--- a/go/src/com/android/launcher3/util/AbsGridOccupancy.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.launcher3.util;
-
-/**
- * Defines method to find the next vacant cell on a grid.
- * This uses the default top-down, left-right approach and can be over-written through
- * code swaps in different launchers.
- */
-public abstract class AbsGridOccupancy {
-
- /**
- * Find the first vacant cell, if there is one.
- *
- * @param vacantOut Holds the x and y coordinate of the vacant cell
- * @param spanX Horizontal cell span.
- * @param spanY Vertical cell span.
- *
- * @return true if a vacant cell was found
- */
- protected boolean findVacantCell(int[] vacantOut, boolean[][] cells, int countX, int countY,
- int spanX, int spanY) {
- for (int y = 0; (y + spanY) <= countY; y++) {
- for (int x = 0; (x + spanX) <= countX; x++) {
- boolean available = !cells[x][y];
- out:
- for (int i = x; i < x + spanX; i++) {
- for (int j = y; j < y + spanY; j++) {
- available = available && !cells[i][j];
- if (!available) break out;
- }
- }
- if (available) {
- vacantOut[0] = x;
- vacantOut[1] = y;
- return true;
- }
- }
- }
- return false;
- }
-}
diff --git a/gradle.properties b/gradle.properties
index d5c1d7734b..7f4c60911e 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,7 +1,6 @@
# Until all the dependencies move to android X
android.useAndroidX = true
android.enableJetifier = true
-org.gradle.parallel=true
ANDROID_X_VERSION=1+
diff --git a/lint-baseline-launcher3.xml b/lint-baseline-launcher3.xml
index 107a34694b..9a68405d73 100644
--- a/lint-baseline-launcher3.xml
+++ b/lint-baseline-launcher3.xml
@@ -3,17 +3,6 @@
<issue
id="NewApi"
- message="Call requires API level 28 (current min is 26): `android.os.UserManager#requestQuietModeEnabled`"
- errorLine1=" showConfirm |= !userManager.requestQuietModeEnabled(!toState, userProfile);"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="packages/apps/Launcher3/src/com/android/launcher3/allapps/WorkModeSwitch.java"
- line="110"
- column="41"/>
- </issue>
-
- <issue
- id="NewApi"
message="Call requires API level R (current min is 26): `android.view.View#getWindowInsetsController`"
errorLine1=" getWindowInsetsController().hide(WindowInsets.Type.ime());"
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
@@ -587,12 +576,12 @@
<issue
id="NewApi"
message="Call requires API level 31 (current min is 26): `android.appwidget.AppWidgetHostView#setColorResources`"
- errorLine1=" setColorResources(mWallpaperColorResources);"
- errorLine2=" ~~~~~~~~~~~~~~~~~">
+ errorLine1=" view.setColorResources(mWallpaperColorResources);"
+ errorLine2=" ~~~~~~~~~~~~~~~~~">
<location
file="packages/apps/Launcher3/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java"
- line="528"
- column="17"/>
+ line="381"
+ column="18"/>
</issue>
<issue
@@ -602,7 +591,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~">
<location
file="packages/apps/Launcher3/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java"
- line="288"
+ line="270"
column="61"/>
</issue>
diff --git a/protos/launcher_atom.proto b/protos/launcher_atom.proto
index 10eedc8578..6d49d75953 100644
--- a/protos/launcher_atom.proto
+++ b/protos/launcher_atom.proto
@@ -23,8 +23,6 @@ import "launcher_atom_extension.proto";
//
// ItemInfos
message ItemInfo {
- reserved 8;
-
oneof Item {
Application application = 1;
Task task = 2;
@@ -44,14 +42,7 @@ message ItemInfo {
optional ContainerInfo container_info = 7;
// Stores the origin of the Item
- repeated Attribute item_attributes = 12;
-}
-
-message LauncherAttributes{
-
- // Integer value of item attribute enum
- // (e.g. SUGGESTED_LABEL, ALL_APPS_SEARCH_RESULT_SETTING etc)
- repeated int32 item_attributes = 1;
+ optional Attribute attribute = 8;
}
// Represents various launcher surface where items are placed.
@@ -68,17 +59,12 @@ message ContainerInfo {
SettingsContainer settings_container = 9;
PredictedHotseatContainer predicted_hotseat_container = 10;
TaskSwitcherContainer task_switcher_container = 11;
- TaskBarContainer task_bar_container = 12;
- WallpapersContainer wallpapers_container = 13;
ExtendedContainers extended_containers = 20;
}
}
// Represents the apps list sorted alphabetically inside the all-apps view.
message AllAppsContainer {
- oneof ParentContainer {
- TaskBarContainer taskbar_container = 1;
- }
}
message WidgetsContainer {
@@ -86,9 +72,6 @@ message WidgetsContainer {
// Represents the predicted apps row(top row) in the all-apps view.
message PredictionContainer {
- oneof ParentContainer {
- TaskBarContainer taskbar_container = 1;
- }
}
// Represents the apps container within search results.
@@ -117,17 +100,6 @@ message SettingsContainer {
message TaskSwitcherContainer {
}
-// Container for taskbar.
-// Configured to show up on large screens(tablet-sized) such as foldables in expanded state, within
-// an app view(not in launcher screen).
-message TaskBarContainer {
- optional int32 index = 1;
-
- // Bit encoded value to capture pinned and predicted taskbar positions.
- optional int32 cardinality = 2;
-}
-
-// Next value 40
enum Attribute {
UNKNOWN = 0;
DEFAULT_LAYOUT = 1; // icon automatically placed in workspace, folder, hotseat
@@ -169,20 +141,6 @@ enum Attribute {
ALL_APPS_SEARCH_RESULT_NAVVYSITE = 25;
ALL_APPS_SEARCH_RESULT_TIPS = 26;
ALL_APPS_SEARCH_RESULT_PEOPLE_TILE = 27;
- ALL_APPS_SEARCH_RESULT_LEGACY_SHORTCUT = 30;
- ALL_APPS_SEARCH_RESULT_ASSISTANT_MEMORY = 31;
-
- // Web suggestions provided by AGA
- ALL_APPS_SEARCH_RESULT_WEB_SUGGEST = 39;
-
- // Suggestion Type provided by AGA
- WEB_SEARCH_RESULT_QUERY = 32;
- WEB_SEARCH_RESULT_TRENDING = 33;
- WEB_SEARCH_RESULT_ENTITY = 34;
- WEB_SEARCH_RESULT_ANSWER = 35;
- WEB_SEARCH_RESULT_PERSONAL = 36;
- WEB_SEARCH_RESULT_CALCULATOR = 37;
- WEB_SEARCH_RESULT_URL = 38;
WIDGETS_BOTTOM_TRAY = 28;
WIDGETS_TRAY_PREDICTION = 29;
@@ -272,16 +230,9 @@ message FolderContainer {
oneof ParentContainer {
WorkspaceContainer workspace = 4;
HotseatContainer hotseat = 5;
- TaskBarContainer taskbar = 6;
}
}
-// Represents wallpapers container for quick switching.
-message WallpapersContainer {
- // Number of wallpapers in the container.
- optional int32 cardinality = 1;
-}
-
// Represents state of EditText field before update.
enum FromState {
// Default value.
diff --git a/quickstep/Android.bp b/quickstep/Android.bp
index 70b1438c38..38c9919b07 100644
--- a/quickstep/Android.bp
+++ b/quickstep/Android.bp
@@ -14,7 +14,11 @@
package {
// See: http://go/android-license-faq
- default_applicable_licenses: ["Android-Apache-2.0"],
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "packages_apps_Launcher3_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["packages_apps_Launcher3_license"],
}
filegroup {
@@ -22,19 +26,3 @@ filegroup {
path: "robolectric_tests",
srcs: ["robolectric_tests/src/**/*.java"],
}
-
-filegroup {
- name: "launcher3-quickstep-tests-src",
- path: "tests",
- srcs: ["tests/src/**/*.java"],
-}
-
-filegroup {
- name: "launcher3-quickstep-oop-tests-src",
- path: "tests",
- srcs: [
- "tests/src/com/android/quickstep/NavigationModeSwitchRule.java",
- "tests/src/com/android/quickstep/AbstractQuickStepTest.java",
- "tests/src/com/android/quickstep/TaplTestsQuickstep.java",
- ]
-}
diff --git a/quickstep/AndroidManifest-launcher.xml b/quickstep/AndroidManifest-launcher.xml
index 7d7054f5a5..6808222258 100644
--- a/quickstep/AndroidManifest-launcher.xml
+++ b/quickstep/AndroidManifest-launcher.xml
@@ -20,7 +20,7 @@
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.launcher3">
- <uses-sdk android:targetSdkVersion="33" android:minSdkVersion="26"/>
+ <uses-sdk android:targetSdkVersion="29" android:minSdkVersion="25"/>
<!--
Manifest entries specific to Launcher3. This is merged with AndroidManifest-common.xml.
Refer comments around specific entries on how to extend individual components.
@@ -49,7 +49,7 @@
android:stateNotNeeded="true"
android:windowSoftInputMode="adjustPan"
android:screenOrientation="unspecified"
- android:configChanges="keyboard|keyboardHidden|mcc|mnc|navigation|orientation|screenSize|screenLayout|smallestScreenSize"
+ android:configChanges="keyboard|keyboardHidden|mcc|mnc|navigation|orientation|screenSize|screenLayout|smallestScreenSize|density"
android:resizeableActivity="true"
android:resumeWhilePausing="true"
android:taskAffinity=""
@@ -57,7 +57,6 @@
android:enabled="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
- <action android:name="android.intent.action.SHOW_WORK_APPS" />
<category android:name="android.intent.category.HOME" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.MONKEY"/>
diff --git a/quickstep/AndroidManifest.xml b/quickstep/AndroidManifest.xml
index 352cd3e7b6..f82080feea 100644
--- a/quickstep/AndroidManifest.xml
+++ b/quickstep/AndroidManifest.xml
@@ -22,13 +22,17 @@
xmlns:tools="http://schemas.android.com/tools"
package="com.android.launcher3">
+ <permission
+ android:name="${packageName}.permission.HOTSEAT_EDU"
+ android:permissionGroup="android.permission-group.SYSTEM_TOOLS"
+ android:protectionLevel="signatureOrSystem" />
+
<uses-permission android:name="android.permission.BROADCAST_CLOSE_SYSTEM_DIALOGS" />
<uses-permission android:name="android.permission.CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS"/>
<uses-permission android:name="android.permission.VIBRATE"/>
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES"/>
<uses-permission android:name="android.permission.START_TASKS_FROM_RECENTS"/>
<uses-permission android:name="android.permission.REMOVE_TASKS"/>
- <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS"/>
<uses-permission android:name="android.permission.MANAGE_ACTIVITY_TASKS"/>
<uses-permission android:name="android.permission.STATUS_BAR"/>
<uses-permission android:name="android.permission.STOP_APP_SWITCHES"/>
@@ -38,6 +42,7 @@
<uses-permission android:name="android.permission.MONITOR_INPUT"/>
<uses-permission android:name="android.permission.ALLOW_SLIPPERY_TOUCHES"/>
+ <uses-permission android:name="${packageName}.permission.HOTSEAT_EDU" />
<uses-permission android:name="android.permission.SYSTEM_APPLICATION_OVERLAY" />
<application android:backupAgent="com.android.launcher3.LauncherBackupAgent"
@@ -67,7 +72,7 @@
android:stateNotNeeded="true"
android:theme="@style/LauncherTheme"
android:screenOrientation="unspecified"
- android:configChanges="keyboard|keyboardHidden|mcc|mnc|navigation|orientation|screenSize|screenLayout|smallestScreenSize"
+ android:configChanges="keyboard|keyboardHidden|mcc|mnc|navigation|orientation|screenSize|screenLayout|smallestScreenSize|density"
android:resizeableActivity="true"
android:resumeWhilePausing="true"
android:taskAffinity=""/>
@@ -102,6 +107,7 @@
<activity android:name="com.android.quickstep.interaction.GestureSandboxActivity"
android:autoRemoveFromRecents="true"
android:excludeFromRecents="true"
+ android:screenOrientation="portrait"
android:exported="true">
<intent-filter>
<action android:name="com.android.quickstep.action.GESTURE_SANDBOX"/>
@@ -117,6 +123,7 @@
<activity android:name="com.android.quickstep.interaction.AllSetActivity"
android:autoRemoveFromRecents="true"
android:excludeFromRecents="true"
+ android:screenOrientation="portrait"
android:permission="android.permission.REBOOT"
android:theme="@style/AllSetTheme"
android:label="@string/allset_title"
@@ -127,6 +134,20 @@
</intent-filter>
</activity>
+ <activity
+ android:name=".hybridhotseat.HotseatEduActivity"
+ android:theme="@android:style/Theme.NoDisplay"
+ android:noHistory="true"
+ android:launchMode="singleTask"
+ android:clearTaskOnLaunch="true"
+ android:permission="${packageName}.permission.HOTSEAT_EDU"
+ android:exported="true">
+ <intent-filter>
+ <action android:name="com.android.launcher3.action.SHOW_HYBRID_HOTSEAT_EDU"/>
+ <category android:name="android.intent.category.DEFAULT" />
+ </intent-filter>
+ </activity>
+
</application>
</manifest>
diff --git a/quickstep/ext_tests/src/com/android/quickstep/DebugQuickstepTestInformationHandler.java b/quickstep/ext_tests/src/com/android/quickstep/DebugQuickstepTestInformationHandler.java
deleted file mode 100644
index e5f0295ff6..0000000000
--- a/quickstep/ext_tests/src/com/android/quickstep/DebugQuickstepTestInformationHandler.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.quickstep;
-
-import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.os.Bundle;
-
-import androidx.annotation.Nullable;
-
-import com.android.launcher3.BaseQuickstepLauncher;
-import com.android.launcher3.Launcher;
-import com.android.launcher3.R;
-import com.android.launcher3.taskbar.LauncherTaskbarUIController;
-import com.android.launcher3.testing.DebugTestInformationHandler;
-import com.android.launcher3.testing.TestProtocol;
-
-import java.util.concurrent.ExecutionException;
-
-/**
- * Class to handle requests from tests, including debug ones, to Quickstep Launcher builds.
- */
-public abstract class DebugQuickstepTestInformationHandler extends QuickstepTestInformationHandler {
-
- private final DebugTestInformationHandler mDebugTestInformationHandler;
-
- public DebugQuickstepTestInformationHandler(Context context) {
- super(context);
- mDebugTestInformationHandler = new DebugTestInformationHandler(context);
- }
-
- @Override
- public Bundle call(String method, String arg, @Nullable Bundle extras) {
- Bundle response = new Bundle();
- switch (method) {
- case TestProtocol.REQUEST_ENABLE_MANUAL_TASKBAR_STASHING:
- runOnUIThread(l -> {
- enableManualTaskbarStashing(l, true);
- });
- return response;
-
- case TestProtocol.REQUEST_DISABLE_MANUAL_TASKBAR_STASHING:
- runOnUIThread(l -> {
- enableManualTaskbarStashing(l, false);
- });
- return response;
-
- case TestProtocol.REQUEST_UNSTASH_TASKBAR_IF_STASHED:
- runOnUIThread(l -> {
- enableManualTaskbarStashing(l, true);
-
- BaseQuickstepLauncher quickstepLauncher = (BaseQuickstepLauncher) l;
- LauncherTaskbarUIController taskbarUIController =
- quickstepLauncher.getTaskbarUIController();
-
- // Allow null-pointer to catch illegal states.
- taskbarUIController.unstashTaskbarIfStashed();
-
- enableManualTaskbarStashing(l, false);
- });
- return response;
-
- case TestProtocol.REQUEST_STASHED_TASKBAR_HEIGHT: {
- final Resources resources = mContext.getResources();
- response.putInt(TestProtocol.TEST_INFO_RESPONSE_FIELD,
- resources.getDimensionPixelSize(R.dimen.taskbar_stashed_size));
- return response;
- }
-
- default:
- response = super.call(method, arg, extras);
- if (response != null) return response;
- return mDebugTestInformationHandler.call(method, arg, extras);
- }
- }
-
- private void enableManualTaskbarStashing(Launcher launcher, boolean enable) {
- BaseQuickstepLauncher quickstepLauncher = (BaseQuickstepLauncher) launcher;
- LauncherTaskbarUIController taskbarUIController =
- quickstepLauncher.getTaskbarUIController();
-
- // Allow null-pointer to catch illegal states.
- taskbarUIController.enableManualStashingForTests(enable);
- }
-
- /**
- * Runs the given command on the UI thread.
- */
- private static void runOnUIThread(UIThreadCommand command) {
- try {
- MAIN_EXECUTOR.submit(() -> {
- command.execute(Launcher.ACTIVITY_TRACKER.getCreatedActivity());
- return null;
- }).get();
- } catch (ExecutionException | InterruptedException e) {
- throw new RuntimeException(e);
- }
- }
-
- private interface UIThreadCommand {
-
- void execute(Launcher launcher);
- }
-}
-
diff --git a/quickstep/protos_overrides/launcher_atom_extension.proto b/quickstep/protos_overrides/launcher_atom_extension.proto
index f5a277bb95..d2dc0cb745 100644
--- a/quickstep/protos_overrides/launcher_atom_extension.proto
+++ b/quickstep/protos_overrides/launcher_atom_extension.proto
@@ -22,45 +22,21 @@ option java_outer_classname = "LauncherAtomExtensions";
// Wrapper message for containers used at the quickstep level.
// Message name should match with launcher_atom_extension.proto message at
// the AOSP level.
-// Next ID = 3
message ExtendedContainers {
- reserved 2; // Deleted fields
oneof Container{
DeviceSearchResultContainer device_search_result_container = 1;
+ CorrectedDeviceSearchResultContainer corrected_device_search_result_container = 2;
}
}
// Represents on-device search result container.
-// Next ID = 4
message DeviceSearchResultContainer{
optional int32 query_length = 1;
- optional SearchAttributes search_attributes = 2;
- // [0, m], m varies based on the display density and resolution
- // To indicate the location of the tapped on-device search result.
- // For application, it will be the column number in the apps row.
- optional int32 grid_x = 3;
-
- // Next ID = 4
- message SearchAttributes{
-
- // True if results are based on spell corrected query
- optional bool corrected_query = 1;
-
- // True if the item's title/content is a direct match to the search query, false otherwise.
- optional bool direct_match = 2;
-
- // Entry point for this on-device search session
- optional EntryState entry_state = 3;
-
- enum EntryState{
- ENTRY_STATE_UNKNOWN = 0;
-
- // User entered using swipe-up gesture from homescreen and searchbox in AllApps drawer.
- ALL_APPS = 1;
+}
- // User entered by tapping on QSB bar on homescreen.
- QSB = 2;
- }
- }
+// Represents on-device search result container with results from spell-corrected query.
+message CorrectedDeviceSearchResultContainer{
+ optional int32 query_length = 1;
}
+
diff --git a/quickstep/res/drawable-v28/gesture_tutorial_action_button_background.xml b/quickstep/res/drawable-v28/gesture_tutorial_action_button_background.xml
index 710482f162..57423c2ffc 100644
--- a/quickstep/res/drawable-v28/gesture_tutorial_action_button_background.xml
+++ b/quickstep/res/drawable-v28/gesture_tutorial_action_button_background.xml
@@ -16,5 +16,5 @@
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="?android:attr/dialogCornerRadius"/>
- <solid android:color="?android:attr/colorAccent"/>
+ <solid android:color="@color/gesture_tutorial_primary_color"/>
</shape> \ No newline at end of file
diff --git a/quickstep/res/drawable/bg_overview_clear_all_button.xml b/quickstep/res/drawable/bg_overview_clear_all_button.xml
deleted file mode 100644
index fb014f75b1..0000000000
--- a/quickstep/res/drawable/bg_overview_clear_all_button.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2021 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.
--->
-<ripple android:color="?android:attr/colorControlHighlight"
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
- <item>
- <shape android:shape="rectangle"
- android:tint="?colorButtonNormal">
- <corners android:radius="24dp" />
- <solid android:color="?androidprv:attr/colorSurface"/>
- </shape>
- </item>
-</ripple> \ No newline at end of file
diff --git a/quickstep/res/drawable/bg_sandbox_feedback.xml b/quickstep/res/drawable/bg_sandbox_feedback.xml
index 83d7e4396c..83a3deada8 100644
--- a/quickstep/res/drawable/bg_sandbox_feedback.xml
+++ b/quickstep/res/drawable/bg_sandbox_feedback.xml
@@ -14,8 +14,7 @@
limitations under the License.
-->
<shape xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
android:shape="rectangle">
<corners android:radius="28dp"/>
- <solid android:color="?androidprv:attr/colorSurface"/>
+ <solid android:color="?android:attr/colorBackgroundFloating"/>
</shape>
diff --git a/quickstep/res/drawable/button_taskbar_edu_bordered.xml b/quickstep/res/drawable/button_taskbar_edu_bordered.xml
deleted file mode 100644
index 47f8e8f8cd..0000000000
--- a/quickstep/res/drawable/button_taskbar_edu_bordered.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2021 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.
--->
-
-<inset
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
- <ripple
- android:color="?android:attr/colorControlHighlight">
- <item>
- <shape android:shape="rectangle">
- <corners android:radius="16dp" />
- <solid android:color="?androidprv:attr/colorSurface"/>
- <stroke
- android:width="1dp"
- android:color="?androidprv:attr/colorAccentPrimaryVariant"/>
- </shape>
- </item>
- </ripple>
-</inset> \ No newline at end of file
diff --git a/quickstep/res/drawable/button_taskbar_edu_colored.xml b/quickstep/res/drawable/button_taskbar_edu_colored.xml
deleted file mode 100644
index 70bfc9f255..0000000000
--- a/quickstep/res/drawable/button_taskbar_edu_colored.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2021 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.
--->
-
-<inset
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
- <ripple
- android:color="?android:attr/colorControlHighlight">
- <item>
- <shape android:shape="rectangle">
- <corners android:radius="16dp"/>
- <solid android:color="?androidprv:attr/colorAccentPrimary"/>
- </shape>
- </item>
- </ripple>
-</inset> \ No newline at end of file
diff --git a/res/xml/grayscale_icon_map.xml b/quickstep/res/drawable/default_sandbox_app_previous_task_thumbnail.xml
index f6383ceb1e..9c9549779e 100644
--- a/res/xml/grayscale_icon_map.xml
+++ b/quickstep/res/drawable/default_sandbox_app_previous_task_thumbnail.xml
@@ -1,17 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
- Copyright (C) 2022 The Android Open Source Project
-
+ Copyright (C) 2020 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.
-->
-<icons></icons>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shape="rectangle">
+ <solid android:color="@color/gesture_tutorial_fake_previous_task_view_color" />
+</shape>
diff --git a/quickstep/res/drawable/default_sandbox_mock_launcher.xml b/quickstep/res/drawable/default_sandbox_mock_launcher.xml
new file mode 100644
index 0000000000..38fbcf09b6
--- /dev/null
+++ b/quickstep/res/drawable/default_sandbox_mock_launcher.xml
@@ -0,0 +1,21 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="360dp"
+ android:height="146dp"
+ android:viewportWidth="360"
+ android:viewportHeight="146">
+ <path
+ android:pathData="M25,96L335,96A25,25 0,0 1,360 121L360,121A25,25 0,0 1,335 146L25,146A25,25 0,0 1,0 121L0,121A25,25 0,0 1,25 96z"
+ android:fillColor="#3C4043"/>
+ <path
+ android:pathData="M30,30m-30,0a30,30 0,1 1,60 0a30,30 0,1 1,-60 0"
+ android:fillColor="#8AB4F8"/>
+ <path
+ android:pathData="M130,30m-30,0a30,30 0,1 1,60 0a30,30 0,1 1,-60 0"
+ android:fillColor="#F28B82"/>
+ <path
+ android:pathData="M230,30m-30,0a30,30 0,1 1,60 0a30,30 0,1 1,-60 0"
+ android:fillColor="#FDD663"/>
+ <path
+ android:pathData="M330,30m-30,0a30,30 0,1 1,60 0a30,30 0,1 1,-60 0"
+ android:fillColor="#81C995"/>
+</vector>
diff --git a/quickstep/res/drawable/gesture_tutorial_action_button_background.xml b/quickstep/res/drawable/gesture_tutorial_action_button_background.xml
index 98dc1a5f78..ac6a52a623 100644
--- a/quickstep/res/drawable/gesture_tutorial_action_button_background.xml
+++ b/quickstep/res/drawable/gesture_tutorial_action_button_background.xml
@@ -25,7 +25,7 @@
<shape
android:shape="rectangle">
<corners android:radius="50dp"/>
- <solid android:color="?android:attr/colorAccent"/>
+ <solid android:color="@color/gesture_tutorial_primary_color"/>
</shape>
</item>
</layer-list> \ No newline at end of file
diff --git a/quickstep/res/drawable/gesture_tutorial_cancel_button_background.xml b/quickstep/res/drawable/gesture_tutorial_cancel_button_background.xml
index 77626154f8..0a34af6475 100644
--- a/quickstep/res/drawable/gesture_tutorial_cancel_button_background.xml
+++ b/quickstep/res/drawable/gesture_tutorial_cancel_button_background.xml
@@ -17,5 +17,5 @@
android:shape="rectangle">
<corners android:radius="50dp"/>
<solid android:color="@android:color/transparent"/>
- <stroke android:width="1dp" android:color="?android:attr/colorAccent"/>
+ <stroke android:width="1dp" android:color="@color/gesture_tutorial_primary_color"/>
</shape> \ No newline at end of file
diff --git a/quickstep/res/drawable/gesture_tutorial_finger_dot.xml b/quickstep/res/drawable/gesture_tutorial_finger_dot.xml
deleted file mode 100644
index cbb26122db..0000000000
--- a/quickstep/res/drawable/gesture_tutorial_finger_dot.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="oval">
- <solid android:color="?android:attr/colorAccent" />
- <size android:width="92dp" android:height="92dp"/>
-</shape> \ No newline at end of file
diff --git a/quickstep/res/drawable/gesture_tutorial_loop_back.xml b/quickstep/res/drawable/gesture_tutorial_loop_back.xml
index ae47709b22..d2909fffc9 100644
--- a/quickstep/res/drawable/gesture_tutorial_loop_back.xml
+++ b/quickstep/res/drawable/gesture_tutorial_loop_back.xml
@@ -85,7 +85,7 @@
<path
android:name="_R_G_L_0_G_D_0_P_0"
android:fillAlpha="0.25"
- android:fillColor="?android:attr/colorAccent"
+ android:fillColor="@color/gesture_tutorial_primary_color"
android:fillType="nonZero"
android:pathData=" M12.5 -446 C12.5,-446 12.5,446 12.5,446 C12.5,446 -12.5,446 -12.5,446 C-12.5,446 -12.5,-446 -12.5,-446 C-12.5,-446 12.5,-446 12.5,-446c " />
</group>
diff --git a/quickstep/res/drawable/gesture_tutorial_loop_home.xml b/quickstep/res/drawable/gesture_tutorial_loop_home.xml
index bed35dd0fa..931f8c0197 100644
--- a/quickstep/res/drawable/gesture_tutorial_loop_home.xml
+++ b/quickstep/res/drawable/gesture_tutorial_loop_home.xml
@@ -81,7 +81,7 @@
<path
android:name="_R_G_L_1_G_D_0_P_0"
android:fillAlpha="0.25"
- android:fillColor="?android:attr/colorAccent"
+ android:fillColor="@color/gesture_tutorial_primary_color"
android:fillType="nonZero"
android:pathData=" M206 -12.5 C206,-12.5 206,12.5 206,12.5 C206,12.5 -206,12.5 -206,12.5 C-206,12.5 -206,-12.5 -206,-12.5 C-206,-12.5 206,-12.5 206,-12.5c " />
</group>
diff --git a/quickstep/res/drawable/gesture_tutorial_loop_overview.xml b/quickstep/res/drawable/gesture_tutorial_loop_overview.xml
index 53e8b5fec5..a4c532bdfa 100644
--- a/quickstep/res/drawable/gesture_tutorial_loop_overview.xml
+++ b/quickstep/res/drawable/gesture_tutorial_loop_overview.xml
@@ -81,7 +81,7 @@
<path
android:name="_R_G_L_1_G_D_0_P_0"
android:fillAlpha="0.25"
- android:fillColor="?android:attr/colorAccent"
+ android:fillColor="@color/gesture_tutorial_primary_color"
android:fillType="nonZero"
android:pathData=" M206 -12.5 C206,-12.5 206,12.5 206,12.5 C206,12.5 -206,12.5 -206,12.5 C-206,12.5 -206,-12.5 -206,-12.5 C-206,-12.5 206,-12.5 206,-12.5c " />
</group>
diff --git a/quickstep/res/drawable/gesture_tutorial_motion_back.xml b/quickstep/res/drawable/gesture_tutorial_motion_back.xml
new file mode 100644
index 0000000000..a6860fac64
--- /dev/null
+++ b/quickstep/res/drawable/gesture_tutorial_motion_back.xml
@@ -0,0 +1,1233 @@
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:aapt="http://schemas.android.com/aapt">
+ <target android:name="_R_G_L_3_G_L_0_G_L_0_G_D_0_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="133"
+ android:propertyName="fillAlpha"
+ android:startOffset="1217"
+ android:valueFrom="1"
+ android:valueTo="0"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_L_0_G_L_0_G_D_1_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="133"
+ android:propertyName="fillAlpha"
+ android:startOffset="1217"
+ android:valueFrom="1"
+ android:valueTo="0"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_L_0_G_L_0_G_D_2_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="133"
+ android:propertyName="fillAlpha"
+ android:startOffset="1217"
+ android:valueFrom="1"
+ android:valueTo="0"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_L_0_G_L_0_G_D_3_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="133"
+ android:propertyName="fillAlpha"
+ android:startOffset="1217"
+ android:valueFrom="1"
+ android:valueTo="0"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_L_0_G_L_0_G_D_4_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="133"
+ android:propertyName="fillAlpha"
+ android:startOffset="1217"
+ android:valueFrom="1"
+ android:valueTo="0"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_L_0_G_L_0_G_D_5_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="133"
+ android:propertyName="fillAlpha"
+ android:startOffset="1217"
+ android:valueFrom="1"
+ android:valueTo="0"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_L_0_G_L_0_G_D_6_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="133"
+ android:propertyName="fillAlpha"
+ android:startOffset="1217"
+ android:valueFrom="1"
+ android:valueTo="0"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_L_0_G_L_0_G_D_7_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="133"
+ android:propertyName="fillAlpha"
+ android:startOffset="1217"
+ android:valueFrom="1"
+ android:valueTo="0"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_L_0_G_L_0_G_D_8_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="133"
+ android:propertyName="fillAlpha"
+ android:startOffset="1217"
+ android:valueFrom="1"
+ android:valueTo="0"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_L_0_G_L_0_G_D_9_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="133"
+ android:propertyName="fillAlpha"
+ android:startOffset="1217"
+ android:valueFrom="1"
+ android:valueTo="0"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_L_0_G_L_0_G_D_10_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="133"
+ android:propertyName="fillAlpha"
+ android:startOffset="1217"
+ android:valueFrom="1"
+ android:valueTo="0"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_L_0_G_L_0_G_D_11_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="133"
+ android:propertyName="fillAlpha"
+ android:startOffset="1217"
+ android:valueFrom="1"
+ android:valueTo="0"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_L_0_G_L_0_G_D_12_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="133"
+ android:propertyName="fillAlpha"
+ android:startOffset="1217"
+ android:valueFrom="1"
+ android:valueTo="0"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_L_0_G_L_0_G_D_13_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="133"
+ android:propertyName="fillAlpha"
+ android:startOffset="1217"
+ android:valueFrom="1"
+ android:valueTo="0"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_L_0_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="0"
+ android:propertyName="scaleY"
+ android:startOffset="1367"
+ android:valueFrom="1"
+ android:valueTo="0"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="283"
+ android:propertyName="scaleX"
+ android:startOffset="1217"
+ android:valueFrom="1"
+ android:valueTo="0.88012"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,0.536 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="283"
+ android:propertyName="scaleY"
+ android:startOffset="1217"
+ android:valueFrom="1"
+ android:valueTo="0.88012"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,0.536 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="0"
+ android:propertyName="scaleY"
+ android:startOffset="2417"
+ android:valueFrom="1"
+ android:valueTo="0"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_2_G_L_0_G_L_0_G_D_0_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="333"
+ android:propertyName="fillAlpha"
+ android:startOffset="1417"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_2_G_L_0_G_L_0_G_D_1_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="333"
+ android:propertyName="fillAlpha"
+ android:startOffset="1417"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_2_G_L_0_G_L_0_G_D_2_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="333"
+ android:propertyName="fillAlpha"
+ android:startOffset="1417"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_2_G_L_0_G_L_0_G_D_3_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="333"
+ android:propertyName="fillAlpha"
+ android:startOffset="1417"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_2_G_L_0_G_L_0_G_D_4_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="333"
+ android:propertyName="fillAlpha"
+ android:startOffset="1417"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_2_G_L_0_G_L_0_G_D_5_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="333"
+ android:propertyName="fillAlpha"
+ android:startOffset="1417"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_2_G_L_0_G_L_0_G_D_6_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="333"
+ android:propertyName="fillAlpha"
+ android:startOffset="1417"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_2_G_L_0_G_L_0_G_D_7_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="333"
+ android:propertyName="fillAlpha"
+ android:startOffset="1417"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_2_G_L_0_G_L_0_G_D_8_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="333"
+ android:propertyName="fillAlpha"
+ android:startOffset="1417"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_2_G_L_0_G_L_0_G_D_9_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="333"
+ android:propertyName="fillAlpha"
+ android:startOffset="1417"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_2_G_L_0_G_L_0_G_D_10_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="333"
+ android:propertyName="fillAlpha"
+ android:startOffset="1417"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_2_G_L_0_G_L_0_G_D_11_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="333"
+ android:propertyName="fillAlpha"
+ android:startOffset="1417"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_2_G_L_0_G_L_0_G_D_12_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="333"
+ android:propertyName="fillAlpha"
+ android:startOffset="1417"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_2_G_L_0_G_L_0_G_D_13_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="333"
+ android:propertyName="fillAlpha"
+ android:startOffset="1417"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_2_G_L_0_G_L_0_G_D_14_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="333"
+ android:propertyName="fillAlpha"
+ android:startOffset="1417"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_2_G_L_0_G_L_0_G_D_15_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="333"
+ android:propertyName="fillAlpha"
+ android:startOffset="1417"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_2_G_L_0_G_L_0_G_D_16_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="333"
+ android:propertyName="fillAlpha"
+ android:startOffset="1417"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_2_G_L_0_G_L_0_G_D_17_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="333"
+ android:propertyName="fillAlpha"
+ android:startOffset="1417"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_2_G_L_0_G_L_0_G_D_18_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="333"
+ android:propertyName="fillAlpha"
+ android:startOffset="1417"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_2_G_L_0_G_L_0_G_D_19_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="333"
+ android:propertyName="fillAlpha"
+ android:startOffset="1417"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_2_G_L_0_G_L_0_G_D_20_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="333"
+ android:propertyName="fillAlpha"
+ android:startOffset="1417"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_2_G_L_0_G_L_0_G_D_21_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="333"
+ android:propertyName="fillAlpha"
+ android:startOffset="1417"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_2_G_L_0_G_L_0_G_D_22_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="333"
+ android:propertyName="fillAlpha"
+ android:startOffset="1417"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_2_G_L_0_G_L_0_G_D_23_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="333"
+ android:propertyName="fillAlpha"
+ android:startOffset="1417"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_2_G_L_0_G_L_0_G_D_24_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="333"
+ android:propertyName="fillAlpha"
+ android:startOffset="1417"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_2_G_L_0_G_L_0_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="0"
+ android:propertyName="scaleY"
+ android:startOffset="1417"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_2_G_L_0_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="0"
+ android:propertyName="scaleY"
+ android:startOffset="1417"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_2_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="0"
+ android:propertyName="scaleY"
+ android:startOffset="1417"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G_D_0_P_0_G_0_T_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="667"
+ android:pathData="M 123.282,129.757C 134.28199999999998,129.757 178.282,129.757 189.282,129.757"
+ android:propertyName="translateXY"
+ android:propertyXName="translateX"
+ android:propertyYName="translateY"
+ android:startOffset="217">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.5,0 0,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="333"
+ android:pathData="M 189.282,129.757C 189.282,129.757 189.282,129.757 189.282,129.757"
+ android:propertyName="translateXY"
+ android:propertyXName="translateX"
+ android:propertyYName="translateY"
+ android:startOffset="883">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0.333 0.667,0.667 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="250"
+ android:pathData="M 189.282,129.757C 178.282,129.757 134.28199999999998,129.757 123.282,129.757"
+ android:propertyName="translateXY"
+ android:propertyXName="translateX"
+ android:propertyYName="translateY"
+ android:startOffset="1217">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="0"
+ android:propertyName="scaleY"
+ android:startOffset="217"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="0"
+ android:propertyName="scaleY"
+ android:startOffset="2383"
+ android:valueFrom="1"
+ android:valueTo="0"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_D_0_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="217"
+ android:propertyName="fillAlpha"
+ android:startOffset="0"
+ android:valueFrom="0"
+ android:valueTo="0.75"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="967"
+ android:propertyName="fillAlpha"
+ android:startOffset="217"
+ android:valueFrom="0.75"
+ android:valueTo="0.75"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="167"
+ android:propertyName="fillAlpha"
+ android:startOffset="1183"
+ android:valueFrom="0.75"
+ android:valueTo="0"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0 0.833,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_D_0_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="217"
+ android:propertyName="pathData"
+ android:startOffset="0"
+ android:valueFrom="M-206.5 13.5 C-186.34,13.5 -170,29.84 -170,50 C-170,70.16 -186.34,86.5 -206.5,86.5 C-226.66,86.5 -243,70.16 -243,50 C-243,29.84 -226.66,13.5 -206.5,13.5c "
+ android:valueTo="M-206 0 C-178.39,0 -156,22.39 -156,50 C-156,77.61 -178.39,100 -206,100 C-233.61,100 -256,77.61 -256,50 C-256,22.39 -233.61,0 -206,0c "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="583"
+ android:propertyName="pathData"
+ android:startOffset="217"
+ android:valueFrom="M-206 0 C-178.39,0 -156,22.39 -156,50 C-156,77.61 -178.39,100 -206,100 C-233.61,100 -256,77.61 -256,50 C-256,22.39 -233.61,0 -206,0c "
+ android:valueTo="M0 0 C27.61,0 50,22.39 50,50 C50,77.61 27.61,100 0,100 C-27.61,100 -50,77.61 -50,50 C-50,22.39 -27.61,0 0,0c "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.5,0 0.5,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="383"
+ android:propertyName="pathData"
+ android:startOffset="800"
+ android:valueFrom="M0 0 C27.61,0 50,22.39 50,50 C50,77.61 27.61,100 0,100 C-27.61,100 -50,77.61 -50,50 C-50,22.39 -27.61,0 0,0c "
+ android:valueTo="M0 0 C27.61,0 50,22.39 50,50 C50,77.61 27.61,100 0,100 C-27.61,100 -50,77.61 -50,50 C-50,22.39 -27.61,0 0,0c "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="167"
+ android:propertyName="pathData"
+ android:startOffset="1183"
+ android:valueFrom="M0 0 C27.61,0 50,22.39 50,50 C50,77.61 27.61,100 0,100 C-27.61,100 -50,77.61 -50,50 C-50,22.39 -27.61,0 0,0c "
+ android:valueTo="M0 13.5 C20.16,13.5 36.5,29.84 36.5,50 C36.5,70.16 20.16,86.5 0,86.5 C-20.16,86.5 -36.5,70.16 -36.5,50 C-36.5,29.84 -20.16,13.5 0,13.5c "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="time_group">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="1767"
+ android:propertyName="translateX"
+ android:startOffset="0"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <aapt:attr name="android:drawable">
+ <vector
+ android:width="412dp"
+ android:height="892dp"
+ android:viewportHeight="892"
+ android:viewportWidth="412">
+ <group android:name="_R_G">
+ <group
+ android:name="_R_G_L_4_G"
+ android:translateX="206"
+ android:translateY="446">
+ <path
+ android:name="_R_G_L_4_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#dadce0"
+ android:fillType="nonZero"
+ android:pathData=" M206 -446 C206,-446 206,446 206,446 C206,446 -206,446 -206,446 C-206,446 -206,-446 -206,-446 C-206,-446 206,-446 206,-446c " />
+ </group>
+ <group
+ android:name="_R_G_L_3_G"
+ android:pivotX="206"
+ android:pivotY="446"
+ android:scaleX="1"
+ android:scaleY="1">
+ <group android:name="_R_G_L_3_G_L_0_G">
+ <group android:name="_R_G_L_3_G_L_0_G_L_0_G">
+ <path
+ android:name="_R_G_L_3_G_L_0_G_L_0_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#f1f3f4"
+ android:fillType="nonZero"
+ android:pathData=" M412 101 C412,101 412,892 412,892 C412,892 0,892 0,892 C0,892 0,101 0,101 C0,101 412,101 412,101c " />
+ <path
+ android:name="_R_G_L_3_G_L_0_G_L_0_G_D_1_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#e8eaed"
+ android:fillType="nonZero"
+ android:pathData=" M412 0 C412,0 412,101 412,101 C412,101 0,101 0,101 C0,101 0,0 0,0 C0,0 412,0 412,0c " />
+ <path
+ android:name="_R_G_L_3_G_L_0_G_L_0_G_D_2_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#dadce0"
+ android:fillType="nonZero"
+ android:pathData=" M383 804 C383,816.15 373.15,826 361,826 C361,826 51,826 51,826 C38.85,826 29,816.15 29,804 C29,791.85 38.85,782 51,782 C51,782 361,782 361,782 C373.15,782 383,791.85 383,804c " />
+ <path
+ android:name="_R_G_L_3_G_L_0_G_L_0_G_D_3_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#dadce0"
+ android:fillType="nonZero"
+ android:pathData=" M201 47 C201,47 201,75 201,75 C201,77.21 199.21,79 197,79 C197,79 38,79 38,79 C35.79,79 34,77.21 34,75 C34,75 34,47 34,47 C34,44.79 35.79,43 38,43 C38,43 197,43 197,43 C199.21,43 201,44.79 201,47c " />
+ <path
+ android:name="_R_G_L_3_G_L_0_G_L_0_G_D_4_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#dadce0"
+ android:fillType="nonZero"
+ android:pathData=" M388 47 C388,47 388,75 388,75 C388,77.21 386.21,79 384,79 C384,79 356,79 356,79 C353.79,79 352,77.21 352,75 C352,75 352,47 352,47 C352,44.79 353.79,43 356,43 C356,43 384,43 384,43 C386.21,43 388,44.79 388,47c " />
+ <path
+ android:name="_R_G_L_3_G_L_0_G_L_0_G_D_5_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#dadce0"
+ android:fillType="nonZero"
+ android:pathData=" M336 47 C336,47 336,75 336,75 C336,77.21 334.21,79 332,79 C332,79 304,79 304,79 C301.79,79 300,77.21 300,75 C300,75 300,47 300,47 C300,44.79 301.79,43 304,43 C304,43 332,43 332,43 C334.21,43 336,44.79 336,47c " />
+ <path
+ android:name="_R_G_L_3_G_L_0_G_L_0_G_D_6_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#dadce0"
+ android:fillType="nonZero"
+ android:pathData=" M70 618 C70,630.15 60.15,640 48,640 C35.85,640 26,630.15 26,618 C26,605.85 35.85,596 48,596 C60.15,596 70,605.85 70,618c " />
+ <path
+ android:name="_R_G_L_3_G_L_0_G_L_0_G_D_7_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#dadce0"
+ android:fillType="nonZero"
+ android:pathData=" M70 396 C70,408.15 60.15,418 48,418 C35.85,418 26,408.15 26,396 C26,383.85 35.85,374 48,374 C60.15,374 70,383.85 70,396c " />
+ <path
+ android:name="_R_G_L_3_G_L_0_G_L_0_G_D_8_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M394 248 C394,248 394,324 394,324 C394,333.94 385.94,342 376,342 C376,342 142,342 142,342 C132.06,342 124,333.94 124,324 C124,324 124,248 124,248 C124,238.06 132.06,230 142,230 C142,230 376,230 376,230 C385.94,230 394,238.06 394,248c " />
+ <path
+ android:name="_R_G_L_3_G_L_0_G_L_0_G_D_9_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M393.94 468.38 C393.94,468.38 393.94,481.5 393.94,481.5 C393.94,483.71 392.15,485.5 389.94,485.5 C389.94,485.5 303.5,485.5 303.5,485.5 C301.29,485.5 299.5,483.71 299.5,481.5 C299.5,481.5 299.5,468.38 299.5,468.38 C299.5,466.17 301.29,464.38 303.5,464.38 C303.5,464.38 389.94,464.38 389.94,464.38 C392.15,464.38 393.94,466.17 393.94,468.38c M394 468 C394,477.67 386.17,485.5 376.5,485.5 C376.5,485.5 290,485.5 290,485.5 C280.33,485.5 272.5,477.67 272.5,468 C272.5,458.34 280.33,450.5 290,450.5 C290,450.5 376.5,450.5 376.5,450.5 C386.17,450.5 394,458.34 394,468c " />
+ <path
+ android:name="_R_G_L_3_G_L_0_G_L_0_G_D_10_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M394 494 C394,494 394,547 394,547 C394,549.21 392.21,551 390,551 C390,551 164,551 164,551 C161.79,551 160,549.21 160,547 C160,547 160,494 160,494 C160,491.79 161.79,490 164,490 C164,490 390,490 390,490 C392.21,490 394,491.79 394,494c M394 508 C394,508 394,545 394,545 C394,554.94 385.94,563 376,563 C376,563 142,563 142,563 C132.06,563 124,554.94 124,545 C124,545 124,508 124,508 C124,498.06 132.06,490 142,490 C142,490 376,490 376,490 C385.94,490 394,498.06 394,508c " />
+ <path
+ android:name="_R_G_L_3_G_L_0_G_L_0_G_D_11_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M394 690 C394,690 394,727 394,727 C394,736.94 385.94,745 376,745 C376,745 142,745 142,745 C132.06,745 124,736.94 124,727 C124,727 124,690 124,690 C124,680.06 132.06,672 142,672 C142,672 376,672 376,672 C385.94,672 394,680.06 394,690c " />
+ <path
+ android:name="_R_G_L_3_G_L_0_G_L_0_G_D_12_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#e8eaed"
+ android:fillType="nonZero"
+ android:pathData=" M267.5 617 C267.5,626.67 259.67,634.5 250,634.5 C250,634.5 104.5,634.5 104.5,634.5 C94.84,634.5 87,626.67 87,617 C87,607.34 94.84,599.5 104.5,599.5 C104.5,599.5 250,599.5 250,599.5 C259.67,599.5 267.5,607.34 267.5,617c " />
+ <path
+ android:name="_R_G_L_3_G_L_0_G_L_0_G_D_13_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#e8eaed"
+ android:fillType="nonZero"
+ android:pathData=" M299 395.5 C299,405.17 291.16,413 281.5,413 C281.5,413 104.5,413 104.5,413 C94.84,413 87,405.17 87,395.5 C87,385.84 94.84,378 104.5,378 C104.5,378 281.5,378 281.5,378 C291.16,378 299,385.84 299,395.5c " />
+ </group>
+ </group>
+ </group>
+ <group
+ android:name="_R_G_L_2_G"
+ android:scaleY="0">
+ <group
+ android:name="_R_G_L_2_G_L_0_G"
+ android:scaleY="0">
+ <group
+ android:name="_R_G_L_2_G_L_0_G_L_0_G"
+ android:scaleY="0">
+ <path
+ android:name="_R_G_L_2_G_L_0_G_L_0_G_D_0_P_0"
+ android:fillAlpha="0"
+ android:fillColor="#dadce0"
+ android:fillType="nonZero"
+ android:pathData=" M412 0 C412,0 412,892 412,892 C412,892 0,892 0,892 C0,892 0,0 0,0 C0,0 412,0 412,0c " />
+ <path
+ android:name="_R_G_L_2_G_L_0_G_L_0_G_D_1_P_0"
+ android:fillAlpha="0"
+ android:fillColor="#e8eaed"
+ android:fillType="nonZero"
+ android:pathData=" M412 0 C412,0 412,101 412,101 C412,101 0,101 0,101 C0,101 0,0 0,0 C0,0 412,0 412,0c " />
+ <path
+ android:name="_R_G_L_2_G_L_0_G_L_0_G_D_2_P_0"
+ android:fillAlpha="0"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M195 143 C195,143 195,153 195,153 C195,155.21 193.21,157 191,157 C191,157 106,157 106,157 C103.79,157 102,155.21 102,153 C102,153 102,143 102,143 C102,140.79 103.79,139 106,139 C106,139 191,139 191,139 C193.21,139 195,140.79 195,143c " />
+ <path
+ android:name="_R_G_L_2_G_L_0_G_L_0_G_D_3_P_0"
+ android:fillAlpha="0"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M270 165 C270,165 270,173 270,173 C270,175.21 268.21,177 266,177 C266,177 106,177 106,177 C103.79,177 102,175.21 102,173 C102,173 102,165 102,165 C102,162.79 103.79,161 106,161 C106,161 266,161 266,161 C268.21,161 270,162.79 270,165c " />
+ <path
+ android:name="_R_G_L_2_G_L_0_G_L_0_G_D_4_P_0"
+ android:fillAlpha="0"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M222 231 C222,231 222,241 222,241 C222,243.21 220.21,245 218,245 C218,245 106,245 106,245 C103.79,245 102,243.21 102,241 C102,241 102,231 102,231 C102,228.79 103.79,227 106,227 C106,227 218,227 218,227 C220.21,227 222,228.79 222,231c " />
+ <path
+ android:name="_R_G_L_2_G_L_0_G_L_0_G_D_5_P_0"
+ android:fillAlpha="0"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M241 253 C241,253 241,261 241,261 C241,263.21 239.21,265 237,265 C237,265 106,265 106,265 C103.79,265 102,263.21 102,261 C102,261 102,253 102,253 C102,250.79 103.79,249 106,249 C106,249 237,249 237,249 C239.21,249 241,250.79 241,253c " />
+ <path
+ android:name="_R_G_L_2_G_L_0_G_L_0_G_D_6_P_0"
+ android:fillAlpha="0"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M214 319 C214,319 214,329 214,329 C214,331.21 212.21,333 210,333 C210,333 106,333 106,333 C103.79,333 102,331.21 102,329 C102,329 102,319 102,319 C102,316.79 103.79,315 106,315 C106,315 210,315 210,315 C212.21,315 214,316.79 214,319c " />
+ <path
+ android:name="_R_G_L_2_G_L_0_G_L_0_G_D_7_P_0"
+ android:fillAlpha="0"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M333 341 C333,341 333,349 333,349 C333,351.21 331.21,353 329,353 C329,353 106,353 106,353 C103.79,353 102,351.21 102,349 C102,349 102,341 102,341 C102,338.79 103.79,337 106,337 C106,337 329,337 329,337 C331.21,337 333,338.79 333,341c " />
+ <path
+ android:name="_R_G_L_2_G_L_0_G_L_0_G_D_8_P_0"
+ android:fillAlpha="0"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M238 407 C238,407 238,417 238,417 C238,419.21 236.21,421 234,421 C234,421 106,421 106,421 C103.79,421 102,419.21 102,417 C102,417 102,407 102,407 C102,404.79 103.79,403 106,403 C106,403 234,403 234,403 C236.21,403 238,404.79 238,407c " />
+ <path
+ android:name="_R_G_L_2_G_L_0_G_L_0_G_D_9_P_0"
+ android:fillAlpha="0"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M295 429 C295,429 295,437 295,437 C295,439.21 293.21,441 291,441 C291,441 106,441 106,441 C103.79,441 102,439.21 102,437 C102,437 102,429 102,429 C102,426.79 103.79,425 106,425 C106,425 291,425 291,425 C293.21,425 295,426.79 295,429c " />
+ <path
+ android:name="_R_G_L_2_G_L_0_G_L_0_G_D_10_P_0"
+ android:fillAlpha="0"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M168 495 C168,495 168,505 168,505 C168,507.21 166.21,509 164,509 C164,509 106,509 106,509 C103.79,509 102,507.21 102,505 C102,505 102,495 102,495 C102,492.79 103.79,491 106,491 C106,491 164,491 164,491 C166.21,491 168,492.79 168,495c " />
+ <path
+ android:name="_R_G_L_2_G_L_0_G_L_0_G_D_11_P_0"
+ android:fillAlpha="0"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M269 517 C269,517 269,525 269,525 C269,527.21 267.21,529 265,529 C265,529 106,529 106,529 C103.79,529 102,527.21 102,525 C102,525 102,517 102,517 C102,514.79 103.79,513 106,513 C106,513 265,513 265,513 C267.21,513 269,514.79 269,517c " />
+ <path
+ android:name="_R_G_L_2_G_L_0_G_L_0_G_D_12_P_0"
+ android:fillAlpha="0"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M235 583 C235,583 235,593 235,593 C235,595.21 233.21,597 231,597 C231,597 106,597 106,597 C103.79,597 102,595.21 102,593 C102,593 102,583 102,583 C102,580.79 103.79,579 106,579 C106,579 231,579 231,579 C233.21,579 235,580.79 235,583c " />
+ <path
+ android:name="_R_G_L_2_G_L_0_G_L_0_G_D_13_P_0"
+ android:fillAlpha="0"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M295 605 C295,605 295,613 295,613 C295,615.21 293.21,617 291,617 C291,617 106,617 106,617 C103.79,617 102,615.21 102,613 C102,613 102,605 102,605 C102,602.79 103.79,601 106,601 C106,601 291,601 291,601 C293.21,601 295,602.79 295,605c " />
+ <path
+ android:name="_R_G_L_2_G_L_0_G_L_0_G_D_14_P_0"
+ android:fillAlpha="0"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M223 671 C223,671 223,681 223,681 C223,683.21 221.21,685 219,685 C219,685 106,685 106,685 C103.79,685 102,683.21 102,681 C102,681 102,671 102,671 C102,668.79 103.79,667 106,667 C106,667 219,667 219,667 C221.21,667 223,668.79 223,671c " />
+ <path
+ android:name="_R_G_L_2_G_L_0_G_L_0_G_D_15_P_0"
+ android:fillAlpha="0"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M246 693 C246,693 246,701 246,701 C246,703.21 244.21,705 242,705 C242,705 106,705 106,705 C103.79,705 102,703.21 102,701 C102,701 102,693 102,693 C102,690.79 103.79,689 106,689 C106,689 242,689 242,689 C244.21,689 246,690.79 246,693c " />
+ <path
+ android:name="_R_G_L_2_G_L_0_G_L_0_G_D_16_P_0"
+ android:fillAlpha="0"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M388 798 C388,798 388,798 388,798 C388,813.45 375.45,826 360,826 C360,826 267,826 267,826 C251.55,826 239,813.45 239,798 C239,798 239,798 239,798 C239,782.55 251.55,770 267,770 C267,770 360,770 360,770 C375.45,770 388,782.55 388,798c " />
+ <path
+ android:name="_R_G_L_2_G_L_0_G_L_0_G_D_17_P_0"
+ android:fillAlpha="0"
+ android:fillColor="#f8f9fa"
+ android:fillType="nonZero"
+ android:pathData=" M377 47 C377,47 377,75 377,75 C377,77.21 375.21,79 373,79 C373,79 38,79 38,79 C35.79,79 34,77.21 34,75 C34,75 34,47 34,47 C34,44.79 35.79,43 38,43 C38,43 373,43 373,43 C375.21,43 377,44.79 377,47c " />
+ <path
+ android:name="_R_G_L_2_G_L_0_G_L_0_G_D_18_P_0"
+ android:fillAlpha="0"
+ android:fillColor="#9aa0a6"
+ android:fillType="nonZero"
+ android:pathData=" M82 157 C82,172.46 69.46,185 54,185 C38.54,185 26,172.46 26,157 C26,141.54 38.54,129 54,129 C69.46,129 82,141.54 82,157c " />
+ <path
+ android:name="_R_G_L_2_G_L_0_G_L_0_G_D_19_P_0"
+ android:fillAlpha="0"
+ android:fillColor="#9aa0a6"
+ android:fillType="nonZero"
+ android:pathData=" M82 245 C82,260.46 69.46,273 54,273 C38.54,273 26,260.46 26,245 C26,229.54 38.54,217 54,217 C69.46,217 82,229.54 82,245c " />
+ <path
+ android:name="_R_G_L_2_G_L_0_G_L_0_G_D_20_P_0"
+ android:fillAlpha="0"
+ android:fillColor="#9aa0a6"
+ android:fillType="nonZero"
+ android:pathData=" M82 333 C82,348.46 69.46,361 54,361 C38.54,361 26,348.46 26,333 C26,317.54 38.54,305 54,305 C69.46,305 82,317.54 82,333c " />
+ <path
+ android:name="_R_G_L_2_G_L_0_G_L_0_G_D_21_P_0"
+ android:fillAlpha="0"
+ android:fillColor="#9aa0a6"
+ android:fillType="nonZero"
+ android:pathData=" M82 421 C82,436.46 69.46,449 54,449 C38.54,449 26,436.46 26,421 C26,405.54 38.54,393 54,393 C69.46,393 82,405.54 82,421c " />
+ <path
+ android:name="_R_G_L_2_G_L_0_G_L_0_G_D_22_P_0"
+ android:fillAlpha="0"
+ android:fillColor="#9aa0a6"
+ android:fillType="nonZero"
+ android:pathData=" M82 509 C82,524.46 69.46,537 54,537 C38.54,537 26,524.46 26,509 C26,493.54 38.54,481 54,481 C69.46,481 82,493.54 82,509c " />
+ <path
+ android:name="_R_G_L_2_G_L_0_G_L_0_G_D_23_P_0"
+ android:fillAlpha="0"
+ android:fillColor="#9aa0a6"
+ android:fillType="nonZero"
+ android:pathData=" M82 597 C82,612.46 69.46,625 54,625 C38.54,625 26,612.46 26,597 C26,581.54 38.54,569 54,569 C69.46,569 82,581.54 82,597c " />
+ <path
+ android:name="_R_G_L_2_G_L_0_G_L_0_G_D_24_P_0"
+ android:fillAlpha="0"
+ android:fillColor="#9aa0a6"
+ android:fillType="nonZero"
+ android:pathData=" M82 685 C82,700.46 69.46,713 54,713 C38.54,713 26,700.46 26,685 C26,669.54 38.54,657 54,657 C69.46,657 82,669.54 82,685c " />
+ </group>
+ </group>
+ </group>
+ <group
+ android:name="_R_G_L_1_G"
+ android:scaleY="0"
+ android:translateX="-17.875"
+ android:translateY="322.017">
+ <group
+ android:name="_R_G_L_1_G_D_0_P_0_G_0_T_0"
+ android:translateX="123.282"
+ android:translateY="129.757">
+ <path
+ android:name="_R_G_L_1_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#3b4043"
+ android:fillType="nonZero"
+ android:pathData=" M-109 27.43 C-109,27.43 -112.61,23.81 -112.61,23.81 C-112.61,23.81 -133.03,44.23 -133.03,44.23 C-133.03,44.23 -112.61,64.64 -112.61,64.64 C-112.61,64.64 -109,61.03 -109,61.03 C-109,61.03 -125.8,44.23 -125.8,44.23 C-125.8,44.23 -109,27.43 -109,27.43c " />
+ </group>
+ </group>
+ <group
+ android:name="_R_G_L_0_G"
+ android:translateX="206"
+ android:translateY="446">
+ <path
+ android:name="_R_G_L_0_G_D_0_P_0"
+ android:fillAlpha="0"
+ android:fillColor="@color/gesture_tutorial_primary_color"
+ android:fillType="nonZero"
+ android:pathData=" M-206.5 13.5 C-186.34,13.5 -170,29.84 -170,50 C-170,70.16 -186.34,86.5 -206.5,86.5 C-226.66,86.5 -243,70.16 -243,50 C-243,29.84 -226.66,13.5 -206.5,13.5c " />
+ </group>
+ </group>
+ <group android:name="time_group" />
+ </vector>
+ </aapt:attr>
+</animated-vector> \ No newline at end of file
diff --git a/quickstep/res/drawable/gesture_tutorial_motion_home_dark_mode.xml b/quickstep/res/drawable/gesture_tutorial_motion_home_dark_mode.xml
new file mode 100644
index 0000000000..aff35c1bce
--- /dev/null
+++ b/quickstep/res/drawable/gesture_tutorial_motion_home_dark_mode.xml
@@ -0,0 +1,1254 @@
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:aapt="http://schemas.android.com/aapt">
+ <target android:name="_R_G_L_2_G_L_4_G_D_0_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="50"
+ android:propertyName="fillAlpha"
+ android:startOffset="600"
+ android:valueFrom="0"
+ android:valueTo="0"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="167"
+ android:propertyName="fillAlpha"
+ android:startOffset="650"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_2_G_L_4_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="50"
+ android:pathData="M 206,776C 206,776 206,776 206,776"
+ android:propertyName="translateXY"
+ android:propertyXName="translateX"
+ android:propertyYName="translateY"
+ android:startOffset="600">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.27,0 0,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="700"
+ android:pathData="M 206,776C 206,776 206,797 206,797"
+ android:propertyName="translateXY"
+ android:propertyXName="translateX"
+ android:propertyYName="translateY"
+ android:startOffset="650">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.27,0 0,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_2_G_L_4_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="0"
+ android:propertyName="scaleY"
+ android:startOffset="650"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_2_G_L_3_G_D_0_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="167"
+ android:propertyName="fillAlpha"
+ android:startOffset="600"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_2_G_L_3_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="700"
+ android:pathData="M 56,673C 56,673 56,706 56,706"
+ android:propertyName="translateXY"
+ android:propertyXName="translateX"
+ android:propertyYName="translateY"
+ android:startOffset="600">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.27,0 0,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_2_G_L_3_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="0"
+ android:propertyName="scaleY"
+ android:startOffset="600"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_2_G_L_2_G_D_0_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="167"
+ android:propertyName="fillAlpha"
+ android:startOffset="600"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_2_G_L_2_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="700"
+ android:pathData="M 156,673C 156,673 156,706 156,706"
+ android:propertyName="translateXY"
+ android:propertyXName="translateX"
+ android:propertyYName="translateY"
+ android:startOffset="600">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.27,0 0,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_2_G_L_2_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="0"
+ android:propertyName="scaleY"
+ android:startOffset="600"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_2_G_L_1_G_D_0_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="167"
+ android:propertyName="fillAlpha"
+ android:startOffset="600"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_2_G_L_1_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="700"
+ android:pathData="M 256,673C 256,673 256,706 256,706"
+ android:propertyName="translateXY"
+ android:propertyXName="translateX"
+ android:propertyYName="translateY"
+ android:startOffset="600">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.27,0 0,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_2_G_L_1_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="0"
+ android:propertyName="scaleY"
+ android:startOffset="600"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_2_G_L_0_G_D_0_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="167"
+ android:propertyName="fillAlpha"
+ android:startOffset="600"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_2_G_L_0_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="700"
+ android:pathData="M 356,673C 356,673 356,706 356,706"
+ android:propertyName="translateXY"
+ android:propertyXName="translateX"
+ android:propertyYName="translateY"
+ android:startOffset="600">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.27,0 0,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_2_G_L_0_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="0"
+ android:propertyName="scaleY"
+ android:startOffset="600"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_2_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="0"
+ android:propertyName="scaleY"
+ android:startOffset="600"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G_L_4_G_L_11_G_D_0_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="100"
+ android:propertyName="fillColor"
+ android:startOffset="400"
+ android:valueFrom="#dadce0"
+ android:valueTo="#bac4d6"
+ android:valueType="colorType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,1.215 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G_L_4_G_L_10_G_D_0_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="100"
+ android:propertyName="fillColor"
+ android:startOffset="400"
+ android:valueFrom="#bdc1c6"
+ android:valueTo="#bac4d6"
+ android:valueType="colorType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,1.92 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G_L_4_G_L_9_G_D_0_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="100"
+ android:propertyName="fillColor"
+ android:startOffset="400"
+ android:valueFrom="#bdc1c6"
+ android:valueTo="#bac4d6"
+ android:valueType="colorType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,1.92 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G_L_4_G_L_8_G_D_0_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="100"
+ android:propertyName="fillColor"
+ android:startOffset="400"
+ android:valueFrom="#bdc1c6"
+ android:valueTo="#bac4d6"
+ android:valueType="colorType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,1.92 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G_L_4_G_L_7_G_D_0_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="100"
+ android:propertyName="fillColor"
+ android:startOffset="400"
+ android:valueFrom="#bdc1c6"
+ android:valueTo="#bac4d6"
+ android:valueType="colorType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,1.92 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G_L_4_G_L_6_G_D_0_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="100"
+ android:propertyName="fillColor"
+ android:startOffset="400"
+ android:valueFrom="#bdc1c6"
+ android:valueTo="#bac4d6"
+ android:valueType="colorType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,1.92 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G_L_4_G_L_5_G_D_0_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="100"
+ android:propertyName="fillColor"
+ android:startOffset="400"
+ android:valueFrom="#bdc1c6"
+ android:valueTo="#bac4d6"
+ android:valueType="colorType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,1.92 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G_L_4_G_L_4_G_D_0_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="100"
+ android:propertyName="fillColor"
+ android:startOffset="400"
+ android:valueFrom="#bdc1c6"
+ android:valueTo="#bac4d6"
+ android:valueType="colorType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,1.92 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G_L_4_G_L_3_G_D_0_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="100"
+ android:propertyName="fillColor"
+ android:startOffset="400"
+ android:valueFrom="#bdc1c6"
+ android:valueTo="#bac4d6"
+ android:valueType="colorType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,1.92 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G_L_4_G_L_2_G_D_0_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="100"
+ android:propertyName="fillColor"
+ android:startOffset="400"
+ android:valueFrom="#bdc1c6"
+ android:valueTo="#bac4d6"
+ android:valueType="colorType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,1.92 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G_L_4_G_L_1_G_D_0_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="100"
+ android:propertyName="fillColor"
+ android:startOffset="400"
+ android:valueFrom="#bdc1c6"
+ android:valueTo="#bac4d6"
+ android:valueType="colorType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,1.92 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G_L_4_G_L_0_G_D_0_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="100"
+ android:propertyName="fillColor"
+ android:startOffset="400"
+ android:valueFrom="#bdc1c6"
+ android:valueTo="#bac4d6"
+ android:valueType="colorType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,1.92 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G_L_4_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="0"
+ android:propertyName="scaleY"
+ android:startOffset="517"
+ android:valueFrom="1"
+ android:valueTo="0"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G_L_3_G_L_0_G_D_0_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="100"
+ android:propertyName="fillColor"
+ android:startOffset="400"
+ android:valueFrom="#bdc1c6"
+ android:valueTo="#bac4d6"
+ android:valueType="colorType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,1.92 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G_L_3_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="0"
+ android:propertyName="scaleY"
+ android:startOffset="517"
+ android:valueFrom="1"
+ android:valueTo="0"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G_L_2_G_L_2_G_D_0_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="100"
+ android:propertyName="fillColor"
+ android:startOffset="400"
+ android:valueFrom="#e8eaed"
+ android:valueTo="#bac4d6"
+ android:valueType="colorType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,1.232 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G_L_2_G_L_1_G_D_0_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="100"
+ android:propertyName="fillColor"
+ android:startOffset="400"
+ android:valueFrom="#80868b"
+ android:valueTo="#bac4d6"
+ android:valueType="colorType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,0.674 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G_L_2_G_L_0_G_D_0_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="100"
+ android:propertyName="fillColor"
+ android:startOffset="400"
+ android:valueFrom="#80868b"
+ android:valueTo="#bac4d6"
+ android:valueType="colorType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,0.674 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G_L_2_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="0"
+ android:propertyName="scaleY"
+ android:startOffset="517"
+ android:valueFrom="1"
+ android:valueTo="0"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G_L_1_G_L_2_G_D_0_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="150"
+ android:propertyName="fillColor"
+ android:startOffset="350"
+ android:valueFrom="#202124"
+ android:valueTo="#bac4d6"
+ android:valueType="colorType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,0.69 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G_L_1_G_L_1_G_D_0_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="150"
+ android:propertyName="fillColor"
+ android:startOffset="350"
+ android:valueFrom="#202124"
+ android:valueTo="#bac4d6"
+ android:valueType="colorType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,0.69 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G_L_1_G_L_0_G_D_0_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="150"
+ android:propertyName="fillColor"
+ android:startOffset="350"
+ android:valueFrom="#3c4043"
+ android:valueTo="#bac4d6"
+ android:valueType="colorType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,0.69 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G_L_1_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="0"
+ android:propertyName="scaleY"
+ android:startOffset="517"
+ android:valueFrom="1"
+ android:valueTo="0"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G_L_0_G_D_0_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="133"
+ android:propertyName="fillColor"
+ android:startOffset="500"
+ android:valueFrom="#bac4d6"
+ android:valueTo="#bac4d6"
+ android:valueType="colorType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="50"
+ android:propertyName="fillColor"
+ android:startOffset="633"
+ android:valueFrom="#bac4d6"
+ android:valueTo="#8ab4f8"
+ android:valueType="colorType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,-0.214 0.667,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G_L_0_G_D_0_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="283"
+ android:propertyName="fillAlpha"
+ android:startOffset="500"
+ android:valueFrom="1"
+ android:valueTo="1"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.999,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G_L_0_G_D_0_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="283"
+ android:propertyName="pathData"
+ android:startOffset="500"
+ android:valueFrom="M206.06 -430.06 C206.06,-430.06 206,431 206,431 C206,446 189.75,446 189.79,446 C189.79,446 -189.98,446 -189.98,446 C-189.94,446 -206,446 -206,431 C-206,431 -206,-430 -206,-430 C-206,-446 -189.97,-446 -190.01,-446 C-190.01,-446 188.98,-446.06 188.98,-446.06 C188.94,-446.06 206,-446 206.06,-430.06c "
+ android:valueTo="M60 -0.06 C60,-0.06 60,0.06 60,0.06 C60,28 36,60.25 -0.02,60.25 C-0.02,60.25 0.02,60.25 0.02,60.25 C-32.5,60.25 -60,31.5 -60,0.06 C-60,0.06 -60,-0.06 -60,-0.06 C-60,-31.25 -34,-59.25 0.02,-59.25 C0.02,-59.25 -0.02,-59.25 -0.02,-59.25 C33.5,-59.25 60,-38 60,-0.06c "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.999,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G_L_0_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="0"
+ android:propertyName="scaleY"
+ android:startOffset="500"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G_L_0_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="0"
+ android:propertyName="scaleY"
+ android:startOffset="850"
+ android:valueFrom="1"
+ android:valueTo="0"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G_T_1">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="283"
+ android:pathData="M 206,446C 201.417,411.133 195,385.297 195,385.297"
+ android:propertyName="translateXY"
+ android:propertyXName="translateX"
+ android:propertyYName="translateY"
+ android:startOffset="217">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.5,0 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="333"
+ android:pathData="M 195,385.297C 195,385.297 105.5,148.09000000000003 56,691.5"
+ android:propertyName="translateXY"
+ android:propertyXName="translateX"
+ android:propertyYName="translateY"
+ android:startOffset="500">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.443,0.093 0.5,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G_T_1">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="467"
+ android:propertyName="scaleX"
+ android:startOffset="217"
+ android:valueFrom="1"
+ android:valueTo="0.5"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.5,0 0.5,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="467"
+ android:propertyName="scaleY"
+ android:startOffset="217"
+ android:valueFrom="1"
+ android:valueTo="0.5"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.5,0 0.5,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G_T_1">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="0"
+ android:propertyName="scaleY"
+ android:startOffset="2167"
+ android:valueFrom="1"
+ android:valueTo="0"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_D_0_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="217"
+ android:propertyName="fillAlpha"
+ android:startOffset="0"
+ android:valueFrom="0"
+ android:valueTo="0.75"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="233"
+ android:propertyName="fillAlpha"
+ android:startOffset="217"
+ android:valueFrom="0.75"
+ android:valueTo="0.75"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="167"
+ android:propertyName="fillAlpha"
+ android:startOffset="450"
+ android:valueFrom="0.75"
+ android:valueTo="0"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_D_0_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="217"
+ android:propertyName="pathData"
+ android:startOffset="0"
+ android:valueFrom="M0 411 C19.33,411 35,426.67 35,446 C35,465.33 19.33,481 0,481 C-19.33,481 -35,465.33 -35,446 C-35,426.67 -19.33,411 0,411c "
+ android:valueTo="M0 396 C27.61,396 50,418.39 50,446 C50,473.61 27.61,496 0,496 C-27.61,496 -50,473.61 -50,446 C-50,418.39 -27.61,396 0,396c "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="433"
+ android:propertyName="pathData"
+ android:startOffset="217"
+ android:valueFrom="M0 396 C27.61,396 50,418.39 50,446 C50,473.61 27.61,496 0,496 C-27.61,496 -50,473.61 -50,446 C-50,418.39 -27.61,396 0,396c "
+ android:valueTo="M0 68 C27.61,68 50,90.39 50,118 C50,145.61 27.61,168 0,168 C-27.61,168 -50,145.61 -50,118 C-50,90.39 -27.61,68 0,68c "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.5,0 0.5,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="0"
+ android:propertyName="scaleY"
+ android:startOffset="0"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="0"
+ android:propertyName="scaleY"
+ android:startOffset="2167"
+ android:valueFrom="1"
+ android:valueTo="0"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="time_group">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="1367"
+ android:propertyName="translateX"
+ android:startOffset="0"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <aapt:attr name="android:drawable">
+ <vector
+ android:width="412dp"
+ android:height="892dp"
+ android:viewportHeight="892"
+ android:viewportWidth="412">
+ <group android:name="_R_G">
+ <group
+ android:name="_R_G_L_3_G"
+ android:translateX="206"
+ android:translateY="446">
+ <path
+ android:name="_R_G_L_3_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="@color/fake_wallpaper_color_dark_mode"
+ android:fillType="nonZero"
+ android:pathData=" M206 -446 C206,-446 206,446 206,446 C206,446 -206,446 -206,446 C-206,446 -206,-446 -206,-446 C-206,-446 206,-446 206,-446c " />
+ </group>
+ <group
+ android:name="_R_G_L_2_G"
+ android:scaleY="0">
+ <group
+ android:name="_R_G_L_2_G_L_4_G"
+ android:scaleY="0"
+ android:translateX="206"
+ android:translateY="776">
+ <path
+ android:name="_R_G_L_2_G_L_4_G_D_0_P_0"
+ android:fillAlpha="0"
+ android:fillColor="#3c4043"
+ android:fillType="nonZero"
+ android:pathData=" M180 0 C180,0 180,0 180,0 C180,13.8 168.8,25 155,25 C155,25 -155,25 -155,25 C-168.8,25 -180,13.8 -180,0 C-180,0 -180,0 -180,0 C-180,-13.8 -168.8,-25 -155,-25 C-155,-25 155,-25 155,-25 C168.8,-25 180,-13.8 180,0c " />
+ </group>
+ <group
+ android:name="_R_G_L_2_G_L_3_G"
+ android:scaleY="0"
+ android:translateX="56"
+ android:translateY="673">
+ <path
+ android:name="_R_G_L_2_G_L_3_G_D_0_P_0"
+ android:fillAlpha="0"
+ android:fillColor="#8ab4f8"
+ android:fillType="nonZero"
+ android:pathData=" M0 -30 C16.56,-30 30,-16.56 30,0 C30,16.56 16.56,30 0,30 C-16.56,30 -30,16.56 -30,0 C-30,-16.56 -16.56,-30 0,-30c " />
+ </group>
+ <group
+ android:name="_R_G_L_2_G_L_2_G"
+ android:scaleY="0"
+ android:translateX="156"
+ android:translateY="673">
+ <path
+ android:name="_R_G_L_2_G_L_2_G_D_0_P_0"
+ android:fillAlpha="0"
+ android:fillColor="#f28b82"
+ android:fillType="nonZero"
+ android:pathData=" M0 -30 C16.56,-30 30,-16.56 30,0 C30,16.56 16.56,30 0,30 C-16.56,30 -30,16.56 -30,0 C-30,-16.56 -16.56,-30 0,-30c " />
+ </group>
+ <group
+ android:name="_R_G_L_2_G_L_1_G"
+ android:scaleY="0"
+ android:translateX="256"
+ android:translateY="673">
+ <path
+ android:name="_R_G_L_2_G_L_1_G_D_0_P_0"
+ android:fillAlpha="0"
+ android:fillColor="#fdd663"
+ android:fillType="nonZero"
+ android:pathData=" M0 -30 C16.56,-30 30,-16.56 30,0 C30,16.56 16.56,30 0,30 C-16.56,30 -30,16.56 -30,0 C-30,-16.56 -16.56,-30 0,-30c " />
+ </group>
+ <group
+ android:name="_R_G_L_2_G_L_0_G"
+ android:scaleY="0"
+ android:translateX="356"
+ android:translateY="673">
+ <path
+ android:name="_R_G_L_2_G_L_0_G_D_0_P_0"
+ android:fillAlpha="0"
+ android:fillColor="#81c995"
+ android:fillType="nonZero"
+ android:pathData=" M0 -30 C16.56,-30 30,-16.56 30,0 C30,16.56 16.56,30 0,30 C-16.56,30 -30,16.56 -30,0 C-30,-16.56 -16.56,-30 0,-30c " />
+ </group>
+ </group>
+ <group
+ android:name="_R_G_L_1_G_T_1"
+ android:scaleX="1"
+ android:scaleY="1"
+ android:translateX="206"
+ android:translateY="446">
+ <group
+ android:name="_R_G_L_1_G"
+ android:translateX="-206"
+ android:translateY="-446">
+ <group android:name="_R_G_L_1_G_L_4_G">
+ <group
+ android:name="_R_G_L_1_G_L_4_G_L_11_G"
+ android:scaleX="0.87473"
+ android:scaleY="0.98643"
+ android:translateX="206"
+ android:translateY="472.769">
+ <path
+ android:name="_R_G_L_1_G_L_4_G_L_11_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#dadce0"
+ android:fillType="nonZero"
+ android:pathData=" M235.5 -407 C235.5,-407 235.5,407 235.5,407 C235.5,416.93 227.43,425 217.5,425 C217.5,425 -217.5,425 -217.5,425 C-227.43,425 -235.5,416.93 -235.5,407 C-235.5,407 -235.5,-407 -235.5,-407 C-235.5,-416.93 -227.43,-425 -217.5,-425 C-217.5,-425 217.5,-425 217.5,-425 C227.43,-425 235.5,-416.93 235.5,-407c " />
+ </group>
+ <group
+ android:name="_R_G_L_1_G_L_4_G_L_10_G"
+ android:translateX="182.5"
+ android:translateY="831">
+ <path
+ android:name="_R_G_L_1_G_L_4_G_L_10_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M158.5 -3 C158.5,-3 158.5,3 158.5,3 C158.5,7.42 154.92,11 150.5,11 C150.5,11 -150.5,11 -150.5,11 C-154.92,11 -158.5,7.42 -158.5,3 C-158.5,3 -158.5,-3 -158.5,-3 C-158.5,-7.42 -154.92,-11 -150.5,-11 C-150.5,-11 150.5,-11 150.5,-11 C154.92,-11 158.5,-7.42 158.5,-3c " />
+ </group>
+ <group
+ android:name="_R_G_L_1_G_L_4_G_L_9_G"
+ android:translateX="186"
+ android:translateY="801">
+ <path
+ android:name="_R_G_L_1_G_L_4_G_L_9_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M162 -3 C162,-3 162,3 162,3 C162,7.42 158.42,11 154,11 C154,11 -154,11 -154,11 C-158.42,11 -162,7.42 -162,3 C-162,3 -162,-3 -162,-3 C-162,-7.42 -158.42,-11 -154,-11 C-154,-11 154,-11 154,-11 C158.42,-11 162,-7.42 162,-3c " />
+ </group>
+ <group
+ android:name="_R_G_L_1_G_L_4_G_L_8_G"
+ android:translateX="119"
+ android:translateY="755">
+ <path
+ android:name="_R_G_L_1_G_L_4_G_L_8_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M95 -3 C95,-3 95,3 95,3 C95,7.42 91.42,11 87,11 C87,11 -87,11 -87,11 C-91.42,11 -95,7.42 -95,3 C-95,3 -95,-3 -95,-3 C-95,-7.42 -91.42,-11 -87,-11 C-87,-11 87,-11 87,-11 C91.42,-11 95,-7.42 95,-3c " />
+ </group>
+ <group
+ android:name="_R_G_L_1_G_L_4_G_L_7_G"
+ android:translateX="182.5"
+ android:translateY="725">
+ <path
+ android:name="_R_G_L_1_G_L_4_G_L_7_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M158.5 -3 C158.5,-3 158.5,3 158.5,3 C158.5,7.42 154.92,11 150.5,11 C150.5,11 -150.5,11 -150.5,11 C-154.92,11 -158.5,7.42 -158.5,3 C-158.5,3 -158.5,-3 -158.5,-3 C-158.5,-7.42 -154.92,-11 -150.5,-11 C-150.5,-11 150.5,-11 150.5,-11 C154.92,-11 158.5,-7.42 158.5,-3c " />
+ </group>
+ <group
+ android:name="_R_G_L_1_G_L_4_G_L_6_G"
+ android:translateX="197.5"
+ android:translateY="695">
+ <path
+ android:name="_R_G_L_1_G_L_4_G_L_6_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M173.5 -3 C173.5,-3 173.5,3 173.5,3 C173.5,7.42 169.92,11 165.5,11 C165.5,11 -165.5,11 -165.5,11 C-169.92,11 -173.5,7.42 -173.5,3 C-173.5,3 -173.5,-3 -173.5,-3 C-173.5,-7.42 -169.92,-11 -165.5,-11 C-165.5,-11 165.5,-11 165.5,-11 C169.92,-11 173.5,-7.42 173.5,-3c " />
+ </group>
+ <group
+ android:name="_R_G_L_1_G_L_4_G_L_5_G"
+ android:translateX="192"
+ android:translateY="665">
+ <path
+ android:name="_R_G_L_1_G_L_4_G_L_5_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M168 -3 C168,-3 168,3 168,3 C168,7.42 164.42,11 160,11 C160,11 -160,11 -160,11 C-164.42,11 -168,7.42 -168,3 C-168,3 -168,-3 -168,-3 C-168,-7.42 -164.42,-11 -160,-11 C-160,-11 160,-11 160,-11 C164.42,-11 168,-7.42 168,-3c " />
+ </group>
+ <group
+ android:name="_R_G_L_1_G_L_4_G_L_4_G"
+ android:translateX="105.5"
+ android:translateY="360">
+ <path
+ android:name="_R_G_L_1_G_L_4_G_L_4_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M23.5 -2 C23.5,-2 23.5,2 23.5,2 C23.5,4.21 21.71,6 19.5,6 C19.5,6 -19.5,6 -19.5,6 C-21.71,6 -23.5,4.21 -23.5,2 C-23.5,2 -23.5,-2 -23.5,-2 C-23.5,-4.21 -21.71,-6 -19.5,-6 C-19.5,-6 19.5,-6 19.5,-6 C21.71,-6 23.5,-4.21 23.5,-2c " />
+ </group>
+ <group
+ android:name="_R_G_L_1_G_L_4_G_L_3_G"
+ android:translateX="47.5"
+ android:translateY="360">
+ <path
+ android:name="_R_G_L_1_G_L_4_G_L_3_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M23.5 -2 C23.5,-2 23.5,2 23.5,2 C23.5,4.21 21.71,6 19.5,6 C19.5,6 -19.5,6 -19.5,6 C-21.71,6 -23.5,4.21 -23.5,2 C-23.5,2 -23.5,-2 -23.5,-2 C-23.5,-4.21 -21.71,-6 -19.5,-6 C-19.5,-6 19.5,-6 19.5,-6 C21.71,-6 23.5,-4.21 23.5,-2c " />
+ </group>
+ <group
+ android:name="_R_G_L_1_G_L_4_G_L_2_G"
+ android:translateX="142.5"
+ android:translateY="328">
+ <path
+ android:name="_R_G_L_1_G_L_4_G_L_2_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M118.5 -10 C118.5,-10 118.5,10 118.5,10 C118.5,14.42 114.92,18 110.5,18 C110.5,18 -110.5,18 -110.5,18 C-114.92,18 -118.5,14.42 -118.5,10 C-118.5,10 -118.5,-10 -118.5,-10 C-118.5,-14.42 -114.92,-18 -110.5,-18 C-110.5,-18 110.5,-18 110.5,-18 C114.92,-18 118.5,-14.42 118.5,-10c " />
+ </group>
+ <group
+ android:name="_R_G_L_1_G_L_4_G_L_1_G"
+ android:translateX="186"
+ android:translateY="284">
+ <path
+ android:name="_R_G_L_1_G_L_4_G_L_1_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M162 -10 C162,-10 162,10 162,10 C162,14.42 158.42,18 154,18 C154,18 -154,18 -154,18 C-158.42,18 -162,14.42 -162,10 C-162,10 -162,-10 -162,-10 C-162,-14.42 -158.42,-18 -154,-18 C-154,-18 154,-18 154,-18 C158.42,-18 162,-14.42 162,-10c " />
+ </group>
+ <group
+ android:name="_R_G_L_1_G_L_4_G_L_0_G"
+ android:translateX="155"
+ android:translateY="240">
+ <path
+ android:name="_R_G_L_1_G_L_4_G_L_0_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M131 -10 C131,-10 131,10 131,10 C131,14.42 127.42,18 123,18 C123,18 -123,18 -123,18 C-127.42,18 -131,14.42 -131,10 C-131,10 -131,-10 -131,-10 C-131,-14.42 -127.42,-18 -123,-18 C-123,-18 123,-18 123,-18 C127.42,-18 131,-14.42 131,-10c " />
+ </group>
+ </group>
+ <group
+ android:name="_R_G_L_1_G_L_3_G"
+ android:translateX="24"
+ android:translateY="390">
+ <group
+ android:name="_R_G_L_1_G_L_3_G_L_0_G"
+ android:translateX="182"
+ android:translateY="120">
+ <path
+ android:name="_R_G_L_1_G_L_3_G_L_0_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M182 -98 C182,-98 182,98 182,98 C182,110.14 172.14,120 160,120 C160,120 -160,120 -160,120 C-172.14,120 -182,110.14 -182,98 C-182,98 -182,-98 -182,-98 C-182,-110.14 -172.14,-120 -160,-120 C-160,-120 160,-120 160,-120 C172.14,-120 182,-110.14 182,-98c " />
+ </group>
+ </group>
+ <group android:name="_R_G_L_1_G_L_2_G">
+ <group
+ android:name="_R_G_L_1_G_L_2_G_L_2_G"
+ android:translateX="206"
+ android:translateY="145">
+ <path
+ android:name="_R_G_L_1_G_L_2_G_L_2_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#e8eaed"
+ android:fillType="nonZero"
+ android:pathData=" M206 -95.63 C206,-95.63 206,42.37 206,42.37 C206,43.47 205.1,44.37 204,44.37 C204,44.37 -204,44.37 -204,44.37 C-205.1,44.37 -206,43.47 -206,42.37 C-206,42.37 -206,-95.63 -206,-95.63 C-206,-96.73 -205.1,-97.63 -204,-97.63 C-204,-97.63 204,-97.63 204,-97.63 C205.1,-97.63 206,-96.73 206,-95.63c " />
+ </group>
+ <group
+ android:name="_R_G_L_1_G_L_2_G_L_1_G"
+ android:translateX="206"
+ android:translateY="145">
+ <path
+ android:name="_R_G_L_1_G_L_2_G_L_1_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#80868b"
+ android:fillType="nonZero"
+ android:pathData=" M109 -14 C109,-14 109,14 109,14 C109,15.1 108.1,16 107,16 C107,16 -107,16 -107,16 C-108.1,16 -109,15.1 -109,14 C-109,14 -109,-14 -109,-14 C-109,-15.1 -108.1,-16 -107,-16 C-107,-16 107,-16 107,-16 C108.1,-16 109,-15.1 109,-14c " />
+ </group>
+ <group
+ android:name="_R_G_L_1_G_L_2_G_L_0_G"
+ android:translateX="46"
+ android:translateY="145">
+ <path
+ android:name="_R_G_L_1_G_L_2_G_L_0_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#80868b"
+ android:fillType="nonZero"
+ android:pathData=" M22 -14 C22,-14 22,14 22,14 C22,18.42 18.42,22 14,22 C14,22 -14,22 -14,22 C-18.42,22 -22,18.42 -22,14 C-22,14 -22,-14 -22,-14 C-22,-18.42 -18.42,-22 -14,-22 C-14,-22 14,-22 14,-22 C18.42,-22 22,-18.42 22,-14c " />
+ </group>
+ </group>
+ <group android:name="_R_G_L_1_G_L_1_G">
+ <group
+ android:name="_R_G_L_1_G_L_1_G_L_2_G"
+ android:translateX="206"
+ android:translateY="51">
+ <path
+ android:name="_R_G_L_1_G_L_1_G_L_2_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#202124"
+ android:fillType="nonZero"
+ android:pathData=" M206 -0.27 C206,-0.27 206,49.73 206,49.73 C206,49.73 -206,49.73 -206,49.73 C-206,49.73 -206,-0.27 -206,-0.27 C-206,-0.27 206,-0.27 206,-0.27c " />
+ </group>
+ <group
+ android:name="_R_G_L_1_G_L_1_G_L_1_G"
+ android:translateX="206"
+ android:translateY="50.5">
+ <path
+ android:name="_R_G_L_1_G_L_1_G_L_1_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#202124"
+ android:fillType="nonZero"
+ android:pathData=" M206 -32.5 C206,-32.5 206,32.5 206,32.5 C206,42.43 197.93,50.5 188,50.5 C188,50.5 -188,50.5 -188,50.5 C-197.93,50.5 -206,42.43 -206,32.5 C-206,32.5 -206,-32.5 -206,-32.5 C-206,-42.43 -197.93,-50.5 -188,-50.5 C-188,-50.5 188,-50.5 188,-50.5 C197.93,-50.5 206,-42.43 206,-32.5c " />
+ </group>
+ <group
+ android:name="_R_G_L_1_G_L_1_G_L_0_G"
+ android:translateX="206"
+ android:translateY="66.5">
+ <path
+ android:name="_R_G_L_1_G_L_1_G_L_0_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#3c4043"
+ android:fillType="nonZero"
+ android:pathData=" M190 0 C190,0 190,0 190,0 C190,10.21 181.71,18.5 171.5,18.5 C171.5,18.5 -171.5,18.5 -171.5,18.5 C-181.71,18.5 -190,10.21 -190,0 C-190,0 -190,0 -190,0 C-190,-10.21 -181.71,-18.5 -171.5,-18.5 C-171.5,-18.5 171.5,-18.5 171.5,-18.5 C181.71,-18.5 190,-10.21 190,0c " />
+ </group>
+ </group>
+ <group
+ android:name="_R_G_L_1_G_L_0_G"
+ android:scaleY="0"
+ android:translateX="206"
+ android:translateY="446">
+ <path
+ android:name="_R_G_L_1_G_L_0_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bac4d6"
+ android:fillType="nonZero"
+ android:pathData=" M206.06 -430.06 C206.06,-430.06 206,431 206,431 C206,446 189.75,446 189.79,446 C189.79,446 -189.98,446 -189.98,446 C-189.94,446 -206,446 -206,431 C-206,431 -206,-430 -206,-430 C-206,-446 -189.97,-446 -190.01,-446 C-190.01,-446 188.98,-446.06 188.98,-446.06 C188.94,-446.06 206,-446 206.06,-430.06c " />
+ </group>
+ </group>
+ </group>
+ <group
+ android:name="_R_G_L_0_G"
+ android:translateX="206"
+ android:translateY="446">
+ <path
+ android:name="_R_G_L_0_G_D_0_P_0"
+ android:fillAlpha="0"
+ android:fillColor="@color/gesture_tutorial_primary_color"
+ android:fillType="nonZero"
+ android:pathData=" M0 411 C19.33,411 35,426.67 35,446 C35,465.33 19.33,481 0,481 C-19.33,481 -35,465.33 -35,446 C-35,426.67 -19.33,411 0,411c " />
+ </group>
+ </group>
+ <group android:name="time_group" />
+ </vector>
+ </aapt:attr>
+</animated-vector> \ No newline at end of file
diff --git a/quickstep/res/drawable/gesture_tutorial_motion_home_light_mode.xml b/quickstep/res/drawable/gesture_tutorial_motion_home_light_mode.xml
new file mode 100644
index 0000000000..98d97ad62d
--- /dev/null
+++ b/quickstep/res/drawable/gesture_tutorial_motion_home_light_mode.xml
@@ -0,0 +1,1254 @@
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:aapt="http://schemas.android.com/aapt">
+ <target android:name="_R_G_L_2_G_L_4_G_D_0_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="50"
+ android:propertyName="fillAlpha"
+ android:startOffset="600"
+ android:valueFrom="0"
+ android:valueTo="0"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="167"
+ android:propertyName="fillAlpha"
+ android:startOffset="650"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_2_G_L_4_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="50"
+ android:pathData="M 206,776C 206,776 206,776 206,776"
+ android:propertyName="translateXY"
+ android:propertyXName="translateX"
+ android:propertyYName="translateY"
+ android:startOffset="600">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.27,0 0,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="700"
+ android:pathData="M 206,776C 206,776 206,797 206,797"
+ android:propertyName="translateXY"
+ android:propertyXName="translateX"
+ android:propertyYName="translateY"
+ android:startOffset="650">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.27,0 0,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_2_G_L_4_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="0"
+ android:propertyName="scaleY"
+ android:startOffset="650"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_2_G_L_3_G_D_0_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="167"
+ android:propertyName="fillAlpha"
+ android:startOffset="600"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_2_G_L_3_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="700"
+ android:pathData="M 56,673C 56,673 56,706 56,706"
+ android:propertyName="translateXY"
+ android:propertyXName="translateX"
+ android:propertyYName="translateY"
+ android:startOffset="600">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.27,0 0,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_2_G_L_3_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="0"
+ android:propertyName="scaleY"
+ android:startOffset="600"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_2_G_L_2_G_D_0_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="167"
+ android:propertyName="fillAlpha"
+ android:startOffset="600"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_2_G_L_2_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="700"
+ android:pathData="M 156,673C 156,673 156,706 156,706"
+ android:propertyName="translateXY"
+ android:propertyXName="translateX"
+ android:propertyYName="translateY"
+ android:startOffset="600">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.27,0 0,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_2_G_L_2_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="0"
+ android:propertyName="scaleY"
+ android:startOffset="600"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_2_G_L_1_G_D_0_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="167"
+ android:propertyName="fillAlpha"
+ android:startOffset="600"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_2_G_L_1_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="700"
+ android:pathData="M 256,673C 256,673 256,706 256,706"
+ android:propertyName="translateXY"
+ android:propertyXName="translateX"
+ android:propertyYName="translateY"
+ android:startOffset="600">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.27,0 0,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_2_G_L_1_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="0"
+ android:propertyName="scaleY"
+ android:startOffset="600"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_2_G_L_0_G_D_0_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="167"
+ android:propertyName="fillAlpha"
+ android:startOffset="600"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_2_G_L_0_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="700"
+ android:pathData="M 356,673C 356,673 356,706 356,706"
+ android:propertyName="translateXY"
+ android:propertyXName="translateX"
+ android:propertyYName="translateY"
+ android:startOffset="600">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.27,0 0,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_2_G_L_0_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="0"
+ android:propertyName="scaleY"
+ android:startOffset="600"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_2_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="0"
+ android:propertyName="scaleY"
+ android:startOffset="600"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G_L_4_G_L_11_G_D_0_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="100"
+ android:propertyName="fillColor"
+ android:startOffset="400"
+ android:valueFrom="#dadce0"
+ android:valueTo="#bac4d6"
+ android:valueType="colorType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,1.215 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G_L_4_G_L_10_G_D_0_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="100"
+ android:propertyName="fillColor"
+ android:startOffset="400"
+ android:valueFrom="#bdc1c6"
+ android:valueTo="#bac4d6"
+ android:valueType="colorType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,1.92 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G_L_4_G_L_9_G_D_0_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="100"
+ android:propertyName="fillColor"
+ android:startOffset="400"
+ android:valueFrom="#bdc1c6"
+ android:valueTo="#bac4d6"
+ android:valueType="colorType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,1.92 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G_L_4_G_L_8_G_D_0_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="100"
+ android:propertyName="fillColor"
+ android:startOffset="400"
+ android:valueFrom="#bdc1c6"
+ android:valueTo="#bac4d6"
+ android:valueType="colorType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,1.92 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G_L_4_G_L_7_G_D_0_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="100"
+ android:propertyName="fillColor"
+ android:startOffset="400"
+ android:valueFrom="#bdc1c6"
+ android:valueTo="#bac4d6"
+ android:valueType="colorType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,1.92 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G_L_4_G_L_6_G_D_0_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="100"
+ android:propertyName="fillColor"
+ android:startOffset="400"
+ android:valueFrom="#bdc1c6"
+ android:valueTo="#bac4d6"
+ android:valueType="colorType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,1.92 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G_L_4_G_L_5_G_D_0_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="100"
+ android:propertyName="fillColor"
+ android:startOffset="400"
+ android:valueFrom="#bdc1c6"
+ android:valueTo="#bac4d6"
+ android:valueType="colorType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,1.92 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G_L_4_G_L_4_G_D_0_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="100"
+ android:propertyName="fillColor"
+ android:startOffset="400"
+ android:valueFrom="#bdc1c6"
+ android:valueTo="#bac4d6"
+ android:valueType="colorType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,1.92 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G_L_4_G_L_3_G_D_0_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="100"
+ android:propertyName="fillColor"
+ android:startOffset="400"
+ android:valueFrom="#bdc1c6"
+ android:valueTo="#bac4d6"
+ android:valueType="colorType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,1.92 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G_L_4_G_L_2_G_D_0_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="100"
+ android:propertyName="fillColor"
+ android:startOffset="400"
+ android:valueFrom="#bdc1c6"
+ android:valueTo="#bac4d6"
+ android:valueType="colorType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,1.92 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G_L_4_G_L_1_G_D_0_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="100"
+ android:propertyName="fillColor"
+ android:startOffset="400"
+ android:valueFrom="#bdc1c6"
+ android:valueTo="#bac4d6"
+ android:valueType="colorType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,1.92 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G_L_4_G_L_0_G_D_0_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="100"
+ android:propertyName="fillColor"
+ android:startOffset="400"
+ android:valueFrom="#bdc1c6"
+ android:valueTo="#bac4d6"
+ android:valueType="colorType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,1.92 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G_L_4_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="0"
+ android:propertyName="scaleY"
+ android:startOffset="517"
+ android:valueFrom="1"
+ android:valueTo="0"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G_L_3_G_L_0_G_D_0_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="100"
+ android:propertyName="fillColor"
+ android:startOffset="400"
+ android:valueFrom="#bdc1c6"
+ android:valueTo="#bac4d6"
+ android:valueType="colorType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,1.92 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G_L_3_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="0"
+ android:propertyName="scaleY"
+ android:startOffset="517"
+ android:valueFrom="1"
+ android:valueTo="0"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G_L_2_G_L_2_G_D_0_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="100"
+ android:propertyName="fillColor"
+ android:startOffset="400"
+ android:valueFrom="#e8eaed"
+ android:valueTo="#bac4d6"
+ android:valueType="colorType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,1.232 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G_L_2_G_L_1_G_D_0_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="100"
+ android:propertyName="fillColor"
+ android:startOffset="400"
+ android:valueFrom="#80868b"
+ android:valueTo="#bac4d6"
+ android:valueType="colorType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,0.674 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G_L_2_G_L_0_G_D_0_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="100"
+ android:propertyName="fillColor"
+ android:startOffset="400"
+ android:valueFrom="#80868b"
+ android:valueTo="#bac4d6"
+ android:valueType="colorType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,0.674 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G_L_2_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="0"
+ android:propertyName="scaleY"
+ android:startOffset="517"
+ android:valueFrom="1"
+ android:valueTo="0"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G_L_1_G_L_2_G_D_0_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="150"
+ android:propertyName="fillColor"
+ android:startOffset="350"
+ android:valueFrom="#6e7175"
+ android:valueTo="#bac4d6"
+ android:valueType="colorType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,0.674 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G_L_1_G_L_1_G_D_0_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="150"
+ android:propertyName="fillColor"
+ android:startOffset="350"
+ android:valueFrom="#6e7175"
+ android:valueTo="#bac4d6"
+ android:valueType="colorType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,0.676 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G_L_1_G_L_0_G_D_0_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="150"
+ android:propertyName="fillColor"
+ android:startOffset="350"
+ android:valueFrom="#9a9a9a"
+ android:valueTo="#bac4d6"
+ android:valueType="colorType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,0.584 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G_L_1_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="0"
+ android:propertyName="scaleY"
+ android:startOffset="517"
+ android:valueFrom="1"
+ android:valueTo="0"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G_L_0_G_D_0_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="133"
+ android:propertyName="fillColor"
+ android:startOffset="500"
+ android:valueFrom="#bac4d6"
+ android:valueTo="#bac4d6"
+ android:valueType="colorType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="50"
+ android:propertyName="fillColor"
+ android:startOffset="633"
+ android:valueFrom="#bac4d6"
+ android:valueTo="#8ab4f8"
+ android:valueType="colorType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,-0.214 0.667,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G_L_0_G_D_0_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="283"
+ android:propertyName="fillAlpha"
+ android:startOffset="500"
+ android:valueFrom="1"
+ android:valueTo="1"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.999,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G_L_0_G_D_0_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="283"
+ android:propertyName="pathData"
+ android:startOffset="500"
+ android:valueFrom="M206.06 -430.06 C206.06,-430.06 206,431 206,431 C206,446 189.75,446 189.79,446 C189.79,446 -189.98,446 -189.98,446 C-189.94,446 -206,446 -206,431 C-206,431 -206,-430 -206,-430 C-206,-446 -189.97,-446 -190.01,-446 C-190.01,-446 188.98,-446.06 188.98,-446.06 C188.94,-446.06 206,-446 206.06,-430.06c "
+ android:valueTo="M60 -0.06 C60,-0.06 60,0.06 60,0.06 C60,28 36,60.25 -0.02,60.25 C-0.02,60.25 0.02,60.25 0.02,60.25 C-32.5,60.25 -60,31.5 -60,0.06 C-60,0.06 -60,-0.06 -60,-0.06 C-60,-31.25 -34,-59.25 0.02,-59.25 C0.02,-59.25 -0.02,-59.25 -0.02,-59.25 C33.5,-59.25 60,-38 60,-0.06c "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.999,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G_L_0_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="0"
+ android:propertyName="scaleY"
+ android:startOffset="500"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G_L_0_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="0"
+ android:propertyName="scaleY"
+ android:startOffset="850"
+ android:valueFrom="1"
+ android:valueTo="0"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G_T_1">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="283"
+ android:pathData="M 206,446C 201.417,411.133 195,385.297 195,385.297"
+ android:propertyName="translateXY"
+ android:propertyXName="translateX"
+ android:propertyYName="translateY"
+ android:startOffset="217">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.5,0 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="333"
+ android:pathData="M 195,385.297C 195,385.297 105.5,148.09000000000003 56,691.5"
+ android:propertyName="translateXY"
+ android:propertyXName="translateX"
+ android:propertyYName="translateY"
+ android:startOffset="500">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.443,0.093 0.5,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G_T_1">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="467"
+ android:propertyName="scaleX"
+ android:startOffset="217"
+ android:valueFrom="1"
+ android:valueTo="0.5"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.5,0 0.5,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="467"
+ android:propertyName="scaleY"
+ android:startOffset="217"
+ android:valueFrom="1"
+ android:valueTo="0.5"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.5,0 0.5,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G_T_1">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="0"
+ android:propertyName="scaleY"
+ android:startOffset="2167"
+ android:valueFrom="1"
+ android:valueTo="0"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_D_0_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="217"
+ android:propertyName="fillAlpha"
+ android:startOffset="0"
+ android:valueFrom="0"
+ android:valueTo="0.75"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="233"
+ android:propertyName="fillAlpha"
+ android:startOffset="217"
+ android:valueFrom="0.75"
+ android:valueTo="0.75"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="167"
+ android:propertyName="fillAlpha"
+ android:startOffset="450"
+ android:valueFrom="0.75"
+ android:valueTo="0"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_D_0_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="217"
+ android:propertyName="pathData"
+ android:startOffset="0"
+ android:valueFrom="M0 411 C19.33,411 35,426.67 35,446 C35,465.33 19.33,481 0,481 C-19.33,481 -35,465.33 -35,446 C-35,426.67 -19.33,411 0,411c "
+ android:valueTo="M0 396 C27.61,396 50,418.39 50,446 C50,473.61 27.61,496 0,496 C-27.61,496 -50,473.61 -50,446 C-50,418.39 -27.61,396 0,396c "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="433"
+ android:propertyName="pathData"
+ android:startOffset="217"
+ android:valueFrom="M0 396 C27.61,396 50,418.39 50,446 C50,473.61 27.61,496 0,496 C-27.61,496 -50,473.61 -50,446 C-50,418.39 -27.61,396 0,396c "
+ android:valueTo="M0 68 C27.61,68 50,90.39 50,118 C50,145.61 27.61,168 0,168 C-27.61,168 -50,145.61 -50,118 C-50,90.39 -27.61,68 0,68c "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.5,0 0.5,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="0"
+ android:propertyName="scaleY"
+ android:startOffset="0"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="0"
+ android:propertyName="scaleY"
+ android:startOffset="2167"
+ android:valueFrom="1"
+ android:valueTo="0"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="time_group">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="1367"
+ android:propertyName="translateX"
+ android:startOffset="0"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <aapt:attr name="android:drawable">
+ <vector
+ android:width="412dp"
+ android:height="892dp"
+ android:viewportHeight="892"
+ android:viewportWidth="412">
+ <group android:name="_R_G">
+ <group
+ android:name="_R_G_L_3_G"
+ android:translateX="206"
+ android:translateY="446">
+ <path
+ android:name="_R_G_L_3_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="@color/fake_wallpaper_color_light_mode"
+ android:fillType="nonZero"
+ android:pathData=" M206 -446 C206,-446 206,446 206,446 C206,446 -206,446 -206,446 C-206,446 -206,-446 -206,-446 C-206,-446 206,-446 206,-446c " />
+ </group>
+ <group
+ android:name="_R_G_L_2_G"
+ android:scaleY="0">
+ <group
+ android:name="_R_G_L_2_G_L_4_G"
+ android:scaleY="0"
+ android:translateX="206"
+ android:translateY="776">
+ <path
+ android:name="_R_G_L_2_G_L_4_G_D_0_P_0"
+ android:fillAlpha="0"
+ android:fillColor="#d9d9da"
+ android:fillType="nonZero"
+ android:pathData=" M180 0 C180,0 180,0 180,0 C180,13.8 168.8,25 155,25 C155,25 -155,25 -155,25 C-168.8,25 -180,13.8 -180,0 C-180,0 -180,0 -180,0 C-180,-13.8 -168.8,-25 -155,-25 C-155,-25 155,-25 155,-25 C168.8,-25 180,-13.8 180,0c " />
+ </group>
+ <group
+ android:name="_R_G_L_2_G_L_3_G"
+ android:scaleY="0"
+ android:translateX="56"
+ android:translateY="673">
+ <path
+ android:name="_R_G_L_2_G_L_3_G_D_0_P_0"
+ android:fillAlpha="0"
+ android:fillColor="#8ab4f8"
+ android:fillType="nonZero"
+ android:pathData=" M0 -30 C16.56,-30 30,-16.56 30,0 C30,16.56 16.56,30 0,30 C-16.56,30 -30,16.56 -30,0 C-30,-16.56 -16.56,-30 0,-30c " />
+ </group>
+ <group
+ android:name="_R_G_L_2_G_L_2_G"
+ android:scaleY="0"
+ android:translateX="156"
+ android:translateY="673">
+ <path
+ android:name="_R_G_L_2_G_L_2_G_D_0_P_0"
+ android:fillAlpha="0"
+ android:fillColor="#f28b82"
+ android:fillType="nonZero"
+ android:pathData=" M0 -30 C16.56,-30 30,-16.56 30,0 C30,16.56 16.56,30 0,30 C-16.56,30 -30,16.56 -30,0 C-30,-16.56 -16.56,-30 0,-30c " />
+ </group>
+ <group
+ android:name="_R_G_L_2_G_L_1_G"
+ android:scaleY="0"
+ android:translateX="256"
+ android:translateY="673">
+ <path
+ android:name="_R_G_L_2_G_L_1_G_D_0_P_0"
+ android:fillAlpha="0"
+ android:fillColor="#fdd663"
+ android:fillType="nonZero"
+ android:pathData=" M0 -30 C16.56,-30 30,-16.56 30,0 C30,16.56 16.56,30 0,30 C-16.56,30 -30,16.56 -30,0 C-30,-16.56 -16.56,-30 0,-30c " />
+ </group>
+ <group
+ android:name="_R_G_L_2_G_L_0_G"
+ android:scaleY="0"
+ android:translateX="356"
+ android:translateY="673">
+ <path
+ android:name="_R_G_L_2_G_L_0_G_D_0_P_0"
+ android:fillAlpha="0"
+ android:fillColor="#81c995"
+ android:fillType="nonZero"
+ android:pathData=" M0 -30 C16.56,-30 30,-16.56 30,0 C30,16.56 16.56,30 0,30 C-16.56,30 -30,16.56 -30,0 C-30,-16.56 -16.56,-30 0,-30c " />
+ </group>
+ </group>
+ <group
+ android:name="_R_G_L_1_G_T_1"
+ android:scaleX="1"
+ android:scaleY="1"
+ android:translateX="206"
+ android:translateY="446">
+ <group
+ android:name="_R_G_L_1_G"
+ android:translateX="-206"
+ android:translateY="-446">
+ <group android:name="_R_G_L_1_G_L_4_G">
+ <group
+ android:name="_R_G_L_1_G_L_4_G_L_11_G"
+ android:scaleX="0.87473"
+ android:scaleY="0.98643"
+ android:translateX="206"
+ android:translateY="472.769">
+ <path
+ android:name="_R_G_L_1_G_L_4_G_L_11_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#dadce0"
+ android:fillType="nonZero"
+ android:pathData=" M235.5 -407 C235.5,-407 235.5,407 235.5,407 C235.5,416.93 227.43,425 217.5,425 C217.5,425 -217.5,425 -217.5,425 C-227.43,425 -235.5,416.93 -235.5,407 C-235.5,407 -235.5,-407 -235.5,-407 C-235.5,-416.93 -227.43,-425 -217.5,-425 C-217.5,-425 217.5,-425 217.5,-425 C227.43,-425 235.5,-416.93 235.5,-407c " />
+ </group>
+ <group
+ android:name="_R_G_L_1_G_L_4_G_L_10_G"
+ android:translateX="182.5"
+ android:translateY="831">
+ <path
+ android:name="_R_G_L_1_G_L_4_G_L_10_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M158.5 -3 C158.5,-3 158.5,3 158.5,3 C158.5,7.42 154.92,11 150.5,11 C150.5,11 -150.5,11 -150.5,11 C-154.92,11 -158.5,7.42 -158.5,3 C-158.5,3 -158.5,-3 -158.5,-3 C-158.5,-7.42 -154.92,-11 -150.5,-11 C-150.5,-11 150.5,-11 150.5,-11 C154.92,-11 158.5,-7.42 158.5,-3c " />
+ </group>
+ <group
+ android:name="_R_G_L_1_G_L_4_G_L_9_G"
+ android:translateX="186"
+ android:translateY="801">
+ <path
+ android:name="_R_G_L_1_G_L_4_G_L_9_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M162 -3 C162,-3 162,3 162,3 C162,7.42 158.42,11 154,11 C154,11 -154,11 -154,11 C-158.42,11 -162,7.42 -162,3 C-162,3 -162,-3 -162,-3 C-162,-7.42 -158.42,-11 -154,-11 C-154,-11 154,-11 154,-11 C158.42,-11 162,-7.42 162,-3c " />
+ </group>
+ <group
+ android:name="_R_G_L_1_G_L_4_G_L_8_G"
+ android:translateX="119"
+ android:translateY="755">
+ <path
+ android:name="_R_G_L_1_G_L_4_G_L_8_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M95 -3 C95,-3 95,3 95,3 C95,7.42 91.42,11 87,11 C87,11 -87,11 -87,11 C-91.42,11 -95,7.42 -95,3 C-95,3 -95,-3 -95,-3 C-95,-7.42 -91.42,-11 -87,-11 C-87,-11 87,-11 87,-11 C91.42,-11 95,-7.42 95,-3c " />
+ </group>
+ <group
+ android:name="_R_G_L_1_G_L_4_G_L_7_G"
+ android:translateX="182.5"
+ android:translateY="725">
+ <path
+ android:name="_R_G_L_1_G_L_4_G_L_7_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M158.5 -3 C158.5,-3 158.5,3 158.5,3 C158.5,7.42 154.92,11 150.5,11 C150.5,11 -150.5,11 -150.5,11 C-154.92,11 -158.5,7.42 -158.5,3 C-158.5,3 -158.5,-3 -158.5,-3 C-158.5,-7.42 -154.92,-11 -150.5,-11 C-150.5,-11 150.5,-11 150.5,-11 C154.92,-11 158.5,-7.42 158.5,-3c " />
+ </group>
+ <group
+ android:name="_R_G_L_1_G_L_4_G_L_6_G"
+ android:translateX="197.5"
+ android:translateY="695">
+ <path
+ android:name="_R_G_L_1_G_L_4_G_L_6_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M173.5 -3 C173.5,-3 173.5,3 173.5,3 C173.5,7.42 169.92,11 165.5,11 C165.5,11 -165.5,11 -165.5,11 C-169.92,11 -173.5,7.42 -173.5,3 C-173.5,3 -173.5,-3 -173.5,-3 C-173.5,-7.42 -169.92,-11 -165.5,-11 C-165.5,-11 165.5,-11 165.5,-11 C169.92,-11 173.5,-7.42 173.5,-3c " />
+ </group>
+ <group
+ android:name="_R_G_L_1_G_L_4_G_L_5_G"
+ android:translateX="192"
+ android:translateY="665">
+ <path
+ android:name="_R_G_L_1_G_L_4_G_L_5_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M168 -3 C168,-3 168,3 168,3 C168,7.42 164.42,11 160,11 C160,11 -160,11 -160,11 C-164.42,11 -168,7.42 -168,3 C-168,3 -168,-3 -168,-3 C-168,-7.42 -164.42,-11 -160,-11 C-160,-11 160,-11 160,-11 C164.42,-11 168,-7.42 168,-3c " />
+ </group>
+ <group
+ android:name="_R_G_L_1_G_L_4_G_L_4_G"
+ android:translateX="105.5"
+ android:translateY="360">
+ <path
+ android:name="_R_G_L_1_G_L_4_G_L_4_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M23.5 -2 C23.5,-2 23.5,2 23.5,2 C23.5,4.21 21.71,6 19.5,6 C19.5,6 -19.5,6 -19.5,6 C-21.71,6 -23.5,4.21 -23.5,2 C-23.5,2 -23.5,-2 -23.5,-2 C-23.5,-4.21 -21.71,-6 -19.5,-6 C-19.5,-6 19.5,-6 19.5,-6 C21.71,-6 23.5,-4.21 23.5,-2c " />
+ </group>
+ <group
+ android:name="_R_G_L_1_G_L_4_G_L_3_G"
+ android:translateX="47.5"
+ android:translateY="360">
+ <path
+ android:name="_R_G_L_1_G_L_4_G_L_3_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M23.5 -2 C23.5,-2 23.5,2 23.5,2 C23.5,4.21 21.71,6 19.5,6 C19.5,6 -19.5,6 -19.5,6 C-21.71,6 -23.5,4.21 -23.5,2 C-23.5,2 -23.5,-2 -23.5,-2 C-23.5,-4.21 -21.71,-6 -19.5,-6 C-19.5,-6 19.5,-6 19.5,-6 C21.71,-6 23.5,-4.21 23.5,-2c " />
+ </group>
+ <group
+ android:name="_R_G_L_1_G_L_4_G_L_2_G"
+ android:translateX="142.5"
+ android:translateY="328">
+ <path
+ android:name="_R_G_L_1_G_L_4_G_L_2_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M118.5 -10 C118.5,-10 118.5,10 118.5,10 C118.5,14.42 114.92,18 110.5,18 C110.5,18 -110.5,18 -110.5,18 C-114.92,18 -118.5,14.42 -118.5,10 C-118.5,10 -118.5,-10 -118.5,-10 C-118.5,-14.42 -114.92,-18 -110.5,-18 C-110.5,-18 110.5,-18 110.5,-18 C114.92,-18 118.5,-14.42 118.5,-10c " />
+ </group>
+ <group
+ android:name="_R_G_L_1_G_L_4_G_L_1_G"
+ android:translateX="186"
+ android:translateY="284">
+ <path
+ android:name="_R_G_L_1_G_L_4_G_L_1_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M162 -10 C162,-10 162,10 162,10 C162,14.42 158.42,18 154,18 C154,18 -154,18 -154,18 C-158.42,18 -162,14.42 -162,10 C-162,10 -162,-10 -162,-10 C-162,-14.42 -158.42,-18 -154,-18 C-154,-18 154,-18 154,-18 C158.42,-18 162,-14.42 162,-10c " />
+ </group>
+ <group
+ android:name="_R_G_L_1_G_L_4_G_L_0_G"
+ android:translateX="155"
+ android:translateY="240">
+ <path
+ android:name="_R_G_L_1_G_L_4_G_L_0_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M131 -10 C131,-10 131,10 131,10 C131,14.42 127.42,18 123,18 C123,18 -123,18 -123,18 C-127.42,18 -131,14.42 -131,10 C-131,10 -131,-10 -131,-10 C-131,-14.42 -127.42,-18 -123,-18 C-123,-18 123,-18 123,-18 C127.42,-18 131,-14.42 131,-10c " />
+ </group>
+ </group>
+ <group
+ android:name="_R_G_L_1_G_L_3_G"
+ android:translateX="24"
+ android:translateY="390">
+ <group
+ android:name="_R_G_L_1_G_L_3_G_L_0_G"
+ android:translateX="182"
+ android:translateY="120">
+ <path
+ android:name="_R_G_L_1_G_L_3_G_L_0_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M182 -98 C182,-98 182,98 182,98 C182,110.14 172.14,120 160,120 C160,120 -160,120 -160,120 C-172.14,120 -182,110.14 -182,98 C-182,98 -182,-98 -182,-98 C-182,-110.14 -172.14,-120 -160,-120 C-160,-120 160,-120 160,-120 C172.14,-120 182,-110.14 182,-98c " />
+ </group>
+ </group>
+ <group android:name="_R_G_L_1_G_L_2_G">
+ <group
+ android:name="_R_G_L_1_G_L_2_G_L_2_G"
+ android:translateX="206"
+ android:translateY="145">
+ <path
+ android:name="_R_G_L_1_G_L_2_G_L_2_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#e8eaed"
+ android:fillType="nonZero"
+ android:pathData=" M206 -95.63 C206,-95.63 206,42.37 206,42.37 C206,43.47 205.1,44.37 204,44.37 C204,44.37 -204,44.37 -204,44.37 C-205.1,44.37 -206,43.47 -206,42.37 C-206,42.37 -206,-95.63 -206,-95.63 C-206,-96.73 -205.1,-97.63 -204,-97.63 C-204,-97.63 204,-97.63 204,-97.63 C205.1,-97.63 206,-96.73 206,-95.63c " />
+ </group>
+ <group
+ android:name="_R_G_L_1_G_L_2_G_L_1_G"
+ android:translateX="206"
+ android:translateY="145">
+ <path
+ android:name="_R_G_L_1_G_L_2_G_L_1_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#80868b"
+ android:fillType="nonZero"
+ android:pathData=" M109 -14 C109,-14 109,14 109,14 C109,15.1 108.1,16 107,16 C107,16 -107,16 -107,16 C-108.1,16 -109,15.1 -109,14 C-109,14 -109,-14 -109,-14 C-109,-15.1 -108.1,-16 -107,-16 C-107,-16 107,-16 107,-16 C108.1,-16 109,-15.1 109,-14c " />
+ </group>
+ <group
+ android:name="_R_G_L_1_G_L_2_G_L_0_G"
+ android:translateX="46"
+ android:translateY="145">
+ <path
+ android:name="_R_G_L_1_G_L_2_G_L_0_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#80868b"
+ android:fillType="nonZero"
+ android:pathData=" M22 -14 C22,-14 22,14 22,14 C22,18.42 18.42,22 14,22 C14,22 -14,22 -14,22 C-18.42,22 -22,18.42 -22,14 C-22,14 -22,-14 -22,-14 C-22,-18.42 -18.42,-22 -14,-22 C-14,-22 14,-22 14,-22 C18.42,-22 22,-18.42 22,-14c " />
+ </group>
+ </group>
+ <group android:name="_R_G_L_1_G_L_1_G">
+ <group
+ android:name="_R_G_L_1_G_L_1_G_L_2_G"
+ android:translateX="206"
+ android:translateY="51">
+ <path
+ android:name="_R_G_L_1_G_L_1_G_L_2_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#6e7175"
+ android:fillType="nonZero"
+ android:pathData=" M206 -0.27 C206,-0.27 206,49.73 206,49.73 C206,49.73 -206,49.73 -206,49.73 C-206,49.73 -206,-0.27 -206,-0.27 C-206,-0.27 206,-0.27 206,-0.27c " />
+ </group>
+ <group
+ android:name="_R_G_L_1_G_L_1_G_L_1_G"
+ android:translateX="206"
+ android:translateY="50.5">
+ <path
+ android:name="_R_G_L_1_G_L_1_G_L_1_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#6e7175"
+ android:fillType="nonZero"
+ android:pathData=" M206 -32.5 C206,-32.5 206,32.5 206,32.5 C206,42.43 197.93,50.5 188,50.5 C188,50.5 -188,50.5 -188,50.5 C-197.93,50.5 -206,42.43 -206,32.5 C-206,32.5 -206,-32.5 -206,-32.5 C-206,-42.43 -197.93,-50.5 -188,-50.5 C-188,-50.5 188,-50.5 188,-50.5 C197.93,-50.5 206,-42.43 206,-32.5c " />
+ </group>
+ <group
+ android:name="_R_G_L_1_G_L_1_G_L_0_G"
+ android:translateX="206"
+ android:translateY="66.5">
+ <path
+ android:name="_R_G_L_1_G_L_1_G_L_0_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#9a9a9a"
+ android:fillType="nonZero"
+ android:pathData=" M190 0 C190,0 190,0 190,0 C190,10.21 181.71,18.5 171.5,18.5 C171.5,18.5 -171.5,18.5 -171.5,18.5 C-181.71,18.5 -190,10.21 -190,0 C-190,0 -190,0 -190,0 C-190,-10.21 -181.71,-18.5 -171.5,-18.5 C-171.5,-18.5 171.5,-18.5 171.5,-18.5 C181.71,-18.5 190,-10.21 190,0c " />
+ </group>
+ </group>
+ <group
+ android:name="_R_G_L_1_G_L_0_G"
+ android:scaleY="0"
+ android:translateX="206"
+ android:translateY="446">
+ <path
+ android:name="_R_G_L_1_G_L_0_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bac4d6"
+ android:fillType="nonZero"
+ android:pathData=" M206.06 -430.06 C206.06,-430.06 206,431 206,431 C206,446 189.75,446 189.79,446 C189.79,446 -189.98,446 -189.98,446 C-189.94,446 -206,446 -206,431 C-206,431 -206,-430 -206,-430 C-206,-446 -189.97,-446 -190.01,-446 C-190.01,-446 188.98,-446.06 188.98,-446.06 C188.94,-446.06 206,-446 206.06,-430.06c " />
+ </group>
+ </group>
+ </group>
+ <group
+ android:name="_R_G_L_0_G"
+ android:translateX="206"
+ android:translateY="446">
+ <path
+ android:name="_R_G_L_0_G_D_0_P_0"
+ android:fillAlpha="0"
+ android:fillColor="#84ba69"
+ android:fillType="nonZero"
+ android:pathData=" M0 411 C19.33,411 35,426.67 35,446 C35,465.33 19.33,481 0,481 C-19.33,481 -35,465.33 -35,446 C-35,426.67 -19.33,411 0,411c " />
+ </group>
+ </group>
+ <group android:name="time_group" />
+ </vector>
+ </aapt:attr>
+</animated-vector> \ No newline at end of file
diff --git a/quickstep/res/drawable/gesture_tutorial_motion_overview_dark_mode.xml b/quickstep/res/drawable/gesture_tutorial_motion_overview_dark_mode.xml
new file mode 100644
index 0000000000..b007d20f34
--- /dev/null
+++ b/quickstep/res/drawable/gesture_tutorial_motion_overview_dark_mode.xml
@@ -0,0 +1,1623 @@
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:aapt="http://schemas.android.com/aapt">
+ <target android:name="_R_G_L_4_G_N_3_T_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="1050"
+ android:pathData="M 206,446C 206,446 206,395 206,395"
+ android:propertyName="translateXY"
+ android:propertyXName="translateX"
+ android:propertyYName="translateY"
+ android:startOffset="217">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.5,0 0.5,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_4_G_N_3_T_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="1050"
+ android:propertyName="scaleX"
+ android:startOffset="217"
+ android:valueFrom="1"
+ android:valueTo="0.6"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.5,0 0.5,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="1050"
+ android:propertyName="scaleY"
+ android:startOffset="217"
+ android:valueFrom="1"
+ android:valueTo="0.6"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.5,0 0.5,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_4_G_N_3_T_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="0"
+ android:propertyName="scaleY"
+ android:startOffset="3400"
+ android:valueFrom="1"
+ android:valueTo="0"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_L_0_G_L_28_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="0"
+ android:propertyName="scaleY"
+ android:startOffset="2083"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_L_0_G_L_27_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="0"
+ android:propertyName="scaleY"
+ android:startOffset="2083"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_L_0_G_L_26_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="0"
+ android:propertyName="scaleY"
+ android:startOffset="2083"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_L_0_G_L_25_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="0"
+ android:propertyName="scaleY"
+ android:startOffset="2083"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_L_0_G_L_24_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="0"
+ android:propertyName="scaleY"
+ android:startOffset="2083"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_L_0_G_L_23_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="0"
+ android:propertyName="scaleY"
+ android:startOffset="2083"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_L_0_G_L_22_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="0"
+ android:propertyName="scaleY"
+ android:startOffset="2083"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_L_0_G_L_21_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="0"
+ android:propertyName="scaleY"
+ android:startOffset="2083"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_L_0_G_L_20_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="0"
+ android:propertyName="scaleY"
+ android:startOffset="2083"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_L_0_G_L_19_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="0"
+ android:propertyName="scaleY"
+ android:startOffset="2083"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_L_0_G_L_18_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="0"
+ android:propertyName="scaleY"
+ android:startOffset="2083"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_L_0_G_L_17_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="0"
+ android:propertyName="scaleY"
+ android:startOffset="2083"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_L_0_G_L_16_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="0"
+ android:propertyName="scaleY"
+ android:startOffset="2083"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_L_0_G_L_15_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="0"
+ android:propertyName="scaleY"
+ android:startOffset="2083"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_L_0_G_L_14_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="0"
+ android:propertyName="scaleY"
+ android:startOffset="2083"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_L_0_G_L_13_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="0"
+ android:propertyName="scaleY"
+ android:startOffset="2083"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_L_0_G_L_12_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="0"
+ android:propertyName="scaleY"
+ android:startOffset="2083"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_L_0_G_L_11_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="0"
+ android:propertyName="scaleY"
+ android:startOffset="2083"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_L_0_G_L_10_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="0"
+ android:propertyName="scaleY"
+ android:startOffset="2083"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_L_0_G_L_9_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="0"
+ android:propertyName="scaleY"
+ android:startOffset="2083"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_L_0_G_L_8_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="0"
+ android:propertyName="scaleY"
+ android:startOffset="2083"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_L_0_G_L_7_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="0"
+ android:propertyName="scaleY"
+ android:startOffset="2083"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_L_0_G_L_6_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="0"
+ android:propertyName="scaleY"
+ android:startOffset="2083"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_L_0_G_L_5_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="0"
+ android:propertyName="scaleY"
+ android:startOffset="2083"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_L_0_G_L_4_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="0"
+ android:propertyName="scaleY"
+ android:startOffset="2083"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_L_0_G_L_3_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="0"
+ android:propertyName="scaleY"
+ android:startOffset="2083"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_L_0_G_L_2_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="0"
+ android:propertyName="scaleY"
+ android:startOffset="2083"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_L_0_G_L_1_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="0"
+ android:propertyName="scaleY"
+ android:startOffset="2083"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_L_0_G_L_0_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="0"
+ android:propertyName="scaleY"
+ android:startOffset="2083"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_L_0_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="0"
+ android:propertyName="scaleY"
+ android:startOffset="2083"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_N_2_T_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="350"
+ android:pathData="M 206,395C 206,403.5 206,437.5 206,446"
+ android:propertyName="translateXY"
+ android:propertyXName="translateX"
+ android:propertyYName="translateY"
+ android:startOffset="2083">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.34,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_N_2_T_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="350"
+ android:propertyName="scaleX"
+ android:startOffset="2083"
+ android:valueFrom="0.6"
+ android:valueTo="0.72718"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.34,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="350"
+ android:propertyName="scaleY"
+ android:startOffset="2083"
+ android:valueFrom="0.6"
+ android:valueTo="0.72718"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.34,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="217"
+ android:propertyName="scaleX"
+ android:startOffset="2433"
+ android:valueFrom="0.72718"
+ android:valueTo="0.72"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0 0.51,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="217"
+ android:propertyName="scaleY"
+ android:startOffset="2433"
+ android:valueFrom="0.72718"
+ android:valueTo="0.72"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0 0.51,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_N_2_T_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="0"
+ android:propertyName="scaleY"
+ android:startOffset="2083"
+ android:valueFrom="0"
+ android:valueTo="0.6"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_2_G_D_0_P_0_G_0_T_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="167"
+ android:propertyName="scaleX"
+ android:startOffset="2567"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="167"
+ android:propertyName="scaleY"
+ android:startOffset="2567"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_2_G_N_2_T_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="350"
+ android:pathData="M 206,395C 206,403.5 206,437.5 206,446"
+ android:propertyName="translateXY"
+ android:propertyXName="translateX"
+ android:propertyYName="translateY"
+ android:startOffset="2083">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.34,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_2_G_N_2_T_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="350"
+ android:propertyName="scaleX"
+ android:startOffset="2083"
+ android:valueFrom="0.6"
+ android:valueTo="0.72718"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.34,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="350"
+ android:propertyName="scaleY"
+ android:startOffset="2083"
+ android:valueFrom="0.6"
+ android:valueTo="0.72718"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.34,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="217"
+ android:propertyName="scaleX"
+ android:startOffset="2433"
+ android:valueFrom="0.72718"
+ android:valueTo="0.72"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0 0.51,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="217"
+ android:propertyName="scaleY"
+ android:startOffset="2433"
+ android:valueFrom="0.72718"
+ android:valueTo="0.72"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0 0.51,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_2_G_N_2_T_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="0"
+ android:propertyName="scaleY"
+ android:startOffset="2567"
+ android:valueFrom="0"
+ android:valueTo="0.6"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="250"
+ android:pathData="M -556.176,-7.307C -556.176,-7.307 -421.176,-7.307 -421.176,-7.307"
+ android:propertyName="translateXY"
+ android:propertyXName="translateX"
+ android:propertyYName="translateY"
+ android:startOffset="1350">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.272,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="417"
+ android:pathData="M -421.176,-7.307C -421.176,-7.307 -429.51,-7.307 -429.51,-7.307"
+ android:propertyName="translateXY"
+ android:propertyXName="translateX"
+ android:propertyYName="translateY"
+ android:startOffset="1600">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G_N_2_T_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="350"
+ android:pathData="M 206,395C 206,403.5 206,437.5 206,446"
+ android:propertyName="translateXY"
+ android:propertyXName="translateX"
+ android:propertyYName="translateY"
+ android:startOffset="2083">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.34,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G_N_2_T_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="350"
+ android:propertyName="scaleX"
+ android:startOffset="2083"
+ android:valueFrom="0.6"
+ android:valueTo="0.72718"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.34,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="350"
+ android:propertyName="scaleY"
+ android:startOffset="2083"
+ android:valueFrom="0.6"
+ android:valueTo="0.72718"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.34,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="217"
+ android:propertyName="scaleX"
+ android:startOffset="2433"
+ android:valueFrom="0.72718"
+ android:valueTo="0.72"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0 0.51,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="217"
+ android:propertyName="scaleY"
+ android:startOffset="2433"
+ android:valueFrom="0.72718"
+ android:valueTo="0.72"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0 0.51,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G_N_2_T_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="0"
+ android:propertyName="scaleY"
+ android:startOffset="1350"
+ android:valueFrom="0"
+ android:valueTo="0.6"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_D_0_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="217"
+ android:propertyName="fillAlpha"
+ android:startOffset="0"
+ android:valueFrom="0"
+ android:valueTo="0.75"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="1833"
+ android:propertyName="fillAlpha"
+ android:startOffset="217"
+ android:valueFrom="0.75"
+ android:valueTo="0.75"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0 0.667,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="167"
+ android:propertyName="fillAlpha"
+ android:startOffset="2050"
+ android:valueFrom="0.75"
+ android:valueTo="0"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_D_0_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="217"
+ android:propertyName="pathData"
+ android:startOffset="0"
+ android:valueFrom="M0 406 C21.54,406 39,423.46 39,445 C39,466.54 21.54,484 0,484 C-21.54,484 -39,466.54 -39,445 C-39,423.46 -21.54,406 0,406c "
+ android:valueTo="M0 395 C27.61,395 50,417.39 50,445 C50,472.61 27.61,495 0,495 C-27.61,495 -50,472.61 -50,445 C-50,417.39 -27.61,395 0,395c "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="1050"
+ android:propertyName="pathData"
+ android:startOffset="217"
+ android:valueFrom="M0 395 C27.61,395 50,417.39 50,445 C50,472.61 27.61,495 0,495 C-27.61,495 -50,472.61 -50,445 C-50,417.39 -27.61,395 0,395c "
+ android:valueTo="M0 166 C27.61,166 50,188.39 50,216 C50,243.61 27.61,266 0,266 C-27.61,266 -50,243.61 -50,216 C-50,188.39 -27.61,166 0,166c "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.5,0 0.5,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="783"
+ android:propertyName="pathData"
+ android:startOffset="1267"
+ android:valueFrom="M0 166 C27.61,166 50,188.39 50,216 C50,243.61 27.61,266 0,266 C-27.61,266 -50,243.61 -50,216 C-50,188.39 -27.61,166 0,166c "
+ android:valueTo="M0 166 C27.61,166 50,188.39 50,216 C50,243.61 27.61,266 0,266 C-27.61,266 -50,243.61 -50,216 C-50,188.39 -27.61,166 0,166c "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="167"
+ android:propertyName="pathData"
+ android:startOffset="2050"
+ android:valueFrom="M0 166 C27.61,166 50,188.39 50,216 C50,243.61 27.61,266 0,266 C-27.61,266 -50,243.61 -50,216 C-50,188.39 -27.61,166 0,166c "
+ android:valueTo="M0 180 C19.88,180 36,196.12 36,216 C36,235.88 19.88,252 0,252 C-19.88,252 -36,235.88 -36,216 C-36,196.12 -19.88,180 0,180c "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="time_group">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="2750"
+ android:propertyName="translateX"
+ android:startOffset="0"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <aapt:attr name="android:drawable">
+ <vector
+ android:width="412dp"
+ android:height="892dp"
+ android:viewportHeight="892"
+ android:viewportWidth="412">
+ <group android:name="_R_G">
+ <group
+ android:name="_R_G_L_5_G"
+ android:translateX="206"
+ android:translateY="446">
+ <path
+ android:name="_R_G_L_5_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="@color/fake_wallpaper_color_dark_mode"
+ android:fillType="nonZero"
+ android:pathData=" M206 -446 C206,-446 206,446 206,446 C206,446 -206,446 -206,446 C-206,446 -206,-446 -206,-446 C-206,-446 206,-446 206,-446c " />
+ </group>
+ <group
+ android:name="_R_G_L_4_G_N_3_T_0"
+ android:scaleX="1"
+ android:scaleY="1"
+ android:translateX="206"
+ android:translateY="446">
+ <group
+ android:name="_R_G_L_4_G"
+ android:translateX="-206"
+ android:translateY="-446">
+ <group android:name="_R_G_L_4_G_L_0_G">
+ <group
+ android:name="_R_G_L_4_G_L_0_G_L_28_G"
+ android:translateX="206"
+ android:translateY="446">
+ <path
+ android:name="_R_G_L_4_G_L_0_G_L_28_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#000000"
+ android:fillType="nonZero"
+ android:pathData=" M206 -422 C206,-422 206,422 206,422 C206,435.25 195.25,446 182,446 C182,446 -182,446 -182,446 C-195.25,446 -206,435.25 -206,422 C-206,422 -206,-422 -206,-422 C-206,-435.25 -195.25,-446 -182,-446 C-182,-446 182,-446 182,-446 C195.25,-446 206,-435.25 206,-422c " />
+ </group>
+ <group
+ android:name="_R_G_L_4_G_L_0_G_L_27_G"
+ android:translateX="206"
+ android:translateY="422.5">
+ <path
+ android:name="_R_G_L_4_G_L_0_G_L_27_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#dadce0"
+ android:fillType="nonZero"
+ android:pathData=" M206 -395.5 C206,-395.5 206,395.5 206,395.5 C206,395.5 -206,395.5 -206,395.5 C-206,395.5 -206,-395.5 -206,-395.5 C-206,-395.5 206,-395.5 206,-395.5c " />
+ </group>
+ <group
+ android:name="_R_G_L_4_G_L_0_G_L_26_G"
+ android:translateX="206"
+ android:translateY="496.5">
+ <path
+ android:name="_R_G_L_4_G_L_0_G_L_26_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#dadce0"
+ android:fillType="nonZero"
+ android:pathData=" M206 -377.5 C206,-377.5 206,377.5 206,377.5 C206,387.43 197.93,395.5 188,395.5 C188,395.5 -188,395.5 -188,395.5 C-197.93,395.5 -206,387.43 -206,377.5 C-206,377.5 -206,-377.5 -206,-377.5 C-206,-387.43 -197.93,-395.5 -188,-395.5 C-188,-395.5 188,-395.5 188,-395.5 C197.93,-395.5 206,-387.43 206,-377.5c " />
+ </group>
+ <group
+ android:name="_R_G_L_4_G_L_0_G_L_25_G"
+ android:translateX="206"
+ android:translateY="50.5">
+ <path
+ android:name="_R_G_L_4_G_L_0_G_L_25_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#e8eaed"
+ android:fillType="nonZero"
+ android:pathData=" M206 -23.5 C206,-23.5 206,50.5 206,50.5 C206,50.5 -206,50.5 -206,50.5 C-206,50.5 -206,-23.5 -206,-23.5 C-206,-23.5 206,-23.5 206,-23.5c " />
+ </group>
+ <group
+ android:name="_R_G_L_4_G_L_0_G_L_24_G"
+ android:translateX="206"
+ android:translateY="50.5">
+ <path
+ android:name="_R_G_L_4_G_L_0_G_L_24_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#e8eaed"
+ android:fillType="nonZero"
+ android:pathData=" M206 -32.5 C206,-32.5 206,32.5 206,32.5 C206,42.43 197.93,50.5 188,50.5 C188,50.5 -188,50.5 -188,50.5 C-197.93,50.5 -206,42.43 -206,32.5 C-206,32.5 -206,-32.5 -206,-32.5 C-206,-42.43 -197.93,-50.5 -188,-50.5 C-188,-50.5 188,-50.5 188,-50.5 C197.93,-50.5 206,-42.43 206,-32.5c " />
+ </group>
+ <group
+ android:name="_R_G_L_4_G_L_0_G_L_23_G"
+ android:translateX="54"
+ android:translateY="157">
+ <path
+ android:name="_R_G_L_4_G_L_0_G_L_23_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#9aa0a6"
+ android:fillType="nonZero"
+ android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
+ </group>
+ <group
+ android:name="_R_G_L_4_G_L_0_G_L_22_G"
+ android:translateX="54"
+ android:translateY="157">
+ <path
+ android:name="_R_G_L_4_G_L_0_G_L_22_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#9aa0a6"
+ android:fillType="nonZero"
+ android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
+ </group>
+ <group
+ android:name="_R_G_L_4_G_L_0_G_L_21_G"
+ android:translateX="148.5"
+ android:translateY="148">
+ <path
+ android:name="_R_G_L_4_G_L_0_G_L_21_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M46.5 -5 C46.5,-5 46.5,5 46.5,5 C46.5,7.21 44.71,9 42.5,9 C42.5,9 -42.5,9 -42.5,9 C-44.71,9 -46.5,7.21 -46.5,5 C-46.5,5 -46.5,-5 -46.5,-5 C-46.5,-7.21 -44.71,-9 -42.5,-9 C-42.5,-9 42.5,-9 42.5,-9 C44.71,-9 46.5,-7.21 46.5,-5c " />
+ </group>
+ <group
+ android:name="_R_G_L_4_G_L_0_G_L_20_G"
+ android:translateX="186"
+ android:translateY="169">
+ <path
+ android:name="_R_G_L_4_G_L_0_G_L_20_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M84 -4 C84,-4 84,4 84,4 C84,6.21 82.21,8 80,8 C80,8 -80,8 -80,8 C-82.21,8 -84,6.21 -84,4 C-84,4 -84,-4 -84,-4 C-84,-6.21 -82.21,-8 -80,-8 C-80,-8 80,-8 80,-8 C82.21,-8 84,-6.21 84,-4c " />
+ </group>
+ <group
+ android:name="_R_G_L_4_G_L_0_G_L_19_G"
+ android:translateX="54"
+ android:translateY="245">
+ <path
+ android:name="_R_G_L_4_G_L_0_G_L_19_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#9aa0a6"
+ android:fillType="nonZero"
+ android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
+ </group>
+ <group
+ android:name="_R_G_L_4_G_L_0_G_L_18_G"
+ android:translateX="162"
+ android:translateY="236">
+ <path
+ android:name="_R_G_L_4_G_L_0_G_L_18_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M60 -5 C60,-5 60,5 60,5 C60,7.21 58.21,9 56,9 C56,9 -56,9 -56,9 C-58.21,9 -60,7.21 -60,5 C-60,5 -60,-5 -60,-5 C-60,-7.21 -58.21,-9 -56,-9 C-56,-9 56,-9 56,-9 C58.21,-9 60,-7.21 60,-5c " />
+ </group>
+ <group
+ android:name="_R_G_L_4_G_L_0_G_L_17_G"
+ android:translateX="171.5"
+ android:translateY="257">
+ <path
+ android:name="_R_G_L_4_G_L_0_G_L_17_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M69.5 -4 C69.5,-4 69.5,4 69.5,4 C69.5,6.21 67.71,8 65.5,8 C65.5,8 -65.5,8 -65.5,8 C-67.71,8 -69.5,6.21 -69.5,4 C-69.5,4 -69.5,-4 -69.5,-4 C-69.5,-6.21 -67.71,-8 -65.5,-8 C-65.5,-8 65.5,-8 65.5,-8 C67.71,-8 69.5,-6.21 69.5,-4c " />
+ </group>
+ <group
+ android:name="_R_G_L_4_G_L_0_G_L_16_G"
+ android:translateX="54"
+ android:translateY="333">
+ <path
+ android:name="_R_G_L_4_G_L_0_G_L_16_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#9aa0a6"
+ android:fillType="nonZero"
+ android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
+ </group>
+ <group
+ android:name="_R_G_L_4_G_L_0_G_L_15_G"
+ android:translateX="158"
+ android:translateY="324">
+ <path
+ android:name="_R_G_L_4_G_L_0_G_L_15_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M56 -5 C56,-5 56,5 56,5 C56,7.21 54.21,9 52,9 C52,9 -52,9 -52,9 C-54.21,9 -56,7.21 -56,5 C-56,5 -56,-5 -56,-5 C-56,-7.21 -54.21,-9 -52,-9 C-52,-9 52,-9 52,-9 C54.21,-9 56,-7.21 56,-5c " />
+ </group>
+ <group
+ android:name="_R_G_L_4_G_L_0_G_L_14_G"
+ android:translateX="217.5"
+ android:translateY="345">
+ <path
+ android:name="_R_G_L_4_G_L_0_G_L_14_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M115.5 -4 C115.5,-4 115.5,4 115.5,4 C115.5,6.21 113.71,8 111.5,8 C111.5,8 -111.5,8 -111.5,8 C-113.71,8 -115.5,6.21 -115.5,4 C-115.5,4 -115.5,-4 -115.5,-4 C-115.5,-6.21 -113.71,-8 -111.5,-8 C-111.5,-8 111.5,-8 111.5,-8 C113.71,-8 115.5,-6.21 115.5,-4c " />
+ </group>
+ <group
+ android:name="_R_G_L_4_G_L_0_G_L_13_G"
+ android:translateX="54"
+ android:translateY="421">
+ <path
+ android:name="_R_G_L_4_G_L_0_G_L_13_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#9aa0a6"
+ android:fillType="nonZero"
+ android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
+ </group>
+ <group
+ android:name="_R_G_L_4_G_L_0_G_L_12_G"
+ android:translateX="170"
+ android:translateY="412">
+ <path
+ android:name="_R_G_L_4_G_L_0_G_L_12_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M68 -5 C68,-5 68,5 68,5 C68,7.21 66.21,9 64,9 C64,9 -64,9 -64,9 C-66.21,9 -68,7.21 -68,5 C-68,5 -68,-5 -68,-5 C-68,-7.21 -66.21,-9 -64,-9 C-64,-9 64,-9 64,-9 C66.21,-9 68,-7.21 68,-5c " />
+ </group>
+ <group
+ android:name="_R_G_L_4_G_L_0_G_L_11_G"
+ android:translateX="198.5"
+ android:translateY="433">
+ <path
+ android:name="_R_G_L_4_G_L_0_G_L_11_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M96.5 -4 C96.5,-4 96.5,4 96.5,4 C96.5,6.21 94.71,8 92.5,8 C92.5,8 -92.5,8 -92.5,8 C-94.71,8 -96.5,6.21 -96.5,4 C-96.5,4 -96.5,-4 -96.5,-4 C-96.5,-6.21 -94.71,-8 -92.5,-8 C-92.5,-8 92.5,-8 92.5,-8 C94.71,-8 96.5,-6.21 96.5,-4c " />
+ </group>
+ <group
+ android:name="_R_G_L_4_G_L_0_G_L_10_G"
+ android:translateX="54"
+ android:translateY="509">
+ <path
+ android:name="_R_G_L_4_G_L_0_G_L_10_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#9aa0a6"
+ android:fillType="nonZero"
+ android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
+ </group>
+ <group
+ android:name="_R_G_L_4_G_L_0_G_L_9_G"
+ android:translateX="135"
+ android:translateY="500">
+ <path
+ android:name="_R_G_L_4_G_L_0_G_L_9_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M33 -5 C33,-5 33,5 33,5 C33,7.21 31.21,9 29,9 C29,9 -29,9 -29,9 C-31.21,9 -33,7.21 -33,5 C-33,5 -33,-5 -33,-5 C-33,-7.21 -31.21,-9 -29,-9 C-29,-9 29,-9 29,-9 C31.21,-9 33,-7.21 33,-5c " />
+ </group>
+ <group
+ android:name="_R_G_L_4_G_L_0_G_L_8_G"
+ android:translateX="185.5"
+ android:translateY="521">
+ <path
+ android:name="_R_G_L_4_G_L_0_G_L_8_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M83.5 -4 C83.5,-4 83.5,4 83.5,4 C83.5,6.21 81.71,8 79.5,8 C79.5,8 -79.5,8 -79.5,8 C-81.71,8 -83.5,6.21 -83.5,4 C-83.5,4 -83.5,-4 -83.5,-4 C-83.5,-6.21 -81.71,-8 -79.5,-8 C-79.5,-8 79.5,-8 79.5,-8 C81.71,-8 83.5,-6.21 83.5,-4c " />
+ </group>
+ <group
+ android:name="_R_G_L_4_G_L_0_G_L_7_G"
+ android:translateX="54"
+ android:translateY="597">
+ <path
+ android:name="_R_G_L_4_G_L_0_G_L_7_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#9aa0a6"
+ android:fillType="nonZero"
+ android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
+ </group>
+ <group
+ android:name="_R_G_L_4_G_L_0_G_L_6_G"
+ android:translateX="168.5"
+ android:translateY="588">
+ <path
+ android:name="_R_G_L_4_G_L_0_G_L_6_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M66.5 -5 C66.5,-5 66.5,5 66.5,5 C66.5,7.21 64.71,9 62.5,9 C62.5,9 -62.5,9 -62.5,9 C-64.71,9 -66.5,7.21 -66.5,5 C-66.5,5 -66.5,-5 -66.5,-5 C-66.5,-7.21 -64.71,-9 -62.5,-9 C-62.5,-9 62.5,-9 62.5,-9 C64.71,-9 66.5,-7.21 66.5,-5c " />
+ </group>
+ <group
+ android:name="_R_G_L_4_G_L_0_G_L_5_G"
+ android:translateX="198.5"
+ android:translateY="609">
+ <path
+ android:name="_R_G_L_4_G_L_0_G_L_5_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M96.5 -4 C96.5,-4 96.5,4 96.5,4 C96.5,6.21 94.71,8 92.5,8 C92.5,8 -92.5,8 -92.5,8 C-94.71,8 -96.5,6.21 -96.5,4 C-96.5,4 -96.5,-4 -96.5,-4 C-96.5,-6.21 -94.71,-8 -92.5,-8 C-92.5,-8 92.5,-8 92.5,-8 C94.71,-8 96.5,-6.21 96.5,-4c " />
+ </group>
+ <group
+ android:name="_R_G_L_4_G_L_0_G_L_4_G"
+ android:translateX="54"
+ android:translateY="685">
+ <path
+ android:name="_R_G_L_4_G_L_0_G_L_4_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#9aa0a6"
+ android:fillType="nonZero"
+ android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
+ </group>
+ <group
+ android:name="_R_G_L_4_G_L_0_G_L_3_G"
+ android:translateX="162.5"
+ android:translateY="676">
+ <path
+ android:name="_R_G_L_4_G_L_0_G_L_3_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M60.5 -5 C60.5,-5 60.5,5 60.5,5 C60.5,7.21 58.71,9 56.5,9 C56.5,9 -56.5,9 -56.5,9 C-58.71,9 -60.5,7.21 -60.5,5 C-60.5,5 -60.5,-5 -60.5,-5 C-60.5,-7.21 -58.71,-9 -56.5,-9 C-56.5,-9 56.5,-9 56.5,-9 C58.71,-9 60.5,-7.21 60.5,-5c " />
+ </group>
+ <group
+ android:name="_R_G_L_4_G_L_0_G_L_2_G"
+ android:translateX="174"
+ android:translateY="697">
+ <path
+ android:name="_R_G_L_4_G_L_0_G_L_2_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M72 -4 C72,-4 72,4 72,4 C72,6.21 70.21,8 68,8 C68,8 -68,8 -68,8 C-70.21,8 -72,6.21 -72,4 C-72,4 -72,-4 -72,-4 C-72,-6.21 -70.21,-8 -68,-8 C-68,-8 68,-8 68,-8 C70.21,-8 72,-6.21 72,-4c " />
+ </group>
+ <group
+ android:name="_R_G_L_4_G_L_0_G_L_1_G"
+ android:translateX="313.5"
+ android:translateY="798">
+ <path
+ android:name="_R_G_L_4_G_L_0_G_L_1_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M74.5 0 C74.5,0 74.5,0 74.5,0 C74.5,15.45 61.95,28 46.5,28 C46.5,28 -46.5,28 -46.5,28 C-61.95,28 -74.5,15.45 -74.5,0 C-74.5,0 -74.5,0 -74.5,0 C-74.5,-15.45 -61.95,-28 -46.5,-28 C-46.5,-28 46.5,-28 46.5,-28 C61.95,-28 74.5,-15.45 74.5,0c " />
+ </group>
+ <group
+ android:name="_R_G_L_4_G_L_0_G_L_0_G"
+ android:translateX="205.5"
+ android:translateY="61">
+ <path
+ android:name="_R_G_L_4_G_L_0_G_L_0_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#f8f9fa"
+ android:fillType="nonZero"
+ android:pathData=" M171.5 -14 C171.5,-14 171.5,14 171.5,14 C171.5,16.21 169.71,18 167.5,18 C167.5,18 -167.5,18 -167.5,18 C-169.71,18 -171.5,16.21 -171.5,14 C-171.5,14 -171.5,-14 -171.5,-14 C-171.5,-16.21 -169.71,-18 -167.5,-18 C-167.5,-18 167.5,-18 167.5,-18 C169.71,-18 171.5,-16.21 171.5,-14c " />
+ </group>
+ </group>
+ </group>
+ </group>
+ <group
+ android:name="_R_G_L_3_G_N_2_T_0"
+ android:scaleX="0.6"
+ android:scaleY="0"
+ android:translateX="206"
+ android:translateY="395">
+ <group
+ android:name="_R_G_L_3_G"
+ android:translateX="-206"
+ android:translateY="-446">
+ <group
+ android:name="_R_G_L_3_G_L_0_G"
+ android:scaleY="0">
+ <group
+ android:name="_R_G_L_3_G_L_0_G_L_28_G"
+ android:scaleY="0"
+ android:translateX="206"
+ android:translateY="446">
+ <path
+ android:name="_R_G_L_3_G_L_0_G_L_28_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#000000"
+ android:fillType="nonZero"
+ android:pathData=" M206 -422 C206,-422 206,422 206,422 C206,435.25 195.25,446 182,446 C182,446 -182,446 -182,446 C-195.25,446 -206,435.25 -206,422 C-206,422 -206,-422 -206,-422 C-206,-435.25 -195.25,-446 -182,-446 C-182,-446 182,-446 182,-446 C195.25,-446 206,-435.25 206,-422c " />
+ </group>
+ <group
+ android:name="_R_G_L_3_G_L_0_G_L_27_G"
+ android:scaleY="0"
+ android:translateX="206"
+ android:translateY="422.5">
+ <path
+ android:name="_R_G_L_3_G_L_0_G_L_27_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#dadce0"
+ android:fillType="nonZero"
+ android:pathData=" M206 -395.5 C206,-395.5 206,395.5 206,395.5 C206,395.5 -206,395.5 -206,395.5 C-206,395.5 -206,-395.5 -206,-395.5 C-206,-395.5 206,-395.5 206,-395.5c " />
+ </group>
+ <group
+ android:name="_R_G_L_3_G_L_0_G_L_26_G"
+ android:scaleY="0"
+ android:translateX="206"
+ android:translateY="496.5">
+ <path
+ android:name="_R_G_L_3_G_L_0_G_L_26_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#dadce0"
+ android:fillType="nonZero"
+ android:pathData=" M206 -377.5 C206,-377.5 206,377.5 206,377.5 C206,387.43 197.93,395.5 188,395.5 C188,395.5 -188,395.5 -188,395.5 C-197.93,395.5 -206,387.43 -206,377.5 C-206,377.5 -206,-377.5 -206,-377.5 C-206,-387.43 -197.93,-395.5 -188,-395.5 C-188,-395.5 188,-395.5 188,-395.5 C197.93,-395.5 206,-387.43 206,-377.5c " />
+ </group>
+ <group
+ android:name="_R_G_L_3_G_L_0_G_L_25_G"
+ android:scaleY="0"
+ android:translateX="206"
+ android:translateY="50.5">
+ <path
+ android:name="_R_G_L_3_G_L_0_G_L_25_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#e8eaed"
+ android:fillType="nonZero"
+ android:pathData=" M206 -23.5 C206,-23.5 206,50.5 206,50.5 C206,50.5 -206,50.5 -206,50.5 C-206,50.5 -206,-23.5 -206,-23.5 C-206,-23.5 206,-23.5 206,-23.5c " />
+ </group>
+ <group
+ android:name="_R_G_L_3_G_L_0_G_L_24_G"
+ android:scaleY="0"
+ android:translateX="206"
+ android:translateY="50.5">
+ <path
+ android:name="_R_G_L_3_G_L_0_G_L_24_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#e8eaed"
+ android:fillType="nonZero"
+ android:pathData=" M206 -32.5 C206,-32.5 206,32.5 206,32.5 C206,42.43 197.93,50.5 188,50.5 C188,50.5 -188,50.5 -188,50.5 C-197.93,50.5 -206,42.43 -206,32.5 C-206,32.5 -206,-32.5 -206,-32.5 C-206,-42.43 -197.93,-50.5 -188,-50.5 C-188,-50.5 188,-50.5 188,-50.5 C197.93,-50.5 206,-42.43 206,-32.5c " />
+ </group>
+ <group
+ android:name="_R_G_L_3_G_L_0_G_L_23_G"
+ android:scaleY="0"
+ android:translateX="54"
+ android:translateY="157">
+ <path
+ android:name="_R_G_L_3_G_L_0_G_L_23_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#9aa0a6"
+ android:fillType="nonZero"
+ android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
+ </group>
+ <group
+ android:name="_R_G_L_3_G_L_0_G_L_22_G"
+ android:scaleY="0"
+ android:translateX="54"
+ android:translateY="157">
+ <path
+ android:name="_R_G_L_3_G_L_0_G_L_22_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#9aa0a6"
+ android:fillType="nonZero"
+ android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
+ </group>
+ <group
+ android:name="_R_G_L_3_G_L_0_G_L_21_G"
+ android:scaleY="0"
+ android:translateX="148.5"
+ android:translateY="148">
+ <path
+ android:name="_R_G_L_3_G_L_0_G_L_21_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M46.5 -5 C46.5,-5 46.5,5 46.5,5 C46.5,7.21 44.71,9 42.5,9 C42.5,9 -42.5,9 -42.5,9 C-44.71,9 -46.5,7.21 -46.5,5 C-46.5,5 -46.5,-5 -46.5,-5 C-46.5,-7.21 -44.71,-9 -42.5,-9 C-42.5,-9 42.5,-9 42.5,-9 C44.71,-9 46.5,-7.21 46.5,-5c " />
+ </group>
+ <group
+ android:name="_R_G_L_3_G_L_0_G_L_20_G"
+ android:scaleY="0"
+ android:translateX="186"
+ android:translateY="169">
+ <path
+ android:name="_R_G_L_3_G_L_0_G_L_20_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M84 -4 C84,-4 84,4 84,4 C84,6.21 82.21,8 80,8 C80,8 -80,8 -80,8 C-82.21,8 -84,6.21 -84,4 C-84,4 -84,-4 -84,-4 C-84,-6.21 -82.21,-8 -80,-8 C-80,-8 80,-8 80,-8 C82.21,-8 84,-6.21 84,-4c " />
+ </group>
+ <group
+ android:name="_R_G_L_3_G_L_0_G_L_19_G"
+ android:scaleY="0"
+ android:translateX="54"
+ android:translateY="245">
+ <path
+ android:name="_R_G_L_3_G_L_0_G_L_19_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#9aa0a6"
+ android:fillType="nonZero"
+ android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
+ </group>
+ <group
+ android:name="_R_G_L_3_G_L_0_G_L_18_G"
+ android:scaleY="0"
+ android:translateX="162"
+ android:translateY="236">
+ <path
+ android:name="_R_G_L_3_G_L_0_G_L_18_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M60 -5 C60,-5 60,5 60,5 C60,7.21 58.21,9 56,9 C56,9 -56,9 -56,9 C-58.21,9 -60,7.21 -60,5 C-60,5 -60,-5 -60,-5 C-60,-7.21 -58.21,-9 -56,-9 C-56,-9 56,-9 56,-9 C58.21,-9 60,-7.21 60,-5c " />
+ </group>
+ <group
+ android:name="_R_G_L_3_G_L_0_G_L_17_G"
+ android:scaleY="0"
+ android:translateX="171.5"
+ android:translateY="257">
+ <path
+ android:name="_R_G_L_3_G_L_0_G_L_17_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M69.5 -4 C69.5,-4 69.5,4 69.5,4 C69.5,6.21 67.71,8 65.5,8 C65.5,8 -65.5,8 -65.5,8 C-67.71,8 -69.5,6.21 -69.5,4 C-69.5,4 -69.5,-4 -69.5,-4 C-69.5,-6.21 -67.71,-8 -65.5,-8 C-65.5,-8 65.5,-8 65.5,-8 C67.71,-8 69.5,-6.21 69.5,-4c " />
+ </group>
+ <group
+ android:name="_R_G_L_3_G_L_0_G_L_16_G"
+ android:scaleY="0"
+ android:translateX="54"
+ android:translateY="333">
+ <path
+ android:name="_R_G_L_3_G_L_0_G_L_16_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#9aa0a6"
+ android:fillType="nonZero"
+ android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
+ </group>
+ <group
+ android:name="_R_G_L_3_G_L_0_G_L_15_G"
+ android:scaleY="0"
+ android:translateX="158"
+ android:translateY="324">
+ <path
+ android:name="_R_G_L_3_G_L_0_G_L_15_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M56 -5 C56,-5 56,5 56,5 C56,7.21 54.21,9 52,9 C52,9 -52,9 -52,9 C-54.21,9 -56,7.21 -56,5 C-56,5 -56,-5 -56,-5 C-56,-7.21 -54.21,-9 -52,-9 C-52,-9 52,-9 52,-9 C54.21,-9 56,-7.21 56,-5c " />
+ </group>
+ <group
+ android:name="_R_G_L_3_G_L_0_G_L_14_G"
+ android:scaleY="0"
+ android:translateX="217.5"
+ android:translateY="345">
+ <path
+ android:name="_R_G_L_3_G_L_0_G_L_14_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M115.5 -4 C115.5,-4 115.5,4 115.5,4 C115.5,6.21 113.71,8 111.5,8 C111.5,8 -111.5,8 -111.5,8 C-113.71,8 -115.5,6.21 -115.5,4 C-115.5,4 -115.5,-4 -115.5,-4 C-115.5,-6.21 -113.71,-8 -111.5,-8 C-111.5,-8 111.5,-8 111.5,-8 C113.71,-8 115.5,-6.21 115.5,-4c " />
+ </group>
+ <group
+ android:name="_R_G_L_3_G_L_0_G_L_13_G"
+ android:scaleY="0"
+ android:translateX="54"
+ android:translateY="421">
+ <path
+ android:name="_R_G_L_3_G_L_0_G_L_13_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#9aa0a6"
+ android:fillType="nonZero"
+ android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
+ </group>
+ <group
+ android:name="_R_G_L_3_G_L_0_G_L_12_G"
+ android:scaleY="0"
+ android:translateX="170"
+ android:translateY="412">
+ <path
+ android:name="_R_G_L_3_G_L_0_G_L_12_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M68 -5 C68,-5 68,5 68,5 C68,7.21 66.21,9 64,9 C64,9 -64,9 -64,9 C-66.21,9 -68,7.21 -68,5 C-68,5 -68,-5 -68,-5 C-68,-7.21 -66.21,-9 -64,-9 C-64,-9 64,-9 64,-9 C66.21,-9 68,-7.21 68,-5c " />
+ </group>
+ <group
+ android:name="_R_G_L_3_G_L_0_G_L_11_G"
+ android:scaleY="0"
+ android:translateX="198.5"
+ android:translateY="433">
+ <path
+ android:name="_R_G_L_3_G_L_0_G_L_11_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M96.5 -4 C96.5,-4 96.5,4 96.5,4 C96.5,6.21 94.71,8 92.5,8 C92.5,8 -92.5,8 -92.5,8 C-94.71,8 -96.5,6.21 -96.5,4 C-96.5,4 -96.5,-4 -96.5,-4 C-96.5,-6.21 -94.71,-8 -92.5,-8 C-92.5,-8 92.5,-8 92.5,-8 C94.71,-8 96.5,-6.21 96.5,-4c " />
+ </group>
+ <group
+ android:name="_R_G_L_3_G_L_0_G_L_10_G"
+ android:scaleY="0"
+ android:translateX="54"
+ android:translateY="509">
+ <path
+ android:name="_R_G_L_3_G_L_0_G_L_10_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#9aa0a6"
+ android:fillType="nonZero"
+ android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
+ </group>
+ <group
+ android:name="_R_G_L_3_G_L_0_G_L_9_G"
+ android:scaleY="0"
+ android:translateX="135"
+ android:translateY="500">
+ <path
+ android:name="_R_G_L_3_G_L_0_G_L_9_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M33 -5 C33,-5 33,5 33,5 C33,7.21 31.21,9 29,9 C29,9 -29,9 -29,9 C-31.21,9 -33,7.21 -33,5 C-33,5 -33,-5 -33,-5 C-33,-7.21 -31.21,-9 -29,-9 C-29,-9 29,-9 29,-9 C31.21,-9 33,-7.21 33,-5c " />
+ </group>
+ <group
+ android:name="_R_G_L_3_G_L_0_G_L_8_G"
+ android:scaleY="0"
+ android:translateX="185.5"
+ android:translateY="521">
+ <path
+ android:name="_R_G_L_3_G_L_0_G_L_8_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M83.5 -4 C83.5,-4 83.5,4 83.5,4 C83.5,6.21 81.71,8 79.5,8 C79.5,8 -79.5,8 -79.5,8 C-81.71,8 -83.5,6.21 -83.5,4 C-83.5,4 -83.5,-4 -83.5,-4 C-83.5,-6.21 -81.71,-8 -79.5,-8 C-79.5,-8 79.5,-8 79.5,-8 C81.71,-8 83.5,-6.21 83.5,-4c " />
+ </group>
+ <group
+ android:name="_R_G_L_3_G_L_0_G_L_7_G"
+ android:scaleY="0"
+ android:translateX="54"
+ android:translateY="597">
+ <path
+ android:name="_R_G_L_3_G_L_0_G_L_7_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#9aa0a6"
+ android:fillType="nonZero"
+ android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
+ </group>
+ <group
+ android:name="_R_G_L_3_G_L_0_G_L_6_G"
+ android:scaleY="0"
+ android:translateX="168.5"
+ android:translateY="588">
+ <path
+ android:name="_R_G_L_3_G_L_0_G_L_6_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M66.5 -5 C66.5,-5 66.5,5 66.5,5 C66.5,7.21 64.71,9 62.5,9 C62.5,9 -62.5,9 -62.5,9 C-64.71,9 -66.5,7.21 -66.5,5 C-66.5,5 -66.5,-5 -66.5,-5 C-66.5,-7.21 -64.71,-9 -62.5,-9 C-62.5,-9 62.5,-9 62.5,-9 C64.71,-9 66.5,-7.21 66.5,-5c " />
+ </group>
+ <group
+ android:name="_R_G_L_3_G_L_0_G_L_5_G"
+ android:scaleY="0"
+ android:translateX="198.5"
+ android:translateY="609">
+ <path
+ android:name="_R_G_L_3_G_L_0_G_L_5_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M96.5 -4 C96.5,-4 96.5,4 96.5,4 C96.5,6.21 94.71,8 92.5,8 C92.5,8 -92.5,8 -92.5,8 C-94.71,8 -96.5,6.21 -96.5,4 C-96.5,4 -96.5,-4 -96.5,-4 C-96.5,-6.21 -94.71,-8 -92.5,-8 C-92.5,-8 92.5,-8 92.5,-8 C94.71,-8 96.5,-6.21 96.5,-4c " />
+ </group>
+ <group
+ android:name="_R_G_L_3_G_L_0_G_L_4_G"
+ android:scaleY="0"
+ android:translateX="54"
+ android:translateY="685">
+ <path
+ android:name="_R_G_L_3_G_L_0_G_L_4_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#9aa0a6"
+ android:fillType="nonZero"
+ android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
+ </group>
+ <group
+ android:name="_R_G_L_3_G_L_0_G_L_3_G"
+ android:scaleY="0"
+ android:translateX="162.5"
+ android:translateY="676">
+ <path
+ android:name="_R_G_L_3_G_L_0_G_L_3_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M60.5 -5 C60.5,-5 60.5,5 60.5,5 C60.5,7.21 58.71,9 56.5,9 C56.5,9 -56.5,9 -56.5,9 C-58.71,9 -60.5,7.21 -60.5,5 C-60.5,5 -60.5,-5 -60.5,-5 C-60.5,-7.21 -58.71,-9 -56.5,-9 C-56.5,-9 56.5,-9 56.5,-9 C58.71,-9 60.5,-7.21 60.5,-5c " />
+ </group>
+ <group
+ android:name="_R_G_L_3_G_L_0_G_L_2_G"
+ android:scaleY="0"
+ android:translateX="174"
+ android:translateY="697">
+ <path
+ android:name="_R_G_L_3_G_L_0_G_L_2_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M72 -4 C72,-4 72,4 72,4 C72,6.21 70.21,8 68,8 C68,8 -68,8 -68,8 C-70.21,8 -72,6.21 -72,4 C-72,4 -72,-4 -72,-4 C-72,-6.21 -70.21,-8 -68,-8 C-68,-8 68,-8 68,-8 C70.21,-8 72,-6.21 72,-4c " />
+ </group>
+ <group
+ android:name="_R_G_L_3_G_L_0_G_L_1_G"
+ android:scaleY="0"
+ android:translateX="313.5"
+ android:translateY="798">
+ <path
+ android:name="_R_G_L_3_G_L_0_G_L_1_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M74.5 0 C74.5,0 74.5,0 74.5,0 C74.5,15.45 61.95,28 46.5,28 C46.5,28 -46.5,28 -46.5,28 C-61.95,28 -74.5,15.45 -74.5,0 C-74.5,0 -74.5,0 -74.5,0 C-74.5,-15.45 -61.95,-28 -46.5,-28 C-46.5,-28 46.5,-28 46.5,-28 C61.95,-28 74.5,-15.45 74.5,0c " />
+ </group>
+ <group
+ android:name="_R_G_L_3_G_L_0_G_L_0_G"
+ android:scaleY="0"
+ android:translateX="205.5"
+ android:translateY="61">
+ <path
+ android:name="_R_G_L_3_G_L_0_G_L_0_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#f8f9fa"
+ android:fillType="nonZero"
+ android:pathData=" M171.5 -14 C171.5,-14 171.5,14 171.5,14 C171.5,16.21 169.71,18 167.5,18 C167.5,18 -167.5,18 -167.5,18 C-169.71,18 -171.5,16.21 -171.5,14 C-171.5,14 -171.5,-14 -171.5,-14 C-171.5,-16.21 -169.71,-18 -167.5,-18 C-167.5,-18 167.5,-18 167.5,-18 C169.71,-18 171.5,-16.21 171.5,-14c " />
+ </group>
+ </group>
+ </group>
+ </group>
+ <group
+ android:name="_R_G_L_2_G_N_2_T_0"
+ android:scaleX="0.6"
+ android:scaleY="0"
+ android:translateX="206"
+ android:translateY="395">
+ <group
+ android:name="_R_G_L_2_G"
+ android:scaleX="1.3767699999999998"
+ android:scaleY="1.3767699999999998"
+ android:translateY="-508.163">
+ <group
+ android:name="_R_G_L_2_G_D_0_P_0_G_0_T_0"
+ android:scaleX="0"
+ android:scaleY="0">
+ <path
+ android:name="_R_G_L_2_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#9aa0a6"
+ android:fillType="nonZero"
+ android:pathData=" M0 25 C13.81,25 25,13.81 25,0 C25,-13.81 13.81,-25 0,-25 C-13.81,-25 -25,-13.81 -25,0 C-25,13.81 -13.81,25 0,25c " />
+ </group>
+ </group>
+ </group>
+ <group
+ android:name="_R_G_L_1_G_N_2_T_0"
+ android:scaleX="0.6"
+ android:scaleY="0"
+ android:translateX="206"
+ android:translateY="395">
+ <group
+ android:name="_R_G_L_1_G"
+ android:scaleX="1.39"
+ android:scaleY="1.39"
+ android:translateX="-556.176"
+ android:translateY="-7.307">
+ <path
+ android:name="_R_G_L_1_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="@color/gesture_tutorial_fake_previous_task_view_color"
+ android:fillType="nonZero"
+ android:pathData=" M135 -301 C135,-301 135,311 135,311 C135,319.28 128.28,326 120,326 C120,326 -120,326 -120,326 C-128.28,326 -135,319.28 -135,311 C-135,311 -135,-301 -135,-301 C-135,-309.28 -128.28,-316 -120,-316 C-120,-316 120,-316 120,-316 C128.28,-316 135,-309.28 135,-301c " />
+ </group>
+ </group>
+ <group
+ android:name="_R_G_L_0_G"
+ android:translateX="206"
+ android:translateY="446">
+ <path
+ android:name="_R_G_L_0_G_D_0_P_0"
+ android:fillAlpha="0"
+ android:fillColor="@color/gesture_tutorial_primary_color"
+ android:fillType="nonZero"
+ android:pathData=" M0 406 C21.54,406 39,423.46 39,445 C39,466.54 21.54,484 0,484 C-21.54,484 -39,466.54 -39,445 C-39,423.46 -21.54,406 0,406c " />
+ </group>
+ </group>
+ <group android:name="time_group" />
+ </vector>
+ </aapt:attr>
+</animated-vector> \ No newline at end of file
diff --git a/quickstep/res/drawable/ic_screenshot.xml b/quickstep/res/drawable/ic_screenshot.xml
index 9ee6c44011..d97eae1d15 100644
--- a/quickstep/res/drawable/ic_screenshot.xml
+++ b/quickstep/res/drawable/ic_screenshot.xml
@@ -13,20 +13,11 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="20dp"
- android:height="20dp"
- android:viewportWidth="20"
- android:viewportHeight="20">
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
<path
- android:pathData="M5.8334,1.666H8.3334V3.3327H5.8334V6.666H4.1667V3.3327C4.1667,2.4122 4.9129,1.666 5.8334,1.666Z"
- android:fillColor="#000000"/>
- <path
- android:pathData="M4.1667,13.3327V16.666C4.1667,17.5865 4.9129,18.3327 5.8334,18.3327H8.3334V16.666H5.8334V13.3327H4.1667Z"
- android:fillColor="#000000"/>
- <path
- android:pathData="M14.1667,13.3327V16.666H11.6667V18.3327H14.1667C15.0872,18.3327 15.8334,17.5865 15.8334,16.666V13.3327H14.1667Z"
- android:fillColor="#000000"/>
- <path
- android:pathData="M15.8334,6.666V3.3327C15.8334,2.4122 15.0872,1.666 14.1667,1.666H11.6667V3.3327H14.1667V6.666H15.8334Z"
- android:fillColor="#000000"/>
-</vector> \ No newline at end of file
+ android:fillColor="#FF000000"
+ android:pathData="M17,1.01L7,1c-1.1,0 -2,0.9 -2,2v18c0,1.1 0.9,2 2,2h10c1.1,0 2,-0.9 2,-2L19,3c0,-1.1 -0.9,-1.99 -2,-1.99zM17,21L7,21v-1h10v1zM17,18L7,18L7,6h10v12zM17,4L7,4L7,3h10v1zM9.5,8.5L12,8.5L12,7L8,7v4h1.5zM12,17h4v-4h-1.5v2.5L12,15.5z"/>
+</vector>
diff --git a/quickstep/res/drawable/ic_sysbar_accessibility_button.xml b/quickstep/res/drawable/ic_sysbar_accessibility_button.xml
deleted file mode 100644
index e0d5406810..0000000000
--- a/quickstep/res/drawable/ic_sysbar_accessibility_button.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2018 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.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="21dp"
- android:height="21dp"
- android:viewportWidth="24"
- android:viewportHeight="24">
- <path
- android:pathData="M20.5,6c-2.61,0.7 -5.67,1 -8.5,1S6.11,6.7 3.5,6L3,8c1.86,0.5 4,0.83 6,1v13h2v-6h2v6h2V9c2,-0.17 4.14,-0.5 6,-1L20.5,6zM12,6c1.1,0 2,-0.9 2,-2s-0.9,-2 -2,-2s-2,0.9 -2,2S10.9,6 12,6z"
- android:fillColor="@android:color/white"
- />
-</vector> \ No newline at end of file
diff --git a/quickstep/res/drawable/ic_sysbar_back_kids.xml b/quickstep/res/drawable/ic_sysbar_back_kids.xml
deleted file mode 100644
index ac6d49b7f3..0000000000
--- a/quickstep/res/drawable/ic_sysbar_back_kids.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="24dp"
- android:height="24dp"
- android:viewportWidth="24"
- android:viewportHeight="24">
- <path
- android:fillColor="@android:color/white"
- android:pathData="M21,11.4v1c0,1 -0.8,1.8 -1.8,1.8l0,0h-8.8l2.7,2.7c0.7,0.7 0.7,1.8 0,2.5c0,0 0,0 0,0l-0.7,0.7c-0.7,0.7 -1.8,0.7 -2.5,0c0,0 0,0 0,0l-5.9,-5.9C2.6,13 2.6,11 3.9,9.7l5.9,-5.9c0.7,-0.7 1.8,-0.7 2.5,0c0,0 0,0 0,0l0.7,0.7c0.7,0.7 0.7,1.8 0,2.5c0,0 0,0 0,0l-2.6,2.6h8.7C20.2,9.6 21,10.5 21,11.4z"/>
-</vector>
diff --git a/quickstep/res/drawable/ic_sysbar_home_kids.xml b/quickstep/res/drawable/ic_sysbar_home_kids.xml
deleted file mode 100644
index 2397e70025..0000000000
--- a/quickstep/res/drawable/ic_sysbar_home_kids.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="24dp"
- android:height="24dp"
- android:viewportWidth="24"
- android:viewportHeight="24">
- <path
- android:fillColor="@android:color/white"
- android:pathData="M22.7,11l-7.9,-7c-1.6,-1.4 -3.9,-1.4 -5.5,0L7.4,5.7V4.1C7.4,3.5 6.9,3 6.3,3H5.2C4.5,3 4,3.5 4,4.1c0,0 0,0 0,0v4.6L1.4,11c-0.5,0.4 -0.5,1.1 -0.1,1.5c0,0 0,0 0,0c0.2,0.2 0.5,0.4 0.8,0.4H4v5c0,1.3 1,2.3 2.3,2.3c0,0 0,0 0,0h11.4c1.3,0 2.3,-1 2.3,-2.3v-5h2c0.6,0 1.1,-0.5 1.1,-1.1C23,11.5 22.9,11.2 22.7,11L22.7,11zM14.3,15.6c0,0.6 -0.5,1.1 -1.1,1.2h-2.3c-0.6,0 -1.1,-0.5 -1.1,-1.1v-1.3c0,-0.6 0.5,-1.1 1.1,-1.1c0,0 0,0 0,0h2.3c0.6,0 1.1,0.5 1.1,1.1c0,0 0,0 0,0L14.3,15.6z"/>
-</vector>
diff --git a/quickstep/res/drawable/ic_sysbar_notifications.xml b/quickstep/res/drawable/ic_sysbar_notifications.xml
deleted file mode 100644
index 21fcf90536..0000000000
--- a/quickstep/res/drawable/ic_sysbar_notifications.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="24dp"
- android:height="24dp"
- android:viewportWidth="24"
- android:viewportHeight="24"
- android:tint="?attr/colorControlNormal">
- <path
- android:fillColor="@android:color/white"
- android:pathData="M18,17v-6c0,-3.07 -1.63,-5.64 -4.5,-6.32L13.5,4c0,-0.83 -0.67,-1.5 -1.5,-1.5s-1.5,0.67 -1.5,1.5v0.68C7.64,5.36 6,7.92 6,11v6L4,17v2h16v-2h-2zM16,17L8,17v-6c0,-2.48 1.51,-4.5 4,-4.5s4,2.02 4,4.5v6zM12,22c1.1,0 2,-0.9 2,-2h-4c0,1.1 0.9,2 2,2z"/>
-</vector>
diff --git a/quickstep/res/drawable/ic_sysbar_quick_settings.xml b/quickstep/res/drawable/ic_sysbar_quick_settings.xml
deleted file mode 100644
index 958284d4c4..0000000000
--- a/quickstep/res/drawable/ic_sysbar_quick_settings.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="24dp"
- android:height="24dp"
- android:viewportWidth="24"
- android:viewportHeight="24"
- android:tint="?attr/colorControlNormal">
- <path
- android:fillColor="@android:color/white"
- android:pathData="M13.85,22.25h-3.7c-0.74,0 -1.36,-0.54 -1.45,-1.27l-0.27,-1.89c-0.27,-0.14 -0.53,-0.29 -0.79,-0.46l-1.8,0.72c-0.7,0.26 -1.47,-0.03 -1.81,-0.65L2.2,15.53c-0.35,-0.66 -0.2,-1.44 0.36,-1.88l1.53,-1.19c-0.01,-0.15 -0.02,-0.3 -0.02,-0.46 0,-0.15 0.01,-0.31 0.02,-0.46l-1.52,-1.19c-0.59,-0.45 -0.74,-1.26 -0.37,-1.88l1.85,-3.19c0.34,-0.62 1.11,-0.9 1.79,-0.63l1.81,0.73c0.26,-0.17 0.52,-0.32 0.78,-0.46l0.27,-1.91c0.09,-0.7 0.71,-1.25 1.44,-1.25h3.7c0.74,0 1.36,0.54 1.45,1.27l0.27,1.89c0.27,0.14 0.53,0.29 0.79,0.46l1.8,-0.72c0.71,-0.26 1.48,0.03 1.82,0.65l1.84,3.18c0.36,0.66 0.2,1.44 -0.36,1.88l-1.52,1.19c0.01,0.15 0.02,0.3 0.02,0.46s-0.01,0.31 -0.02,0.46l1.52,1.19c0.56,0.45 0.72,1.23 0.37,1.86l-1.86,3.22c-0.34,0.62 -1.11,0.9 -1.8,0.63l-1.8,-0.72c-0.26,0.17 -0.52,0.32 -0.78,0.46l-0.27,1.91c-0.1,0.68 -0.72,1.22 -1.46,1.22zM10.62,20.25h2.76l0.37,-2.55 0.53,-0.22c0.44,-0.18 0.88,-0.44 1.34,-0.78l0.45,-0.34 2.38,0.96 1.38,-2.4 -2.03,-1.58 0.07,-0.56c0.03,-0.26 0.06,-0.51 0.06,-0.78s-0.03,-0.53 -0.06,-0.78l-0.07,-0.56 2.03,-1.58 -1.39,-2.4 -2.39,0.96 -0.45,-0.35c-0.42,-0.32 -0.87,-0.58 -1.33,-0.77l-0.52,-0.22 -0.37,-2.55h-2.76l-0.37,2.55 -0.53,0.21c-0.44,0.19 -0.88,0.44 -1.34,0.79l-0.45,0.33 -2.38,-0.95 -1.39,2.39 2.03,1.58 -0.07,0.56c-0.03,0.26 -0.06,0.53 -0.06,0.79s0.02,0.53 0.06,0.78l0.07,0.56 -2.03,1.58 1.38,2.4 2.39,-0.96 0.45,0.35c0.43,0.33 0.86,0.58 1.33,0.77l0.53,0.22 0.38,2.55z"/>
- <path
- android:fillColor="@android:color/white"
- android:pathData="M12,12m-3.5,0a3.5,3.5 0,1 1,7 0a3.5,3.5 0,1 1,-7 0"/>
-</vector>
diff --git a/quickstep/res/drawable/ic_sysbar_rotate_button_ccw_start_0.xml b/quickstep/res/drawable/ic_sysbar_rotate_button_ccw_start_0.xml
deleted file mode 100644
index ff5cb9ef6b..0000000000
--- a/quickstep/res/drawable/ic_sysbar_rotate_button_ccw_start_0.xml
+++ /dev/null
@@ -1,187 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2020 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.
--->
-<animated-vector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:aapt="http://schemas.android.com/aapt">
- <aapt:attr name="android:drawable">
- <vector android:name="root"
- android:width="28dp"
- android:height="28dp"
- android:viewportWidth="28.0"
- android:viewportHeight="28.0">
- <!-- Use scaleX to flip icon so arrows always point in the direction of motion -->
- <group android:name="icon" android:pivotX="14" android:pivotY="14"
- android:scaleX="1">
- <!-- Tint color to be set directly -->
- <path android:fillColor="#FFFFFFFF"
- android:pathData="M12.02,10.83L9.25,8.06l2.77,-2.77l1.12,1.12l-0.85,0.86h5.16c0.72,0 1.31,0.56 1.31,1.26v9.16l-1.58,-1.58V8.85h-4.89l0.86,0.86L12.02,10.83zM15.98,17.17l-1.12,1.12l0.85,0.86h-4.88v-7.26L9.25,10.3v9.17c0,0.7 0.59,1.26 1.31,1.26h5.16v0.01l-0.85,0.85l1.12,1.12l2.77,-2.77L15.98,17.17z"/>
- </group>
- </vector>
- </aapt:attr>
-
- <!-- Repeat all animations 5 times but don't fade out at the end -->
- <target android:name="root">
- <aapt:attr name="android:animation">
- <set android:ordering="sequentially">
- <!-- Linear fade in-->
- <objectAnimator android:propertyName="alpha"
- android:duration="100"
- android:valueFrom="0"
- android:valueTo="1"
- android:interpolator="@android:anim/linear_interpolator" />
- <!-- Linear fade out -->
- <objectAnimator android:propertyName="alpha"
- android:duration="100"
- android:startOffset="1700"
- android:valueFrom="1"
- android:valueTo="0"
- android:interpolator="@android:anim/linear_interpolator"/>
- <!-- Linear fade in-->
- <objectAnimator android:propertyName="alpha"
- android:duration="100"
- android:startOffset="100"
- android:valueFrom="0"
- android:valueTo="1"
- android:interpolator="@android:anim/linear_interpolator" />
- <!-- Linear fade out -->
- <objectAnimator android:propertyName="alpha"
- android:duration="100"
- android:startOffset="1700"
- android:valueFrom="1"
- android:valueTo="0"
- android:interpolator="@android:anim/linear_interpolator"/>
- <!-- Linear fade in-->
- <objectAnimator android:propertyName="alpha"
- android:duration="100"
- android:startOffset="100"
- android:valueFrom="0"
- android:valueTo="1"
- android:interpolator="@android:anim/linear_interpolator" />
- <!-- Linear fade out -->
- <objectAnimator android:propertyName="alpha"
- android:duration="100"
- android:startOffset="1700"
- android:valueFrom="1"
- android:valueTo="0"
- android:interpolator="@android:anim/linear_interpolator"/>
- <!-- Linear fade in-->
- <objectAnimator android:propertyName="alpha"
- android:duration="100"
- android:startOffset="100"
- android:valueFrom="0"
- android:valueTo="1"
- android:interpolator="@android:anim/linear_interpolator" />
- <!-- Linear fade out -->
- <objectAnimator android:propertyName="alpha"
- android:duration="100"
- android:startOffset="1700"
- android:valueFrom="1"
- android:valueTo="0"
- android:interpolator="@android:anim/linear_interpolator"/>
- <!-- Linear fade in-->
- <objectAnimator android:propertyName="alpha"
- android:duration="100"
- android:startOffset="100"
- android:valueFrom="0"
- android:valueTo="1"
- android:interpolator="@android:anim/linear_interpolator" />
- </set>
- </aapt:attr>
- </target>
- <target android:name="icon">
- <aapt:attr name="android:animation">
- <set android:ordering="sequentially">
- <!-- Icon rotation with start timing offset after fade in -->
- <objectAnimator android:propertyName="rotation"
- android:startOffset="100"
- android:duration="600"
- android:valueFrom="0"
- android:valueTo="-90">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.408,1.181 0.674,1.08 1.0,1.0"/>
- </aapt:attr>
- </objectAnimator>
-
- <!-- Reset rotation position for fade in -->
- <objectAnimator android:propertyName="rotation"
- android:startOffset="1300"
- android:duration="100"
- android:valueFrom="0"
- android:valueTo="0"/>
-
- <!-- Icon rotation with start timing offset after fade in -->
- <objectAnimator android:propertyName="rotation"
- android:duration="600"
- android:valueFrom="0"
- android:valueTo="-90">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.408,1.181 0.674,1.08 1.0,1.0"/>
- </aapt:attr>
- </objectAnimator>
-
- <!-- Reset rotation position for fade in -->
- <objectAnimator android:propertyName="rotation"
- android:startOffset="1300"
- android:duration="100"
- android:valueFrom="0"
- android:valueTo="0"/>
-
- <!-- Icon rotation with start timing offset after fade in -->
- <objectAnimator android:propertyName="rotation"
- android:duration="600"
- android:valueFrom="0"
- android:valueTo="-90">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.408,1.181 0.674,1.08 1.0,1.0"/>
- </aapt:attr>
- </objectAnimator>
-
- <!-- Reset rotation position for fade in -->
- <objectAnimator android:propertyName="rotation"
- android:startOffset="1300"
- android:duration="100"
- android:valueFrom="0"
- android:valueTo="0"/>
-
- <!-- Icon rotation with start timing offset after fade in -->
- <objectAnimator android:propertyName="rotation"
- android:duration="600"
- android:valueFrom="0"
- android:valueTo="-90">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.408,1.181 0.674,1.08 1.0,1.0"/>
- </aapt:attr>
- </objectAnimator>
-
- <!-- Reset rotation position for fade in -->
- <objectAnimator android:propertyName="rotation"
- android:startOffset="1300"
- android:duration="100"
- android:valueFrom="0"
- android:valueTo="0"/>
-
- <!-- Icon rotation with start timing offset after fade in -->
- <objectAnimator android:propertyName="rotation"
- android:duration="600"
- android:valueFrom="0"
- android:valueTo="-90">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.408,1.181 0.674,1.08 1.0,1.0"/>
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
-</animated-vector> \ No newline at end of file
diff --git a/quickstep/res/drawable/ic_sysbar_rotate_button_ccw_start_90.xml b/quickstep/res/drawable/ic_sysbar_rotate_button_ccw_start_90.xml
deleted file mode 100644
index 90fedb17ec..0000000000
--- a/quickstep/res/drawable/ic_sysbar_rotate_button_ccw_start_90.xml
+++ /dev/null
@@ -1,187 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2020 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.
--->
-<animated-vector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:aapt="http://schemas.android.com/aapt">
- <aapt:attr name="android:drawable">
- <vector android:name="root"
- android:width="28dp"
- android:height="28dp"
- android:viewportWidth="28.0"
- android:viewportHeight="28.0">
- <!-- Use scaleX to flip icon so arrows always point in the direction of motion -->
- <group android:name="icon" android:pivotX="14" android:pivotY="14"
- android:scaleX="1">
- <!-- Tint color to be set directly -->
- <path android:fillColor="#FFFFFFFF"
- android:pathData="M12.02,10.83L9.25,8.06l2.77,-2.77l1.12,1.12l-0.85,0.86h5.16c0.72,0 1.31,0.56 1.31,1.26v9.16l-1.58,-1.58V8.85h-4.89l0.86,0.86L12.02,10.83zM15.98,17.17l-1.12,1.12l0.85,0.86h-4.88v-7.26L9.25,10.3v9.17c0,0.7 0.59,1.26 1.31,1.26h5.16v0.01l-0.85,0.85l1.12,1.12l2.77,-2.77L15.98,17.17z"/>
- </group>
- </vector>
- </aapt:attr>
-
- <!-- Repeat all animations 5 times but don't fade out at the end -->
- <target android:name="root">
- <aapt:attr name="android:animation">
- <set android:ordering="sequentially">
- <!-- Linear fade in-->
- <objectAnimator android:propertyName="alpha"
- android:duration="100"
- android:valueFrom="0"
- android:valueTo="1"
- android:interpolator="@android:anim/linear_interpolator" />
- <!-- Linear fade out -->
- <objectAnimator android:propertyName="alpha"
- android:duration="100"
- android:startOffset="1700"
- android:valueFrom="1"
- android:valueTo="0"
- android:interpolator="@android:anim/linear_interpolator"/>
- <!-- Linear fade in-->
- <objectAnimator android:propertyName="alpha"
- android:duration="100"
- android:startOffset="100"
- android:valueFrom="0"
- android:valueTo="1"
- android:interpolator="@android:anim/linear_interpolator" />
- <!-- Linear fade out -->
- <objectAnimator android:propertyName="alpha"
- android:duration="100"
- android:startOffset="1700"
- android:valueFrom="1"
- android:valueTo="0"
- android:interpolator="@android:anim/linear_interpolator"/>
- <!-- Linear fade in-->
- <objectAnimator android:propertyName="alpha"
- android:duration="100"
- android:startOffset="100"
- android:valueFrom="0"
- android:valueTo="1"
- android:interpolator="@android:anim/linear_interpolator" />
- <!-- Linear fade out -->
- <objectAnimator android:propertyName="alpha"
- android:duration="100"
- android:startOffset="1700"
- android:valueFrom="1"
- android:valueTo="0"
- android:interpolator="@android:anim/linear_interpolator"/>
- <!-- Linear fade in-->
- <objectAnimator android:propertyName="alpha"
- android:duration="100"
- android:startOffset="100"
- android:valueFrom="0"
- android:valueTo="1"
- android:interpolator="@android:anim/linear_interpolator" />
- <!-- Linear fade out -->
- <objectAnimator android:propertyName="alpha"
- android:duration="100"
- android:startOffset="1700"
- android:valueFrom="1"
- android:valueTo="0"
- android:interpolator="@android:anim/linear_interpolator"/>
- <!-- Linear fade in-->
- <objectAnimator android:propertyName="alpha"
- android:duration="100"
- android:startOffset="100"
- android:valueFrom="0"
- android:valueTo="1"
- android:interpolator="@android:anim/linear_interpolator" />
- </set>
- </aapt:attr>
- </target>
- <target android:name="icon">
- <aapt:attr name="android:animation">
- <set android:ordering="sequentially">
- <!-- Icon rotation with start timing offset after fade in -->
- <objectAnimator android:propertyName="rotation"
- android:startOffset="100"
- android:duration="600"
- android:valueFrom="90"
- android:valueTo="0">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.408,1.181 0.674,1.08 1.0,1.0"/>
- </aapt:attr>
- </objectAnimator>
-
- <!-- Reset rotation position for fade in -->
- <objectAnimator android:propertyName="rotation"
- android:startOffset="1300"
- android:duration="100"
- android:valueFrom="90"
- android:valueTo="90"/>
-
- <!-- Icon rotation with start timing offset after fade in -->
- <objectAnimator android:propertyName="rotation"
- android:duration="600"
- android:valueFrom="90"
- android:valueTo="0">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.408,1.181 0.674,1.08 1.0,1.0"/>
- </aapt:attr>
- </objectAnimator>
-
- <!-- Reset rotation position for fade in -->
- <objectAnimator android:propertyName="rotation"
- android:startOffset="1300"
- android:duration="100"
- android:valueFrom="90"
- android:valueTo="90"/>
-
- <!-- Icon rotation with start timing offset after fade in -->
- <objectAnimator android:propertyName="rotation"
- android:duration="600"
- android:valueFrom="90"
- android:valueTo="0">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.408,1.181 0.674,1.08 1.0,1.0"/>
- </aapt:attr>
- </objectAnimator>
-
- <!-- Reset rotation position for fade in -->
- <objectAnimator android:propertyName="rotation"
- android:startOffset="1300"
- android:duration="100"
- android:valueFrom="90"
- android:valueTo="90"/>
-
- <!-- Icon rotation with start timing offset after fade in -->
- <objectAnimator android:propertyName="rotation"
- android:duration="600"
- android:valueFrom="90"
- android:valueTo="0">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.408,1.181 0.674,1.08 1.0,1.0"/>
- </aapt:attr>
- </objectAnimator>
-
- <!-- Reset rotation position for fade in -->
- <objectAnimator android:propertyName="rotation"
- android:startOffset="1300"
- android:duration="100"
- android:valueFrom="90"
- android:valueTo="90"/>
-
- <!-- Icon rotation with start timing offset after fade in -->
- <objectAnimator android:propertyName="rotation"
- android:duration="600"
- android:valueFrom="90"
- android:valueTo="0">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.408,1.181 0.674,1.08 1.0,1.0"/>
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
-</animated-vector> \ No newline at end of file
diff --git a/quickstep/res/drawable/ic_sysbar_rotate_button_cw_start_0.xml b/quickstep/res/drawable/ic_sysbar_rotate_button_cw_start_0.xml
deleted file mode 100644
index a89e7a34ad..0000000000
--- a/quickstep/res/drawable/ic_sysbar_rotate_button_cw_start_0.xml
+++ /dev/null
@@ -1,187 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2020 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.
--->
-<animated-vector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:aapt="http://schemas.android.com/aapt">
- <aapt:attr name="android:drawable">
- <vector android:name="root"
- android:width="28dp"
- android:height="28dp"
- android:viewportWidth="28.0"
- android:viewportHeight="28.0">
- <!-- Use scaleX to flip icon so arrows always point in the direction of motion -->
- <group android:name="icon" android:pivotX="14" android:pivotY="14"
- android:scaleX="-1">
- <!-- Tint color to be set directly -->
- <path android:fillColor="#FFFFFFFF"
- android:pathData="M12.02,10.83L9.25,8.06l2.77,-2.77l1.12,1.12l-0.85,0.86h5.16c0.72,0 1.31,0.56 1.31,1.26v9.16l-1.58,-1.58V8.85h-4.89l0.86,0.86L12.02,10.83zM15.98,17.17l-1.12,1.12l0.85,0.86h-4.88v-7.26L9.25,10.3v9.17c0,0.7 0.59,1.26 1.31,1.26h5.16v0.01l-0.85,0.85l1.12,1.12l2.77,-2.77L15.98,17.17z"/>
- </group>
- </vector>
- </aapt:attr>
-
- <!-- Repeat all animations 5 times but don't fade out at the end -->
- <target android:name="root">
- <aapt:attr name="android:animation">
- <set android:ordering="sequentially">
- <!-- Linear fade in-->
- <objectAnimator android:propertyName="alpha"
- android:duration="100"
- android:valueFrom="0"
- android:valueTo="1"
- android:interpolator="@android:anim/linear_interpolator" />
- <!-- Linear fade out -->
- <objectAnimator android:propertyName="alpha"
- android:duration="100"
- android:startOffset="1700"
- android:valueFrom="1"
- android:valueTo="0"
- android:interpolator="@android:anim/linear_interpolator"/>
- <!-- Linear fade in-->
- <objectAnimator android:propertyName="alpha"
- android:duration="100"
- android:startOffset="100"
- android:valueFrom="0"
- android:valueTo="1"
- android:interpolator="@android:anim/linear_interpolator" />
- <!-- Linear fade out -->
- <objectAnimator android:propertyName="alpha"
- android:duration="100"
- android:startOffset="1700"
- android:valueFrom="1"
- android:valueTo="0"
- android:interpolator="@android:anim/linear_interpolator"/>
- <!-- Linear fade in-->
- <objectAnimator android:propertyName="alpha"
- android:duration="100"
- android:startOffset="100"
- android:valueFrom="0"
- android:valueTo="1"
- android:interpolator="@android:anim/linear_interpolator" />
- <!-- Linear fade out -->
- <objectAnimator android:propertyName="alpha"
- android:duration="100"
- android:startOffset="1700"
- android:valueFrom="1"
- android:valueTo="0"
- android:interpolator="@android:anim/linear_interpolator"/>
- <!-- Linear fade in-->
- <objectAnimator android:propertyName="alpha"
- android:duration="100"
- android:startOffset="100"
- android:valueFrom="0"
- android:valueTo="1"
- android:interpolator="@android:anim/linear_interpolator" />
- <!-- Linear fade out -->
- <objectAnimator android:propertyName="alpha"
- android:duration="100"
- android:startOffset="1700"
- android:valueFrom="1"
- android:valueTo="0"
- android:interpolator="@android:anim/linear_interpolator"/>
- <!-- Linear fade in-->
- <objectAnimator android:propertyName="alpha"
- android:duration="100"
- android:startOffset="100"
- android:valueFrom="0"
- android:valueTo="1"
- android:interpolator="@android:anim/linear_interpolator" />
- </set>
- </aapt:attr>
- </target>
- <target android:name="icon">
- <aapt:attr name="android:animation">
- <set android:ordering="sequentially">
- <!-- Icon rotation with start timing offset after fade in -->
- <objectAnimator android:propertyName="rotation"
- android:startOffset="100"
- android:duration="600"
- android:valueFrom="0"
- android:valueTo="90">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.408,1.181 0.674,1.08 1.0,1.0"/>
- </aapt:attr>
- </objectAnimator>
-
- <!-- Reset rotation position for fade in -->
- <objectAnimator android:propertyName="rotation"
- android:startOffset="1300"
- android:duration="100"
- android:valueFrom="0"
- android:valueTo="0"/>
-
- <!-- Icon rotation with start timing offset after fade in -->
- <objectAnimator android:propertyName="rotation"
- android:duration="600"
- android:valueFrom="0"
- android:valueTo="90">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.408,1.181 0.674,1.08 1.0,1.0"/>
- </aapt:attr>
- </objectAnimator>
-
- <!-- Reset rotation position for fade in -->
- <objectAnimator android:propertyName="rotation"
- android:startOffset="1300"
- android:duration="100"
- android:valueFrom="0"
- android:valueTo="0"/>
-
- <!-- Icon rotation with start timing offset after fade in -->
- <objectAnimator android:propertyName="rotation"
- android:duration="600"
- android:valueFrom="0"
- android:valueTo="90">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.408,1.181 0.674,1.08 1.0,1.0"/>
- </aapt:attr>
- </objectAnimator>
-
- <!-- Reset rotation position for fade in -->
- <objectAnimator android:propertyName="rotation"
- android:startOffset="1300"
- android:duration="100"
- android:valueFrom="0"
- android:valueTo="0"/>
-
- <!-- Icon rotation with start timing offset after fade in -->
- <objectAnimator android:propertyName="rotation"
- android:duration="600"
- android:valueFrom="0"
- android:valueTo="90">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.408,1.181 0.674,1.08 1.0,1.0"/>
- </aapt:attr>
- </objectAnimator>
-
- <!-- Reset rotation position for fade in -->
- <objectAnimator android:propertyName="rotation"
- android:startOffset="1300"
- android:duration="100"
- android:valueFrom="0"
- android:valueTo="0"/>
-
- <!-- Icon rotation with start timing offset after fade in -->
- <objectAnimator android:propertyName="rotation"
- android:duration="600"
- android:valueFrom="0"
- android:valueTo="90">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.408,1.181 0.674,1.08 1.0,1.0"/>
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
-</animated-vector> \ No newline at end of file
diff --git a/quickstep/res/drawable/ic_sysbar_rotate_button_cw_start_90.xml b/quickstep/res/drawable/ic_sysbar_rotate_button_cw_start_90.xml
deleted file mode 100644
index 0dc67b0d22..0000000000
--- a/quickstep/res/drawable/ic_sysbar_rotate_button_cw_start_90.xml
+++ /dev/null
@@ -1,187 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2020 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.
--->
-<animated-vector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:aapt="http://schemas.android.com/aapt">
- <aapt:attr name="android:drawable">
- <vector android:name="root"
- android:width="28dp"
- android:height="28dp"
- android:viewportWidth="28.0"
- android:viewportHeight="28.0">
- <!-- Use scaleX to flip icon so arrows always point in the direction of motion -->
- <group android:name="icon" android:pivotX="14" android:pivotY="14"
- android:scaleX="-1">
- <!-- Tint color to be set directly -->
- <path android:fillColor="#FFFFFFFF"
- android:pathData="M12.02,10.83L9.25,8.06l2.77,-2.77l1.12,1.12l-0.85,0.86h5.16c0.72,0 1.31,0.56 1.31,1.26v9.16l-1.58,-1.58V8.85h-4.89l0.86,0.86L12.02,10.83zM15.98,17.17l-1.12,1.12l0.85,0.86h-4.88v-7.26L9.25,10.3v9.17c0,0.7 0.59,1.26 1.31,1.26h5.16v0.01l-0.85,0.85l1.12,1.12l2.77,-2.77L15.98,17.17z"/>
- </group>
- </vector>
- </aapt:attr>
-
- <!-- Repeat all animations 5 times but don't fade out at the end -->
- <target android:name="root">
- <aapt:attr name="android:animation">
- <set android:ordering="sequentially">
- <!-- Linear fade in-->
- <objectAnimator android:propertyName="alpha"
- android:duration="100"
- android:valueFrom="0"
- android:valueTo="1"
- android:interpolator="@android:anim/linear_interpolator" />
- <!-- Linear fade out -->
- <objectAnimator android:propertyName="alpha"
- android:duration="100"
- android:startOffset="1700"
- android:valueFrom="1"
- android:valueTo="0"
- android:interpolator="@android:anim/linear_interpolator"/>
- <!-- Linear fade in-->
- <objectAnimator android:propertyName="alpha"
- android:duration="100"
- android:startOffset="100"
- android:valueFrom="0"
- android:valueTo="1"
- android:interpolator="@android:anim/linear_interpolator" />
- <!-- Linear fade out -->
- <objectAnimator android:propertyName="alpha"
- android:duration="100"
- android:startOffset="1700"
- android:valueFrom="1"
- android:valueTo="0"
- android:interpolator="@android:anim/linear_interpolator"/>
- <!-- Linear fade in-->
- <objectAnimator android:propertyName="alpha"
- android:duration="100"
- android:startOffset="100"
- android:valueFrom="0"
- android:valueTo="1"
- android:interpolator="@android:anim/linear_interpolator" />
- <!-- Linear fade out -->
- <objectAnimator android:propertyName="alpha"
- android:duration="100"
- android:startOffset="1700"
- android:valueFrom="1"
- android:valueTo="0"
- android:interpolator="@android:anim/linear_interpolator"/>
- <!-- Linear fade in-->
- <objectAnimator android:propertyName="alpha"
- android:duration="100"
- android:startOffset="100"
- android:valueFrom="0"
- android:valueTo="1"
- android:interpolator="@android:anim/linear_interpolator" />
- <!-- Linear fade out -->
- <objectAnimator android:propertyName="alpha"
- android:duration="100"
- android:startOffset="1700"
- android:valueFrom="1"
- android:valueTo="0"
- android:interpolator="@android:anim/linear_interpolator"/>
- <!-- Linear fade in-->
- <objectAnimator android:propertyName="alpha"
- android:duration="100"
- android:startOffset="100"
- android:valueFrom="0"
- android:valueTo="1"
- android:interpolator="@android:anim/linear_interpolator" />
- </set>
- </aapt:attr>
- </target>
- <target android:name="icon">
- <aapt:attr name="android:animation">
- <set android:ordering="sequentially">
- <!-- Icon rotation with start timing offset after fade in -->
- <objectAnimator android:propertyName="rotation"
- android:startOffset="100"
- android:duration="600"
- android:valueFrom="90"
- android:valueTo="180">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.408,1.181 0.674,1.08 1.0,1.0"/>
- </aapt:attr>
- </objectAnimator>
-
- <!-- Reset rotation position for fade in -->
- <objectAnimator android:propertyName="rotation"
- android:startOffset="1300"
- android:duration="100"
- android:valueFrom="90"
- android:valueTo="90"/>
-
- <!-- Icon rotation with start timing offset after fade in -->
- <objectAnimator android:propertyName="rotation"
- android:duration="600"
- android:valueFrom="90"
- android:valueTo="180">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.408,1.181 0.674,1.08 1.0,1.0"/>
- </aapt:attr>
- </objectAnimator>
-
- <!-- Reset rotation position for fade in -->
- <objectAnimator android:propertyName="rotation"
- android:startOffset="1300"
- android:duration="100"
- android:valueFrom="90"
- android:valueTo="90"/>
-
- <!-- Icon rotation with start timing offset after fade in -->
- <objectAnimator android:propertyName="rotation"
- android:duration="600"
- android:valueFrom="90"
- android:valueTo="180">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.408,1.181 0.674,1.08 1.0,1.0"/>
- </aapt:attr>
- </objectAnimator>
-
- <!-- Reset rotation position for fade in -->
- <objectAnimator android:propertyName="rotation"
- android:startOffset="1300"
- android:duration="100"
- android:valueFrom="90"
- android:valueTo="90"/>
-
- <!-- Icon rotation with start timing offset after fade in -->
- <objectAnimator android:propertyName="rotation"
- android:duration="600"
- android:valueFrom="90"
- android:valueTo="180">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.408,1.181 0.674,1.08 1.0,1.0"/>
- </aapt:attr>
- </objectAnimator>
-
- <!-- Reset rotation position for fade in -->
- <objectAnimator android:propertyName="rotation"
- android:startOffset="1300"
- android:duration="100"
- android:valueFrom="90"
- android:valueTo="90"/>
-
- <!-- Icon rotation with start timing offset after fade in -->
- <objectAnimator android:propertyName="rotation"
- android:duration="600"
- android:valueFrom="90"
- android:valueTo="180">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.408,1.181 0.674,1.08 1.0,1.0"/>
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
-</animated-vector> \ No newline at end of file
diff --git a/quickstep/res/drawable/mock_conversation.xml b/quickstep/res/drawable/mock_conversation.xml
new file mode 100644
index 0000000000..272d9ed8a8
--- /dev/null
+++ b/quickstep/res/drawable/mock_conversation.xml
@@ -0,0 +1,212 @@
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:aapt="http://schemas.android.com/aapt">
+ <target android:name="time_group">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="83"
+ android:propertyName="translateX"
+ android:startOffset="0"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <aapt:attr name="android:drawable">
+ <vector
+ android:width="412dp"
+ android:height="892dp"
+ android:viewportHeight="892"
+ android:viewportWidth="412">
+ <group android:name="_R_G">
+ <group
+ android:name="_R_G_L_1_G"
+ android:translateX="206"
+ android:translateY="446">
+ <path
+ android:name="_R_G_L_1_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#dadce0"
+ android:fillType="nonZero"
+ android:pathData=" M206 -446 C206,-446 206,446 206,446 C206,446 -206,446 -206,446 C-206,446 -206,-446 -206,-446 C-206,-446 206,-446 206,-446c " />
+ </group>
+ <group
+ android:name="_R_G_L_0_G"
+ android:pivotX="206"
+ android:pivotY="446"
+ android:scaleX="1"
+ android:scaleY="1">
+ <group android:name="_R_G_L_0_G_L_0_G">
+ <group
+ android:name="_R_G_L_0_G_L_0_G_L_14_G"
+ android:translateX="206"
+ android:translateY="446">
+ <path
+ android:name="_R_G_L_0_G_L_0_G_L_14_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#000000"
+ android:fillType="nonZero"
+ android:pathData=" M206 -422 C206,-422 206,422 206,422 C206,435.25 195.25,446 182,446 C182,446 -182,446 -182,446 C-195.25,446 -206,435.25 -206,422 C-206,422 -206,-422 -206,-422 C-206,-435.25 -195.25,-446 -182,-446 C-182,-446 182,-446 182,-446 C195.25,-446 206,-435.25 206,-422c " />
+ </group>
+ <group
+ android:name="_R_G_L_0_G_L_0_G_L_13_G"
+ android:translateX="206"
+ android:translateY="496.5">
+ <path
+ android:name="_R_G_L_0_G_L_0_G_L_13_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#f1f3f4"
+ android:fillType="nonZero"
+ android:pathData=" M206 -395.5 C206,-395.5 206,395.5 206,395.5 C206,395.5 -206,395.5 -206,395.5 C-206,395.5 -206,-395.5 -206,-395.5 C-206,-395.5 206,-395.5 206,-395.5c " />
+ </group>
+ <group
+ android:name="_R_G_L_0_G_L_0_G_L_12_G"
+ android:translateX="206"
+ android:translateY="50.5">
+ <path
+ android:name="_R_G_L_0_G_L_0_G_L_12_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#e8eaed"
+ android:fillType="nonZero"
+ android:pathData=" M206 -50.5 C206,-50.5 206,50.5 206,50.5 C206,50.5 -206,50.5 -206,50.5 C-206,50.5 -206,-50.5 -206,-50.5 C-206,-50.5 206,-50.5 206,-50.5c " />
+ </group>
+ <group
+ android:name="_R_G_L_0_G_L_0_G_L_11_G"
+ android:translateX="206"
+ android:translateY="804">
+ <path
+ android:name="_R_G_L_0_G_L_0_G_L_11_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#dadce0"
+ android:fillType="nonZero"
+ android:pathData=" M177 0 C177,12.15 167.15,22 155,22 C155,22 -155,22 -155,22 C-167.15,22 -177,12.15 -177,0 C-177,-12.15 -167.15,-22 -155,-22 C-155,-22 155,-22 155,-22 C167.15,-22 177,-12.15 177,0c " />
+ </group>
+ <group
+ android:name="_R_G_L_0_G_L_0_G_L_10_G"
+ android:translateX="117.5"
+ android:translateY="61">
+ <path
+ android:name="_R_G_L_0_G_L_0_G_L_10_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#dadce0"
+ android:fillType="nonZero"
+ android:pathData=" M83.5 -14 C83.5,-14 83.5,14 83.5,14 C83.5,16.21 81.71,18 79.5,18 C79.5,18 -79.5,18 -79.5,18 C-81.71,18 -83.5,16.21 -83.5,14 C-83.5,14 -83.5,-14 -83.5,-14 C-83.5,-16.21 -81.71,-18 -79.5,-18 C-79.5,-18 79.5,-18 79.5,-18 C81.71,-18 83.5,-16.21 83.5,-14c " />
+ </group>
+ <group
+ android:name="_R_G_L_0_G_L_0_G_L_9_G"
+ android:translateX="370"
+ android:translateY="61">
+ <path
+ android:name="_R_G_L_0_G_L_0_G_L_9_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#dadce0"
+ android:fillType="nonZero"
+ android:pathData=" M18 -14 C18,-14 18,14 18,14 C18,16.21 16.21,18 14,18 C14,18 -14,18 -14,18 C-16.21,18 -18,16.21 -18,14 C-18,14 -18,-14 -18,-14 C-18,-16.21 -16.21,-18 -14,-18 C-14,-18 14,-18 14,-18 C16.21,-18 18,-16.21 18,-14c " />
+ </group>
+ <group
+ android:name="_R_G_L_0_G_L_0_G_L_8_G"
+ android:translateX="318"
+ android:translateY="61">
+ <path
+ android:name="_R_G_L_0_G_L_0_G_L_8_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#dadce0"
+ android:fillType="nonZero"
+ android:pathData=" M18 -14 C18,-14 18,14 18,14 C18,16.21 16.21,18 14,18 C14,18 -14,18 -14,18 C-16.21,18 -18,16.21 -18,14 C-18,14 -18,-14 -18,-14 C-18,-16.21 -16.21,-18 -14,-18 C-14,-18 14,-18 14,-18 C16.21,-18 18,-16.21 18,-14c " />
+ </group>
+ <group
+ android:name="_R_G_L_0_G_L_0_G_L_7_G"
+ android:translateX="48"
+ android:translateY="618">
+ <path
+ android:name="_R_G_L_0_G_L_0_G_L_7_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#dadce0"
+ android:fillType="nonZero"
+ android:pathData=" M22 0 C22,12.15 12.15,22 0,22 C-12.15,22 -22,12.15 -22,0 C-22,-12.15 -12.15,-22 0,-22 C12.15,-22 22,-12.15 22,0c " />
+ </group>
+ <group
+ android:name="_R_G_L_0_G_L_0_G_L_6_G"
+ android:translateX="48"
+ android:translateY="396">
+ <path
+ android:name="_R_G_L_0_G_L_0_G_L_6_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#dadce0"
+ android:fillType="nonZero"
+ android:pathData=" M22 0 C22,12.15 12.15,22 0,22 C-12.15,22 -22,12.15 -22,0 C-22,-12.15 -12.15,-22 0,-22 C12.15,-22 22,-12.15 22,0c " />
+ </group>
+ <group
+ android:name="_R_G_L_0_G_L_0_G_L_5_G"
+ android:translateX="259"
+ android:translateY="286">
+ <path
+ android:name="_R_G_L_0_G_L_0_G_L_5_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M135 -38 C135,-38 135,38 135,38 C135,47.94 126.94,56 117,56 C117,56 -117,56 -117,56 C-126.94,56 -135,47.94 -135,38 C-135,38 -135,-38 -135,-38 C-135,-47.94 -126.94,-56 -117,-56 C-117,-56 117,-56 117,-56 C126.94,-56 135,-47.94 135,-38c " />
+ </group>
+ <group
+ android:name="_R_G_L_0_G_L_0_G_L_4_G"
+ android:translateX="259"
+ android:translateY="468">
+ <path
+ android:name="_R_G_L_0_G_L_0_G_L_4_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M134.5 4 C134.5,4 134.5,14 134.5,14 C134.5,16.21 132.71,18 130.5,18 C130.5,18 44.5,18 44.5,18 C42.29,18 40.5,16.21 40.5,14 C40.5,14 40.5,4 40.5,4 C40.5,1.79 42.29,0 44.5,0 C44.5,0 130.5,0 130.5,0 C132.71,0 134.5,1.79 134.5,4c M135 0 C135,9.66 127.17,17.5 117.5,17.5 C117.5,17.5 31,17.5 31,17.5 C21.34,17.5 13.5,9.66 13.5,0 C13.5,-9.66 21.34,-17.5 31,-17.5 C31,-17.5 117.5,-17.5 117.5,-17.5 C127.17,-17.5 135,-9.66 135,0c " />
+ </group>
+ <group
+ android:name="_R_G_L_0_G_L_0_G_L_3_G"
+ android:translateX="259"
+ android:translateY="526.5">
+ <path
+ android:name="_R_G_L_0_G_L_0_G_L_3_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M135 -32.5 C135,-32.5 135,20.5 135,20.5 C135,22.71 133.21,24.5 131,24.5 C131,24.5 -95,24.5 -95,24.5 C-97.21,24.5 -99,22.71 -99,20.5 C-99,20.5 -99,-32.5 -99,-32.5 C-99,-34.71 -97.21,-36.5 -95,-36.5 C-95,-36.5 131,-36.5 131,-36.5 C133.21,-36.5 135,-34.71 135,-32.5c M135 -18.5 C135,-18.5 135,18.5 135,18.5 C135,28.44 126.94,36.5 117,36.5 C117,36.5 -117,36.5 -117,36.5 C-126.94,36.5 -135,28.44 -135,18.5 C-135,18.5 -135,-18.5 -135,-18.5 C-135,-28.44 -126.94,-36.5 -117,-36.5 C-117,-36.5 117,-36.5 117,-36.5 C126.94,-36.5 135,-28.44 135,-18.5c " />
+ </group>
+ <group
+ android:name="_R_G_L_0_G_L_0_G_L_2_G"
+ android:translateX="259"
+ android:translateY="708.5">
+ <path
+ android:name="_R_G_L_0_G_L_0_G_L_2_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M135 -18.5 C135,-18.5 135,18.5 135,18.5 C135,28.44 126.94,36.5 117,36.5 C117,36.5 -117,36.5 -117,36.5 C-126.94,36.5 -135,28.44 -135,18.5 C-135,18.5 -135,-18.5 -135,-18.5 C-135,-28.44 -126.94,-36.5 -117,-36.5 C-117,-36.5 117,-36.5 117,-36.5 C126.94,-36.5 135,-28.44 135,-18.5c " />
+ </group>
+ <group
+ android:name="_R_G_L_0_G_L_0_G_L_1_G"
+ android:translateX="222"
+ android:translateY="617">
+ <path
+ android:name="_R_G_L_0_G_L_0_G_L_1_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#e8eaed"
+ android:fillType="nonZero"
+ android:pathData=" M45.5 0 C45.5,9.66 37.67,17.5 28,17.5 C28,17.5 -117.5,17.5 -117.5,17.5 C-127.16,17.5 -135,9.66 -135,0 C-135,-9.66 -127.16,-17.5 -117.5,-17.5 C-117.5,-17.5 28,-17.5 28,-17.5 C37.67,-17.5 45.5,-9.66 45.5,0c " />
+ </group>
+ <group
+ android:name="_R_G_L_0_G_L_0_G_L_0_G"
+ android:translateX="222"
+ android:translateY="395.5">
+ <path
+ android:name="_R_G_L_0_G_L_0_G_L_0_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#e8eaed"
+ android:fillType="nonZero"
+ android:pathData=" M77 0 C77,9.66 69.16,17.5 59.5,17.5 C59.5,17.5 -117.5,17.5 -117.5,17.5 C-127.16,17.5 -135,9.66 -135,0 C-135,-9.66 -127.16,-17.5 -117.5,-17.5 C-117.5,-17.5 59.5,-17.5 59.5,-17.5 C69.16,-17.5 77,-9.66 77,0c " />
+ </group>
+ </group>
+ </group>
+ </group>
+ <group android:name="time_group" />
+ </vector>
+ </aapt:attr>
+</animated-vector> \ No newline at end of file
diff --git a/quickstep/res/drawable/mock_conversations_list.xml b/quickstep/res/drawable/mock_conversations_list.xml
new file mode 100644
index 0000000000..2dbc88f0bf
--- /dev/null
+++ b/quickstep/res/drawable/mock_conversations_list.xml
@@ -0,0 +1,361 @@
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:aapt="http://schemas.android.com/aapt">
+ <target android:name="time_group">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="83"
+ android:propertyName="translateX"
+ android:startOffset="0"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <aapt:attr name="android:drawable">
+ <vector
+ android:width="412dp"
+ android:height="892dp"
+ android:viewportHeight="892"
+ android:viewportWidth="412">
+ <group android:name="_R_G">
+ <group
+ android:name="_R_G_L_1_G"
+ android:translateX="206"
+ android:translateY="446">
+ <path
+ android:name="_R_G_L_1_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#dadce0"
+ android:fillType="nonZero"
+ android:pathData=" M206 -446 C206,-446 206,446 206,446 C206,446 -206,446 -206,446 C-206,446 -206,-446 -206,-446 C-206,-446 206,-446 206,-446c " />
+ </group>
+ <group android:name="_R_G_L_0_G">
+ <group android:name="_R_G_L_0_G_L_0_G">
+ <group
+ android:name="_R_G_L_0_G_L_0_G_L_28_G"
+ android:translateX="206"
+ android:translateY="446">
+ <path
+ android:name="_R_G_L_0_G_L_0_G_L_28_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#000000"
+ android:fillType="nonZero"
+ android:pathData=" M206 -422 C206,-422 206,422 206,422 C206,435.25 195.25,446 182,446 C182,446 -182,446 -182,446 C-195.25,446 -206,435.25 -206,422 C-206,422 -206,-422 -206,-422 C-206,-435.25 -195.25,-446 -182,-446 C-182,-446 182,-446 182,-446 C195.25,-446 206,-435.25 206,-422c " />
+ </group>
+ <group
+ android:name="_R_G_L_0_G_L_0_G_L_27_G"
+ android:translateX="206"
+ android:translateY="422.5">
+ <path
+ android:name="_R_G_L_0_G_L_0_G_L_27_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#dadce0"
+ android:fillType="nonZero"
+ android:pathData=" M206 -395.5 C206,-395.5 206,395.5 206,395.5 C206,395.5 -206,395.5 -206,395.5 C-206,395.5 -206,-395.5 -206,-395.5 C-206,-395.5 206,-395.5 206,-395.5c " />
+ </group>
+ <group
+ android:name="_R_G_L_0_G_L_0_G_L_26_G"
+ android:translateX="206"
+ android:translateY="496.5">
+ <path
+ android:name="_R_G_L_0_G_L_0_G_L_26_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#dadce0"
+ android:fillType="nonZero"
+ android:pathData=" M206 -377.5 C206,-377.5 206,377.5 206,377.5 C206,387.43 197.93,395.5 188,395.5 C188,395.5 -188,395.5 -188,395.5 C-197.93,395.5 -206,387.43 -206,377.5 C-206,377.5 -206,-377.5 -206,-377.5 C-206,-387.43 -197.93,-395.5 -188,-395.5 C-188,-395.5 188,-395.5 188,-395.5 C197.93,-395.5 206,-387.43 206,-377.5c " />
+ </group>
+ <group
+ android:name="_R_G_L_0_G_L_0_G_L_25_G"
+ android:translateX="206"
+ android:translateY="50.5">
+ <path
+ android:name="_R_G_L_0_G_L_0_G_L_25_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#e8eaed"
+ android:fillType="nonZero"
+ android:pathData=" M206 -23.5 C206,-23.5 206,50.5 206,50.5 C206,50.5 -206,50.5 -206,50.5 C-206,50.5 -206,-23.5 -206,-23.5 C-206,-23.5 206,-23.5 206,-23.5c " />
+ </group>
+ <group
+ android:name="_R_G_L_0_G_L_0_G_L_24_G"
+ android:translateX="206"
+ android:translateY="50.5">
+ <path
+ android:name="_R_G_L_0_G_L_0_G_L_24_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#e8eaed"
+ android:fillType="nonZero"
+ android:pathData=" M206 -32.5 C206,-32.5 206,32.5 206,32.5 C206,42.43 197.93,50.5 188,50.5 C188,50.5 -188,50.5 -188,50.5 C-197.93,50.5 -206,42.43 -206,32.5 C-206,32.5 -206,-32.5 -206,-32.5 C-206,-42.43 -197.93,-50.5 -188,-50.5 C-188,-50.5 188,-50.5 188,-50.5 C197.93,-50.5 206,-42.43 206,-32.5c " />
+ </group>
+ <group
+ android:name="_R_G_L_0_G_L_0_G_L_23_G"
+ android:translateX="54"
+ android:translateY="157">
+ <path
+ android:name="_R_G_L_0_G_L_0_G_L_23_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#9aa0a6"
+ android:fillType="nonZero"
+ android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
+ </group>
+ <group
+ android:name="_R_G_L_0_G_L_0_G_L_22_G"
+ android:translateX="54"
+ android:translateY="157">
+ <path
+ android:name="_R_G_L_0_G_L_0_G_L_22_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#9aa0a6"
+ android:fillType="nonZero"
+ android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
+ </group>
+ <group
+ android:name="_R_G_L_0_G_L_0_G_L_21_G"
+ android:translateX="148.5"
+ android:translateY="148">
+ <path
+ android:name="_R_G_L_0_G_L_0_G_L_21_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M46.5 -5 C46.5,-5 46.5,5 46.5,5 C46.5,7.21 44.71,9 42.5,9 C42.5,9 -42.5,9 -42.5,9 C-44.71,9 -46.5,7.21 -46.5,5 C-46.5,5 -46.5,-5 -46.5,-5 C-46.5,-7.21 -44.71,-9 -42.5,-9 C-42.5,-9 42.5,-9 42.5,-9 C44.71,-9 46.5,-7.21 46.5,-5c " />
+ </group>
+ <group
+ android:name="_R_G_L_0_G_L_0_G_L_20_G"
+ android:translateX="186"
+ android:translateY="169">
+ <path
+ android:name="_R_G_L_0_G_L_0_G_L_20_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M84 -4 C84,-4 84,4 84,4 C84,6.21 82.21,8 80,8 C80,8 -80,8 -80,8 C-82.21,8 -84,6.21 -84,4 C-84,4 -84,-4 -84,-4 C-84,-6.21 -82.21,-8 -80,-8 C-80,-8 80,-8 80,-8 C82.21,-8 84,-6.21 84,-4c " />
+ </group>
+ <group
+ android:name="_R_G_L_0_G_L_0_G_L_19_G"
+ android:translateX="54"
+ android:translateY="245">
+ <path
+ android:name="_R_G_L_0_G_L_0_G_L_19_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#9aa0a6"
+ android:fillType="nonZero"
+ android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
+ </group>
+ <group
+ android:name="_R_G_L_0_G_L_0_G_L_18_G"
+ android:translateX="162"
+ android:translateY="236">
+ <path
+ android:name="_R_G_L_0_G_L_0_G_L_18_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M60 -5 C60,-5 60,5 60,5 C60,7.21 58.21,9 56,9 C56,9 -56,9 -56,9 C-58.21,9 -60,7.21 -60,5 C-60,5 -60,-5 -60,-5 C-60,-7.21 -58.21,-9 -56,-9 C-56,-9 56,-9 56,-9 C58.21,-9 60,-7.21 60,-5c " />
+ </group>
+ <group
+ android:name="_R_G_L_0_G_L_0_G_L_17_G"
+ android:translateX="171.5"
+ android:translateY="257">
+ <path
+ android:name="_R_G_L_0_G_L_0_G_L_17_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M69.5 -4 C69.5,-4 69.5,4 69.5,4 C69.5,6.21 67.71,8 65.5,8 C65.5,8 -65.5,8 -65.5,8 C-67.71,8 -69.5,6.21 -69.5,4 C-69.5,4 -69.5,-4 -69.5,-4 C-69.5,-6.21 -67.71,-8 -65.5,-8 C-65.5,-8 65.5,-8 65.5,-8 C67.71,-8 69.5,-6.21 69.5,-4c " />
+ </group>
+ <group
+ android:name="_R_G_L_0_G_L_0_G_L_16_G"
+ android:translateX="54"
+ android:translateY="333">
+ <path
+ android:name="_R_G_L_0_G_L_0_G_L_16_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#9aa0a6"
+ android:fillType="nonZero"
+ android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
+ </group>
+ <group
+ android:name="_R_G_L_0_G_L_0_G_L_15_G"
+ android:translateX="158"
+ android:translateY="324">
+ <path
+ android:name="_R_G_L_0_G_L_0_G_L_15_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M56 -5 C56,-5 56,5 56,5 C56,7.21 54.21,9 52,9 C52,9 -52,9 -52,9 C-54.21,9 -56,7.21 -56,5 C-56,5 -56,-5 -56,-5 C-56,-7.21 -54.21,-9 -52,-9 C-52,-9 52,-9 52,-9 C54.21,-9 56,-7.21 56,-5c " />
+ </group>
+ <group
+ android:name="_R_G_L_0_G_L_0_G_L_14_G"
+ android:translateX="217.5"
+ android:translateY="345">
+ <path
+ android:name="_R_G_L_0_G_L_0_G_L_14_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M115.5 -4 C115.5,-4 115.5,4 115.5,4 C115.5,6.21 113.71,8 111.5,8 C111.5,8 -111.5,8 -111.5,8 C-113.71,8 -115.5,6.21 -115.5,4 C-115.5,4 -115.5,-4 -115.5,-4 C-115.5,-6.21 -113.71,-8 -111.5,-8 C-111.5,-8 111.5,-8 111.5,-8 C113.71,-8 115.5,-6.21 115.5,-4c " />
+ </group>
+ <group
+ android:name="_R_G_L_0_G_L_0_G_L_13_G"
+ android:translateX="54"
+ android:translateY="421">
+ <path
+ android:name="_R_G_L_0_G_L_0_G_L_13_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#9aa0a6"
+ android:fillType="nonZero"
+ android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
+ </group>
+ <group
+ android:name="_R_G_L_0_G_L_0_G_L_12_G"
+ android:translateX="170"
+ android:translateY="412">
+ <path
+ android:name="_R_G_L_0_G_L_0_G_L_12_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M68 -5 C68,-5 68,5 68,5 C68,7.21 66.21,9 64,9 C64,9 -64,9 -64,9 C-66.21,9 -68,7.21 -68,5 C-68,5 -68,-5 -68,-5 C-68,-7.21 -66.21,-9 -64,-9 C-64,-9 64,-9 64,-9 C66.21,-9 68,-7.21 68,-5c " />
+ </group>
+ <group
+ android:name="_R_G_L_0_G_L_0_G_L_11_G"
+ android:translateX="198.5"
+ android:translateY="433">
+ <path
+ android:name="_R_G_L_0_G_L_0_G_L_11_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M96.5 -4 C96.5,-4 96.5,4 96.5,4 C96.5,6.21 94.71,8 92.5,8 C92.5,8 -92.5,8 -92.5,8 C-94.71,8 -96.5,6.21 -96.5,4 C-96.5,4 -96.5,-4 -96.5,-4 C-96.5,-6.21 -94.71,-8 -92.5,-8 C-92.5,-8 92.5,-8 92.5,-8 C94.71,-8 96.5,-6.21 96.5,-4c " />
+ </group>
+ <group
+ android:name="_R_G_L_0_G_L_0_G_L_10_G"
+ android:translateX="54"
+ android:translateY="509">
+ <path
+ android:name="_R_G_L_0_G_L_0_G_L_10_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#9aa0a6"
+ android:fillType="nonZero"
+ android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
+ </group>
+ <group
+ android:name="_R_G_L_0_G_L_0_G_L_9_G"
+ android:translateX="135"
+ android:translateY="500">
+ <path
+ android:name="_R_G_L_0_G_L_0_G_L_9_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M33 -5 C33,-5 33,5 33,5 C33,7.21 31.21,9 29,9 C29,9 -29,9 -29,9 C-31.21,9 -33,7.21 -33,5 C-33,5 -33,-5 -33,-5 C-33,-7.21 -31.21,-9 -29,-9 C-29,-9 29,-9 29,-9 C31.21,-9 33,-7.21 33,-5c " />
+ </group>
+ <group
+ android:name="_R_G_L_0_G_L_0_G_L_8_G"
+ android:translateX="185.5"
+ android:translateY="521">
+ <path
+ android:name="_R_G_L_0_G_L_0_G_L_8_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M83.5 -4 C83.5,-4 83.5,4 83.5,4 C83.5,6.21 81.71,8 79.5,8 C79.5,8 -79.5,8 -79.5,8 C-81.71,8 -83.5,6.21 -83.5,4 C-83.5,4 -83.5,-4 -83.5,-4 C-83.5,-6.21 -81.71,-8 -79.5,-8 C-79.5,-8 79.5,-8 79.5,-8 C81.71,-8 83.5,-6.21 83.5,-4c " />
+ </group>
+ <group
+ android:name="_R_G_L_0_G_L_0_G_L_7_G"
+ android:translateX="54"
+ android:translateY="597">
+ <path
+ android:name="_R_G_L_0_G_L_0_G_L_7_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#9aa0a6"
+ android:fillType="nonZero"
+ android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
+ </group>
+ <group
+ android:name="_R_G_L_0_G_L_0_G_L_6_G"
+ android:translateX="168.5"
+ android:translateY="588">
+ <path
+ android:name="_R_G_L_0_G_L_0_G_L_6_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M66.5 -5 C66.5,-5 66.5,5 66.5,5 C66.5,7.21 64.71,9 62.5,9 C62.5,9 -62.5,9 -62.5,9 C-64.71,9 -66.5,7.21 -66.5,5 C-66.5,5 -66.5,-5 -66.5,-5 C-66.5,-7.21 -64.71,-9 -62.5,-9 C-62.5,-9 62.5,-9 62.5,-9 C64.71,-9 66.5,-7.21 66.5,-5c " />
+ </group>
+ <group
+ android:name="_R_G_L_0_G_L_0_G_L_5_G"
+ android:translateX="198.5"
+ android:translateY="609">
+ <path
+ android:name="_R_G_L_0_G_L_0_G_L_5_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M96.5 -4 C96.5,-4 96.5,4 96.5,4 C96.5,6.21 94.71,8 92.5,8 C92.5,8 -92.5,8 -92.5,8 C-94.71,8 -96.5,6.21 -96.5,4 C-96.5,4 -96.5,-4 -96.5,-4 C-96.5,-6.21 -94.71,-8 -92.5,-8 C-92.5,-8 92.5,-8 92.5,-8 C94.71,-8 96.5,-6.21 96.5,-4c " />
+ </group>
+ <group
+ android:name="_R_G_L_0_G_L_0_G_L_4_G"
+ android:translateX="54"
+ android:translateY="685">
+ <path
+ android:name="_R_G_L_0_G_L_0_G_L_4_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#9aa0a6"
+ android:fillType="nonZero"
+ android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
+ </group>
+ <group
+ android:name="_R_G_L_0_G_L_0_G_L_3_G"
+ android:translateX="162.5"
+ android:translateY="676">
+ <path
+ android:name="_R_G_L_0_G_L_0_G_L_3_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M60.5 -5 C60.5,-5 60.5,5 60.5,5 C60.5,7.21 58.71,9 56.5,9 C56.5,9 -56.5,9 -56.5,9 C-58.71,9 -60.5,7.21 -60.5,5 C-60.5,5 -60.5,-5 -60.5,-5 C-60.5,-7.21 -58.71,-9 -56.5,-9 C-56.5,-9 56.5,-9 56.5,-9 C58.71,-9 60.5,-7.21 60.5,-5c " />
+ </group>
+ <group
+ android:name="_R_G_L_0_G_L_0_G_L_2_G"
+ android:translateX="174"
+ android:translateY="697">
+ <path
+ android:name="_R_G_L_0_G_L_0_G_L_2_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M72 -4 C72,-4 72,4 72,4 C72,6.21 70.21,8 68,8 C68,8 -68,8 -68,8 C-70.21,8 -72,6.21 -72,4 C-72,4 -72,-4 -72,-4 C-72,-6.21 -70.21,-8 -68,-8 C-68,-8 68,-8 68,-8 C70.21,-8 72,-6.21 72,-4c " />
+ </group>
+ <group
+ android:name="_R_G_L_0_G_L_0_G_L_1_G"
+ android:translateX="313.5"
+ android:translateY="798">
+ <path
+ android:name="_R_G_L_0_G_L_0_G_L_1_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M74.5 0 C74.5,0 74.5,0 74.5,0 C74.5,15.45 61.95,28 46.5,28 C46.5,28 -46.5,28 -46.5,28 C-61.95,28 -74.5,15.45 -74.5,0 C-74.5,0 -74.5,0 -74.5,0 C-74.5,-15.45 -61.95,-28 -46.5,-28 C-46.5,-28 46.5,-28 46.5,-28 C61.95,-28 74.5,-15.45 74.5,0c " />
+ </group>
+ <group
+ android:name="_R_G_L_0_G_L_0_G_L_0_G"
+ android:translateX="205.5"
+ android:translateY="61">
+ <path
+ android:name="_R_G_L_0_G_L_0_G_L_0_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#f8f9fa"
+ android:fillType="nonZero"
+ android:pathData=" M171.5 -14 C171.5,-14 171.5,14 171.5,14 C171.5,16.21 169.71,18 167.5,18 C167.5,18 -167.5,18 -167.5,18 C-169.71,18 -171.5,16.21 -171.5,14 C-171.5,14 -171.5,-14 -171.5,-14 C-171.5,-16.21 -169.71,-18 -167.5,-18 C-167.5,-18 167.5,-18 167.5,-18 C169.71,-18 171.5,-16.21 171.5,-14c " />
+ </group>
+ </group>
+ </group>
+ </group>
+ <group android:name="time_group" />
+ </vector>
+ </aapt:attr>
+</animated-vector> \ No newline at end of file
diff --git a/quickstep/res/drawable/mock_webpage_dark_mode.xml b/quickstep/res/drawable/mock_webpage_dark_mode.xml
new file mode 100644
index 0000000000..93b22b7d31
--- /dev/null
+++ b/quickstep/res/drawable/mock_webpage_dark_mode.xml
@@ -0,0 +1,251 @@
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:aapt="http://schemas.android.com/aapt">
+ <target android:name="time_group">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="83"
+ android:propertyName="translateX"
+ android:startOffset="0"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <aapt:attr name="android:drawable">
+ <vector
+ android:width="412dp"
+ android:height="892dp"
+ android:viewportHeight="892"
+ android:viewportWidth="412">
+ <group android:name="_R_G">
+ <group android:name="_R_G_L_0_G">
+ <group android:name="_R_G_L_0_G_L_3_G">
+ <group
+ android:name="_R_G_L_0_G_L_3_G_L_11_G"
+ android:scaleX="0.87473"
+ android:scaleY="0.98643"
+ android:translateX="206"
+ android:translateY="472.769">
+ <path
+ android:name="_R_G_L_0_G_L_3_G_L_11_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#dadce0"
+ android:fillType="nonZero"
+ android:pathData=" M235.5 -407 C235.5,-407 235.5,407 235.5,407 C235.5,416.93 227.43,425 217.5,425 C217.5,425 -217.5,425 -217.5,425 C-227.43,425 -235.5,416.93 -235.5,407 C-235.5,407 -235.5,-407 -235.5,-407 C-235.5,-416.93 -227.43,-425 -217.5,-425 C-217.5,-425 217.5,-425 217.5,-425 C227.43,-425 235.5,-416.93 235.5,-407c " />
+ </group>
+ <group
+ android:name="_R_G_L_0_G_L_3_G_L_10_G"
+ android:translateX="182.5"
+ android:translateY="831">
+ <path
+ android:name="_R_G_L_0_G_L_3_G_L_10_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M158.5 -3 C158.5,-3 158.5,3 158.5,3 C158.5,7.42 154.92,11 150.5,11 C150.5,11 -150.5,11 -150.5,11 C-154.92,11 -158.5,7.42 -158.5,3 C-158.5,3 -158.5,-3 -158.5,-3 C-158.5,-7.42 -154.92,-11 -150.5,-11 C-150.5,-11 150.5,-11 150.5,-11 C154.92,-11 158.5,-7.42 158.5,-3c " />
+ </group>
+ <group
+ android:name="_R_G_L_0_G_L_3_G_L_9_G"
+ android:translateX="186"
+ android:translateY="801">
+ <path
+ android:name="_R_G_L_0_G_L_3_G_L_9_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M162 -3 C162,-3 162,3 162,3 C162,7.42 158.42,11 154,11 C154,11 -154,11 -154,11 C-158.42,11 -162,7.42 -162,3 C-162,3 -162,-3 -162,-3 C-162,-7.42 -158.42,-11 -154,-11 C-154,-11 154,-11 154,-11 C158.42,-11 162,-7.42 162,-3c " />
+ </group>
+ <group
+ android:name="_R_G_L_0_G_L_3_G_L_8_G"
+ android:translateX="119"
+ android:translateY="755">
+ <path
+ android:name="_R_G_L_0_G_L_3_G_L_8_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M95 -3 C95,-3 95,3 95,3 C95,7.42 91.42,11 87,11 C87,11 -87,11 -87,11 C-91.42,11 -95,7.42 -95,3 C-95,3 -95,-3 -95,-3 C-95,-7.42 -91.42,-11 -87,-11 C-87,-11 87,-11 87,-11 C91.42,-11 95,-7.42 95,-3c " />
+ </group>
+ <group
+ android:name="_R_G_L_0_G_L_3_G_L_7_G"
+ android:translateX="182.5"
+ android:translateY="725">
+ <path
+ android:name="_R_G_L_0_G_L_3_G_L_7_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M158.5 -3 C158.5,-3 158.5,3 158.5,3 C158.5,7.42 154.92,11 150.5,11 C150.5,11 -150.5,11 -150.5,11 C-154.92,11 -158.5,7.42 -158.5,3 C-158.5,3 -158.5,-3 -158.5,-3 C-158.5,-7.42 -154.92,-11 -150.5,-11 C-150.5,-11 150.5,-11 150.5,-11 C154.92,-11 158.5,-7.42 158.5,-3c " />
+ </group>
+ <group
+ android:name="_R_G_L_0_G_L_3_G_L_6_G"
+ android:translateX="197.5"
+ android:translateY="695">
+ <path
+ android:name="_R_G_L_0_G_L_3_G_L_6_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M173.5 -3 C173.5,-3 173.5,3 173.5,3 C173.5,7.42 169.92,11 165.5,11 C165.5,11 -165.5,11 -165.5,11 C-169.92,11 -173.5,7.42 -173.5,3 C-173.5,3 -173.5,-3 -173.5,-3 C-173.5,-7.42 -169.92,-11 -165.5,-11 C-165.5,-11 165.5,-11 165.5,-11 C169.92,-11 173.5,-7.42 173.5,-3c " />
+ </group>
+ <group
+ android:name="_R_G_L_0_G_L_3_G_L_5_G"
+ android:translateX="192"
+ android:translateY="665">
+ <path
+ android:name="_R_G_L_0_G_L_3_G_L_5_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M168 -3 C168,-3 168,3 168,3 C168,7.42 164.42,11 160,11 C160,11 -160,11 -160,11 C-164.42,11 -168,7.42 -168,3 C-168,3 -168,-3 -168,-3 C-168,-7.42 -164.42,-11 -160,-11 C-160,-11 160,-11 160,-11 C164.42,-11 168,-7.42 168,-3c " />
+ </group>
+ <group
+ android:name="_R_G_L_0_G_L_3_G_L_4_G"
+ android:translateX="105.5"
+ android:translateY="360">
+ <path
+ android:name="_R_G_L_0_G_L_3_G_L_4_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M23.5 -2 C23.5,-2 23.5,2 23.5,2 C23.5,4.21 21.71,6 19.5,6 C19.5,6 -19.5,6 -19.5,6 C-21.71,6 -23.5,4.21 -23.5,2 C-23.5,2 -23.5,-2 -23.5,-2 C-23.5,-4.21 -21.71,-6 -19.5,-6 C-19.5,-6 19.5,-6 19.5,-6 C21.71,-6 23.5,-4.21 23.5,-2c " />
+ </group>
+ <group
+ android:name="_R_G_L_0_G_L_3_G_L_3_G"
+ android:translateX="47.5"
+ android:translateY="360">
+ <path
+ android:name="_R_G_L_0_G_L_3_G_L_3_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M23.5 -2 C23.5,-2 23.5,2 23.5,2 C23.5,4.21 21.71,6 19.5,6 C19.5,6 -19.5,6 -19.5,6 C-21.71,6 -23.5,4.21 -23.5,2 C-23.5,2 -23.5,-2 -23.5,-2 C-23.5,-4.21 -21.71,-6 -19.5,-6 C-19.5,-6 19.5,-6 19.5,-6 C21.71,-6 23.5,-4.21 23.5,-2c " />
+ </group>
+ <group
+ android:name="_R_G_L_0_G_L_3_G_L_2_G"
+ android:translateX="142.5"
+ android:translateY="328">
+ <path
+ android:name="_R_G_L_0_G_L_3_G_L_2_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M118.5 -10 C118.5,-10 118.5,10 118.5,10 C118.5,14.42 114.92,18 110.5,18 C110.5,18 -110.5,18 -110.5,18 C-114.92,18 -118.5,14.42 -118.5,10 C-118.5,10 -118.5,-10 -118.5,-10 C-118.5,-14.42 -114.92,-18 -110.5,-18 C-110.5,-18 110.5,-18 110.5,-18 C114.92,-18 118.5,-14.42 118.5,-10c " />
+ </group>
+ <group
+ android:name="_R_G_L_0_G_L_3_G_L_1_G"
+ android:translateX="186"
+ android:translateY="284">
+ <path
+ android:name="_R_G_L_0_G_L_3_G_L_1_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M162 -10 C162,-10 162,10 162,10 C162,14.42 158.42,18 154,18 C154,18 -154,18 -154,18 C-158.42,18 -162,14.42 -162,10 C-162,10 -162,-10 -162,-10 C-162,-14.42 -158.42,-18 -154,-18 C-154,-18 154,-18 154,-18 C158.42,-18 162,-14.42 162,-10c " />
+ </group>
+ <group
+ android:name="_R_G_L_0_G_L_3_G_L_0_G"
+ android:translateX="155"
+ android:translateY="240">
+ <path
+ android:name="_R_G_L_0_G_L_3_G_L_0_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M131 -10 C131,-10 131,10 131,10 C131,14.42 127.42,18 123,18 C123,18 -123,18 -123,18 C-127.42,18 -131,14.42 -131,10 C-131,10 -131,-10 -131,-10 C-131,-14.42 -127.42,-18 -123,-18 C-123,-18 123,-18 123,-18 C127.42,-18 131,-14.42 131,-10c " />
+ </group>
+ </group>
+ <group
+ android:name="_R_G_L_0_G_L_2_G"
+ android:translateX="24"
+ android:translateY="390">
+ <group
+ android:name="_R_G_L_0_G_L_2_G_L_0_G"
+ android:translateX="182"
+ android:translateY="120">
+ <path
+ android:name="_R_G_L_0_G_L_2_G_L_0_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M182 -98 C182,-98 182,98 182,98 C182,110.14 172.14,120 160,120 C160,120 -160,120 -160,120 C-172.14,120 -182,110.14 -182,98 C-182,98 -182,-98 -182,-98 C-182,-110.14 -172.14,-120 -160,-120 C-160,-120 160,-120 160,-120 C172.14,-120 182,-110.14 182,-98c " />
+ </group>
+ </group>
+ <group android:name="_R_G_L_0_G_L_1_G">
+ <group
+ android:name="_R_G_L_0_G_L_1_G_L_2_G"
+ android:translateX="206"
+ android:translateY="145">
+ <path
+ android:name="_R_G_L_0_G_L_1_G_L_2_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#e8eaed"
+ android:fillType="nonZero"
+ android:pathData=" M206 -95.63 C206,-95.63 206,42.37 206,42.37 C206,43.47 205.1,44.37 204,44.37 C204,44.37 -204,44.37 -204,44.37 C-205.1,44.37 -206,43.47 -206,42.37 C-206,42.37 -206,-95.63 -206,-95.63 C-206,-96.73 -205.1,-97.63 -204,-97.63 C-204,-97.63 204,-97.63 204,-97.63 C205.1,-97.63 206,-96.73 206,-95.63c " />
+ </group>
+ <group
+ android:name="_R_G_L_0_G_L_1_G_L_1_G"
+ android:translateX="206"
+ android:translateY="145">
+ <path
+ android:name="_R_G_L_0_G_L_1_G_L_1_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#80868b"
+ android:fillType="nonZero"
+ android:pathData=" M109 -14 C109,-14 109,14 109,14 C109,15.1 108.1,16 107,16 C107,16 -107,16 -107,16 C-108.1,16 -109,15.1 -109,14 C-109,14 -109,-14 -109,-14 C-109,-15.1 -108.1,-16 -107,-16 C-107,-16 107,-16 107,-16 C108.1,-16 109,-15.1 109,-14c " />
+ </group>
+ <group
+ android:name="_R_G_L_0_G_L_1_G_L_0_G"
+ android:translateX="46"
+ android:translateY="145">
+ <path
+ android:name="_R_G_L_0_G_L_1_G_L_0_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#80868b"
+ android:fillType="nonZero"
+ android:pathData=" M22 -14 C22,-14 22,14 22,14 C22,18.42 18.42,22 14,22 C14,22 -14,22 -14,22 C-18.42,22 -22,18.42 -22,14 C-22,14 -22,-14 -22,-14 C-22,-18.42 -18.42,-22 -14,-22 C-14,-22 14,-22 14,-22 C18.42,-22 22,-18.42 22,-14c " />
+ </group>
+ </group>
+ <group android:name="_R_G_L_0_G_L_0_G">
+ <group
+ android:name="_R_G_L_0_G_L_0_G_L_2_G"
+ android:translateX="206"
+ android:translateY="51">
+ <path
+ android:name="_R_G_L_0_G_L_0_G_L_2_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#202124"
+ android:fillType="nonZero"
+ android:pathData=" M206 -0.27 C206,-0.27 206,49.73 206,49.73 C206,49.73 -206,49.73 -206,49.73 C-206,49.73 -206,-0.27 -206,-0.27 C-206,-0.27 206,-0.27 206,-0.27c " />
+ </group>
+ <group
+ android:name="_R_G_L_0_G_L_0_G_L_1_G"
+ android:translateX="206"
+ android:translateY="50.5">
+ <path
+ android:name="_R_G_L_0_G_L_0_G_L_1_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#202124"
+ android:fillType="nonZero"
+ android:pathData=" M206 -32.5 C206,-32.5 206,32.5 206,32.5 C206,42.43 197.93,50.5 188,50.5 C188,50.5 -188,50.5 -188,50.5 C-197.93,50.5 -206,42.43 -206,32.5 C-206,32.5 -206,-32.5 -206,-32.5 C-206,-42.43 -197.93,-50.5 -188,-50.5 C-188,-50.5 188,-50.5 188,-50.5 C197.93,-50.5 206,-42.43 206,-32.5c " />
+ </group>
+ <group
+ android:name="_R_G_L_0_G_L_0_G_L_0_G"
+ android:translateX="206"
+ android:translateY="66.5">
+ <path
+ android:name="_R_G_L_0_G_L_0_G_L_0_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#3c4043"
+ android:fillType="nonZero"
+ android:pathData=" M190 0 C190,0 190,0 190,0 C190,10.21 181.71,18.5 171.5,18.5 C171.5,18.5 -171.5,18.5 -171.5,18.5 C-181.71,18.5 -190,10.21 -190,0 C-190,0 -190,0 -190,0 C-190,-10.21 -181.71,-18.5 -171.5,-18.5 C-171.5,-18.5 171.5,-18.5 171.5,-18.5 C181.71,-18.5 190,-10.21 190,0c " />
+ </group>
+ </group>
+ </group>
+ </group>
+ <group android:name="time_group" />
+ </vector>
+ </aapt:attr>
+</animated-vector> \ No newline at end of file
diff --git a/quickstep/res/drawable/mock_webpage_light_mode.xml b/quickstep/res/drawable/mock_webpage_light_mode.xml
new file mode 100644
index 0000000000..98abb92ab7
--- /dev/null
+++ b/quickstep/res/drawable/mock_webpage_light_mode.xml
@@ -0,0 +1,263 @@
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:aapt="http://schemas.android.com/aapt">
+ <target android:name="time_group">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="83"
+ android:propertyName="translateX"
+ android:startOffset="0"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <aapt:attr name="android:drawable">
+ <vector
+ android:width="412dp"
+ android:height="892dp"
+ android:viewportHeight="892"
+ android:viewportWidth="412">
+ <group android:name="_R_G">
+ <group android:name="_R_G_L_0_G">
+ <group android:name="_R_G_L_0_G_L_4_G">
+ <group
+ android:name="_R_G_L_0_G_L_4_G_L_11_G"
+ android:scaleX="0.87473"
+ android:scaleY="0.98643"
+ android:translateX="206"
+ android:translateY="472.769">
+ <path
+ android:name="_R_G_L_0_G_L_4_G_L_11_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#dadce0"
+ android:fillType="nonZero"
+ android:pathData=" M235.5 -407 C235.5,-407 235.5,407 235.5,407 C235.5,416.93 227.43,425 217.5,425 C217.5,425 -217.5,425 -217.5,425 C-227.43,425 -235.5,416.93 -235.5,407 C-235.5,407 -235.5,-407 -235.5,-407 C-235.5,-416.93 -227.43,-425 -217.5,-425 C-217.5,-425 217.5,-425 217.5,-425 C227.43,-425 235.5,-416.93 235.5,-407c " />
+ </group>
+ <group
+ android:name="_R_G_L_0_G_L_4_G_L_10_G"
+ android:translateX="182.5"
+ android:translateY="831">
+ <path
+ android:name="_R_G_L_0_G_L_4_G_L_10_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M158.5 -3 C158.5,-3 158.5,3 158.5,3 C158.5,7.42 154.92,11 150.5,11 C150.5,11 -150.5,11 -150.5,11 C-154.92,11 -158.5,7.42 -158.5,3 C-158.5,3 -158.5,-3 -158.5,-3 C-158.5,-7.42 -154.92,-11 -150.5,-11 C-150.5,-11 150.5,-11 150.5,-11 C154.92,-11 158.5,-7.42 158.5,-3c " />
+ </group>
+ <group
+ android:name="_R_G_L_0_G_L_4_G_L_9_G"
+ android:translateX="186"
+ android:translateY="801">
+ <path
+ android:name="_R_G_L_0_G_L_4_G_L_9_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M162 -3 C162,-3 162,3 162,3 C162,7.42 158.42,11 154,11 C154,11 -154,11 -154,11 C-158.42,11 -162,7.42 -162,3 C-162,3 -162,-3 -162,-3 C-162,-7.42 -158.42,-11 -154,-11 C-154,-11 154,-11 154,-11 C158.42,-11 162,-7.42 162,-3c " />
+ </group>
+ <group
+ android:name="_R_G_L_0_G_L_4_G_L_8_G"
+ android:translateX="119"
+ android:translateY="755">
+ <path
+ android:name="_R_G_L_0_G_L_4_G_L_8_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M95 -3 C95,-3 95,3 95,3 C95,7.42 91.42,11 87,11 C87,11 -87,11 -87,11 C-91.42,11 -95,7.42 -95,3 C-95,3 -95,-3 -95,-3 C-95,-7.42 -91.42,-11 -87,-11 C-87,-11 87,-11 87,-11 C91.42,-11 95,-7.42 95,-3c " />
+ </group>
+ <group
+ android:name="_R_G_L_0_G_L_4_G_L_7_G"
+ android:translateX="182.5"
+ android:translateY="725">
+ <path
+ android:name="_R_G_L_0_G_L_4_G_L_7_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M158.5 -3 C158.5,-3 158.5,3 158.5,3 C158.5,7.42 154.92,11 150.5,11 C150.5,11 -150.5,11 -150.5,11 C-154.92,11 -158.5,7.42 -158.5,3 C-158.5,3 -158.5,-3 -158.5,-3 C-158.5,-7.42 -154.92,-11 -150.5,-11 C-150.5,-11 150.5,-11 150.5,-11 C154.92,-11 158.5,-7.42 158.5,-3c " />
+ </group>
+ <group
+ android:name="_R_G_L_0_G_L_4_G_L_6_G"
+ android:translateX="197.5"
+ android:translateY="695">
+ <path
+ android:name="_R_G_L_0_G_L_4_G_L_6_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M173.5 -3 C173.5,-3 173.5,3 173.5,3 C173.5,7.42 169.92,11 165.5,11 C165.5,11 -165.5,11 -165.5,11 C-169.92,11 -173.5,7.42 -173.5,3 C-173.5,3 -173.5,-3 -173.5,-3 C-173.5,-7.42 -169.92,-11 -165.5,-11 C-165.5,-11 165.5,-11 165.5,-11 C169.92,-11 173.5,-7.42 173.5,-3c " />
+ </group>
+ <group
+ android:name="_R_G_L_0_G_L_4_G_L_5_G"
+ android:translateX="192"
+ android:translateY="665">
+ <path
+ android:name="_R_G_L_0_G_L_4_G_L_5_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M168 -3 C168,-3 168,3 168,3 C168,7.42 164.42,11 160,11 C160,11 -160,11 -160,11 C-164.42,11 -168,7.42 -168,3 C-168,3 -168,-3 -168,-3 C-168,-7.42 -164.42,-11 -160,-11 C-160,-11 160,-11 160,-11 C164.42,-11 168,-7.42 168,-3c " />
+ </group>
+ <group
+ android:name="_R_G_L_0_G_L_4_G_L_4_G"
+ android:translateX="105.5"
+ android:translateY="360">
+ <path
+ android:name="_R_G_L_0_G_L_4_G_L_4_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M23.5 -2 C23.5,-2 23.5,2 23.5,2 C23.5,4.21 21.71,6 19.5,6 C19.5,6 -19.5,6 -19.5,6 C-21.71,6 -23.5,4.21 -23.5,2 C-23.5,2 -23.5,-2 -23.5,-2 C-23.5,-4.21 -21.71,-6 -19.5,-6 C-19.5,-6 19.5,-6 19.5,-6 C21.71,-6 23.5,-4.21 23.5,-2c " />
+ </group>
+ <group
+ android:name="_R_G_L_0_G_L_4_G_L_3_G"
+ android:translateX="47.5"
+ android:translateY="360">
+ <path
+ android:name="_R_G_L_0_G_L_4_G_L_3_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M23.5 -2 C23.5,-2 23.5,2 23.5,2 C23.5,4.21 21.71,6 19.5,6 C19.5,6 -19.5,6 -19.5,6 C-21.71,6 -23.5,4.21 -23.5,2 C-23.5,2 -23.5,-2 -23.5,-2 C-23.5,-4.21 -21.71,-6 -19.5,-6 C-19.5,-6 19.5,-6 19.5,-6 C21.71,-6 23.5,-4.21 23.5,-2c " />
+ </group>
+ <group
+ android:name="_R_G_L_0_G_L_4_G_L_2_G"
+ android:translateX="142.5"
+ android:translateY="328">
+ <path
+ android:name="_R_G_L_0_G_L_4_G_L_2_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M118.5 -10 C118.5,-10 118.5,10 118.5,10 C118.5,14.42 114.92,18 110.5,18 C110.5,18 -110.5,18 -110.5,18 C-114.92,18 -118.5,14.42 -118.5,10 C-118.5,10 -118.5,-10 -118.5,-10 C-118.5,-14.42 -114.92,-18 -110.5,-18 C-110.5,-18 110.5,-18 110.5,-18 C114.92,-18 118.5,-14.42 118.5,-10c " />
+ </group>
+ <group
+ android:name="_R_G_L_0_G_L_4_G_L_1_G"
+ android:translateX="186"
+ android:translateY="284">
+ <path
+ android:name="_R_G_L_0_G_L_4_G_L_1_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M162 -10 C162,-10 162,10 162,10 C162,14.42 158.42,18 154,18 C154,18 -154,18 -154,18 C-158.42,18 -162,14.42 -162,10 C-162,10 -162,-10 -162,-10 C-162,-14.42 -158.42,-18 -154,-18 C-154,-18 154,-18 154,-18 C158.42,-18 162,-14.42 162,-10c " />
+ </group>
+ <group
+ android:name="_R_G_L_0_G_L_4_G_L_0_G"
+ android:translateX="155"
+ android:translateY="240">
+ <path
+ android:name="_R_G_L_0_G_L_4_G_L_0_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M131 -10 C131,-10 131,10 131,10 C131,14.42 127.42,18 123,18 C123,18 -123,18 -123,18 C-127.42,18 -131,14.42 -131,10 C-131,10 -131,-10 -131,-10 C-131,-14.42 -127.42,-18 -123,-18 C-123,-18 123,-18 123,-18 C127.42,-18 131,-14.42 131,-10c " />
+ </group>
+ </group>
+ <group
+ android:name="_R_G_L_0_G_L_3_G"
+ android:translateX="24"
+ android:translateY="390">
+ <group
+ android:name="_R_G_L_0_G_L_3_G_L_0_G"
+ android:translateX="182"
+ android:translateY="120">
+ <path
+ android:name="_R_G_L_0_G_L_3_G_L_0_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M182 -98 C182,-98 182,98 182,98 C182,110.14 172.14,120 160,120 C160,120 -160,120 -160,120 C-172.14,120 -182,110.14 -182,98 C-182,98 -182,-98 -182,-98 C-182,-110.14 -172.14,-120 -160,-120 C-160,-120 160,-120 160,-120 C172.14,-120 182,-110.14 182,-98c " />
+ </group>
+ </group>
+ <group android:name="_R_G_L_0_G_L_2_G">
+ <group
+ android:name="_R_G_L_0_G_L_2_G_L_2_G"
+ android:translateX="206"
+ android:translateY="145">
+ <path
+ android:name="_R_G_L_0_G_L_2_G_L_2_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#e8eaed"
+ android:fillType="nonZero"
+ android:pathData=" M206 -95.63 C206,-95.63 206,42.37 206,42.37 C206,43.47 205.1,44.37 204,44.37 C204,44.37 -204,44.37 -204,44.37 C-205.1,44.37 -206,43.47 -206,42.37 C-206,42.37 -206,-95.63 -206,-95.63 C-206,-96.73 -205.1,-97.63 -204,-97.63 C-204,-97.63 204,-97.63 204,-97.63 C205.1,-97.63 206,-96.73 206,-95.63c " />
+ </group>
+ <group
+ android:name="_R_G_L_0_G_L_2_G_L_1_G"
+ android:translateX="206"
+ android:translateY="145">
+ <path
+ android:name="_R_G_L_0_G_L_2_G_L_1_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#80868b"
+ android:fillType="nonZero"
+ android:pathData=" M109 -14 C109,-14 109,14 109,14 C109,15.1 108.1,16 107,16 C107,16 -107,16 -107,16 C-108.1,16 -109,15.1 -109,14 C-109,14 -109,-14 -109,-14 C-109,-15.1 -108.1,-16 -107,-16 C-107,-16 107,-16 107,-16 C108.1,-16 109,-15.1 109,-14c " />
+ </group>
+ <group
+ android:name="_R_G_L_0_G_L_2_G_L_0_G"
+ android:translateX="46"
+ android:translateY="145">
+ <path
+ android:name="_R_G_L_0_G_L_2_G_L_0_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#80868b"
+ android:fillType="nonZero"
+ android:pathData=" M22 -14 C22,-14 22,14 22,14 C22,18.42 18.42,22 14,22 C14,22 -14,22 -14,22 C-18.42,22 -22,18.42 -22,14 C-22,14 -22,-14 -22,-14 C-22,-18.42 -18.42,-22 -14,-22 C-14,-22 14,-22 14,-22 C18.42,-22 22,-18.42 22,-14c " />
+ </group>
+ </group>
+ <group android:name="_R_G_L_0_G_L_1_G">
+ <group
+ android:name="_R_G_L_0_G_L_1_G_L_2_G"
+ android:translateX="206"
+ android:translateY="51">
+ <path
+ android:name="_R_G_L_0_G_L_1_G_L_2_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#6e7175"
+ android:fillType="nonZero"
+ android:pathData=" M206 -0.27 C206,-0.27 206,49.73 206,49.73 C206,49.73 -206,49.73 -206,49.73 C-206,49.73 -206,-0.27 -206,-0.27 C-206,-0.27 206,-0.27 206,-0.27c " />
+ </group>
+ <group
+ android:name="_R_G_L_0_G_L_1_G_L_1_G"
+ android:translateX="206"
+ android:translateY="50.5">
+ <path
+ android:name="_R_G_L_0_G_L_1_G_L_1_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#6e7175"
+ android:fillType="nonZero"
+ android:pathData=" M206 -32.5 C206,-32.5 206,32.5 206,32.5 C206,42.43 197.93,50.5 188,50.5 C188,50.5 -188,50.5 -188,50.5 C-197.93,50.5 -206,42.43 -206,32.5 C-206,32.5 -206,-32.5 -206,-32.5 C-206,-42.43 -197.93,-50.5 -188,-50.5 C-188,-50.5 188,-50.5 188,-50.5 C197.93,-50.5 206,-42.43 206,-32.5c " />
+ </group>
+ <group
+ android:name="_R_G_L_0_G_L_1_G_L_0_G"
+ android:translateX="206"
+ android:translateY="66.5">
+ <path
+ android:name="_R_G_L_0_G_L_1_G_L_0_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#9a9a9a"
+ android:fillType="nonZero"
+ android:pathData=" M190 0 C190,0 190,0 190,0 C190,10.21 181.71,18.5 171.5,18.5 C171.5,18.5 -171.5,18.5 -171.5,18.5 C-181.71,18.5 -190,10.21 -190,0 C-190,0 -190,0 -190,0 C-190,-10.21 -181.71,-18.5 -171.5,-18.5 C-171.5,-18.5 171.5,-18.5 171.5,-18.5 C181.71,-18.5 190,-10.21 190,0c " />
+ </group>
+ </group>
+ <group
+ android:name="_R_G_L_0_G_L_0_G"
+ android:scaleY="0"
+ android:translateX="206"
+ android:translateY="446">
+ <path
+ android:name="_R_G_L_0_G_L_0_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bac4d6"
+ android:fillType="nonZero"
+ android:pathData=" M206.06 -430.06 C206.06,-430.06 206,431 206,431 C206,446 189.75,446 189.79,446 C189.79,446 -189.98,446 -189.98,446 C-189.94,446 -206,446 -206,431 C-206,431 -206,-430 -206,-430 C-206,-446 -189.97,-446 -190.01,-446 C-190.01,-446 188.98,-446.06 188.98,-446.06 C188.94,-446.06 206,-446 206.06,-430.06c " />
+ </group>
+ </group>
+ </group>
+ <group android:name="time_group" />
+ </vector>
+ </aapt:attr>
+</animated-vector> \ No newline at end of file
diff --git a/quickstep/res/drawable/task_menu_item_bg.xml b/quickstep/res/drawable/task_menu_item_bg.xml
index 16c13ebebc..b6a8b909ee 100644
--- a/quickstep/res/drawable/task_menu_item_bg.xml
+++ b/quickstep/res/drawable/task_menu_item_bg.xml
@@ -15,8 +15,7 @@
limitations under the License.
-->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
- <solid android:color="?androidprv:attr/colorSurface" />
- <corners android:radius="@dimen/task_menu_item_corner_radius" />
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+ <solid android:color="?android:attr/colorPrimary"/>
+ <corners android:radius="@dimen/task_menu_item_corner_radius"/>
</shape>
diff --git a/quickstep/res/drawable/taskbar_edu_splitscreen.png b/quickstep/res/drawable/taskbar_edu_splitscreen.png
deleted file mode 100644
index f9d2a63a0e..0000000000
--- a/quickstep/res/drawable/taskbar_edu_splitscreen.png
+++ /dev/null
Binary files differ
diff --git a/quickstep/res/drawable/taskbar_edu_stashing.png b/quickstep/res/drawable/taskbar_edu_stashing.png
deleted file mode 100644
index f9d2a63a0e..0000000000
--- a/quickstep/res/drawable/taskbar_edu_stashing.png
+++ /dev/null
Binary files differ
diff --git a/quickstep/res/drawable/taskbar_edu_switch_apps.png b/quickstep/res/drawable/taskbar_edu_switch_apps.png
deleted file mode 100644
index f9d2a63a0e..0000000000
--- a/quickstep/res/drawable/taskbar_edu_switch_apps.png
+++ /dev/null
Binary files differ
diff --git a/quickstep/res/drawable/taskbar_icon_click_feedback_roundrect.xml b/quickstep/res/drawable/taskbar_icon_click_feedback_roundrect.xml
index 534f241ae9..d6160def0f 100644
--- a/quickstep/res/drawable/taskbar_icon_click_feedback_roundrect.xml
+++ b/quickstep/res/drawable/taskbar_icon_click_feedback_roundrect.xml
@@ -16,7 +16,7 @@
-->
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
- android:color="@color/taskbar_nav_icon_selection_ripple">
+ android:color="@color/taskbar_icon_selection_ripple">
<item android:id="@android:id/mask">
<shape android:shape="rectangle">
<solid android:color="@android:color/white" />
diff --git a/quickstep/res/interpolator/app_open_x.xml b/quickstep/res/interpolator/app_open_x.xml
deleted file mode 100644
index 5fa0bcb9ae..0000000000
--- a/quickstep/res/interpolator/app_open_x.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 2021, 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.
-*/
--->
-
-<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
- android:pathData="M 0, 0 C 0.1217, 0.0462, 0.15, 0.4686, 0.1667, 0.66 C 0.1834, 0.8878, 0.1667, 1, 1, 1"/>
diff --git a/quickstep/res/interpolator/three_point_fast_out_extra_slow_in.xml b/quickstep/res/interpolator/three_point_fast_out_extra_slow_in.xml
deleted file mode 100644
index 70c4231140..0000000000
--- a/quickstep/res/interpolator/three_point_fast_out_extra_slow_in.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 2021, 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.
-*/
--->
-
-<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
- android:pathData="M 0,0 C 0.05, 0, 0.133333, 0.06, 0.166666, 0.4 C 0.208333, 0.82, 0.25, 1, 1, 1"/>
diff --git a/quickstep/res/layout-land/gesture_tutorial_mock_hotseat.xml b/quickstep/res/layout-land/gesture_tutorial_mock_hotseat.xml
deleted file mode 100644
index 20d2ecc59f..0000000000
--- a/quickstep/res/layout-land/gesture_tutorial_mock_hotseat.xml
+++ /dev/null
@@ -1,80 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2022 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<androidx.constraintlayout.widget.ConstraintLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:app="http://schemas.android.com/apk/res-auto"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:paddingTop="26dp"
- android:paddingBottom="26dp"
- android:paddingStart="56dp"
- android:paddingEnd="56dp">
-
- <androidx.cardview.widget.CardView
- android:id="@+id/hotseat_icon_1"
- android:layout_width="@dimen/gesture_tutorial_hotseat_icon_size"
- android:layout_height="@dimen/gesture_tutorial_hotseat_icon_size"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="@dimen/gesture_tutorial_hotseat_icon_corner_radius"
- app:cardBackgroundColor="@color/mock_app_icon_1"
- app:layout_constraintDimensionRatio="1:1"
- app:layout_constraintVertical_chainStyle="spread_inside"
- app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintBottom_toTopOf="@id/hotseat_icon_2"
- app:layout_constraintStart_toStartOf="parent"/>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/hotseat_icon_2"
- android:layout_width="@dimen/gesture_tutorial_hotseat_icon_size"
- android:layout_height="@dimen/gesture_tutorial_hotseat_icon_size"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="@dimen/gesture_tutorial_hotseat_icon_corner_radius"
- app:cardBackgroundColor="@color/mock_app_icon_2"
- app:layout_constraintDimensionRatio="1:1"
- app:layout_constraintTop_toBottomOf="@id/hotseat_icon_1"
- app:layout_constraintBottom_toTopOf="@id/hotseat_icon_3"
- app:layout_constraintStart_toStartOf="parent"/>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/hotseat_icon_3"
- android:layout_width="@dimen/gesture_tutorial_hotseat_icon_size"
- android:layout_height="@dimen/gesture_tutorial_hotseat_icon_size"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="@dimen/gesture_tutorial_hotseat_icon_corner_radius"
- app:cardBackgroundColor="@color/mock_app_icon_3"
- app:layout_constraintDimensionRatio="1:1"
- app:layout_constraintTop_toBottomOf="@id/hotseat_icon_2"
- app:layout_constraintBottom_toTopOf="@id/hotseat_icon_4"
- app:layout_constraintStart_toStartOf="parent"/>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/hotseat_icon_4"
- android:layout_width="@dimen/gesture_tutorial_hotseat_icon_size"
- android:layout_height="@dimen/gesture_tutorial_hotseat_icon_size"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="@dimen/gesture_tutorial_hotseat_icon_corner_radius"
- app:cardBackgroundColor="@color/mock_app_icon_4"
- app:layout_constraintDimensionRatio="1:1"
- app:layout_constraintTop_toBottomOf="@id/hotseat_icon_3"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintStart_toStartOf="parent"/>
-
-</androidx.constraintlayout.widget.ConstraintLayout> \ No newline at end of file
diff --git a/quickstep/res/layout-land/gesture_tutorial_tablet_mock_hotseat.xml b/quickstep/res/layout-land/gesture_tutorial_tablet_mock_hotseat.xml
deleted file mode 100644
index 6877b89716..0000000000
--- a/quickstep/res/layout-land/gesture_tutorial_tablet_mock_hotseat.xml
+++ /dev/null
@@ -1,123 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2022 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<androidx.constraintlayout.widget.ConstraintLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:app="http://schemas.android.com/apk/res-auto"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:paddingBottom="32dp"
- android:paddingStart="@dimen/gesture_tutorial_hotseat_padding_start_end"
- android:paddingEnd="@dimen/gesture_tutorial_hotseat_padding_start_end">
-
- <androidx.cardview.widget.CardView
- android:id="@+id/hotseat_search_bar"
- android:layout_width="200dp"
- android:layout_height="@dimen/gesture_tutorial_hotseat_search_height"
-
- app:layout_constraintHorizontal_chainStyle="spread_inside"
- app:cardElevation="0dp"
- app:cardCornerRadius="@dimen/gesture_tutorial_hotseat_search_corner_radius"
- app:cardBackgroundColor="@color/mock_search_bar"
- app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toStartOf="@id/hotseat_icon_1"/>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/hotseat_icon_1"
- android:layout_width="@dimen/gesture_tutorial_hotseat_icon_size"
- android:layout_height="@dimen/gesture_tutorial_hotseat_icon_size"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="@dimen/gesture_tutorial_hotseat_icon_corner_radius"
- app:cardBackgroundColor="@color/mock_app_icon_1"
- app:layout_constraintDimensionRatio="1:1"
- app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintStart_toEndOf="@id/hotseat_search_bar"
- app:layout_constraintEnd_toStartOf="@id/hotseat_icon_2"/>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/hotseat_icon_2"
- android:layout_width="@dimen/gesture_tutorial_hotseat_icon_size"
- android:layout_height="@dimen/gesture_tutorial_hotseat_icon_size"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="@dimen/gesture_tutorial_hotseat_icon_corner_radius"
- app:cardBackgroundColor="@color/mock_app_icon_2"
- app:layout_constraintDimensionRatio="1:1"
- app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintStart_toEndOf="@id/hotseat_icon_1"
- app:layout_constraintEnd_toStartOf="@id/hotseat_icon_3"/>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/hotseat_icon_3"
- android:layout_width="@dimen/gesture_tutorial_hotseat_icon_size"
- android:layout_height="@dimen/gesture_tutorial_hotseat_icon_size"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="@dimen/gesture_tutorial_hotseat_icon_corner_radius"
- app:cardBackgroundColor="@color/mock_app_icon_3"
- app:layout_constraintDimensionRatio="1:1"
- app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintStart_toEndOf="@id/hotseat_icon_2"
- app:layout_constraintEnd_toStartOf="@id/hotseat_icon_4"/>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/hotseat_icon_4"
- android:layout_width="@dimen/gesture_tutorial_hotseat_icon_size"
- android:layout_height="@dimen/gesture_tutorial_hotseat_icon_size"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="@dimen/gesture_tutorial_hotseat_icon_corner_radius"
- app:cardBackgroundColor="@color/mock_app_icon_1"
- app:layout_constraintDimensionRatio="1:1"
- app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintStart_toEndOf="@id/hotseat_icon_3"
- app:layout_constraintEnd_toStartOf="@id/hotseat_icon_5"/>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/hotseat_icon_5"
- android:layout_width="@dimen/gesture_tutorial_hotseat_icon_size"
- android:layout_height="@dimen/gesture_tutorial_hotseat_icon_size"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="@dimen/gesture_tutorial_hotseat_icon_corner_radius"
- app:cardBackgroundColor="@color/mock_app_icon_4"
- app:layout_constraintDimensionRatio="1:1"
- app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintStart_toEndOf="@id/hotseat_icon_4"
- app:layout_constraintEnd_toStartOf="@id/hotseat_icon_6"/>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/hotseat_icon_6"
- android:layout_width="@dimen/gesture_tutorial_hotseat_icon_size"
- android:layout_height="@dimen/gesture_tutorial_hotseat_icon_size"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="@dimen/gesture_tutorial_hotseat_icon_corner_radius"
- app:cardBackgroundColor="@color/mock_app_icon_2"
- app:layout_constraintDimensionRatio="1:1"
- app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintStart_toEndOf="@id/hotseat_icon_5"
- app:layout_constraintEnd_toEndOf="parent"/>
-
-</androidx.constraintlayout.widget.ConstraintLayout> \ No newline at end of file
diff --git a/quickstep/res/layout/activity_allset.xml b/quickstep/res/layout/activity_allset.xml
index 0cae733dbe..e79e57efef 100644
--- a/quickstep/res/layout/activity_allset.xml
+++ b/quickstep/res/layout/activity_allset.xml
@@ -14,109 +14,68 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<FrameLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:app="http://schemas.android.com/apk/res-auto"
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:id="@+id/root_view"
- android:background="@color/all_set_page_background" >
+ android:paddingStart="@dimen/allset_page_margin_horizontal"
+ android:paddingEnd="@dimen/allset_page_margin_horizontal"
+ android:layoutDirection="locale"
+ android:textDirection="locale">
- <androidx.constraintlayout.widget.ConstraintLayout
+ <LinearLayout
android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:id="@+id/content_view"
- android:fitsSystemWindows="true">
-
- <com.airbnb.lottie.LottieAnimationView
- android:id="@+id/animated_background"
+ android:layout_height="wrap_content"
+ android:layout_alignParentTop="true"
+ android:layout_gravity="start"
+ android:gravity="start"
+ android:orientation="vertical">
+
+ <ImageView
+ android:id="@+id/icon"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="@dimen/allset_title_icon_margin_top"
+ android:src="@drawable/ic_all_set"/>
+
+ <TextView
+ android:id="@+id/title"
+ style="@style/TextAppearance.GestureTutorial.Feedback.Title"
android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:gravity="center"
- android:scaleType="centerCrop"
-
- app:lottie_rawRes="@raw/all_set_page_bg"
- app:lottie_autoPlay="true"
- app:lottie_loop="true" />
-
- <androidx.constraintlayout.widget.ConstraintLayout
+ android:layout_height="wrap_content"
+ android:layout_marginTop="@dimen/allset_title_margin_top"
+ android:gravity="start"
+ android:text="@string/allset_title"/>
+
+ <TextView
+ android:id="@+id/subtitle"
+ style="@style/TextAppearance.GestureTutorial.Feedback.Subtitle"
android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_marginStart="@dimen/allset_page_margin_horizontal"
- android:layout_marginEnd="@dimen/allset_page_margin_horizontal"
- android:layoutDirection="locale"
- android:textDirection="locale"
- android:forceHasOverlappingRendering="false"
- android:fitsSystemWindows="true" >
-
- <ImageView
- android:id="@+id/icon"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginTop="@dimen/allset_title_icon_margin_top"
- app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintStart_toStartOf="parent"
- android:src="@drawable/ic_all_set"/>
-
- <TextView
- android:id="@+id/title"
- style="@style/TextAppearance.GestureTutorial.Feedback.Title.AllSet"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginTop="@dimen/allset_title_margin_top"
- app:layout_constraintTop_toBottomOf="@id/icon"
- app:layout_constraintStart_toStartOf="parent"
- android:gravity="start"
- android:text="@string/allset_title"/>
-
- <TextView
- android:id="@+id/subtitle"
- style="@style/TextAppearance.GestureTutorial.Feedback.Subtitle.AllSet"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginTop="@dimen/allset_subtitle_margin_top"
- app:layout_constraintTop_toBottomOf="@id/title"
- app:layout_constraintStart_toStartOf="parent"
- android:gravity="start"/>
-
- <androidx.constraintlayout.widget.Guideline
- android:id="@+id/navigation_settings_guideline_bottom"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:orientation="horizontal"
- app:layout_constraintGuide_percent="0.83" />
-
- <TextView
- android:id="@+id/navigation_settings"
- style="@style/TextAppearance.GestureTutorial.LinkText"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintBottom_toBottomOf="@id/navigation_settings_guideline_bottom"
- android:minHeight="48dp"
- android:background="?android:attr/selectableItemBackground"
- android:text="@string/allset_navigation_settings" />
-
- <androidx.constraintlayout.widget.Guideline
- android:id="@+id/hint_guideline_bottom"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:orientation="horizontal"
- app:layout_constraintGuide_percent="0.94" />
-
- <TextView
- android:id="@+id/hint"
- style="@style/TextAppearance.GestureTutorial.Feedback.Subtitle"
- android:textSize="14sp"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintBottom_toBottomOf="@id/hint_guideline_bottom"
- android:text="@string/allset_hint"/>
- </androidx.constraintlayout.widget.ConstraintLayout>
-
- </androidx.constraintlayout.widget.ConstraintLayout>
-
-</FrameLayout> \ No newline at end of file
+ android:layout_height="wrap_content"
+ android:layout_marginTop="@dimen/allset_subtitle_margin_top"
+ android:gravity="start"
+ android:text="@string/allset_description"/>
+ </LinearLayout>
+
+ <TextView
+ android:id="@+id/navigation_settings"
+ style="@style/TextAppearance.GestureTutorial.LinkText"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_above="@+id/hint"
+ android:gravity="center"
+ android:layout_marginBottom="72dp"
+ android:minHeight="48dp"
+ android:background="?android:attr/selectableItemBackground"
+ android:text="@string/allset_navigation_settings" />
+
+ <TextView
+ android:id="@id/hint"
+ style="@style/TextAppearance.GestureTutorial.Feedback.Subtitle"
+ android:textSize="14sp"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="@dimen/allset_hint_margin_bottom"
+ android:layout_alignParentBottom="true"
+ android:layout_centerHorizontal="true"
+ android:text="@string/allset_hint"/>
+</RelativeLayout>
diff --git a/quickstep/res/layout/fallback_recents_activity.xml b/quickstep/res/layout/fallback_recents_activity.xml
index bfeb82d9f9..a43296f602 100644
--- a/quickstep/res/layout/fallback_recents_activity.xml
+++ b/quickstep/res/layout/fallback_recents_activity.xml
@@ -45,7 +45,8 @@
android:layout_height="match_parent"
android:clipChildren="false"
android:clipToPadding="false"
- android:outlineProvider="none" />
+ android:outlineProvider="none"
+ android:theme="@style/HomeScreenElementTheme" />
<include
android:id="@+id/overview_actions_view"
diff --git a/quickstep/res/layout/gesture_tutorial_dialog.xml b/quickstep/res/layout/gesture_tutorial_dialog.xml
index db6ec8533f..59bf7b965c 100644
--- a/quickstep/res/layout/gesture_tutorial_dialog.xml
+++ b/quickstep/res/layout/gesture_tutorial_dialog.xml
@@ -1,18 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2021 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.
--->
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
diff --git a/quickstep/res/layout/gesture_tutorial_foldable_mock_hotseat.xml b/quickstep/res/layout/gesture_tutorial_foldable_mock_hotseat.xml
deleted file mode 100644
index 027e4a05b0..0000000000
--- a/quickstep/res/layout/gesture_tutorial_foldable_mock_hotseat.xml
+++ /dev/null
@@ -1,122 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2022 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<androidx.constraintlayout.widget.ConstraintLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:app="http://schemas.android.com/apk/res-auto"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:paddingBottom="32dp"
- android:paddingStart="@dimen/gesture_tutorial_hotseat_padding_start_end"
- android:paddingEnd="@dimen/gesture_tutorial_hotseat_padding_start_end">
-
- <androidx.cardview.widget.CardView
- android:id="@+id/hotseat_search_bar"
- android:layout_width="0dp"
- android:layout_height="@dimen/gesture_tutorial_hotseat_search_height"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="@dimen/gesture_tutorial_hotseat_search_corner_radius"
- app:cardBackgroundColor="@color/mock_search_bar"
- app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toEndOf="parent"/>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/hotseat_icon_1"
- android:layout_width="@dimen/gesture_tutorial_hotseat_icon_size"
- android:layout_height="@dimen/gesture_tutorial_hotseat_icon_size"
- android:layout_marginTop="@dimen/gesture_tutorial_hotseat_icon_search_margin"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="@dimen/gesture_tutorial_hotseat_icon_corner_radius"
- app:cardBackgroundColor="@color/mock_app_icon_1"
- app:layout_constraintDimensionRatio="1:1"
- app:layout_constraintHorizontal_chainStyle="spread_inside"
- app:layout_constraintTop_toBottomOf="@id/hotseat_search_bar"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toStartOf="@id/hotseat_icon_2"/>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/hotseat_icon_2"
- android:layout_width="@dimen/gesture_tutorial_hotseat_icon_size"
- android:layout_height="@dimen/gesture_tutorial_hotseat_icon_size"
- android:layout_marginTop="@dimen/gesture_tutorial_hotseat_icon_search_margin"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="@dimen/gesture_tutorial_hotseat_icon_corner_radius"
- app:cardBackgroundColor="@color/mock_app_icon_2"
- app:layout_constraintDimensionRatio="1:1"
- app:layout_constraintTop_toBottomOf="@id/hotseat_search_bar"
- app:layout_constraintStart_toEndOf="@id/hotseat_icon_1"
- app:layout_constraintEnd_toStartOf="@id/hotseat_icon_3"/>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/hotseat_icon_3"
- android:layout_width="@dimen/gesture_tutorial_hotseat_icon_size"
- android:layout_height="@dimen/gesture_tutorial_hotseat_icon_size"
- android:layout_marginTop="@dimen/gesture_tutorial_hotseat_icon_search_margin"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="@dimen/gesture_tutorial_hotseat_icon_corner_radius"
- app:cardBackgroundColor="@color/mock_app_icon_3"
- app:layout_constraintDimensionRatio="1:1"
- app:layout_constraintTop_toBottomOf="@id/hotseat_search_bar"
- app:layout_constraintStart_toEndOf="@id/hotseat_icon_2"
- app:layout_constraintEnd_toStartOf="@id/hotseat_icon_4"/>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/hotseat_icon_4"
- android:layout_width="@dimen/gesture_tutorial_hotseat_icon_size"
- android:layout_height="@dimen/gesture_tutorial_hotseat_icon_size"
- android:layout_marginTop="@dimen/gesture_tutorial_hotseat_icon_search_margin"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="@dimen/gesture_tutorial_hotseat_icon_corner_radius"
- app:cardBackgroundColor="@color/mock_app_icon_1"
- app:layout_constraintDimensionRatio="1:1"
- app:layout_constraintTop_toBottomOf="@id/hotseat_search_bar"
- app:layout_constraintStart_toEndOf="@id/hotseat_icon_3"
- app:layout_constraintEnd_toStartOf="@id/hotseat_icon_5"/>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/hotseat_icon_5"
- android:layout_width="@dimen/gesture_tutorial_hotseat_icon_size"
- android:layout_height="@dimen/gesture_tutorial_hotseat_icon_size"
- android:layout_marginTop="@dimen/gesture_tutorial_hotseat_icon_search_margin"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="@dimen/gesture_tutorial_hotseat_icon_corner_radius"
- app:cardBackgroundColor="@color/mock_app_icon_4"
- app:layout_constraintDimensionRatio="1:1"
- app:layout_constraintTop_toBottomOf="@id/hotseat_search_bar"
- app:layout_constraintStart_toEndOf="@id/hotseat_icon_4"
- app:layout_constraintEnd_toStartOf="@id/hotseat_icon_6"/>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/hotseat_icon_6"
- android:layout_width="@dimen/gesture_tutorial_hotseat_icon_size"
- android:layout_height="@dimen/gesture_tutorial_hotseat_icon_size"
- android:layout_marginTop="@dimen/gesture_tutorial_hotseat_icon_search_margin"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="@dimen/gesture_tutorial_hotseat_icon_corner_radius"
- app:cardBackgroundColor="@color/mock_app_icon_2"
- app:layout_constraintDimensionRatio="1:1"
- app:layout_constraintTop_toBottomOf="@id/hotseat_search_bar"
- app:layout_constraintStart_toEndOf="@id/hotseat_icon_5"
- app:layout_constraintEnd_toEndOf="parent"/>
-
-</androidx.constraintlayout.widget.ConstraintLayout> \ No newline at end of file
diff --git a/quickstep/res/layout/gesture_tutorial_fragment.xml b/quickstep/res/layout/gesture_tutorial_fragment.xml
index b3ca297888..cdda43c8a8 100644
--- a/quickstep/res/layout/gesture_tutorial_fragment.xml
+++ b/quickstep/res/layout/gesture_tutorial_fragment.xml
@@ -25,10 +25,13 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
- <FrameLayout
+ <ImageView
android:id="@+id/gesture_tutorial_fake_hotseat_view"
- android:layout_width="@dimen/gesture_tutorial_hotseat_width"
- android:layout_height="@dimen/gesture_tutorial_hotseat_height"/>
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_centerHorizontal="true"
+ android:layout_alignParentBottom="true"
+ android:layout_marginBottom="70dp"/>
</RelativeLayout>
@@ -38,56 +41,15 @@
android:layout_height="20dp"
android:visibility="invisible" />
- <com.android.quickstep.interaction.AnimatedTaskView
+ <View
android:id="@+id/gesture_tutorial_fake_previous_task_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleX="0.98"
android:scaleY="0.98"
- android:visibility="invisible">
-
- <View
- android:id="@+id/full_task_view"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:visibility="invisible"
-
- app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toEndOf="parent"/>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/top_task_view"
- android:layout_width="match_parent"
- android:layout_height="0dp"
- android:visibility="invisible"
- android:layout_marginBottom="@dimen/gesture_tutorial_multi_row_task_view_spacing"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="@dimen/gesture_tutorial_small_task_view_corner_radius"
- app:layout_constraintVertical_chainStyle="spread"
- app:layout_constraintTop_toTopOf="@id/full_task_view"
- app:layout_constraintBottom_toTopOf="@id/bottom_task_view"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toEndOf="parent"/>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/bottom_task_view"
- android:layout_width="match_parent"
- android:layout_height="0dp"
- android:visibility="invisible"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="@dimen/gesture_tutorial_small_task_view_corner_radius"
- app:layout_constraintTop_toBottomOf="@id/top_task_view"
- app:layout_constraintBottom_toBottomOf="@id/full_task_view"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toEndOf="parent"/>
-
- </com.android.quickstep.interaction.AnimatedTaskView>
+ android:visibility="invisible" />
- <FrameLayout
+ <View
android:id="@+id/gesture_tutorial_fake_task_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
@@ -99,17 +61,19 @@
android:layout_height="match_parent"
android:background="@drawable/gesture_tutorial_ripple"/>
- <include
- layout="@layout/gesture_tutorial_tablet_mock_taskbar"
- android:id="@+id/gesture_tutorial_fake_taskbar_view"
+ <ImageView
+ android:id="@+id/gesture_tutorial_feedback_video"
android:layout_width="match_parent"
- android:layout_height="@dimen/gesture_tutorial_mock_taskbar_height"
+ android:layout_height="match_parent"
+ android:layout_alignParentTop="true"
android:layout_alignParentBottom="true"
android:layout_alignParentStart="true"
- android:layout_alignParentEnd="true" />
+ android:layout_alignParentEnd="true"
+ android:scaleType="fitXY"
+ android:visibility="gone"/>
<ImageView
- android:id="@+id/gesture_tutorial_edge_gesture_video"
+ android:id="@+id/gesture_tutorial_gesture_video"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentTop="true"
@@ -125,17 +89,20 @@
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
+ android:layout_marginStart="@dimen/gesture_tutorial_feedback_margin_start_end"
+ android:layout_marginEnd="@dimen/gesture_tutorial_feedback_margin_start_end"
+ android:layout_marginTop="24dp"
android:paddingTop="24dp"
android:paddingBottom="16dp"
- android:paddingStart="24dp"
- android:paddingEnd="24dp"
android:background="@drawable/bg_sandbox_feedback">
<TextView
android:id="@+id/gesture_tutorial_fragment_feedback_title"
style="@style/TextAppearance.GestureTutorial.Feedback.Title"
- android:layout_width="wrap_content"
+ android:layout_width="0dp"
android:layout_height="wrap_content"
+ android:layout_marginStart="24dp"
+ android:layout_marginEnd="24dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
@@ -146,7 +113,9 @@
style="@style/TextAppearance.GestureTutorial.Feedback.Subtitle"
android:layout_width="0dp"
android:layout_height="wrap_content"
- android:layout_marginTop="16dp"
+ android:layout_marginTop="24dp"
+ android:layout_marginStart="24dp"
+ android:layout_marginEnd="24dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
@@ -168,6 +137,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="32dp"
+ android:layout_marginEnd="16dp"
android:paddingTop="16dp"
android:paddingBottom="16dp"
android:paddingStart="26dp"
@@ -186,8 +156,11 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="32dp"
+ android:layout_marginEnd="16dp"
android:paddingTop="16dp"
android:paddingBottom="16dp"
+ android:paddingStart="26dp"
+ android:paddingEnd="26dp"
android:text="@string/gesture_tutorial_action_button_label_skip"
android:background="?android:attr/selectableItemBackgroundBorderless"
@@ -196,13 +169,4 @@
</androidx.constraintlayout.widget.ConstraintLayout>
- <ImageView
- android:id="@+id/gesture_tutorial_finger_dot"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:src="@drawable/gesture_tutorial_finger_dot"
- android:layout_centerHorizontal="true"
- android:layout_centerVertical="true"
- android:visibility="gone"/>
-
</com.android.quickstep.interaction.RootSandboxLayout> \ No newline at end of file
diff --git a/quickstep/res/layout/gesture_tutorial_mock_conversation.xml b/quickstep/res/layout/gesture_tutorial_mock_conversation.xml
deleted file mode 100644
index 5550389e25..0000000000
--- a/quickstep/res/layout/gesture_tutorial_mock_conversation.xml
+++ /dev/null
@@ -1,242 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2021 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.
--->
-<androidx.constraintlayout.widget.ConstraintLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:app="http://schemas.android.com/apk/res-auto"
- android:layout_width="match_parent"
- android:layout_height="match_parent">
-
- <androidx.constraintlayout.widget.ConstraintLayout
- android:id="@+id/top_bar"
- android:layout_width="match_parent"
- android:layout_height="101dp"
- android:background="@color/mock_conversation_top_bar"
-
- app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toEndOf="parent">
-
- <androidx.cardview.widget.CardView
- android:layout_width="0dp"
- android:layout_height="0dp"
- android:layout_marginTop="43dp"
- android:layout_marginBottom="22dp"
- android:layout_marginStart="@dimen/gesture_tutorial_top_bar_margin_start"
- android:layout_marginEnd="@dimen/gesture_tutorial_top_bar_margin_end"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="4dp"
- app:cardBackgroundColor="@color/mock_conversation_top_bar_item"
- app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toEndOf="parent"/>
-
- <androidx.cardview.widget.CardView
- android:layout_width="0dp"
- android:layout_height="0dp"
- android:layout_marginTop="43dp"
- android:layout_marginBottom="22dp"
- android:layout_marginStart="300dp"
- android:layout_marginEnd="16dp"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="4dp"
- app:cardBackgroundColor="@color/mock_conversation_top_bar_item"
- app:layout_constraintDimensionRatio="1:1"
- app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintEnd_toStartOf="@id/top_bar_button"/>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/top_bar_button"
- android:layout_width="0dp"
- android:layout_height="0dp"
- android:layout_marginTop="43dp"
- android:layout_marginBottom="22dp"
- android:layout_marginStart="300dp"
- android:layout_marginEnd="24dp"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="4dp"
- app:cardBackgroundColor="@color/mock_conversation_top_bar_item"
- app:layout_constraintDimensionRatio="1:1"
- app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintEnd_toEndOf="parent"/>
-
- </androidx.constraintlayout.widget.ConstraintLayout>
-
- <androidx.constraintlayout.widget.ConstraintLayout
- android:layout_width="match_parent"
- android:layout_height="0dp"
- android:background="@color/mock_conversation_background"
- android:paddingBottom="@dimen/gesture_tutorial_conversation_bottom_padding"
-
- app:layout_constraintTop_toBottomOf="@id/top_bar"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toEndOf="parent">
-
- <androidx.constraintlayout.widget.ConstraintLayout
- android:layout_width="match_parent"
- android:layout_height="0dp"
- android:paddingBottom="@dimen/gesture_tutorial_message_input_margin_top"
-
- app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintBottom_toTopOf="@id/message_bar"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toEndOf="parent">
-
- <androidx.cardview.widget.CardView
- android:id="@+id/message_1"
- android:layout_width="0dp"
- android:layout_height="112dp"
- android:layout_marginBottom="@dimen/gesture_tutorial_message_large_margin_bottom"
- android:layout_marginStart="124dp"
- android:layout_marginEnd="@dimen/gesture_tutorial_message_padding_end"
- android:visibility="@integer/gesture_tutorial_extra_messages_visibility"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="18dp"
- app:cardBackgroundColor="@color/mock_conversation_sent_message"
- app:layout_constraintBottom_toTopOf="@id/reply_icon_1"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toEndOf="parent"/>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/reply_icon_1"
- android:layout_width="@dimen/gesture_tutorial_message_icon_size"
- android:layout_height="@dimen/gesture_tutorial_message_icon_size"
- android:layout_marginBottom="@dimen/gesture_tutorial_message_large_margin_bottom"
- android:layout_marginStart="@dimen/gesture_tutorial_message_padding_start"
- android:visibility="@integer/gesture_tutorial_extra_messages_visibility"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="@dimen/gesture_tutorial_message_icon_corner_radius"
- app:cardBackgroundColor="@color/mock_conversation_profile_icon"
- app:layout_constraintDimensionRatio="1:1"
- app:layout_constraintBottom_toTopOf="@id/message_2"
- app:layout_constraintStart_toStartOf="parent"/>
-
- <androidx.cardview.widget.CardView
- android:layout_width="0dp"
- android:layout_height="36dp"
- android:layout_marginStart="17dp"
- android:layout_marginEnd="112dp"
- android:visibility="@integer/gesture_tutorial_extra_messages_visibility"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="18dp"
- app:cardBackgroundColor="@color/mock_conversation_received_message"
- app:layout_constraintTop_toTopOf="@id/reply_icon_1"
- app:layout_constraintBottom_toBottomOf="@id/reply_icon_1"
- app:layout_constraintStart_toEndOf="@id/reply_icon_1"
- app:layout_constraintEnd_toEndOf="parent"/>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/message_2"
- android:layout_width="0dp"
- android:layout_height="36dp"
- android:layout_marginBottom="@dimen/gesture_tutorial_message_small_margin_bottom"
- android:layout_marginStart="280dp"
- android:layout_marginEnd="@dimen/gesture_tutorial_message_padding_end"
- android:visibility="@integer/gesture_tutorial_extra_messages_visibility"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="18dp"
- app:cardBackgroundColor="@color/mock_conversation_sent_message"
- app:layout_constraintBottom_toTopOf="@id/message_3"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toEndOf="parent"/>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/message_3"
- android:layout_width="0dp"
- android:layout_height="74dp"
- android:layout_marginBottom="@dimen/gesture_tutorial_message_large_margin_bottom"
- android:layout_marginStart="@dimen/gesture_tutorial_message_margin_start"
- android:layout_marginEnd="@dimen/gesture_tutorial_message_padding_end"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="18dp"
- app:cardBackgroundColor="@color/mock_conversation_sent_message"
- app:layout_constraintBottom_toTopOf="@id/reply_icon_2"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toEndOf="parent"/>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/reply_icon_2"
- android:layout_width="@dimen/gesture_tutorial_message_icon_size"
- android:layout_height="@dimen/gesture_tutorial_message_icon_size"
- android:layout_marginBottom="@dimen/gesture_tutorial_message_large_margin_bottom"
- android:layout_marginStart="@dimen/gesture_tutorial_message_padding_start"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="@dimen/gesture_tutorial_message_icon_corner_radius"
- app:cardBackgroundColor="@color/mock_conversation_profile_icon"
- app:layout_constraintDimensionRatio="1:1"
- app:layout_constraintBottom_toTopOf="@id/message_4"
- app:layout_constraintStart_toStartOf="parent"/>
-
- <androidx.cardview.widget.CardView
- android:layout_width="0dp"
- android:layout_height="36dp"
- android:layout_marginStart="17dp"
- android:layout_marginEnd="@dimen/gesture_tutorial_reply_margin_end"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="18dp"
- app:cardBackgroundColor="@color/mock_conversation_received_message"
- app:layout_constraintTop_toTopOf="@id/reply_icon_2"
- app:layout_constraintBottom_toBottomOf="@id/reply_icon_2"
- app:layout_constraintStart_toEndOf="@id/reply_icon_2"
- app:layout_constraintEnd_toEndOf="parent"/>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/message_4"
- android:layout_width="0dp"
- android:layout_height="74dp"
- android:layout_marginStart="@dimen/gesture_tutorial_message_margin_start"
- android:layout_marginEnd="@dimen/gesture_tutorial_message_padding_end"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="18dp"
- app:cardBackgroundColor="@color/mock_conversation_sent_message"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toEndOf="parent"/>
-
- </androidx.constraintlayout.widget.ConstraintLayout>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/message_bar"
- android:layout_width="0dp"
- android:layout_height="44dp"
- android:layout_marginTop="36dp"
- android:layout_marginStart="34dp"
- android:layout_marginEnd="24dp"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="164dp"
- app:cardBackgroundColor="@color/mock_conversation_message_input"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toEndOf="parent" />
-
- </androidx.constraintlayout.widget.ConstraintLayout>
-
-</androidx.constraintlayout.widget.ConstraintLayout> \ No newline at end of file
diff --git a/quickstep/res/layout/gesture_tutorial_mock_conversation_list.xml b/quickstep/res/layout/gesture_tutorial_mock_conversation_list.xml
deleted file mode 100644
index a172ad3712..0000000000
--- a/quickstep/res/layout/gesture_tutorial_mock_conversation_list.xml
+++ /dev/null
@@ -1,393 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2021 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.
--->
-<androidx.constraintlayout.widget.ConstraintLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:app="http://schemas.android.com/apk/res-auto"
- android:layout_width="match_parent"
- android:layout_height="match_parent">
-
- <androidx.constraintlayout.widget.ConstraintLayout
- android:id="@+id/top_bar"
- android:layout_width="match_parent"
- android:layout_height="101dp"
- android:background="@color/mock_list_top_bar"
-
- app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toEndOf="parent">
-
- <androidx.cardview.widget.CardView
- android:layout_width="0dp"
- android:layout_height="0dp"
- android:layout_marginTop="43dp"
- android:layout_marginBottom="22dp"
- android:layout_marginStart="34dp"
- android:layout_marginEnd="34dp"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="4dp"
- app:cardBackgroundColor="@color/mock_list_top_bar_item"
- app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toEndOf="parent"/>
-
- </androidx.constraintlayout.widget.ConstraintLayout>
-
- <androidx.constraintlayout.widget.ConstraintLayout
- android:layout_width="match_parent"
- android:layout_height="0dp"
- android:background="@color/mock_list_background"
- android:paddingTop="@dimen/gesture_tutorial_conversation_list_padding_top"
- android:paddingStart="26dp"
-
- app:layout_constraintTop_toBottomOf="@id/top_bar"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toEndOf="parent">
-
- <androidx.cardview.widget.CardView
- android:id="@+id/conversation_icon_1"
- android:layout_width="@dimen/gesture_tutorial_conversation_icon_size"
- android:layout_height="@dimen/gesture_tutorial_conversation_icon_size"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="@dimen/gesture_tutorial_conversation_icon_corner_radius"
- app:cardBackgroundColor="@color/mock_list_profile_icon"
- app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintStart_toStartOf="parent"/>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/conversation_line_1"
- android:layout_width="0dp"
- android:layout_height="18dp"
- android:layout_marginStart="@dimen/gesture_tutorial_conversation_line_padding_start"
- android:layout_marginEnd="@dimen/gesture_tutorial_conversation_line_1_margin_end"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="4dp"
- app:cardBackgroundColor="@color/mock_list_preview_message"
- app:layout_constraintVertical_chainStyle="packed"
- app:layout_constraintTop_toTopOf="@id/conversation_icon_1"
- app:layout_constraintStart_toEndOf="@id/conversation_icon_1"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintBottom_toTopOf="@id/conversation_line_2"/>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/conversation_line_2"
- android:layout_width="0dp"
- android:layout_height="16dp"
- android:layout_marginStart="@dimen/gesture_tutorial_conversation_line_padding_start"
- android:layout_marginEnd="@dimen/gesture_tutorial_conversation_line_2_margin_end"
- android:layout_marginTop="4dp"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="4dp"
- app:cardBackgroundColor="@color/mock_list_preview_message"
- app:layout_constraintTop_toBottomOf="@id/conversation_line_1"
- app:layout_constraintStart_toEndOf="@id/conversation_icon_1"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintBottom_toBottomOf="@id/conversation_icon_1"/>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/conversation_icon_2"
- android:layout_width="@dimen/gesture_tutorial_conversation_icon_size"
- android:layout_height="@dimen/gesture_tutorial_conversation_icon_size"
- android:layout_marginTop="32dp"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="@dimen/gesture_tutorial_conversation_icon_corner_radius"
- app:cardBackgroundColor="@color/mock_list_profile_icon"
- app:layout_constraintTop_toBottomOf="@id/conversation_icon_1"
- app:layout_constraintStart_toStartOf="parent"/>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/conversation_line_3"
- android:layout_width="0dp"
- android:layout_height="18dp"
- android:layout_marginStart="@dimen/gesture_tutorial_conversation_line_padding_start"
- android:layout_marginEnd="@dimen/gesture_tutorial_conversation_line_3_margin_end"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="4dp"
- app:cardBackgroundColor="@color/mock_list_preview_message"
- app:layout_constraintVertical_chainStyle="packed"
- app:layout_constraintTop_toTopOf="@id/conversation_icon_2"
- app:layout_constraintStart_toEndOf="@id/conversation_icon_2"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintBottom_toTopOf="@id/conversation_line_4"/>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/conversation_line_4"
- android:layout_width="0dp"
- android:layout_height="16dp"
- android:layout_marginStart="@dimen/gesture_tutorial_conversation_line_padding_start"
- android:layout_marginEnd="@dimen/gesture_tutorial_conversation_line_4_margin_end"
- android:layout_marginTop="4dp"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="4dp"
- app:cardBackgroundColor="@color/mock_list_preview_message"
- app:layout_constraintTop_toBottomOf="@id/conversation_line_3"
- app:layout_constraintStart_toEndOf="@id/conversation_icon_2"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintBottom_toBottomOf="@id/conversation_icon_2"/>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/conversation_icon_3"
- android:layout_width="@dimen/gesture_tutorial_conversation_icon_size"
- android:layout_height="@dimen/gesture_tutorial_conversation_icon_size"
- android:layout_marginTop="32dp"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="@dimen/gesture_tutorial_conversation_icon_corner_radius"
- app:cardBackgroundColor="@color/mock_list_profile_icon"
- app:layout_constraintTop_toBottomOf="@id/conversation_icon_2"
- app:layout_constraintStart_toStartOf="parent"/>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/conversation_line_5"
- android:layout_width="0dp"
- android:layout_height="18dp"
- android:layout_marginStart="@dimen/gesture_tutorial_conversation_line_padding_start"
- android:layout_marginEnd="@dimen/gesture_tutorial_conversation_line_5_margin_end"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="4dp"
- app:cardBackgroundColor="@color/mock_list_preview_message"
- app:layout_constraintVertical_chainStyle="packed"
- app:layout_constraintTop_toTopOf="@id/conversation_icon_3"
- app:layout_constraintStart_toEndOf="@id/conversation_icon_3"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintBottom_toTopOf="@id/conversation_line_6"/>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/conversation_line_6"
- android:layout_width="0dp"
- android:layout_height="16dp"
- android:layout_marginStart="@dimen/gesture_tutorial_conversation_line_padding_start"
- android:layout_marginEnd="@dimen/gesture_tutorial_conversation_line_6_margin_end"
- android:layout_marginTop="4dp"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="4dp"
- app:cardBackgroundColor="@color/mock_list_preview_message"
- app:layout_constraintTop_toBottomOf="@id/conversation_line_5"
- app:layout_constraintStart_toEndOf="@id/conversation_icon_3"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintBottom_toBottomOf="@id/conversation_icon_3"/>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/conversation_icon_4"
- android:layout_width="@dimen/gesture_tutorial_conversation_icon_size"
- android:layout_height="@dimen/gesture_tutorial_conversation_icon_size"
- android:layout_marginTop="32dp"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="@dimen/gesture_tutorial_conversation_icon_corner_radius"
- app:cardBackgroundColor="@color/mock_list_profile_icon"
- app:layout_constraintTop_toBottomOf="@id/conversation_icon_3"
- app:layout_constraintStart_toStartOf="parent"/>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/conversation_line_7"
- android:layout_width="0dp"
- android:layout_height="18dp"
- android:layout_marginStart="@dimen/gesture_tutorial_conversation_line_padding_start"
- android:layout_marginEnd="@dimen/gesture_tutorial_conversation_line_7_margin_end"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="4dp"
- app:cardBackgroundColor="@color/mock_list_preview_message"
- app:layout_constraintVertical_chainStyle="packed"
- app:layout_constraintTop_toTopOf="@id/conversation_icon_4"
- app:layout_constraintStart_toEndOf="@id/conversation_icon_4"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintBottom_toTopOf="@id/conversation_line_8"/>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/conversation_line_8"
- android:layout_width="0dp"
- android:layout_height="16dp"
- android:layout_marginStart="@dimen/gesture_tutorial_conversation_line_padding_start"
- android:layout_marginEnd="@dimen/gesture_tutorial_conversation_line_8_margin_end"
- android:layout_marginTop="4dp"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="4dp"
- app:cardBackgroundColor="@color/mock_list_preview_message"
- app:layout_constraintTop_toBottomOf="@id/conversation_line_7"
- app:layout_constraintStart_toEndOf="@id/conversation_icon_4"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintBottom_toBottomOf="@id/conversation_icon_4"/>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/conversation_icon_5"
- android:layout_width="@dimen/gesture_tutorial_conversation_icon_size"
- android:layout_height="@dimen/gesture_tutorial_conversation_icon_size"
- android:layout_marginTop="32dp"
- android:visibility="@integer/gesture_tutorial_extra_conversations_visibility"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="@dimen/gesture_tutorial_conversation_icon_corner_radius"
- app:cardBackgroundColor="@color/mock_list_profile_icon"
- app:layout_constraintTop_toBottomOf="@id/conversation_icon_4"
- app:layout_constraintStart_toStartOf="parent"/>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/conversation_line_9"
- android:layout_width="0dp"
- android:layout_height="18dp"
- android:layout_marginStart="@dimen/gesture_tutorial_conversation_line_padding_start"
- android:layout_marginEnd="244dp"
- android:visibility="@integer/gesture_tutorial_extra_conversations_visibility"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="4dp"
- app:cardBackgroundColor="@color/mock_list_preview_message"
- app:layout_constraintVertical_chainStyle="packed"
- app:layout_constraintTop_toTopOf="@id/conversation_icon_5"
- app:layout_constraintStart_toEndOf="@id/conversation_icon_5"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintBottom_toTopOf="@id/conversation_line_10"/>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/conversation_line_10"
- android:layout_width="0dp"
- android:layout_height="16dp"
- android:layout_marginStart="@dimen/gesture_tutorial_conversation_line_padding_start"
- android:layout_marginEnd="143dp"
- android:layout_marginTop="4dp"
- android:visibility="@integer/gesture_tutorial_extra_conversations_visibility"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="4dp"
- app:cardBackgroundColor="@color/mock_list_preview_message"
- app:layout_constraintTop_toBottomOf="@id/conversation_line_9"
- app:layout_constraintStart_toEndOf="@id/conversation_icon_5"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintBottom_toBottomOf="@id/conversation_icon_5"/>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/conversation_icon_6"
- android:layout_width="@dimen/gesture_tutorial_conversation_icon_size"
- android:layout_height="@dimen/gesture_tutorial_conversation_icon_size"
- android:layout_marginTop="32dp"
- android:visibility="@integer/gesture_tutorial_extra_conversations_visibility"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="@dimen/gesture_tutorial_conversation_icon_corner_radius"
- app:cardBackgroundColor="@color/mock_list_profile_icon"
- app:layout_constraintTop_toBottomOf="@id/conversation_icon_5"
- app:layout_constraintStart_toStartOf="parent"/>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/conversation_line_11"
- android:layout_width="0dp"
- android:layout_height="18dp"
- android:layout_marginStart="@dimen/gesture_tutorial_conversation_line_padding_start"
- android:layout_marginEnd="177dp"
- android:visibility="@integer/gesture_tutorial_extra_conversations_visibility"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="4dp"
- app:cardBackgroundColor="@color/mock_list_preview_message"
- app:layout_constraintVertical_chainStyle="packed"
- app:layout_constraintTop_toTopOf="@id/conversation_icon_6"
- app:layout_constraintStart_toEndOf="@id/conversation_icon_6"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintBottom_toTopOf="@id/conversation_line_12"/>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/conversation_line_12"
- android:layout_width="0dp"
- android:layout_height="16dp"
- android:layout_marginStart="@dimen/gesture_tutorial_conversation_line_padding_start"
- android:layout_marginEnd="117dp"
- android:layout_marginTop="4dp"
- android:visibility="@integer/gesture_tutorial_extra_conversations_visibility"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="4dp"
- app:cardBackgroundColor="@color/mock_list_preview_message"
- app:layout_constraintTop_toBottomOf="@id/conversation_line_11"
- app:layout_constraintStart_toEndOf="@id/conversation_icon_6"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintBottom_toBottomOf="@id/conversation_icon_6"/>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/conversation_icon_7"
- android:layout_width="@dimen/gesture_tutorial_conversation_icon_size"
- android:layout_height="@dimen/gesture_tutorial_conversation_icon_size"
- android:layout_marginTop="32dp"
- android:visibility="@integer/gesture_tutorial_extra_conversations_visibility"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="@dimen/gesture_tutorial_conversation_icon_corner_radius"
- app:cardBackgroundColor="@color/mock_list_profile_icon"
- app:layout_constraintTop_toBottomOf="@id/conversation_icon_6"
- app:layout_constraintStart_toStartOf="parent"/>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/conversation_line_13"
- android:layout_width="0dp"
- android:layout_height="18dp"
- android:layout_marginStart="@dimen/gesture_tutorial_conversation_line_padding_start"
- android:layout_marginEnd="189dp"
- android:visibility="@integer/gesture_tutorial_extra_conversations_visibility"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="4dp"
- app:cardBackgroundColor="@color/mock_list_preview_message"
- app:layout_constraintVertical_chainStyle="packed"
- app:layout_constraintTop_toTopOf="@id/conversation_icon_7"
- app:layout_constraintStart_toEndOf="@id/conversation_icon_7"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintBottom_toTopOf="@id/conversation_line_14"/>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/conversation_line_14"
- android:layout_width="0dp"
- android:layout_height="16dp"
- android:layout_marginStart="@dimen/gesture_tutorial_conversation_line_padding_start"
- android:layout_marginEnd="166dp"
- android:layout_marginTop="4dp"
- android:visibility="@integer/gesture_tutorial_extra_conversations_visibility"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="4dp"
- app:cardBackgroundColor="@color/mock_list_preview_message"
- app:layout_constraintTop_toBottomOf="@id/conversation_line_13"
- app:layout_constraintStart_toEndOf="@id/conversation_icon_7"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintBottom_toBottomOf="@id/conversation_icon_7"/>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/mock_button"
- android:layout_width="149dp"
- android:layout_height="56dp"
- android:layout_marginEnd="@dimen/gesture_tutorial_mock_button_margin_end"
- android:layout_marginBottom="@dimen/gesture_tutorial_mock_button_margin_bottom"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="164dp"
- app:cardBackgroundColor="@color/mock_list_button"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintEnd_toEndOf="parent"/>
-
- </androidx.constraintlayout.widget.ConstraintLayout>
-
-</androidx.constraintlayout.widget.ConstraintLayout> \ No newline at end of file
diff --git a/quickstep/res/layout/gesture_tutorial_mock_hotseat.xml b/quickstep/res/layout/gesture_tutorial_mock_hotseat.xml
deleted file mode 100644
index b3e86cf4de..0000000000
--- a/quickstep/res/layout/gesture_tutorial_mock_hotseat.xml
+++ /dev/null
@@ -1,76 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<androidx.constraintlayout.widget.ConstraintLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:app="http://schemas.android.com/apk/res-auto"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:paddingBottom="70dp"
- android:paddingStart="26dp"
- android:paddingEnd="26dp">
-
- <androidx.cardview.widget.CardView
- android:id="@+id/hotseat_icon_1"
- android:layout_width="@dimen/gesture_tutorial_hotseat_icon_size"
- android:layout_height="@dimen/gesture_tutorial_hotseat_icon_size"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="@dimen/gesture_tutorial_hotseat_icon_corner_radius"
- app:cardBackgroundColor="@color/mock_app_icon_1"
- app:layout_constraintDimensionRatio="1:1"
- app:layout_constraintHorizontal_chainStyle="spread_inside"
- app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toStartOf="@id/hotseat_icon_2"/>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/hotseat_icon_2"
- android:layout_width="@dimen/gesture_tutorial_hotseat_icon_size"
- android:layout_height="@dimen/gesture_tutorial_hotseat_icon_size"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="@dimen/gesture_tutorial_hotseat_icon_corner_radius"
- app:cardBackgroundColor="@color/mock_app_icon_2"
- app:layout_constraintDimensionRatio="1:1"
- app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintStart_toEndOf="@id/hotseat_icon_1"
- app:layout_constraintEnd_toStartOf="@id/hotseat_icon_3"/>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/hotseat_icon_3"
- android:layout_width="@dimen/gesture_tutorial_hotseat_icon_size"
- android:layout_height="@dimen/gesture_tutorial_hotseat_icon_size"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="@dimen/gesture_tutorial_hotseat_icon_corner_radius"
- app:cardBackgroundColor="@color/mock_app_icon_3"
- app:layout_constraintDimensionRatio="1:1"
- app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintStart_toEndOf="@id/hotseat_icon_2"
- app:layout_constraintEnd_toStartOf="@id/hotseat_icon_4"/>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/hotseat_icon_4"
- android:layout_width="@dimen/gesture_tutorial_hotseat_icon_size"
- android:layout_height="@dimen/gesture_tutorial_hotseat_icon_size"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="@dimen/gesture_tutorial_hotseat_icon_corner_radius"
- app:cardBackgroundColor="@color/mock_app_icon_4"
- app:layout_constraintDimensionRatio="1:1"
- app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintStart_toEndOf="@id/hotseat_icon_3"
- app:layout_constraintEnd_toEndOf="parent"/>
-
- <androidx.cardview.widget.CardView
- android:layout_width="0dp"
- android:layout_height="@dimen/gesture_tutorial_hotseat_search_height"
- android:layout_marginTop="@dimen/gesture_tutorial_hotseat_icon_search_margin"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="@dimen/gesture_tutorial_hotseat_search_corner_radius"
- app:cardBackgroundColor="@color/mock_search_bar"
- app:layout_constraintTop_toBottomOf="@id/hotseat_icon_1"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toEndOf="parent"/>
-
-</androidx.constraintlayout.widget.ConstraintLayout> \ No newline at end of file
diff --git a/quickstep/res/layout/gesture_tutorial_mock_webpage.xml b/quickstep/res/layout/gesture_tutorial_mock_webpage.xml
deleted file mode 100644
index 0b1b40d1a0..0000000000
--- a/quickstep/res/layout/gesture_tutorial_mock_webpage.xml
+++ /dev/null
@@ -1,277 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2021 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.
--->
-<androidx.constraintlayout.widget.ConstraintLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:app="http://schemas.android.com/apk/res-auto"
- android:layout_width="match_parent"
- android:layout_height="match_parent">
-
- <androidx.constraintlayout.widget.ConstraintLayout
- android:id="@+id/url_bar"
- android:layout_width="match_parent"
- android:layout_height="101dp"
- android:background="@color/mock_webpage_url_bar"
-
- app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toEndOf="parent">
-
- <androidx.cardview.widget.CardView
- android:layout_width="0dp"
- android:layout_height="0dp"
- android:layout_marginTop="48dp"
- android:layout_marginBottom="16dp"
- android:layout_marginStart="@dimen/gesture_tutorial_webpage_url_margin_start_end"
- android:layout_marginEnd="@dimen/gesture_tutorial_webpage_url_margin_start_end"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="100dp"
- app:cardBackgroundColor="@color/mock_webpage_url_bar_item"
- app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toEndOf="parent"/>
-
- </androidx.constraintlayout.widget.ConstraintLayout>
-
- <androidx.constraintlayout.widget.ConstraintLayout
- android:id="@+id/top_bar"
- android:layout_width="match_parent"
- android:layout_height="88dp"
- android:background="@color/mock_webpage_top_bar"
-
- app:layout_constraintTop_toBottomOf="@id/url_bar"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toEndOf="parent">
-
- <androidx.cardview.widget.CardView
- android:id="@+id/top_bar_button"
- android:layout_width="0dp"
- android:layout_height="0dp"
- android:layout_marginTop="22dp"
- android:layout_marginBottom="22dp"
- android:layout_marginStart="@dimen/gesture_tutorial_webpage_top_bar_button_margin_start"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="8dp"
- app:cardBackgroundColor="@color/mock_webpage_top_bar_item"
- app:layout_constraintDimensionRatio="1:1"
- app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintStart_toStartOf="parent"/>
-
- <androidx.cardview.widget.CardView
- android:layout_width="0dp"
- android:layout_height="0dp"
- android:layout_marginTop="28dp"
- android:layout_marginBottom="28dp"
- android:layout_marginStart="@dimen/gesture_tutorial_webpage_top_bar_margin_start"
- android:layout_marginEnd="@dimen/gesture_tutorial_webpage_top_bar_margin_end"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="2dp"
- app:cardBackgroundColor="@color/mock_webpage_top_bar_item"
- app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toEndOf="parent"/>
-
- </androidx.constraintlayout.widget.ConstraintLayout>
-
- <androidx.constraintlayout.widget.ConstraintLayout
- android:layout_width="match_parent"
- android:layout_height="0dp"
- android:background="@color/mock_webpage_background"
- android:paddingTop="@dimen/gesture_tutorial_webpage_padding_top"
- android:paddingStart="24dp"
-
- app:layout_constraintTop_toBottomOf="@id/top_bar"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toEndOf="parent">
-
- <androidx.cardview.widget.CardView
- android:id="@+id/mock_line_1"
- android:layout_width="0dp"
- android:layout_height="@dimen/gesture_tutorial_webpage_large_line_height"
- android:layout_marginEnd="@dimen/gesture_tutorial_webpage_line_1_margin_end"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="@dimen/gesture_tutorial_webpage_small_corner_radius"
- app:cardBackgroundColor="@color/mock_webpage_page_text"
- app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toEndOf="parent"/>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/mock_line_2"
- android:layout_width="0dp"
- android:layout_height="@dimen/gesture_tutorial_webpage_large_line_height"
- android:layout_marginTop="@dimen/gesture_tutorial_webpage_small_margin_top"
- android:layout_marginEnd="@dimen/gesture_tutorial_webpage_line_2_margin_end"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="@dimen/gesture_tutorial_webpage_small_corner_radius"
- app:cardBackgroundColor="@color/mock_webpage_page_text"
- app:layout_constraintTop_toBottomOf="@id/mock_line_1"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toEndOf="parent"/>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/mock_line_3"
- android:layout_width="0dp"
- android:layout_height="@dimen/gesture_tutorial_webpage_large_line_height"
- android:layout_marginTop="@dimen/gesture_tutorial_webpage_small_margin_top"
- android:layout_marginEnd="@dimen/gesture_tutorial_webpage_line_3_margin_end"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="@dimen/gesture_tutorial_webpage_small_corner_radius"
- app:cardBackgroundColor="@color/mock_webpage_page_text"
- app:layout_constraintTop_toBottomOf="@id/mock_line_2"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toEndOf="parent"/>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/mock_button"
- android:layout_width="47dp"
- android:layout_height="12dp"
- android:layout_marginTop="@dimen/gesture_tutorial_webpage_small_margin_top"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="@dimen/gesture_tutorial_webpage_small_corner_radius"
- app:cardBackgroundColor="@color/mock_webpage_page_text"
- app:layout_constraintTop_toBottomOf="@id/mock_line_3"
- app:layout_constraintStart_toStartOf="parent"/>
-
- <androidx.cardview.widget.CardView
- android:layout_width="47dp"
- android:layout_height="12dp"
- android:background="@color/mock_webpage_page_text"
- android:layout_marginStart="11dp"
- android:layout_marginTop="@dimen/gesture_tutorial_webpage_small_margin_top"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="@dimen/gesture_tutorial_webpage_small_corner_radius"
- app:cardBackgroundColor="@color/mock_webpage_page_text"
- app:layout_constraintTop_toBottomOf="@id/mock_line_3"
- app:layout_constraintStart_toEndOf="@id/mock_button"/>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/mock_block"
- android:layout_width="0dp"
- android:layout_height="240dp"
- android:layout_marginTop="@dimen/gesture_tutorial_webpage_large_margin_top"
- android:layout_marginEnd="@dimen/gesture_tutorial_webpage_block_margin_end"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="@dimen/gesture_tutorial_webpage_large_corner_radius"
- app:cardBackgroundColor="@color/mock_webpage_page_text"
- app:layout_constraintTop_toBottomOf="@id/mock_button"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toEndOf="parent"/>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/mock_line_4"
- android:layout_width="0dp"
- android:layout_height="@dimen/gesture_tutorial_webpage_small_line_height"
- android:layout_marginTop="@dimen/gesture_tutorial_webpage_large_margin_top"
- android:layout_marginEnd="52dp"
- android:visibility="@integer/gesture_tutorial_webpage_extra_lines_visibility"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="@dimen/gesture_tutorial_webpage_medium_corner_radius"
- app:cardBackgroundColor="@color/mock_webpage_page_text"
- app:layout_constraintTop_toBottomOf="@id/mock_block"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toEndOf="parent"/>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/mock_line_5"
- android:layout_width="0dp"
- android:layout_height="@dimen/gesture_tutorial_webpage_small_line_height"
- android:layout_marginTop="@dimen/gesture_tutorial_webpage_small_margin_top"
- android:layout_marginEnd="41dp"
- android:visibility="@integer/gesture_tutorial_webpage_extra_lines_visibility"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="@dimen/gesture_tutorial_webpage_medium_corner_radius"
- app:cardBackgroundColor="@color/mock_webpage_page_text"
- app:layout_constraintTop_toBottomOf="@id/mock_line_4"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toEndOf="parent"/>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/mock_line_6"
- android:layout_width="0dp"
- android:layout_height="@dimen/gesture_tutorial_webpage_small_line_height"
- android:layout_marginTop="@dimen/gesture_tutorial_webpage_small_margin_top"
- android:layout_marginEnd="71dp"
- android:visibility="@integer/gesture_tutorial_webpage_extra_lines_visibility"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="@dimen/gesture_tutorial_webpage_medium_corner_radius"
- app:cardBackgroundColor="@color/mock_webpage_page_text"
- app:layout_constraintTop_toBottomOf="@id/mock_line_5"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toEndOf="parent"/>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/mock_line_7"
- android:layout_width="0dp"
- android:layout_height="@dimen/gesture_tutorial_webpage_small_line_height"
- android:layout_marginTop="@dimen/gesture_tutorial_webpage_small_margin_top"
- android:layout_marginEnd="198dp"
- android:visibility="@integer/gesture_tutorial_webpage_extra_lines_visibility"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="@dimen/gesture_tutorial_webpage_medium_corner_radius"
- app:cardBackgroundColor="@color/mock_webpage_page_text"
- app:layout_constraintTop_toBottomOf="@id/mock_line_6"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toEndOf="parent"/>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/mock_line_8"
- android:layout_width="0dp"
- android:layout_height="@dimen/gesture_tutorial_webpage_small_line_height"
- android:layout_marginTop="@dimen/gesture_tutorial_webpage_large_margin_top"
- android:layout_marginEnd="64dp"
- android:visibility="@integer/gesture_tutorial_webpage_extra_lines_visibility"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="@dimen/gesture_tutorial_webpage_medium_corner_radius"
- app:cardBackgroundColor="@color/mock_webpage_page_text"
- app:layout_constraintTop_toBottomOf="@id/mock_line_7"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toEndOf="parent"/>
-
- <androidx.cardview.widget.CardView
- android:layout_width="0dp"
- android:layout_height="@dimen/gesture_tutorial_webpage_small_line_height"
- android:layout_marginTop="@dimen/gesture_tutorial_webpage_small_margin_top"
- android:layout_marginEnd="71dp"
- android:visibility="@integer/gesture_tutorial_webpage_extra_lines_visibility"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="@dimen/gesture_tutorial_webpage_medium_corner_radius"
- app:cardBackgroundColor="@color/mock_webpage_page_text"
- app:layout_constraintTop_toBottomOf="@id/mock_line_8"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toEndOf="parent"/>
-
- </androidx.constraintlayout.widget.ConstraintLayout>
-
-</androidx.constraintlayout.widget.ConstraintLayout> \ No newline at end of file
diff --git a/quickstep/res/layout/gesture_tutorial_tablet_mock_conversation.xml b/quickstep/res/layout/gesture_tutorial_tablet_mock_conversation.xml
deleted file mode 100644
index c8cf8c3cf2..0000000000
--- a/quickstep/res/layout/gesture_tutorial_tablet_mock_conversation.xml
+++ /dev/null
@@ -1,239 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2021 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.
--->
-<androidx.constraintlayout.widget.ConstraintLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:app="http://schemas.android.com/apk/res-auto"
- android:layout_width="match_parent"
- android:layout_height="match_parent">
-
- <androidx.constraintlayout.widget.ConstraintLayout
- android:id="@+id/top_bar"
- android:layout_width="match_parent"
- android:layout_height="101dp"
- android:background="@color/mock_conversation_top_bar"
-
- app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toEndOf="parent">
-
- <androidx.cardview.widget.CardView
- android:layout_width="0dp"
- android:layout_height="0dp"
- android:layout_marginTop="43dp"
- android:layout_marginBottom="22dp"
- android:layout_marginStart="126dp"
- android:layout_marginEnd="548dp"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="4dp"
- app:cardBackgroundColor="@color/mock_conversation_top_bar_item"
- app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toEndOf="parent"/>
-
- <androidx.cardview.widget.CardView
- android:layout_width="0dp"
- android:layout_height="0dp"
- android:layout_marginTop="43dp"
- android:layout_marginBottom="22dp"
- android:layout_marginStart="300dp"
- android:layout_marginEnd="16dp"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="4dp"
- app:cardBackgroundColor="@color/mock_conversation_top_bar_item"
- app:layout_constraintDimensionRatio="1:1"
- app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintEnd_toStartOf="@id/top_bar_button"/>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/top_bar_button"
- android:layout_width="0dp"
- android:layout_height="0dp"
- android:layout_marginTop="43dp"
- android:layout_marginBottom="22dp"
- android:layout_marginStart="300dp"
- android:layout_marginEnd="126dp"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="4dp"
- app:cardBackgroundColor="@color/mock_conversation_top_bar_item"
- app:layout_constraintDimensionRatio="1:1"
- app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintEnd_toEndOf="parent"/>
-
- </androidx.constraintlayout.widget.ConstraintLayout>
-
- <androidx.constraintlayout.widget.ConstraintLayout
- android:layout_width="match_parent"
- android:layout_height="0dp"
- android:background="@color/mock_conversation_background"
- android:paddingBottom="@dimen/gesture_tutorial_mock_taskbar_height"
-
- app:layout_constraintTop_toBottomOf="@id/top_bar"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toEndOf="parent">
-
- <androidx.constraintlayout.widget.ConstraintLayout
- android:layout_width="match_parent"
- android:layout_height="0dp"
- android:paddingBottom="@dimen/gesture_tutorial_message_input_margin_top"
-
- app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintBottom_toTopOf="@id/message_bar"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toEndOf="parent">
-
- <androidx.cardview.widget.CardView
- android:id="@+id/message_1"
- android:layout_width="0dp"
- android:layout_height="112dp"
- android:layout_marginBottom="@dimen/gesture_tutorial_message_large_margin_bottom"
- android:layout_marginStart="@dimen/gesture_tutorial_tablet_message_1_margin"
- android:layout_marginEnd="@dimen/gesture_tutorial_tablet_message_padding_start_end"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="18dp"
- app:cardBackgroundColor="@color/mock_conversation_sent_message"
- app:layout_constraintBottom_toTopOf="@id/reply_icon_1"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toEndOf="parent"/>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/reply_icon_1"
- android:layout_width="@dimen/gesture_tutorial_message_icon_size"
- android:layout_height="@dimen/gesture_tutorial_message_icon_size"
- android:layout_marginBottom="@dimen/gesture_tutorial_message_large_margin_bottom"
- android:layout_marginStart="@dimen/gesture_tutorial_tablet_message_padding_start_end"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="@dimen/gesture_tutorial_message_icon_corner_radius"
- app:cardBackgroundColor="@color/mock_conversation_profile_icon"
- app:layout_constraintDimensionRatio="1:1"
- app:layout_constraintBottom_toTopOf="@id/message_2"
- app:layout_constraintStart_toStartOf="parent"/>
-
- <androidx.cardview.widget.CardView
- android:layout_width="0dp"
- android:layout_height="36dp"
- android:layout_marginStart="17dp"
- android:layout_marginEnd="@dimen/gesture_tutorial_tablet_reply_1_margin"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="18dp"
- app:cardBackgroundColor="@color/mock_conversation_received_message"
- app:layout_constraintTop_toTopOf="@id/reply_icon_1"
- app:layout_constraintBottom_toBottomOf="@id/reply_icon_1"
- app:layout_constraintStart_toEndOf="@id/reply_icon_1"
- app:layout_constraintEnd_toEndOf="parent"/>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/message_2"
- android:layout_width="0dp"
- android:layout_height="36dp"
- android:layout_marginBottom="@dimen/gesture_tutorial_message_small_margin_bottom"
- android:layout_marginStart="@dimen/gesture_tutorial_tablet_message_2_margin"
- android:layout_marginEnd="@dimen/gesture_tutorial_tablet_message_padding_start_end"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="18dp"
- app:cardBackgroundColor="@color/mock_conversation_sent_message"
- app:layout_constraintBottom_toTopOf="@id/message_3"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toEndOf="parent"/>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/message_3"
- android:layout_width="0dp"
- android:layout_height="74dp"
- android:layout_marginBottom="@dimen/gesture_tutorial_message_large_margin_bottom"
- android:layout_marginStart="@dimen/gesture_tutorial_tablet_message_3_margin"
- android:layout_marginEnd="@dimen/gesture_tutorial_tablet_message_padding_start_end"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="18dp"
- app:cardBackgroundColor="@color/mock_conversation_sent_message"
- app:layout_constraintBottom_toTopOf="@id/reply_icon_2"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toEndOf="parent"/>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/reply_icon_2"
- android:layout_width="@dimen/gesture_tutorial_message_icon_size"
- android:layout_height="@dimen/gesture_tutorial_message_icon_size"
- android:layout_marginBottom="32dp"
- android:layout_marginStart="@dimen/gesture_tutorial_tablet_message_padding_start_end"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="@dimen/gesture_tutorial_message_icon_corner_radius"
- app:cardBackgroundColor="@color/mock_conversation_profile_icon"
- app:layout_constraintDimensionRatio="1:1"
- app:layout_constraintBottom_toTopOf="@id/message_4"
- app:layout_constraintStart_toStartOf="parent"/>
-
- <androidx.cardview.widget.CardView
- android:layout_width="0dp"
- android:layout_height="36dp"
- android:layout_marginStart="17dp"
- android:layout_marginEnd="@dimen/gesture_tutorial_tablet_reply_2_margin"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="18dp"
- app:cardBackgroundColor="@color/mock_conversation_received_message"
- app:layout_constraintTop_toTopOf="@id/reply_icon_2"
- app:layout_constraintBottom_toBottomOf="@id/reply_icon_2"
- app:layout_constraintStart_toEndOf="@id/reply_icon_2"
- app:layout_constraintEnd_toEndOf="parent"/>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/message_4"
- android:layout_width="0dp"
- android:layout_height="74dp"
- android:layout_marginStart="345dp"
- android:layout_marginEnd="@dimen/gesture_tutorial_tablet_message_padding_start_end"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="18dp"
- app:cardBackgroundColor="@color/mock_conversation_sent_message"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toEndOf="parent"/>
-
- </androidx.constraintlayout.widget.ConstraintLayout>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/message_bar"
- android:layout_width="0dp"
- android:layout_height="44dp"
- android:layout_marginTop="36dp"
- android:layout_marginBottom="24dp"
- android:layout_marginStart="134dp"
- android:layout_marginEnd="126dp"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="164dp"
- app:cardBackgroundColor="@color/mock_conversation_message_input"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toEndOf="parent" />
-
- </androidx.constraintlayout.widget.ConstraintLayout>
-
-</androidx.constraintlayout.widget.ConstraintLayout> \ No newline at end of file
diff --git a/quickstep/res/layout/gesture_tutorial_tablet_mock_conversation_list.xml b/quickstep/res/layout/gesture_tutorial_tablet_mock_conversation_list.xml
deleted file mode 100644
index 0fb0677673..0000000000
--- a/quickstep/res/layout/gesture_tutorial_tablet_mock_conversation_list.xml
+++ /dev/null
@@ -1,396 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2021 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.
--->
-<androidx.constraintlayout.widget.ConstraintLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:app="http://schemas.android.com/apk/res-auto"
- android:layout_width="match_parent"
- android:layout_height="match_parent">
-
- <androidx.constraintlayout.widget.ConstraintLayout
- android:id="@+id/top_bar"
- android:layout_width="match_parent"
- android:layout_height="101dp"
- android:background="@color/mock_list_top_bar"
-
- app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toEndOf="parent">
-
- <androidx.cardview.widget.CardView
- android:layout_width="0dp"
- android:layout_height="0dp"
- android:layout_marginTop="43dp"
- android:layout_marginBottom="22dp"
- android:layout_marginStart="126dp"
- android:layout_marginEnd="126dp"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="4dp"
- app:cardBackgroundColor="@color/mock_list_top_bar_item"
- app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toEndOf="parent"/>
-
- </androidx.constraintlayout.widget.ConstraintLayout>
-
- <androidx.constraintlayout.widget.ConstraintLayout
- android:layout_width="match_parent"
- android:layout_height="0dp"
- android:background="@color/mock_list_background"
- android:paddingBottom="@dimen/gesture_tutorial_mock_taskbar_height"
-
- app:layout_constraintTop_toBottomOf="@id/top_bar"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toEndOf="parent">
-
- <androidx.constraintlayout.widget.ConstraintLayout
- android:layout_width="0dp"
- android:layout_height="0dp"
- android:paddingTop="@dimen/gesture_tutorial_conversation_list_padding_top"
- android:paddingStart="126dp"
-
- app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toEndOf="parent">
-
- <androidx.cardview.widget.CardView
- android:id="@+id/conversation_icon_1"
- android:layout_width="@dimen/gesture_tutorial_conversation_icon_size"
- android:layout_height="@dimen/gesture_tutorial_conversation_icon_size"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="@dimen/gesture_tutorial_conversation_icon_corner_radius"
- app:cardBackgroundColor="@color/mock_list_profile_icon"
- app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintStart_toStartOf="parent"/>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/conversation_line_1"
- android:layout_width="0dp"
- android:layout_height="18dp"
- android:layout_marginStart="@dimen/gesture_tutorial_conversation_line_padding_start"
- android:layout_marginEnd="270dp"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="4dp"
- app:cardBackgroundColor="@color/mock_list_preview_message"
- app:layout_constraintVertical_chainStyle="packed"
- app:layout_constraintTop_toTopOf="@id/conversation_icon_1"
- app:layout_constraintStart_toEndOf="@id/conversation_icon_1"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintBottom_toTopOf="@id/conversation_line_2"/>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/conversation_line_2"
- android:layout_width="0dp"
- android:layout_height="16dp"
- android:layout_marginStart="@dimen/gesture_tutorial_conversation_line_padding_start"
- android:layout_marginEnd="110dp"
- android:layout_marginTop="4dp"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="4dp"
- app:cardBackgroundColor="@color/mock_list_preview_message"
- app:layout_constraintTop_toBottomOf="@id/conversation_line_1"
- app:layout_constraintStart_toEndOf="@id/conversation_icon_1"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintBottom_toBottomOf="@id/conversation_icon_1"/>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/conversation_icon_2"
- android:layout_width="@dimen/gesture_tutorial_conversation_icon_size"
- android:layout_height="@dimen/gesture_tutorial_conversation_icon_size"
- android:layout_marginTop="32dp"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="@dimen/gesture_tutorial_conversation_icon_corner_radius"
- app:cardBackgroundColor="@color/mock_list_profile_icon"
- app:layout_constraintTop_toBottomOf="@id/conversation_icon_1"
- app:layout_constraintStart_toStartOf="parent"/>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/conversation_line_3"
- android:layout_width="0dp"
- android:layout_height="18dp"
- android:layout_marginStart="@dimen/gesture_tutorial_conversation_line_padding_start"
- android:layout_marginEnd="243dp"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="4dp"
- app:cardBackgroundColor="@color/mock_list_preview_message"
- app:layout_constraintVertical_chainStyle="packed"
- app:layout_constraintTop_toTopOf="@id/conversation_icon_2"
- app:layout_constraintStart_toEndOf="@id/conversation_icon_2"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintBottom_toTopOf="@id/conversation_line_4"/>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/conversation_line_4"
- android:layout_width="0dp"
- android:layout_height="16dp"
- android:layout_marginStart="@dimen/gesture_tutorial_conversation_line_padding_start"
- android:layout_marginEnd="154dp"
- android:layout_marginTop="4dp"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="4dp"
- app:cardBackgroundColor="@color/mock_list_preview_message"
- app:layout_constraintTop_toBottomOf="@id/conversation_line_3"
- app:layout_constraintStart_toEndOf="@id/conversation_icon_2"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintBottom_toBottomOf="@id/conversation_icon_2"/>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/conversation_icon_3"
- android:layout_width="@dimen/gesture_tutorial_conversation_icon_size"
- android:layout_height="@dimen/gesture_tutorial_conversation_icon_size"
- android:layout_marginTop="32dp"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="@dimen/gesture_tutorial_conversation_icon_corner_radius"
- app:cardBackgroundColor="@color/mock_list_profile_icon"
- app:layout_constraintTop_toBottomOf="@id/conversation_icon_2"
- app:layout_constraintStart_toStartOf="parent"/>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/conversation_line_5"
- android:layout_width="0dp"
- android:layout_height="18dp"
- android:layout_marginStart="@dimen/gesture_tutorial_conversation_line_padding_start"
- android:layout_marginEnd="251dp"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="4dp"
- app:cardBackgroundColor="@color/mock_list_preview_message"
- app:layout_constraintVertical_chainStyle="packed"
- app:layout_constraintTop_toTopOf="@id/conversation_icon_3"
- app:layout_constraintStart_toEndOf="@id/conversation_icon_3"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintBottom_toTopOf="@id/conversation_line_6"/>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/conversation_line_6"
- android:layout_width="0dp"
- android:layout_height="16dp"
- android:layout_marginStart="@dimen/gesture_tutorial_conversation_line_padding_start"
- android:layout_marginEnd="@dimen/gesture_tutorial_tablet_conversation_line_6_margin_end"
- android:layout_marginTop="4dp"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="4dp"
- app:cardBackgroundColor="@color/mock_list_preview_message"
- app:layout_constraintTop_toBottomOf="@id/conversation_line_5"
- app:layout_constraintStart_toEndOf="@id/conversation_icon_3"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintBottom_toBottomOf="@id/conversation_icon_3"/>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/conversation_icon_4"
- android:layout_width="@dimen/gesture_tutorial_conversation_icon_size"
- android:layout_height="@dimen/gesture_tutorial_conversation_icon_size"
- android:layout_marginTop="32dp"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="@dimen/gesture_tutorial_conversation_icon_corner_radius"
- app:cardBackgroundColor="@color/mock_list_profile_icon"
- app:layout_constraintTop_toBottomOf="@id/conversation_icon_3"
- app:layout_constraintStart_toStartOf="parent"/>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/conversation_line_7"
- android:layout_width="0dp"
- android:layout_height="18dp"
- android:layout_marginStart="@dimen/gesture_tutorial_conversation_line_padding_start"
- android:layout_marginEnd="227dp"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="4dp"
- app:cardBackgroundColor="@color/mock_list_preview_message"
- app:layout_constraintVertical_chainStyle="packed"
- app:layout_constraintTop_toTopOf="@id/conversation_icon_4"
- app:layout_constraintStart_toEndOf="@id/conversation_icon_4"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintBottom_toTopOf="@id/conversation_line_8"/>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/conversation_line_8"
- android:layout_width="0dp"
- android:layout_height="16dp"
- android:layout_marginStart="@dimen/gesture_tutorial_conversation_line_padding_start"
- android:layout_marginEnd="@dimen/gesture_tutorial_tablet_conversation_line_8_margin_end"
- android:layout_marginTop="4dp"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="4dp"
- app:cardBackgroundColor="@color/mock_list_preview_message"
- app:layout_constraintTop_toBottomOf="@id/conversation_line_7"
- app:layout_constraintStart_toEndOf="@id/conversation_icon_4"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintBottom_toBottomOf="@id/conversation_icon_4"/>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/conversation_icon_5"
- android:layout_width="@dimen/gesture_tutorial_conversation_icon_size"
- android:layout_height="@dimen/gesture_tutorial_conversation_icon_size"
- android:layout_marginTop="32dp"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="@dimen/gesture_tutorial_conversation_icon_corner_radius"
- app:cardBackgroundColor="@color/mock_list_profile_icon"
- app:layout_constraintTop_toBottomOf="@id/conversation_icon_4"
- app:layout_constraintStart_toStartOf="parent"/>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/conversation_line_9"
- android:layout_width="0dp"
- android:layout_height="18dp"
- android:layout_marginStart="@dimen/gesture_tutorial_conversation_line_padding_start"
- android:layout_marginEnd="297dp"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="4dp"
- app:cardBackgroundColor="@color/mock_list_preview_message"
- app:layout_constraintVertical_chainStyle="packed"
- app:layout_constraintTop_toTopOf="@id/conversation_icon_5"
- app:layout_constraintStart_toEndOf="@id/conversation_icon_5"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintBottom_toTopOf="@id/conversation_line_10"/>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/conversation_line_10"
- android:layout_width="0dp"
- android:layout_height="16dp"
- android:layout_marginStart="@dimen/gesture_tutorial_conversation_line_padding_start"
- android:layout_marginEnd="@dimen/gesture_tutorial_tablet_conversation_line_10_margin_end"
- android:layout_marginTop="4dp"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="4dp"
- app:cardBackgroundColor="@color/mock_list_preview_message"
- app:layout_constraintTop_toBottomOf="@id/conversation_line_9"
- app:layout_constraintStart_toEndOf="@id/conversation_icon_5"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintBottom_toBottomOf="@id/conversation_icon_5"/>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/conversation_icon_6"
- android:layout_width="@dimen/gesture_tutorial_conversation_icon_size"
- android:layout_height="@dimen/gesture_tutorial_conversation_icon_size"
- android:layout_marginTop="32dp"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="@dimen/gesture_tutorial_conversation_icon_corner_radius"
- app:cardBackgroundColor="@color/mock_list_profile_icon"
- app:layout_constraintTop_toBottomOf="@id/conversation_icon_5"
- app:layout_constraintStart_toStartOf="parent"/>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/conversation_line_11"
- android:layout_width="0dp"
- android:layout_height="18dp"
- android:layout_marginStart="@dimen/gesture_tutorial_conversation_line_padding_start"
- android:layout_marginEnd="230dp"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="4dp"
- app:cardBackgroundColor="@color/mock_list_preview_message"
- app:layout_constraintVertical_chainStyle="packed"
- app:layout_constraintTop_toTopOf="@id/conversation_icon_6"
- app:layout_constraintStart_toEndOf="@id/conversation_icon_6"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintBottom_toTopOf="@id/conversation_line_12"/>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/conversation_line_12"
- android:layout_width="0dp"
- android:layout_height="16dp"
- android:layout_marginStart="@dimen/gesture_tutorial_conversation_line_padding_start"
- android:layout_marginEnd="72dp"
- android:layout_marginTop="4dp"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="4dp"
- app:cardBackgroundColor="@color/mock_list_preview_message"
- app:layout_constraintTop_toBottomOf="@id/conversation_line_11"
- app:layout_constraintStart_toEndOf="@id/conversation_icon_6"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintBottom_toBottomOf="@id/conversation_icon_6"/>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/conversation_icon_7"
- android:layout_width="@dimen/gesture_tutorial_conversation_icon_size"
- android:layout_height="@dimen/gesture_tutorial_conversation_icon_size"
- android:layout_marginTop="32dp"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="@dimen/gesture_tutorial_conversation_icon_corner_radius"
- app:cardBackgroundColor="@color/mock_list_profile_icon"
- app:layout_constraintTop_toBottomOf="@id/conversation_icon_6"
- app:layout_constraintStart_toStartOf="parent"/>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/conversation_line_13"
- android:layout_width="0dp"
- android:layout_height="18dp"
- android:layout_marginStart="@dimen/gesture_tutorial_conversation_line_padding_start"
- android:layout_marginEnd="242dp"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="4dp"
- app:cardBackgroundColor="@color/mock_list_preview_message"
- app:layout_constraintVertical_chainStyle="packed"
- app:layout_constraintTop_toTopOf="@id/conversation_icon_7"
- app:layout_constraintStart_toEndOf="@id/conversation_icon_7"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintBottom_toTopOf="@id/conversation_line_14"/>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/conversation_line_14"
- android:layout_width="0dp"
- android:layout_height="16dp"
- android:layout_marginStart="@dimen/gesture_tutorial_conversation_line_padding_start"
- android:layout_marginEnd="219dp"
- android:layout_marginTop="4dp"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="4dp"
- app:cardBackgroundColor="@color/mock_list_preview_message"
- app:layout_constraintTop_toBottomOf="@id/conversation_line_13"
- app:layout_constraintStart_toEndOf="@id/conversation_icon_7"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintBottom_toBottomOf="@id/conversation_icon_7"/>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/mock_button"
- android:layout_width="149dp"
- android:layout_height="56dp"
- android:layout_marginEnd="126dp"
- android:layout_marginBottom="24dp"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="164dp"
- app:cardBackgroundColor="@color/mock_list_button"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintEnd_toEndOf="parent"/>
-
- </androidx.constraintlayout.widget.ConstraintLayout>
-
- </androidx.constraintlayout.widget.ConstraintLayout>
-
-</androidx.constraintlayout.widget.ConstraintLayout> \ No newline at end of file
diff --git a/quickstep/res/layout/gesture_tutorial_tablet_mock_hotseat.xml b/quickstep/res/layout/gesture_tutorial_tablet_mock_hotseat.xml
deleted file mode 100644
index 027e4a05b0..0000000000
--- a/quickstep/res/layout/gesture_tutorial_tablet_mock_hotseat.xml
+++ /dev/null
@@ -1,122 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2022 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<androidx.constraintlayout.widget.ConstraintLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:app="http://schemas.android.com/apk/res-auto"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:paddingBottom="32dp"
- android:paddingStart="@dimen/gesture_tutorial_hotseat_padding_start_end"
- android:paddingEnd="@dimen/gesture_tutorial_hotseat_padding_start_end">
-
- <androidx.cardview.widget.CardView
- android:id="@+id/hotseat_search_bar"
- android:layout_width="0dp"
- android:layout_height="@dimen/gesture_tutorial_hotseat_search_height"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="@dimen/gesture_tutorial_hotseat_search_corner_radius"
- app:cardBackgroundColor="@color/mock_search_bar"
- app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toEndOf="parent"/>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/hotseat_icon_1"
- android:layout_width="@dimen/gesture_tutorial_hotseat_icon_size"
- android:layout_height="@dimen/gesture_tutorial_hotseat_icon_size"
- android:layout_marginTop="@dimen/gesture_tutorial_hotseat_icon_search_margin"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="@dimen/gesture_tutorial_hotseat_icon_corner_radius"
- app:cardBackgroundColor="@color/mock_app_icon_1"
- app:layout_constraintDimensionRatio="1:1"
- app:layout_constraintHorizontal_chainStyle="spread_inside"
- app:layout_constraintTop_toBottomOf="@id/hotseat_search_bar"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toStartOf="@id/hotseat_icon_2"/>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/hotseat_icon_2"
- android:layout_width="@dimen/gesture_tutorial_hotseat_icon_size"
- android:layout_height="@dimen/gesture_tutorial_hotseat_icon_size"
- android:layout_marginTop="@dimen/gesture_tutorial_hotseat_icon_search_margin"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="@dimen/gesture_tutorial_hotseat_icon_corner_radius"
- app:cardBackgroundColor="@color/mock_app_icon_2"
- app:layout_constraintDimensionRatio="1:1"
- app:layout_constraintTop_toBottomOf="@id/hotseat_search_bar"
- app:layout_constraintStart_toEndOf="@id/hotseat_icon_1"
- app:layout_constraintEnd_toStartOf="@id/hotseat_icon_3"/>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/hotseat_icon_3"
- android:layout_width="@dimen/gesture_tutorial_hotseat_icon_size"
- android:layout_height="@dimen/gesture_tutorial_hotseat_icon_size"
- android:layout_marginTop="@dimen/gesture_tutorial_hotseat_icon_search_margin"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="@dimen/gesture_tutorial_hotseat_icon_corner_radius"
- app:cardBackgroundColor="@color/mock_app_icon_3"
- app:layout_constraintDimensionRatio="1:1"
- app:layout_constraintTop_toBottomOf="@id/hotseat_search_bar"
- app:layout_constraintStart_toEndOf="@id/hotseat_icon_2"
- app:layout_constraintEnd_toStartOf="@id/hotseat_icon_4"/>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/hotseat_icon_4"
- android:layout_width="@dimen/gesture_tutorial_hotseat_icon_size"
- android:layout_height="@dimen/gesture_tutorial_hotseat_icon_size"
- android:layout_marginTop="@dimen/gesture_tutorial_hotseat_icon_search_margin"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="@dimen/gesture_tutorial_hotseat_icon_corner_radius"
- app:cardBackgroundColor="@color/mock_app_icon_1"
- app:layout_constraintDimensionRatio="1:1"
- app:layout_constraintTop_toBottomOf="@id/hotseat_search_bar"
- app:layout_constraintStart_toEndOf="@id/hotseat_icon_3"
- app:layout_constraintEnd_toStartOf="@id/hotseat_icon_5"/>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/hotseat_icon_5"
- android:layout_width="@dimen/gesture_tutorial_hotseat_icon_size"
- android:layout_height="@dimen/gesture_tutorial_hotseat_icon_size"
- android:layout_marginTop="@dimen/gesture_tutorial_hotseat_icon_search_margin"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="@dimen/gesture_tutorial_hotseat_icon_corner_radius"
- app:cardBackgroundColor="@color/mock_app_icon_4"
- app:layout_constraintDimensionRatio="1:1"
- app:layout_constraintTop_toBottomOf="@id/hotseat_search_bar"
- app:layout_constraintStart_toEndOf="@id/hotseat_icon_4"
- app:layout_constraintEnd_toStartOf="@id/hotseat_icon_6"/>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/hotseat_icon_6"
- android:layout_width="@dimen/gesture_tutorial_hotseat_icon_size"
- android:layout_height="@dimen/gesture_tutorial_hotseat_icon_size"
- android:layout_marginTop="@dimen/gesture_tutorial_hotseat_icon_search_margin"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="@dimen/gesture_tutorial_hotseat_icon_corner_radius"
- app:cardBackgroundColor="@color/mock_app_icon_2"
- app:layout_constraintDimensionRatio="1:1"
- app:layout_constraintTop_toBottomOf="@id/hotseat_search_bar"
- app:layout_constraintStart_toEndOf="@id/hotseat_icon_5"
- app:layout_constraintEnd_toEndOf="parent"/>
-
-</androidx.constraintlayout.widget.ConstraintLayout> \ No newline at end of file
diff --git a/quickstep/res/layout/gesture_tutorial_tablet_mock_taskbar.xml b/quickstep/res/layout/gesture_tutorial_tablet_mock_taskbar.xml
deleted file mode 100644
index ddfeeecf04..0000000000
--- a/quickstep/res/layout/gesture_tutorial_tablet_mock_taskbar.xml
+++ /dev/null
@@ -1,118 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<com.android.quickstep.interaction.AnimatedTaskbarView
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:app="http://schemas.android.com/apk/res-auto"
- android:layout_width="match_parent"
- android:layout_height="@dimen/gesture_tutorial_mock_taskbar_height">
-
- <View
- android:id="@+id/taskbar_background"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:background="@color/gesture_tutorial_taskbar_color"
-
- app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toEndOf="parent"/>
-
- <androidx.constraintlayout.widget.ConstraintLayout
- android:id="@+id/icon_container"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
-
- app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toEndOf="parent">
-
- <androidx.cardview.widget.CardView
- android:id="@+id/taskbar_icon_1"
- android:layout_width="@dimen/gesture_tutorial_taskbar_icon_size"
- android:layout_height="@dimen/gesture_tutorial_taskbar_icon_size"
- android:layout_marginStart="@dimen/gesture_tutorial_taskbar_padding_start_end"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="@dimen/gesture_tutorial_taskbar_icon_corner_radius"
- app:cardBackgroundColor="@color/mock_app_icon_1"
- app:layout_constraintDimensionRatio="1:1"
- app:layout_constraintHorizontal_chainStyle="spread_inside"
- app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toStartOf="@id/taskbar_icon_2"/>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/taskbar_icon_2"
- android:layout_width="@dimen/gesture_tutorial_taskbar_icon_size"
- android:layout_height="@dimen/gesture_tutorial_taskbar_icon_size"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="@dimen/gesture_tutorial_taskbar_icon_corner_radius"
- app:cardBackgroundColor="@color/mock_app_icon_2"
- app:layout_constraintDimensionRatio="1:1"
- app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintStart_toEndOf="@id/taskbar_icon_1"
- app:layout_constraintEnd_toStartOf="@id/taskbar_icon_3"/>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/taskbar_icon_3"
- android:layout_width="@dimen/gesture_tutorial_taskbar_icon_size"
- android:layout_height="@dimen/gesture_tutorial_taskbar_icon_size"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="@dimen/gesture_tutorial_taskbar_icon_corner_radius"
- app:cardBackgroundColor="@color/mock_app_icon_3"
- app:layout_constraintDimensionRatio="1:1"
- app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintStart_toEndOf="@id/taskbar_icon_2"
- app:layout_constraintEnd_toStartOf="@id/taskbar_icon_4"/>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/taskbar_icon_4"
- android:layout_width="@dimen/gesture_tutorial_taskbar_icon_size"
- android:layout_height="@dimen/gesture_tutorial_taskbar_icon_size"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="@dimen/gesture_tutorial_taskbar_icon_corner_radius"
- app:cardBackgroundColor="@color/mock_app_icon_1"
- app:layout_constraintDimensionRatio="1:1"
- app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintStart_toEndOf="@id/taskbar_icon_3"
- app:layout_constraintEnd_toStartOf="@id/taskbar_icon_5"/>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/taskbar_icon_5"
- android:layout_width="@dimen/gesture_tutorial_taskbar_icon_size"
- android:layout_height="@dimen/gesture_tutorial_taskbar_icon_size"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="@dimen/gesture_tutorial_taskbar_icon_corner_radius"
- app:cardBackgroundColor="@color/mock_app_icon_4"
- app:layout_constraintDimensionRatio="1:1"
- app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintStart_toEndOf="@id/taskbar_icon_4"
- app:layout_constraintEnd_toStartOf="@id/taskbar_icon_6"/>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/taskbar_icon_6"
- android:layout_width="@dimen/gesture_tutorial_taskbar_icon_size"
- android:layout_height="@dimen/gesture_tutorial_taskbar_icon_size"
- android:layout_marginEnd="@dimen/gesture_tutorial_taskbar_padding_start_end"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="@dimen/gesture_tutorial_taskbar_icon_corner_radius"
- app:cardBackgroundColor="@color/mock_app_icon_2"
- app:layout_constraintDimensionRatio="1:1"
- app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintStart_toEndOf="@id/taskbar_icon_5"
- app:layout_constraintEnd_toEndOf="parent"/>
-
- </androidx.constraintlayout.widget.ConstraintLayout>
-
-</com.android.quickstep.interaction.AnimatedTaskbarView> \ No newline at end of file
diff --git a/quickstep/res/layout/gesture_tutorial_tablet_mock_webpage.xml b/quickstep/res/layout/gesture_tutorial_tablet_mock_webpage.xml
deleted file mode 100644
index 67e9b02b3d..0000000000
--- a/quickstep/res/layout/gesture_tutorial_tablet_mock_webpage.xml
+++ /dev/null
@@ -1,275 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2021 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.
--->
-<androidx.constraintlayout.widget.ConstraintLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:app="http://schemas.android.com/apk/res-auto"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:background="@color/mock_webpage_background">
-
- <androidx.constraintlayout.widget.ConstraintLayout
- android:id="@+id/url_bar"
- android:layout_width="match_parent"
- android:layout_height="101dp"
- android:background="@color/mock_webpage_url_bar"
-
- app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toEndOf="parent">
-
- <androidx.cardview.widget.CardView
- android:layout_width="0dp"
- android:layout_height="0dp"
- android:layout_marginTop="48dp"
- android:layout_marginBottom="16dp"
- android:layout_marginStart="100dp"
- android:layout_marginEnd="100dp"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="100dp"
- app:cardBackgroundColor="@color/mock_webpage_url_bar_item"
- app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toEndOf="parent"/>
-
- </androidx.constraintlayout.widget.ConstraintLayout>
-
- <androidx.constraintlayout.widget.ConstraintLayout
- android:id="@+id/top_bar"
- android:layout_width="match_parent"
- android:layout_height="88dp"
- android:layout_marginStart="100dp"
- android:layout_marginEnd="100dp"
- android:background="@color/mock_webpage_top_bar"
-
- app:layout_constraintTop_toBottomOf="@id/url_bar"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toEndOf="parent">
-
- <androidx.cardview.widget.CardView
- android:id="@+id/top_bar_button"
- android:layout_width="0dp"
- android:layout_height="0dp"
- android:layout_marginTop="22dp"
- android:layout_marginBottom="22dp"
- android:layout_marginStart="24dp"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="8dp"
- app:cardBackgroundColor="@color/mock_webpage_top_bar_item"
- app:layout_constraintDimensionRatio="1:1"
- app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintStart_toStartOf="parent"/>
-
- <androidx.cardview.widget.CardView
- android:layout_width="0dp"
- android:layout_height="0dp"
- android:layout_marginTop="28dp"
- android:layout_marginBottom="28dp"
- android:layout_marginStart="97dp"
- android:layout_marginEnd="325dp"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="2dp"
- app:cardBackgroundColor="@color/mock_webpage_top_bar_item"
- app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toEndOf="parent"/>
-
- </androidx.constraintlayout.widget.ConstraintLayout>
-
- <androidx.constraintlayout.widget.ConstraintLayout
- android:layout_width="match_parent"
- android:layout_height="0dp"
- android:background="@color/mock_webpage_background"
- android:paddingTop="@dimen/gesture_tutorial_webpage_padding_top"
- android:paddingStart="124dp"
- android:paddingEnd="100dp"
-
- app:layout_constraintTop_toBottomOf="@id/top_bar"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toEndOf="parent">
-
- <androidx.cardview.widget.CardView
- android:id="@+id/mock_line_1"
- android:layout_width="0dp"
- android:layout_height="@dimen/gesture_tutorial_webpage_large_line_height"
- android:layout_marginEnd="126dp"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="@dimen/gesture_tutorial_webpage_small_corner_radius"
- app:cardBackgroundColor="@color/mock_webpage_page_text"
- app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toEndOf="parent"/>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/mock_line_2"
- android:layout_width="0dp"
- android:layout_height="@dimen/gesture_tutorial_webpage_large_line_height"
- android:layout_marginTop="@dimen/gesture_tutorial_webpage_small_margin_top"
- android:layout_marginEnd="64dp"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="@dimen/gesture_tutorial_webpage_small_corner_radius"
- app:cardBackgroundColor="@color/mock_webpage_page_text"
- app:layout_constraintTop_toBottomOf="@id/mock_line_1"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toEndOf="parent"/>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/mock_line_3"
- android:layout_width="0dp"
- android:layout_height="@dimen/gesture_tutorial_webpage_large_line_height"
- android:layout_marginTop="@dimen/gesture_tutorial_webpage_small_margin_top"
- android:layout_marginEnd="151dp"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="@dimen/gesture_tutorial_webpage_small_corner_radius"
- app:cardBackgroundColor="@color/mock_webpage_page_text"
- app:layout_constraintTop_toBottomOf="@id/mock_line_2"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toEndOf="parent"/>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/mock_button"
- android:layout_width="47dp"
- android:layout_height="12dp"
- android:layout_marginTop="@dimen/gesture_tutorial_webpage_small_margin_top"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="@dimen/gesture_tutorial_webpage_small_corner_radius"
- app:cardBackgroundColor="@color/mock_webpage_page_text"
- app:layout_constraintTop_toBottomOf="@id/mock_line_3"
- app:layout_constraintStart_toStartOf="parent"/>
-
- <androidx.cardview.widget.CardView
- android:layout_width="47dp"
- android:layout_height="12dp"
- android:background="@color/mock_webpage_page_text"
- android:layout_marginStart="11dp"
- android:layout_marginTop="@dimen/gesture_tutorial_webpage_small_margin_top"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="@dimen/gesture_tutorial_webpage_small_corner_radius"
- app:cardBackgroundColor="@color/mock_webpage_page_text"
- app:layout_constraintTop_toBottomOf="@id/mock_line_3"
- app:layout_constraintStart_toEndOf="@id/mock_button"/>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/mock_block"
- android:layout_width="0dp"
- android:layout_height="240dp"
- android:layout_marginTop="@dimen/gesture_tutorial_webpage_large_margin_top"
- android:layout_marginEnd="24dp"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="@dimen/gesture_tutorial_webpage_large_corner_radius"
- app:cardBackgroundColor="@color/mock_webpage_page_text"
- app:layout_constraintTop_toBottomOf="@id/mock_button"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toEndOf="parent"/>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/mock_line_4"
- android:layout_width="0dp"
- android:layout_height="@dimen/gesture_tutorial_webpage_small_line_height"
- android:layout_marginTop="@dimen/gesture_tutorial_webpage_large_margin_top"
- android:layout_marginEnd="52dp"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="@dimen/gesture_tutorial_webpage_medium_corner_radius"
- app:cardBackgroundColor="@color/mock_webpage_page_text"
- app:layout_constraintTop_toBottomOf="@id/mock_block"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toEndOf="parent"/>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/mock_line_5"
- android:layout_width="0dp"
- android:layout_height="@dimen/gesture_tutorial_webpage_small_line_height"
- android:layout_marginTop="@dimen/gesture_tutorial_webpage_small_margin_top"
- android:layout_marginEnd="41dp"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="@dimen/gesture_tutorial_webpage_medium_corner_radius"
- app:cardBackgroundColor="@color/mock_webpage_page_text"
- app:layout_constraintTop_toBottomOf="@id/mock_line_4"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toEndOf="parent"/>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/mock_line_6"
- android:layout_width="0dp"
- android:layout_height="@dimen/gesture_tutorial_webpage_small_line_height"
- android:layout_marginTop="@dimen/gesture_tutorial_webpage_small_margin_top"
- android:layout_marginEnd="71dp"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="@dimen/gesture_tutorial_webpage_medium_corner_radius"
- app:cardBackgroundColor="@color/mock_webpage_page_text"
- app:layout_constraintTop_toBottomOf="@id/mock_line_5"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toEndOf="parent"/>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/mock_line_7"
- android:layout_width="0dp"
- android:layout_height="@dimen/gesture_tutorial_webpage_small_line_height"
- android:layout_marginTop="@dimen/gesture_tutorial_webpage_small_margin_top"
- android:layout_marginEnd="198dp"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="@dimen/gesture_tutorial_webpage_medium_corner_radius"
- app:cardBackgroundColor="@color/mock_webpage_page_text"
- app:layout_constraintTop_toBottomOf="@id/mock_line_6"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toEndOf="parent"/>
-
- <androidx.cardview.widget.CardView
- android:id="@+id/mock_line_8"
- android:layout_width="0dp"
- android:layout_height="@dimen/gesture_tutorial_webpage_small_line_height"
- android:layout_marginTop="@dimen/gesture_tutorial_webpage_large_margin_top"
- android:layout_marginEnd="64dp"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="@dimen/gesture_tutorial_webpage_medium_corner_radius"
- app:cardBackgroundColor="@color/mock_webpage_page_text"
- app:layout_constraintTop_toBottomOf="@id/mock_line_7"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toEndOf="parent"/>
-
- <androidx.cardview.widget.CardView
- android:layout_width="0dp"
- android:layout_height="@dimen/gesture_tutorial_webpage_small_line_height"
- android:layout_marginTop="@dimen/gesture_tutorial_webpage_small_margin_top"
- android:layout_marginEnd="71dp"
-
- app:cardElevation="0dp"
- app:cardCornerRadius="@dimen/gesture_tutorial_webpage_medium_corner_radius"
- app:cardBackgroundColor="@color/mock_webpage_page_text"
- app:layout_constraintTop_toBottomOf="@id/mock_line_8"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toEndOf="parent"/>
-
- </androidx.constraintlayout.widget.ConstraintLayout>
-
-</androidx.constraintlayout.widget.ConstraintLayout> \ No newline at end of file
diff --git a/quickstep/res/layout/overview_actions_container.xml b/quickstep/res/layout/overview_actions_container.xml
index 0fda0bf8d4..68680d3f38 100644
--- a/quickstep/res/layout/overview_actions_container.xml
+++ b/quickstep/res/layout/overview_actions_container.xml
@@ -14,10 +14,11 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
+<!-- NOTE! don't add dimensions for margins / gravity to root view in this file, they need to be
+ loaded at runtime. -->
<com.android.quickstep.views.OverviewActionsView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_gravity="center_horizontal|bottom">
+ android:layout_height="wrap_content">
<LinearLayout
android:id="@+id/action_buttons"
@@ -38,29 +39,25 @@
android:layout_height="wrap_content"
android:drawableStart="@drawable/ic_screenshot"
android:text="@string/action_screenshot"
- android:theme="@style/ThemeControlHighlightWorkspaceColor" />
+ android:theme="@style/ThemeControlHighlightWorkspaceColor"
+ android:visibility="gone" />
<Space
- android:id="@+id/action_split_space"
- android:layout_width="@dimen/overview_actions_button_spacing"
+ android:layout_width="0dp"
android:layout_height="1dp"
- android:visibility="gone" />
+ android:layout_weight="1" />
<Button
- android:id="@+id/action_split"
+ android:id="@+id/action_share"
style="@style/OverviewActionButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:text="@string/action_split"
+ android:drawableStart="@drawable/ic_share"
+ android:text="@string/action_share"
android:theme="@style/ThemeControlHighlightWorkspaceColor"
android:visibility="gone" />
<Space
- android:layout_width="0dp"
- android:layout_height="1dp"
- android:layout_weight="1" />
-
- <Space
android:id="@+id/oav_three_button_space"
android:layout_width="0dp"
android:layout_height="1dp"
diff --git a/quickstep/res/layout/overview_clear_all_button.xml b/quickstep/res/layout/overview_clear_all_button.xml
index 1dea57e4b7..1ee726e62e 100644
--- a/quickstep/res/layout/overview_clear_all_button.xml
+++ b/quickstep/res/layout/overview_clear_all_button.xml
@@ -16,7 +16,7 @@
-->
<com.android.quickstep.views.ClearAllButton
xmlns:android="http://schemas.android.com/apk/res/android"
- style="@style/OverviewClearAllButton"
+ style="@android:style/Widget.DeviceDefault.Button.Borderless"
android:id="@+id/clear_all"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
diff --git a/quickstep/res/layout/overview_panel.xml b/quickstep/res/layout/overview_panel.xml
index 01d675f371..f303f31199 100644
--- a/quickstep/res/layout/overview_panel.xml
+++ b/quickstep/res/layout/overview_panel.xml
@@ -25,6 +25,13 @@
android:clipToPadding="false"
android:visibility="invisible" />
+ <com.android.quickstep.views.SplitPlaceholderView
+ android:id="@+id/split_placeholder"
+ android:layout_width="match_parent"
+ android:layout_height="@dimen/split_placeholder_size"
+ android:background="@android:color/darker_gray"
+ android:visibility="gone" />
+
<include
android:id="@+id/overview_actions_view"
layout="@layout/overview_actions_container" />
diff --git a/quickstep/res/layout/predicted_hotseat_edu.xml b/quickstep/res/layout/predicted_hotseat_edu.xml
index f0c12f1029..1dab48267b 100644
--- a/quickstep/res/layout/predicted_hotseat_edu.xml
+++ b/quickstep/res/layout/predicted_hotseat_edu.xml
@@ -42,7 +42,6 @@
android:paddingLeft="@dimen/bottom_sheet_edu_padding"
android:paddingRight="@dimen/bottom_sheet_edu_padding"
android:text="@string/hotseat_edu_title_migrate"
- android:fontFamily="google-sans"
android:textAlignment="center"
android:textColor="@android:color/white"
android:textSize="20sp" />
@@ -74,7 +73,6 @@
launcher:containerType="hotseat" />
<LinearLayout
- android:id="@+id/button_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="@dimen/bottom_sheet_edu_padding"
diff --git a/quickstep/res/layout/rotate_suggestion.xml b/quickstep/res/layout/rotate_suggestion.xml
deleted file mode 100644
index 07cf0c848c..0000000000
--- a/quickstep/res/layout/rotate_suggestion.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2021 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
- -->
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- >
- <com.android.systemui.shared.rotation.FloatingRotationButtonView
- android:id="@+id/rotate_suggestion"
- android:layout_width="@dimen/floating_rotation_button_diameter"
- android:layout_height="@dimen/floating_rotation_button_diameter"
- android:paddingStart="@dimen/navigation_key_padding"
- android:paddingEnd="@dimen/navigation_key_padding"
- android:layout_gravity="bottom|left"
- android:scaleType="center"
- android:visibility="invisible" />
-</FrameLayout>
diff --git a/quickstep/res/layout/task_grouped.xml b/quickstep/res/layout/task_grouped.xml
deleted file mode 100644
index cd5bcbdddd..0000000000
--- a/quickstep/res/layout/task_grouped.xml
+++ /dev/null
@@ -1,54 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?><!--
- Copyright (C) 2021 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.
--->
-<!-- NOTE! don't add dimensions for margins / paddings / sizes that change per orientation to this
- file, they need to be loaded at runtime. -->
-
-<!-- DOUBLE NOTE! Don't deviate IDs from task.xml since this layout acts as a "subclass" (read as
- "bad code"). How can we use the view pool in RecentsView to use task.xml layout with using
- GroupedTaskView.java class? Is that possible (while still keeping code in separate class) ? -->
-
-<com.android.quickstep.views.GroupedTaskView
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:clipChildren="false"
- android:defaultFocusHighlightEnabled="false"
- android:focusable="true">
-
- <com.android.quickstep.views.TaskThumbnailView
- android:id="@+id/snapshot"
- android:layout_width="match_parent"
- android:layout_height="match_parent"/>
-
- <com.android.quickstep.views.TaskThumbnailView
- android:id="@+id/bottomright_snapshot"
- android:layout_width="match_parent"
- android:layout_height="match_parent"/>
-
- <com.android.quickstep.views.IconView
- android:id="@+id/icon"
- android:layout_width="@dimen/task_thumbnail_icon_size"
- android:layout_height="@dimen/task_thumbnail_icon_size"
- android:focusable="false"
- android:importantForAccessibility="no"/>
-
- <com.android.quickstep.views.IconView
- android:id="@+id/bottomRight_icon"
- android:layout_width="@dimen/task_thumbnail_icon_size"
- android:layout_height="@dimen/task_thumbnail_icon_size"
- android:focusable="false"
- android:importantForAccessibility="no"/>
-</com.android.quickstep.views.GroupedTaskView> \ No newline at end of file
diff --git a/quickstep/res/layout/task_menu_with_arrow.xml b/quickstep/res/layout/task_menu_with_arrow.xml
deleted file mode 100644
index 38573fd1e5..0000000000
--- a/quickstep/res/layout/task_menu_with_arrow.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2021 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.
--->
-<com.android.quickstep.views.TaskMenuViewWithArrow
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:animateLayoutChanges="true"
- android:background="@drawable/task_menu_bg"
- android:orientation="vertical"
- android:visibility="invisible">
-
- <LinearLayout
- android:id="@+id/menu_option_layout"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="vertical"
- android:showDividers="middle" />
-
-</com.android.quickstep.views.TaskMenuViewWithArrow> \ No newline at end of file
diff --git a/quickstep/res/layout/task_view_menu_option.xml b/quickstep/res/layout/task_view_menu_option.xml
index 8a8fc36b84..5978b97dd4 100644
--- a/quickstep/res/layout/task_view_menu_option.xml
+++ b/quickstep/res/layout/task_view_menu_option.xml
@@ -18,7 +18,7 @@
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:orientation="horizontal"
+ android:orientation="vertical"
android:paddingTop="@dimen/task_card_menu_option_vertical_padding"
android:paddingBottom="@dimen/task_card_menu_option_vertical_padding"
android:background="@drawable/task_menu_item_bg"
diff --git a/quickstep/res/layout/taskbar.xml b/quickstep/res/layout/taskbar.xml
index 3b1d217ec5..e680233e6a 100644
--- a/quickstep/res/layout/taskbar.xml
+++ b/quickstep/res/layout/taskbar.xml
@@ -13,13 +13,12 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
+
<com.android.launcher3.taskbar.TaskbarDragLayer
xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/taskbar_container"
android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:clipChildren="false">
+ android:layout_height="wrap_content">
<com.android.launcher3.taskbar.TaskbarView
android:id="@+id/taskbar_view"
@@ -27,59 +26,30 @@
android:layout_height="wrap_content"
android:gravity="center"
android:forceHasOverlappingRendering="false"
- android:layout_gravity="bottom"
- android:clipChildren="false" />
-
- <com.android.launcher3.taskbar.TaskbarScrimView
- android:id="@+id/taskbar_scrim"
- android:layout_width="match_parent"
- android:layout_height="match_parent"/>
-
- <FrameLayout
- android:id="@+id/navbuttons_view"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
android:layout_gravity="bottom" >
- <FrameLayout
- android:id="@+id/start_contextual_buttons"
+ <LinearLayout
+ android:id="@+id/system_button_layout"
android:layout_width="wrap_content"
- android:layout_height="match_parent"
+ android:layout_height="wrap_content"
android:paddingLeft="@dimen/taskbar_nav_buttons_spacing"
android:paddingRight="@dimen/taskbar_nav_buttons_spacing"
- android:paddingTop="@dimen/taskbar_contextual_padding_top"
- android:gravity="center_vertical"
- android:layout_gravity="start"/>
+ android:forceHasOverlappingRendering="false"
+ android:gravity="center" />
<LinearLayout
- android:id="@+id/end_nav_buttons"
+ android:id="@+id/hotseat_icons_layout"
android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:orientation="horizontal"
- android:paddingLeft="@dimen/taskbar_nav_buttons_spacing"
- android:paddingRight="@dimen/taskbar_nav_buttons_spacing"
- android:layout_marginEnd="@dimen/taskbar_contextual_button_margin"
- android:gravity="center_vertical"
- android:layout_gravity="end"/>
+ android:layout_height="wrap_content"
+ android:forceHasOverlappingRendering="false"
+ android:gravity="center" />
- <FrameLayout
- android:id="@+id/end_contextual_buttons"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:paddingLeft="@dimen/taskbar_nav_buttons_spacing"
- android:paddingRight="@dimen/taskbar_nav_buttons_spacing"
- android:paddingTop="@dimen/taskbar_contextual_padding_top"
- android:gravity="center_vertical"
- android:layout_gravity="end"/>
- </FrameLayout>
+ </com.android.launcher3.taskbar.TaskbarView>
- <com.android.launcher3.taskbar.StashedHandleView
- android:id="@+id/stashed_handle"
- tools:comment1="The actual size and shape will be set as a ViewOutlineProvider at runtime"
- android:layout_width="match_parent"
+ <com.android.launcher3.taskbar.ImeBarView
+ android:id="@+id/ime_bar_view"
+ android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:background="@color/taskbar_stashed_handle_dark_color"
- android:clipToOutline="true"
- android:layout_gravity="bottom"/>
+ android:visibility="gone"/>
</com.android.launcher3.taskbar.TaskbarDragLayer> \ No newline at end of file
diff --git a/quickstep/res/layout/taskbar_all_apps.xml b/quickstep/res/layout/taskbar_all_apps.xml
deleted file mode 100644
index 34d4b231b1..0000000000
--- a/quickstep/res/layout/taskbar_all_apps.xml
+++ /dev/null
@@ -1,66 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2022 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<com.android.launcher3.taskbar.allapps.TaskbarAllAppsSlideInView
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent">
-
- <com.android.launcher3.taskbar.allapps.TaskbarAllAppsContainerView
- android:id="@+id/apps_view"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:clipChildren="true"
- android:clipToPadding="false"
- android:focusable="false"
- android:saveEnabled="false"
- android:theme="?attr/allAppsTheme">
-
- <include
- layout="@layout/all_apps_bottom_sheet_background"
- android:visibility="gone" />
-
- <include
- layout="@layout/search_results_rv_layout"
- android:visibility="gone" />
-
- <include
- layout="@layout/all_apps_rv_layout"
- android:visibility="gone" />
-
- <com.android.launcher3.allapps.FloatingHeaderView
- android:id="@+id/all_apps_header"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_below="@id/search_container_all_apps"
- android:clipToPadding="false"
- android:paddingTop="@dimen/all_apps_header_top_padding"
- android:orientation="vertical">
-
- <include layout="@layout/floating_header_content" />
-
- <include layout="@layout/all_apps_personal_work_tabs" />
- </com.android.launcher3.allapps.FloatingHeaderView>
-
- <com.android.launcher3.taskbar.allapps.TaskbarAllAppsFallbackSearchContainer
- android:id="@+id/search_container_all_apps"
- android:layout_width="0dp"
- android:layout_height="0dp"
- android:visibility="gone" />
-
- <include layout="@layout/all_apps_fast_scroller" />
- </com.android.launcher3.taskbar.allapps.TaskbarAllAppsContainerView>
-</com.android.launcher3.taskbar.allapps.TaskbarAllAppsSlideInView>
diff --git a/quickstep/res/layout/taskbar_contextual_button.xml b/quickstep/res/layout/taskbar_contextual_button.xml
deleted file mode 100644
index 4ffb8d81dc..0000000000
--- a/quickstep/res/layout/taskbar_contextual_button.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2021 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.
--->
-<ImageView
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="@dimen/taskbar_nav_buttons_size"
- android:layout_height="@dimen/taskbar_nav_buttons_size"
- android:background="@drawable/taskbar_icon_click_feedback_roundrect"
- android:scaleType="center"/> \ No newline at end of file
diff --git a/quickstep/res/layout/taskbar_edu.xml b/quickstep/res/layout/taskbar_edu.xml
deleted file mode 100644
index 3796ff930e..0000000000
--- a/quickstep/res/layout/taskbar_edu.xml
+++ /dev/null
@@ -1,140 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2021 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.
--->
-
-<com.android.launcher3.taskbar.TaskbarEduView xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
- xmlns:app="http://schemas.android.com/apk/res-auto"
- xmlns:launcher="http://schemas.android.com/apk/res-auto"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_gravity="bottom"
- android:gravity="bottom"
- android:orientation="vertical"
- android:layout_marginHorizontal="108dp">
-
- <androidx.constraintlayout.widget.ConstraintLayout
- android:id="@+id/edu_view"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:background="@drawable/bg_rounded_corner_bottom_sheet"
- android:gravity="center_horizontal"
- android:paddingHorizontal="36dp"
- android:paddingTop="64dp">
-
- <com.android.launcher3.taskbar.TaskbarEduPagedView
- android:id="@+id/content"
- android:clipToPadding="false"
- android:layout_width="match_parent"
- android:layout_height="378dp"
- app:layout_constraintTop_toTopOf="parent"
- launcher:pageIndicator="@+id/content_page_indicator">
-
- <LinearLayout
- android:id="@+id/page_switch_apps"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="vertical"
- android:gravity="center_horizontal">
-
- <TextView
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- style="@style/TextAppearance.TaskbarEdu.Title"
- android:text="@string/taskbar_edu_switch_apps"/>
-
- <ImageView
- android:layout_width="322dp"
- android:layout_height="282dp"
- android:layout_marginTop="16dp"
- android:src="@drawable/taskbar_edu_switch_apps"/>
- </LinearLayout>
-
- <LinearLayout
- android:id="@+id/page_splitscreen"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="vertical"
- android:gravity="center_horizontal">
-
- <TextView
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- style="@style/TextAppearance.TaskbarEdu.Title"
- android:text="@string/taskbar_edu_splitscreen"/>
-
- <ImageView
- android:layout_width="322dp"
- android:layout_height="282dp"
- android:layout_marginTop="16dp"
- android:src="@drawable/taskbar_edu_splitscreen"/>
- </LinearLayout>
-
- <LinearLayout
- android:id="@+id/page_stashing"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="vertical"
- android:gravity="center_horizontal">
-
- <TextView
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- style="@style/TextAppearance.TaskbarEdu.Title"
- android:text="@string/taskbar_edu_stashing"/>
-
- <ImageView
- android:layout_width="322dp"
- android:layout_height="282dp"
- android:layout_marginTop="16dp"
- android:src="@drawable/taskbar_edu_stashing"/>
- </LinearLayout>
- </com.android.launcher3.taskbar.TaskbarEduPagedView>
-
- <Button
- android:id="@+id/edu_start_button"
- android:layout_width="wrap_content"
- android:layout_height="36dp"
- android:layout_marginBottom="92dp"
- android:layout_marginTop="32dp"
- app:layout_constraintTop_toBottomOf="@id/content"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintStart_toStartOf="parent"
- android:text="@string/taskbar_edu_close"
- style="@style/TaskbarEdu.Button.Close"
- android:textColor="?android:attr/textColorPrimary"/>
-
- <com.android.launcher3.pageindicators.PageIndicatorDots
- android:id="@+id/content_page_indicator"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- app:layout_constraintTop_toTopOf="@id/edu_start_button"
- app:layout_constraintBottom_toBottomOf="@id/edu_start_button"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toEndOf="parent"
- android:elevation="1dp" />
-
- <Button
- android:id="@+id/edu_end_button"
- android:layout_width="wrap_content"
- android:layout_height="0dp"
- app:layout_constraintTop_toTopOf="@id/edu_start_button"
- app:layout_constraintBottom_toBottomOf="@id/edu_start_button"
- app:layout_constraintEnd_toEndOf="parent"
- android:text="@string/taskbar_edu_next"
- style="@style/TaskbarEdu.Button.Next"
- android:textColor="?androidprv:attr/textColorOnAccent"/>
- </androidx.constraintlayout.widget.ConstraintLayout>
-</com.android.launcher3.taskbar.TaskbarEduView> \ No newline at end of file
diff --git a/quickstep/res/values-af/strings.xml b/quickstep/res/values-af/strings.xml
index ac10cc8d92..64b8e2c3b1 100644
--- a/quickstep/res/values-af/strings.xml
+++ b/quickstep/res/values-af/strings.xml
@@ -19,91 +19,19 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Verdeelde skerm"</string>
<string name="recent_task_option_pin" msgid="7929860679018978258">"Speld vas"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Vormvry"</string>
+ <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Oorsig"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"Geen onlangse items nie"</string>
+ <string name="accessibility_close_task" msgid="5354563209433803643">"Maak toe"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Programgebruikinstellings"</string>
<string name="recents_clear_all" msgid="5328176793634888831">"Vee alles uit"</string>
<string name="accessibility_recent_apps" msgid="4058661986695117371">"Onlangse programme"</string>
- <string name="task_view_closed" msgid="9170038230110856166">"Taak is toegemaak"</string>
<string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
<string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 minuut"</string>
<string name="time_left_for_app" msgid="3111996412933644358">"<xliff:g id="TIME">%1$s</xliff:g> oor vandag"</string>
<string name="title_app_suggestions" msgid="4185902664111965088">"Programvoorstelle"</string>
+ <string name="all_apps_label" msgid="8542784161730910663">"Alle programme"</string>
<string name="all_apps_prediction_tip" msgid="2672336544844936186">"Jou voorspelde programme"</string>
- <string name="hotseat_edu_title_migrate" msgid="306578144424489980">"Kry programvoorstelle in die onderste ry van jou tuisskerm"</string>
- <string name="hotseat_edu_title_migrate_landscape" msgid="3633942953997845243">"Kry programvoorstelle op jou tuisskerm se gunstelingery"</string>
- <string name="hotseat_edu_message_migrate" msgid="8927179260533775320">"Kry maklik toegang tot jou programme wat die meeste gebruik word, direk van die tuisskerm af. Voorstelle sal verander op grond van jou roetines. Programme in die onderste ry sal opskuif na jou tuisskerm."</string>
- <string name="hotseat_edu_message_migrate_landscape" msgid="4248943380443387697">"Kry maklik toegang tot jou programme wat die meeste gebruik word, direk van die tuisskerm af. Voorstelle sal verander op grond van jou roetines. Programme in die gunstelingery sal na jou tuisskerm toe skuif."</string>
- <string name="hotseat_edu_message_migrate_alt" msgid="3042360119039646356">"Kry maklik toegang tot jou programme wat die meeste gebruik word, direk van die tuisskerm af. Voorstelle sal verander op grond van jou roetines. Programme in die onderste ry sal na \'n nuwe vouer toe skuif."</string>
- <string name="hotseat_edu_accept" msgid="1611544083278999837">"Kry programvoorstelle"</string>
- <string name="hotseat_edu_dismiss" msgid="2781161822780201689">"Nee, dankie"</string>
- <string name="hotseat_prediction_settings" msgid="6246554993566070818">"Instellings"</string>
- <string name="hotseat_auto_enrolled" msgid="522100018967146807">"Programme wat die meeste gebruik word, verskyn hier, en verander op grond van roetines"</string>
- <string name="hotseat_tip_no_empty_slots" msgid="1325212677738179185">"Sleep programme van die onderste ry af om programvoorstelle te kry"</string>
- <string name="hotseat_tip_gaps_filled" msgid="3035673010274223538">"Programvoorstelle is in leë spasie bygevoeg"</string>
- <string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Programvoorstelle is geaktiveer"</string>
- <string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Programvoorstelle is gedeaktiveer"</string>
- <string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Voorspelde program: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Maak seker dat jy van die rand heel regs of heel links af swiep."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Maak seker dat jy van die regter- of linkerrand na die middel van die skerm swiep en laat los."</string>
- <string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Jy het geleer hoe om van regs af te swiep om terug te gaan. Nou kan jy leer hoe om tussen programme te wissel."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"Jy het die \"gaan terug\"-gebaar voltooi."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Maak seker dat jy nie te naby aan die onderkant van die skerm swiep nie."</string>
- <string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"Gaan na Instellings om sensitiwiteit van teruggebaar te verander"</string>
- <string name="back_gesture_intro_title" msgid="19551256430224428">"Swiep om terug te gaan"</string>
- <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"Swiep van die linker- of regterrand na die middel van die skerm om na die vorige skerm terug te gaan."</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Maak seker dat jy van die onderrand van die skerm af opswiep."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Maak seker jy onderbreek nie voordat jy laat los nie."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Maak seker jy swiep reguit op."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"Jy het die \"gaan na tuisskerm\"-gebaar voltooi. Nou kan jy leer hoe om terug te gaan."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"Jy het die \"gaan na tuisskerm\"-gebaar voltooi."</string>
- <string name="home_gesture_intro_title" msgid="836590312858441830">"Swiep om na tuisskerm toe te gaan"</string>
- <string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Swiep op van die onderkant van jou skerm af. Hierdie gebaar neem jou altyd na die tuisskerm toe."</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Maak seker dat jy van die onderrand van die skerm af opswiep."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Probeer om die venster langer te hou voordat jy laat los."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Maak seker dat jy reguit opswiep en dan onderbreek."</string>
- <string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Jy het geleer hoe om gebare te gebruik. Gaan na Instellings om gebare af te skakel."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"Jy het die \"wissel tussen programme\"-gebaar voltooi."</string>
- <string name="overview_gesture_intro_title" msgid="2902054412868489378">"Swiep om tussen programme te wissel"</string>
- <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Swiep van die onderkant van jou skerm af op, hou en laat los dan om tussen programme te wissel."</string>
- <string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"Gereed"</string>
- <string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Klaar"</string>
- <string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Instellings"</string>
- <string name="gesture_tutorial_try_again" msgid="65962545858556697">"Probeer weer"</string>
- <string name="gesture_tutorial_nice" msgid="2936275692616928280">"Mooi so!"</string>
- <string name="gesture_tutorial_step" msgid="1279786122817620968">"Tutoriaal <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
- <string name="allset_title" msgid="5021126669778966707">"Gereed!"</string>
- <string name="allset_hint" msgid="2384632994739392447">"Swiep op om na die tuisskerm toe te gaan"</string>
- <string name="allset_description" msgid="6350320429953234580">"Jy is gereed om jou foon te begin gebruik"</string>
- <string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"Stelselnavigasie-instellings"</annotation></string>
- <string name="action_share" msgid="2648470652637092375">"Deel"</string>
- <string name="action_screenshot" msgid="8171125848358142917">"Skermkiekie"</string>
- <string name="action_split" msgid="2098009717623550676">"Verdeel"</string>
- <string name="toast_split_select_app" msgid="5453865907322018352">"Probeer ander program om verdeelde skerm te gebruik"</string>
- <string name="toast_split_app_unsupported" msgid="3271526028981899666">"Program steun nie verdeelde skerm nie."</string>
- <string name="blocked_by_policy" msgid="2071401072261365546">"Jou organisasie laat nie hierdie program toe nie"</string>
- <string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Slaan navigasietutoriaal oor?"</string>
- <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Jy kan dit later in die <xliff:g id="NAME">%1$s</xliff:g>-program kry"</string>
- <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Kanselleer"</string>
- <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Slaan oor"</string>
- <string name="accessibility_rotate_button" msgid="4771825231336502943">"Draai skerm"</string>
- <string name="taskbar_edu_opened" msgid="3950252793551919129">"Taakbalkopvoeding het verskyn"</string>
- <string name="taskbar_edu_closed" msgid="126643734478892862">"Taakbalkopvoeding is toegemaak"</string>
- <string name="taskbar_edu_switch_apps" msgid="6942863327845784813">"Gebruik die taakbalk om tussen programme te wissel"</string>
- <string name="taskbar_edu_splitscreen" msgid="2663361731630346489">"Sleep na die kant om twee programme gelyktydig te gebruik"</string>
- <string name="taskbar_edu_stashing" msgid="5212374387411764031">"Raak en hou om die taakbalk te versteek"</string>
- <string name="taskbar_edu_next" msgid="4007618274426775841">"Volgende"</string>
- <string name="taskbar_edu_previous" msgid="459202320127201702">"Terug"</string>
- <string name="taskbar_edu_close" msgid="887022990168191073">"Maak toe"</string>
- <string name="taskbar_edu_done" msgid="6880178093977704569">"Klaar"</string>
- <string name="taskbar_button_home" msgid="2151398979630664652">"Tuis"</string>
- <string name="taskbar_button_a11y" msgid="5241161324875094465">"Toeganklikheid"</string>
- <string name="taskbar_button_back" msgid="8558862226461164514">"Terug"</string>
- <string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"IME-wisselaar"</string>
- <string name="taskbar_button_recents" msgid="7273376136216613134">"Onlangs"</string>
- <string name="taskbar_button_notifications" msgid="7471740351507357318">"Kennisgewings"</string>
- <string name="taskbar_button_quick_settings" msgid="227662894293189391">"Kitsinstellings"</string>
- <string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Skuif na links bo"</string>
- <string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Skuif na regs onder"</string>
</resources>
diff --git a/quickstep/res/values-am/strings.xml b/quickstep/res/values-am/strings.xml
index dfa8532870..3daa92226c 100644
--- a/quickstep/res/values-am/strings.xml
+++ b/quickstep/res/values-am/strings.xml
@@ -19,91 +19,19 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="recent_task_option_split_screen" msgid="5353188922202653570">"የተከፈለ ማያ ገጽ"</string>
<string name="recent_task_option_pin" msgid="7929860679018978258">"ሰካ"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"ነጻ ቅጽ"</string>
+ <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"ማጠቃለያ"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"ምንም የቅርብ ጊዜ ንጥሎች የሉም"</string>
+ <string name="accessibility_close_task" msgid="5354563209433803643">"ዝጋ"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"የመተግበሪያ አጠቃቀም ቅንብሮች"</string>
<string name="recents_clear_all" msgid="5328176793634888831">"ሁሉንም አጽዳ"</string>
<string name="accessibility_recent_apps" msgid="4058661986695117371">"የቅርብ ጊዜ መተግበሪያዎች"</string>
- <string name="task_view_closed" msgid="9170038230110856166">"ተግባር ተዘግቷል"</string>
<string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>፣ <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
<string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 ደቂቃ"</string>
<string name="time_left_for_app" msgid="3111996412933644358">"ዛሬ <xliff:g id="TIME">%1$s</xliff:g> ቀርቷል"</string>
- <string name="title_app_suggestions" msgid="4185902664111965088">"የመተግበሪያ አስተያየቶች"</string>
+ <string name="title_app_suggestions" msgid="4185902664111965088">"የመተግበሪያ ጥቆማዎች"</string>
+ <string name="all_apps_label" msgid="8542784161730910663">"ሁሉም መተግበሪያዎች"</string>
<string name="all_apps_prediction_tip" msgid="2672336544844936186">"የእርስዎ የሚገመቱ መተግበሪያዎች"</string>
- <string name="hotseat_edu_title_migrate" msgid="306578144424489980">"በመነሻ ገጽዎ ታችኛው ረድፍ ላይ የመተግበሪያ አስተያየት ጥቆማዎችን ያግኙ"</string>
- <string name="hotseat_edu_title_migrate_landscape" msgid="3633942953997845243">"በመነሻ ማያ ገጽዎ የተወዳጆች ረድፍ ላይ የመተግበሪያ አስተያየት ጥቆማዎችን ያግኙ"</string>
- <string name="hotseat_edu_message_migrate" msgid="8927179260533775320">"በጣም ስራ ላይ የዋሉ መተግበሪያዎችዎን በቀላሉ ከመነሻ ገጹ ሆነው ይድረሱባቸው። የአስተያየት ጥቆማዎች በእርስዎ ዕለት ተዕለት ተግባራት ላይ በመመስረት ይቀየራሉ። በታችኛው ረድፍ ላይ ያሉ መተግበሪያዎች ወደ መነሻ ገጽዎ ይወሰዳሉ።"</string>
- <string name="hotseat_edu_message_migrate_landscape" msgid="4248943380443387697">"በጣም ሥራ ላይ የዋሉ መተግበሪያዎችዎን በቀላሉ ከመነሻ ገጹ ሆነው ይድረሱባቸው። የአስተያየት ጥቆማዎች በእርስዎ ዕለት ተዕለት ተግባራት ላይ በመመሥረት ይቀየራሉ። በተወዳጆች ረድፍ ውስጥ ያሉ መተግበሪያዎች ወደ የእርስዎ መነሻ ማያ ገጽ ይንቀሳቀሳሉ።"</string>
- <string name="hotseat_edu_message_migrate_alt" msgid="3042360119039646356">"በጣም ስራ ላይ የዋሉ መተግበሪያዎችዎን በቀላሉ ከመነሻ ገጹ ሆነው ይድረሱባቸው። የአስተያየት ጥቆማዎች በእርስዎ ዕለት ተዕለት ተግባራት ላይ በመመስረት ይቀየራሉ። በታችኛው ረድፍ ላይ ያሉ መተግበሪያዎች ወደ አዲስ አቃፊ ይወሰዳሉ።"</string>
- <string name="hotseat_edu_accept" msgid="1611544083278999837">"የመተግበሪያ አስተያየት ጥቆማዎችን አግኝ"</string>
- <string name="hotseat_edu_dismiss" msgid="2781161822780201689">"አይ፣ አመሰግናለሁ"</string>
- <string name="hotseat_prediction_settings" msgid="6246554993566070818">"ቅንብሮች"</string>
- <string name="hotseat_auto_enrolled" msgid="522100018967146807">"በብዛት ስራ ላይ የዋሉ መተግበሪያዎች እዚህ ይመጣሉ፣ እና በዕለት ተዕለት ተግባራት ላይ በመመስረት ይቀየራሉ"</string>
- <string name="hotseat_tip_no_empty_slots" msgid="1325212677738179185">"የመተግበሪያ ጥቆማዎችን ለማግኘት መተግበሪያዎችን ከታችኛው ረድፍ ይጎትቱ"</string>
- <string name="hotseat_tip_gaps_filled" msgid="3035673010274223538">"የመተግበሪያ አስተያየት ጥቆማዎች ወደ ባዶ ቦታ ታክለዋል"</string>
- <string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"የመተግበሪያ አስተያየት ጥቆማዎች ነቅቷል"</string>
- <string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"የመተግበሪያ አስተያየቶች ቦዝነዋል"</string>
- <string name="hotseat_prediction_content_description" msgid="4582028296938078419">"የተገመተው መተግበሪያ፦ <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"ከቀኝ ጠርዝ ወይም ከግራ ጠርዝ ጥግ ጀምሮ ማንሸራተትዎን ያረጋግጡ።"</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"ከቀኝ ወይም ከግራ ጠርዝ ወደ ማያ ገጹ መሃል ማንሸራተትዎን እና መልቀቅዎን ያረጋግጡ።"</string>
- <string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"ወደ ኋላ ለመመለስ ከቀኝ ጀምሮ እንዴት ማንሸራተት እንደሚችሉ አውቀዋል። ቀጥለው መተግበሪያዎችን እንዴት መቀየር እንደሚችሉ ይወቁ።"</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"ወደኋላ የመመለስ ምልክትን አጠናቀዋል።"</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"ከማያ ገጹ ታችኛው ክፍል ጋር በጣም ጠጋ ብለው አለማንሸራተትዎን ያረጋግጡ።"</string>
- <string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"ከኋላ ስሜት ሰጭነት ደረጃ ለመለወጥ ወደ ቅንብሮች ይመለሱ"</string>
- <string name="back_gesture_intro_title" msgid="19551256430224428">"ወደኋላ ለመመለስ ያንሸራትቱ"</string>
- <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"ወደ መጨረሻው ማያ ገጽ ለመመለስ ከግራ ወይም ከቀኝ ጠርዝ ወደ ማያ ገጹ መሃል ያንሸራትቱ።"</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"ከማያ ገጹ የታችኛው ጫፍ ወደ ላይ ማንሸራተትዎን ያረጋግጡ።"</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"ከመልቀቅዎ በፊት ለአፍታ እንዳልቆሙ ያረጋግጡ።"</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"በቀጥታ ወደ ላይ ማንሸራተትዎን ያረጋግጡ።"</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"የወደ መነሻ ሂድ ምልክትን አጠናቀዋል። ቀጥሎም ወደ ኋላ እንዴት መሄድ እንደሚችሉ ይወቁ።"</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"የወደ መነሻ ሂድ ምልክትን አጠናቀዋል።"</string>
- <string name="home_gesture_intro_title" msgid="836590312858441830">"ወደ መነሻ ለመሄድ ያንሸራትቱ"</string>
- <string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"ከእርስዎ ማያ ገጽ ግርጌ ላይ ወደ ላይ በጣት ጠረግ ያድርጉ። ይህ የእጅ ውዝዋዜ ሁልጊዜ ወደ መነሻ ማያ ገጽ ይወስድዎታል።"</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"ከማያ ገጹ የታችኛው ጫፍ ወደ ላይ ማንሸራተትዎን ያረጋግጡ።"</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"ከመልቀቅዎ በፊት መስኮቱን ረዘም ላለ ጊዜ ለመያዝ ይሞክሩ።"</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"በቀጥታ ወደ ላይ ማንሸራተትዎን ያረጋግጡ፣ ከዚያ ለአፍታ ያቁሙ።"</string>
- <string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"የእጅ ምልክቶችን እንዴት እንደሚጠቀሙ ተምረዋል። የእጅ ምልክቶችን ለማጥፋት ወደ ቅንብሮች ይሂዱ።"</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"መተግበሪያዎችን የመቀያየር ምልክትን አጠናቀዋል።"</string>
- <string name="overview_gesture_intro_title" msgid="2902054412868489378">"መተግበሪያዎችን ለመቀየር ያንሸራትቱ"</string>
- <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"በመተግበሪያዎች መካከል ለመቀያየር ከማያ ገጽዎ ግርጌ ወደ ላይ ያንሸራትቱ፣ ይያዙ፣ ከዚያ ይለቀቁ።"</string>
- <string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"ሁሉም ዝግጁ"</string>
- <string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"ተጠናቋል"</string>
- <string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"ቅንብሮች"</string>
- <string name="gesture_tutorial_try_again" msgid="65962545858556697">"እንደገና ሞክር"</string>
- <string name="gesture_tutorial_nice" msgid="2936275692616928280">"ጥሩ!"</string>
- <string name="gesture_tutorial_step" msgid="1279786122817620968">"አጋዥ ሥልጠና <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
- <string name="allset_title" msgid="5021126669778966707">"ሁሉም ዝግጁ!"</string>
- <string name="allset_hint" msgid="2384632994739392447">"ወደ መነሻ ለመሄድ በጣት ወደ ላይ ማንሸራተት"</string>
- <string name="allset_description" msgid="6350320429953234580">"ስልክዎን መጠቀም ለመጀመር ዝግጁ ነዎት"</string>
- <string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"የስርዓት አሰሳ ቅንብሮች"</annotation></string>
- <string name="action_share" msgid="2648470652637092375">"አጋራ"</string>
- <string name="action_screenshot" msgid="8171125848358142917">"ቅጽበታዊ ገጽ እይታ"</string>
- <string name="action_split" msgid="2098009717623550676">"ክፈል"</string>
- <string name="toast_split_select_app" msgid="5453865907322018352">"የተከፈለ ማያን ለመጠቀም ሌላ መተግበሪያ መታ ያድርጉ"</string>
- <string name="toast_split_app_unsupported" msgid="3271526028981899666">"መተግበሪያው የተከፈለ ማያ ገጽን አይደግፍም።"</string>
- <string name="blocked_by_policy" msgid="2071401072261365546">"ይህ ድርጊት በመተግበሪያው ወይም በእርስዎ ድርጅት አይፈቀድም"</string>
- <string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"የአሰሳ አጋዥ ሥልጠናን ይዝለሉ?"</string>
- <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"ይህን በኋላ በ<xliff:g id="NAME">%1$s</xliff:g> መተግበሪያው ውስጥ ማግኘት ይችላሉ"</string>
- <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"ይቅር"</string>
- <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"ዝለል"</string>
- <string name="accessibility_rotate_button" msgid="4771825231336502943">"ማያ ገጹን አዙር"</string>
- <string name="taskbar_edu_opened" msgid="3950252793551919129">"የተግባር አሞሌ ትምህርት ይታያል"</string>
- <string name="taskbar_edu_closed" msgid="126643734478892862">"የተግባር አሞሌ ትምህርት ተዘግቷል"</string>
- <string name="taskbar_edu_switch_apps" msgid="6942863327845784813">"መተግበሪያዎችን ለመቀየር የተግባር አሞሌውን ይጠቀሙ"</string>
- <string name="taskbar_edu_splitscreen" msgid="2663361731630346489">"በአንድ ጊዜ ሁለት መተግበሪያዎችን ለመጠቀም ወደ ጎን ይጎትቱ"</string>
- <string name="taskbar_edu_stashing" msgid="5212374387411764031">"የተግባር አሞሌውን ለመደበቅ ነክተው ይያዙት"</string>
- <string name="taskbar_edu_next" msgid="4007618274426775841">"ቀጣይ"</string>
- <string name="taskbar_edu_previous" msgid="459202320127201702">"ተመለስ"</string>
- <string name="taskbar_edu_close" msgid="887022990168191073">"ዝጋ"</string>
- <string name="taskbar_edu_done" msgid="6880178093977704569">"ተጠናቅቋል"</string>
- <string name="taskbar_button_home" msgid="2151398979630664652">"መነሻ"</string>
- <string name="taskbar_button_a11y" msgid="5241161324875094465">"ተደራሽነት"</string>
- <string name="taskbar_button_back" msgid="8558862226461164514">"ተመለስ"</string>
- <string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"አይኤምኢ መቀየሪያ"</string>
- <string name="taskbar_button_recents" msgid="7273376136216613134">"የቅርብ ጊዜዎቹ"</string>
- <string name="taskbar_button_notifications" msgid="7471740351507357318">"ማሳወቂያዎች"</string>
- <string name="taskbar_button_quick_settings" msgid="227662894293189391">"ፈጣን ቅንብሮች"</string>
- <string name="move_drop_target_top_or_left" msgid="2988702185049595807">"ወደ ላይ/ግራ ይውሰዱ"</string>
- <string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"ወደ ታች/ቀኝ ይውሰዱ"</string>
</resources>
diff --git a/quickstep/res/values-ar/strings.xml b/quickstep/res/values-ar/strings.xml
index 58b26d1cd3..b036bc1ebd 100644
--- a/quickstep/res/values-ar/strings.xml
+++ b/quickstep/res/values-ar/strings.xml
@@ -19,93 +19,19 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="recent_task_option_split_screen" msgid="5353188922202653570">"تقسيم الشاشة"</string>
<string name="recent_task_option_pin" msgid="7929860679018978258">"تثبيت"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"شكل مجاني"</string>
+ <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"نظرة عامة"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"ليست هناك عناصر تم استخدامها مؤخرًا"</string>
+ <string name="accessibility_close_task" msgid="5354563209433803643">"إغلاق"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"إعدادات استخدام التطبيق"</string>
<string name="recents_clear_all" msgid="5328176793634888831">"محو الكل"</string>
<string name="accessibility_recent_apps" msgid="4058661986695117371">"التطبيقات المستخدمة مؤخرًا"</string>
- <string name="task_view_closed" msgid="9170038230110856166">"تم إغلاق المهمة."</string>
<string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>، <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
<string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"أقل من دقيقة"</string>
<string name="time_left_for_app" msgid="3111996412933644358">"يتبقى اليوم <xliff:g id="TIME">%1$s</xliff:g>."</string>
- <string name="title_app_suggestions" msgid="4185902664111965088">"التطبيقات المقترحة"</string>
+ <string name="title_app_suggestions" msgid="4185902664111965088">"اقتراحات التطبيقات"</string>
+ <string name="all_apps_label" msgid="8542784161730910663">"جميع التطبيقات"</string>
<string name="all_apps_prediction_tip" msgid="2672336544844936186">"تطبيقاتك المتوقّعة"</string>
- <string name="hotseat_edu_title_migrate" msgid="306578144424489980">"رؤية التطبيقات المقترحة في الصف السفلي من الشاشة الرئيسية"</string>
- <string name="hotseat_edu_title_migrate_landscape" msgid="3633942953997845243">"رؤية التطبيقات المقترحة في صف التطبيقات المفضّلة في الشاشة الرئيسية"</string>
- <string name="hotseat_edu_message_migrate" msgid="8927179260533775320">"يمكنك الوصول إلى التطبيقات الأكثر استخدامًا بسهولة من الشاشة الرئيسية مباشرةً. سيتم تغيير الاقتراحات استنادًا إلى استخدامك الروتيني. وسيتم نقل التطبيقات من الصف السفلي في الشاشة الرئيسية إلى الصف الأعلى."</string>
- <string name="hotseat_edu_message_migrate_landscape" msgid="4248943380443387697">"يمكنك الوصول إلى التطبيقات الأكثر استخدامًا بسهولة من الشاشة الرئيسية مباشرةً. سيتم تغيير الاقتراحات استنادًا إلى سلاسل الإجراءات. سيتم نقل التطبيقات من صف التطبيقات المفضّلة إلى الشاشة الرئيسية."</string>
- <string name="hotseat_edu_message_migrate_alt" msgid="3042360119039646356">"يمكنك الوصول إلى التطبيقات الأكثر استخدامًا بسهولة من الشاشة الرئيسية مباشرةً. سيتم تغيير الاقتراحات استنادًا إلى سلاسل الإجراءات. سيتم نقل التطبيقات من الصف الأسفل إلى مجلد جديد."</string>
- <string name="hotseat_edu_accept" msgid="1611544083278999837">"رؤية تطبيقات مقترحة"</string>
- <string name="hotseat_edu_dismiss" msgid="2781161822780201689">"لا، شكرًا"</string>
- <string name="hotseat_prediction_settings" msgid="6246554993566070818">"الإعدادات"</string>
- <string name="hotseat_auto_enrolled" msgid="522100018967146807">"تظهر هنا التطبيقات الأكثر استخدامًا، ويستند التغيير إلى سلاسل الإجراءات."</string>
- <string name="hotseat_tip_no_empty_slots" msgid="1325212677738179185">"يمكنك سحب التطبيقات من الصف الأسفل لتلقّي اقتراحات."</string>
- <string name="hotseat_tip_gaps_filled" msgid="3035673010274223538">"تمت إضافة التطبيقات المقترحة إلى مساحة فارغة."</string>
- <string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"تم تفعيل ميزة \"التطبيقات المقترحة\"."</string>
- <string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"ميزة \"التطبيقات المقترحة\" غير مفعّلة."</string>
- <string name="hotseat_prediction_content_description" msgid="4582028296938078419">"التطبيق المتوقع: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"تأكّد من التمرير سريعًا من أقصى الحافة اليسرى أو اليمنى."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"تأكّد من التمرير سريعًا من الحافة اليسرى أو اليمنى إلى وسط الشاشة ثم ارفع إصبعك."</string>
- <string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"لقد تعلمت كيفية التمرير سريعًا من اليسار للرجوع. تعرّف بعد ذلك على كيفية التبديل بين التطبيقات."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"لقد أكملت التدريب على إيماءة الرجوع."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"تأكّد من عدم التمرير بالقرب من أسفل الشاشة."</string>
- <string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"لتغيير مستوى حساسية إيماءة الرجوع، انتقِل إلى \"الإعدادات\""</string>
- <string name="back_gesture_intro_title" msgid="19551256430224428">"مرِّر سريعًا للرجوع."</string>
- <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"للرجوع إلى الشاشة السابقة، مرِّر سريعًا من الحافة اليسرى أو الحافة اليمنى إلى وسط الشاشة."</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"تأكّد من التمرير سريعًا من الحافة السفلى للشاشة إلى أعلاها."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"تأكّد من عدم التوقّف قليلاً قبل رفع إصبعك."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"تأكّد من التمرير إلى الأعلى مباشرةً."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"لقد أكملت التدريب على إيماءة الانتقال إلى الشاشة الرئيسية. تعرّف بعد ذلك على كيفية الرجوع."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"أكملت التدريب على إيماءة الانتقال إلى الشاشة الرئيسية."</string>
- <string name="home_gesture_intro_title" msgid="836590312858441830">"مرِّر سريعًا للانتقال إلى الشاشة الرئيسية"</string>
- <string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"مرِّر سريعًا من أسفل الشاشة إلى أعلاها. تنقلك هذه الإيماءة دائمًا إلى الشاشة الرئيسية."</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"تأكّد من التمرير سريعًا من الحافة السفلى للشاشة إلى أعلاها."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"حاوِل إبقاء إصبعك على النافذة لمدة أطول قبل رفعه."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"تأكّد من التمرير سريعًا للأعلى مباشرةً ثم التوقّف قليلاً."</string>
- <string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"لقد تعرّفت على كيفية استخدام الإيماءات. لإيقاف الإيماءات، انتقِل إلى \"الإعدادات\"."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"أكملت التدريب على إيماءة التبديل بين التطبيقات."</string>
- <string name="overview_gesture_intro_title" msgid="2902054412868489378">"مرِّر سريعًا للتبديل بين التطبيقات"</string>
- <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"للتبديل بين التطبيقات، مرِّر سريعًا من أسفل الشاشة لأعلاها مع تثبيت إصبعك ثم ارفعه."</string>
- <string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"اكتمل التدريب على الإيماءة"</string>
- <string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"تم"</string>
- <string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"الإعدادات"</string>
- <string name="gesture_tutorial_try_again" msgid="65962545858556697">"إعادة المحاولة"</string>
- <string name="gesture_tutorial_nice" msgid="2936275692616928280">"أحسنت"</string>
- <string name="gesture_tutorial_step" msgid="1279786122817620968">"الدليل التوجيهي <xliff:g id="CURRENT">%1$d</xliff:g> من إجمالي <xliff:g id="TOTAL">%2$d</xliff:g>"</string>
- <string name="allset_title" msgid="5021126669778966707">"اكتملت عملية الإعداد"</string>
- <string name="allset_hint" msgid="2384632994739392447">"مرِّر سريعًا للأعلى للانتقال إلى الشاشة الرئيسية."</string>
- <string name="allset_description" msgid="6350320429953234580">"يمكنك الآن بدء استخدام هاتفك."</string>
- <string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"إعدادات التنقّل داخل النظام"</annotation></string>
- <string name="action_share" msgid="2648470652637092375">"مشاركة"</string>
- <string name="action_screenshot" msgid="8171125848358142917">"لقطة شاشة"</string>
- <string name="action_split" msgid="2098009717623550676">"تقسيم"</string>
- <string name="toast_split_select_app" msgid="5453865907322018352">"انقر على تطبيق آخر لاستخدام وضع تقسيم الشاشة."</string>
- <string name="toast_split_app_unsupported" msgid="3271526028981899666">"التطبيق لا يتيح تقسيم الشاشة."</string>
- <string name="blocked_by_policy" msgid="2071401072261365546">"لا يسمح التطبيق أو لا تسمح مؤسستك بهذا الإجراء."</string>
- <string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"هل تريد تخطي الدليل التوجيهي؟"</string>
- <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"يمكنك العثور على هذا الدليل التوجيهي لاحقًا في التطبيق \"<xliff:g id="NAME">%1$s</xliff:g>\""</string>
- <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"إلغاء"</string>
- <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"التخطي"</string>
- <string name="accessibility_rotate_button" msgid="4771825231336502943">"تدوير الشاشة"</string>
- <string name="taskbar_edu_opened" msgid="3950252793551919129">"ظهرت لوحة تعليم استخدام شريط المهام."</string>
- <string name="taskbar_edu_closed" msgid="126643734478892862">"تم إغلاق لوحة تعليم استخدام شريط المهام."</string>
- <string name="taskbar_edu_switch_apps" msgid="6942863327845784813">"يمكنك استخدام شريط المهام للتبديل بين التطبيقات."</string>
- <string name="taskbar_edu_splitscreen" msgid="2663361731630346489">"اسحبه إلى جانب الشاشة لاستخدام تطبيقين في آنٍ واحد."</string>
- <string name="taskbar_edu_stashing" msgid="5212374387411764031">"انقر مع الاستمرار لإخفاء شريط المهام."</string>
- <string name="taskbar_edu_next" msgid="4007618274426775841">"الشاشة التالية"</string>
- <string name="taskbar_edu_previous" msgid="459202320127201702">"رجوع"</string>
- <string name="taskbar_edu_close" msgid="887022990168191073">"إغلاق"</string>
- <string name="taskbar_edu_done" msgid="6880178093977704569">"تم"</string>
- <string name="taskbar_button_home" msgid="2151398979630664652">"الرئيسية"</string>
- <string name="taskbar_button_a11y" msgid="5241161324875094465">"تسهيل الاستخدام"</string>
- <string name="taskbar_button_back" msgid="8558862226461164514">"رجوع"</string>
- <string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"‏مفتاح التبديل إلى IME"</string>
- <string name="taskbar_button_recents" msgid="7273376136216613134">"الأحدث"</string>
- <!-- no translation found for taskbar_button_notifications (7471740351507357318) -->
- <skip />
- <!-- no translation found for taskbar_button_quick_settings (227662894293189391) -->
- <skip />
- <string name="move_drop_target_top_or_left" msgid="2988702185049595807">"الانتقال إلى يمين الشاشة أو أعلاها"</string>
- <string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"الانتقال إلى يسار الشاشة أو أسفلها"</string>
</resources>
diff --git a/quickstep/res/values-as/strings.xml b/quickstep/res/values-as/strings.xml
index 38a506f265..c188493e59 100644
--- a/quickstep/res/values-as/strings.xml
+++ b/quickstep/res/values-as/strings.xml
@@ -19,93 +19,19 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="recent_task_option_split_screen" msgid="5353188922202653570">"বিভাজিত স্ক্ৰীণ"</string>
<string name="recent_task_option_pin" msgid="7929860679018978258">"পিন"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Freeform"</string>
+ <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"অৱলোকন"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"কোনো শেহতীয়া বস্তু নাই"</string>
- <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"এপে ব্যৱহাৰ কৰা ডেটাৰ ছেটিং"</string>
- <string name="recents_clear_all" msgid="5328176793634888831">"আটাইবোৰ মচক"</string>
+ <string name="accessibility_close_task" msgid="5354563209433803643">"বন্ধ কৰক"</string>
+ <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"এপে ব্যৱহাৰ কৰা ডেটাৰ ছেটিংসমূহ"</string>
+ <string name="recents_clear_all" msgid="5328176793634888831">"সকলো মচক"</string>
<string name="accessibility_recent_apps" msgid="4058661986695117371">"শেহতীয়া এপসমূহ"</string>
- <string name="task_view_closed" msgid="9170038230110856166">"কাৰ্য বন্ধ কৰা হ’ল"</string>
<string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
<string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; ১ মিনিট"</string>
<string name="time_left_for_app" msgid="3111996412933644358">"আজি <xliff:g id="TIME">%1$s</xliff:g> বাকী আছ"</string>
- <string name="title_app_suggestions" msgid="4185902664111965088">"এপ চাজেশ্বন"</string>
- <string name="all_apps_prediction_tip" msgid="2672336544844936186">"আপোনাৰ প্ৰয়োজন হ\'ব পৰা এপ্"</string>
- <string name="hotseat_edu_title_migrate" msgid="306578144424489980">"আপোনাৰ গৃহ স্ক্ৰীনৰ একেবাৰে তলৰ শাৰীটোত এপৰ পৰামর্শসমূহ পাওক"</string>
- <string name="hotseat_edu_title_migrate_landscape" msgid="3633942953997845243">"আপোনাৰ গৃহ স্ক্ৰীনৰ প্ৰিয় সমলৰ শাৰীটোত এপৰ পৰামর্শসমূহ পাওক"</string>
- <string name="hotseat_edu_message_migrate" msgid="8927179260533775320">"আপোনাৰ সকলোতকৈ বেছিকৈ ব্যৱহৃত এপ্‌সমূহ গৃহ স্ক্ৰীনতে সহজে এক্সেছ কৰক। আপোনাৰ ৰুটিনসমূহৰ ভিত্তিত পৰামর্শসমূহ সলনি হ\'ব। একেবাৰে তলৰ শাৰীটোত থকা এপ্‌সমূহ ওপৰৰ আপোনাৰ গৃহ স্ক্ৰীনলৈ যাব।"</string>
- <string name="hotseat_edu_message_migrate_landscape" msgid="4248943380443387697">"আপোনাৰ সকলোতকৈ বেছিকৈ ব্যৱহৃত এপ্‌সমূহ গৃহ স্ক্ৰীনতে সহজে এক্সেছ কৰক। আপোনাৰ ৰুটিনসমূহৰ ভিত্তিত পৰামর্শসমূহ সলনি হ’ব। প্ৰিয় সমলৰ শাৰীত থকা এপ্‌সমূহ আপোনাৰ গৃহ স্ক্রীনলৈ যাব।"</string>
- <string name="hotseat_edu_message_migrate_alt" msgid="3042360119039646356">"আপোনাৰ সকলোতকৈ বেছিকৈ ব্যৱহৃত এপ্‌সমূহ গৃহ স্ক্ৰীনতে সহজে এক্সেছ কৰক। আপোনাৰ ৰুটিনসমূহৰ ভিত্তিত পৰামর্শসমূহ সলনি হ\'ব। একেবাৰে তলৰ শাৰীটোত থকা এপ্‌সমূহ এটা নতুন ফ\'ল্ডাৰলৈ যাব।"</string>
- <string name="hotseat_edu_accept" msgid="1611544083278999837">"এপৰ পৰামর্শসমূহ পাওক"</string>
- <string name="hotseat_edu_dismiss" msgid="2781161822780201689">"নালাগে, ধন্যবাদ"</string>
- <string name="hotseat_prediction_settings" msgid="6246554993566070818">"ছেটিং"</string>
- <string name="hotseat_auto_enrolled" msgid="522100018967146807">"সকলোতকৈ বেছিকৈ ব্যৱহৃত এপ্‌সমূহ ইয়াত প্ৰদর্শিত হয় আৰু ৰুটিনসমূহ ওপৰত ভিত্তি কৰি সলনি হয়"</string>
- <string name="hotseat_tip_no_empty_slots" msgid="1325212677738179185">"এপৰ পৰামর্শসমূহ পাবলৈ একেবাৰে তলৰ শাৰীত থকা এপ্‌সমূহ টানি আঁতৰাওক"</string>
- <string name="hotseat_tip_gaps_filled" msgid="3035673010274223538">"খালী ঠাইত এপৰ পৰামর্শসমূহ যোগ কৰা হ\'ল"</string>
- <string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"এপৰ পৰামৰ্শসমূহ সক্ষম কৰা আছে"</string>
- <string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"এপৰ পৰামৰ্শসমূহ অক্ষম কৰা আছে"</string>
- <string name="hotseat_prediction_content_description" msgid="4582028296938078419">"পূৰ্বানুমান কৰা এপ্: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"আপুনি সোঁ অথবা বাওঁ প্ৰান্তৰৰ একেবাৰে সীমাৰ পৰা ছোৱাইপ কৰাটো নিশ্চিত কৰক।"</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"আপুনি স্ক্ৰীনৰ সোঁ অথবা বাওঁ প্ৰান্তৰৰ পৰা মধ্যভাগলৈকে ছোৱাইপ কৰি এৰি দিয়াটো নিশ্চিত কৰক।"</string>
- <string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"সোঁফালৰ পৰা ছোৱাইপ কৰি কেনেকৈ উভতি যাব লাগে, সেইটো আপুনি জানিলে। ইয়াৰ পাছত, এপ্‌ কেনেকৈ সলনি কৰিব সেয়া জানক।"</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"আপুনি উভতি যাওক নিৰ্দেশটো সম্পূৰ্ণ কৰিলে।"</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"আপুনি স্ক্ৰীনৰ তলৰ অংশৰ বেছি ওচৰলৈ ছোৱাইপ নকৰাটো নিশ্চিত কৰক।"</string>
- <string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"উভতি যোৱাৰ নির্দেশটোৰ সংবেদনশীলতা সলনি কৰিবলৈ ছেটিঙলৈ যাওক"</string>
- <string name="back_gesture_intro_title" msgid="19551256430224428">"উভতি যাবলৈ ছোৱাইপ কৰক"</string>
- <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"অন্তিম স্ক্ৰীনখনলৈ উভতি যাবলৈ বাওঁ অথবা সোঁ প্ৰান্তৰৰ পৰা মাজলৈ ছোৱাইপ কৰক।"</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"আপুনি স্ক্ৰীনৰ তলৰ প্ৰান্তৰ পৰা ওপৰলৈ ছোৱাইপ কৰাটো নিশ্চিত কৰক।"</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"আপুনি এৰি দিয়াৰ পূৰ্বে অলপো নোৰোৱাটো নিশ্চিত কৰক।"</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"আপুনি পোনকৈ ওপৰলৈ ছোৱাইপ কৰাটো নিশ্চিত কৰক।"</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"আপুনি গৃহ স্ক্ৰীনলৈ যোৱাৰ নিৰ্দেশটো সম্পূৰ্ণ কৰিলে। ইয়াৰ পাছত, গৃহ স্ক্ৰীনলৈ কেনেকৈ যাব সেয়া জানক।"</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"আপুনি গৃহ স্ক্ৰীনলৈ যোৱাৰ নিৰ্দেশটো সম্পূৰ্ণ কৰিলে।"</string>
- <string name="home_gesture_intro_title" msgid="836590312858441830">"গৃহ স্ক্ৰীনলৈ যাবলৈ ছোৱাইপ কৰক"</string>
- <string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"আপোনাৰ স্ক্ৰীনৰ তলৰ অংশৰ পৰা ওপৰলৈ ছোৱাইপ কৰক। এই নিৰ্দেশটোৱে আপোনাক সদায় গৃহ স্ক্ৰীনলৈ লৈ যায়।"</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"আপুনি স্ক্ৰীনৰ তলৰ প্ৰান্তৰ পৰা ওপৰলৈ ছোৱাইপ কৰাটো নিশ্চিত কৰক।"</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"এৰি দিয়াৰ পূৰ্বে ৱিণ্ডখন দীৰ্ঘ সময়ৰ বাবে ধৰি ৰাখিবলৈ চেষ্টা কৰক।"</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"আপুনি স্ক্ৰীনৰ ওপৰলৈ পোনকৈ ছোৱাইপ কৰি তাৰ পাছত ৰোৱাটো নিশ্চিত কৰক।"</string>
- <string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"আপুনি নিৰ্দেশসমূহ কেনেকৈ ব্যৱহাৰ কৰিব লাগে সেয়া জানিলে। নিৰ্দেশসমূহ অফ কৰিবলৈ, ছেটিঙলৈ যাওক।"</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"আপুনি এপ্‌ সলনি কৰাৰ নিৰ্দেশটো সম্পূৰ্ণ কৰিলে।"</string>
- <string name="overview_gesture_intro_title" msgid="2902054412868489378">"এপ্‌ সলনি কৰিবলৈ ছোৱাইপ কৰক"</string>
- <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"এপ্‌সমূহ সালসলনিকৈ ব্যৱহাৰ কৰিবলৈ আপোনাৰ স্ক্ৰীনৰ একেবাৰে তলৰ অংশৰ পৰা ওপৰলৈ ছোৱাইপ কৰি ধৰি ৰাখক আৰু তাৰ পাছত এৰি দিয়ক।"</string>
- <string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"সম্পূৰ্ণ সাজু"</string>
- <string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"হ’ল"</string>
- <string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"ছেটিং"</string>
- <string name="gesture_tutorial_try_again" msgid="65962545858556697">"পুনৰ চেষ্টা কৰক"</string>
- <string name="gesture_tutorial_nice" msgid="2936275692616928280">"সুন্দৰ!"</string>
- <string name="gesture_tutorial_step" msgid="1279786122817620968">"টিউট’ৰিয়েল <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
- <string name="allset_title" msgid="5021126669778966707">"সকলো সাজু!"</string>
- <string name="allset_hint" msgid="2384632994739392447">"গৃহ স্ক্ৰীনলৈ যাবলৈ ওপৰলৈ ছোৱাইপ কৰক"</string>
- <string name="allset_description" msgid="6350320429953234580">"আপুনি আপোনাৰ ফ’নটো ব্যৱহাৰ কৰিবলৈ সাজু"</string>
- <string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"ছিষ্টেম নেভিগেশ্বনৰ ছেটিং"</annotation></string>
- <string name="action_share" msgid="2648470652637092375">"শ্বেয়াৰ কৰক"</string>
- <string name="action_screenshot" msgid="8171125848358142917">"স্ক্ৰীনশ্বট"</string>
- <string name="action_split" msgid="2098009717623550676">"বিভাজন কৰক"</string>
- <string name="toast_split_select_app" msgid="5453865907322018352">"বিভাজিত স্ক্ৰীন ব্যৱহাৰ কৰিবলৈ অন্য এটা এপত টিপক"</string>
- <string name="toast_split_app_unsupported" msgid="3271526028981899666">"এপ্‌টোৱে বিভাজিত স্ক্ৰীন সমৰ্থন নকৰে।"</string>
- <string name="blocked_by_policy" msgid="2071401072261365546">"এপ্‌টোৱে অথবা আপোনাৰ প্ৰতিষ্ঠানে এই কাৰ্যটোৰ অনুমতি নিদিয়ে"</string>
- <string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"নেভিগেশ্বনৰ টিউট’ৰিয়েল এৰিব বিচাৰে নেকি?"</string>
- <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"আপুনি এয়া পাছত <xliff:g id="NAME">%1$s</xliff:g> এপ্‌টোত বিচাৰিব পাৰিব"</string>
- <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"বাতিল কৰক"</string>
- <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"এৰি যাওক"</string>
- <string name="accessibility_rotate_button" msgid="4771825231336502943">"স্ক্ৰীনখন ঘূৰাওক"</string>
- <string name="taskbar_edu_opened" msgid="3950252793551919129">"টাস্কবাৰৰ শিক্ষাৰ পেনেলটো প্ৰদর্শিত হৈছে"</string>
- <string name="taskbar_edu_closed" msgid="126643734478892862">"টাস্কবাৰৰ শিক্ষাৰ পেনেলটো বন্ধ হৈছে"</string>
- <string name="taskbar_edu_switch_apps" msgid="6942863327845784813">"এপ্‌ সলনি কৰিবলৈ টাস্কবাৰডাল ব্যৱহাৰ কৰক"</string>
- <string name="taskbar_edu_splitscreen" msgid="2663361731630346489">"এবাৰতে দুটা এপ্‌ ব্যৱহাৰ কৰিবলৈ কাষলৈ টানি আনি এৰক"</string>
- <string name="taskbar_edu_stashing" msgid="5212374387411764031">"টাস্কবাৰডাল লুকুৱাবলৈ স্পৰ্শ কৰি ধৰি ৰাখক"</string>
- <string name="taskbar_edu_next" msgid="4007618274426775841">"পৰৱৰ্তী"</string>
- <string name="taskbar_edu_previous" msgid="459202320127201702">"উভতি যাওক"</string>
- <string name="taskbar_edu_close" msgid="887022990168191073">"বন্ধ কৰক"</string>
- <string name="taskbar_edu_done" msgid="6880178093977704569">"হ’ল"</string>
- <string name="taskbar_button_home" msgid="2151398979630664652">"গৃহপৃষ্ঠা"</string>
- <string name="taskbar_button_a11y" msgid="5241161324875094465">"সাধ্য সুবিধা"</string>
- <string name="taskbar_button_back" msgid="8558862226461164514">"উভতি যাওক"</string>
- <string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"IME ছুইচ্চাৰ"</string>
- <string name="taskbar_button_recents" msgid="7273376136216613134">"শেহতীয়া"</string>
- <!-- no translation found for taskbar_button_notifications (7471740351507357318) -->
- <skip />
- <!-- no translation found for taskbar_button_quick_settings (227662894293189391) -->
- <skip />
- <string name="move_drop_target_top_or_left" msgid="2988702185049595807">"ওপৰৰ বাঁওফাললৈ নিয়ক"</string>
- <string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"তলৰ সোঁফাললৈ নিয়ক"</string>
+ <string name="title_app_suggestions" msgid="4185902664111965088">"এপৰ পৰামৰ্শসমূহ"</string>
+ <string name="all_apps_label" msgid="8542784161730910663">"সকলো এপ্"</string>
+ <string name="all_apps_prediction_tip" msgid="2672336544844936186">"আপোনাৰ অনুমানিক এপ্"</string>
</resources>
diff --git a/quickstep/res/values-az/strings.xml b/quickstep/res/values-az/strings.xml
index 74fcb63faf..aa8fa536ac 100644
--- a/quickstep/res/values-az/strings.xml
+++ b/quickstep/res/values-az/strings.xml
@@ -19,93 +19,19 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Bölünmüş ekran"</string>
<string name="recent_task_option_pin" msgid="7929860679018978258">"Sancın"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Sərbəst rejim"</string>
+ <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"İcmal"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"Son elementlər yoxdur"</string>
+ <string name="accessibility_close_task" msgid="5354563209433803643">"Bağlayın"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Tətbiq istifadə ayarları"</string>
<string name="recents_clear_all" msgid="5328176793634888831">"Hamısını silin"</string>
<string name="accessibility_recent_apps" msgid="4058661986695117371">"Son tətbiqlər"</string>
- <string name="task_view_closed" msgid="9170038230110856166">"Tapşırıq bağlanıb"</string>
<string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
<string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 dəq"</string>
<string name="time_left_for_app" msgid="3111996412933644358">"Bu gün <xliff:g id="TIME">%1$s</xliff:g> qaldı"</string>
<string name="title_app_suggestions" msgid="4185902664111965088">"Tətbiq təklifləri"</string>
+ <string name="all_apps_label" msgid="8542784161730910663">"Bütün tətbiqlər"</string>
<string name="all_apps_prediction_tip" msgid="2672336544844936186">"Təklif edilən tətbiqlər"</string>
- <string name="hotseat_edu_title_migrate" msgid="306578144424489980">"Ana ekranın aşağı sırasında tətbiq təklifləri alın"</string>
- <string name="hotseat_edu_title_migrate_landscape" msgid="3633942953997845243">"Ana ekranın sevimlilər sırasında tətbiq təklifləri alın"</string>
- <string name="hotseat_edu_message_migrate" msgid="8927179260533775320">"Birbaşa Ana ekrandan ən çox istifadə edilən tətbiqlərə asanlıqla daxil olun. Təkliflər rejimlərinizə uyğun olaraq dəyişəcək. Aşağı sıradakı tətbiqlər Ana ekrana köçürüləcək."</string>
- <string name="hotseat_edu_message_migrate_landscape" msgid="4248943380443387697">"Birbaşa Ana ekrandan ən çox işlədilən tətbiqlərə asanlıqla girin. Təkliflər rejimlərinizə uyğun olaraq dəyişəcək. Sevimlilər sırasındakı tətbiqlər Əsas ekrana köçürüləcək."</string>
- <string name="hotseat_edu_message_migrate_alt" msgid="3042360119039646356">"Birbaşa Əsas səhifədən ən çox istifadə edilən tətbiqlərə asanlıqla daxil olun. Təkliflər rejimlərinizə uyğun olaraq dəyişəcək. Aşağı sıradakı tətbiqlər yeni qovluğa köçürüləcək."</string>
- <string name="hotseat_edu_accept" msgid="1611544083278999837">"Tətbiq təklifləri əldə edin"</string>
- <string name="hotseat_edu_dismiss" msgid="2781161822780201689">"Yox, çox sağolun"</string>
- <string name="hotseat_prediction_settings" msgid="6246554993566070818">"Ayarlar"</string>
- <string name="hotseat_auto_enrolled" msgid="522100018967146807">"Ən çox istifadə edilən tətbiqlər burada görünür və rejimlərə uyğun olaraq dəyişir"</string>
- <string name="hotseat_tip_no_empty_slots" msgid="1325212677738179185">"Tətbiq təklifləri əldə etmək üçün tətbiqləri aşağı sıradan kənara sürüşdürün"</string>
- <string name="hotseat_tip_gaps_filled" msgid="3035673010274223538">"Tətbiq təklifləri boş sahəyə əlavə edildi"</string>
- <string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Tətbiq təklifləri aktivdir"</string>
- <string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Tətbiq təklifləri deaktivdir"</string>
- <string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Proqnozlaşdırılan tətbiq: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Ekranın ən sağ və ya sol kənarından sürüşdürün."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Ekranın sağ və ya sol kənarından ortasına sürüşdürüb buraxın."</string>
- <string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Geri qayıtmaq üçün sağdan sürüşdürmək qaydasını öyrəndiniz. Sonra tətbiqləri keçirməyi öyrənin."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"Geri getmə jestini tamamladınız."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Ekranın altına çox yaxın sürüşdürmədiyinizə əmin olun."</string>
- <string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"Geri qayıtma jestinin həssaslığını dəyişmək üçün Ayarlara keçin"</string>
- <string name="back_gesture_intro_title" msgid="19551256430224428">"Geri qayıtmaq üçün sürüşdürün"</string>
- <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"Sonuncu ekrana qayıtmaq üçün ekranın sol, yaxud sağ kənarından mərkəzinə doğru sürüşdürün."</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Ekranın ən kənar aşağısından yuxarı sürüşdürün."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Buraxmazdan əvvəl durdurmadığınıza əmin olun."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Birbaşa yuxarı sürüşdürün."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"Əsas səhifəyə keçmə jestini tamamladınız. Sonra geri qayıtmağı öyrənin."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"Əsas səhifəyə keçmə jestini tamamladınız."</string>
- <string name="home_gesture_intro_title" msgid="836590312858441830">"Əsas səhifəyə keçmək üçün sürüşdürün"</string>
- <string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Ekranın aşağısından yuxarısına sürüşdürün. Bu jest həmişə Əsas səhifəyə aparır."</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Ekranın ən kənar aşağısından yuxarı sürüşdürün."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Barmağı buraxmadan öncə displeydə bir müddət saxlayın."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Sürüşdürüb ekranın yuxarı kənarında saxlayın."</string>
- <string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Jestlərdən istifadə qaydasını öyrəndiniz. Jestləri deaktiv etmək üçün Ayarlara keçin."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"Tətbiqləri keçirmə jestini tamamladınız."</string>
- <string name="overview_gesture_intro_title" msgid="2902054412868489378">"Tətbiqi keçirmək üçün sürüşdürün"</string>
- <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Tətbiqlər arasında keçid üçün ekranın aşağısından yuxarı doğru sürüşdürüb saxlayın, sonra buraxın."</string>
- <string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"Tam hazır"</string>
- <string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Oldu"</string>
- <string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Ayarlar"</string>
- <string name="gesture_tutorial_try_again" msgid="65962545858556697">"Yenə sınayın"</string>
- <string name="gesture_tutorial_nice" msgid="2936275692616928280">"Əla!"</string>
- <string name="gesture_tutorial_step" msgid="1279786122817620968">"Dərslik <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
- <string name="allset_title" msgid="5021126669778966707">"Hər şey hazırdır!"</string>
- <string name="allset_hint" msgid="2384632994739392447">"Əsas səhifəyə keçmək üçün yuxarı çəkin"</string>
- <string name="allset_description" msgid="6350320429953234580">"Telefondan istifadəyə başlamağa hazırsınız"</string>
- <string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"Sistem naviqasiya ayarları"</annotation></string>
- <string name="action_share" msgid="2648470652637092375">"Paylaşın"</string>
- <string name="action_screenshot" msgid="8171125848358142917">"Skrinşot"</string>
- <string name="action_split" msgid="2098009717623550676">"Ayırın"</string>
- <string name="toast_split_select_app" msgid="5453865907322018352">"Bölmə ekranını istifadə etmək üçün başqa tətbiqə toxunun"</string>
- <string name="toast_split_app_unsupported" msgid="3271526028981899666">"Tətbiq ekran bölünməsini dəstəkləmir."</string>
- <string name="blocked_by_policy" msgid="2071401072261365546">"Bu əməliyyata tətbiq və ya təşkilatınız tərəfindən icazə verilmir"</string>
- <string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Naviqasiya dərsliyi ötürülsün?"</string>
- <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Bunu sonra <xliff:g id="NAME">%1$s</xliff:g> tətbiqində tapa bilərsiniz"</string>
- <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Ləğv edin"</string>
- <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Ötürün"</string>
- <string name="accessibility_rotate_button" msgid="4771825231336502943">"Ekranı fırladın"</string>
- <string name="taskbar_edu_opened" msgid="3950252793551919129">"Tapşırıq panelindəki təlim bölməsi görünür"</string>
- <string name="taskbar_edu_closed" msgid="126643734478892862">"Tapşırıq panelindəki təlim bölməsi bağlanıb"</string>
- <string name="taskbar_edu_switch_apps" msgid="6942863327845784813">"Tətbiqləri keçirmək üçün tapşırıq panelindən istifadə edin"</string>
- <string name="taskbar_edu_splitscreen" msgid="2663361731630346489">"Eyni anda iki tətbiqi istifadə etmək üçün yan tərəfə çəkin"</string>
- <string name="taskbar_edu_stashing" msgid="5212374387411764031">"Tapşırıq panelini toxunub saxlamaqla gizlədin"</string>
- <string name="taskbar_edu_next" msgid="4007618274426775841">"Sonra"</string>
- <string name="taskbar_edu_previous" msgid="459202320127201702">"Geri"</string>
- <string name="taskbar_edu_close" msgid="887022990168191073">"Bağlayın"</string>
- <string name="taskbar_edu_done" msgid="6880178093977704569">"Hazırdır"</string>
- <string name="taskbar_button_home" msgid="2151398979630664652">"Ev"</string>
- <string name="taskbar_button_a11y" msgid="5241161324875094465">"Əlçatımlılıq"</string>
- <string name="taskbar_button_back" msgid="8558862226461164514">"Geriyə"</string>
- <string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"IME keçiricisi"</string>
- <string name="taskbar_button_recents" msgid="7273376136216613134">"Sonuncular"</string>
- <!-- no translation found for taskbar_button_notifications (7471740351507357318) -->
- <skip />
- <!-- no translation found for taskbar_button_quick_settings (227662894293189391) -->
- <skip />
- <string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Yuxarı/sola köçürün"</string>
- <string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Aşağı/sağa köçürün"</string>
</resources>
diff --git a/quickstep/res/values-b+sr+Latn/strings.xml b/quickstep/res/values-b+sr+Latn/strings.xml
index f495b00cbe..fbbe9d2dc5 100644
--- a/quickstep/res/values-b+sr+Latn/strings.xml
+++ b/quickstep/res/values-b+sr+Latn/strings.xml
@@ -19,91 +19,19 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Podeljeni ekran"</string>
<string name="recent_task_option_pin" msgid="7929860679018978258">"Zakači"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Slobodni oblik"</string>
+ <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Pregled"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"Nema nedavnih stavki"</string>
+ <string name="accessibility_close_task" msgid="5354563209433803643">"Zatvori"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Podešavanja korišćenja aplikacije"</string>
<string name="recents_clear_all" msgid="5328176793634888831">"Obriši sve"</string>
<string name="accessibility_recent_apps" msgid="4058661986695117371">"Nedavne aplikacije"</string>
- <string name="task_view_closed" msgid="9170038230110856166">"Zadatak je zatvoren"</string>
<string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
<string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 min"</string>
<string name="time_left_for_app" msgid="3111996412933644358">"Još <xliff:g id="TIME">%1$s</xliff:g> danas"</string>
<string name="title_app_suggestions" msgid="4185902664111965088">"Predlozi aplikacija"</string>
+ <string name="all_apps_label" msgid="8542784161730910663">"Sve aplikacije"</string>
<string name="all_apps_prediction_tip" msgid="2672336544844936186">"Predviđene aplikacije"</string>
- <string name="hotseat_edu_title_migrate" msgid="306578144424489980">"Dobijajte predloge aplikacija u donjem redu početnog ekrana"</string>
- <string name="hotseat_edu_title_migrate_landscape" msgid="3633942953997845243">"Dobijajte predloge aplikacija u redu sa omiljenim stavkama na početnom ekranu"</string>
- <string name="hotseat_edu_message_migrate" msgid="8927179260533775320">"Lako pristupajte aplikacijama koje najčešće koristite direktno sa početnog ekrana. Predlozi se menjaju na osnovu upotrebe. Aplikacije iz donjeg reda se premeštaju nagore na početni ekran."</string>
- <string name="hotseat_edu_message_migrate_landscape" msgid="4248943380443387697">"Lako pristupajte aplikacijama koje najčešće koristite direktno sa početnog ekrana. Predlozi se menjaju na osnovu vaših rutina. Aplikacije iz reda sa omiljenim stavkama se premeštaju na početni ekran."</string>
- <string name="hotseat_edu_message_migrate_alt" msgid="3042360119039646356">"Lako pristupajte aplikacijama koje najčešće koristite direktno sa početnog ekrana. Predlozi se menjaju na osnovu upotrebe. Aplikacije iz donjeg reda se premeštaju u nov folder."</string>
- <string name="hotseat_edu_accept" msgid="1611544083278999837">"Prikazuj predloge aplikacija"</string>
- <string name="hotseat_edu_dismiss" msgid="2781161822780201689">"Ne, hvala"</string>
- <string name="hotseat_prediction_settings" msgid="6246554993566070818">"Podešavanja"</string>
- <string name="hotseat_auto_enrolled" msgid="522100018967146807">"Ovde se prikazuju najčešće korišćene aplikacije i menjaju se u zavisnosti od upotrebe"</string>
- <string name="hotseat_tip_no_empty_slots" msgid="1325212677738179185">"Prevucite aplikacije iz donjeg reda da biste dobili predloge"</string>
- <string name="hotseat_tip_gaps_filled" msgid="3035673010274223538">"Predlozi aplikacija se dodaju na prazno mesto"</string>
- <string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Predlozi aplikacija su omogućeni"</string>
- <string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Predlozi aplikacija su onemogućeni"</string>
- <string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Predviđamo aplikaciju: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Obavezno prevucite od same desne ili leve ivice."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Obavezno prevucite od desne ili leve ivice do sredine ekrana i otpustite."</string>
- <string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Naučili ste kako da prevlačite zdesna da biste se vratili unazad. Sada naučite da zamenite aplikacije."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"Dovršili ste pokret za povratak."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Nikako ne prevlačite previše blizu dna ekrana."</string>
- <string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"Osetljivost pok. za nazad možete da promenite u Podešavanjima"</string>
- <string name="back_gesture_intro_title" msgid="19551256430224428">"Prevucite da biste se vratili unazad"</string>
- <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"Da biste se vratili na poslednji ekran, prevucite od leve ili desne ivice do sredine ekrana."</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Obavezno prevucite nagore od donje ivice ekrana."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Nikako ne stajte pre otpuštanja."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Obavezno prevucite pravo nagore."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"Dovršili ste pokret za povratak na početnu stranicu. Sada saznajte kako da se vratite."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"Dovršili ste pokret za povratak na početnu stranicu."</string>
- <string name="home_gesture_intro_title" msgid="836590312858441830">"Prevucite da biste otišli na početnu stranicu"</string>
- <string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Prevucite nagore od dna ekrana. Ovaj pokret vas uvek vodi na početni ekran."</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Obavezno prevucite nagore od donje ivice ekrana."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Probajte da držite prozor duže pre otpuštanja."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Obavezno prevucite pravo nagore, pa zastanite."</string>
- <string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Naučili ste kako da koristite pokrete. Da biste isključili pokrete, idite na podešavanja."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"Dovršili ste pokret za promenu aplikacija."</string>
- <string name="overview_gesture_intro_title" msgid="2902054412868489378">"Prevucite da biste zamenili aplikacije"</string>
- <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Za prelazak sa jedne aplikacije na drugu prevucite nagore od dna ekrana, zadržite, pa pustite."</string>
- <string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"To je to"</string>
- <string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Gotovo"</string>
- <string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Podešavanja"</string>
- <string name="gesture_tutorial_try_again" msgid="65962545858556697">"Probajte ponovo"</string>
- <string name="gesture_tutorial_nice" msgid="2936275692616928280">"Svaka čast!"</string>
- <string name="gesture_tutorial_step" msgid="1279786122817620968">"Vodič <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
- <string name="allset_title" msgid="5021126669778966707">"Gotovo!"</string>
- <string name="allset_hint" msgid="2384632994739392447">"Prevucite nagore da biste otvorili početni ekran"</string>
- <string name="allset_description" msgid="6350320429953234580">"Spremni ste da počnete da koristite telefon"</string>
- <string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"Podešavanja kretanja kroz sistem"</annotation></string>
- <string name="action_share" msgid="2648470652637092375">"Deli"</string>
- <string name="action_screenshot" msgid="8171125848358142917">"Snimak ekrana"</string>
- <string name="action_split" msgid="2098009717623550676">"Podeli"</string>
- <string name="toast_split_select_app" msgid="5453865907322018352">"Dodirnite drugu aplikaciju za podeljeni ekran"</string>
- <string name="toast_split_app_unsupported" msgid="3271526028981899666">"Aplikacija ne podržava podeljeni ekran."</string>
- <string name="blocked_by_policy" msgid="2071401072261365546">"Aplikacija ili organizacija ne dozvoljavaju ovu radnju"</string>
- <string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Želite da preskočite vodič za kretanje?"</string>
- <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Možete da pronađete ovo kasnije u aplikaciji <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Otkaži"</string>
- <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Preskoči"</string>
- <string name="accessibility_rotate_button" msgid="4771825231336502943">"Rotirajte ekran"</string>
- <string name="taskbar_edu_opened" msgid="3950252793551919129">"Edukativno okno iz trake zadataka se pojavilo"</string>
- <string name="taskbar_edu_closed" msgid="126643734478892862">"Edukativno okno iz trake zadataka je zatvoreno"</string>
- <string name="taskbar_edu_switch_apps" msgid="6942863327845784813">"Koristite traku zadataka da biste menjali aplikacije"</string>
- <string name="taskbar_edu_splitscreen" msgid="2663361731630346489">"Prevucite na stranu da koristite dve aplikacije odjednom"</string>
- <string name="taskbar_edu_stashing" msgid="5212374387411764031">"Dodirnite i zadržite za skrivanje trake zadataka"</string>
- <string name="taskbar_edu_next" msgid="4007618274426775841">"Dalje"</string>
- <string name="taskbar_edu_previous" msgid="459202320127201702">"Nazad"</string>
- <string name="taskbar_edu_close" msgid="887022990168191073">"Zatvori"</string>
- <string name="taskbar_edu_done" msgid="6880178093977704569">"Gotovo"</string>
- <string name="taskbar_button_home" msgid="2151398979630664652">"Početna"</string>
- <string name="taskbar_button_a11y" msgid="5241161324875094465">"Pristupačnost"</string>
- <string name="taskbar_button_back" msgid="8558862226461164514">"Nazad"</string>
- <string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"IME prebacivač"</string>
- <string name="taskbar_button_recents" msgid="7273376136216613134">"Nedavno"</string>
- <string name="taskbar_button_notifications" msgid="7471740351507357318">"Obaveštenja"</string>
- <string name="taskbar_button_quick_settings" msgid="227662894293189391">"Brza podešavanja"</string>
- <string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Premesti gore levo"</string>
- <string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Premesti dole desno"</string>
</resources>
diff --git a/quickstep/res/values-be/strings.xml b/quickstep/res/values-be/strings.xml
index 4872f7d61b..c4a277267c 100644
--- a/quickstep/res/values-be/strings.xml
+++ b/quickstep/res/values-be/strings.xml
@@ -19,93 +19,19 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Падзяліць экран"</string>
<string name="recent_task_option_pin" msgid="7929860679018978258">"Замацаваць"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Адвольная форма"</string>
+ <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Агляд"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"Няма новых элементаў"</string>
+ <string name="accessibility_close_task" msgid="5354563209433803643">"Закрыць"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Налады выкарыстання праграмы"</string>
<string name="recents_clear_all" msgid="5328176793634888831">"Ачысціць усё"</string>
<string name="accessibility_recent_apps" msgid="4058661986695117371">"Нядаўнія праграмы"</string>
- <string name="task_view_closed" msgid="9170038230110856166">"Задача закрыта"</string>
<string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
<string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 хв"</string>
<string name="time_left_for_app" msgid="3111996412933644358">"Сёння засталося <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="title_app_suggestions" msgid="4185902664111965088">"Прапановы праграм"</string>
+ <string name="all_apps_label" msgid="8542784161730910663">"Усе праграмы"</string>
<string name="all_apps_prediction_tip" msgid="2672336544844936186">"Вашы праграмы з падказак"</string>
- <string name="hotseat_edu_title_migrate" msgid="306578144424489980">"Атрымлівайце прапановы праграм у ніжнім радку на Галоўным экране."</string>
- <string name="hotseat_edu_title_migrate_landscape" msgid="3633942953997845243">"Атрымлівайце прапановы праграм у пераліку абраных на Галоўным экране"</string>
- <string name="hotseat_edu_message_migrate" msgid="8927179260533775320">"Атрымлiвайце доступ да праграм, якімі вы карыстаецеся найбольш часта, непасрэдна з Галоўнага экрана. Прапановы будуць змяняцца ў залежнасці ад вашых дзеянняў. Праграмы, якія знаходзяцца ў ніжнім радку, будуць перамешчаны на Галоўны экран."</string>
- <string name="hotseat_edu_message_migrate_landscape" msgid="4248943380443387697">"Атрымлівайце доступ да праграм, якімі вы карыстаецеся найбольш часта, непасрэдна з Галоўнага экрана. Прапановы будуць змяняцца ў залежнасці ад вашых дзеянняў. Пералік абраных праграм будзе перамешчаны на Галоўны экран."</string>
- <string name="hotseat_edu_message_migrate_alt" msgid="3042360119039646356">"Атрымлiвайце просты доступ да праграм, якімі вы карыстаецеся найбольш часта, непасрэдна з Галоўнага экрана. Прапановы будуць змяняцца ў залежнасці ад вашых дзеянняў. Праграмы, якія знаходзяцца ў ніжнім радку, будуць перамешчаны ў новую папку."</string>
- <string name="hotseat_edu_accept" msgid="1611544083278999837">"Атрымаць прапановы праграм"</string>
- <string name="hotseat_edu_dismiss" msgid="2781161822780201689">"Не, дзякуй"</string>
- <string name="hotseat_prediction_settings" msgid="6246554993566070818">"Налады"</string>
- <string name="hotseat_auto_enrolled" msgid="522100018967146807">"Тут з\'яўляюцца праграмы, якімі вы карыстаецеся найбольш часта. Гэты спіс змяняецца на падставе вашых дзеянняў"</string>
- <string name="hotseat_tip_no_empty_slots" msgid="1325212677738179185">"Перацягніце праграмы з ніжняга радка, каб атрымаць прапановы праграм"</string>
- <string name="hotseat_tip_gaps_filled" msgid="3035673010274223538">"Прапановы праграм дададзены на свабоднае месца"</string>
- <string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Прапановы праграм уключаны"</string>
- <string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Прапановы праграм выключаны"</string>
- <string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Праграма з падказкі: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Пераканайцеся, што вы праводзіце пальцам ад самага вугла (правага ці левага) экрана."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Пераканайцеся, што праводзіце пальцам з правага ці левага вугла ў цэнтр экрана, а потым адпускаеце."</string>
- <string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Вы даведаліся, як гартаць справа для вяртання. Цяпер даведайцеся, як пераключацца паміж праграмамі."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"Вы навучыліся рабіць жэст вяртання."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Пераканайцеся, што вы не праводзіце пальцам занадта блізка да ніжняга краю экрана."</string>
- <string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"Каб змяніць адчувальнасць жэста вяртання, адкрыйце налады"</string>
- <string name="back_gesture_intro_title" msgid="19551256430224428">"Правядзіце пальцам, каб вярнуцца"</string>
- <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"Каб вярнуцца на папярэдні экран, правядзіце пальцам ад левага ці правага краю да цэнтра экрана."</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Пераканайцеся, што праводзіце пальцам па экране знізу ўверх."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Пераканайцеся, што не затрымліваецеся перад адпусканнем."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Пераканайцеся, што праводзіце пальцам вертыкальна."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"Вы навучыліся рабіць жэст пераходу на галоўны экран. А зараз даведайцеся, як вярнуцца назад."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"Вы навучыліся рабіць жэст пераходу на галоўны экран."</string>
- <string name="home_gesture_intro_title" msgid="836590312858441830">"Правядзіце пальцам для пераходу на галоўны экран"</string>
- <string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Правядзіце пальцам па экране знізу ўверх. Гэты жэст дазваляе вярнуцца на Галоўны экран."</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Пераканайцеся, што праводзіце пальцам па экране знізу ўверх."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Перш чым адпусціць палец, паспрабуйце даўжэй утрымліваць акно націснутым."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Пераканайцеся, што праводзіце пальцам вертыкальна, а потым затрымліваеце яго."</string>
- <string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Вы навучыліся выкарыстоўваць жэсты. Каб выключыць жэсты, адкрыйце Налады."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"Вы навучыліся рабіць жэст пераключэння паміж праграмамі."</string>
- <string name="overview_gesture_intro_title" msgid="2902054412868489378">"Правядзіце пальцам для пераключэння паміж праграмамі"</string>
- <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Каб пераключыцца на іншую праграму, правядзіце па экране знізу ўверх, патрымайце палец і адпусціце."</string>
- <string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"Гатова"</string>
- <string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Гатова"</string>
- <string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Налады"</string>
- <string name="gesture_tutorial_try_again" msgid="65962545858556697">"Паўтарыць спробу"</string>
- <string name="gesture_tutorial_nice" msgid="2936275692616928280">"Выдатна!"</string>
- <string name="gesture_tutorial_step" msgid="1279786122817620968">"Дапаможнік <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
- <string name="allset_title" msgid="5021126669778966707">"Гатова!"</string>
- <string name="allset_hint" msgid="2384632994739392447">"Каб перайсці на галоўны экран, правядзіце пальцам уверх"</string>
- <string name="allset_description" msgid="6350320429953234580">"Вы можаце пачаць карыстанне тэлефонам"</string>
- <string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"Налады навігацыі ў сістэме"</annotation></string>
- <string name="action_share" msgid="2648470652637092375">"Абагуліць"</string>
- <string name="action_screenshot" msgid="8171125848358142917">"Здымак экрана"</string>
- <string name="action_split" msgid="2098009717623550676">"Падзелены экран"</string>
- <string name="toast_split_select_app" msgid="5453865907322018352">"Для падзеленага экрана націсніце на іншую праграму"</string>
- <string name="toast_split_app_unsupported" msgid="3271526028981899666">"Праграма не падтрымлівае рэжым падзеленага экрана."</string>
- <string name="blocked_by_policy" msgid="2071401072261365546">"Гэта дзеянне не дазволена праграмай ці вашай арганізацыяй"</string>
- <string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Прапусціць дапаможнік па навігацыі?"</string>
- <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Знайсці дапаможнік можна ў праграме \"<xliff:g id="NAME">%1$s</xliff:g>\""</string>
- <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Скасаваць"</string>
- <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Прапусціць"</string>
- <string name="accessibility_rotate_button" msgid="4771825231336502943">"Павярнуць экран"</string>
- <string name="taskbar_edu_opened" msgid="3950252793551919129">"З\'явілася панэль навучання на панэлі задач"</string>
- <string name="taskbar_edu_closed" msgid="126643734478892862">"Панэль навучання на панэлі задач закрыта"</string>
- <string name="taskbar_edu_switch_apps" msgid="6942863327845784813">"Выкарыстоўвайце панэль задач для пераключэння праграм"</string>
- <string name="taskbar_edu_splitscreen" msgid="2663361731630346489">"Перацягніце ўбок, каб адначасова скарыстаць дзве праграмы"</string>
- <string name="taskbar_edu_stashing" msgid="5212374387411764031">"Націсніце і ўтрымлівайце, каб схаваць панэль задач"</string>
- <string name="taskbar_edu_next" msgid="4007618274426775841">"Далей"</string>
- <string name="taskbar_edu_previous" msgid="459202320127201702">"Назад"</string>
- <string name="taskbar_edu_close" msgid="887022990168191073">"Закрыць"</string>
- <string name="taskbar_edu_done" msgid="6880178093977704569">"Гатова"</string>
- <string name="taskbar_button_home" msgid="2151398979630664652">"Галоўны экран"</string>
- <string name="taskbar_button_a11y" msgid="5241161324875094465">"Спецыяльныя"</string>
- <string name="taskbar_button_back" msgid="8558862226461164514">"Назад"</string>
- <string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"Выключальнік IME"</string>
- <string name="taskbar_button_recents" msgid="7273376136216613134">"Нядаўнія"</string>
- <!-- no translation found for taskbar_button_notifications (7471740351507357318) -->
- <skip />
- <!-- no translation found for taskbar_button_quick_settings (227662894293189391) -->
- <skip />
- <string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Перамясціць уверх/улева"</string>
- <string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Перамясціць уніз/управа"</string>
</resources>
diff --git a/quickstep/res/values-bg/strings.xml b/quickstep/res/values-bg/strings.xml
index 3fea5ee55e..9e8c54a9c7 100644
--- a/quickstep/res/values-bg/strings.xml
+++ b/quickstep/res/values-bg/strings.xml
@@ -19,93 +19,19 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Разделен екран"</string>
<string name="recent_task_option_pin" msgid="7929860679018978258">"Фиксиране"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Свободна форма"</string>
+ <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Общ преглед"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"Няма скорошни елементи"</string>
+ <string name="accessibility_close_task" msgid="5354563209433803643">"Затваряне"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Настройки за използването на приложенията"</string>
<string name="recents_clear_all" msgid="5328176793634888831">"Изчистване на всички"</string>
<string name="accessibility_recent_apps" msgid="4058661986695117371">"Скорошни приложения"</string>
- <string name="task_view_closed" msgid="9170038230110856166">"Задачата е затворена"</string>
<string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
<string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 мин"</string>
<string name="time_left_for_app" msgid="3111996412933644358">"Оставащо време днес: <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="title_app_suggestions" msgid="4185902664111965088">"Предложения за приложения"</string>
+ <string name="all_apps_label" msgid="8542784161730910663">"Всички приложения"</string>
<string name="all_apps_prediction_tip" msgid="2672336544844936186">"Предвидени приложения"</string>
- <string name="hotseat_edu_title_migrate" msgid="306578144424489980">"Получавайте предложения за приложения на най-долния ред на началния си екран"</string>
- <string name="hotseat_edu_title_migrate_landscape" msgid="3633942953997845243">"Получаване на предложения за приложения в реда с любими на началния екран"</string>
- <string name="hotseat_edu_message_migrate" msgid="8927179260533775320">"Осъществявайте лесен достъп до най-използваните от вас приложения директно от началния екран. Предложенията ще се променят въз основа на действията ви. Приложенията на най-долния ред ще се преместят на началния ви екран."</string>
- <string name="hotseat_edu_message_migrate_landscape" msgid="4248943380443387697">"Осъществявайте лесен достъп до най-използваните от вас приложения директно от началния екран. Предложенията ще се променят въз основа на действията ви. Приложенията в реда с любими ще бъдат преместени на началния екран."</string>
- <string name="hotseat_edu_message_migrate_alt" msgid="3042360119039646356">"Осъществявайте лесен достъп до най-използваните от вас приложения директно от началния екран. Предложенията ще се променят въз основа на действията ви. Приложенията на най-долния ред ще се преместят в нова папка."</string>
- <string name="hotseat_edu_accept" msgid="1611544083278999837">"Предложения"</string>
- <string name="hotseat_edu_dismiss" msgid="2781161822780201689">"Не, благодаря"</string>
- <string name="hotseat_prediction_settings" msgid="6246554993566070818">"Настройки"</string>
- <string name="hotseat_auto_enrolled" msgid="522100018967146807">"Най-използваните приложения се показват тук и се променят въз основа на поредиците"</string>
- <string name="hotseat_tip_no_empty_slots" msgid="1325212677738179185">"За да получавате предложения за приложения, с плъзгане премахнете приложенията от най-долния ред"</string>
- <string name="hotseat_tip_gaps_filled" msgid="3035673010274223538">"Предложенията за приложения са добавени на празното място"</string>
- <string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Предложенията за приложения са активирани"</string>
- <string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Функцията „Предложения за приложения“ е деактивирана"</string>
- <string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Предвидено приложение: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Трябва да прекарате пръст от най-дясната или най-лявата част на екрана."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Трябва да прекарате пръст от десния или левия край на екрана до средата, след което да освободите."</string>
- <string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Научихте жеста за връщане с плъзгане от дясно. Сега научете как се превключва между приложения."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"Изпълнихте жеста за връщане назад."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Не прекарвайте пръст твърде близо до долната част на екрана."</string>
- <string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"Променете чувств. на жеста за връщане назад от настройките"</string>
- <string name="back_gesture_intro_title" msgid="19551256430224428">"Жест за връщане назад"</string>
- <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"За да се върнете на предишния екран, прекарайте пръст от левия или десния край на екрана до средата."</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Трябва да прекарате пръст нагоре от долния край на екрана."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Не задържайте, преди да вдигнете пръста си."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Трябва да прекарате пръст право нагоре."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"Изпълнихте жеста за преминаване към началния екран. В следващия урок ще научите как да се върнете назад."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"Изпълнихте жеста за преминаване към началния екран."</string>
- <string name="home_gesture_intro_title" msgid="836590312858441830">"Жест за преминаване към началния екран"</string>
- <string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Прекарайте пръст нагоре от долната част на екрана. Този жест винаги ще ви отвежда до началния екран."</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Трябва да прекарате пръст нагоре от долния край на екрана."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Задръжте прозореца по-дълго, преди да вдигнете пръста си."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Прекарайте пръст право нагоре, след което задръжте."</string>
- <string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Научихте как да използвате жестовете. За да ги изключите, отворете настройките."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"Изпълнихте жеста за превключване между приложения."</string>
- <string name="overview_gesture_intro_title" msgid="2902054412868489378">"Жест за превключване между приложенията"</string>
- <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"За превключване прекарайте пръст нагоре от долната част на екрана, задръжте и освободете"</string>
- <string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"Готово"</string>
- <string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Готово"</string>
- <string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Настройки"</string>
- <string name="gesture_tutorial_try_again" msgid="65962545858556697">"Опитайте отново"</string>
- <string name="gesture_tutorial_nice" msgid="2936275692616928280">"Чудесно!"</string>
- <string name="gesture_tutorial_step" msgid="1279786122817620968">"Урок <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
- <string name="allset_title" msgid="5021126669778966707">"Готово!"</string>
- <string name="allset_hint" msgid="2384632994739392447">"Прекарайте пръст нагоре, за да отворите началния екран"</string>
- <string name="allset_description" msgid="6350320429953234580">"Можете да започнете да използвате телефона си"</string>
- <string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"Настройки за навигиране в системата"</annotation></string>
- <string name="action_share" msgid="2648470652637092375">"Споделяне"</string>
- <string name="action_screenshot" msgid="8171125848358142917">"Екранна снимка"</string>
- <string name="action_split" msgid="2098009717623550676">"Разделяне на екрана"</string>
- <string name="toast_split_select_app" msgid="5453865907322018352">"Докоснете друго прил., за да ползвате разд. екран"</string>
- <string name="toast_split_app_unsupported" msgid="3271526028981899666">"Приложението не поддържа разделен екран."</string>
- <string name="blocked_by_policy" msgid="2071401072261365546">"Това действие не е разрешено от приложението или организацията ви"</string>
- <string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Пропускане на урока за навигиране?"</string>
- <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Урокът е налице в приложението <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Отказ"</string>
- <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Пропускане"</string>
- <string name="accessibility_rotate_button" msgid="4771825231336502943">"Завъртане на екрана"</string>
- <string name="taskbar_edu_opened" msgid="3950252793551919129">"Показва се урокът за лентата на задачите"</string>
- <string name="taskbar_edu_closed" msgid="126643734478892862">"Урокът за лентата на задачите бе затворен"</string>
- <string name="taskbar_edu_switch_apps" msgid="6942863327845784813">"Използвайте лентата на задачите за превключване между прил."</string>
- <string name="taskbar_edu_splitscreen" msgid="2663361731630346489">"Плъзнете встрани, за да използвате едновременно 2 приложения"</string>
- <string name="taskbar_edu_stashing" msgid="5212374387411764031">"Докоснете и задръжте, за да скриете лентата на задачите"</string>
- <string name="taskbar_edu_next" msgid="4007618274426775841">"Напред"</string>
- <string name="taskbar_edu_previous" msgid="459202320127201702">"Назад"</string>
- <string name="taskbar_edu_close" msgid="887022990168191073">"Затваряне"</string>
- <string name="taskbar_edu_done" msgid="6880178093977704569">"Готово"</string>
- <string name="taskbar_button_home" msgid="2151398979630664652">"Начало"</string>
- <string name="taskbar_button_a11y" msgid="5241161324875094465">"Достъпност"</string>
- <string name="taskbar_button_back" msgid="8558862226461164514">"Назад"</string>
- <string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"Редактор за метода на въвежд.: Превключвател"</string>
- <string name="taskbar_button_recents" msgid="7273376136216613134">"Скорошни"</string>
- <!-- no translation found for taskbar_button_notifications (7471740351507357318) -->
- <skip />
- <!-- no translation found for taskbar_button_quick_settings (227662894293189391) -->
- <skip />
- <string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Преместване горе/вляво"</string>
- <string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Преместване долу/вдясно"</string>
</resources>
diff --git a/quickstep/res/values-bn/strings.xml b/quickstep/res/values-bn/strings.xml
index ddd0edd77e..57f92e5a0c 100644
--- a/quickstep/res/values-bn/strings.xml
+++ b/quickstep/res/values-bn/strings.xml
@@ -19,91 +19,19 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="recent_task_option_split_screen" msgid="5353188922202653570">"স্ক্রিন স্প্লিট করুন"</string>
<string name="recent_task_option_pin" msgid="7929860679018978258">"পিন করুন"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"ফ্রি-ফর্ম"</string>
+ <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"এক নজরে"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"কোনো সাম্প্রতিক আইটেম নেই"</string>
+ <string name="accessibility_close_task" msgid="5354563209433803643">"বন্ধ করুন"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"অ্যাপ ব্যবহারের সেটিংস"</string>
<string name="recents_clear_all" msgid="5328176793634888831">"সবকিছু খালি করুন"</string>
<string name="accessibility_recent_apps" msgid="4058661986695117371">"সম্প্রতি ব্যবহৃত অ্যাপ"</string>
- <string name="task_view_closed" msgid="9170038230110856166">"টাস্ক বন্ধ করা হয়েছে"</string>
<string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
<string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; ১ মি."</string>
<string name="time_left_for_app" msgid="3111996412933644358">"আজকে <xliff:g id="TIME">%1$s</xliff:g> বাকি আছে"</string>
<string name="title_app_suggestions" msgid="4185902664111965088">"অ্যাপের সাজেশন"</string>
+ <string name="all_apps_label" msgid="8542784161730910663">"সব অ্যাপ"</string>
<string name="all_apps_prediction_tip" msgid="2672336544844936186">"আপনার প্রয়োজন হতে পারে এমন অ্যাপ"</string>
- <string name="hotseat_edu_title_migrate" msgid="306578144424489980">"আপনার হোম স্ক্রিনের নিচে সারিতে অ্যাপ সাজেশন পান"</string>
- <string name="hotseat_edu_title_migrate_landscape" msgid="3633942953997845243">"হোম স্ক্রিনের \'ফেভারিট রো\' বিকল্পের জন্য অ্যাপ সাজেশন পান"</string>
- <string name="hotseat_edu_message_migrate" msgid="8927179260533775320">"হোম স্ক্রিন থেকে সরাসরি সব থেকে বেশি ব্যবহার করা অ্যাপগুলি অ্যাক্সেস করুন। আপনার রুটিনের উপর ভিত্তি করে সাজেশন পরির্তন করা হবে। নিচের সারিতে থাকা অ্যাপ আপনার হোম স্ক্রিনে সরানো হবে।"</string>
- <string name="hotseat_edu_message_migrate_landscape" msgid="4248943380443387697">"খুব বেশি ব্যবহার করেন এমন অ্যাপগুলি হোম স্ক্রিন থেকে সহজে সরাসরি অ্যাক্সেস করুন। আপনার রুটিন অনুযায়ী সাজেশন পরির্তন করা হবে। \'ফেভারিট রো\' বিকল্পে থাকা অ্যাপগুলি হোম স্ক্রিনে সরিয়ে দেওয়া হবে।"</string>
- <string name="hotseat_edu_message_migrate_alt" msgid="3042360119039646356">"হোম স্ক্রিনের পাশে সব থেকে ব্যবহার করা অ্যাপ সহজেই অ্যাক্সেস করুন। আপনার রুটিনের উপর ভিত্তি করে সাজেশন পরির্তন করা হবে। নিচের সারিতে থাকা অ্যাপ নতুন ফোল্ডারে সরানো হবে।"</string>
- <string name="hotseat_edu_accept" msgid="1611544083278999837">"অ্যাপ সাজেশন পান"</string>
- <string name="hotseat_edu_dismiss" msgid="2781161822780201689">"না থাক"</string>
- <string name="hotseat_prediction_settings" msgid="6246554993566070818">"সেটিংস"</string>
- <string name="hotseat_auto_enrolled" msgid="522100018967146807">"সব থেকে বেশি ব্যবহার করা অ্যাপ এখানে দেখানো হয় এবং রুটিনের উপর ভিত্তি করে পরিবর্তন হতে পারে"</string>
- <string name="hotseat_tip_no_empty_slots" msgid="1325212677738179185">"অ্যাপ সাজেশন পেতে নিচের সারিতে অ্যাপগুলি টেনে আনুন"</string>
- <string name="hotseat_tip_gaps_filled" msgid="3035673010274223538">"খালি জায়গাতে অ্যাপ সাজেশন যোগ করা হয়েছে"</string>
- <string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"অ্যাপ সাজেশন চালু করা আছে"</string>
- <string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"অ্যাপ সাজেশন বন্ধ করা আছে"</string>
- <string name="hotseat_prediction_content_description" msgid="4582028296938078419">"আপনার প্রয়োজন হতে পারে এমন অ্যাপ: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"স্ক্রিনের একেবারে ডান বা বাঁদিকের প্রান্ত থেকে সোয়াইপ করেছেন কিনা তা দেখে নিন।"</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"স্ক্রিনের ডান বা বাঁদিকের প্রান্ত থেকে মাঝখান পর্যন্ত সোয়াইপ করে আঙুল তুলে নিয়েছেন কিনা তা দেখে নিন।"</string>
- <string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"ফিরে যেতে, কীভাবে ডানদিক থেকে সোয়াইপ করতে হয় তা আপনি শিখেছেন। এরপর, একটি অ্যাপ থেকে অন্য অ্যাপে কীভাবে যাবেন জেনে নিন।"</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"আপনি ফিরে যাওয়ার জেসচার সম্পর্কে জেনেছেন।"</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"স্ক্রিনের নিচের প্রান্তের খুব কাছে পর্যন্ত যাতে সোয়াইপ না করেন সেটি ভাল করে দেখে নিন।"</string>
- <string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"ফিরে যাওয়ার জেসচারের সেন্সিটিভিটি পরিবর্তন করতে, সেটিংসে যান"</string>
- <string name="back_gesture_intro_title" msgid="19551256430224428">"ফিরে যেতে সোয়াইপ করুন"</string>
- <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"শেষের স্ক্রিনে ফিরে যেতে, ডান বা বাঁ প্রান্ত থেকে স্ক্রিনের মাঝখান পর্যন্ত সোয়াইপ করুন।"</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"স্ক্রিনের নিচের প্রান্ত থেকে আপনি সোয়াইপ করেছেন কিনা ভাল করে দেখে নিন।"</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"আঙুল তুলে নেওয়ার আগে আপনি যাতে পজ না করেন সেটি ভাল করে দেখে নিন।"</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"আপনি উপরের দিকে সোজাসুজি সোয়াইপ করেছেন কিনা ভাল করে দেখে নিন।"</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"আপনি হোম স্ক্রিনে যাওয়ার জেসচার সম্পর্কে জেনেছেন। এরপর, ফিরে কীভাবে যাবেন তা জেনে নিন।"</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"আপনি হোম স্ক্রিনে যাওয়ার জেসচার সম্পর্কে জেনেছেন।"</string>
- <string name="home_gesture_intro_title" msgid="836590312858441830">"হোম স্ক্রিনে যেতে সোয়াইপ করুন"</string>
- <string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"স্ক্রিনের নিচের প্রান্ত থেকে উপরের দিকে সোয়াইপ করুন। এটি করলে, আপনি সবসময় হোম স্ক্রিনে যেতে পারবেন।"</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"স্ক্রিনের নিচের প্রান্ত থেকে আপনি সোয়াইপ করেছেন কিনা ভাল করে দেখে নিন।"</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"চেষ্টা করুন যাতে আঙুল সরিয়ে নেওয়ার আগে উইন্ডো কিছুক্ষণ প্রেস করে রাখা যায়।"</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"আপনি উপরের দিকে সোজাসুজি সোয়াইপ করেছেন কিনা ভাল করে দেখে নিয়ে তারপর পজ করুন।"</string>
- <string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"জেসচার কীভাবে ব্যবহার করতে হয় আপনি তা শিখে ফেলেছেন। জেসচার বন্ধ করতে, সেটিংসে যান।"</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"আপনি একটি অ্যাপ থেকে অন্য অ্যাপে যাওয়ার জেসচার সম্পর্কে জেনেছেন।"</string>
- <string name="overview_gesture_intro_title" msgid="2902054412868489378">"একটি অ্যাপ থেকে অন্য অ্যাপে যেতে সোয়াইপ করুন"</string>
- <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"একটি অ্যাপ থেকে অন্যটিতে পাল্টাতে, স্ক্রিনের নিচ থেকে উপরে সোয়াইপ করে ধরে রাখুন, তারপরে ছেড়ে দিন।"</string>
- <string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"সব প্রস্তুত"</string>
- <string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"সম্পূর্ণ হয়েছে"</string>
- <string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"সেটিংস"</string>
- <string name="gesture_tutorial_try_again" msgid="65962545858556697">"আবার চেষ্টা করুন"</string>
- <string name="gesture_tutorial_nice" msgid="2936275692616928280">"সাবাস!"</string>
- <string name="gesture_tutorial_step" msgid="1279786122817620968">"টিউটোরিয়াল <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
- <string name="allset_title" msgid="5021126669778966707">"সব রেডি!"</string>
- <string name="allset_hint" msgid="2384632994739392447">"হোম স্ক্রিনে যেতে উপরের দিকে সোয়াইপ করুন"</string>
- <string name="allset_description" msgid="6350320429953234580">"এবারে আপনি ফোন ব্যবহার করতে পারবেন"</string>
- <string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"সিস্টেম নেভিগেশন সেটিংস"</annotation></string>
- <string name="action_share" msgid="2648470652637092375">"শেয়ার করুন"</string>
- <string name="action_screenshot" msgid="8171125848358142917">"স্ক্রিনশট নিন"</string>
- <string name="action_split" msgid="2098009717623550676">"স্প্লিট"</string>
- <string name="toast_split_select_app" msgid="5453865907322018352">"স্প্লিটস্ক্রিন ব্যবহার করতে অন্য অ্যাপে ট্যাপ করুন"</string>
- <string name="toast_split_app_unsupported" msgid="3271526028981899666">"স্প্লিট-স্ক্রিনে এই অ্যাপ কাজ করে না।"</string>
- <string name="blocked_by_policy" msgid="2071401072261365546">"এই অ্যাপ বা আপনার প্রতিষ্ঠান এই অ্যাকশনটি পারফর্ম করার অনুমতি দেয়নি"</string>
- <string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"নেভিগেশন টিউটোরিয়াল এড়িয়ে যেতে চান?"</string>
- <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"আপনি <xliff:g id="NAME">%1$s</xliff:g> অ্যাপে পরে এটি খুঁজে পাবেন"</string>
- <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"বাতিল করুন"</string>
- <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"এড়িয়ে যান"</string>
- <string name="accessibility_rotate_button" msgid="4771825231336502943">"স্ক্রিন ঘোরান"</string>
- <string name="taskbar_edu_opened" msgid="3950252793551919129">"টাস্কবার এডুকেশন দেখানো হয়েছে"</string>
- <string name="taskbar_edu_closed" msgid="126643734478892862">"টাস্কবার এডুকেশন বন্ধ করা আছে"</string>
- <string name="taskbar_edu_switch_apps" msgid="6942863327845784813">"অ্যাপ পাল্টানোর জন্য টাস্কবার ব্যবহার করুন"</string>
- <string name="taskbar_edu_splitscreen" msgid="2663361731630346489">"একসাথে দুটি অ্যাপ ব্যবহার করতে পাশে টেনে আনুন"</string>
- <string name="taskbar_edu_stashing" msgid="5212374387411764031">"টাস্কবার লুকানোর জন্য টাচ করে ধরে থাকুন"</string>
- <string name="taskbar_edu_next" msgid="4007618274426775841">"পরবর্তী"</string>
- <string name="taskbar_edu_previous" msgid="459202320127201702">"ফিরুন"</string>
- <string name="taskbar_edu_close" msgid="887022990168191073">"বন্ধ করুন"</string>
- <string name="taskbar_edu_done" msgid="6880178093977704569">"হয়ে গেছে"</string>
- <string name="taskbar_button_home" msgid="2151398979630664652">"হোম"</string>
- <string name="taskbar_button_a11y" msgid="5241161324875094465">"অ্যাক্সেসিবিলিটি"</string>
- <string name="taskbar_button_back" msgid="8558862226461164514">"ফিরে যান"</string>
- <string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"IME সুইচার"</string>
- <string name="taskbar_button_recents" msgid="7273376136216613134">"সম্প্রতি"</string>
- <string name="taskbar_button_notifications" msgid="7471740351507357318">"বিজ্ঞপ্তি"</string>
- <string name="taskbar_button_quick_settings" msgid="227662894293189391">"দ্রুত সেটিংস"</string>
- <string name="move_drop_target_top_or_left" msgid="2988702185049595807">"উপরে/বাঁদিকে সরান"</string>
- <string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"নিচে/ডানদিকে সরান"</string>
</resources>
diff --git a/quickstep/res/values-bs/strings.xml b/quickstep/res/values-bs/strings.xml
index 2cf2ef4878..7968f7cc68 100644
--- a/quickstep/res/values-bs/strings.xml
+++ b/quickstep/res/values-bs/strings.xml
@@ -19,91 +19,19 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Način rada podijeljenog ekrana"</string>
<string name="recent_task_option_pin" msgid="7929860679018978258">"Zakači"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Slobodan oblik"</string>
+ <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Pregled"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"Nema nedavnih stavki"</string>
+ <string name="accessibility_close_task" msgid="5354563209433803643">"Zatvaranje"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Postavke korištenja aplikacije"</string>
<string name="recents_clear_all" msgid="5328176793634888831">"Obriši sve"</string>
<string name="accessibility_recent_apps" msgid="4058661986695117371">"Nedavne aplikacije"</string>
- <string name="task_view_closed" msgid="9170038230110856166">"Zadatak je zatvoren"</string>
<string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
<string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 min"</string>
<string name="time_left_for_app" msgid="3111996412933644358">"Preostalo vrijeme: <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <string name="title_app_suggestions" msgid="4185902664111965088">"Prijedlozi aplikacija"</string>
+ <string name="title_app_suggestions" msgid="4185902664111965088">"Prijedlozi za aplikacije"</string>
+ <string name="all_apps_label" msgid="8542784161730910663">"Sve aplikacije"</string>
<string name="all_apps_prediction_tip" msgid="2672336544844936186">"Predviđene aplikacije"</string>
- <string name="hotseat_edu_title_migrate" msgid="306578144424489980">"Primajte prijedloge aplikacija u donjem redu početnog ekrana"</string>
- <string name="hotseat_edu_title_migrate_landscape" msgid="3633942953997845243">"Primajte prijedloge aplikacija u redu omiljenih stavki početnog ekrana"</string>
- <string name="hotseat_edu_message_migrate" msgid="8927179260533775320">"Jednostavno pristupite najčešće korištenim aplikacijama direktno na početnom ekranu. Prijedlozi će se mijenjati na osnovu vaših rutina. Aplikacije koje se nalaze u donjem redu će se premjestiti na početni ekran."</string>
- <string name="hotseat_edu_message_migrate_landscape" msgid="4248943380443387697">"Jednostavno pristupite najčešće korištenim aplikacijama direktno na početnom ekranu. Prijedlozi će se mijenjati na osnovu vaših rutina. Aplikacije u redu omiljenih stavki će se premjestiti na početni ekran."</string>
- <string name="hotseat_edu_message_migrate_alt" msgid="3042360119039646356">"Jednostavno pristupite najčešće korištenim aplikacijama, direktno na početnom ekranu. Prijedlozi će se mijenjati na osnovu vaših rutina. Aplikacije koje se nalaze u donjem redu će se premjestiti u novi folder."</string>
- <string name="hotseat_edu_accept" msgid="1611544083278999837">"Prikaži prijedloge aplikacija"</string>
- <string name="hotseat_edu_dismiss" msgid="2781161822780201689">"Ne, hvala"</string>
- <string name="hotseat_prediction_settings" msgid="6246554993566070818">"Postavke"</string>
- <string name="hotseat_auto_enrolled" msgid="522100018967146807">"Ovdje se prikazuju najčešće korištene aplikacije i njihov prikaz se mijenja na osnovu rutina"</string>
- <string name="hotseat_tip_no_empty_slots" msgid="1325212677738179185">"Prevucite aplikacije iz donjeg reda da dobijete prijedloge aplikacija"</string>
- <string name="hotseat_tip_gaps_filled" msgid="3035673010274223538">"Prijedlozi aplikacija su dodani u prazan prostor"</string>
- <string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Prijedlozi aplikacija su omogućeni"</string>
- <string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Prijedlozi aplikacija su onemogućeni"</string>
- <string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Predviđena aplikacija: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Vodite računa da prevučete s krajnjeg desnog ili krajnjeg lijevog ruba."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Vodite računa da prevučete s desnog ili lijevog ruba prema sredini ekrana i pustite."</string>
- <string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Naučili ste kako prevući zdesna da se vratite. Sljedeće naučite kako prebacivati između aplikacija."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"Završili ste pokret za vraćanje."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Obratite pažnju da ne prevučete preblizu donjem dijelu ekrana."</string>
- <string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"Promijenite osjetljivost pokreta za povratak u Postavkama"</string>
- <string name="back_gesture_intro_title" msgid="19551256430224428">"Prevucite da se vratite"</string>
- <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"Da se vratite na posljednji ekran, prevucite s lijevog ili desnog ruba prema sredini ekrana."</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Trebate prevući prema gore s donjeg ruba ekrana."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Obratite pažnju da ne zastanete prije puštanja."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Trebate prevući ravno prema gore."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"Završili ste pokret za otvaranje početnog ekrana. Sljedeće naučite kako se vratiti."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"Završili ste pokret za otvaranje početnog ekrana."</string>
- <string name="home_gesture_intro_title" msgid="836590312858441830">"Prevucite da odete na početni ekran"</string>
- <string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Prevucite s dna ekrana prema gore. Tim pokretom uvijek idete na početni ekran."</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Trebate prevući prema gore s donjeg ruba ekrana."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Pokušajte zadržati prozor duže prije puštanja."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Trebate prevući ravno prema gore, a zatim zastati."</string>
- <string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Naučili ste kako koristiti pokrete. Idite u Postavke da isključite pokrete."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"Završili ste pokret za prebacivanje između aplikacija."</string>
- <string name="overview_gesture_intro_title" msgid="2902054412868489378">"Prevucite da prebacujete između aplikacija"</string>
- <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Da prebacujete između aplikacija, prevucite s dna ekrana prema gore, zadržite, a zatim pustite."</string>
- <string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"Sve je spremno"</string>
- <string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Gotovo"</string>
- <string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Postavke"</string>
- <string name="gesture_tutorial_try_again" msgid="65962545858556697">"Pokušajte ponovo"</string>
- <string name="gesture_tutorial_nice" msgid="2936275692616928280">"Odlično!"</string>
- <string name="gesture_tutorial_step" msgid="1279786122817620968">"Vodič <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
- <string name="allset_title" msgid="5021126669778966707">"Sve je spremno!"</string>
- <string name="allset_hint" msgid="2384632994739392447">"Prevucite prema gore da odete na početnu stranicu"</string>
- <string name="allset_description" msgid="6350320429953234580">"Sve je spremno da počnete koristiti telefon"</string>
- <string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"Postavke navigiranja sistemom"</annotation></string>
- <string name="action_share" msgid="2648470652637092375">"Dijeli"</string>
- <string name="action_screenshot" msgid="8171125848358142917">"Snimak ekrana"</string>
- <string name="action_split" msgid="2098009717623550676">"Podijeli"</string>
- <string name="toast_split_select_app" msgid="5453865907322018352">"Dodirnite drugu apl. da koristite podijeljeni ekran"</string>
- <string name="toast_split_app_unsupported" msgid="3271526028981899666">"Aplikacija ne podržava podijeljeni ekran."</string>
- <string name="blocked_by_policy" msgid="2071401072261365546">"Ovu radnju ne dozvoljava aplikacija ili vaša organizacija"</string>
- <string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Preskočiti vodič za navigiranje?"</string>
- <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"To možete pronaći kasnije u aplikaciji <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Otkaži"</string>
- <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Preskoči"</string>
- <string name="accessibility_rotate_button" msgid="4771825231336502943">"Rotiranje ekrana"</string>
- <string name="taskbar_edu_opened" msgid="3950252793551919129">"Edukacija o programskoj traci je prikazana"</string>
- <string name="taskbar_edu_closed" msgid="126643734478892862">"Edukacija o programskoj traci je zatvorena"</string>
- <string name="taskbar_edu_switch_apps" msgid="6942863327845784813">"Koristite programsku traku da promijenite aplikacije"</string>
- <string name="taskbar_edu_splitscreen" msgid="2663361731630346489">"Prevucite u stranu da istovremeno koristite dvije aplikacije"</string>
- <string name="taskbar_edu_stashing" msgid="5212374387411764031">"Dodirnite i držite da sakrijete programsku traku"</string>
- <string name="taskbar_edu_next" msgid="4007618274426775841">"Naprijed"</string>
- <string name="taskbar_edu_previous" msgid="459202320127201702">"Nazad"</string>
- <string name="taskbar_edu_close" msgid="887022990168191073">"Zatvori"</string>
- <string name="taskbar_edu_done" msgid="6880178093977704569">"Gotovo"</string>
- <string name="taskbar_button_home" msgid="2151398979630664652">"Dom"</string>
- <string name="taskbar_button_a11y" msgid="5241161324875094465">"Pristupačnost"</string>
- <string name="taskbar_button_back" msgid="8558862226461164514">"Nazad"</string>
- <string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"IME prebacivač"</string>
- <string name="taskbar_button_recents" msgid="7273376136216613134">"Nedavno"</string>
- <string name="taskbar_button_notifications" msgid="7471740351507357318">"Obavještenja"</string>
- <string name="taskbar_button_quick_settings" msgid="227662894293189391">"Brze postavke"</string>
- <string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Premjesti gore lijevo"</string>
- <string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Premjesti dolje desno"</string>
</resources>
diff --git a/quickstep/res/values-ca/strings.xml b/quickstep/res/values-ca/strings.xml
index 0f6c4862dd..6420aa8cb8 100644
--- a/quickstep/res/values-ca/strings.xml
+++ b/quickstep/res/values-ca/strings.xml
@@ -19,93 +19,19 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Pantalla dividida"</string>
<string name="recent_task_option_pin" msgid="7929860679018978258">"Fixa"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Format lliure"</string>
+ <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Aplicacions recents"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"No hi ha cap element recent"</string>
+ <string name="accessibility_close_task" msgid="5354563209433803643">"Tanca"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Configuració d\'ús d\'aplicacions"</string>
<string name="recents_clear_all" msgid="5328176793634888831">"Esborra-ho tot"</string>
<string name="accessibility_recent_apps" msgid="4058661986695117371">"Aplicacions recents"</string>
- <string name="task_view_closed" msgid="9170038230110856166">"Tasca tancada"</string>
<string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>; <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
<string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 minut"</string>
<string name="time_left_for_app" msgid="3111996412933644358">"temps restant avui: <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="title_app_suggestions" msgid="4185902664111965088">"Suggeriments d\'aplicacions"</string>
+ <string name="all_apps_label" msgid="8542784161730910663">"Totes les aplicacions"</string>
<string name="all_apps_prediction_tip" msgid="2672336544844936186">"Prediccions d\'aplicacions"</string>
- <string name="hotseat_edu_title_migrate" msgid="306578144424489980">"Obtén suggeriments d\'aplicacions a la fila inferior de la pantalla d\'inici"</string>
- <string name="hotseat_edu_title_migrate_landscape" msgid="3633942953997845243">"Obtén suggeriments d\'aplicacions a la fila Preferides de la teva pantalla d\'inici"</string>
- <string name="hotseat_edu_message_migrate" msgid="8927179260533775320">"Accedeix fàcilment a les aplicacions que més utilitzes des de la pantalla d\'inici. Els suggeriments variaran en funció dels teus hàbits. Les aplicacions de la fila inferior pujaran a la pantalla d\'inici."</string>
- <string name="hotseat_edu_message_migrate_landscape" msgid="4248943380443387697">"Accedeix fàcilment a les aplicacions que més utilitzes des de la pantalla d\'inici. Els suggeriments variaran en funció dels teus hàbits. Les aplicacions de la fila Preferides es mouran a la teva pantalla d\'inici."</string>
- <string name="hotseat_edu_message_migrate_alt" msgid="3042360119039646356">"Accedeix fàcilment a les aplicacions que més utilitzes des de la pantalla d\'inici. Els suggeriments variaran en funció dels teus hàbits. Les aplicacions de la fila inferior es mouran a una carpeta nova."</string>
- <string name="hotseat_edu_accept" msgid="1611544083278999837">"Mostra suggeriments d\'aplicacions"</string>
- <string name="hotseat_edu_dismiss" msgid="2781161822780201689">"No, gràcies"</string>
- <string name="hotseat_prediction_settings" msgid="6246554993566070818">"Configuració"</string>
- <string name="hotseat_auto_enrolled" msgid="522100018967146807">"Les aplicacions que més utilitzes apareixen aquí i poden variar en funció dels teus hàbits"</string>
- <string name="hotseat_tip_no_empty_slots" msgid="1325212677738179185">"Arrossega les aplicacions fora de la fila inferior per obtenir suggeriments d\'aplicacions"</string>
- <string name="hotseat_tip_gaps_filled" msgid="3035673010274223538">"S\'han afegit suggeriments d\'aplicacions en un espai buit"</string>
- <string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Els suggeriments d\'aplicacions estan activats"</string>
- <string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Els suggeriments d\'aplicacions estan desactivats"</string>
- <string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Predicció d\'aplicació: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Assegura\'t de lliscar des de l\'extrem dret o esquerre de la pantalla."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Assegura\'t de lliscar des de la vora dreta o esquerra cap al centre de la pantalla i deixar anar."</string>
- <string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Has après com pots lliscar des de la dreta per tornar enrere. Ara, descobreix com pots canviar d\'app."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"Has completat el gest per tornar enrere."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Assegura\'t de no lliscar massa a prop de la part inferior de la pantalla."</string>
- <string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"Per canviar la sensibilitat del gest, ves a Configuració"</string>
- <string name="back_gesture_intro_title" msgid="19551256430224428">"Llisca per anar enrere"</string>
- <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"Per tornar a la darrera pantalla, llisca des de la vora esquerra o dreta cap al centre de la pantalla."</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Assegura\'t de lliscar des de la vora inferior de la pantalla."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Assegura\'t de no aturar-te abans de deixar anar."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Assegura\'t de lliscar directament cap amunt."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"Has completat el gest per anar a la pantalla d\'inici. Ara, descobreix com pots tornar enrere."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"Has completat el gest per anar a la pantalla d\'inici."</string>
- <string name="home_gesture_intro_title" msgid="836590312858441830">"Llisca per anar a la pantalla d\'inici"</string>
- <string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Llisca cap amunt des de la part inferior de la pantalla. Aquest gest et porta a la pantalla d\'inici."</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Assegura\'t de lliscar des de la vora inferior de la pantalla."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Prova de mantenir premuda la finestra durant més temps abans de deixar-la anar."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Assegura\'t de lliscar directament cap amunt i després aturar-te."</string>
- <string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Has après a utilitzar els gestos. Per desactivar-los, ves a Configuració."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"Has completat el gest per canviar d\'aplicació."</string>
- <string name="overview_gesture_intro_title" msgid="2902054412868489378">"Llisca per canviar d\'aplicació"</string>
- <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Per canviar entre aplicacions, llisca cap amunt des de la part inferior, mantén premut i deixa anar."</string>
- <string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"Tot a punt"</string>
- <string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Fet"</string>
- <string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Configuració"</string>
- <string name="gesture_tutorial_try_again" msgid="65962545858556697">"Torna-ho a provar"</string>
- <string name="gesture_tutorial_nice" msgid="2936275692616928280">"Molt bé!"</string>
- <string name="gesture_tutorial_step" msgid="1279786122817620968">"Tutorial <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
- <string name="allset_title" msgid="5021126669778966707">"Tot a punt!"</string>
- <string name="allset_hint" msgid="2384632994739392447">"Llisca cap amunt per anar a la pàgina d\'inici"</string>
- <string name="allset_description" msgid="6350320429953234580">"Ja pots començar a utilitzar el telèfon"</string>
- <string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"Configuració de navegació del sistema"</annotation></string>
- <string name="action_share" msgid="2648470652637092375">"Comparteix"</string>
- <string name="action_screenshot" msgid="8171125848358142917">"Captura de pantalla"</string>
- <string name="action_split" msgid="2098009717623550676">"Divideix"</string>
- <string name="toast_split_select_app" msgid="5453865907322018352">"Toca una altra aplicació per dividir la pantalla"</string>
- <string name="toast_split_app_unsupported" msgid="3271526028981899666">"L\'aplicació no admet la pantalla dividida."</string>
- <string name="blocked_by_policy" msgid="2071401072261365546">"L\'aplicació o la teva organització no permeten aquesta acció"</string>
- <string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Vols ometre el tutorial de navegació?"</string>
- <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Pots trobar-lo més tard a l\'aplicació <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Cancel·la"</string>
- <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Omet"</string>
- <string name="accessibility_rotate_button" msgid="4771825231336502943">"Gira la pantalla"</string>
- <string name="taskbar_edu_opened" msgid="3950252793551919129">"Ha aparegut el tauler educatiu de la barra de tasques"</string>
- <string name="taskbar_edu_closed" msgid="126643734478892862">"S\'ha tancat el tauler educatiu de la barra de tasques"</string>
- <string name="taskbar_edu_switch_apps" msgid="6942863327845784813">"Utilitza la barra de tasques per canviar d\'aplicació"</string>
- <string name="taskbar_edu_splitscreen" msgid="2663361731630346489">"Arrossega al costat per utilitzar dues aplicacions alhora"</string>
- <string name="taskbar_edu_stashing" msgid="5212374387411764031">"Mantén premut per amagar la barra de tasques"</string>
- <string name="taskbar_edu_next" msgid="4007618274426775841">"Següent"</string>
- <string name="taskbar_edu_previous" msgid="459202320127201702">"Enrere"</string>
- <string name="taskbar_edu_close" msgid="887022990168191073">"Tanca"</string>
- <string name="taskbar_edu_done" msgid="6880178093977704569">"Fet"</string>
- <string name="taskbar_button_home" msgid="2151398979630664652">"Inici"</string>
- <string name="taskbar_button_a11y" msgid="5241161324875094465">"Accessibilitat"</string>
- <string name="taskbar_button_back" msgid="8558862226461164514">"Enrere"</string>
- <string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"Selector d\'IME"</string>
- <string name="taskbar_button_recents" msgid="7273376136216613134">"Recents"</string>
- <!-- no translation found for taskbar_button_notifications (7471740351507357318) -->
- <skip />
- <!-- no translation found for taskbar_button_quick_settings (227662894293189391) -->
- <skip />
- <string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Mou a la part superior o a l\'esquerra"</string>
- <string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Mou a la part inferior o a la dreta"</string>
</resources>
diff --git a/quickstep/res/values-cs/strings.xml b/quickstep/res/values-cs/strings.xml
index 6aef1a48e5..194ff87dc5 100644
--- a/quickstep/res/values-cs/strings.xml
+++ b/quickstep/res/values-cs/strings.xml
@@ -19,93 +19,19 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="recent_task_option_pin" msgid="7929860679018978258">"Připnout"</string>
+ <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Rozdělená obrazovka"</string>
+ <string name="recent_task_option_pin" msgid="7929860679018978258">"PIN"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Neomezený režim"</string>
+ <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Přehled"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"Žádné nedávné položky"</string>
+ <string name="accessibility_close_task" msgid="5354563209433803643">"Zavřít"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Nastavení využití aplikací"</string>
<string name="recents_clear_all" msgid="5328176793634888831">"Vymazat vše"</string>
<string name="accessibility_recent_apps" msgid="4058661986695117371">"Poslední aplikace"</string>
- <string name="task_view_closed" msgid="9170038230110856166">"Úkol byl zavřen"</string>
<string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
<string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 minuta"</string>
<string name="time_left_for_app" msgid="3111996412933644358">"dnes zbývá: <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="title_app_suggestions" msgid="4185902664111965088">"Návrhy aplikací"</string>
- <string name="all_apps_prediction_tip" msgid="2672336544844936186">"Návrhy aplikací pro vás"</string>
- <string name="hotseat_edu_title_migrate" msgid="306578144424489980">"Nechte si ve spodním řádku na ploše zobrazovat návrhy aplikací"</string>
- <string name="hotseat_edu_title_migrate_landscape" msgid="3633942953997845243">"Nechte si na řádku oblíbených na ploše zobrazovat návrhy aplikací"</string>
- <string name="hotseat_edu_message_migrate" msgid="8927179260533775320">"Mějte nejpoužívanější aplikace k dispozici přímo na ploše. Návrhy se budou měnit podle vašich zvyklostí. Aplikace ve spodním řádku se přesunou nahoru na vaši plochu."</string>
- <string name="hotseat_edu_message_migrate_landscape" msgid="4248943380443387697">"Mějte nejpoužívanější aplikace k dispozici přímo na ploše. Návrhy se budou měnit podle vašich zvyklostí. Aplikace na řádku oblíbených se přesunou na plochu."</string>
- <string name="hotseat_edu_message_migrate_alt" msgid="3042360119039646356">"Mějte nejpoužívanější aplikace k dispozici přímo na ploše. Návrhy se budou měnit podle vašich zvyklostí. Aplikace ve spodním řádku se přesunou do nové složky."</string>
- <string name="hotseat_edu_accept" msgid="1611544083278999837">"Zobrazovat návrhy aplikací"</string>
- <string name="hotseat_edu_dismiss" msgid="2781161822780201689">"Ne, díky"</string>
- <string name="hotseat_prediction_settings" msgid="6246554993566070818">"Nastavení"</string>
- <string name="hotseat_auto_enrolled" msgid="522100018967146807">"Zde se zobrazují nejpoužívanější aplikace (které se mění podle sledů činností)"</string>
- <string name="hotseat_tip_no_empty_slots" msgid="1325212677738179185">"Návrhy aplikací získáte přetažením aplikací z dolního řádku"</string>
- <string name="hotseat_tip_gaps_filled" msgid="3035673010274223538">"Volné místo bylo vyplněno návrhy aplikací"</string>
- <string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Návrhy aplikací jsou povoleny"</string>
- <string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Návrhy aplikací jsou zakázány"</string>
- <string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Předpokládaná aplikace: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Přejeďte prstem z úplného pravého nebo levého okraje obrazovky."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Přejeďte prstem z pravého nebo levého okraje doprostřed obrazovky a zdvihněte prst."</string>
- <string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Naučili jste se, jak se vrátit zpět přejetím prstem zprava. Teď se naučíte přepínat aplikace."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"Dokončili jste gesto pro přechod zpět."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Dejte pozor, abyste prstem nepřejížděli moc blízko ke spodnímu okraji obrazovky."</string>
- <string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"Citlivost gesta pro přechod zpět můžete změnit v Nastavení"</string>
- <string name="back_gesture_intro_title" msgid="19551256430224428">"Přejetím prstem se vrátíte zpět"</string>
- <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"K návratu na poslední obrazovku přejeďte prstem z levého nebo pravého okraje obrazovky doprostřed."</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Přejeďte prstem nahoru z dolního okraje obrazovky."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Před zdvihnutím prstu nedělejte pauzu."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Přejeďte prstem přímo nahoru."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"Dokončili jste gesto pro přechod na plochu. Teď se naučíte vrátit se zpět."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"Dokončili jste gesto pro přechod na plochu."</string>
- <string name="home_gesture_intro_title" msgid="836590312858441830">"Přechod na plochu přejetím prstem"</string>
- <string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Přejeďte prstem ze spodní části obrazovky nahoru. Tímto gestem se vždy dostanete na plochu."</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Přejeďte prstem nahoru z dolního okraje obrazovky."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Zkuste podržet okno delší dobu, než ho uvolníte."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Přejeďte prstem přímo nahoru a pak udělejte pauzu."</string>
- <string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Naučili jste se používat gesta. Gesta můžete vypnout v nastavení."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"Dokončili jste gesto pro přepínání aplikací."</string>
- <string name="overview_gesture_intro_title" msgid="2902054412868489378">"Přepínání aplikací přejetím prstem"</string>
- <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Přepínání mezi aplikacemi: Přejeďte nahoru z dolního okraje obrazovky, podržte obrazovku a uvolněte."</string>
- <string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"Vše je nastaveno"</string>
- <string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Hotovo"</string>
- <string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Nastavení"</string>
- <string name="gesture_tutorial_try_again" msgid="65962545858556697">"Zkusit znovu"</string>
- <string name="gesture_tutorial_nice" msgid="2936275692616928280">"Skvělé!"</string>
- <string name="gesture_tutorial_step" msgid="1279786122817620968">"Výukový program <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
- <string name="allset_title" msgid="5021126669778966707">"Hotovo!"</string>
- <string name="allset_hint" msgid="2384632994739392447">"Přejetím nahoru se vrátíte na plochu"</string>
- <string name="allset_description" msgid="6350320429953234580">"Jste připraveni začít používat telefon"</string>
- <string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"Nastavení navigace v systému"</annotation></string>
- <string name="action_share" msgid="2648470652637092375">"Sdílet"</string>
- <string name="action_screenshot" msgid="8171125848358142917">"Snímek obrazovky"</string>
- <string name="action_split" msgid="2098009717623550676">"Rozdělit"</string>
- <string name="toast_split_select_app" msgid="5453865907322018352">"Klepnutím na jinou aplikaci rozdělíte obrazovku"</string>
- <string name="toast_split_app_unsupported" msgid="3271526028981899666">"Aplikace nepodporuje režim rozdělené obrazovky."</string>
- <string name="blocked_by_policy" msgid="2071401072261365546">"Aplikace nebo organizace zakazuje tuto akci"</string>
- <string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Přeskočit výukový program k navigaci?"</string>
- <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Program později najdete v aplikaci <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Zrušit"</string>
- <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Přeskočit"</string>
- <string name="accessibility_rotate_button" msgid="4771825231336502943">"Otočit obrazovku"</string>
- <string name="taskbar_edu_opened" msgid="3950252793551919129">"Zobrazila se výuka k hlavnímu panelu"</string>
- <string name="taskbar_edu_closed" msgid="126643734478892862">"Výuka k hlavnímu panelu byla zavřena"</string>
- <string name="taskbar_edu_switch_apps" msgid="6942863327845784813">"Aplikace lze přepínat pomocí hlavního panelu"</string>
- <string name="taskbar_edu_splitscreen" msgid="2663361731630346489">"Po přetažení na stranu lze používat dvě aplikace současně"</string>
- <string name="taskbar_edu_stashing" msgid="5212374387411764031">"Hlavní panel můžete skrýt podržením"</string>
- <string name="taskbar_edu_next" msgid="4007618274426775841">"Další"</string>
- <string name="taskbar_edu_previous" msgid="459202320127201702">"Zpět"</string>
- <string name="taskbar_edu_close" msgid="887022990168191073">"Zavřít"</string>
- <string name="taskbar_edu_done" msgid="6880178093977704569">"Hotovo"</string>
- <string name="taskbar_button_home" msgid="2151398979630664652">"Domů"</string>
- <string name="taskbar_button_a11y" msgid="5241161324875094465">"Přístupnost"</string>
- <string name="taskbar_button_back" msgid="8558862226461164514">"Zpět"</string>
- <string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"Přepínač IME"</string>
- <string name="taskbar_button_recents" msgid="7273376136216613134">"Poslední"</string>
- <!-- no translation found for taskbar_button_notifications (7471740351507357318) -->
- <skip />
- <!-- no translation found for taskbar_button_quick_settings (227662894293189391) -->
- <skip />
- <string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Přesunout doleva nahoru"</string>
- <string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Přesunout doprava dolů"</string>
+ <string name="all_apps_label" msgid="8542784161730910663">"Všechny aplikace"</string>
+ <string name="all_apps_prediction_tip" msgid="2672336544844936186">"Vaše předpovídané aplikace"</string>
</resources>
diff --git a/quickstep/res/values-da/strings.xml b/quickstep/res/values-da/strings.xml
index c2e66812cb..b43a76eb94 100644
--- a/quickstep/res/values-da/strings.xml
+++ b/quickstep/res/values-da/strings.xml
@@ -19,93 +19,19 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Opdel skærm"</string>
<string name="recent_task_option_pin" msgid="7929860679018978258">"Fastgør"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Frit format"</string>
+ <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Oversigt"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"Ingen nye elementer"</string>
+ <string name="accessibility_close_task" msgid="5354563209433803643">"Luk"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Indstillinger for appforbrug"</string>
<string name="recents_clear_all" msgid="5328176793634888831">"Ryd alt"</string>
<string name="accessibility_recent_apps" msgid="4058661986695117371">"Seneste apps"</string>
- <string name="task_view_closed" msgid="9170038230110856166">"Opgaven er lukket"</string>
<string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
<string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 min"</string>
<string name="time_left_for_app" msgid="3111996412933644358">"<xliff:g id="TIME">%1$s</xliff:g> tilbage i dag"</string>
<string name="title_app_suggestions" msgid="4185902664111965088">"Appforslag"</string>
+ <string name="all_apps_label" msgid="8542784161730910663">"Alle apps"</string>
<string name="all_apps_prediction_tip" msgid="2672336544844936186">"Dine foreslåede apps"</string>
- <string name="hotseat_edu_title_migrate" msgid="306578144424489980">"Få appforslag på den nederste række af din startskærm"</string>
- <string name="hotseat_edu_title_migrate_landscape" msgid="3633942953997845243">"Få appforslag i rækken med favoritter på din startskærm"</string>
- <string name="hotseat_edu_message_migrate" msgid="8927179260533775320">"Få nem adgang til dine mest brugte apps direkte fra startskærmen. Forslagene ændres ud fra dine vaner. Apps i nederste række bliver flyttet op til din startskærm."</string>
- <string name="hotseat_edu_message_migrate_landscape" msgid="4248943380443387697">"Få nem adgang til dine mest brugte apps direkte fra startskærmen. Forslagene ændres ud fra dine vaner. Apps i rækken med favoritter bliver flyttet til din startskærm."</string>
- <string name="hotseat_edu_message_migrate_alt" msgid="3042360119039646356">"Få nem adgang til dine mest brugte apps direkte fra startskærmen. Forslagene ændres ud fra dine vaner. Apps i nederste række bliver flyttet til en ny mappe."</string>
- <string name="hotseat_edu_accept" msgid="1611544083278999837">"Få appforslag"</string>
- <string name="hotseat_edu_dismiss" msgid="2781161822780201689">"Nej tak"</string>
- <string name="hotseat_prediction_settings" msgid="6246554993566070818">"Indstillinger"</string>
- <string name="hotseat_auto_enrolled" msgid="522100018967146807">"De mest brugte apps vises her, og visningen ændres ud fra dine vaner"</string>
- <string name="hotseat_tip_no_empty_slots" msgid="1325212677738179185">"Træk apps væk fra den nederste række for at få appforslag"</string>
- <string name="hotseat_tip_gaps_filled" msgid="3035673010274223538">"Appforslag blev føjet til tom plads"</string>
- <string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Appforslag er aktiveret"</string>
- <string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Appforslag er deaktiveret"</string>
- <string name="hotseat_prediction_content_description" msgid="4582028296938078419">"App, du forventes at skulle bruge: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Stryg fra kanten yderst til højre eller venstre."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Stryg fra højre eller venstre kant mod midten af skærmen, og løft fingeren."</string>
- <string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Du har lært, hvordan du stryger fra højre for at gå tilbage. Nu skal du se, hvordan du skifter app."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"Du har fuldført bevægelsen for Gå tilbage."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Undgå at stryge for tæt på bunden af skærmen."</string>
- <string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"Juster følsomheden for bevægelsen Gå tilbage i Indstillinger"</string>
- <string name="back_gesture_intro_title" msgid="19551256430224428">"Stryg for at gå tilbage"</string>
- <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"Stryg mod midten af skærmen fra venstre eller højre kant for at gå tilbage til den seneste skærm."</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Stryg opad fra bunden af skærmen."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Undlad at holde fingeren stille, indtil du løfter fingeren."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Stryg lige opad."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"Du har fuldført bevægelsen for Gå til startskærmen. Som det næste kan du se, hvordan du går tilbage."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"Du har fuldført bevægelsen for Gå til startskærmen."</string>
- <string name="home_gesture_intro_title" msgid="836590312858441830">"Stryg for at gå til startskærmen"</string>
- <string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Stryg opad fra bunden af skærmen. Denne bevægelse åbner altid startskærmen."</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Stryg opad fra bunden af skærmen."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Prøv at holde fingeren nede på vinduet i længere tid, inden du løfter den."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Stryg lige opad, og hold derefter fingeren stille."</string>
- <string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Du har lært, hvordan du bruger bevægelser. Du kan aktivere bevægelser i Indstillinger."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"Du har fuldført bevægelsen for Skift app."</string>
- <string name="overview_gesture_intro_title" msgid="2902054412868489378">"Stryg for at skifte app"</string>
- <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Skift mellem apps ved at stryge opad fra bunden af skærmen, holde fingeren stille og løfte den."</string>
- <string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"Så er du klar"</string>
- <string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Luk"</string>
- <string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Indstillinger"</string>
- <string name="gesture_tutorial_try_again" msgid="65962545858556697">"Prøv igen"</string>
- <string name="gesture_tutorial_nice" msgid="2936275692616928280">"Sådan!"</string>
- <string name="gesture_tutorial_step" msgid="1279786122817620968">"Selvstudie <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
- <string name="allset_title" msgid="5021126669778966707">"Alt er parat!"</string>
- <string name="allset_hint" msgid="2384632994739392447">"Stryg opad for at gå til startsiden"</string>
- <string name="allset_description" msgid="6350320429953234580">"Du er klar til at bruge din telefon"</string>
- <string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"Indstillinger for systemnavigation"</annotation></string>
- <string name="action_share" msgid="2648470652637092375">"Del"</string>
- <string name="action_screenshot" msgid="8171125848358142917">"Screenshot"</string>
- <string name="action_split" msgid="2098009717623550676">"Opdel"</string>
- <string name="toast_split_select_app" msgid="5453865907322018352">"Tryk på en anden app for at bruge opdelt skærm"</string>
- <string name="toast_split_app_unsupported" msgid="3271526028981899666">"Appen understøtter ikke opdelt skærm."</string>
- <string name="blocked_by_policy" msgid="2071401072261365546">"Appen eller din organisation tillader ikke denne handling"</string>
- <string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Vil du springe selvstudiet for navigation over?"</string>
- <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Du kan finde dette senere i appen <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Annuller"</string>
- <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Spring over"</string>
- <string name="accessibility_rotate_button" msgid="4771825231336502943">"Roter skærm"</string>
- <string name="taskbar_edu_opened" msgid="3950252793551919129">"Vejledningen om proceslinjen blev åbnet"</string>
- <string name="taskbar_edu_closed" msgid="126643734478892862">"Vejledningen om proceslinjen blev lukket"</string>
- <string name="taskbar_edu_switch_apps" msgid="6942863327845784813">"Skift mellem apps ved hjælp af proceslinjen"</string>
- <string name="taskbar_edu_splitscreen" msgid="2663361731630346489">"Træk til siden for at bruge to apps samtidig"</string>
- <string name="taskbar_edu_stashing" msgid="5212374387411764031">"Du kan skjule proceslinjen ved at holde fingeren nede"</string>
- <string name="taskbar_edu_next" msgid="4007618274426775841">"Næste"</string>
- <string name="taskbar_edu_previous" msgid="459202320127201702">"Tilbage"</string>
- <string name="taskbar_edu_close" msgid="887022990168191073">"Luk"</string>
- <string name="taskbar_edu_done" msgid="6880178093977704569">"Luk"</string>
- <string name="taskbar_button_home" msgid="2151398979630664652">"Hjem"</string>
- <string name="taskbar_button_a11y" msgid="5241161324875094465">"Hjælpefunktioner"</string>
- <string name="taskbar_button_back" msgid="8558862226461164514">"Tilbage"</string>
- <string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"IME-vælger"</string>
- <string name="taskbar_button_recents" msgid="7273376136216613134">"Seneste"</string>
- <!-- no translation found for taskbar_button_notifications (7471740351507357318) -->
- <skip />
- <!-- no translation found for taskbar_button_quick_settings (227662894293189391) -->
- <skip />
- <string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Flyt til toppen eller venstre side"</string>
- <string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Flyt til bunden eller højre side"</string>
</resources>
diff --git a/quickstep/res/values-de/strings.xml b/quickstep/res/values-de/strings.xml
index 8d5aa7a07d..449cc8c11d 100644
--- a/quickstep/res/values-de/strings.xml
+++ b/quickstep/res/values-de/strings.xml
@@ -19,91 +19,19 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="recent_task_option_pin" msgid="7929860679018978258">"Fixieren"</string>
+ <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Splitscreen"</string>
+ <string name="recent_task_option_pin" msgid="7929860679018978258">"Anpinnen"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Freeform-Modus"</string>
+ <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Übersicht"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"Keine kürzlich verwendeten Elemente"</string>
+ <string name="accessibility_close_task" msgid="5354563209433803643">"Schließen"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Einstellungen zur App-Nutzung"</string>
<string name="recents_clear_all" msgid="5328176793634888831">"Alle Apps schließen"</string>
- <string name="accessibility_recent_apps" msgid="4058661986695117371">"Kürzlich geöffnete Apps"</string>
- <string name="task_view_closed" msgid="9170038230110856166">"Aufgabe geschlossen"</string>
+ <string name="accessibility_recent_apps" msgid="4058661986695117371">"Zuletzt aktive Apps"</string>
<string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
- <string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 Min."</string>
+ <string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 min"</string>
<string name="time_left_for_app" msgid="3111996412933644358">"Heute noch <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="title_app_suggestions" msgid="4185902664111965088">"App-Vorschläge"</string>
+ <string name="all_apps_label" msgid="8542784161730910663">"Alle Apps"</string>
<string name="all_apps_prediction_tip" msgid="2672336544844936186">"App-Vorschläge für dich"</string>
- <string name="hotseat_edu_title_migrate" msgid="306578144424489980">"Lass dir in der unteren Reihe auf deinem Startbildschirm Vorschläge für Apps anzeigen"</string>
- <string name="hotseat_edu_title_migrate_landscape" msgid="3633942953997845243">"Lass dir in der Favoritenleiste auf dem Startbildschirm App-Vorschläge anzeigen"</string>
- <string name="hotseat_edu_message_migrate" msgid="8927179260533775320">"Schneller Zugriff auf deine meistverwendeten Apps direkt über den Startbildschirm. Die Vorschläge werden deiner Nutzung entsprechend laufend angepasst. Apps in der unteren Reihe werden nach oben auf den Startbildschirm verschoben."</string>
- <string name="hotseat_edu_message_migrate_landscape" msgid="4248943380443387697">"Schneller Zugriff auf deine meistverwendeten Apps direkt über den Startbildschirm. Die Vorschläge werden deiner Nutzung entsprechend laufend angepasst. Apps der Favoritenleiste werden auf den Startbildschirm verschoben."</string>
- <string name="hotseat_edu_message_migrate_alt" msgid="3042360119039646356">"Schneller Zugriff auf deine meistverwendeten Apps direkt über den Startbildschirm. Die Vorschläge werden deiner Nutzung entsprechend laufend angepasst. Apps in der unteren Reihe werden in einen neuen Ordner verschoben."</string>
- <string name="hotseat_edu_accept" msgid="1611544083278999837">"App-Vorschläge erhalten"</string>
- <string name="hotseat_edu_dismiss" msgid="2781161822780201689">"Nein danke"</string>
- <string name="hotseat_prediction_settings" msgid="6246554993566070818">"Einstellungen"</string>
- <string name="hotseat_auto_enrolled" msgid="522100018967146807">"Hier erscheinen die meistverwendeten Apps. Die Angaben können sich je nach deiner gewöhnlichen Nutzung ändern"</string>
- <string name="hotseat_tip_no_empty_slots" msgid="1325212677738179185">"Ziehe Apps aus der unteren Reihe heraus, um Vorschläge für Apps zu erhalten"</string>
- <string name="hotseat_tip_gaps_filled" msgid="3035673010274223538">"App-Vorschläge in freiem Bereich hinzugefügt"</string>
- <string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Funktion „App-Vorschläge“ aktiviert"</string>
- <string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Funktion \"App-Vorschläge\" deaktiviert"</string>
- <string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Vorgeschlagene App: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Wische vom äußersten rechten oder linken Displayrand."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Wische vom rechten oder linken Displayrand zur Displaymitte und lass los."</string>
- <string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Du kannst jetzt vom rechten Displayrand aus wischen, um zurückzugehen. Gleich erfährst du, wie man zwischen Apps wechselt."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"Du hast die „Zurück“-Touch-Geste abgeschlossen."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Wische nicht zu nah am unteren Displayrand."</string>
- <string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"Du kannst die Empfindlichkeit von „Zurück“ in den Einstellungen ändern"</string>
- <string name="back_gesture_intro_title" msgid="19551256430224428">"Zum Zurückgehen wischen"</string>
- <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"Wenn du zum letzten Bildschirm zurückgehen möchtest, wische vom linken oder rechten Rand zur Mitte."</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Wische vom unteren Displayrand nach oben."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Achte darauf, nicht innezuhalten, bevor du loslässt."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Wische gerade nach oben."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"Du hast die „Startbildschirm“-Touch-Geste abgeschlossen. Gleich erfährst du, wie du zurückgelangst."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"Du hast die „Startbildschirm“-Touch-Geste abgeschlossen."</string>
- <string name="home_gesture_intro_title" msgid="836590312858441830">"Zum Startbildschirm gehen"</string>
- <string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Wenn du zum Startbildschirm gehen möchtest, wische einfach vom unteren Displayrand nach oben."</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Wische vom unteren Displayrand nach oben."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Versuche, das Fenster länger festzuhalten, bevor du es loslässt."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Wische gerade nach oben und halte dann inne."</string>
- <string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Nun weißt du, wie Touch-Gesten funktionieren. Du kannst sie in den Einstellungen deaktivieren."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"Du hast die „Apps wechseln“-Touch-Geste abgeschlossen."</string>
- <string name="overview_gesture_intro_title" msgid="2902054412868489378">"Zwischen Apps wechseln"</string>
- <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Wische auf dem Display von unten nach oben und lass dann los, um zwischen Apps zu wechseln."</string>
- <string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"Fertig"</string>
- <string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Fertig"</string>
- <string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Einstellungen"</string>
- <string name="gesture_tutorial_try_again" msgid="65962545858556697">"Wiederholen"</string>
- <string name="gesture_tutorial_nice" msgid="2936275692616928280">"Sehr gut!"</string>
- <string name="gesture_tutorial_step" msgid="1279786122817620968">"Anleitung <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
- <string name="allset_title" msgid="5021126669778966707">"Fertig!"</string>
- <string name="allset_hint" msgid="2384632994739392447">"Nach oben wischen, um den Startbildschirm aufzurufen"</string>
- <string name="allset_description" msgid="6350320429953234580">"Du kannst dein Smartphone jetzt verwenden"</string>
- <string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"Einstellungen der Systemsteuerung"</annotation></string>
- <string name="action_share" msgid="2648470652637092375">"Teilen"</string>
- <string name="action_screenshot" msgid="8171125848358142917">"Screenshot"</string>
- <string name="action_split" msgid="2098009717623550676">"Teilen"</string>
- <string name="toast_split_select_app" msgid="5453865907322018352">"Für „Bildschirm teilen“ auf weitere App tippen"</string>
- <string name="toast_split_app_unsupported" msgid="3271526028981899666">"„Bildschirm teilen“ wird von der App nicht unterstützt."</string>
- <string name="blocked_by_policy" msgid="2071401072261365546">"Die App oder deine Organisation lässt diese Aktion nicht zu"</string>
- <string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Navigationstutorial überspringen?"</string>
- <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Du findest es später auch in der <xliff:g id="NAME">%1$s</xliff:g> App"</string>
- <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Abbrechen"</string>
- <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Überspringen"</string>
- <string name="accessibility_rotate_button" msgid="4771825231336502943">"Bildschirm drehen"</string>
- <string name="taskbar_edu_opened" msgid="3950252793551919129">"Anleitung für Taskleiste eingeblendet"</string>
- <string name="taskbar_edu_closed" msgid="126643734478892862">"Anleitung für Taskleiste geschlossen"</string>
- <string name="taskbar_edu_switch_apps" msgid="6942863327845784813">"Über die Taskleiste zwischen Apps wechseln"</string>
- <string name="taskbar_edu_splitscreen" msgid="2663361731630346489">"Zur Seite ziehen, um zwei Apps gleichzeitig zu verwenden"</string>
- <string name="taskbar_edu_stashing" msgid="5212374387411764031">"Gedrückt halten, um die Taskleiste auszublenden"</string>
- <string name="taskbar_edu_next" msgid="4007618274426775841">"Weiter"</string>
- <string name="taskbar_edu_previous" msgid="459202320127201702">"Zurück"</string>
- <string name="taskbar_edu_close" msgid="887022990168191073">"Schließen"</string>
- <string name="taskbar_edu_done" msgid="6880178093977704569">"Fertig"</string>
- <string name="taskbar_button_home" msgid="2151398979630664652">"Startbildschirm"</string>
- <string name="taskbar_button_a11y" msgid="5241161324875094465">"Bedienungshilfen"</string>
- <string name="taskbar_button_back" msgid="8558862226461164514">"Zurück"</string>
- <string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"IME-Wechsler"</string>
- <string name="taskbar_button_recents" msgid="7273376136216613134">"Letzte Apps"</string>
- <string name="taskbar_button_notifications" msgid="7471740351507357318">"Benachrichtigungen"</string>
- <string name="taskbar_button_quick_settings" msgid="227662894293189391">"Schnelleinstellungen"</string>
- <string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Nach oben / Nach links verschieben"</string>
- <string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Nach unten / Nach rechts verschieben"</string>
</resources>
diff --git a/quickstep/res/values-el/strings.xml b/quickstep/res/values-el/strings.xml
index 10c39b40d9..87268df749 100644
--- a/quickstep/res/values-el/strings.xml
+++ b/quickstep/res/values-el/strings.xml
@@ -19,91 +19,19 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Διαχωρισμός οθόνης"</string>
<string name="recent_task_option_pin" msgid="7929860679018978258">"Καρφίτσωμα"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Ελεύθερη μορφή"</string>
+ <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Επισκόπηση"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"Δεν υπάρχουν πρόσφατα στοιχεία"</string>
+ <string name="accessibility_close_task" msgid="5354563209433803643">"Κλείσιμο"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Ρυθμίσεις χρήσης εφαρμογής"</string>
<string name="recents_clear_all" msgid="5328176793634888831">"Διαγραφή όλων"</string>
<string name="accessibility_recent_apps" msgid="4058661986695117371">"Πρόσφατες εφαρμογές"</string>
- <string name="task_view_closed" msgid="9170038230110856166">"Η εργασία έκλεισε"</string>
<string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
<string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 λ."</string>
<string name="time_left_for_app" msgid="3111996412933644358">"Απομένουν <xliff:g id="TIME">%1$s</xliff:g> σήμερα"</string>
- <string name="title_app_suggestions" msgid="4185902664111965088">"Προτεινόμενες εφαρμογές"</string>
+ <string name="title_app_suggestions" msgid="4185902664111965088">"Προτάσεις εφαρμογών"</string>
+ <string name="all_apps_label" msgid="8542784161730910663">"Όλες οι εφαρμογές"</string>
<string name="all_apps_prediction_tip" msgid="2672336544844936186">"Προβλέψεις εφαρμογών"</string>
- <string name="hotseat_edu_title_migrate" msgid="306578144424489980">"Δείτε τις προτεινόμενες εφαρμογές στην κάτω σειρά της αρχικής οθόνης"</string>
- <string name="hotseat_edu_title_migrate_landscape" msgid="3633942953997845243">"Δείτε τις προτεινόμενες εφαρμογές στη σειρά Αγαπημένα της αρχικής οθόνης."</string>
- <string name="hotseat_edu_message_migrate" msgid="8927179260533775320">"Αποκτήστε εύκολα πρόσβαση στις εφαρμογές που χρησιμοποιείτε περισσότερο απευθείας από την αρχική οθόνη. Οι προτάσεις θα αλλάζουν με βάση τις ρουτίνες σας. Οι εφαρμογές στην κάτω σειρά θα μετακινηθούν προς τα επάνω στην αρχική οθόνη."</string>
- <string name="hotseat_edu_message_migrate_landscape" msgid="4248943380443387697">"Αποκτήστε εύκολα πρόσβαση στις εφαρμογές που χρησιμοποιείτε περισσότερο απευθείας από την αρχική οθόνη. Οι προτάσεις θα αλλάζουν με βάση τις ρουτίνες σας. Οι εφαρμογές στην σειρά Αγαπημένα θα μετακινηθούν στην αρχική οθόνη σας."</string>
- <string name="hotseat_edu_message_migrate_alt" msgid="3042360119039646356">"Αποκτήστε εύκολα πρόσβαση στις εφαρμογές που χρησιμοποιείτε περισσότερο, απευθείας από την αρχική οθόνη. Οι προτάσεις θα αλλάζουν με βάση τις ρουτίνες σας. Οι εφαρμογές στην κάτω σειρά θα μεταφερθούν σε νέο φάκελο."</string>
- <string name="hotseat_edu_accept" msgid="1611544083278999837">"Προβολή προτεινόμενων εφαρμογών"</string>
- <string name="hotseat_edu_dismiss" msgid="2781161822780201689">"Όχι, ευχαριστώ"</string>
- <string name="hotseat_prediction_settings" msgid="6246554993566070818">"Ρυθμίσεις"</string>
- <string name="hotseat_auto_enrolled" msgid="522100018967146807">"Οι εφαρμογές που χρησιμοποιείτε περισσότερο εμφανίζονται εδώ και αλλάζουν με βάση τις ρουτίνες"</string>
- <string name="hotseat_tip_no_empty_slots" msgid="1325212677738179185">"Σύρετε εφαρμογές μακριά από την κάτω σειρά, για να δείτε τις προτεινόμενες εφαρμογές"</string>
- <string name="hotseat_tip_gaps_filled" msgid="3035673010274223538">"Οι προτεινόμενες εφαρμογές προστέθηκαν στον κενό χώρο"</string>
- <string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Οι προτεινόμενες εφαρμογές ενεργοποιήθηκαν"</string>
- <string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Οι προτεινόμενες εφαρμογές είναι απενεργοποιημένες"</string>
- <string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Εφαρμογή από πρόβλεψη: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Φροντίστε να σύρετε από το άκρο της δεξιάς ή της αριστερής πλευράς."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Σύρετε από το δεξί ή αριστερό άκρο προς το μέσο της οθόνης και απομακρύνετε το δάχτυλό σας."</string>
- <string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Μάθατε πώς να σύρετε από τα δεξιά για επιστροφή. Στη συνέχεια, μάθετε πώς να κάνετε εναλλαγή εφαρμ."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"Ολοκληρώσατε την κίνηση επιστροφής."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Φροντίστε να μην σύρετε υπερβολικά κοντά στο κάτω μέρος της οθόνης."</string>
- <string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"Μεταβείτε στις Ρυθμίσεις για αλλαγή ευαισθ. κίνησης επιστρ."</string>
- <string name="back_gesture_intro_title" msgid="19551256430224428">"Σύρετε για επιστροφή"</string>
- <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"Για να επιστρέψετε στην τελευτ. οθόνη, σύρετε από το αριστ. ή το δεξί άκρο προς το μέσο της οθόνης."</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Φροντίστε να σύρετε προς τα επάνω από το κάτω άκρο της οθόνης."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Φροντίστε να μην κάνετε παύση προτού απομακρύνετε τα δάχτυλά σας."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Φροντίστε να σύρετε απευθείας προς τα επάνω."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"Ολοκληρώσατε την κίνηση μετάβασης στην αρχική οθόνη. Στη συνέχεια, μάθετε πώς να κάνετε επιστροφή."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"Ολοκληρώσατε την κίνηση μετάβασης στην αρχική οθόνη."</string>
- <string name="home_gesture_intro_title" msgid="836590312858441830">"Σύρετε για μετάβαση στην αρχική οθόνη"</string>
- <string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Σύρετε προς τα πάνω από το κάτω μέρος της οθόνης. Αυτή η κίνηση σάς μεταφέρει πάντα στην αρχ. οθόνη."</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Φροντίστε να σύρετε προς τα επάνω από το κάτω άκρο της οθόνης."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Δοκιμάστε να κρατήσετε περισσότερο το παράθυρο προτού απελευθερώσετε."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Φροντίστε να σύρετε απευθείας προς τα επάνω και έπειτα κάντε παύση."</string>
- <string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Μάθατε πώς να χρησιμοποιείτε κινήσεις. Μεταβείτε στις Ρυθμίσεις για απενεργοποίηση των κινήσεων."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"Ολοκληρώσατε την κίνηση εναλλαγής εφαρμογών."</string>
- <string name="overview_gesture_intro_title" msgid="2902054412868489378">"Σύρετε για εναλλαγή εφαρμογών"</string>
- <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Για εναλλαγή εφαρμογών, σύρετε προς τα πάνω από το κάτω μέρος της οθόνης, πατήστε παρατεταμένα και μετά αφήστε."</string>
- <string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"Όλα είναι έτοιμα"</string>
- <string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Τέλος"</string>
- <string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Ρυθμίσεις"</string>
- <string name="gesture_tutorial_try_again" msgid="65962545858556697">"Δοκιμάστε ξανά"</string>
- <string name="gesture_tutorial_nice" msgid="2936275692616928280">"Ωραία!"</string>
- <string name="gesture_tutorial_step" msgid="1279786122817620968">"Οδηγός <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
- <string name="allset_title" msgid="5021126669778966707">"Όλα έτοιμα!"</string>
- <string name="allset_hint" msgid="2384632994739392447">"Σύρετε προς τα πάνω για μετάβαση στην αρχική οθόνη."</string>
- <string name="allset_description" msgid="6350320429953234580">"Είστε έτοιμοι να ξεκινήσετε να χρησιμοποιείτε το τηλέφωνό σας"</string>
- <string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"Ρυθμίσεις πλοήγησης συστήματος"</annotation></string>
- <string name="action_share" msgid="2648470652637092375">"Κοινοποίηση"</string>
- <string name="action_screenshot" msgid="8171125848358142917">"Στιγμιότυπο οθόνης"</string>
- <string name="action_split" msgid="2098009717623550676">"Διαχωρισμός"</string>
- <string name="toast_split_select_app" msgid="5453865907322018352">"Πατήστε άλλη εφαρμογή για χρήση διαχωρισμού οθόνης"</string>
- <string name="toast_split_app_unsupported" msgid="3271526028981899666">"Η εφαρμογή δεν υποστηρίζει διαχωρισμό οθόνης."</string>
- <string name="blocked_by_policy" msgid="2071401072261365546">"Αυτή η ενέργεια δεν επιτρέπεται από την εφαρμογή ή τον οργανισμό σας."</string>
- <string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Παράβλεψη οδηγού πλοήγησης;"</string>
- <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Βρείτε τον αργότερα στην εφαρμογή <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Ακύρωση"</string>
- <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Παράβλεψη"</string>
- <string name="accessibility_rotate_button" msgid="4771825231336502943">"Περιστροφή οθόνης"</string>
- <string name="taskbar_edu_opened" msgid="3950252793551919129">"Η εκπαίδευση για τη γραμμή εργασιών εμφανίστηκε"</string>
- <string name="taskbar_edu_closed" msgid="126643734478892862">"Η εκπαίδευση για τη γραμμή εργασιών έκλεισε"</string>
- <string name="taskbar_edu_switch_apps" msgid="6942863327845784813">"Χρήση της γραμμής εργασιών για εναλλαγή εφαρμογών"</string>
- <string name="taskbar_edu_splitscreen" msgid="2663361731630346489">"Σύρετε στο πλάι για ταυτόχρονη χρήση δύο εφαρμογών"</string>
- <string name="taskbar_edu_stashing" msgid="5212374387411764031">"Αγγίξτε παρατεταμένα για απόκρυψη της γραμμής εργασιών."</string>
- <string name="taskbar_edu_next" msgid="4007618274426775841">"Επόμενο"</string>
- <string name="taskbar_edu_previous" msgid="459202320127201702">"Πίσω"</string>
- <string name="taskbar_edu_close" msgid="887022990168191073">"Κλείσιμο"</string>
- <string name="taskbar_edu_done" msgid="6880178093977704569">"Τέλος"</string>
- <string name="taskbar_button_home" msgid="2151398979630664652">"Αρχική σελίδα"</string>
- <string name="taskbar_button_a11y" msgid="5241161324875094465">"Προσβασιμότητα"</string>
- <string name="taskbar_button_back" msgid="8558862226461164514">"Πίσω"</string>
- <string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"Εναλλαγή IME"</string>
- <string name="taskbar_button_recents" msgid="7273376136216613134">"Πρόσφατα"</string>
- <string name="taskbar_button_notifications" msgid="7471740351507357318">"Ειδοποιήσεις"</string>
- <string name="taskbar_button_quick_settings" msgid="227662894293189391">"Γρήγορες ρυθμ."</string>
- <string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Μετακίνηση επάνω/αριστερά"</string>
- <string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Μετακίνηση κάτω/δεξιά"</string>
</resources>
diff --git a/quickstep/res/values-en-rAU/strings.xml b/quickstep/res/values-en-rAU/strings.xml
index c67f4c92a7..2d1418e5f4 100644
--- a/quickstep/res/values-en-rAU/strings.xml
+++ b/quickstep/res/values-en-rAU/strings.xml
@@ -19,91 +19,19 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Split screen"</string>
<string name="recent_task_option_pin" msgid="7929860679018978258">"Pin"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Freeform"</string>
+ <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Overview"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"No recent items"</string>
+ <string name="accessibility_close_task" msgid="5354563209433803643">"Close"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"App usage settings"</string>
<string name="recents_clear_all" msgid="5328176793634888831">"Clear all"</string>
<string name="accessibility_recent_apps" msgid="4058661986695117371">"Recent apps"</string>
- <string name="task_view_closed" msgid="9170038230110856166">"Task closed"</string>
<string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
<string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 minute"</string>
<string name="time_left_for_app" msgid="3111996412933644358">"<xliff:g id="TIME">%1$s</xliff:g> left today"</string>
<string name="title_app_suggestions" msgid="4185902664111965088">"App suggestions"</string>
+ <string name="all_apps_label" msgid="8542784161730910663">"All apps"</string>
<string name="all_apps_prediction_tip" msgid="2672336544844936186">"Your predicted apps"</string>
- <string name="hotseat_edu_title_migrate" msgid="306578144424489980">"Get app suggestions on the bottom row of your home screen"</string>
- <string name="hotseat_edu_title_migrate_landscape" msgid="3633942953997845243">"Get app suggestions on the favourites row of your home screen"</string>
- <string name="hotseat_edu_message_migrate" msgid="8927179260533775320">"Easily access your most-used apps directly from the home screen. Suggestions will change based on your routines. Apps on the bottom row will move up to your home screen."</string>
- <string name="hotseat_edu_message_migrate_landscape" msgid="4248943380443387697">"Easily access your most-used apps directly from the home screen. Suggestions will change based on your routines. Apps in the favourites row will move to your home screen."</string>
- <string name="hotseat_edu_message_migrate_alt" msgid="3042360119039646356">"Easily access your most-used apps directly from the home screen. Suggestions will change based on your routines. Apps on the bottom row will be moved to a new folder."</string>
- <string name="hotseat_edu_accept" msgid="1611544083278999837">"Get app suggestions"</string>
- <string name="hotseat_edu_dismiss" msgid="2781161822780201689">"No, thanks"</string>
- <string name="hotseat_prediction_settings" msgid="6246554993566070818">"Settings"</string>
- <string name="hotseat_auto_enrolled" msgid="522100018967146807">"Most-used apps appear here, and change based on routines"</string>
- <string name="hotseat_tip_no_empty_slots" msgid="1325212677738179185">"Drag apps off the bottom row to get app suggestions"</string>
- <string name="hotseat_tip_gaps_filled" msgid="3035673010274223538">"App suggestions added to empty space"</string>
- <string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"App suggestions enabled"</string>
- <string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"App suggestions are disabled"</string>
- <string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Predicted app: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Make sure that you swipe from the far-right or far-left edge."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Make sure that you swipe from the right or left edge to the middle of the screen and let go."</string>
- <string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"You learned how to swipe from the right to go back. Next, learn how to switch apps."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"You completed the go back gesture."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Make sure that you don\'t swipe too close to the bottom of the screen."</string>
- <string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"To change sensitivity of the back gesture, go to Settings"</string>
- <string name="back_gesture_intro_title" msgid="19551256430224428">"Swipe to go back"</string>
- <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"To go back to the last screen, swipe from the left or right edge to the middle of the screen."</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Make sure that you swipe up from the bottom edge of the screen."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Make sure that you don\'t pause before letting go."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Make sure that you swipe straight up."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"You completed the go home gesture. Next, learn how to go back."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"You completed the go home gesture."</string>
- <string name="home_gesture_intro_title" msgid="836590312858441830">"Swipe to go home"</string>
- <string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Swipe up from the bottom of your screen. This gesture always takes you to the home screen."</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Make sure that you swipe up from the bottom edge of the screen."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Try holding the window for longer before releasing."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Make sure that you swipe straight up, then pause."</string>
- <string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"You learned how to use gestures. To turn off gestures, go to Settings."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"You completed the switch apps gesture."</string>
- <string name="overview_gesture_intro_title" msgid="2902054412868489378">"Swipe to switch apps"</string>
- <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"To switch between apps, swipe up from the bottom of your screen, hold, then release."</string>
- <string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"All set"</string>
- <string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Done"</string>
- <string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Settings"</string>
- <string name="gesture_tutorial_try_again" msgid="65962545858556697">"Try again"</string>
- <string name="gesture_tutorial_nice" msgid="2936275692616928280">"Nice!"</string>
- <string name="gesture_tutorial_step" msgid="1279786122817620968">"Tutorial <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
- <string name="allset_title" msgid="5021126669778966707">"Ready!"</string>
- <string name="allset_hint" msgid="2384632994739392447">"Swipe up to go home"</string>
- <string name="allset_description" msgid="6350320429953234580">"You’re ready to start using your phone"</string>
- <string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"System navigation settings"</annotation></string>
- <string name="action_share" msgid="2648470652637092375">"Share"</string>
- <string name="action_screenshot" msgid="8171125848358142917">"Screenshot"</string>
- <string name="action_split" msgid="2098009717623550676">"Split"</string>
- <string name="toast_split_select_app" msgid="5453865907322018352">"Tap another app to use split-screen"</string>
- <string name="toast_split_app_unsupported" msgid="3271526028981899666">"App does not support split-screen."</string>
- <string name="blocked_by_policy" msgid="2071401072261365546">"This action isn\'t allowed by the app or your organisation"</string>
- <string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Skip navigation tutorial?"</string>
- <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"You can find this later in the <xliff:g id="NAME">%1$s</xliff:g> app"</string>
- <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Cancel"</string>
- <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Skip"</string>
- <string name="accessibility_rotate_button" msgid="4771825231336502943">"Rotate screen"</string>
- <string name="taskbar_edu_opened" msgid="3950252793551919129">"Taskbar education appeared"</string>
- <string name="taskbar_edu_closed" msgid="126643734478892862">"Taskbar education closed"</string>
- <string name="taskbar_edu_switch_apps" msgid="6942863327845784813">"Use the taskbar to switch apps"</string>
- <string name="taskbar_edu_splitscreen" msgid="2663361731630346489">"Drag to the side to use two apps at once"</string>
- <string name="taskbar_edu_stashing" msgid="5212374387411764031">"Touch &amp; hold to hide the taskbar"</string>
- <string name="taskbar_edu_next" msgid="4007618274426775841">"Next"</string>
- <string name="taskbar_edu_previous" msgid="459202320127201702">"Back"</string>
- <string name="taskbar_edu_close" msgid="887022990168191073">"Close"</string>
- <string name="taskbar_edu_done" msgid="6880178093977704569">"Done"</string>
- <string name="taskbar_button_home" msgid="2151398979630664652">"Home"</string>
- <string name="taskbar_button_a11y" msgid="5241161324875094465">"Accessibility"</string>
- <string name="taskbar_button_back" msgid="8558862226461164514">"Back"</string>
- <string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"IME switcher"</string>
- <string name="taskbar_button_recents" msgid="7273376136216613134">"Recents"</string>
- <string name="taskbar_button_notifications" msgid="7471740351507357318">"Notifications"</string>
- <string name="taskbar_button_quick_settings" msgid="227662894293189391">"Quick Settings"</string>
- <string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Move to top/left"</string>
- <string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Move to bottom/right"</string>
</resources>
diff --git a/quickstep/res/values-en-rCA/strings.xml b/quickstep/res/values-en-rCA/strings.xml
deleted file mode 100644
index c67f4c92a7..0000000000
--- a/quickstep/res/values-en-rCA/strings.xml
+++ /dev/null
@@ -1,109 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2017 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="recent_task_option_pin" msgid="7929860679018978258">"Pin"</string>
- <string name="recent_task_option_freeform" msgid="48863056265284071">"Freeform"</string>
- <string name="recents_empty_message" msgid="7040467240571714191">"No recent items"</string>
- <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"App usage settings"</string>
- <string name="recents_clear_all" msgid="5328176793634888831">"Clear all"</string>
- <string name="accessibility_recent_apps" msgid="4058661986695117371">"Recent apps"</string>
- <string name="task_view_closed" msgid="9170038230110856166">"Task closed"</string>
- <string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
- <string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 minute"</string>
- <string name="time_left_for_app" msgid="3111996412933644358">"<xliff:g id="TIME">%1$s</xliff:g> left today"</string>
- <string name="title_app_suggestions" msgid="4185902664111965088">"App suggestions"</string>
- <string name="all_apps_prediction_tip" msgid="2672336544844936186">"Your predicted apps"</string>
- <string name="hotseat_edu_title_migrate" msgid="306578144424489980">"Get app suggestions on the bottom row of your home screen"</string>
- <string name="hotseat_edu_title_migrate_landscape" msgid="3633942953997845243">"Get app suggestions on the favourites row of your home screen"</string>
- <string name="hotseat_edu_message_migrate" msgid="8927179260533775320">"Easily access your most-used apps directly from the home screen. Suggestions will change based on your routines. Apps on the bottom row will move up to your home screen."</string>
- <string name="hotseat_edu_message_migrate_landscape" msgid="4248943380443387697">"Easily access your most-used apps directly from the home screen. Suggestions will change based on your routines. Apps in the favourites row will move to your home screen."</string>
- <string name="hotseat_edu_message_migrate_alt" msgid="3042360119039646356">"Easily access your most-used apps directly from the home screen. Suggestions will change based on your routines. Apps on the bottom row will be moved to a new folder."</string>
- <string name="hotseat_edu_accept" msgid="1611544083278999837">"Get app suggestions"</string>
- <string name="hotseat_edu_dismiss" msgid="2781161822780201689">"No, thanks"</string>
- <string name="hotseat_prediction_settings" msgid="6246554993566070818">"Settings"</string>
- <string name="hotseat_auto_enrolled" msgid="522100018967146807">"Most-used apps appear here, and change based on routines"</string>
- <string name="hotseat_tip_no_empty_slots" msgid="1325212677738179185">"Drag apps off the bottom row to get app suggestions"</string>
- <string name="hotseat_tip_gaps_filled" msgid="3035673010274223538">"App suggestions added to empty space"</string>
- <string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"App suggestions enabled"</string>
- <string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"App suggestions are disabled"</string>
- <string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Predicted app: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Make sure that you swipe from the far-right or far-left edge."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Make sure that you swipe from the right or left edge to the middle of the screen and let go."</string>
- <string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"You learned how to swipe from the right to go back. Next, learn how to switch apps."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"You completed the go back gesture."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Make sure that you don\'t swipe too close to the bottom of the screen."</string>
- <string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"To change sensitivity of the back gesture, go to Settings"</string>
- <string name="back_gesture_intro_title" msgid="19551256430224428">"Swipe to go back"</string>
- <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"To go back to the last screen, swipe from the left or right edge to the middle of the screen."</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Make sure that you swipe up from the bottom edge of the screen."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Make sure that you don\'t pause before letting go."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Make sure that you swipe straight up."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"You completed the go home gesture. Next, learn how to go back."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"You completed the go home gesture."</string>
- <string name="home_gesture_intro_title" msgid="836590312858441830">"Swipe to go home"</string>
- <string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Swipe up from the bottom of your screen. This gesture always takes you to the home screen."</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Make sure that you swipe up from the bottom edge of the screen."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Try holding the window for longer before releasing."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Make sure that you swipe straight up, then pause."</string>
- <string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"You learned how to use gestures. To turn off gestures, go to Settings."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"You completed the switch apps gesture."</string>
- <string name="overview_gesture_intro_title" msgid="2902054412868489378">"Swipe to switch apps"</string>
- <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"To switch between apps, swipe up from the bottom of your screen, hold, then release."</string>
- <string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"All set"</string>
- <string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Done"</string>
- <string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Settings"</string>
- <string name="gesture_tutorial_try_again" msgid="65962545858556697">"Try again"</string>
- <string name="gesture_tutorial_nice" msgid="2936275692616928280">"Nice!"</string>
- <string name="gesture_tutorial_step" msgid="1279786122817620968">"Tutorial <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
- <string name="allset_title" msgid="5021126669778966707">"Ready!"</string>
- <string name="allset_hint" msgid="2384632994739392447">"Swipe up to go home"</string>
- <string name="allset_description" msgid="6350320429953234580">"You’re ready to start using your phone"</string>
- <string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"System navigation settings"</annotation></string>
- <string name="action_share" msgid="2648470652637092375">"Share"</string>
- <string name="action_screenshot" msgid="8171125848358142917">"Screenshot"</string>
- <string name="action_split" msgid="2098009717623550676">"Split"</string>
- <string name="toast_split_select_app" msgid="5453865907322018352">"Tap another app to use split-screen"</string>
- <string name="toast_split_app_unsupported" msgid="3271526028981899666">"App does not support split-screen."</string>
- <string name="blocked_by_policy" msgid="2071401072261365546">"This action isn\'t allowed by the app or your organisation"</string>
- <string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Skip navigation tutorial?"</string>
- <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"You can find this later in the <xliff:g id="NAME">%1$s</xliff:g> app"</string>
- <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Cancel"</string>
- <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Skip"</string>
- <string name="accessibility_rotate_button" msgid="4771825231336502943">"Rotate screen"</string>
- <string name="taskbar_edu_opened" msgid="3950252793551919129">"Taskbar education appeared"</string>
- <string name="taskbar_edu_closed" msgid="126643734478892862">"Taskbar education closed"</string>
- <string name="taskbar_edu_switch_apps" msgid="6942863327845784813">"Use the taskbar to switch apps"</string>
- <string name="taskbar_edu_splitscreen" msgid="2663361731630346489">"Drag to the side to use two apps at once"</string>
- <string name="taskbar_edu_stashing" msgid="5212374387411764031">"Touch &amp; hold to hide the taskbar"</string>
- <string name="taskbar_edu_next" msgid="4007618274426775841">"Next"</string>
- <string name="taskbar_edu_previous" msgid="459202320127201702">"Back"</string>
- <string name="taskbar_edu_close" msgid="887022990168191073">"Close"</string>
- <string name="taskbar_edu_done" msgid="6880178093977704569">"Done"</string>
- <string name="taskbar_button_home" msgid="2151398979630664652">"Home"</string>
- <string name="taskbar_button_a11y" msgid="5241161324875094465">"Accessibility"</string>
- <string name="taskbar_button_back" msgid="8558862226461164514">"Back"</string>
- <string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"IME switcher"</string>
- <string name="taskbar_button_recents" msgid="7273376136216613134">"Recents"</string>
- <string name="taskbar_button_notifications" msgid="7471740351507357318">"Notifications"</string>
- <string name="taskbar_button_quick_settings" msgid="227662894293189391">"Quick Settings"</string>
- <string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Move to top/left"</string>
- <string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Move to bottom/right"</string>
-</resources>
diff --git a/quickstep/res/values-en-rGB/strings.xml b/quickstep/res/values-en-rGB/strings.xml
index c67f4c92a7..2d1418e5f4 100644
--- a/quickstep/res/values-en-rGB/strings.xml
+++ b/quickstep/res/values-en-rGB/strings.xml
@@ -19,91 +19,19 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Split screen"</string>
<string name="recent_task_option_pin" msgid="7929860679018978258">"Pin"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Freeform"</string>
+ <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Overview"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"No recent items"</string>
+ <string name="accessibility_close_task" msgid="5354563209433803643">"Close"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"App usage settings"</string>
<string name="recents_clear_all" msgid="5328176793634888831">"Clear all"</string>
<string name="accessibility_recent_apps" msgid="4058661986695117371">"Recent apps"</string>
- <string name="task_view_closed" msgid="9170038230110856166">"Task closed"</string>
<string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
<string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 minute"</string>
<string name="time_left_for_app" msgid="3111996412933644358">"<xliff:g id="TIME">%1$s</xliff:g> left today"</string>
<string name="title_app_suggestions" msgid="4185902664111965088">"App suggestions"</string>
+ <string name="all_apps_label" msgid="8542784161730910663">"All apps"</string>
<string name="all_apps_prediction_tip" msgid="2672336544844936186">"Your predicted apps"</string>
- <string name="hotseat_edu_title_migrate" msgid="306578144424489980">"Get app suggestions on the bottom row of your home screen"</string>
- <string name="hotseat_edu_title_migrate_landscape" msgid="3633942953997845243">"Get app suggestions on the favourites row of your home screen"</string>
- <string name="hotseat_edu_message_migrate" msgid="8927179260533775320">"Easily access your most-used apps directly from the home screen. Suggestions will change based on your routines. Apps on the bottom row will move up to your home screen."</string>
- <string name="hotseat_edu_message_migrate_landscape" msgid="4248943380443387697">"Easily access your most-used apps directly from the home screen. Suggestions will change based on your routines. Apps in the favourites row will move to your home screen."</string>
- <string name="hotseat_edu_message_migrate_alt" msgid="3042360119039646356">"Easily access your most-used apps directly from the home screen. Suggestions will change based on your routines. Apps on the bottom row will be moved to a new folder."</string>
- <string name="hotseat_edu_accept" msgid="1611544083278999837">"Get app suggestions"</string>
- <string name="hotseat_edu_dismiss" msgid="2781161822780201689">"No, thanks"</string>
- <string name="hotseat_prediction_settings" msgid="6246554993566070818">"Settings"</string>
- <string name="hotseat_auto_enrolled" msgid="522100018967146807">"Most-used apps appear here, and change based on routines"</string>
- <string name="hotseat_tip_no_empty_slots" msgid="1325212677738179185">"Drag apps off the bottom row to get app suggestions"</string>
- <string name="hotseat_tip_gaps_filled" msgid="3035673010274223538">"App suggestions added to empty space"</string>
- <string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"App suggestions enabled"</string>
- <string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"App suggestions are disabled"</string>
- <string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Predicted app: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Make sure that you swipe from the far-right or far-left edge."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Make sure that you swipe from the right or left edge to the middle of the screen and let go."</string>
- <string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"You learned how to swipe from the right to go back. Next, learn how to switch apps."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"You completed the go back gesture."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Make sure that you don\'t swipe too close to the bottom of the screen."</string>
- <string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"To change sensitivity of the back gesture, go to Settings"</string>
- <string name="back_gesture_intro_title" msgid="19551256430224428">"Swipe to go back"</string>
- <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"To go back to the last screen, swipe from the left or right edge to the middle of the screen."</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Make sure that you swipe up from the bottom edge of the screen."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Make sure that you don\'t pause before letting go."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Make sure that you swipe straight up."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"You completed the go home gesture. Next, learn how to go back."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"You completed the go home gesture."</string>
- <string name="home_gesture_intro_title" msgid="836590312858441830">"Swipe to go home"</string>
- <string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Swipe up from the bottom of your screen. This gesture always takes you to the home screen."</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Make sure that you swipe up from the bottom edge of the screen."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Try holding the window for longer before releasing."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Make sure that you swipe straight up, then pause."</string>
- <string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"You learned how to use gestures. To turn off gestures, go to Settings."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"You completed the switch apps gesture."</string>
- <string name="overview_gesture_intro_title" msgid="2902054412868489378">"Swipe to switch apps"</string>
- <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"To switch between apps, swipe up from the bottom of your screen, hold, then release."</string>
- <string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"All set"</string>
- <string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Done"</string>
- <string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Settings"</string>
- <string name="gesture_tutorial_try_again" msgid="65962545858556697">"Try again"</string>
- <string name="gesture_tutorial_nice" msgid="2936275692616928280">"Nice!"</string>
- <string name="gesture_tutorial_step" msgid="1279786122817620968">"Tutorial <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
- <string name="allset_title" msgid="5021126669778966707">"Ready!"</string>
- <string name="allset_hint" msgid="2384632994739392447">"Swipe up to go home"</string>
- <string name="allset_description" msgid="6350320429953234580">"You’re ready to start using your phone"</string>
- <string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"System navigation settings"</annotation></string>
- <string name="action_share" msgid="2648470652637092375">"Share"</string>
- <string name="action_screenshot" msgid="8171125848358142917">"Screenshot"</string>
- <string name="action_split" msgid="2098009717623550676">"Split"</string>
- <string name="toast_split_select_app" msgid="5453865907322018352">"Tap another app to use split-screen"</string>
- <string name="toast_split_app_unsupported" msgid="3271526028981899666">"App does not support split-screen."</string>
- <string name="blocked_by_policy" msgid="2071401072261365546">"This action isn\'t allowed by the app or your organisation"</string>
- <string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Skip navigation tutorial?"</string>
- <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"You can find this later in the <xliff:g id="NAME">%1$s</xliff:g> app"</string>
- <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Cancel"</string>
- <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Skip"</string>
- <string name="accessibility_rotate_button" msgid="4771825231336502943">"Rotate screen"</string>
- <string name="taskbar_edu_opened" msgid="3950252793551919129">"Taskbar education appeared"</string>
- <string name="taskbar_edu_closed" msgid="126643734478892862">"Taskbar education closed"</string>
- <string name="taskbar_edu_switch_apps" msgid="6942863327845784813">"Use the taskbar to switch apps"</string>
- <string name="taskbar_edu_splitscreen" msgid="2663361731630346489">"Drag to the side to use two apps at once"</string>
- <string name="taskbar_edu_stashing" msgid="5212374387411764031">"Touch &amp; hold to hide the taskbar"</string>
- <string name="taskbar_edu_next" msgid="4007618274426775841">"Next"</string>
- <string name="taskbar_edu_previous" msgid="459202320127201702">"Back"</string>
- <string name="taskbar_edu_close" msgid="887022990168191073">"Close"</string>
- <string name="taskbar_edu_done" msgid="6880178093977704569">"Done"</string>
- <string name="taskbar_button_home" msgid="2151398979630664652">"Home"</string>
- <string name="taskbar_button_a11y" msgid="5241161324875094465">"Accessibility"</string>
- <string name="taskbar_button_back" msgid="8558862226461164514">"Back"</string>
- <string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"IME switcher"</string>
- <string name="taskbar_button_recents" msgid="7273376136216613134">"Recents"</string>
- <string name="taskbar_button_notifications" msgid="7471740351507357318">"Notifications"</string>
- <string name="taskbar_button_quick_settings" msgid="227662894293189391">"Quick Settings"</string>
- <string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Move to top/left"</string>
- <string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Move to bottom/right"</string>
</resources>
diff --git a/quickstep/res/values-en-rIN/strings.xml b/quickstep/res/values-en-rIN/strings.xml
index c67f4c92a7..2d1418e5f4 100644
--- a/quickstep/res/values-en-rIN/strings.xml
+++ b/quickstep/res/values-en-rIN/strings.xml
@@ -19,91 +19,19 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Split screen"</string>
<string name="recent_task_option_pin" msgid="7929860679018978258">"Pin"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Freeform"</string>
+ <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Overview"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"No recent items"</string>
+ <string name="accessibility_close_task" msgid="5354563209433803643">"Close"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"App usage settings"</string>
<string name="recents_clear_all" msgid="5328176793634888831">"Clear all"</string>
<string name="accessibility_recent_apps" msgid="4058661986695117371">"Recent apps"</string>
- <string name="task_view_closed" msgid="9170038230110856166">"Task closed"</string>
<string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
<string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 minute"</string>
<string name="time_left_for_app" msgid="3111996412933644358">"<xliff:g id="TIME">%1$s</xliff:g> left today"</string>
<string name="title_app_suggestions" msgid="4185902664111965088">"App suggestions"</string>
+ <string name="all_apps_label" msgid="8542784161730910663">"All apps"</string>
<string name="all_apps_prediction_tip" msgid="2672336544844936186">"Your predicted apps"</string>
- <string name="hotseat_edu_title_migrate" msgid="306578144424489980">"Get app suggestions on the bottom row of your home screen"</string>
- <string name="hotseat_edu_title_migrate_landscape" msgid="3633942953997845243">"Get app suggestions on the favourites row of your home screen"</string>
- <string name="hotseat_edu_message_migrate" msgid="8927179260533775320">"Easily access your most-used apps directly from the home screen. Suggestions will change based on your routines. Apps on the bottom row will move up to your home screen."</string>
- <string name="hotseat_edu_message_migrate_landscape" msgid="4248943380443387697">"Easily access your most-used apps directly from the home screen. Suggestions will change based on your routines. Apps in the favourites row will move to your home screen."</string>
- <string name="hotseat_edu_message_migrate_alt" msgid="3042360119039646356">"Easily access your most-used apps directly from the home screen. Suggestions will change based on your routines. Apps on the bottom row will be moved to a new folder."</string>
- <string name="hotseat_edu_accept" msgid="1611544083278999837">"Get app suggestions"</string>
- <string name="hotseat_edu_dismiss" msgid="2781161822780201689">"No, thanks"</string>
- <string name="hotseat_prediction_settings" msgid="6246554993566070818">"Settings"</string>
- <string name="hotseat_auto_enrolled" msgid="522100018967146807">"Most-used apps appear here, and change based on routines"</string>
- <string name="hotseat_tip_no_empty_slots" msgid="1325212677738179185">"Drag apps off the bottom row to get app suggestions"</string>
- <string name="hotseat_tip_gaps_filled" msgid="3035673010274223538">"App suggestions added to empty space"</string>
- <string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"App suggestions enabled"</string>
- <string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"App suggestions are disabled"</string>
- <string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Predicted app: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Make sure that you swipe from the far-right or far-left edge."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Make sure that you swipe from the right or left edge to the middle of the screen and let go."</string>
- <string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"You learned how to swipe from the right to go back. Next, learn how to switch apps."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"You completed the go back gesture."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Make sure that you don\'t swipe too close to the bottom of the screen."</string>
- <string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"To change sensitivity of the back gesture, go to Settings"</string>
- <string name="back_gesture_intro_title" msgid="19551256430224428">"Swipe to go back"</string>
- <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"To go back to the last screen, swipe from the left or right edge to the middle of the screen."</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Make sure that you swipe up from the bottom edge of the screen."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Make sure that you don\'t pause before letting go."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Make sure that you swipe straight up."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"You completed the go home gesture. Next, learn how to go back."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"You completed the go home gesture."</string>
- <string name="home_gesture_intro_title" msgid="836590312858441830">"Swipe to go home"</string>
- <string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Swipe up from the bottom of your screen. This gesture always takes you to the home screen."</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Make sure that you swipe up from the bottom edge of the screen."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Try holding the window for longer before releasing."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Make sure that you swipe straight up, then pause."</string>
- <string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"You learned how to use gestures. To turn off gestures, go to Settings."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"You completed the switch apps gesture."</string>
- <string name="overview_gesture_intro_title" msgid="2902054412868489378">"Swipe to switch apps"</string>
- <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"To switch between apps, swipe up from the bottom of your screen, hold, then release."</string>
- <string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"All set"</string>
- <string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Done"</string>
- <string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Settings"</string>
- <string name="gesture_tutorial_try_again" msgid="65962545858556697">"Try again"</string>
- <string name="gesture_tutorial_nice" msgid="2936275692616928280">"Nice!"</string>
- <string name="gesture_tutorial_step" msgid="1279786122817620968">"Tutorial <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
- <string name="allset_title" msgid="5021126669778966707">"Ready!"</string>
- <string name="allset_hint" msgid="2384632994739392447">"Swipe up to go home"</string>
- <string name="allset_description" msgid="6350320429953234580">"You’re ready to start using your phone"</string>
- <string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"System navigation settings"</annotation></string>
- <string name="action_share" msgid="2648470652637092375">"Share"</string>
- <string name="action_screenshot" msgid="8171125848358142917">"Screenshot"</string>
- <string name="action_split" msgid="2098009717623550676">"Split"</string>
- <string name="toast_split_select_app" msgid="5453865907322018352">"Tap another app to use split-screen"</string>
- <string name="toast_split_app_unsupported" msgid="3271526028981899666">"App does not support split-screen."</string>
- <string name="blocked_by_policy" msgid="2071401072261365546">"This action isn\'t allowed by the app or your organisation"</string>
- <string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Skip navigation tutorial?"</string>
- <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"You can find this later in the <xliff:g id="NAME">%1$s</xliff:g> app"</string>
- <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Cancel"</string>
- <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Skip"</string>
- <string name="accessibility_rotate_button" msgid="4771825231336502943">"Rotate screen"</string>
- <string name="taskbar_edu_opened" msgid="3950252793551919129">"Taskbar education appeared"</string>
- <string name="taskbar_edu_closed" msgid="126643734478892862">"Taskbar education closed"</string>
- <string name="taskbar_edu_switch_apps" msgid="6942863327845784813">"Use the taskbar to switch apps"</string>
- <string name="taskbar_edu_splitscreen" msgid="2663361731630346489">"Drag to the side to use two apps at once"</string>
- <string name="taskbar_edu_stashing" msgid="5212374387411764031">"Touch &amp; hold to hide the taskbar"</string>
- <string name="taskbar_edu_next" msgid="4007618274426775841">"Next"</string>
- <string name="taskbar_edu_previous" msgid="459202320127201702">"Back"</string>
- <string name="taskbar_edu_close" msgid="887022990168191073">"Close"</string>
- <string name="taskbar_edu_done" msgid="6880178093977704569">"Done"</string>
- <string name="taskbar_button_home" msgid="2151398979630664652">"Home"</string>
- <string name="taskbar_button_a11y" msgid="5241161324875094465">"Accessibility"</string>
- <string name="taskbar_button_back" msgid="8558862226461164514">"Back"</string>
- <string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"IME switcher"</string>
- <string name="taskbar_button_recents" msgid="7273376136216613134">"Recents"</string>
- <string name="taskbar_button_notifications" msgid="7471740351507357318">"Notifications"</string>
- <string name="taskbar_button_quick_settings" msgid="227662894293189391">"Quick Settings"</string>
- <string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Move to top/left"</string>
- <string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Move to bottom/right"</string>
</resources>
diff --git a/quickstep/res/values-en-rXC/strings.xml b/quickstep/res/values-en-rXC/strings.xml
deleted file mode 100644
index c3007f04e0..0000000000
--- a/quickstep/res/values-en-rXC/strings.xml
+++ /dev/null
@@ -1,109 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2017 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="recent_task_option_pin" msgid="7929860679018978258">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‏‎‏‏‏‎‎‎‎‎‏‏‎‎‏‎‎‎‎‏‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‎‏‏‎‏‎‎‎‎‏‏‏‎‎‏‏‎‏‏‏‏‎‏‎‎‏‎‎Pin‎‏‎‎‏‎"</string>
- <string name="recent_task_option_freeform" msgid="48863056265284071">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‎‎‎‏‎‏‎‏‏‎‏‏‎‎‏‏‎‎‎‏‎‏‏‎‎‎‎‏‏‎‏‎‏‏‏‎‏‎‏‎‏‎‏‎‎‎‎‏‎‎‏‏‏‏‎‎‏‏‏‎Freeform‎‏‎‎‏‎"</string>
- <string name="recents_empty_message" msgid="7040467240571714191">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‏‎‎‎‎‏‏‎‏‏‎‏‎‎‏‏‎‎‎‎‏‏‏‎‏‎‎‏‏‏‎‎‏‏‏‏‏‏‎‎‎‎‏‏‎‏‎‎‏‏‏‎‏‎‏‎‎‎‏‏‏‏‎No recent items‎‏‎‎‏‎"</string>
- <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‎‏‎‏‏‏‏‎‎‏‏‎‏‏‏‏‎‎‏‏‎‎‏‎‎‏‎‎‏‎‏‏‎‏‎‎‏‏‎‏‏‎‎‎‎‏‎‏‎‏‎‎‎‏‏‏‎‏‎‏‎‏‎App usage settings‎‏‎‎‏‎"</string>
- <string name="recents_clear_all" msgid="5328176793634888831">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‎‎‏‎‎‏‏‏‏‏‎‎‎‏‎‏‏‏‏‏‎‎‏‎‎‏‎‎‎‎‎‏‎‏‏‏‎‏‎‎‎‏‎‏‏‎‎‏‎‏‏‏‎‎‎‏‏‏‏‏‏‏‎Clear all‎‏‎‎‏‎"</string>
- <string name="accessibility_recent_apps" msgid="4058661986695117371">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‏‏‎‎‎‎‏‎‏‎‎‏‏‎‏‎‎‎‎‏‏‏‎‎‏‎‎‏‎‏‎‏‏‏‏‎‎‎‏‎‏‎‏‏‏‏‏‏‏‏‎‏‎‎‎‏‏‏‎‏‏‎Recent apps‎‏‎‎‏‎"</string>
- <string name="task_view_closed" msgid="9170038230110856166">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‎‏‎‎‎‎‏‎‏‎‎‎‎‏‎‏‎‎‏‎‏‏‏‏‎‏‏‏‎‎‏‎‏‎‎‎‎‎‏‎‎‏‏‎‎‎‏‏‏‏‏‎‎‏‏‎‎Task Closed‎‏‎‎‏‎"</string>
- <string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‏‏‏‏‎‎‎‏‎‏‎‏‏‎‎‎‎‏‏‎‏‎‎‏‎‏‏‏‎‎‎‏‏‏‎‏‏‏‏‏‎‎‏‎‏‏‏‏‏‎‎‏‏‎‎‏‎‏‏‎‏‎‎‏‎‎‏‏‎<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>‎‏‎‎‏‏‏‎, ‎‏‎‎‏‏‎<xliff:g id="REMAINING_TIME">%2$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
- <string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‎‎‎‎‎‏‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‎‏‏‏‎‏‎‏‏‏‎‏‏‏‏‏‎‏‏‏‎‏‎‎‏‏‎‎‎‎‏‏‎‏‎‏‎‎‎‎&lt; 1 minute‎‏‎‎‏‎"</string>
- <string name="time_left_for_app" msgid="3111996412933644358">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‎‏‎‏‏‎‎‏‏‎‎‎‎‎‎‎‎‏‎‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‏‎‎‏‏‎‎‏‏‎‎‏‎‎‎‎‎‎‏‎‎‎‏‏‎‎‎‏‎‎‏‏‎<xliff:g id="TIME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ left today‎‏‎‎‏‎"</string>
- <string name="title_app_suggestions" msgid="4185902664111965088">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‏‏‎‏‎‎‎‎‏‎‏‏‏‎‏‎‏‎‎‎‎‎‏‎‎‏‎‏‏‏‎‎‎‏‏‏‎‏‏‎‎‎‎‎‏‎‏‎‎‎‎‏‏‏‎‏‎‎‎‎‎‎App suggestions‎‏‎‎‏‎"</string>
- <string name="all_apps_prediction_tip" msgid="2672336544844936186">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‎‎‏‎‏‎‎‎‏‎‏‏‎‎‎‎‎‏‎‏‏‏‏‏‎‏‏‎‏‏‏‎‎‏‎‏‏‏‏‎‎‎‏‏‎‏‏‏‏‎‎‏‏‏‏‏‏‏‎‏‎‎Your predicted apps‎‏‎‎‏‎"</string>
- <string name="hotseat_edu_title_migrate" msgid="306578144424489980">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‎‏‏‏‎‎‎‏‎‎‎‎‎‏‎‎‏‎‏‏‏‏‎‎‏‏‎‎‏‎‏‎‏‏‎‎‏‎‎‏‎‏‎‎‎‏‏‏‏‏‎‎‏‏‏‏‏‏‏‏‎‎‎Get app suggestions on the bottom row of your Home screen‎‏‎‎‏‎"</string>
- <string name="hotseat_edu_title_migrate_landscape" msgid="3633942953997845243">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‏‎‎‏‎‎‏‏‎‏‏‏‎‎‏‎‏‏‎‏‏‏‏‎‏‏‏‎‎‏‏‏‏‏‎‏‏‎‎‎‏‎‎‏‏‎‏‎‎‎‎‏‎‏‏‏‏‏‎‏‏‎Get app suggestions on favorites row of your Home screen‎‏‎‎‏‎"</string>
- <string name="hotseat_edu_message_migrate" msgid="8927179260533775320">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‏‏‏‎‏‏‏‏‏‎‎‎‏‏‏‎‏‏‎‏‏‎‎‎‏‏‏‏‎‏‎‎‏‏‏‏‏‎‎‏‎‏‏‎‎‏‏‎‎‏‏‎‏‏‏‏‎‏‏‎‎‎‎Easily access your most-used apps right on the Home screen. Suggestions will change based on your routines. Apps on the bottom row will move up to your Home screen.‎‏‎‎‏‎"</string>
- <string name="hotseat_edu_message_migrate_landscape" msgid="4248943380443387697">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‏‏‎‏‎‏‏‏‏‎‏‏‏‎‏‎‎‎‏‏‏‎‏‏‏‏‏‏‎‎‎‎‏‏‏‏‎‎‎‎‏‎‎‏‏‎‏‎‏‎‏‏‏‎‎‏‏‎‎‎‏‎Easily access your most-used apps right on the Home screen. Suggestions will change based on your routines. Apps in favorites row will move to your Home screen.‎‏‎‎‏‎"</string>
- <string name="hotseat_edu_message_migrate_alt" msgid="3042360119039646356">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‎‏‎‏‎‎‎‏‏‏‎‎‎‏‎‏‎‎‎‏‎‎‏‏‎‏‎‎‎‏‎‏‏‏‏‏‎‎‎‏‎‏‏‎‎‎‏‎‏‏‎‏‎‏‎‎‏‎‏‎‎‎Easily access your most-used apps, right on the Home screen. Suggestions will change based on your routines. Apps on the bottom row will move to a new folder.‎‏‎‎‏‎"</string>
- <string name="hotseat_edu_accept" msgid="1611544083278999837">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‎‏‏‎‏‏‎‎‏‎‏‏‏‎‏‎‏‎‏‏‎‏‎‏‏‎‎‏‏‏‎‎‎‏‎‏‏‏‏‏‎‏‏‏‎‏‎‎‎‏‏‎‎‎‏‎‎‎‏‏‏‎‏‎Get app suggestions‎‏‎‎‏‎"</string>
- <string name="hotseat_edu_dismiss" msgid="2781161822780201689">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‎‎‏‏‎‏‎‎‏‏‎‎‎‏‎‏‎‏‎‏‏‏‏‏‏‎‎‎‏‎‏‎‎‏‏‎‏‏‎‏‏‎‎‎‏‎‎‎‏‏‎‏‎‏‏‎‏‏‎‎‏‎No thanks‎‏‎‎‏‎"</string>
- <string name="hotseat_prediction_settings" msgid="6246554993566070818">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‎‏‎‏‏‎‏‎‏‏‎‎‎‎‎‎‏‏‏‎‎‎‏‎‏‎‏‎‏‏‏‏‎‎‎‏‎‏‎‏‏‏‎‎‏‎‏‎‏‏‏‎‎‎‎‎‏‎‎‎‏‎‎Settings‎‏‎‎‏‎"</string>
- <string name="hotseat_auto_enrolled" msgid="522100018967146807">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‎‏‏‏‏‏‎‎‏‏‏‏‏‎‏‏‎‏‏‏‏‏‎‎‏‏‎‎‏‏‎‏‏‏‎‏‏‏‏‏‎‎‎‎‏‎‏‏‏‏‎‎‎‏‎‎‏‏‎‏‏‏‎Most-used apps appear here, and change based on routines‎‏‎‎‏‎"</string>
- <string name="hotseat_tip_no_empty_slots" msgid="1325212677738179185">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‎‏‏‎‎‏‎‎‏‏‎‎‏‎‎‎‎‎‏‏‎‎‏‏‏‏‎‏‎‎‎‏‎‏‏‏‏‎‎‎‏‏‎‏‏‎‏‏‎‏‎‏‎‏‎‎‏‏‏‎‎‎‏‎Drag apps off the bottom row to get app suggestions‎‏‎‎‏‎"</string>
- <string name="hotseat_tip_gaps_filled" msgid="3035673010274223538">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‎‏‎‏‎‎‎‏‎‎‎‎‎‏‏‏‎‎‎‎‎‏‎‎‎‎‏‎‎‏‏‏‎‎‏‏‏‏‎‏‎‎‎‏‎‏‏‎‎‎‏‎‏‏‎‏‏‎‎‏‎‎App suggestions added to empty space‎‏‎‎‏‎"</string>
- <string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‎‏‏‏‏‏‎‏‏‏‏‏‏‏‏‎‎‏‎‏‏‎‏‏‏‎‏‏‏‏‏‎‏‎‏‏‎‎‏‎‏‏‏‏‏‎‎‏‎‎‎‏‏‏‏‎‏‎‎‎‎‏‎‎App suggestions enabled‎‏‎‎‏‎"</string>
- <string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‎‏‏‎‏‎‎‏‏‏‎‎‏‏‏‏‏‏‎‎‏‏‎‏‎‏‏‏‏‎‎‏‏‎‎‏‎‎‏‎‏‎‏‎‎‏‏‏‎‎‏‎‏‎‏‎‎‏‏‏‎‏‏‎App suggestions are disabled‎‏‎‎‏‎"</string>
- <string name="hotseat_prediction_content_description" msgid="4582028296938078419">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‏‏‏‏‏‏‎‎‏‎‏‏‎‏‎‏‎‎‎‏‎‎‏‏‏‎‏‎‏‏‎‎‏‏‏‎‏‏‏‎‎‏‎‎‎‎‏‎‎‎‎‎‎‏‏‎‏‎‎‏‏‎Predicted app: ‎‏‎‎‏‏‎<xliff:g id="TITLE">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‎‏‏‎‏‏‏‏‏‎‎‎‎‎‎‏‏‏‏‏‏‎‎‏‎‎‏‏‎‎‎‏‏‏‎‏‎‏‎‏‎‎‏‏‏‎‏‎‏‏‎‏‎‎‎‏‏‎‎‎‎‏‎‎Make sure you swipe from the far-right or far-left edge.‎‏‎‎‏‎"</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‎‏‏‎‏‎‏‏‏‎‎‎‎‏‏‏‏‎‎‎‏‏‏‏‎‏‎‎‏‎‏‎‎‎‏‎‏‎‏‎‎‎‎‏‏‎‏‏‏‏‎‎‏‏‎‎‎‎‎‎‎‎Make sure you swipe from the right or left edge to the middle of the screen and let go.‎‏‎‎‏‎"</string>
- <string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‎‏‎‏‏‎‎‏‎‎‎‏‏‏‏‏‏‏‎‎‎‏‏‎‏‎‏‏‎‏‎‎‏‎‎‎‏‎‎‏‏‏‎‏‎‏‏‏‏‏‎‎‎‏‏‏‎You learned how to swipe from the right to go back. Next up, learn how to switch apps.‎‏‎‎‏‎"</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‎‏‏‎‎‎‏‏‏‎‎‏‎‏‎‏‏‏‎‎‎‎‎‏‏‎‎‏‎‎‎‏‏‎‏‏‏‏‎‎‎‏‎‏‎‏‎‏‏‎‏‎‏‏‎‏‏‎‎‏‏‎‎You completed the go back gesture.‎‏‎‎‏‎"</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‎‎‏‏‏‏‏‏‏‎‏‏‏‏‎‎‏‏‏‎‎‎‎‏‏‎‏‏‎‎‎‎‏‎‎‎‏‎‏‎‎‏‎‎‏‎‎‏‎‏‏‎‎‏‎‎‎‎‏‎‏‏‎Make sure you don\'t swipe too close to the bottom of the screen.‎‏‎‎‏‎"</string>
- <string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‎‎‎‏‏‏‏‏‏‎‎‏‏‏‏‎‏‏‎‎‎‏‏‏‎‏‎‎‎‏‏‏‏‏‎‏‏‏‎‏‎‏‎‎‏‎‏‎‎‏‏‏‏‏‎‎‏‎‎‎‏‎‎To change the sensitivity of the back gesture, go to Settings‎‏‎‎‏‎"</string>
- <string name="back_gesture_intro_title" msgid="19551256430224428">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‎‏‏‏‏‎‎‎‏‎‏‎‏‏‏‎‏‎‏‏‏‎‎‎‎‏‏‏‎‎‏‏‏‏‎‎‏‏‎‏‏‏‏‏‎‏‎‎‏‎‎‎‎‏‎‏‏‎‎‎Swipe to go back‎‏‎‎‏‎"</string>
- <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‏‎‏‏‎‏‏‏‎‎‏‏‏‏‎‎‎‏‏‏‏‎‎‏‏‎‎‎‏‏‏‎‎‎‎‎‎‏‎‎‏‏‏‎‎‎‎‏‏‎‎‎‏‏‏‎‏‎‏‏‎‏‎To go back to the last screen, swipe from the left or right edge to the middle of the screen.‎‏‎‎‏‎"</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‎‏‏‎‏‎‎‎‎‎‏‎‎‏‏‏‏‏‏‏‎‎‏‎‏‎‏‏‏‏‏‏‏‏‏‏‏‏‎‏‎‏‏‏‏‎‎‏‏‏‎‏‏‏‎‏‏‎‏‎‎‏‎‎Make sure you swipe up from the bottom edge of the screen.‎‏‎‎‏‎"</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‎‏‏‎‏‎‏‏‎‎‏‏‏‎‏‎‏‏‎‏‏‏‏‏‏‎‎‎‏‏‎‏‎‎‏‏‎‎‎‏‏‎‎‎‏‏‎‎‎‏‏‎‎‎‏‎‏‏‏‎‏‎‏‎Make sure you don\'t pause before letting go.‎‏‎‎‏‎"</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‏‎‎‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‎‏‏‎‎‏‎‏‎‏‏‏‎‏‎‎‏‎‎‏‏‎‏‎‎‏‎‎‏‏‏‏‎‎‎‎‏‎‏‏‏‏‎‎Make sure you swipe straight up.‎‏‎‎‏‎"</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‎‏‏‎‎‏‏‏‏‎‏‎‎‎‎‏‏‎‏‎‎‏‎‎‎‎‎‏‎‏‏‏‎‏‏‏‏‎‎‏‎‏‏‏‏‏‏‏‏‎‎‎‏‎‏‏‎‏‎‏‎‏‎‎You completed the go Home gesture. Next up, learn how to go back.‎‏‎‎‏‎"</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‏‎‏‏‏‏‏‎‏‏‎‏‎‎‎‎‏‎‎‏‎‏‎‏‎‏‎‏‏‎‎‏‎‏‏‏‎‎‏‎‎‏‏‎‏‎‎‎‎‎‏‏‎‎‏‏‏‏‏‎‏‎‎You completed the go Home gesture.‎‏‎‎‏‎"</string>
- <string name="home_gesture_intro_title" msgid="836590312858441830">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‎‎‏‎‏‏‏‎‎‏‏‏‎‎‎‎‏‎‏‎‏‎‎‏‏‏‎‏‎‏‎‎‎‎‎‏‎‎‎‏‏‏‎‏‎‏‏‏‎‏‏‎‎‎‎‏‏‎‎‏‏‎‎Swipe to go home‎‏‎‎‏‎"</string>
- <string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‎‏‎‏‏‏‎‎‏‏‎‎‏‎‎‎‎‏‎‎‎‎‎‎‏‏‏‏‎‏‏‎‎‏‏‎‎‎‎‎‎‏‏‏‏‎‎Swipe up from the bottom of your screen. This gesture always takes you to the Home screen.‎‏‎‎‏‎"</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‎‏‎‏‎‎‎‎‏‎‏‏‎‏‎‎‎‎‏‎‏‎‎‏‏‏‏‎‏‎‏‏‏‎‏‏‎‏‎‏‏‎‎‏‏‎‏‏‎‏‏‎‎‏‎‎‎‏‎‎‏‎Make sure you swipe up from the bottom edge of the screen.‎‏‎‎‏‎"</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‎‏‏‎‎‏‏‏‎‎‏‎‏‎‏‎‏‎‏‏‎‎‎‎‎‏‎‎‎‏‏‏‏‎‏‏‏‏‏‏‏‏‎‎‏‏‎‎‎‏‎‎‏‏‎‏‎‎‎‏‎‎‏‎Try holding the window for longer before releasing.‎‏‎‎‏‎"</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‎‏‏‏‎‏‎‏‎‏‎‏‏‎‏‏‏‎‏‎‏‎‎‎‎‏‏‏‎‎‎‏‎‏‎‎‏‏‏‎‎‏‎‏‏‎‎‎‏‎‏‎‎‎‎‎‎‏‎‏‎‏‎Make sure you swipe straight up, then pause.‎‏‎‎‏‎"</string>
- <string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‏‎‎‎‏‎‎‏‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‏‎‏‏‎‎‎‎‎‎‎‏‎‎‏‏‎‎‏‏‎‎‏‎‏‏‏‎‏‎‎‏‎‎‎‏‎‎You learned how to use gestures. To turn off gestures, go to Settings.‎‏‎‎‏‎"</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‎‏‏‎‎‎‏‏‎‎‏‏‎‏‏‎‏‏‎‏‏‏‏‎‎‎‎‎‎‎‎‎‏‏‏‎‎‎‏‎‎‏‏‎‏‏‏‎‎‎‏‏‏‎‎‎‏‎‎‎‎‎You completed the switch apps gesture.‎‏‎‎‏‎"</string>
- <string name="overview_gesture_intro_title" msgid="2902054412868489378">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‎‏‎‎‎‎‏‎‎‎‏‏‎‎‎‏‎‏‎‏‏‎‎‎‏‏‏‎‎‏‏‎‏‏‏‎‏‏‏‏‎‎‎‎‏‏‎‎‏‎‎‎‎‏‎‏‎‎‎‏‎‎Swipe to switch apps‎‏‎‎‏‎"</string>
- <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‎‎‎‏‎‎‏‏‏‏‎‎‏‎‎‎‏‏‎‏‎‎‎‏‏‏‎‏‎‎‏‏‏‎‎‏‏‎‏‏‏‎‎‏‏‏‎‏‎‏‏‎‏‎‏‏‏‎‏‎‏‏‎To switch between apps, swipe up from the bottom of your screen, hold, then release.‎‏‎‎‏‎"</string>
- <string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‎‏‎‏‏‎‎‎‎‏‎‎‎‎‎‎‏‏‎‏‏‎‎‎‎‏‏‏‎‎‎‏‎‎‏‎‏‏‎‏‎‏‎‏‎‏‏‏‎‏‎‏‏‏‎‏‏‎‏‏‎‎‎All set‎‏‎‎‏‎"</string>
- <string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‎‏‎‏‏‎‏‎‏‏‏‎‏‏‏‏‏‎‏‎‏‎‎‎‎‏‏‎‏‏‏‏‎‎‏‎‏‎‏‎‏‎‎‎‏‎‎‎‎‏‎‏‏‏‎‎‎‏‏‎‏‎‎Done‎‏‎‎‏‎"</string>
- <string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‎‏‎‎‎‏‎‎‏‎‎‏‎‏‏‎‎‏‎‎‏‏‏‎‏‏‎‏‎‎‏‏‎‎‎‏‎‏‏‏‎‏‎‏‎‏‏‎‏‏‏‏‏‏‏‎‎‏‏‎‎‎Settings‎‏‎‎‏‎"</string>
- <string name="gesture_tutorial_try_again" msgid="65962545858556697">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‎‎‎‏‏‏‎‏‎‏‎‎‏‎‏‏‎‎‎‏‎‎‏‎‏‏‎‎‎‎‎‎‎‏‎‎‏‏‎‎‎‎‏‎‎‏‏‎‎‏‏‎‎‎‏‏‎‎‏‎Try again‎‏‎‎‏‎"</string>
- <string name="gesture_tutorial_nice" msgid="2936275692616928280">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‎‏‎‎‎‏‎‏‏‏‏‏‏‏‎‏‏‏‏‏‏‎‎‏‎‏‏‏‏‎‏‏‏‎‏‎‏‎‎‎‎‏‎‏‏‏‏‎‎‏‏‎‎‎‎‎‏‏‎‎‎‎Nice!‎‏‎‎‏‎"</string>
- <string name="gesture_tutorial_step" msgid="1279786122817620968">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‎‏‏‎‎‎‏‏‏‎‎‎‎‏‎‏‎‏‏‎‏‏‎‏‎‏‏‎‎‏‎‏‎‏‏‎‏‏‏‎‎‎‎‎‏‎‎‏‏‎‎‏‎‏‏‏‏‏‎‏‎‎‎‎Tutorial ‎‏‎‎‏‏‎<xliff:g id="CURRENT">%1$d</xliff:g>‎‏‎‎‏‏‏‎/‎‏‎‎‏‏‎<xliff:g id="TOTAL">%2$d</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
- <string name="allset_title" msgid="5021126669778966707">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‎‎‎‏‎‏‏‎‏‎‏‏‏‎‏‎‏‎‎‎‎‎‎‎‎‏‏‎‏‎‎‏‏‎‎‏‎‎‎‏‏‎‏‎‏‎‎‏‎‏‏‎‎‎‏‎‏‏‎‎‏‏‎All set!‎‏‎‎‏‎"</string>
- <string name="allset_hint" msgid="2384632994739392447">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‎‎‎‎‏‎‎‎‏‎‏‏‏‏‏‏‎‏‎‏‏‎‎‎‏‎‎‏‏‎‎‎‎‏‎‏‏‎‎‎‏‏‏‏‎‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‏‎Swipe up to go Home‎‏‎‎‏‎"</string>
- <string name="allset_description" msgid="6350320429953234580">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‎‏‏‎‎‎‎‎‏‎‎‎‎‎‏‏‎‏‏‏‏‎‏‏‎‎‏‎‎‏‎‎‎‏‏‏‎‏‎‏‎‎‎‏‎‎‏‎‏‏‎‏‏‎‏‎‎‏‎‏‎‎‎You’re ready to start using your phone‎‏‎‎‏‎"</string>
- <string name="allset_navigation_settings" msgid="4713404605961476027">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‎‎‎‎‎‏‎‏‏‎‏‎‎‏‎‏‏‎‎‎‎‎‏‎‎‎‎‏‎‎‎‎‏‏‎‏‎‏‎‎‎‎‎‏‏‎‎‎‎‏‎‏‏‏‏‎‏‏‏‎‏‏‎‎‏‎‎‏‏‎"<annotation id="link">"‎‏‎‎‏‏‏‎System navigation settings‎‏‎‎‏‏‎"</annotation>"‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
- <string name="action_share" msgid="2648470652637092375">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‎‎‏‎‎‏‏‎‎‎‎‎‏‎‏‎‎‎‎‏‎‎‎‎‎‎‏‏‎‏‏‎‎‎‎‎‎‎‏‏‏‏‎‏‏‎‎‎‏‏‎‏‎‎‎‎‏‎‏‏‏‎Share‎‏‎‎‏‎"</string>
- <string name="action_screenshot" msgid="8171125848358142917">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‏‏‎‎‎‏‎‏‏‎‎‏‎‏‏‎‏‎‏‎‏‏‏‎‏‎‏‎‏‎‏‎‏‎‎‏‏‎‎‏‏‎‎‏‏‎‎‏‎‎‎‎‏‏‏‏‎‎‎‏‎‏‎Screenshot‎‏‎‎‏‎"</string>
- <string name="action_split" msgid="2098009717623550676">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‎‏‏‏‏‎‏‎‎‎‏‏‏‎‏‏‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‏‏‏‏‎‎‏‎‎‏‎‎‎‏‎‎‏‏‏‏‎‎‏‎‏‏‎‏‎‏‎‎‎Split‎‏‎‎‏‎"</string>
- <string name="toast_split_select_app" msgid="5453865907322018352">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‎‎‏‎‏‏‏‎‏‏‎‎‎‎‎‎‎‎‎‏‏‎‎‎‏‎‎‏‎‏‏‎‎‏‏‎‏‎‏‎‎‎‏‎‏‎‏‏‎‏‏‎‏‎‎‎‏‏‎‎‎‎‎Tap another app to use splitscreen‎‏‎‎‏‎"</string>
- <string name="toast_split_app_unsupported" msgid="3271526028981899666">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‎‏‏‎‏‎‏‏‎‎‏‏‎‏‏‎‎‏‎‏‏‏‎‎‏‎‏‏‏‎‎‎‎‏‏‏‎‏‏‏‎‏‎‎‏‎‎‎‏‎‎‎‏‏‎‎‏‎‎‏‎‎App does not support split-screen.‎‏‎‎‏‎"</string>
- <string name="blocked_by_policy" msgid="2071401072261365546">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‎‏‏‏‏‎‎‏‎‏‏‏‏‏‏‎‎‎‏‏‎‎‎‎‏‎‎‏‏‎‎‏‏‏‎‏‎‏‏‏‎‎‎‎‎‎‎‎‏‏‏‏‏‏‏‎‎‏‎‏‎‏‎‎This action isn\'t allowed by the app or your organization‎‏‎‎‏‎"</string>
- <string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‎‎‏‎‏‏‏‎‏‎‎‏‏‎‏‏‎‏‏‏‎‎‎‎‎‎‎‏‏‏‎‎‏‏‎‏‏‎‏‏‎‎‎‎‎‏‎‎‏‏‎‎‏‎‎‏‏‏‎‏‎‎Skip navigation tutorial?‎‏‎‎‏‎"</string>
- <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‎‏‏‏‏‏‏‎‎‎‏‏‎‎‏‏‏‎‎‏‏‎‏‎‏‏‎‏‏‎‎‏‏‎‏‏‏‏‏‏‏‏‏‎‎‎‎‎‎‏‏‏‏‏‎‏‎‎‏‏‏‎‎You can find this later in the ‎‏‎‎‏‏‎<xliff:g id="NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ app‎‏‎‎‏‎"</string>
- <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‏‎‏‎‎‏‏‎‏‏‏‏‏‎‏‎‎‎‏‏‏‏‎‏‎‎‎‎‏‏‎‏‎‎‏‎‎‎‏‎‏‎‏‏‏‏‏‏‏‎‏‏‏‎‏‏‎‏‏‎‎‎Cancel‎‏‎‎‏‎"</string>
- <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‎‏‏‏‎‏‎‏‏‏‏‎‎‏‎‏‏‎‎‎‎‎‏‎‏‏‎‎‏‏‎‎‏‎‏‎‎‏‏‏‏‎‎‎‏‎‏‎‎‎‎‎‏‎‏‎‎‏‏‎‎‎‎Skip‎‏‎‎‏‎"</string>
- <string name="accessibility_rotate_button" msgid="4771825231336502943">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‎‎‎‎‏‎‎‎‏‏‏‎‎‎‏‏‏‎‏‏‎‏‏‏‎‎‎‏‎‎‎‎‎‎‎‏‎‎‎‎‎‎‏‏‏‎‏‏‏‏‎‏‏‎‏‎‎‏‏‏‏‏‎Rotate screen‎‏‎‎‏‎"</string>
- <string name="taskbar_edu_opened" msgid="3950252793551919129">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‏‎‏‏‎‏‏‎‏‎‎‏‎‎‎‎‏‏‏‎‏‏‏‏‏‏‏‎‎‏‎‎‎‎‏‎‎‏‎‏‎‏‎‎‎‎‎‎‏‏‎‎‎‎‎‎‏‏‎‎‏‎Taskbar education appeared‎‏‎‎‏‎"</string>
- <string name="taskbar_edu_closed" msgid="126643734478892862">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‎‎‏‏‏‏‎‎‎‎‎‏‏‏‏‎‏‏‎‏‏‏‎‎‏‏‏‎‎‎‏‏‎‏‏‎‏‎‏‎‎‏‎‎‏‎‏‎‏‏‏‏‎‎‏‏‏‏‏‎‎Taskbar education closed‎‏‎‎‏‎"</string>
- <string name="taskbar_edu_switch_apps" msgid="6942863327845784813">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‏‎‎‎‎‎‎‏‎‏‏‎‏‎‎‎‎‎‎‎‎‏‎‏‏‎‏‎‎‏‎‏‏‎‏‏‎‎‎‏‎‏‎‏‎‏‏‎‎‏‏‏‎‎‏‏‏‎‏‏‎‏‎Use the taskbar to switch apps‎‏‎‎‏‎"</string>
- <string name="taskbar_edu_splitscreen" msgid="2663361731630346489">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‎‎‏‎‎‏‏‏‏‎‏‏‎‎‎‏‎‏‎‎‏‎‏‏‎‎‎‏‎‎‏‎‎‎‎‏‎‎‎‏‏‎‎‏‎‎‎‏‏‎‎‎‎‏‏‏‏‏‎‎‏‎Drag to the side to use two apps at once‎‏‎‎‏‎"</string>
- <string name="taskbar_edu_stashing" msgid="5212374387411764031">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‎‎‏‎‎‎‎‏‎‏‎‏‏‎‎‎‎‏‎‎‏‎‏‏‏‎‎‎‏‏‏‎‎‏‎‏‏‎‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‏‎‎‏‏‏‏‏‏‎Touch &amp; hold to hide the taskbar‎‏‎‎‏‎"</string>
- <string name="taskbar_edu_next" msgid="4007618274426775841">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‏‎‏‏‏‏‎‎‏‏‏‎‏‏‏‏‎‏‎‏‏‏‎‎‏‎‏‏‎‎‏‎‏‏‎‏‎‏‎‎‏‎‎‏‎‎‏‏‎‏‎‎‏‎‎‏‎‎‎‎‏‎Next‎‏‎‎‏‎"</string>
- <string name="taskbar_edu_previous" msgid="459202320127201702">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‎‏‏‏‏‎‎‏‎‏‏‏‏‏‎‏‏‎‏‎‏‎‎‎‎‏‎‎‏‏‏‏‎‎‎‎‏‏‎‎‏‏‎‏‏‏‏‎‎‏‎‎‎‏‏‎‏‎‎‏‏‎‎Back‎‏‎‎‏‎"</string>
- <string name="taskbar_edu_close" msgid="887022990168191073">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‎‎‏‏‎‎‎‏‎‎‏‏‏‏‎‏‎‏‎‏‏‎‏‎‏‏‎‏‎‏‏‎‏‏‏‏‎‎‏‎‎‏‎‏‎‎‎‏‏‏‎‎‎‎‎‏‏‎‎‎‎‏‎Close‎‏‎‎‏‎"</string>
- <string name="taskbar_edu_done" msgid="6880178093977704569">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‎‏‏‏‏‏‎‏‏‏‏‎‏‏‎‏‎‎‏‏‎‏‏‎‎‎‎‏‏‎‎‎‎‏‎‎‏‎‏‏‏‏‎‏‏‏‎‎‎‏‏‎‎‎‎‏‏‏‏‎‎‏‎Done‎‏‎‎‏‎"</string>
- <string name="taskbar_button_home" msgid="2151398979630664652">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‎‏‏‏‏‎‏‏‏‎‏‏‎‏‏‎‏‎‎‏‏‎‏‏‏‏‏‏‎‎‏‎‎‏‎‏‏‏‏‎‎‎‎‎‏‏‎‎‎‎‎‏‎‏‏‏‏‎‎‏‏‎‎‎Home‎‏‎‎‏‎"</string>
- <string name="taskbar_button_a11y" msgid="5241161324875094465">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‎‎‏‎‎‎‏‎‏‏‏‏‎‎‎‏‎‏‏‎‎‎‎‏‏‏‎‏‎‎‏‏‎‎‎‎‏‏‏‎‏‏‎‎‏‎‎‎‎‏‏‎‎‏‏‏‎‎‎‎‎‏‎Accessibility‎‏‎‎‏‎"</string>
- <string name="taskbar_button_back" msgid="8558862226461164514">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‏‏‎‏‏‎‏‏‎‎‎‏‏‏‎‎‏‎‏‏‏‏‏‏‎‏‏‎‎‏‎‎‏‎‎‎‎‏‏‎‏‏‏‎‏‎‎‎‎‎‎‎‏‏‏‏‏‎‎‎‏‎‎Back‎‏‎‎‏‎"</string>
- <string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‎‏‏‏‎‎‎‎‎‎‎‎‎‏‏‎‎‎‏‎‎‎‎‎‎‎‏‎‏‎‎‎‎‏‏‏‎‏‎‏‎‎‎‎‏‎‏‎‎‎‎‎‎‏‏‏‎‏‏‏‏‎‏‎IME switcher‎‏‎‎‏‎"</string>
- <string name="taskbar_button_recents" msgid="7273376136216613134">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‏‎‎‏‎‎‏‏‏‏‎‎‎‎‎‎‏‏‏‎‎‏‎‎‎‎‏‏‏‏‎‏‎‏‎‏‎‎‏‏‏‏‏‏‏‎‏‎‎‏‎‎‎‏‎‎‎‎‏‏‏‎‎Recents‎‏‎‎‏‎"</string>
- <string name="taskbar_button_notifications" msgid="7471740351507357318">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‏‎‎‏‏‏‏‎‏‏‎‎‎‎‏‏‏‏‎‏‎‎‎‏‎‎‎‎‏‏‎‏‎‎‎‎‎‏‏‎‎‎‏‏‎‎‎‏‎‏‏‏‏‎‏‎‎‎‎‏‏‎‎Notifications‎‏‎‎‏‎"</string>
- <string name="taskbar_button_quick_settings" msgid="227662894293189391">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‎‏‎‏‏‎‎‏‎‏‎‎‎‏‏‎‏‎‎‏‎‎‎‏‏‎‎‏‎‎‎‏‏‎‏‏‎‏‏‏‎‎‎‏‎‎‎‎‎‎‎‏‏‎‎‎‎‏‏‏‏‎Quick Settings‎‏‎‎‏‎"</string>
- <string name="move_drop_target_top_or_left" msgid="2988702185049595807">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‎‏‎‎‏‎‏‏‏‏‎‏‎‎‎‎‎‎‎‎‎‏‏‎‎‏‏‎‏‎‏‏‎‏‏‏‏‎‏‎‏‎‎‎‎‏‎‎‏‏‏‏‏‏‎‎‏‏‏‏‏‎Move to top/left‎‏‎‎‏‎"</string>
- <string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‎‎‏‎‏‏‎‏‏‎‎‎‎‎‎‎‏‎‏‏‏‏‏‎‎‎‏‎‎‏‏‎‏‎‎‎‏‎‏‏‎‏‎‎‏‏‏‎‎‏‏‎‏‏‏‏‎‎‎‎‏‎‎Move to bottom/right‎‏‎‎‏‎"</string>
-</resources>
diff --git a/quickstep/res/values-es-rUS/strings.xml b/quickstep/res/values-es-rUS/strings.xml
index 69b6015a2a..5f5d0bdfe9 100644
--- a/quickstep/res/values-es-rUS/strings.xml
+++ b/quickstep/res/values-es-rUS/strings.xml
@@ -19,91 +19,19 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Pantalla dividida"</string>
<string name="recent_task_option_pin" msgid="7929860679018978258">"Fijar"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Formato libre"</string>
+ <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Recientes"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"No hay elementos recientes"</string>
+ <string name="accessibility_close_task" msgid="5354563209433803643">"Cerrar"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Configuración de uso de la app"</string>
<string name="recents_clear_all" msgid="5328176793634888831">"Borrar todo"</string>
<string name="accessibility_recent_apps" msgid="4058661986695117371">"Apps recientes"</string>
- <string name="task_view_closed" msgid="9170038230110856166">"Se cerró la tarea"</string>
<string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g> (<xliff:g id="REMAINING_TIME">%2$s</xliff:g>)"</string>
<string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 minuto"</string>
<string name="time_left_for_app" msgid="3111996412933644358">"Tiempo restante: <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <string name="title_app_suggestions" msgid="4185902664111965088">"Sugerencias de aplicaciones"</string>
+ <string name="title_app_suggestions" msgid="4185902664111965088">"Sugerencias de apps"</string>
+ <string name="all_apps_label" msgid="8542784161730910663">"Todas las apps"</string>
<string name="all_apps_prediction_tip" msgid="2672336544844936186">"Predicción de tus apps"</string>
- <string name="hotseat_edu_title_migrate" msgid="306578144424489980">"Obtén sugerencias de aplicaciones en la fila inferior de la pantalla principal"</string>
- <string name="hotseat_edu_title_migrate_landscape" msgid="3633942953997845243">"Obtén sugerencias de apps en la fila de favoritos de la pantalla principal"</string>
- <string name="hotseat_edu_message_migrate" msgid="8927179260533775320">"Accede fácilmente en la pantalla principal a las apps que más usas. Las sugerencias cambiarán según tus rutinas. Las apps de la fila inferior se desplazarán hacia arriba en la pantalla principal."</string>
- <string name="hotseat_edu_message_migrate_landscape" msgid="4248943380443387697">"Accede fácilmente en la pantalla principal a las apps que más usas. Las sugerencias cambiarán según tus rutinas. Se moverán a la pantalla principal las apps que estén en la fila de favoritos."</string>
- <string name="hotseat_edu_message_migrate_alt" msgid="3042360119039646356">"Accede fácilmente a las apps que más usas en la pantalla principal. Las sugerencias cambiarán según tus rutinas. Las apps de la fila inferior se moverán a una nueva carpeta."</string>
- <string name="hotseat_edu_accept" msgid="1611544083278999837">"Obtén sugerencias de aplicaciones"</string>
- <string name="hotseat_edu_dismiss" msgid="2781161822780201689">"No, gracias"</string>
- <string name="hotseat_prediction_settings" msgid="6246554993566070818">"Configuración"</string>
- <string name="hotseat_auto_enrolled" msgid="522100018967146807">"Las apps que más se usan se muestran aquí y cambian según las rutinas"</string>
- <string name="hotseat_tip_no_empty_slots" msgid="1325212677738179185">"Arrastra apps fuera de la fila inferior para obtener sugerencias"</string>
- <string name="hotseat_tip_gaps_filled" msgid="3035673010274223538">"Se agregaron sugerencias de aplicaciones a un espacio vacío"</string>
- <string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Sugerencias de apps habilitadas"</string>
- <string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Las sugerencias de aplicaciones están inhabilitadas"</string>
- <string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Predicción de app: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Asegúrate de deslizar desde el extremo derecho o izquierdo."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Asegúrate de deslizar desde borde izquierdo o derecho hacia centro de la pantalla y, luego, soltar."</string>
- <string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Aprendiste a deslizar el dedo desde la derecha para volver. Ahora, descubre cómo cambiar de app."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"Completaste el gesto \"Atrás\"."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Asegúrate de no hacerlo muy cerca de la parte inferior de la pantalla."</string>
- <string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"Cambia sensibilidad de gesto \"Atrás\" en Configuración"</string>
- <string name="back_gesture_intro_title" msgid="19551256430224428">"Desliza el dedo para volver"</string>
- <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"Desliza el dedo desde el borde derecho o izquierdo para volver a la última pantalla."</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Desliza el dedo hacia arriba desde el borde inferior de la pantalla."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Asegúrate de no detenerte antes de soltarlo."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Desliza el dedo directamente hacia arriba."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"Completaste el gesto para ir a la página principal. A continuación, obtén información para volver."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"Completaste el gesto para ir a la página principal."</string>
- <string name="home_gesture_intro_title" msgid="836590312858441830">"Desliza el dedo para ir a la página principal"</string>
- <string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Desliza el dedo hacia arriba desde la parte inferior de la pantalla. Este gesto te llevará siempre a la pantalla principal."</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Desliza el dedo hacia arriba desde el borde inferior de la pantalla."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Prueba mantener presionada la ventana más tiempo antes de soltarla."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Desliza el dedo directamente hacia arriba y luego detente."</string>
- <string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Ya sabes cómo usar los gestos. Para desactivarlos, ve a Configuración."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"Completaste el gesto para cambiar de app."</string>
- <string name="overview_gesture_intro_title" msgid="2902054412868489378">"Desliza el dedo para cambiar de app"</string>
- <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Para cambiar de app, desliza hacia arriba desde parte inferior, mantén presionado y, luego, suelta."</string>
- <string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"Listo"</string>
- <string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Listo"</string>
- <string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Configuración"</string>
- <string name="gesture_tutorial_try_again" msgid="65962545858556697">"Reintentar"</string>
- <string name="gesture_tutorial_nice" msgid="2936275692616928280">"¡Genial!"</string>
- <string name="gesture_tutorial_step" msgid="1279786122817620968">"Instructivo <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
- <string name="allset_title" msgid="5021126669778966707">"Todo listo"</string>
- <string name="allset_hint" msgid="2384632994739392447">"Desliza el dedo hacia arriba para ir a la pantalla principal"</string>
- <string name="allset_description" msgid="6350320429953234580">"Ya puedes empezar a usar tu teléfono"</string>
- <string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"Configuración de navegación del sistema"</annotation></string>
- <string name="action_share" msgid="2648470652637092375">"Compartir"</string>
- <string name="action_screenshot" msgid="8171125848358142917">"Captura de pantalla"</string>
- <string name="action_split" msgid="2098009717623550676">"Pantalla dividida"</string>
- <string name="toast_split_select_app" msgid="5453865907322018352">"Presiona otra app para usar la pantalla dividida"</string>
- <string name="toast_split_app_unsupported" msgid="3271526028981899666">"La app no es compatible con la función de pantalla dividida."</string>
- <string name="blocked_by_policy" msgid="2071401072261365546">"La app o tu organización no permiten realizar esta acción"</string>
- <string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"¿Omitir el instructivo de navegación?"</string>
- <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Puedes encontrarlo en la app de <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Cancelar"</string>
- <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Omitir"</string>
- <string name="accessibility_rotate_button" msgid="4771825231336502943">"Girar pantalla"</string>
- <string name="taskbar_edu_opened" msgid="3950252793551919129">"Se abrió la barra de herramientas Educación"</string>
- <string name="taskbar_edu_closed" msgid="126643734478892862">"Se cerró la barra de herramientas Educación"</string>
- <string name="taskbar_edu_switch_apps" msgid="6942863327845784813">"Usa la barra de tareas para cambiar de app"</string>
- <string name="taskbar_edu_splitscreen" msgid="2663361731630346489">"Arrastra a un lado para usar dos apps a la vez"</string>
- <string name="taskbar_edu_stashing" msgid="5212374387411764031">"Mantén presionado para ocultar la barra de tareas"</string>
- <string name="taskbar_edu_next" msgid="4007618274426775841">"Siguiente"</string>
- <string name="taskbar_edu_previous" msgid="459202320127201702">"Atrás"</string>
- <string name="taskbar_edu_close" msgid="887022990168191073">"Cerrar"</string>
- <string name="taskbar_edu_done" msgid="6880178093977704569">"Listo"</string>
- <string name="taskbar_button_home" msgid="2151398979630664652">"Botón de inicio"</string>
- <string name="taskbar_button_a11y" msgid="5241161324875094465">"Accesibilidad"</string>
- <string name="taskbar_button_back" msgid="8558862226461164514">"Atrás"</string>
- <string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"Botón de IME"</string>
- <string name="taskbar_button_recents" msgid="7273376136216613134">"Recientes"</string>
- <string name="taskbar_button_notifications" msgid="7471740351507357318">"Notificaciones"</string>
- <string name="taskbar_button_quick_settings" msgid="227662894293189391">"Config. rápida"</string>
- <string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Mover a la parte superior o izquierda"</string>
- <string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Mover a la parte inferior o derecha"</string>
</resources>
diff --git a/quickstep/res/values-es/strings.xml b/quickstep/res/values-es/strings.xml
index b5dc6e610d..329286b3bf 100644
--- a/quickstep/res/values-es/strings.xml
+++ b/quickstep/res/values-es/strings.xml
@@ -19,93 +19,19 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Dividir pantalla"</string>
<string name="recent_task_option_pin" msgid="7929860679018978258">"Fijar"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Formato libre"</string>
- <string name="recents_empty_message" msgid="7040467240571714191">"No hay nada reciente"</string>
+ <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Aplicaciones recientes"</string>
+ <string name="recents_empty_message" msgid="7040467240571714191">"No hay elementos recientes"</string>
+ <string name="accessibility_close_task" msgid="5354563209433803643">"Cerrar"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Ajustes de uso de la aplicación"</string>
<string name="recents_clear_all" msgid="5328176793634888831">"Borrar todo"</string>
<string name="accessibility_recent_apps" msgid="4058661986695117371">"Aplicaciones recientes"</string>
- <string name="task_view_closed" msgid="9170038230110856166">"Tarea cerrada"</string>
<string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g> (<xliff:g id="REMAINING_TIME">%2$s</xliff:g>)"</string>
<string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt;1 minuto"</string>
<string name="time_left_for_app" msgid="3111996412933644358">"tiempo restante: <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="title_app_suggestions" msgid="4185902664111965088">"Sugerencias de aplicaciones"</string>
+ <string name="all_apps_label" msgid="8542784161730910663">"Todas las aplicaciones"</string>
<string name="all_apps_prediction_tip" msgid="2672336544844936186">"Predicción de aplicaciones"</string>
- <string name="hotseat_edu_title_migrate" msgid="306578144424489980">"Obtén sugerencias de aplicaciones en la fila inferior de la pantalla de inicio"</string>
- <string name="hotseat_edu_title_migrate_landscape" msgid="3633942953997845243">"Recibe sugerencias de aplicaciones en la fila de aplicaciones favoritas de la pantalla de inicio"</string>
- <string name="hotseat_edu_message_migrate" msgid="8927179260533775320">"Accede fácilmente a las aplicaciones que más usas desde la pantalla de inicio. Las sugerencias cambiarán según tus hábitos. Las aplicaciones de la fila inferior pasarán a mostrarse en la pantalla de inicio."</string>
- <string name="hotseat_edu_message_migrate_landscape" msgid="4248943380443387697">"Accede fácilmente a las aplicaciones que más usas desde la pantalla de inicio. Las sugerencias cambiarán según tus hábitos. Las aplicaciones de la fila de aplicaciones favoritas se moverán a la pantalla de inicio."</string>
- <string name="hotseat_edu_message_migrate_alt" msgid="3042360119039646356">"Accede fácilmente a las aplicaciones que más usas desde la pantalla de inicio. Las sugerencias cambiarán según tus hábitos. Las aplicaciones de la fila inferior se pondrán en una carpeta nueva."</string>
- <string name="hotseat_edu_accept" msgid="1611544083278999837">"Sí, obtener sugerencias"</string>
- <string name="hotseat_edu_dismiss" msgid="2781161822780201689">"No, gracias"</string>
- <string name="hotseat_prediction_settings" msgid="6246554993566070818">"Ajustes"</string>
- <string name="hotseat_auto_enrolled" msgid="522100018967146807">"Las aplicaciones que más usas aparecen aquí, y van variando según tus rutinas"</string>
- <string name="hotseat_tip_no_empty_slots" msgid="1325212677738179185">"Arrastra aplicaciones de la fila inferior para ver sugerencias de aplicaciones"</string>
- <string name="hotseat_tip_gaps_filled" msgid="3035673010274223538">"Sugerencias de aplicaciones añadidas a espacios vacíos"</string>
- <string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Sugerencias de aplicaciones habilitadas"</string>
- <string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Las sugerencias de aplicaciones están inhabilitadas"</string>
- <string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Aplicación sugerida: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Desliza el dedo desde el borde derecho o izquierdo de la pantalla."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Desliza el dedo desde el borde derecho o izquierdo de la pantalla hasta el centro y luego levántalo."</string>
- <string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Ya sabes deslizar el dedo desde la derecha para ir atrás. Descubre ahora cómo cambiar de aplicación."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"Has completado el gesto para volver."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"No deslices el dedo demasiado cerca de la parte inferior de la pantalla."</string>
- <string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"Para cambiar la sensibilidad del gesto, ve a Ajustes"</string>
- <string name="back_gesture_intro_title" msgid="19551256430224428">"Desliza el dedo para volver"</string>
- <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"Para volver a la última pantalla, desliza el dedo desde un lateral de la pantalla hasta el centro."</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Desliza el dedo hacia arriba desde el borde inferior de la pantalla."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"No hagas ninguna pausa antes de levantar el dedo."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Desliza el dedo directamente hacia arriba."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"Has completado el gesto para ir a la pantalla de inicio. Ahora, descubre cómo volver."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"Has completado el gesto para ir a la pantalla de inicio."</string>
- <string name="home_gesture_intro_title" msgid="836590312858441830">"Desliza el dedo para ir a la pantalla de inicio"</string>
- <string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Desliza hacia arriba desde la parte inferior. Con este gesto, siempre irás a la pantalla de inicio."</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Desliza el dedo hacia arriba desde el borde inferior de la pantalla."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Prueba a mantener pulsada la ventana durante más tiempo antes de soltarla."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Desliza el dedo directamente hacia arriba y luego mantenlo pulsado."</string>
- <string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Ya sabes cómo utilizar gestos. Para desactivarlos, ve a Configuración."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"Has completado el gesto para cambiar de aplicación."</string>
- <string name="overview_gesture_intro_title" msgid="2902054412868489378">"Deslizar el dedo para cambiar de aplicación"</string>
- <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Para cambiar de app, desliza el dedo hacia arriba desde el borde inferior y no lo levantes enseguida."</string>
- <string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"Todo listo"</string>
- <string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Hecho"</string>
- <string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Ajustes"</string>
- <string name="gesture_tutorial_try_again" msgid="65962545858556697">"Vuélvelo a intentar"</string>
- <string name="gesture_tutorial_nice" msgid="2936275692616928280">"¡Muy bien!"</string>
- <string name="gesture_tutorial_step" msgid="1279786122817620968">"Tutorial <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
- <string name="allset_title" msgid="5021126669778966707">"¡Ya está!"</string>
- <string name="allset_hint" msgid="2384632994739392447">"Desliza el dedo hacia arriba para ir a la pantalla de inicio"</string>
- <string name="allset_description" msgid="6350320429953234580">"Ya puedes empezar a usar tu teléfono"</string>
- <string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"Ajustes de navegación del sistema"</annotation></string>
- <string name="action_share" msgid="2648470652637092375">"Compartir"</string>
- <string name="action_screenshot" msgid="8171125848358142917">"Hacer captura"</string>
- <string name="action_split" msgid="2098009717623550676">"Dividir"</string>
- <string name="toast_split_select_app" msgid="5453865907322018352">"Toca otra aplicación para usar la pantalla dividida"</string>
- <string name="toast_split_app_unsupported" msgid="3271526028981899666">"La aplicación no admite la pantalla dividida."</string>
- <string name="blocked_by_policy" msgid="2071401072261365546">"No puedes hacerlo porque la aplicación o tu organización no lo permiten"</string>
- <string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"¿Saltar tutorial de navegación?"</string>
- <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Puedes consultarlo en otro momento en la aplicación <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Cancelar"</string>
- <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Saltar"</string>
- <string name="accessibility_rotate_button" msgid="4771825231336502943">"Girar la pantalla"</string>
- <string name="taskbar_edu_opened" msgid="3950252793551919129">"Ha aparecido una nota sobre la barra de tareas"</string>
- <string name="taskbar_edu_closed" msgid="126643734478892862">"Nota sobre la barra de tareas cerrada"</string>
- <string name="taskbar_edu_switch_apps" msgid="6942863327845784813">"Usa la barra de tareas para cambiar de aplicación"</string>
- <string name="taskbar_edu_splitscreen" msgid="2663361731630346489">"Arrastra hacia un lado para usar dos aplicaciones a la vez"</string>
- <string name="taskbar_edu_stashing" msgid="5212374387411764031">"Mantén pulsada la barra de tareas para ocultarla"</string>
- <string name="taskbar_edu_next" msgid="4007618274426775841">"Siguiente"</string>
- <string name="taskbar_edu_previous" msgid="459202320127201702">"Atrás"</string>
- <string name="taskbar_edu_close" msgid="887022990168191073">"Cerrar"</string>
- <string name="taskbar_edu_done" msgid="6880178093977704569">"Hecho"</string>
- <string name="taskbar_button_home" msgid="2151398979630664652">"Inicio"</string>
- <string name="taskbar_button_a11y" msgid="5241161324875094465">"Accesibilidad"</string>
- <string name="taskbar_button_back" msgid="8558862226461164514">"Atrás"</string>
- <string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"Interruptor IME"</string>
- <string name="taskbar_button_recents" msgid="7273376136216613134">"Recientes"</string>
- <!-- no translation found for taskbar_button_notifications (7471740351507357318) -->
- <skip />
- <!-- no translation found for taskbar_button_quick_settings (227662894293189391) -->
- <skip />
- <string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Mover arriba/a la izquierda"</string>
- <string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Mover abajo/a la derecha"</string>
</resources>
diff --git a/quickstep/res/values-et/strings.xml b/quickstep/res/values-et/strings.xml
index 950263f263..0577b0f562 100644
--- a/quickstep/res/values-et/strings.xml
+++ b/quickstep/res/values-et/strings.xml
@@ -19,93 +19,19 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Jagatud ekraan"</string>
<string name="recent_task_option_pin" msgid="7929860679018978258">"Kinnita"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Vabavorm"</string>
+ <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Ülevaade"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"Hiljutisi üksusi pole"</string>
+ <string name="accessibility_close_task" msgid="5354563209433803643">"Sule"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Rakenduse kasutuse seaded"</string>
<string name="recents_clear_all" msgid="5328176793634888831">"Sule kõik"</string>
<string name="accessibility_recent_apps" msgid="4058661986695117371">"Hiljutised rakendused"</string>
- <string name="task_view_closed" msgid="9170038230110856166">"Ülesanne suleti"</string>
<string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g> <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
<string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 minut"</string>
<string name="time_left_for_app" msgid="3111996412933644358">"Tääna jäänud <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="title_app_suggestions" msgid="4185902664111965088">"Rakenduste soovitused"</string>
+ <string name="all_apps_label" msgid="8542784161730910663">"Kõik rakendused"</string>
<string name="all_apps_prediction_tip" msgid="2672336544844936186">"Teie ennustatud rakendused"</string>
- <string name="hotseat_edu_title_migrate" msgid="306578144424489980">"Hankige avakuva alumisel real rakenduste soovitusi"</string>
- <string name="hotseat_edu_title_migrate_landscape" msgid="3633942953997845243">"Hankige avakuva lemmikute reale rakenduste soovitusi"</string>
- <string name="hotseat_edu_message_migrate" msgid="8927179260533775320">"Pääsete enim kasutatavatele rakendustele hõlpsasti juurde otse avakuvalt. Soovitused muutuvad olenevalt teie rutiinist. Alumisel real olevad rakendused teisaldatakse teie avakuvale."</string>
- <string name="hotseat_edu_message_migrate_landscape" msgid="4248943380443387697">"Pääsete enim kasutatavatele rakendustele hõlpsasti juurde otse avakuvalt. Soovitused muutuvad olenevalt teie rutiinist. Lemmikute real olevad rakendused teisaldatakse teie avakuvale."</string>
- <string name="hotseat_edu_message_migrate_alt" msgid="3042360119039646356">"Pääsete enim kasutatavatele rakendustele hõlpsasti juurde otse avakuvalt. Soovitused muutuvad olenevalt teie rutiinist. Alumisel real olevad rakendused teisaldatakse uude kausta."</string>
- <string name="hotseat_edu_accept" msgid="1611544083278999837">"Hangi rakenduste soovitusi"</string>
- <string name="hotseat_edu_dismiss" msgid="2781161822780201689">"Tänan, ei"</string>
- <string name="hotseat_prediction_settings" msgid="6246554993566070818">"Seaded"</string>
- <string name="hotseat_auto_enrolled" msgid="522100018967146807">"Siin kuvatakse enim kasutatavad rakendused, mis võivad olenevalt rutiinist muutuda."</string>
- <string name="hotseat_tip_no_empty_slots" msgid="1325212677738179185">"Rakenduste soovituste hankimiseks lohistage rakendused alumiselt realt ära"</string>
- <string name="hotseat_tip_gaps_filled" msgid="3035673010274223538">"Rakenduste soovitused lisati tühjale kohale"</string>
- <string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Rakenduste soovitused on lubatud"</string>
- <string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Rakenduste soovitused on keelatud"</string>
- <string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Ennustatud rakendus: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Pühkige kindlasti parem- või vasakpoolsest servast."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Pühkige ekraanikuva paremast või vasakust servast keskele ja eemaldage sõrm."</string>
- <string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Õppisite, kuidas tagasiliikumiseks paremalt pühkida. Nüüd vaadake, kuidas rakenduste vahel vahetada."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"Tegite tagasiliikumise liigutuse."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Veenduge, et te ei pühiks liiga ekraanikuva allosa lähedalt."</string>
- <string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"Tagasiliigutuse tundlikkuse muutmiseks avage menüü Seaded"</string>
- <string name="back_gesture_intro_title" msgid="19551256430224428">"Tagasiliikumiseks pühkige"</string>
- <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"Eelmisele ekraanikuvale naasmiseks pühkige vasakust või paremast servast ekraanikuva keskele."</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Pühkige kindlasti ekraanikuva alumisest servast üles."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Veenduge, et te enne vabastamist liigutust ei peataks."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Pühkige kindlasti otse üles."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"Tegite avakuvale minemise liigutuse. Järgmisena vaadake, kuidas minna tagasi."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"Tegite avakuvale minemise liigutuse."</string>
- <string name="home_gesture_intro_title" msgid="836590312858441830">"Pühkige avakuvale minemiseks"</string>
- <string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Pühkige ekraani alaosast üles. See liigutus viib teid alati tagasi avakuvale."</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Pühkige kindlasti ekraanikuva alumisest servast üles."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Hoidke sõrme aknal pisut kauem, enne kui vabastate."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Pühkige kindlasti otse üles, seejärel peatuge."</string>
- <string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Õppisite liigutusi kasutama. Liigutuste väljalülitamiseks avage seaded."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"Tegite rakenduste vahel vahetamise liigutuse."</string>
- <string name="overview_gesture_intro_title" msgid="2902054412868489378">"Pühkige rakenduste vahetamiseks"</string>
- <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Rakenduste vahel vahetamiseks pühkige ekraanikuva alaosast üles, hoidke ja seejärel vabastage."</string>
- <string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"Valmis"</string>
- <string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Valmis"</string>
- <string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Seaded"</string>
- <string name="gesture_tutorial_try_again" msgid="65962545858556697">"Proovige uuesti"</string>
- <string name="gesture_tutorial_nice" msgid="2936275692616928280">"Tubli töö!"</string>
- <string name="gesture_tutorial_step" msgid="1279786122817620968">"Õpetus <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
- <string name="allset_title" msgid="5021126669778966707">"Valmis!"</string>
- <string name="allset_hint" msgid="2384632994739392447">"Avakuvale liikumiseks pühkige üles"</string>
- <string name="allset_description" msgid="6350320429953234580">"Olete valmis oma telefoni kasutama."</string>
- <string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"Süsteemi navigeerimisseaded"</annotation></string>
- <string name="action_share" msgid="2648470652637092375">"Jaga"</string>
- <string name="action_screenshot" msgid="8171125848358142917">"Ekraanipilt"</string>
- <string name="action_split" msgid="2098009717623550676">"Eralda"</string>
- <string name="toast_split_select_app" msgid="5453865907322018352">"Jagatud kuva kasutamiseks puudutage muud rakendust"</string>
- <string name="toast_split_app_unsupported" msgid="3271526028981899666">"Rakendus ei toeta jagatud ekraani."</string>
- <string name="blocked_by_policy" msgid="2071401072261365546">"Rakendus või teie organisatsioon on selle toimingu keelanud"</string>
- <string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Kas jätta navigeerimise õpetused vahele?"</string>
- <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Leiate selle hiljem rakendusest <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Tühista"</string>
- <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Jäta vahele"</string>
- <string name="accessibility_rotate_button" msgid="4771825231336502943">"Pöörake ekraani"</string>
- <string name="taskbar_edu_opened" msgid="3950252793551919129">"Tegumiriba juhised kuvati"</string>
- <string name="taskbar_edu_closed" msgid="126643734478892862">"Tegumiriba juhised on suletud"</string>
- <string name="taskbar_edu_switch_apps" msgid="6942863327845784813">"Kasutage rakenduste vahetamiseks tegumiriba"</string>
- <string name="taskbar_edu_splitscreen" msgid="2663361731630346489">"Kahe rakenduse korraga kasutamiseks lohistage külje poole"</string>
- <string name="taskbar_edu_stashing" msgid="5212374387411764031">"Tegumiriba peitmiseks puudutage pikalt"</string>
- <string name="taskbar_edu_next" msgid="4007618274426775841">"Järgmine"</string>
- <string name="taskbar_edu_previous" msgid="459202320127201702">"Tagasi"</string>
- <string name="taskbar_edu_close" msgid="887022990168191073">"Sule"</string>
- <string name="taskbar_edu_done" msgid="6880178093977704569">"Valmis"</string>
- <string name="taskbar_button_home" msgid="2151398979630664652">"Avaleht"</string>
- <string name="taskbar_button_a11y" msgid="5241161324875094465">"Juurdepääsetavus"</string>
- <string name="taskbar_button_back" msgid="8558862226461164514">"Tagasi"</string>
- <string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"IME vahetaja"</string>
- <string name="taskbar_button_recents" msgid="7273376136216613134">"Hiljutised"</string>
- <!-- no translation found for taskbar_button_notifications (7471740351507357318) -->
- <skip />
- <!-- no translation found for taskbar_button_quick_settings (227662894293189391) -->
- <skip />
- <string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Teisalda üles/vasakule"</string>
- <string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Teisalda alla/paremale"</string>
</resources>
diff --git a/quickstep/res/values-eu/strings.xml b/quickstep/res/values-eu/strings.xml
index 6193e359fd..c2d149e362 100644
--- a/quickstep/res/values-eu/strings.xml
+++ b/quickstep/res/values-eu/strings.xml
@@ -19,91 +19,19 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Zatitu pantaila"</string>
<string name="recent_task_option_pin" msgid="7929860679018978258">"Ainguratu"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Modu librea"</string>
+ <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Ikuspegi orokorra"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"Ez dago azkenaldi honetako ezer"</string>
+ <string name="accessibility_close_task" msgid="5354563209433803643">"Itxi"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Aplikazioen erabileraren ezarpenak"</string>
<string name="recents_clear_all" msgid="5328176793634888831">"Garbitu guztiak"</string>
<string name="accessibility_recent_apps" msgid="4058661986695117371">"Azken aplikazioak"</string>
- <string name="task_view_closed" msgid="9170038230110856166">"Itxi da zeregina"</string>
<string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g> (<xliff:g id="REMAINING_TIME">%2$s</xliff:g>)"</string>
<string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 min"</string>
<string name="time_left_for_app" msgid="3111996412933644358">"<xliff:g id="TIME">%1$s</xliff:g> gelditzen dira gaur"</string>
- <string name="title_app_suggestions" msgid="4185902664111965088">"Aplikazioen iradokizunak"</string>
- <string name="all_apps_prediction_tip" msgid="2672336544844936186">"Iradokitako aplikazioak"</string>
- <string name="hotseat_edu_title_migrate" msgid="306578144424489980">"Jaso aplikazioen iradokizunak hasierako pantailaren beheko errenkadan"</string>
- <string name="hotseat_edu_title_migrate_landscape" msgid="3633942953997845243">"Jaso aplikazioen iradokizunak hasierako pantailako gogokoen errenkadan"</string>
- <string name="hotseat_edu_message_migrate" msgid="8927179260533775320">"Atzitu erraz aplikazio erabilienak hasierako pantailatik bertatik. Ohituren arabera aldatuko dira iradokizunak. Hasierako pantailara eramango dira beheko errenkadan dauden aplikazioak."</string>
- <string name="hotseat_edu_message_migrate_landscape" msgid="4248943380443387697">"Atzitu erraz aplikazio erabilienak hasierako pantailatik bertatik. Ohituren arabera aldatuko dira iradokizunak. Gogokoen errenkadako aplikazioak hasierako pantailara eramango ditugu."</string>
- <string name="hotseat_edu_message_migrate_alt" msgid="3042360119039646356">"Atzitu erraz aplikazio erabilienak hasierako pantailatik bertatik. Ohituren arabera aldatuko dira iradokizunak. Karpeta berri batera eramango dira beheko errenkadan dauden aplikazioak."</string>
- <string name="hotseat_edu_accept" msgid="1611544083278999837">"Jaso aplikazioen iradokizunak"</string>
- <string name="hotseat_edu_dismiss" msgid="2781161822780201689">"Ez, eskerrik asko"</string>
- <string name="hotseat_prediction_settings" msgid="6246554993566070818">"Ezarpenak"</string>
- <string name="hotseat_auto_enrolled" msgid="522100018967146807">"Hemen agertzen dira aplikazio erabilienak, eta ohituren arabera aldatzen dira"</string>
- <string name="hotseat_tip_no_empty_slots" msgid="1325212677738179185">"Arrastatu aplikazioak beheko errenkadatik aplikazioen iradokizunak jasotzeko"</string>
- <string name="hotseat_tip_gaps_filled" msgid="3035673010274223538">"Aplikazioen iradokizunak eremu huts batean gehitu dira"</string>
- <string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Gaituta daude aplikazioen iradokizunak"</string>
- <string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Desgaituta daude aplikazioen iradokizunak"</string>
- <string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Iragarritako aplikazioa: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Ziurtatu hatza pantailaren eskuineko edo ezkerreko ertzetik hasten zarela pasatzen."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Ziurtatu hatza pantailaren eskuineko edo ezkerreko ertzetik erdialdera pasatzen eta altxatzen duzula."</string>
- <string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Hatza eskuinetik pasatuta atzera egiten ikasi duzu. Jarraian, ikasi aplikazioa aldatzen."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"Ikasi duzu atzera egiteko keinua."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Ziurtatu hatza ez duzula pantailaren behealdetik gertuegi pasatzen."</string>
- <string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"Keinuaren sentikortasuna aldatzeko, joan ezarpenetara"</string>
- <string name="back_gesture_intro_title" msgid="19551256430224428">"Pasatu hatza atzera egiteko"</string>
- <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"Aurreko pantailara itzultzeko, pasatu hatza pantailaren ezkerreko edo eskuineko ertzetik erdialdera."</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Ziurtatu hatza pantailaren beheko ertzetik gora pasatzen duzula."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Ziurtatu askatu aurretik ez duzula hatza gelditzen."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Ziurtatu hatza zuzen gora pasatzen duzula."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"Ikasi duzu hasierako pantailara joateko keinua. Jarraian, ikasi atzera egiten."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"Ikasi duzu hasierako pantailara joateko keinua."</string>
- <string name="home_gesture_intro_title" msgid="836590312858441830">"Pasatu hatza hasierako pantailara joateko"</string>
- <string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Pasatu hatza pantailaren behealdetik gora. Keinu horrek hasierako pantailara eramango zaitu beti."</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Ziurtatu hatza pantailaren beheko ertzetik gora pasatzen duzula."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Eduki sakatuta leihoa luzaroago hatza altxatu aurretik."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Ziurtatu hatza zuzen gora pasatzen duzula; ondoren, gelditu."</string>
- <string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Ikasi duzu keinuak erabiltzen. Keinuak desaktibatzeko, joan ezarpenetara."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"Ikasi duzu aplikazioa aldatzeko keinua."</string>
- <string name="overview_gesture_intro_title" msgid="2902054412868489378">"Pasatu hatza aplikazioa aldatzeko"</string>
- <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Aplikazio batetik bestera joateko, pasatu hatza pantailaren behealdetik gora, eduki pantaila sakatuta eta altxatu hatza."</string>
- <string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"Dena prest"</string>
- <string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Eginda"</string>
- <string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Ezarpenak"</string>
- <string name="gesture_tutorial_try_again" msgid="65962545858556697">"Saiatu berriro"</string>
- <string name="gesture_tutorial_nice" msgid="2936275692616928280">"Ederki!"</string>
- <string name="gesture_tutorial_step" msgid="1279786122817620968">"Tutoriala: <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
- <string name="allset_title" msgid="5021126669778966707">"Dena prest!"</string>
- <string name="allset_hint" msgid="2384632994739392447">"Pasatu hatza gora hasierako pantailara joateko"</string>
- <string name="allset_description" msgid="6350320429953234580">"Prest zaude telefonoa erabiltzen hasteko"</string>
- <string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"Sisteman nabigatzeko ezarpenak"</annotation></string>
- <string name="action_share" msgid="2648470652637092375">"Partekatu"</string>
- <string name="action_screenshot" msgid="8171125848358142917">"Atera pantaila-argazki bat"</string>
- <string name="action_split" msgid="2098009717623550676">"Zatitu"</string>
- <string name="toast_split_select_app" msgid="5453865907322018352">"Sakatu beste aplikazio bat pantaila zatitzeko"</string>
- <string name="toast_split_app_unsupported" msgid="3271526028981899666">"Aplikazioak ez du onartzen pantaila zatitua."</string>
- <string name="blocked_by_policy" msgid="2071401072261365546">"Aplikazioak edo erakundeak ez du eman ekintza hori gauzatzeko baimena"</string>
- <string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Nabigazio-tutoriala saltatu nahi duzu?"</string>
- <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"<xliff:g id="NAME">%1$s</xliff:g> aplikazioan dago eskuragarri tutoriala"</string>
- <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Utzi"</string>
- <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Saltatu"</string>
- <string name="accessibility_rotate_button" msgid="4771825231336502943">"Biratu pantaila"</string>
- <string name="taskbar_edu_opened" msgid="3950252793551919129">"Agertu egin da zereginen barraren tutoriala"</string>
- <string name="taskbar_edu_closed" msgid="126643734478892862">"Itxi egin da zereginen barraren tutoriala"</string>
- <string name="taskbar_edu_switch_apps" msgid="6942863327845784813">"Erabili zereginen barra aplikazioz aldatzeko"</string>
- <string name="taskbar_edu_splitscreen" msgid="2663361731630346489">"Bi aplikazio batera erabiltzeko, arrastatu hatza albo batera"</string>
- <string name="taskbar_edu_stashing" msgid="5212374387411764031">"Zereginen barra ezkutatzeko, eduki ezazu sakatuta"</string>
- <string name="taskbar_edu_next" msgid="4007618274426775841">"Hurrengoa"</string>
- <string name="taskbar_edu_previous" msgid="459202320127201702">"Atzera"</string>
- <string name="taskbar_edu_close" msgid="887022990168191073">"Itxi"</string>
- <string name="taskbar_edu_done" msgid="6880178093977704569">"Eginda"</string>
- <string name="taskbar_button_home" msgid="2151398979630664652">"Hasiera"</string>
- <string name="taskbar_button_a11y" msgid="5241161324875094465">"Erabilerraztasuna"</string>
- <string name="taskbar_button_back" msgid="8558862226461164514">"Atzera"</string>
- <string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"IMEaren etengailua"</string>
- <string name="taskbar_button_recents" msgid="7273376136216613134">"Azkenak"</string>
- <string name="taskbar_button_notifications" msgid="7471740351507357318">"Jakinarazpenak"</string>
- <string name="taskbar_button_quick_settings" msgid="227662894293189391">"Ezarpen bizkorrak"</string>
- <string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Eraman gora, ezkerretara"</string>
- <string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Eraman behera, eskuinetara"</string>
+ <string name="title_app_suggestions" msgid="4185902664111965088">"Iradokitako aplikazioak"</string>
+ <string name="all_apps_label" msgid="8542784161730910663">"Aplikazio guztiak"</string>
+ <string name="all_apps_prediction_tip" msgid="2672336544844936186">"Lagungarri izan dakizkizukeen aplikazioak"</string>
</resources>
diff --git a/quickstep/res/values-fa/strings.xml b/quickstep/res/values-fa/strings.xml
index 2323b3b657..cc26695a60 100644
--- a/quickstep/res/values-fa/strings.xml
+++ b/quickstep/res/values-fa/strings.xml
@@ -19,91 +19,19 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="recent_task_option_split_screen" msgid="5353188922202653570">"تقسیم صفحه"</string>
<string name="recent_task_option_pin" msgid="7929860679018978258">"پین"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Freeform"</string>
+ <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"نمای کلی"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"بدون موارد اخیر"</string>
+ <string name="accessibility_close_task" msgid="5354563209433803643">"بستن"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"تنظیمات استفاده از برنامه"</string>
<string name="recents_clear_all" msgid="5328176793634888831">"پاک کردن همه"</string>
<string name="accessibility_recent_apps" msgid="4058661986695117371">"برنامه‌های اخیر"</string>
- <string name="task_view_closed" msgid="9170038230110856166">"تکلیف بسته شد"</string>
<string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>، <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
<string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; ۱ دقیقه"</string>
<string name="time_left_for_app" msgid="3111996412933644358">"<xliff:g id="TIME">%1$s</xliff:g> باقی‌مانده برای امروز"</string>
- <string name="title_app_suggestions" msgid="4185902664111965088">"پیشنهادهای برنامه"</string>
+ <string name="title_app_suggestions" msgid="4185902664111965088">"برنامه‌های پیشنهادی"</string>
+ <string name="all_apps_label" msgid="8542784161730910663">"همه برنامه‌ها"</string>
<string name="all_apps_prediction_tip" msgid="2672336544844936186">"برنامه‌های پیش‌بینی‌شده"</string>
- <string name="hotseat_edu_title_migrate" msgid="306578144424489980">"دریافت پیشنهادهای برنامه در ردیف پایین صفحه اصلی"</string>
- <string name="hotseat_edu_title_migrate_landscape" msgid="3633942953997845243">"دریافت «پیشنهاد برنامه» در ردیف موارد دلخواه صفحه اصلی"</string>
- <string name="hotseat_edu_message_migrate" msgid="8927179260533775320">"به‌راحتی در صفحه اصلی به پرکاربردترین برنامه‌ها دسترسی داشته باشید. پیشنهادها براساس روال‌هایتان تغییر خواهد کرد. برنامه‌های ردیف پایین در صفحه اصلی به بالا منتقل خواهند شد."</string>
- <string name="hotseat_edu_message_migrate_landscape" msgid="4248943380443387697">"به‌راحتی در صفحه اصلی به پرکاربردترین برنامه‌ها دسترسی داشته باشید. پیشنهادها براساس روال‌هایتان تغییر خواهد کرد. برنامه‌های موجود در ردیف موارد دلخواه به صفحه اصلی منتقل می‌شوند."</string>
- <string name="hotseat_edu_message_migrate_alt" msgid="3042360119039646356">"به‌راحتی در صفحه اصلی به پرکاربردترین برنامه‌ها دسترسی داشته باشید. پیشنهادها براساس روال‌هایتان تغییر خواهد کرد. برنامه‌های ردیف پایین به پوشه جدیدی منتقل خواهند شد."</string>
- <string name="hotseat_edu_accept" msgid="1611544083278999837">"دریافت پیشنهادهای برنامه"</string>
- <string name="hotseat_edu_dismiss" msgid="2781161822780201689">"نه متشکرم"</string>
- <string name="hotseat_prediction_settings" msgid="6246554993566070818">"تنظیمات"</string>
- <string name="hotseat_auto_enrolled" msgid="522100018967146807">"پرکاربردترین برنامه‌ها اینجا ظاهر می‌شوند و براساس روال‌ها تغییر می‌کنند"</string>
- <string name="hotseat_tip_no_empty_slots" msgid="1325212677738179185">"برای دریافت پیشنهادهای برنامه، برنامه‌ها را به بیرون از ردیف پایین بکشید"</string>
- <string name="hotseat_tip_gaps_filled" msgid="3035673010274223538">"«پیشنهاد برنامه» به فضای خالی اضافه شد"</string>
- <string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"«پیشنهاد برنامه» فعال است"</string>
- <string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"«پیشنهاد برنامه» غیرفعال است"</string>
- <string name="hotseat_prediction_content_description" msgid="4582028296938078419">"برنامه پیش‌بینی‌شده: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"دقت کنید که از انتهای لبه سمت راست یا سمت چپ تند بکشید."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"دقت کنید که از لبه سمت راست یا سمت چپ تند به وسط صفحه بکشید و رها کنید."</string>
- <string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"یاد گرفتید چگونه برای رفتن به عقب از سمت راست تند بکشید. مورد بعدی، با نحوه جابه‌جا شدن بین برنامه‌ها آشنا شوید."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"اشاره برگشتن را تکمیل کردید."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"دقت کنید که موقع تند کشیدن بیش‌از حد به پایین صفحه نزدیک نشوید."</string>
- <string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"برای تغییر حساسیت اشاره برگشت، به «تنظیمات» بروید"</string>
- <string name="back_gesture_intro_title" msgid="19551256430224428">"تند بکشید تا به‌عقب برگردید"</string>
- <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"برای برگشتن به صفحه آخر، از لبه سمت چپ یا راست تند به وسط صفحه بکشید."</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"دقت کنید که از لبه پایینی صفحه تند به بالا بکشید."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"دقت کنید که تا قبل‌از رها کردن، کشیدن را متوقف نکنید."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"دقت کنید که مستقیماً تند به بالا بکشید."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"اشاره رفتن به «صفحه اصلی» را تکمیل کردید. مورد بعدی، با نحوه برگشتن به عقب آشنا شوید."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"اشاره رفتن به «صفحه اصلی» را تکمیل کردید."</string>
- <string name="home_gesture_intro_title" msgid="836590312858441830">"تند کشیدن برای رفتن به صفحه اصلی"</string>
- <string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"از پایین صفحه، تند به‌سمت بالا بکشید. این اشاره همیشه شما را به صفحه اصلی می‌برد."</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"دقت کنید که از لبه پایینی صفحه تند به بالا بکشید."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"سعی کنید قبل‌از رها کردن، پنجره را برای مدت طولانی‌تری نگه دارید."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"دقت کنید که مستقیماً تند به بالا بکشید و سپس توقف کنید."</string>
- <string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"با نحوه استفاده از اشاره‌ها آشنا شدید. برای خاموش کردن اشاره‌ها، به «تنظیمات» بروید."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"اشاره جابه‌جا شدن بین برنامه‌ها را تکمیل کردید."</string>
- <string name="overview_gesture_intro_title" msgid="2902054412868489378">"برای جابه‌جا شدن بین برنامه‌ها، تند به‌بالا بکشید"</string>
- <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"برای جابه‌جا شدن بین برنامه‌ها، از پایین صفحه تند به‌بالا بکشید، نگه دارید، و سپس رها کنید."</string>
- <string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"همه چیز آماده است"</string>
- <string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"تمام"</string>
- <string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"تنظیمات"</string>
- <string name="gesture_tutorial_try_again" msgid="65962545858556697">"امتحان مجدد"</string>
- <string name="gesture_tutorial_nice" msgid="2936275692616928280">"عالی!"</string>
- <string name="gesture_tutorial_step" msgid="1279786122817620968">"آموزش گام‌به‌گام <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
- <string name="allset_title" msgid="5021126669778966707">"همه چیز آماده است!"</string>
- <string name="allset_hint" msgid="2384632994739392447">"برای رفتن به «صفحه اصلی»، تند به‌بالا بکشید"</string>
- <string name="allset_description" msgid="6350320429953234580">"آماده‌اید از تلفنتان استفاده کنید"</string>
- <string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"تنظیمات پیمایش سیستم"</annotation></string>
- <string name="action_share" msgid="2648470652637092375">"هم‌رسانی"</string>
- <string name="action_screenshot" msgid="8171125848358142917">"نماگرفت"</string>
- <string name="action_split" msgid="2098009717623550676">"دونیمه"</string>
- <string name="toast_split_select_app" msgid="5453865907322018352">"برای استفاده از صفحهٔ دونیمه، روی برنامه دیگری ضربه بزنید"</string>
- <string name="toast_split_app_unsupported" msgid="3271526028981899666">"برنامه از صفحهٔ دونیمه پشتیبانی نمی‌کند."</string>
- <string name="blocked_by_policy" msgid="2071401072261365546">"برنامه یا سازمان شما اجازه نمی‌دهد این کنش انجام شود."</string>
- <string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"آموزش گام‌به‌گام پیمایش رد شود؟"</string>
- <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"می‌توانید آن را بعداً در برنامه <xliff:g id="NAME">%1$s</xliff:g> پیدا کنید"</string>
- <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"لغو"</string>
- <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"رد شدن"</string>
- <string name="accessibility_rotate_button" msgid="4771825231336502943">"چرخاندن صفحه"</string>
- <string name="taskbar_edu_opened" msgid="3950252793551919129">"پانل آموزشی نوار وظیفه نمایان شد"</string>
- <string name="taskbar_edu_closed" msgid="126643734478892862">"پانل آموزشی نوار وظیفه بسته شد"</string>
- <string name="taskbar_edu_switch_apps" msgid="6942863327845784813">"برای جابه‌جایی بین برنامه‌ها، از نوار وظیفه استفاده کنید"</string>
- <string name="taskbar_edu_splitscreen" msgid="2663361731630346489">"برای استفاده هم‌زمان از دو برنامه، آن را به کنار بکشید"</string>
- <string name="taskbar_edu_stashing" msgid="5212374387411764031">"برای پنهان کردن نوار وظیفه، لمس کنید و نگه دارید"</string>
- <string name="taskbar_edu_next" msgid="4007618274426775841">"بعدی"</string>
- <string name="taskbar_edu_previous" msgid="459202320127201702">"برگشت"</string>
- <string name="taskbar_edu_close" msgid="887022990168191073">"بستن"</string>
- <string name="taskbar_edu_done" msgid="6880178093977704569">"تمام"</string>
- <string name="taskbar_button_home" msgid="2151398979630664652">"صفحه اصلی"</string>
- <string name="taskbar_button_a11y" msgid="5241161324875094465">"دسترس‌پذیری"</string>
- <string name="taskbar_button_back" msgid="8558862226461164514">"برگشت"</string>
- <string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"‏تعویض‌کننده IME"</string>
- <string name="taskbar_button_recents" msgid="7273376136216613134">"موارد اخیر"</string>
- <string name="taskbar_button_notifications" msgid="7471740351507357318">"اعلان‌ها"</string>
- <string name="taskbar_button_quick_settings" msgid="227662894293189391">"تنظیمات فوری"</string>
- <string name="move_drop_target_top_or_left" msgid="2988702185049595807">"انتقال به بالا/ چپ"</string>
- <string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"انتقال به پایین/ راست"</string>
</resources>
diff --git a/quickstep/res/values-fi/strings.xml b/quickstep/res/values-fi/strings.xml
index 9505039bf0..f43433e3a1 100644
--- a/quickstep/res/values-fi/strings.xml
+++ b/quickstep/res/values-fi/strings.xml
@@ -19,93 +19,19 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Jaettu näyttö"</string>
<string name="recent_task_option_pin" msgid="7929860679018978258">"Kiinnitä"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Vapaamuotoinen"</string>
+ <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Viimeisimmät"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"Ei viimeaikaisia kohteita"</string>
+ <string name="accessibility_close_task" msgid="5354563209433803643">"Sulje"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Sovelluksen käyttöasetukset"</string>
<string name="recents_clear_all" msgid="5328176793634888831">"Poista kaikki"</string>
<string name="accessibility_recent_apps" msgid="4058661986695117371">"Viimeisimmät sovellukset"</string>
- <string name="task_view_closed" msgid="9170038230110856166">"Tehtävä suljettu"</string>
<string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
<string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 min"</string>
<string name="time_left_for_app" msgid="3111996412933644358">"<xliff:g id="TIME">%1$s</xliff:g> jäljellä tänään"</string>
<string name="title_app_suggestions" msgid="4185902664111965088">"Sovellusehdotukset"</string>
+ <string name="all_apps_label" msgid="8542784161730910663">"Kaikki sovellukset"</string>
<string name="all_apps_prediction_tip" msgid="2672336544844936186">"Sovellusennusteet"</string>
- <string name="hotseat_edu_title_migrate" msgid="306578144424489980">"Näytä sovellusehdotuksia aloitusnäytön alimmalla rivillä"</string>
- <string name="hotseat_edu_title_migrate_landscape" msgid="3633942953997845243">"Näytä sovellusehdotuksia aloitusnäytön Suosikit-rivillä"</string>
- <string name="hotseat_edu_message_migrate" msgid="8927179260533775320">"Voit avata käytetyimmät sovellukset kätevästi aloitusnäytöltä. Ehdotukset muuttuvat rutiiniesi perusteella. Alimmalla rivillä olevat sovellukset siirretään aloitusnäytön yläosaan."</string>
- <string name="hotseat_edu_message_migrate_landscape" msgid="4248943380443387697">"Voit avata käytetyimmät sovellukset kätevästi aloitusnäytöltä. Ehdotukset muuttuvat rutiiniesi perusteella. Suosikit-rivillä olevat sovellukset siirretään aloitusnäytölle."</string>
- <string name="hotseat_edu_message_migrate_alt" msgid="3042360119039646356">"Voit avata käytetyimmät sovellukset kätevästi aloitusnäytöltä. Ehdotukset muuttuvat rutiiniesi perusteella. Alimmalla rivillä olevat sovellukset siirretään uuteen kansioon."</string>
- <string name="hotseat_edu_accept" msgid="1611544083278999837">"Näytä sovellusehdotuksia"</string>
- <string name="hotseat_edu_dismiss" msgid="2781161822780201689">"Ei kiitos"</string>
- <string name="hotseat_prediction_settings" msgid="6246554993566070818">"Asetukset"</string>
- <string name="hotseat_auto_enrolled" msgid="522100018967146807">"Käytetyimmät sovellukset näkyvät täällä ja muuttuvat rutiiniesi perusteella"</string>
- <string name="hotseat_tip_no_empty_slots" msgid="1325212677738179185">"Siirrä sovelluksia pois alimmalta riviltä, niin voit saada sovellusehdotuksia"</string>
- <string name="hotseat_tip_gaps_filled" msgid="3035673010274223538">"Sovellusehdotuksia lisätty tyhjään kohtaan"</string>
- <string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Sovellusehdotukset käytössä"</string>
- <string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Sovellusehdotukset on poistettu käytöstä"</string>
- <string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Ennakoitu sovellus: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Muista pyyhkäistä aivan oikeasta tai vasemmasta reunasta."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Pyyhkäise näytön oikeasta tai vasemmasta reunasta keskelle ja päästä irti."</string>
- <string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Osaat palata takaisin pyyhkäisemällä oikeasta reunasta. Opettele seuraavaksi vaihtamaan sovellusta."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"Olet oppinut Takaisin-eleen."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Varo, ettet pyyhkäise liian lähellä alareunaa."</string>
- <string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"Voit muuttaa Takaisin-eleen herkkyyttä asetuksista"</string>
- <string name="back_gesture_intro_title" msgid="19551256430224428">"Siirry takaisin pyyhkäisemällä"</string>
- <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"Voit palata edelliseen näkymään pyyhkäisemällä näytön vasemmasta tai oikeasta reunasta keskelle."</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Pyyhkäise ylös näytön alareunasta."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Varo keskeyttämästä ennen kuin päästät irti."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Muista pyyhkäistä suoraan ylöspäin."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"Olet oppinut aloitusnäytölle palaamiseleen. Opettele seuraavaksi siirtymään takaisin."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"Olet oppinut aloitusnäytölle palaamiseleen."</string>
- <string name="home_gesture_intro_title" msgid="836590312858441830">"Siirry aloitusnäytölle pyyhkäisemällä"</string>
- <string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Pyyhkäise ylös näytön alareunasta. Tämä ele vie sinut aina aloitusnäytölle."</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Pyyhkäise ylös näytön alareunasta."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Kokeile pitää ikkunaa painettuna pidempään ennen kuin päästät irti."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Muista pyyhkäistä suoraan ylöspäin ja keskeytä sitten."</string>
- <string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Olet oppinut käyttämään eleitä. Jos haluat laittaa eleet pois päältä, avaa Asetukset."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"Olet oppinut sovellusten vaihtamiseleen."</string>
- <string name="overview_gesture_intro_title" msgid="2902054412868489378">"Vaihda sovellusta pyyhkäisemällä"</string>
- <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Voit vaihtaa sovelluksesta toiseen pyyhkäisemällä ylöspäin näytön alareunasta ja päästämällä sitten irti."</string>
- <string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"Valmista"</string>
- <string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Valmis"</string>
- <string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Asetukset"</string>
- <string name="gesture_tutorial_try_again" msgid="65962545858556697">"Yritä uudelleen"</string>
- <string name="gesture_tutorial_nice" msgid="2936275692616928280">"Hienoa!"</string>
- <string name="gesture_tutorial_step" msgid="1279786122817620968">"Ohje <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
- <string name="allset_title" msgid="5021126669778966707">"Valmis"</string>
- <string name="allset_hint" msgid="2384632994739392447">"Siirry aloitusnäytölle pyyhkäisemällä ylös"</string>
- <string name="allset_description" msgid="6350320429953234580">"Olet valmis aloittamaan puhelimen käytön"</string>
- <string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"Järjestelmän navigointiasetukset"</annotation></string>
- <string name="action_share" msgid="2648470652637092375">"Jaa"</string>
- <string name="action_screenshot" msgid="8171125848358142917">"Kuvakaappaus"</string>
- <string name="action_split" msgid="2098009717623550676">"Jaa"</string>
- <string name="toast_split_select_app" msgid="5453865907322018352">"Avaa jaettu näyttö napauttamalla toista sovellusta"</string>
- <string name="toast_split_app_unsupported" msgid="3271526028981899666">"Sovellus ei tue jaetun näytön tilaa."</string>
- <string name="blocked_by_policy" msgid="2071401072261365546">"Sovellus tai organisaatio ei salli tätä toimintoa"</string>
- <string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Ohitetaanko navigointiohje?"</string>
- <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Löydät tämän myöhemmin sovelluksesta: <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Peru"</string>
- <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Ohita"</string>
- <string name="accessibility_rotate_button" msgid="4771825231336502943">"Käännä näyttö"</string>
- <string name="taskbar_edu_opened" msgid="3950252793551919129">"Tehtäväpalkin ohje näkyvissä"</string>
- <string name="taskbar_edu_closed" msgid="126643734478892862">"Tehtäväpalkin ohje suljettu"</string>
- <string name="taskbar_edu_switch_apps" msgid="6942863327845784813">"Vaihda sovellusta tehtäväpalkin kautta"</string>
- <string name="taskbar_edu_splitscreen" msgid="2663361731630346489">"Vetämällä sivuun voit käyttää kahta sovellusta samaan aikaan"</string>
- <string name="taskbar_edu_stashing" msgid="5212374387411764031">"Piilota tehtäväpalkki koskettamalla pitkään"</string>
- <string name="taskbar_edu_next" msgid="4007618274426775841">"Seuraava"</string>
- <string name="taskbar_edu_previous" msgid="459202320127201702">"Takaisin"</string>
- <string name="taskbar_edu_close" msgid="887022990168191073">"Sulje"</string>
- <string name="taskbar_edu_done" msgid="6880178093977704569">"Valmis"</string>
- <string name="taskbar_button_home" msgid="2151398979630664652">"Etusivu"</string>
- <string name="taskbar_button_a11y" msgid="5241161324875094465">"Esteettömyys"</string>
- <string name="taskbar_button_back" msgid="8558862226461164514">"Takaisin"</string>
- <string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"IME-vaihtopalvelu"</string>
- <string name="taskbar_button_recents" msgid="7273376136216613134">"Viimeaikaiset"</string>
- <!-- no translation found for taskbar_button_notifications (7471740351507357318) -->
- <skip />
- <!-- no translation found for taskbar_button_quick_settings (227662894293189391) -->
- <skip />
- <string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Siirrä ylös tai vasemmalle"</string>
- <string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Siirrä alas tai oikealle"</string>
</resources>
diff --git a/quickstep/res/values-fr-rCA/strings.xml b/quickstep/res/values-fr-rCA/strings.xml
index e34cb5d328..a9a1cffb6d 100644
--- a/quickstep/res/values-fr-rCA/strings.xml
+++ b/quickstep/res/values-fr-rCA/strings.xml
@@ -19,93 +19,19 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Écran divisé"</string>
<string name="recent_task_option_pin" msgid="7929860679018978258">"Épingler"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Forme libre"</string>
+ <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Aperçu"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"Aucun élément récent"</string>
+ <string name="accessibility_close_task" msgid="5354563209433803643">"Fermer"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Paramètres d\'utilisation de l\'application"</string>
<string name="recents_clear_all" msgid="5328176793634888831">"Tout effacer"</string>
<string name="accessibility_recent_apps" msgid="4058661986695117371">"Applications récentes"</string>
- <string name="task_view_closed" msgid="9170038230110856166">"Tâche fermée"</string>
<string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g> : <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
<string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 min"</string>
<string name="time_left_for_app" msgid="3111996412933644358">"Il reste <xliff:g id="TIME">%1$s</xliff:g> aujourd\'hui"</string>
<string name="title_app_suggestions" msgid="4185902664111965088">"Suggestions d\'applications"</string>
+ <string name="all_apps_label" msgid="8542784161730910663">"Toutes les applications"</string>
<string name="all_apps_prediction_tip" msgid="2672336544844936186">"Vos prédictions d\'applications"</string>
- <string name="hotseat_edu_title_migrate" msgid="306578144424489980">"Obtenir des suggestions d\'applications dans la rangée du bas de votre écran d\'accueil"</string>
- <string name="hotseat_edu_title_migrate_landscape" msgid="3633942953997845243">"Retrouvez des suggestions d\'applications dans la rangée des favoris de votre écran d\'accueil"</string>
- <string name="hotseat_edu_message_migrate" msgid="8927179260533775320">"Accédez facilement aux applications que vous utilisez le plus, directement à l\'écran d\'accueil. Les suggestions changeront en fonction de vos habitudes. Les applications dans la rangée du bas seront déplacées vers votre écran d\'accueil."</string>
- <string name="hotseat_edu_message_migrate_landscape" msgid="4248943380443387697">"Accédez facilement aux applications que vous utilisez le plus, directement à l\'écran d\'accueil. Les suggestions changeront en fonction de vos habitudes. Les applications dans la rangée des favoris seront déplacées vers votre écran d\'accueil."</string>
- <string name="hotseat_edu_message_migrate_alt" msgid="3042360119039646356">"Accédez facilement aux applications que vous utilisez le plus, directement à l\'écran d\'accueil. Les suggestions changeront en fonction de vos habitudes. Les applications dans la rangée du bas seront déplacées vers un nouveau dossier."</string>
- <string name="hotseat_edu_accept" msgid="1611544083278999837">"Obtenir des suggestions d\'applications"</string>
- <string name="hotseat_edu_dismiss" msgid="2781161822780201689">"Non merci"</string>
- <string name="hotseat_prediction_settings" msgid="6246554993566070818">"Paramètres"</string>
- <string name="hotseat_auto_enrolled" msgid="522100018967146807">"Les applications les plus utilisées s\'affichent ici et changent en fonction des habitudes"</string>
- <string name="hotseat_tip_no_empty_slots" msgid="1325212677738179185">"Faites glisser des applications hors de la rangée du bas pour obtenir des suggestions d\'applications"</string>
- <string name="hotseat_tip_gaps_filled" msgid="3035673010274223538">"Applications suggérées ajoutées à l\'espace vide"</string>
- <string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Les suggestions d\'applications sont activées"</string>
- <string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Les suggestions d\'applications sont désactivées"</string>
- <string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Application prédite : <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Assurez-vous de balayer l\'écran à partir de l\'extrémité droite ou gauche."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Balayez l\'écran de l\'extrémité droite ou gauche jusqu\'au centre de l\'écran, puis levez le doigt."</string>
- <string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Vous avez appris à balayer de la droite pour revenir en arrière. Apprenez comment changer d\'appli."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"Vous avez appris le geste de retour en arrière."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Assurez-vous de ne pas balayer trop près du bas de l\'écran."</string>
- <string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"Modifiez la sensibilité du geste de retour dans Paramètres"</string>
- <string name="back_gesture_intro_title" msgid="19551256430224428">"Balayer l\'écran pour revenir en arrière"</string>
- <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"Pour revenir à l\'écran précédent, balayez l\'écran de l\'extrémité gauche ou droite vers le centre."</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Assurez-vous de balayer l\'écran à partir de l\'extrémité inférieure vers le haut."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Assurez-vous de ne pas interrompre le geste avant de lever le doigt."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Assurez-vous de balayer l\'écran en ligne droite vers le haut."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"Vous avez appris le geste de retour à l\'écran d\'accueil. Maintenant, apprenez à revenir en arrière."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"Vous avez appris le geste de retour à l\'écran d\'accueil."</string>
- <string name="home_gesture_intro_title" msgid="836590312858441830">"Balayer pour revenir à l\'écran d\'accueil"</string>
- <string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Balayez l\'écran du bas vers le haut. Ce geste vous ramène toujours à l\'écran d\'accueil."</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Assurez-vous de balayer l\'écran à partir de l\'extrémité inférieure vers le haut."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Essayez de tenir la fenêtre plus longtemps avant de relâcher."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Assurez-vous de balayer l\'écran vers le haut, puis de faire une pause."</string>
- <string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Vous avez appris à utiliser les gestes. Pour les désactiver, accédez au menu Paramètres."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"Vous avez appris le geste de changement d\'application."</string>
- <string name="overview_gesture_intro_title" msgid="2902054412868489378">"Balayer pour basculer entre les applications"</string>
- <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Pour passer d\'une application à l\'autre, balayez l\'écran de bas en haut, maintenez la pression, puis relâchez."</string>
- <string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"Terminé"</string>
- <string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"OK"</string>
- <string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Paramètres"</string>
- <string name="gesture_tutorial_try_again" msgid="65962545858556697">"Réessayer"</string>
- <string name="gesture_tutorial_nice" msgid="2936275692616928280">"Bien!"</string>
- <string name="gesture_tutorial_step" msgid="1279786122817620968">"Étape <xliff:g id="CURRENT">%1$d</xliff:g> sur <xliff:g id="TOTAL">%2$d</xliff:g> du tutoriel"</string>
- <string name="allset_title" msgid="5021126669778966707">"Tout est prêt!"</string>
- <string name="allset_hint" msgid="2384632994739392447">"Balayez l\'écran vers le haut pour accéder à l\'écran d\'accueil"</string>
- <string name="allset_description" msgid="6350320429953234580">"Vous êtes maintenant prêt à utiliser votre téléphone"</string>
- <string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"Paramètres de navigation du système"</annotation></string>
- <string name="action_share" msgid="2648470652637092375">"Partager"</string>
- <string name="action_screenshot" msgid="8171125848358142917">"Capture d\'écran"</string>
- <string name="action_split" msgid="2098009717623550676">"Séparé"</string>
- <string name="toast_split_select_app" msgid="5453865907322018352">"Touchez une autre appli pour partager l\'écran"</string>
- <string name="toast_split_app_unsupported" msgid="3271526028981899666">"L\'appli n\'est pas compatible avec l\'écran partagé."</string>
- <string name="blocked_by_policy" msgid="2071401072261365546">"L\'application ou votre organisation n\'autorise pas cette action"</string>
- <string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Ignorer le tutoriel sur la navigation?"</string>
- <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Vous trouverez le tutoriel dans l\'application <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Annuler"</string>
- <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Ignorer"</string>
- <string name="accessibility_rotate_button" msgid="4771825231336502943">"Faire pivoter l\'écran"</string>
- <string name="taskbar_edu_opened" msgid="3950252793551919129">"La barre des tâches éducatives s\'est affichée"</string>
- <string name="taskbar_edu_closed" msgid="126643734478892862">"La barre des tâches éducatives est fermée"</string>
- <string name="taskbar_edu_switch_apps" msgid="6942863327845784813">"Utilisez la barre des tâches pour changer les applications"</string>
- <string name="taskbar_edu_splitscreen" msgid="2663361731630346489">"Glissez sur le côté pour utiliser 2 applications à la fois"</string>
- <string name="taskbar_edu_stashing" msgid="5212374387411764031">"Maintenez le doigt sur la barre des tâches pour la masquer"</string>
- <string name="taskbar_edu_next" msgid="4007618274426775841">"Suivant"</string>
- <string name="taskbar_edu_previous" msgid="459202320127201702">"Retour"</string>
- <string name="taskbar_edu_close" msgid="887022990168191073">"Fermer"</string>
- <string name="taskbar_edu_done" msgid="6880178093977704569">"OK"</string>
- <string name="taskbar_button_home" msgid="2151398979630664652">"Accueil"</string>
- <string name="taskbar_button_a11y" msgid="5241161324875094465">"Accessibilité"</string>
- <string name="taskbar_button_back" msgid="8558862226461164514">"Retour"</string>
- <string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"Sélecteur IME"</string>
- <string name="taskbar_button_recents" msgid="7273376136216613134">"Récents"</string>
- <!-- no translation found for taskbar_button_notifications (7471740351507357318) -->
- <skip />
- <!-- no translation found for taskbar_button_quick_settings (227662894293189391) -->
- <skip />
- <string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Déplacer vers le coin supérieur gauche de l\'écran"</string>
- <string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Déplacer vers le coin inférieur droit de l\'écran"</string>
</resources>
diff --git a/quickstep/res/values-fr/strings.xml b/quickstep/res/values-fr/strings.xml
index 3c28c4649e..01dcff202d 100644
--- a/quickstep/res/values-fr/strings.xml
+++ b/quickstep/res/values-fr/strings.xml
@@ -19,93 +19,19 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Écran partagé"</string>
<string name="recent_task_option_pin" msgid="7929860679018978258">"Épingler"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Format libre"</string>
+ <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Aperçu"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"Aucun élément récent"</string>
+ <string name="accessibility_close_task" msgid="5354563209433803643">"Fermer"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Paramètres de consommation de l\'application"</string>
<string name="recents_clear_all" msgid="5328176793634888831">"Tout effacer"</string>
<string name="accessibility_recent_apps" msgid="4058661986695117371">"Applications récentes"</string>
- <string name="task_view_closed" msgid="9170038230110856166">"Tâche fermée"</string>
<string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
<string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 min"</string>
<string name="time_left_for_app" msgid="3111996412933644358">"Encore <xliff:g id="TIME">%1$s</xliff:g> aujourd\'hui"</string>
- <string name="title_app_suggestions" msgid="4185902664111965088">"Applications suggérées"</string>
+ <string name="title_app_suggestions" msgid="4185902664111965088">"Suggestions d\'applications"</string>
+ <string name="all_apps_label" msgid="8542784161730910663">"Toutes les applications"</string>
<string name="all_apps_prediction_tip" msgid="2672336544844936186">"Applications prévues pour vous"</string>
- <string name="hotseat_edu_title_migrate" msgid="306578144424489980">"Retrouvez vos applications favorites au bas de votre écran d\'accueil"</string>
- <string name="hotseat_edu_title_migrate_landscape" msgid="3633942953997845243">"Retrouvez des suggestions d\'applications dans la zone des favoris de votre écran d\'accueil"</string>
- <string name="hotseat_edu_message_migrate" msgid="8927179260533775320">"Les suggestions d\'applications permettent d\'afficher vos applications favorites au bas de votre écran d\'accueil. Elles s\'adaptent à vos habitudes d\'utilisation. Les icônes auparavant affichées au bas de l\'écran seront déplacées vers le haut."</string>
- <string name="hotseat_edu_message_migrate_landscape" msgid="4248943380443387697">"Accédez facilement aux applications dont vous vous servez le plus, directement depuis l\'écran d\'accueil. Ces suggestions peuvent varier en fonction de vos habitudes d\'utilisation. Les applications de la zone des favoris seront transférées sur votre écran d\'accueil."</string>
- <string name="hotseat_edu_message_migrate_alt" msgid="3042360119039646356">"Les suggestions d\'applications permettent d\'afficher vos applications favorites au bas de votre écran d\'accueil. Elles s\'adaptent à vos habitudes d\'utilisation. Les icônes auparavant affichées au bas de l\'écran seront placées dans un nouveau dossier."</string>
- <string name="hotseat_edu_accept" msgid="1611544083278999837">"Activer les suggestions"</string>
- <string name="hotseat_edu_dismiss" msgid="2781161822780201689">"Non, merci"</string>
- <string name="hotseat_prediction_settings" msgid="6246554993566070818">"Paramètres"</string>
- <string name="hotseat_auto_enrolled" msgid="522100018967146807">"Les applications dont vous vous servez le plus s\'affichent ici (ces suggestions peuvent varier en fonction de vos habitudes d\'utilisation)"</string>
- <string name="hotseat_tip_no_empty_slots" msgid="1325212677738179185">"Faites glisser des applications hors de la rangée du bas pour obtenir des suggestions d\'applications"</string>
- <string name="hotseat_tip_gaps_filled" msgid="3035673010274223538">"Des suggestions d\'applications ont été ajoutées à un emplacement vide"</string>
- <string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Suggestions d\'applications activées"</string>
- <string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Les suggestions d\'applications sont désactivées"</string>
- <string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Application prédite : <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Veillez à bien balayer l\'écran depuis le bord gauche ou droit."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Balayez bien l\'écran depuis le bord gauche ou droit jusqu\'au centre avant de relever le doigt."</string>
- <string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Vous savez revenir en arrière en balayant depuis la droite. Apprenez à passer d\'une appli à l\'autre."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"Vous avez appris le geste pour revenir en arrière."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Veillez à ne pas balayer l\'écran trop près du bas."</string>
- <string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"Modifiez la sensibilité du geste retour dans les paramètres"</string>
- <string name="back_gesture_intro_title" msgid="19551256430224428">"Balayez l\'écran pour revenir en arrière"</string>
- <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"Pour revenir à l\'écran précédent, balayez l\'écran depuis le bord droit ou gauche jusqu\'au centre."</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Veillez à balayer l\'écran de bas en haut."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Veillez à ne pas marquer de pause dans votre geste avant de relever le doigt."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Veillez à balayer l\'écran vers le haut."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"Vous savez désormais revenir à l\'écran d\'accueil. Apprenez maintenant à revenir en arrière."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"Vous avez appris le geste pour revenir à l\'écran d\'accueil."</string>
- <string name="home_gesture_intro_title" msgid="836590312858441830">"Balayez pour revenir à l\'écran d\'accueil"</string>
- <string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Balayez l\'écran de bas en haut. Ce geste vous ramènera toujours à l\'écran d\'accueil."</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Veillez à balayer l\'écran de bas en haut."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Essayez d\'appuyer plus longtemps sur la fenêtre avant de relever le doigt."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Veillez à balayer l\'écran vers le haut, puis à marquer une pause."</string>
- <string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Vous avez appris à utiliser les gestes. Pour les désactiver, accédez aux paramètres."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"Vous avez appris le geste pour passer d\'une appli à l\'autre."</string>
- <string name="overview_gesture_intro_title" msgid="2902054412868489378">"Balayez pour passer d\'une appli à l\'autre"</string>
- <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Pour changer d\'appli, balayez l\'écran de bas en haut, appuyez de manière prolongée et relâchez."</string>
- <string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"Vous avez terminé"</string>
- <string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"OK"</string>
- <string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Paramètres"</string>
- <string name="gesture_tutorial_try_again" msgid="65962545858556697">"Réessayez"</string>
- <string name="gesture_tutorial_nice" msgid="2936275692616928280">"Bravo !"</string>
- <string name="gesture_tutorial_step" msgid="1279786122817620968">"Tutoriel <xliff:g id="CURRENT">%1$d</xliff:g> sur <xliff:g id="TOTAL">%2$d</xliff:g>"</string>
- <string name="allset_title" msgid="5021126669778966707">"Tout est prêt !"</string>
- <string name="allset_hint" msgid="2384632994739392447">"Balayez l\'écran vers le haut pour revenir à l\'accueil"</string>
- <string name="allset_description" msgid="6350320429953234580">"Vous pouvez maintenant utiliser votre téléphone"</string>
- <string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"Paramètres de navigation système"</annotation></string>
- <string name="action_share" msgid="2648470652637092375">"Partager"</string>
- <string name="action_screenshot" msgid="8171125848358142917">"Capture d\'écran"</string>
- <string name="action_split" msgid="2098009717623550676">"Partager"</string>
- <string name="toast_split_select_app" msgid="5453865907322018352">"Appuyez sur autre appli pour utiliser écran partagé"</string>
- <string name="toast_split_app_unsupported" msgid="3271526028981899666">"Appli incompatible avec l\'écran partagé."</string>
- <string name="blocked_by_policy" msgid="2071401072261365546">"Cette action n\'est pas autorisée par l\'application ou par votre organisation"</string>
- <string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Ignorer le tutoriel de navigation ?"</string>
- <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Vous le retrouverez dans l\'appli <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Annuler"</string>
- <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Passer"</string>
- <string name="accessibility_rotate_button" msgid="4771825231336502943">"Faire pivoter l\'écran"</string>
- <string name="taskbar_edu_opened" msgid="3950252793551919129">"Infos sur la barre des tâches affichées"</string>
- <string name="taskbar_edu_closed" msgid="126643734478892862">"Infos sur la barre des tâches fermées"</string>
- <string name="taskbar_edu_switch_apps" msgid="6942863327845784813">"Utilisez la barre des tâches pour changer d\'application"</string>
- <string name="taskbar_edu_splitscreen" msgid="2663361731630346489">"Faites glisser sur côté pour utiliser deux applis à la fois"</string>
- <string name="taskbar_edu_stashing" msgid="5212374387411764031">"Appuyez de manière prolongée pour masquer barre des tâches"</string>
- <string name="taskbar_edu_next" msgid="4007618274426775841">"Suivant"</string>
- <string name="taskbar_edu_previous" msgid="459202320127201702">"Retour"</string>
- <string name="taskbar_edu_close" msgid="887022990168191073">"Fermer"</string>
- <string name="taskbar_edu_done" msgid="6880178093977704569">"OK"</string>
- <string name="taskbar_button_home" msgid="2151398979630664652">"Accueil"</string>
- <string name="taskbar_button_a11y" msgid="5241161324875094465">"Accessibilité"</string>
- <string name="taskbar_button_back" msgid="8558862226461164514">"Retour"</string>
- <string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"Sélecteur IME"</string>
- <string name="taskbar_button_recents" msgid="7273376136216613134">"Récents"</string>
- <!-- no translation found for taskbar_button_notifications (7471740351507357318) -->
- <skip />
- <!-- no translation found for taskbar_button_quick_settings (227662894293189391) -->
- <skip />
- <string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Déplacer en haut ou à gauche"</string>
- <string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Déplacer en bas ou à droite"</string>
</resources>
diff --git a/quickstep/res/values-gl/strings.xml b/quickstep/res/values-gl/strings.xml
index 4095f7d52c..356d10d5da 100644
--- a/quickstep/res/values-gl/strings.xml
+++ b/quickstep/res/values-gl/strings.xml
@@ -19,93 +19,19 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Pantalla dividida"</string>
<string name="recent_task_option_pin" msgid="7929860679018978258">"Fixar"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Forma libre"</string>
+ <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Visión xeral"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"Non hai elementos recentes"</string>
+ <string name="accessibility_close_task" msgid="5354563209433803643">"Pecha a aplicación"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Configuración do uso de aplicacións"</string>
<string name="recents_clear_all" msgid="5328176793634888831">"Borrar todo"</string>
<string name="accessibility_recent_apps" msgid="4058661986695117371">"Apps recentes"</string>
- <string name="task_view_closed" msgid="9170038230110856166">"Tarefa pechada"</string>
<string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g> (<xliff:g id="REMAINING_TIME">%2$s</xliff:g>)"</string>
<string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt;1 min"</string>
<string name="time_left_for_app" msgid="3111996412933644358">"Tempo restante hoxe <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="title_app_suggestions" msgid="4185902664111965088">"Suxestións de aplicacións"</string>
- <string name="all_apps_prediction_tip" msgid="2672336544844936186">"Previsión das túas aplicacións"</string>
- <string name="hotseat_edu_title_migrate" msgid="306578144424489980">"Recibe suxestións de aplicacións na fila inferior da pantalla de inicio"</string>
- <string name="hotseat_edu_title_migrate_landscape" msgid="3633942953997845243">"Recibe suxestións de aplicacións na fila de Favoritos da pantalla de inicio"</string>
- <string name="hotseat_edu_message_migrate" msgid="8927179260533775320">"Accede facilmente desde a pantalla de inicio ás aplicacións que máis usas. As suxestións irán cambiando en función das túas rutinas. As aplicacións da fila inferior pasarán á pantalla de inicio."</string>
- <string name="hotseat_edu_message_migrate_landscape" msgid="4248943380443387697">"Accede facilmente desde a pantalla de inicio ás aplicacións que máis usas. As suxestións irán cambiando en función das túas rutinas. As aplicacións da fila de Favoritos moveranse á túa pantalla de inicio."</string>
- <string name="hotseat_edu_message_migrate_alt" msgid="3042360119039646356">"Accede facilmente desde a pantalla de inicio ás aplicacións que máis usas. As suxestións irán cambiando en función das túas rutinas. As aplicacións da fila inferior pasarán a un cartafol novo."</string>
- <string name="hotseat_edu_accept" msgid="1611544083278999837">"Recibir suxestións de aplicacións"</string>
- <string name="hotseat_edu_dismiss" msgid="2781161822780201689">"Non, grazas"</string>
- <string name="hotseat_prediction_settings" msgid="6246554993566070818">"Configuración"</string>
- <string name="hotseat_auto_enrolled" msgid="522100018967146807">"As aplicacións máis usadas aparecen aquí e van cambiando en función das túas rutinas"</string>
- <string name="hotseat_tip_no_empty_slots" msgid="1325212677738179185">"Arrastra aplicacións desde a fila inferior para recibir suxestións de aplicacións"</string>
- <string name="hotseat_tip_gaps_filled" msgid="3035673010274223538">"Engadíronse suxestións de aplicacións ao espazo baleiro"</string>
- <string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"As suxestións de aplicacións están activadas"</string>
- <string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"As suxestións de aplicacións están desactivadas"</string>
- <string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Aplicación predita: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Asegúrate de pasar o dedo desde o bordo dereito ou esquerdo máis afastado."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Asegúrate de pasar o dedo desde o bordo dereito ou esquerdo ata o medio da pantalla e avanza."</string>
- <string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Aprendiches a pasar o dedo desde a dereita para volver. Agora, aprende a cambiar de aplicación."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"Completaches o xesto de volver á última pantalla."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Asegúrate de non pasar o dedo demasiado preto da parte inferior da pantalla."</string>
- <string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"Podes cambiar a sensibilidade do xesto en Configuración"</string>
- <string name="back_gesture_intro_title" msgid="19551256430224428">"Pasar o dedo para volver"</string>
- <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"Para volver á última pantalla, pasa o dedo cara ao medio desde o bordo dereito ou esquerdo."</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Asegúrate de pasar o dedo cara arriba desde o bordo inferior da pantalla."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Asegúrate de non facer unha pausa antes de avanzar."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Asegúrate de pasar o dedo cara arriba cun movemento vertical."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"Completaches o xesto de ir ao inicio. O próximo é aprender a volver á última pantalla."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"Completaches o xesto de ir ao inicio."</string>
- <string name="home_gesture_intro_title" msgid="836590312858441830">"Pasar o dedo para ir ao inicio"</string>
- <string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Pasa o dedo cara arriba desde a parte inferior da pantalla. Ao facelo, irás á pantalla de inicio."</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Asegúrate de pasar o dedo cara arriba desde o bordo inferior da pantalla."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Proba a manter premida a pantalla máis tempo antes de soltala."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Asegúrate de pasar o dedo cara arriba cun movemento vertical. Despois, fai unha pausa."</string>
- <string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Aprendiches a usar os xestos. Para desactivalos, vai a Configuración."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"Completaches o xesto para cambiar de aplicación."</string>
- <string name="overview_gesture_intro_title" msgid="2902054412868489378">"Pasar o dedo para cambiar de aplicación"</string>
- <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Para cambiar de aplicación, pasa o dedo cara arriba desde abaixo, mantén premido e levanta o dedo."</string>
- <string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"Todo listo"</string>
- <string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Feito"</string>
- <string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Configuración"</string>
- <string name="gesture_tutorial_try_again" msgid="65962545858556697">"Téntao de novo"</string>
- <string name="gesture_tutorial_nice" msgid="2936275692616928280">"Excelente!"</string>
- <string name="gesture_tutorial_step" msgid="1279786122817620968">"Titorial <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
- <string name="allset_title" msgid="5021126669778966707">"Todo listo"</string>
- <string name="allset_hint" msgid="2384632994739392447">"Pasa o dedo cara arriba para ir á pantalla de inicio"</string>
- <string name="allset_description" msgid="6350320429953234580">"Todo está listo para comezar a utilizar o teléfono"</string>
- <string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"Configuración da navegación do sistema"</annotation></string>
- <string name="action_share" msgid="2648470652637092375">"Compartir"</string>
- <string name="action_screenshot" msgid="8171125848358142917">"Facer captura"</string>
- <string name="action_split" msgid="2098009717623550676">"Dividir"</string>
- <string name="toast_split_select_app" msgid="5453865907322018352">"Para usar a pantalla dividida, toca outra app"</string>
- <string name="toast_split_app_unsupported" msgid="3271526028981899666">"A app non admite a función de pantalla dividida."</string>
- <string name="blocked_by_policy" msgid="2071401072261365546">"A aplicación ou a túa organización non permite realizar esta acción"</string>
- <string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Queres omitir o titorial de navegación?"</string>
- <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Podes atopar isto máis tarde na aplicación <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Cancelar"</string>
- <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Omitir"</string>
- <string name="accessibility_rotate_button" msgid="4771825231336502943">"Xira a pantalla"</string>
- <string name="taskbar_edu_opened" msgid="3950252793551919129">"Panel de información de barra de tarefas aberto"</string>
- <string name="taskbar_edu_closed" msgid="126643734478892862">"Panel de información de barra de tarefas pechado"</string>
- <string name="taskbar_edu_switch_apps" msgid="6942863327845784813">"Usa a barra de ferramentas para cambiar de aplicación"</string>
- <string name="taskbar_edu_splitscreen" msgid="2663361731630346489">"Para usar dúas aplicacións á vez, arrastra cara ao lado"</string>
- <string name="taskbar_edu_stashing" msgid="5212374387411764031">"Mantén premida a barra de tarefas para ocultala"</string>
- <string name="taskbar_edu_next" msgid="4007618274426775841">"Seguinte"</string>
- <string name="taskbar_edu_previous" msgid="459202320127201702">"Atrás"</string>
- <string name="taskbar_edu_close" msgid="887022990168191073">"Pechar"</string>
- <string name="taskbar_edu_done" msgid="6880178093977704569">"Feito"</string>
- <string name="taskbar_button_home" msgid="2151398979630664652">"Inicio"</string>
- <string name="taskbar_button_a11y" msgid="5241161324875094465">"Accesibilidade"</string>
- <string name="taskbar_button_back" msgid="8558862226461164514">"Atrás"</string>
- <string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"Selector do IME"</string>
- <string name="taskbar_button_recents" msgid="7273376136216613134">"Recentes"</string>
- <!-- no translation found for taskbar_button_notifications (7471740351507357318) -->
- <skip />
- <!-- no translation found for taskbar_button_quick_settings (227662894293189391) -->
- <skip />
- <string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Mover á parte superior ou á esquerda"</string>
- <string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Mover á parte inferior ou á dereita"</string>
+ <string name="all_apps_label" msgid="8542784161730910663">"Todas as aplicacións"</string>
+ <string name="all_apps_prediction_tip" msgid="2672336544844936186">"As túas aplicacións preditas"</string>
</resources>
diff --git a/quickstep/res/values-gu/strings.xml b/quickstep/res/values-gu/strings.xml
index 6bb100a060..660ad87acc 100644
--- a/quickstep/res/values-gu/strings.xml
+++ b/quickstep/res/values-gu/strings.xml
@@ -19,91 +19,19 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="recent_task_option_split_screen" msgid="5353188922202653570">"સ્ક્રીનને વિભાજિત કરો"</string>
<string name="recent_task_option_pin" msgid="7929860679018978258">"પિન કરો"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"ફ્રિફોર્મ"</string>
+ <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"ઝલક"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"તાજેતરની કોઈ આઇટમ નથી"</string>
+ <string name="accessibility_close_task" msgid="5354563209433803643">"બંધ કરો"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"ઍપ વપરાશનું સેટિંગ"</string>
<string name="recents_clear_all" msgid="5328176793634888831">"બધું સાફ કરો"</string>
<string name="accessibility_recent_apps" msgid="4058661986695117371">"તાજેતરની ઍપ"</string>
- <string name="task_view_closed" msgid="9170038230110856166">"કાર્ય બંધ કર્યું"</string>
<string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
<string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 મિનિટ"</string>
<string name="time_left_for_app" msgid="3111996412933644358">"<xliff:g id="TIME">%1$s</xliff:g> આજે બાકી"</string>
<string name="title_app_suggestions" msgid="4185902664111965088">"ઍપ સૂચનો"</string>
+ <string name="all_apps_label" msgid="8542784161730910663">"બધી ઍપ"</string>
<string name="all_apps_prediction_tip" msgid="2672336544844936186">"તમારી પૂર્વાનુમાનિત ઍપ"</string>
- <string name="hotseat_edu_title_migrate" msgid="306578144424489980">"તમારી હોમ સ્ક્રીનની નીચલી પંક્તિમાં ઍપના સુઝાવો મેળવો"</string>
- <string name="hotseat_edu_title_migrate_landscape" msgid="3633942953997845243">"તમારી હોમ સ્ક્રીનની મનપસંદ પંક્તિમાં ઍપના સુઝાવો મેળવો"</string>
- <string name="hotseat_edu_message_migrate" msgid="8927179260533775320">"તમારી સૌથી વધુ વપરાતી ઍપને સીધી હોમ સ્ક્રીન પરથી જ સરળતાથી ઍક્સેસ કરો. સૂચનો તમારા રૂટિનના આધારે બદલાશે. નીચેની પંક્તિમાં રહેલી ઍપ તમારી હોમ સ્ક્રીન પર ખસેડાશે."</string>
- <string name="hotseat_edu_message_migrate_landscape" msgid="4248943380443387697">"તમારી સૌથી વધુ વપરાતી ઍપને સીધી હોમ સ્ક્રીન પરથી જ સરળતાથી ઍક્સેસ કરો. સૂચનો તમારા રૂટિનના આધારે બદલાશે. મનપસંદ પંક્તિમાં રહેલી ઍપ તમારી હોમ સ્ક્રીન પર ખસેડાશે."</string>
- <string name="hotseat_edu_message_migrate_alt" msgid="3042360119039646356">"તમારી સૌથી વધુ વપરાતી ઍપને સીધી હોમ સ્ક્રીન પરથી જ સરળતાથી ઍક્સેસ કરો. સૂચનો તમારા રૂટિનના આધારે બદલાશે. નીચેની પંક્તિમાં રહેલી ઍપ નવા ફોલ્ડરમાં ખસેડાશે."</string>
- <string name="hotseat_edu_accept" msgid="1611544083278999837">"ઍપ અંગેના સુઝાવો મેળવો"</string>
- <string name="hotseat_edu_dismiss" msgid="2781161822780201689">"ના, આભાર"</string>
- <string name="hotseat_prediction_settings" msgid="6246554993566070818">"સેટિંગ"</string>
- <string name="hotseat_auto_enrolled" msgid="522100018967146807">"સૌથી વધુ વપરાતી ઍપ અહીં દેખાય છે અને રૂટિનના આધારે બદલાય છે"</string>
- <string name="hotseat_tip_no_empty_slots" msgid="1325212677738179185">"ઍપ અંગેના સૂચનો મેળવવા માટે ઍપને નીચલી પંક્તિમાંથી બહાર ખેંચો"</string>
- <string name="hotseat_tip_gaps_filled" msgid="3035673010274223538">"ઍપ અંગેના સૂચનો ખાલી જગ્યામાં ઉમેરાયા"</string>
- <string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"ઍપના સુઝાવો ચાલુ છે"</string>
- <string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"ઍપના સુઝાવો બંધ છે"</string>
- <string name="hotseat_prediction_content_description" msgid="4582028296938078419">"પૂર્વાનુમાનિત ઍપ: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"ખાતરી કરો કે તમે એકદમ દૂરની જમણી કે ડાબી કિનારીએથી સ્વાઇપ કરો છો."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"ખાતરી કરો કે તમે જમણી કે ડાબી કિનારીએથી સ્ક્રીનના મધ્ય ભાગ સુધી સ્વાઇપ કરો છો અને આંગળી ઊંચકી લો છો."</string>
- <string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"પાછળ જવા જમણેથી કેવી રીતે સ્વાઇપ કરવું એ તમે શીખી લીધું છે. હવે પછી, ઍપ સ્વિચ કરવાની રીત જાણો."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"તમે પાછા જવાનો સંકેત પૂર્ણ કર્યો છે."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"ખાતરી કરો કે તમારાથી સ્ક્રીનની એકદમ નીચેની કિનારીની ખૂબ નજીક સુધી સ્વાઇપ ન થઈ જાય."</string>
- <string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"પાછા જવાના સંકેતની સંવેદિતા બદલવા માટે, સેટિંગમાં જાઓ"</string>
- <string name="back_gesture_intro_title" msgid="19551256430224428">"પાછળ જવા માટે સ્વાઇપ કરો"</string>
- <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"છેલ્લી સ્ક્રીન પર પાછા જવા, ડાબી કે જમણી કિનારીએથી સ્ક્રીનના મધ્ય ભાગ સુધી સ્વાઇપ કરો."</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"ખાતરી કરો કે તમે સ્ક્રીનની નીચેની કિનારીએથી ઉપરની તરફ સ્વાઇપ કરો છો."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"ખાતરી કરો કે તમે આંગળી ઊંચકી લેતા પહેલાં સ્વાઇપ કરવાનું થોભાવતા નથી."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"ખાતરી કરો કે તમે સીધું ઉપરની તરફ સ્વાઇપ કરો છો."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"તમે હોમ સ્ક્રીન પર પાછા જવાનો સંકેત પૂર્ણ કર્યો છે. હવે પછી, પાછા જવાની રીત વિશે જાણો."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"તમે હોમ સ્ક્રીન પર પાછા જવાનો સંકેત પૂર્ણ કર્યો છે."</string>
- <string name="home_gesture_intro_title" msgid="836590312858441830">"હોમ સ્ક્રીન પર જવા માટે સ્વાઇપ કરો"</string>
- <string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"તમારી સ્ક્રીનના નીચેના ભાગથી ઉપરની તરફ સ્વાઇપ કરો. આ સંકેત તમને હંમેશાં હોમ સ્ક્રીન પર લઈ જાય છે."</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"ખાતરી કરો કે તમે સ્ક્રીનની નીચેની કિનારીએથી ઉપરની તરફ સ્વાઇપ કરો છો."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"તમારી આંગળી ઊંચકતા પહેલાં તેને વિન્ડો પર થોડી વધારે વાર માટે દબાવી રાખવાનો પ્રયાસ કરો."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"ખાતરી કરો કે તમે સીધું ઉપર સ્વાઇપ કરો છો, પછી થોભી જાઓ છો."</string>
- <string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"સંકેતોનો ઉપયોગ કરવાની રીત વિશે તમે જાણ્યું. સંકેતો બંધ કરવા, સેટિંગમાં જાઓ."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"તમે ઍપ સ્વિચ કરવાનો સંકેત પૂર્ણ કર્યો છે."</string>
- <string name="overview_gesture_intro_title" msgid="2902054412868489378">"ઍપ સ્વિચ કરવા સ્વાઇપ કરો"</string>
- <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"એક ઍપ પરથી બીજી ઍપ પર સ્વિચ કરવા માટે, તમારી સ્ક્રીનના નીચેના ભાગથી ઉપરની તરફ સ્વાઇપ કરીને, થોડીવાર દબાવી રાખો, પછી છોડી દો."</string>
- <string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"બધું સેટ થઈ ગયું"</string>
- <string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"થઈ ગયું"</string>
- <string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"સેટિંગ"</string>
- <string name="gesture_tutorial_try_again" msgid="65962545858556697">"ફરી પ્રયાસ કરો"</string>
- <string name="gesture_tutorial_nice" msgid="2936275692616928280">"સરસ!"</string>
- <string name="gesture_tutorial_step" msgid="1279786122817620968">"ટ્યૂટૉરિઅલ <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
- <string name="allset_title" msgid="5021126669778966707">"બધું સેટ થઈ ગયું!"</string>
- <string name="allset_hint" msgid="2384632994739392447">"હોમપેજ પર જવા માટે ઉપરની તરફ સ્વાઇપ કરો"</string>
- <string name="allset_description" msgid="6350320429953234580">"તમે તમારા ફોનનો ઉપયોગ કરવા માટે તૈયાર છો"</string>
- <string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"સિસ્ટમના નૅવિગેશન સેટિંગ"</annotation></string>
- <string name="action_share" msgid="2648470652637092375">"શેર કરો"</string>
- <string name="action_screenshot" msgid="8171125848358142917">"સ્ક્રીનશૉટ"</string>
- <string name="action_split" msgid="2098009717623550676">"વિભાજિત કરો"</string>
- <string name="toast_split_select_app" msgid="5453865907322018352">"સ્પલિટસ્ક્રીનના વપરાશ માટે, કોઈ અન્ય ઍપ પર ટૅપ કરો"</string>
- <string name="toast_split_app_unsupported" msgid="3271526028981899666">"ઍપ સ્ક્રીન-વિભાજનને સપોર્ટ કરતી નથી."</string>
- <string name="blocked_by_policy" msgid="2071401072261365546">"ઍપ કે તમારી સંસ્થા દ્વારા આ ક્રિયા કરવાની મંજૂરી નથી"</string>
- <string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"નૅવિગેશન ટ્યૂટૉરિઅલ છોડી દઈએ?"</string>
- <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"તમે આને પછીથી <xliff:g id="NAME">%1$s</xliff:g> ઍપમાં જોઈ શકો છો"</string>
- <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"રદ કરો"</string>
- <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"છોડો"</string>
- <string name="accessibility_rotate_button" msgid="4771825231336502943">"સ્ક્રીન ફેરવો"</string>
- <string name="taskbar_edu_opened" msgid="3950252793551919129">"ટાસ્કબારનું શિક્ષણ આપતી પૅનલ દેખાય છે"</string>
- <string name="taskbar_edu_closed" msgid="126643734478892862">"ટાસ્કબારનું શિક્ષણ આપતી પૅનલ બંધ થઈ છે"</string>
- <string name="taskbar_edu_switch_apps" msgid="6942863327845784813">"ઍપ સ્વિચ કરવા માટે, ટાસ્કબારનો ઉપયોગ કરો"</string>
- <string name="taskbar_edu_splitscreen" msgid="2663361731630346489">"એક જ સમયે બે ઍપનો ઉપયોગ કરવા માટે, ખેંચીને બાજુ પર લઈ જાઓ"</string>
- <string name="taskbar_edu_stashing" msgid="5212374387411764031">"ટાસ્કબાર છુપાવવા, તેને ટચ કરીને થોડીવાર દબાવી રાખો"</string>
- <string name="taskbar_edu_next" msgid="4007618274426775841">"આગળ"</string>
- <string name="taskbar_edu_previous" msgid="459202320127201702">"પાછળ"</string>
- <string name="taskbar_edu_close" msgid="887022990168191073">"બંધ કરો"</string>
- <string name="taskbar_edu_done" msgid="6880178093977704569">"થઈ ગયું"</string>
- <string name="taskbar_button_home" msgid="2151398979630664652">"હોમ"</string>
- <string name="taskbar_button_a11y" msgid="5241161324875094465">"ઍક્સેસિબિલિટી"</string>
- <string name="taskbar_button_back" msgid="8558862226461164514">"પાછળ"</string>
- <string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"IME સ્વિચર"</string>
- <string name="taskbar_button_recents" msgid="7273376136216613134">"તાજેતરના"</string>
- <string name="taskbar_button_notifications" msgid="7471740351507357318">"નોટિફિકેશન"</string>
- <string name="taskbar_button_quick_settings" msgid="227662894293189391">"ઝડપી સેટિંગ"</string>
- <string name="move_drop_target_top_or_left" msgid="2988702185049595807">"સૌથી ઉપર ડાબી બાજુએ ખસેડો"</string>
- <string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"સૌથી નીચે જમણી બાજુએ ખસેડો"</string>
</resources>
diff --git a/quickstep/res/values-hi/strings.xml b/quickstep/res/values-hi/strings.xml
index 957125a54c..387d509587 100644
--- a/quickstep/res/values-hi/strings.xml
+++ b/quickstep/res/values-hi/strings.xml
@@ -19,91 +19,19 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="recent_task_option_split_screen" msgid="5353188922202653570">"स्क्रीन को दो हिस्सों में बाँटना (स्प्लिट स्क्रीन)"</string>
<string name="recent_task_option_pin" msgid="7929860679018978258">"पिन करना"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"फ़्रीफ़ॉर्म"</string>
+ <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"खास जानकारी"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"हाल ही में इस्तेमाल किया गया कोई ऐप्लिकेशन नहीं है"</string>
+ <string name="accessibility_close_task" msgid="5354563209433803643">"बंद करें"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"ऐप्लिकेशन इस्तेमाल की सेटिंग"</string>
<string name="recents_clear_all" msgid="5328176793634888831">"सभी ऐप्लिकेशन बंद करें"</string>
<string name="accessibility_recent_apps" msgid="4058661986695117371">"हाल ही में इस्तेमाल किए गए ऐप्लिकेशन"</string>
- <string name="task_view_closed" msgid="9170038230110856166">"टास्क बंद किया गया"</string>
<string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
<string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt;1 मिनट"</string>
<string name="time_left_for_app" msgid="3111996412933644358">"आज <xliff:g id="TIME">%1$s</xliff:g> और चलेगा"</string>
- <string name="title_app_suggestions" msgid="4185902664111965088">"सुझाए गए ऐप्लिकेशन"</string>
+ <string name="title_app_suggestions" msgid="4185902664111965088">"ऐप्लिकेशन के सुझाव"</string>
+ <string name="all_apps_label" msgid="8542784161730910663">"सभी ऐप्लिकेशन"</string>
<string name="all_apps_prediction_tip" msgid="2672336544844936186">"आपके काम के ऐप्लिकेशन"</string>
- <string name="hotseat_edu_title_migrate" msgid="306578144424489980">"अपने होम स्क्रीन की सबसे नीचे वाली पंक्ति में ऐप्लिकेशन के सुझाव पाएं"</string>
- <string name="hotseat_edu_title_migrate_landscape" msgid="3633942953997845243">"अपने होम स्क्रीन की सबसे नीचे वाली पंक्ति में पसंदीदा ऐप्लिकेशन के सुझाव पाएं"</string>
- <string name="hotseat_edu_message_migrate" msgid="8927179260533775320">"आप जिन ऐप्लिकेशन का ज़्यादा इस्तेमाल करते हैं उन्हें सीधा अपने होम स्क्रीन पर पाएं. ऐप्लिकेशन इस्तेमाल करने के आपके रूटीन के हिसाब से सुझाव बदलते रहते हैं. नीचे की पंक्ति के ऐप्लिकेशन होम स्क्रीन पर आ जाएंगे."</string>
- <string name="hotseat_edu_message_migrate_landscape" msgid="4248943380443387697">"सबसे ज़्यादा इस्तेमाल होने वाले ऐप्लिकेशन सीधे होम स्क्रीन पर देखें. आप ऐप्लिकेशन का कितना इस्तेमाल कर रहे हैं, उसके हिसाब से सुझाव बदलते रहते हैं. आपके पसंदीदा ऐप्लिकेशन, होम स्क्रीन पर नीचे की पंक्ति में दिखाई देंगे."</string>
- <string name="hotseat_edu_message_migrate_alt" msgid="3042360119039646356">"सबसे ज़्यादा इस्तेमाल होने वाले ऐप्लिकेशन, सीधे होम स्क्रीन पर पाएं. आपके ऐप्लिकेशन इस्तेमाल करने के रूटीन के हिसाब से सुझाव बदलते रहते हैं. नीचे की पंक्ति के ऐप्लिकेशन एक नए फ़ोल्डर में चले जाएंगे."</string>
- <string name="hotseat_edu_accept" msgid="1611544083278999837">"ऐप्लिकेशन के बारे में सुझाव पाएं"</string>
- <string name="hotseat_edu_dismiss" msgid="2781161822780201689">"रहने दें"</string>
- <string name="hotseat_prediction_settings" msgid="6246554993566070818">"सेटिंग"</string>
- <string name="hotseat_auto_enrolled" msgid="522100018967146807">"सबसे ज़्यादा इस्तेमाल होने वाले ऐप्लिकेशन यहां दिखेंगे. यह ऐप्लिकेशन, आपके इस्तेमाल के रूटीन के हिसाब से बदलते रहते हैं"</string>
- <string name="hotseat_tip_no_empty_slots" msgid="1325212677738179185">"नीचे वाली पंक्ति से ऐप्लिकेशन को खींचकर हटाएं, ताकि आप ऐप्लिकेशन के सुझाव पा सकें"</string>
- <string name="hotseat_tip_gaps_filled" msgid="3035673010274223538">"खाली जगह पर ऐप्लिकेशन के सुझाव जोड़े गए"</string>
- <string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"सुझाए गए ऐप्लिकेशन की सुविधा चालू है"</string>
- <string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"सुझाए गए ऐप्लिकेशन की सुविधा बंद है"</string>
- <string name="hotseat_prediction_content_description" msgid="4582028296938078419">"सुझाया गया ऐप्लिकेशन: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"पक्का करें कि आप स्क्रीन की दाईं या बाईं ओर के बिल्कुल किनारे से स्वाइप कर रहे हों."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"स्क्रीन के दाएं या बाएं किनारे से स्क्रीन के बीच तक स्वाइप करें और अपनी उंगली उठा लें."</string>
- <string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"आपने स्क्रीन के दाएं किनारे से स्वाइप करके, पिछली स्क्रीन पर वापस जाने का तरीका सीख लिया है. अब, एक ऐप से दूसरे ऐप पर जाने का तरीका सीखें."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"आपने पेज पर पीछे ले जाने वाले हाथ के जेस्चर (हाव-भाव) के बारे में जान लिया है."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"देख लें कि आप स्क्रीन पर बिल्कुल नीचे तक स्वाइप न कर रहे हों."</string>
- <string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"\'सेटिंग\' में जाकर, पीछे जाने के लिए इस्तेमाल होने वाले हाथ के जेस्चर (हाव-भाव) की संवेदनशीलता बदलें"</string>
- <string name="back_gesture_intro_title" msgid="19551256430224428">"पिछली स्क्रीन पर वापस जाने के लिए स्वाइप करें"</string>
- <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"पिछली स्क्रीन पर वापस जाने के लिए, स्क्रीन के बाएं या दाएं किनारे से बीचों-बीच तक स्वाइप करें."</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"देख लें कि आप स्क्रीन के निचले किनारे से ऊपर की ओर स्वाइप कर रहे हों."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"देख लें कि आप स्क्रीन से अपनी उंगली उठाने से पहले, इसे कहीं न रोक रहे हों."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"देख लें कि आप ऊपर की ओर बिल्कुल सीधे स्वाइप कर रहे हों."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"आपने होम स्क्रीन पर ले जाने वाले हाथ के जेस्चर के बारे में जान लिया है. अब, वापस जाने का तरीका जानें."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"आपने होम स्क्रीन पर ले जाने वाले हाथ के जेस्चर (हाव-भाव) के बारे में जान लिया है."</string>
- <string name="home_gesture_intro_title" msgid="836590312858441830">"होम स्क्रीन पर जाने के लिए स्वाइप करें"</string>
- <string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"स्क्रीन पर नीचे से ऊपर की ओर स्वाइप करें. हाथ का यह जेस्चर आपको हमेशा होम स्क्रीन पर ले जाता है."</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"देख लें कि आप स्क्रीन के निचले किनारे से ऊपर की ओर स्वाइप कर रहे हों."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"कोशिश करें कि स्क्रीन से उंगली उठाने से पहले, इसे कुछ देर स्क्रीन पर दबाकर रखें."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"देख लें कि आप स्क्रीन पर ऊपर की तरफ़, बिल्कुल सीधे स्वाइप कर रहे हों और फिर रुकें."</string>
- <string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"आपने हाथ के जेस्चर (हाव-भाव) इस्तेमाल करने सीख लिए हैं. जेस्चर बंद करने के लिए, सेटिंग में जाएं."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"आपने एक ऐप्लिकेशन से दूसरे पर जाने के लिए इस्तेमाल होने वाले हाथ के जेस्चर के बारे में जान लिया है."</string>
- <string name="overview_gesture_intro_title" msgid="2902054412868489378">"एक ऐप्लिकेशन से दूसरे पर जाने के लिए स्वाइप करें"</string>
- <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"एक ऐप से दूसरे पर जाने के लिए, स्क्रीन पर नीचे से ऊपर की ओर स्वाइप करें, दबाकर रखें, और फिर छोड़ दें."</string>
- <string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"आप पूरी तरह तैयार हैं"</string>
- <string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"हो गया"</string>
- <string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"सेटिंग"</string>
- <string name="gesture_tutorial_try_again" msgid="65962545858556697">"फिर से कोशिश करें"</string>
- <string name="gesture_tutorial_nice" msgid="2936275692616928280">"बहुत बढ़िया!"</string>
- <string name="gesture_tutorial_step" msgid="1279786122817620968">"ट्यूटोरियल <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
- <string name="allset_title" msgid="5021126669778966707">"हो गया!"</string>
- <string name="allset_hint" msgid="2384632994739392447">"होम स्क्रीन पर जाने के लिए, ऊपर की ओर स्वाइप करें"</string>
- <string name="allset_description" msgid="6350320429953234580">"अब आप अपना फ़ोन इस्तेमाल कर सकते हैं"</string>
- <string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"सिस्टम नेविगेशन सेटिंग"</annotation></string>
- <string name="action_share" msgid="2648470652637092375">"शेयर करें"</string>
- <string name="action_screenshot" msgid="8171125848358142917">"स्क्रीनशॉट लें"</string>
- <string name="action_split" msgid="2098009717623550676">"स्प्लिट स्क्रीन मोड"</string>
- <string name="toast_split_select_app" msgid="5453865907322018352">"स्प्लिट स्क्रीन मोड के लिए, दूसरे ऐप पर टैप करें"</string>
- <string name="toast_split_app_unsupported" msgid="3271526028981899666">"यह ऐप्लिकेशन, स्प्लिट स्क्रीन पर काम नहीं करता है."</string>
- <string name="blocked_by_policy" msgid="2071401072261365546">"ऐप्लिकेशन या आपका संगठन इस कार्रवाई की अनुमति नहीं देता"</string>
- <string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"नेविगेशन ट्यूटोरियल छोड़ना चाहते हैं?"</string>
- <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"आप बाद में <xliff:g id="NAME">%1$s</xliff:g> ऐप्लिकेशन पर इसे देख सकते हैं"</string>
- <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"अभी नहीं"</string>
- <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"अभी नहीं"</string>
- <string name="accessibility_rotate_button" msgid="4771825231336502943">"स्क्रीन घुमाएं"</string>
- <string name="taskbar_edu_opened" msgid="3950252793551919129">"टास्कबार ट्यूटोरियल दिखाया गया"</string>
- <string name="taskbar_edu_closed" msgid="126643734478892862">"टास्कबार ट्यूटोरियल बंद किया गया"</string>
- <string name="taskbar_edu_switch_apps" msgid="6942863327845784813">"ऐप्लिकेशन स्विच करने के लिए, टास्कबार का इस्तेमाल करें"</string>
- <string name="taskbar_edu_splitscreen" msgid="2663361731630346489">"एक साथ दो ऐप्लिकेशन इस्तेमाल करने के लिए, उन्हें किनारे की ओर खींचें और छोड़ें"</string>
- <string name="taskbar_edu_stashing" msgid="5212374387411764031">"टास्कबार को छिपाने के लिए, उसे दबाकर रखें"</string>
- <string name="taskbar_edu_next" msgid="4007618274426775841">"आगे बढ़ें"</string>
- <string name="taskbar_edu_previous" msgid="459202320127201702">"वापस जाएं"</string>
- <string name="taskbar_edu_close" msgid="887022990168191073">"बंद करें"</string>
- <string name="taskbar_edu_done" msgid="6880178093977704569">"हो गया"</string>
- <string name="taskbar_button_home" msgid="2151398979630664652">"होम"</string>
- <string name="taskbar_button_a11y" msgid="5241161324875094465">"सुलभता"</string>
- <string name="taskbar_button_back" msgid="8558862226461164514">"वापस जाएं"</string>
- <string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"IME स्विचर"</string>
- <string name="taskbar_button_recents" msgid="7273376136216613134">"हाल ही के"</string>
- <string name="taskbar_button_notifications" msgid="7471740351507357318">"सूचनाएं"</string>
- <string name="taskbar_button_quick_settings" msgid="227662894293189391">"फटाफट सेटिंग"</string>
- <string name="move_drop_target_top_or_left" msgid="2988702185049595807">"ऊपर/बाईं तरफ़ ले जाएं"</string>
- <string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"नीचे/दाईं तरफ़ ले जाएं"</string>
</resources>
diff --git a/quickstep/res/values-hr/strings.xml b/quickstep/res/values-hr/strings.xml
index 6c29822c69..ab56e57b50 100644
--- a/quickstep/res/values-hr/strings.xml
+++ b/quickstep/res/values-hr/strings.xml
@@ -19,91 +19,19 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Podijeljeni zaslon"</string>
<string name="recent_task_option_pin" msgid="7929860679018978258">"Prikvači"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Slobodni oblik"</string>
+ <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Pregled"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"Nema nedavnih stavki"</string>
+ <string name="accessibility_close_task" msgid="5354563209433803643">"Zatvori"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Postavke upotrebe aplikacija"</string>
<string name="recents_clear_all" msgid="5328176793634888831">"Izbriši sve"</string>
<string name="accessibility_recent_apps" msgid="4058661986695117371">"Nedavne aplikacije"</string>
- <string name="task_view_closed" msgid="9170038230110856166">"Zadatak je zatvoren"</string>
<string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
<string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 min"</string>
<string name="time_left_for_app" msgid="3111996412933644358">"Još <xliff:g id="TIME">%1$s</xliff:g> danas"</string>
- <string name="title_app_suggestions" msgid="4185902664111965088">"Prijedlozi aplikacija"</string>
+ <string name="title_app_suggestions" msgid="4185902664111965088">"Predložene aplikacije"</string>
+ <string name="all_apps_label" msgid="8542784161730910663">"Sve aplikacije"</string>
<string name="all_apps_prediction_tip" msgid="2672336544844936186">"Vaše predviđene aplikacije"</string>
- <string name="hotseat_edu_title_migrate" msgid="306578144424489980">"Primajte prijedloge aplikacija u donjem retku početnog zaslona"</string>
- <string name="hotseat_edu_title_migrate_landscape" msgid="3633942953997845243">"Primajte prijedloge aplikacija u retku omiljenih na početnom zaslonu"</string>
- <string name="hotseat_edu_message_migrate" msgid="8927179260533775320">"Lako pristupite najčešće upotrebljavanim aplikacijama s početnog zaslona. Prijedlozi će se mijenjati na temelju vaših rutina. Aplikacije iz donjeg retka pomaknut će se na početni zaslon."</string>
- <string name="hotseat_edu_message_migrate_landscape" msgid="4248943380443387697">"Lako pristupite najčešće upotrebljavanim aplikacijama s početnog zaslona. Prijedlozi će se mijenjati na temelju vaših rutina. Aplikacije koje se nalaze u retku omiljenih pomaknut će se na početni zaslon."</string>
- <string name="hotseat_edu_message_migrate_alt" msgid="3042360119039646356">"Lako pristupite najčešće upotrebljavanim aplikacijama s početnog zaslona. Prijedlozi će se mijenjati na temelju vaših rutina. Aplikacije iz donjeg retka pomaknut će se u novu mapu."</string>
- <string name="hotseat_edu_accept" msgid="1611544083278999837">"Predloži mi aplikacije"</string>
- <string name="hotseat_edu_dismiss" msgid="2781161822780201689">"Ne, hvala"</string>
- <string name="hotseat_prediction_settings" msgid="6246554993566070818">"Postavke"</string>
- <string name="hotseat_auto_enrolled" msgid="522100018967146807">"Ovdje se prikazuju najčešće upotrebljavane aplikacije i mijenjaju se na temelju rutina"</string>
- <string name="hotseat_tip_no_empty_slots" msgid="1325212677738179185">"Povucite aplikacije iz donjeg retka da biste dobili prijedloge aplikacija"</string>
- <string name="hotseat_tip_gaps_filled" msgid="3035673010274223538">"Predložene aplikacije dodane u prazan prostor"</string>
- <string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Predlaganje apl. omogućeno"</string>
- <string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Predlaganje apl. onemogućeno"</string>
- <string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Predviđena aplikacija: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Pazite da prijeđete prstom od krajnjeg desnog ili krajnjeg lijevog ruba."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Pazite da prijeđete prstom od desnog ili lijevog ruba do sredine zaslona i podignite prst."</string>
- <string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Naučili ste kako prijeći prstom zdesna da biste se vratili. Sad saznajte kako promijeniti aplikaciju."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"Izvršili ste pokret za povratak."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Pazite da ne prijeđete prstom preblizu dnu zaslona."</string>
- <string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"Osjetljivost pokreta povratka promijenite u postavkama"</string>
- <string name="back_gesture_intro_title" msgid="19551256430224428">"Prijeđite prstom da biste se vratili"</string>
- <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"Za povratak na zadnji zaslon prijeđite prstom od lijevog ili desnog ruba do sredine zaslona."</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Pazite da prijeđete prstom prema gore od donjeg ruba zaslona."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Pazite da ne zastanete prije podizanja prsta."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Pazite da prijeđete prstom ravno prema gore."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"Izvršili ste pokret za otvaranje početnog zaslona. Sad saznajte kako se vratiti."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"Izvršili ste pokret za otvaranje početnog zaslona."</string>
- <string name="home_gesture_intro_title" msgid="836590312858441830">"Prijeđite prstom da biste otvorili početni zaslon"</string>
- <string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Prijeđite prstom od dna zaslona prema gore. Tim pokretom uvijek će se otvoriti početni zaslon."</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Pazite da prijeđete prstom prema gore od donjeg ruba zaslona."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Pokušajte zadržati prozor dulje prije podizanja prsta."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Pazite da prijeđete prstom ravno prema gore, a zatim zastanete."</string>
- <string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Naučili ste koristiti pokrete. Pokrete možete isključiti u postavkama."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"Izvršili ste pokret za promjenu aplikacije."</string>
- <string name="overview_gesture_intro_title" msgid="2902054412868489378">"Povlačenje prstom za promjenu aplikacije"</string>
- <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Za promjenu aplikacije prijeđite prstom od dna zaslona prema gore, zadržite pritisak pa pustite."</string>
- <string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"Sve je spremno"</string>
- <string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Gotovo"</string>
- <string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Postavke"</string>
- <string name="gesture_tutorial_try_again" msgid="65962545858556697">"Pokušajte ponovo"</string>
- <string name="gesture_tutorial_nice" msgid="2936275692616928280">"Odlično!"</string>
- <string name="gesture_tutorial_step" msgid="1279786122817620968">"Vodič <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
- <string name="allset_title" msgid="5021126669778966707">"Sve je spremno!"</string>
- <string name="allset_hint" msgid="2384632994739392447">"Prijeđite prstom prema gore da biste otvorili početni zaslon"</string>
- <string name="allset_description" msgid="6350320429953234580">"Spremni ste za početak upotrebe telefona"</string>
- <string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"Postavke navigacije sustavom"</annotation></string>
- <string name="action_share" msgid="2648470652637092375">"Podijeli"</string>
- <string name="action_screenshot" msgid="8171125848358142917">"Snimka zaslona"</string>
- <string name="action_split" msgid="2098009717623550676">"Podijeli"</string>
- <string name="toast_split_select_app" msgid="5453865907322018352">"Dodirnite drugu aplikaciju za podijeljeni zaslon"</string>
- <string name="toast_split_app_unsupported" msgid="3271526028981899666">"Aplikacija ne podržava podijeljeni zaslon."</string>
- <string name="blocked_by_policy" msgid="2071401072261365546">"Aplikacija ili vaša organizacija ne dopuštaju ovu radnju"</string>
- <string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Želite li preskočiti vodič za kretanje?"</string>
- <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Kasnije ga možete pronaći u aplikaciji <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Odustani"</string>
- <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Preskoči"</string>
- <string name="accessibility_rotate_button" msgid="4771825231336502943">"Zakretanje zaslona"</string>
- <string name="taskbar_edu_opened" msgid="3950252793551919129">"Upute za programsku traku su se pojavile"</string>
- <string name="taskbar_edu_closed" msgid="126643734478892862">"Upute za programsku traku su zatvorene"</string>
- <string name="taskbar_edu_switch_apps" msgid="6942863327845784813">"Upotrijebite program. traku da biste promijenili aplikaciju"</string>
- <string name="taskbar_edu_splitscreen" msgid="2663361731630346489">"Povucite u stranu da biste istovremeno koristili dvije aplikacije"</string>
- <string name="taskbar_edu_stashing" msgid="5212374387411764031">"Dodirnite i zadržite da biste sakrili programsku traku"</string>
- <string name="taskbar_edu_next" msgid="4007618274426775841">"Dalje"</string>
- <string name="taskbar_edu_previous" msgid="459202320127201702">"Natrag"</string>
- <string name="taskbar_edu_close" msgid="887022990168191073">"Zatvori"</string>
- <string name="taskbar_edu_done" msgid="6880178093977704569">"Gotovo"</string>
- <string name="taskbar_button_home" msgid="2151398979630664652">"Početna"</string>
- <string name="taskbar_button_a11y" msgid="5241161324875094465">"Pristupačnost"</string>
- <string name="taskbar_button_back" msgid="8558862226461164514">"Natrag"</string>
- <string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"IME prekidač"</string>
- <string name="taskbar_button_recents" msgid="7273376136216613134">"Najnovije"</string>
- <string name="taskbar_button_notifications" msgid="7471740351507357318">"Obavijesti"</string>
- <string name="taskbar_button_quick_settings" msgid="227662894293189391">"Brze postavke"</string>
- <string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Premjesti gore/lijevo"</string>
- <string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Premjesti dolje/desno"</string>
</resources>
diff --git a/quickstep/res/values-hu/strings.xml b/quickstep/res/values-hu/strings.xml
index 5b1aff9896..dec6ea0158 100644
--- a/quickstep/res/values-hu/strings.xml
+++ b/quickstep/res/values-hu/strings.xml
@@ -19,93 +19,19 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="recent_task_option_pin" msgid="7929860679018978258">"Kitűzés"</string>
+ <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Osztott képernyő"</string>
+ <string name="recent_task_option_pin" msgid="7929860679018978258">"Rögzítés"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Szabad forma"</string>
+ <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Áttekintés"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"Nincsenek mostanában használt elemek"</string>
+ <string name="accessibility_close_task" msgid="5354563209433803643">"Bezárás"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Alkalmazáshasználati beállítások"</string>
<string name="recents_clear_all" msgid="5328176793634888831">"Összes törlése"</string>
<string name="accessibility_recent_apps" msgid="4058661986695117371">"Legutóbbi alkalmazások"</string>
- <string name="task_view_closed" msgid="9170038230110856166">"A feladat bezárult"</string>
<string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
<string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 perc"</string>
<string name="time_left_for_app" msgid="3111996412933644358">"Ma még <xliff:g id="TIME">%1$s</xliff:g> van hátra"</string>
<string name="title_app_suggestions" msgid="4185902664111965088">"Alkalmazásjavaslatok"</string>
+ <string name="all_apps_label" msgid="8542784161730910663">"Az összes alkalmazás"</string>
<string name="all_apps_prediction_tip" msgid="2672336544844936186">"Várható alkalmazások"</string>
- <string name="hotseat_edu_title_migrate" msgid="306578144424489980">"Alkalmazásjavaslatokat kaphat a kezdőképernyő alsó sorában"</string>
- <string name="hotseat_edu_title_migrate_landscape" msgid="3633942953997845243">"Alkalmazásjavaslatokat kaphat a kezdőképernyőn megjelenő kedvencek sorában"</string>
- <string name="hotseat_edu_message_migrate" msgid="8927179260533775320">"A kezdőképernyőről könnyedén hozzáférhet a leggyakrabban használt alkalmazásokhoz. A javaslatok a rutinjai alapján változni fognak. Az alsó sorban lévő alkalmazások felkerülnek a kezdőképernyőre."</string>
- <string name="hotseat_edu_message_migrate_landscape" msgid="4248943380443387697">"A kezdőképernyőről könnyedén hozzáférhet a leggyakrabban használt alkalmazásokhoz. A javaslatok a rutinjai alapján változnak majd. A kedvencek sorában lévő alkalmazások a kezdőképernyőre kerülnek."</string>
- <string name="hotseat_edu_message_migrate_alt" msgid="3042360119039646356">"A kezdőképernyőről könnyedén hozzáférhet a leggyakrabban használt alkalmazásokhoz. A javaslatok a rutinjai alapján változni fognak. Az alsó sorban lévő alkalmazások egy új mappába kerülnek."</string>
- <string name="hotseat_edu_accept" msgid="1611544083278999837">"Kérek javaslatokat"</string>
- <string name="hotseat_edu_dismiss" msgid="2781161822780201689">"Köszönöm, nem"</string>
- <string name="hotseat_prediction_settings" msgid="6246554993566070818">"Beállítások"</string>
- <string name="hotseat_auto_enrolled" msgid="522100018967146807">"A leggyakrabban használt alkalmazások jelennek meg itt; a lista a rutinok alapján változhat"</string>
- <string name="hotseat_tip_no_empty_slots" msgid="1325212677738179185">"Alkalmazásjavaslatok kéréséhez húzzon ki alkalmazásokat az alsó sorból"</string>
- <string name="hotseat_tip_gaps_filled" msgid="3035673010274223538">"Alkalmazásjavaslatok hozzáadva az üres területhez"</string>
- <string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Alkalmazásjavaslatok engedélyezve"</string>
- <string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Alkalmazásjavaslatok letiltva"</string>
- <string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Várható alkalmazás: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Csúsztasson a képernyő jobb vagy bal széléről."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Csúsztassa ujját a képernyő jobb vagy bal széléről a képernyő közepéig, majd emelje fel."</string>
- <string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Megtanulta, hogyan léphet vissza jobbról csúsztatva. A következő az appok közötti váltás."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"Teljesítette a visszalépési kézmozdulatot."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Ne csúsztasson túl közel a képernyő aljához."</string>
- <string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"A vissza mozdulat érzékenysége a Beállításokban módosítható"</string>
- <string name="back_gesture_intro_title" msgid="19551256430224428">"Csúsztasson a visszalépéshez"</string>
- <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"Ha visszatérne a legutóbbi képernyőre, csúsztasson a képernyő közepére a bal vagy a jobb széléről."</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Csúsztasson felfelé a képernyő aljától."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Ne álljon meg, mielőtt elengedi a képernyőt."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Csúsztasson egyenesen felfelé."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"Teljesítette a kezdőképernyőre lépés kézmozdulatát. Most megtanulhatja, hogyan léphet vissza."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"Teljesítette a kezdőképernyőre lépés kézmozdulatát."</string>
- <string name="home_gesture_intro_title" msgid="836590312858441830">"Csúsztatás a kezdőképernyőre lépéshez"</string>
- <string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Csúsztassa ujját felfelé a képernyő aljától. Ez a mozdulat mindig a kezdőképernyőre visz."</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Csúsztasson felfelé a képernyő aljától."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Próbálja tovább lenyomva tartani az ablakot, mielőtt elengedi a képernyőt."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Csúsztasson egyenesen felfelé, majd várjon egy kicsit."</string>
- <string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Eddig megismerhette a kézmozdulatok használatát. A kézmozdulatokat a Beállításokban kapcsolhatja ki."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"Teljesítette az alkalmazásváltás kézmozdulatát."</string>
- <string name="overview_gesture_intro_title" msgid="2902054412868489378">"Alkalmazásváltás csúsztatással"</string>
- <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Appok közti váltáshoz csúsztasson felfelé a kép aljáról, tartsa lenyomva az ujját, majd emelje fel."</string>
- <string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"Minden kész"</string>
- <string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Kész"</string>
- <string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Beállítások"</string>
- <string name="gesture_tutorial_try_again" msgid="65962545858556697">"Újra"</string>
- <string name="gesture_tutorial_nice" msgid="2936275692616928280">"Remek!"</string>
- <string name="gesture_tutorial_step" msgid="1279786122817620968">"Útmutató (<xliff:g id="TOTAL">%2$d</xliff:g>/<xliff:g id="CURRENT">%1$d</xliff:g>.)"</string>
- <string name="allset_title" msgid="5021126669778966707">"Kész is!"</string>
- <string name="allset_hint" msgid="2384632994739392447">"Felfelé csúsztatva megjelenik a Kezdőképernyő"</string>
- <string name="allset_description" msgid="6350320429953234580">"Készen áll a telefon használatára"</string>
- <string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"Rendszer-navigációs beállítások"</annotation></string>
- <string name="action_share" msgid="2648470652637092375">"Megosztás"</string>
- <string name="action_screenshot" msgid="8171125848358142917">"Képernyőkép"</string>
- <string name="action_split" msgid="2098009717623550676">"Felosztás"</string>
- <string name="toast_split_select_app" msgid="5453865907322018352">"Koppintson másik appra a képernyőmegosztáshoz"</string>
- <string name="toast_split_app_unsupported" msgid="3271526028981899666">"Az alkalmazás nem támogatja az osztott képernyőt."</string>
- <string name="blocked_by_policy" msgid="2071401072261365546">"Az alkalmazás vagy az Ön szervezete nem engedélyezi ezt a műveletet"</string>
- <string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Kihagyja a navigáció bemutatóját?"</string>
- <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Ezt később megtalálhatja a(z) <xliff:g id="NAME">%1$s</xliff:g> alkalmazásban"</string>
- <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Mégse"</string>
- <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Kihagyás"</string>
- <string name="accessibility_rotate_button" msgid="4771825231336502943">"Képernyő elforgatása"</string>
- <string name="taskbar_edu_opened" msgid="3950252793551919129">"Az eszköztár használatát ismertető panel megjelent"</string>
- <string name="taskbar_edu_closed" msgid="126643734478892862">"Az eszköztár használatát ismertető panel bezárult"</string>
- <string name="taskbar_edu_switch_apps" msgid="6942863327845784813">"Az eszköztárral válthat az alkalmazások között"</string>
- <string name="taskbar_edu_splitscreen" msgid="2663361731630346489">"Húzza oldalra, ha egyszerre két appot szeretne használni"</string>
- <string name="taskbar_edu_stashing" msgid="5212374387411764031">"Nyomva tartással elrejthető az eszköztár"</string>
- <string name="taskbar_edu_next" msgid="4007618274426775841">"Tovább"</string>
- <string name="taskbar_edu_previous" msgid="459202320127201702">"Vissza"</string>
- <string name="taskbar_edu_close" msgid="887022990168191073">"Bezárás"</string>
- <string name="taskbar_edu_done" msgid="6880178093977704569">"Kész"</string>
- <string name="taskbar_button_home" msgid="2151398979630664652">"Kezdőlap"</string>
- <string name="taskbar_button_a11y" msgid="5241161324875094465">"Kisegítő lehetőségek"</string>
- <string name="taskbar_button_back" msgid="8558862226461164514">"Vissza"</string>
- <string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"IME-váltó"</string>
- <string name="taskbar_button_recents" msgid="7273376136216613134">"Legutóbbiak"</string>
- <!-- no translation found for taskbar_button_notifications (7471740351507357318) -->
- <skip />
- <!-- no translation found for taskbar_button_quick_settings (227662894293189391) -->
- <skip />
- <string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Mozgatás felülre vagy a bal oldalra"</string>
- <string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Mozgatás alulra vagy a jobb oldalra"</string>
</resources>
diff --git a/quickstep/res/values-hy/strings.xml b/quickstep/res/values-hy/strings.xml
index df7307834a..1656a1444d 100644
--- a/quickstep/res/values-hy/strings.xml
+++ b/quickstep/res/values-hy/strings.xml
@@ -19,91 +19,19 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Տրոհել էկրանը"</string>
<string name="recent_task_option_pin" msgid="7929860679018978258">"Ամրացնել"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Կամայական ձև"</string>
+ <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Ընդհանուր տեղեկություններ"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"Վերջին տարրեր չկան"</string>
+ <string name="accessibility_close_task" msgid="5354563209433803643">"Փակել"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Հավելվածի օգտագործման կարգավորումներ"</string>
<string name="recents_clear_all" msgid="5328176793634888831">"Փակել բոլորը"</string>
<string name="accessibility_recent_apps" msgid="4058661986695117371">"Վերջին օգտագործած հավելվածները"</string>
- <string name="task_view_closed" msgid="9170038230110856166">"Առաջադրանքը փակված է"</string>
<string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
<string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 ր"</string>
<string name="time_left_for_app" msgid="3111996412933644358">"Այսօր մնացել է՝ <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="title_app_suggestions" msgid="4185902664111965088">"Առաջարկվող հավելվածներ"</string>
+ <string name="all_apps_label" msgid="8542784161730910663">"Բոլոր հավելվածները"</string>
<string name="all_apps_prediction_tip" msgid="2672336544844936186">"Ձեր կանխատեսված հավելվածները"</string>
- <string name="hotseat_edu_title_migrate" msgid="306578144424489980">"Ստացեք հավելվածների առաջարկներ հիմնական էկրանի ներքևում"</string>
- <string name="hotseat_edu_title_migrate_landscape" msgid="3633942953997845243">"Ստացեք հավելվածների առաջարկներ հիմնական էկրանի «Ընտրանի» տողում"</string>
- <string name="hotseat_edu_message_migrate" msgid="8927179260533775320">"Արագ բացեք հաճախ օգտագործվող հավելվածներն անմիջապես հիմնական էկրանից։ Առաջարկները կփոփոխվեն՝ կախված ձեր գործողություններից։ Ներքևում ցուցադրվող հավելվածները կտեղափոխվեն հիմնական էկրանի վերևի մաս։"</string>
- <string name="hotseat_edu_message_migrate_landscape" msgid="4248943380443387697">"Արագ բացեք հաճախ օգտագործվող հավելվածներն անմիջապես հիմնական էկրանից։ Առաջարկները կփոփոխվեն՝ կախված ձեր գործողություններից։ «Ընտրանի» տողի հավելվածները կտեղափոխվեն հիմնական էկրան։"</string>
- <string name="hotseat_edu_message_migrate_alt" msgid="3042360119039646356">"Արագ բացեք հաճախ օգտագործվող հավելվածներն անմիջապես հիմնական էկրանից։ Առաջարկները կփոփոխվեն՝ կախված ձեր գործողություններից։ Ներքևում ցուցադրվող հավելվածները կտեղափոխվեն նոր պանակ։"</string>
- <string name="hotseat_edu_accept" msgid="1611544083278999837">"Ստանալ հավելվածների առաջարկներ"</string>
- <string name="hotseat_edu_dismiss" msgid="2781161822780201689">"Ոչ, շնորհակալություն"</string>
- <string name="hotseat_prediction_settings" msgid="6246554993566070818">"Կարգավորումներ"</string>
- <string name="hotseat_auto_enrolled" msgid="522100018967146807">"Հաճախ օգտագործվող հավելվածները ցուցադրվում են այստեղ և փոփոխվում են ըստ ձեր գործողությունների հերթականության։"</string>
- <string name="hotseat_tip_no_empty_slots" msgid="1325212677738179185">"Քաշեք հավելվածները ներքևի տողից՝ հավելվածների առաջարկները տեսնելու համար"</string>
- <string name="hotseat_tip_gaps_filled" msgid="3035673010274223538">"Առաջարկվող հավելվածները կավելացվեն ազատ տեղերում"</string>
- <string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"«Առաջարկվող հավելվածներ» գործառույթը միացված է"</string>
- <string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"«Առաջարկվող հավելվածներ» գործառույթն անջատված է"</string>
- <string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Առաջարկվող հավելված՝ <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Համոզվեք, որ մատը սահեցնում եք էկրանի աջ կամ ձախ եզրից։"</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Մատը սահեցրեք էկրանի աջ կամ ձախ եզրից դեպի կենտրոն և բաց թողեք։"</string>
- <string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Դուք սովորեցիք՝ ինչպես մատը աջից սահեցնելով հետ գնալ։ Այժմ սովորենք՝ ինչպես անցնել մի հավելվածից մյուսը։"</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"Դուք սովորեցիք հետ գնալու ժեստը։"</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Համոզվեք, որ մատը չափազանց մոտ չեք սահեցնում էկրանին ներքևի հատվածին։"</string>
- <string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"Հետ գնալու ժեստի զգայունությունը փոփոխեք կարգավորումներում"</string>
- <string name="back_gesture_intro_title" msgid="19551256430224428">"Սահեցրեք մատը՝ հետ գնալու համար"</string>
- <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"Վերջին էկրան վերադառնալու համար էկրանի աջ կամ ձախ եզրից մատը սահեցրեք դեպի կենտրոն։"</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Համոզվեք, որ մատն էկրանի ներքևի եզրից վերև եք սահեցնում։"</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Համոզվեք, որ դադար չեք տալիս նախքան բաց թողնելը։"</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Համոզվեք, որ մատն ուղիղ վերև եք սահեցնում։"</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"Դուք սովորեցիք հիմնական էկրան անցնելու ժեստը։ Այժմ սովորենք՝ ինչպես հետ գնալ։"</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"Դուք սովորեցիք հիմնական էկրան անցնելու ժեստը։"</string>
- <string name="home_gesture_intro_title" msgid="836590312858441830">"Սահեցրեք մատը՝ հիմնական էկրան անցնելու համար"</string>
- <string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Մատը սահեցրեք էկրանի ներքևից վերև։ Այս ժեստը բացում է հիմնական էկրանը։"</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Համոզվեք, որ մատն էկրանի ներքևի եզրից վերև եք սահեցնում։"</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Նախքան բաց թողնելը փորձեք հնարավորինս երկար պահել պատուհանը։"</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Համոզվեք, որ մատն ուղիղ վերև եք սահեցնում, այնուհետև դադար տվեք։"</string>
- <string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Դուք սովորեցիք՝ ինչպես օգտագործել ժեստերը։ Ժեստերը կարող եք անջատել կարգավորումներում։"</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"Դուք սովորեցիք մի հավելվածից մյուսն անցնելու ժեստը։"</string>
- <string name="overview_gesture_intro_title" msgid="2902054412868489378">"Մատը սահեցրեք՝ մյուս հավելվածին անցնելու համար"</string>
- <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Մեկ հավելվածից մյուսն անցնելու համար մատը էկրանի ներքևից սահեցրեք վերև, ապա հեռացրեք այն էկրանից։"</string>
- <string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"Պատրաստ է"</string>
- <string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Պատրաստ է"</string>
- <string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Կարգավորումներ"</string>
- <string name="gesture_tutorial_try_again" msgid="65962545858556697">"Նորից փորձեք"</string>
- <string name="gesture_tutorial_nice" msgid="2936275692616928280">"Գերազանց է"</string>
- <string name="gesture_tutorial_step" msgid="1279786122817620968">"Ուղեցույց <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
- <string name="allset_title" msgid="5021126669778966707">"Պատրաստ է"</string>
- <string name="allset_hint" msgid="2384632994739392447">"Մատը սահեցրեք վերև՝ հիմնական էկրան անցնելու համար"</string>
- <string name="allset_description" msgid="6350320429953234580">"Դուք արդեն կարող եք օգտագործել ձեր հեռախոսը"</string>
- <string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"Նավիգացիայի համակարգային կարգավորումներ"</annotation></string>
- <string name="action_share" msgid="2648470652637092375">"Կիսվել"</string>
- <string name="action_screenshot" msgid="8171125848358142917">"Սքրինշոթ անել"</string>
- <string name="action_split" msgid="2098009717623550676">"Տրոհել"</string>
- <string name="toast_split_select_app" msgid="5453865907322018352">"Հպեք այլ հավելվածի՝ էկրանը տրոհելու համար"</string>
- <string name="toast_split_app_unsupported" msgid="3271526028981899666">"Հավելվածը չի աջակցում էկրանի տրոհումը։"</string>
- <string name="blocked_by_policy" msgid="2071401072261365546">"Այս գործողությունն արգելված է հավելվածի կամ ձեր կազմակերպության կողմից"</string>
- <string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Բաց թողնե՞լ նավիգացիայի ուղեցույցը"</string>
- <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Հետագայում սա կարող եք գտնել «<xliff:g id="NAME">%1$s</xliff:g>» հավելվածում"</string>
- <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Չեղարկել"</string>
- <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Բաց թողնել"</string>
- <string name="accessibility_rotate_button" msgid="4771825231336502943">"Պտտել էկրանը"</string>
- <string name="taskbar_edu_opened" msgid="3950252793551919129">"Խնդրագոտու «Կրթություն» վահանակը բացվեց"</string>
- <string name="taskbar_edu_closed" msgid="126643734478892862">"Խնդրագոտու «Կրթություն» վահանակը փակվեց"</string>
- <string name="taskbar_edu_switch_apps" msgid="6942863327845784813">"Օգտագործեք խնդրագոտին՝ մի հավելվածից մյուսին անցնելու համար"</string>
- <string name="taskbar_edu_splitscreen" msgid="2663361731630346489">"Քաշեք մի կողմ՝ միաժամանակ երկու հավելված օգտագործելու համար"</string>
- <string name="taskbar_edu_stashing" msgid="5212374387411764031">"Հպեք և պահեք՝ խնդրագոտին թաքցնելու համար"</string>
- <string name="taskbar_edu_next" msgid="4007618274426775841">"Առաջ"</string>
- <string name="taskbar_edu_previous" msgid="459202320127201702">"Հետ"</string>
- <string name="taskbar_edu_close" msgid="887022990168191073">"Փակել"</string>
- <string name="taskbar_edu_done" msgid="6880178093977704569">"Պատրաստ է"</string>
- <string name="taskbar_button_home" msgid="2151398979630664652">"Սկիզբ"</string>
- <string name="taskbar_button_a11y" msgid="5241161324875094465">"Հատուկ գործառ․"</string>
- <string name="taskbar_button_back" msgid="8558862226461164514">"Հետ"</string>
- <string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"IME փոխանջատիչ"</string>
- <string name="taskbar_button_recents" msgid="7273376136216613134">"Վերջինները"</string>
- <string name="taskbar_button_notifications" msgid="7471740351507357318">"Ծանուցումներ"</string>
- <string name="taskbar_button_quick_settings" msgid="227662894293189391">"Արագ կարգավորումներ"</string>
- <string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Տեղափոխել վերևի ձախ անկյուն"</string>
- <string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Տեղափոխել ներքևի աջ անկյուն"</string>
</resources>
diff --git a/quickstep/res/values-in/strings.xml b/quickstep/res/values-in/strings.xml
index 61bdf31432..6824d16b40 100644
--- a/quickstep/res/values-in/strings.xml
+++ b/quickstep/res/values-in/strings.xml
@@ -19,91 +19,19 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="recent_task_option_pin" msgid="7929860679018978258">"Sematkan"</string>
+ <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Layar terpisah"</string>
+ <string name="recent_task_option_pin" msgid="7929860679018978258">"Pasang pin"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Format bebas"</string>
+ <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Ringkasan"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"Tidak ada item yang baru dibuka"</string>
+ <string name="accessibility_close_task" msgid="5354563209433803643">"Tutup"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Setelan penggunaan aplikasi"</string>
<string name="recents_clear_all" msgid="5328176793634888831">"Hapus semua"</string>
- <string name="accessibility_recent_apps" msgid="4058661986695117371">"Aplikasi terbaru"</string>
- <string name="task_view_closed" msgid="9170038230110856166">"Tugas Ditutup"</string>
+ <string name="accessibility_recent_apps" msgid="4058661986695117371">"Aplikasi baru-baru ini"</string>
<string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
<string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 menit"</string>
<string name="time_left_for_app" msgid="3111996412933644358">"<xliff:g id="TIME">%1$s</xliff:g> tersisa hari ini"</string>
<string name="title_app_suggestions" msgid="4185902664111965088">"Saran aplikasi"</string>
+ <string name="all_apps_label" msgid="8542784161730910663">"Semua aplikasi"</string>
<string name="all_apps_prediction_tip" msgid="2672336544844936186">"Aplikasi yang diprediksi"</string>
- <string name="hotseat_edu_title_migrate" msgid="306578144424489980">"Dapatkan saran aplikasi di baris paling bawah Layar utama"</string>
- <string name="hotseat_edu_title_migrate_landscape" msgid="3633942953997845243">"Dapatkan saran aplikasi di baris favorit Layar utama"</string>
- <string name="hotseat_edu_message_migrate" msgid="8927179260533775320">"Akses aplikasi yang paling sering digunakan dengan mudah, langsung di Layar utama. Saran akan berubah berdasarkan rutinitas Anda. Aplikasi di baris paling bawah akan berpindah naik ke Layar utama."</string>
- <string name="hotseat_edu_message_migrate_landscape" msgid="4248943380443387697">"Mudah mengakses aplikasi yang paling sering digunakan, langsung di Layar utama. Saran akan berubah berdasarkan rutinitas Anda. Aplikasi di baris favorit akan berpindah ke Layar utama."</string>
- <string name="hotseat_edu_message_migrate_alt" msgid="3042360119039646356">"Akses aplikasi yang paling sering digunakan dengan mudah, langsung di Layar utama. Saran akan berubah berdasarkan rutinitas Anda. Aplikasi di baris paling bawah akan berpindah ke folder baru."</string>
- <string name="hotseat_edu_accept" msgid="1611544083278999837">"Dapatkan saran aplikasi"</string>
- <string name="hotseat_edu_dismiss" msgid="2781161822780201689">"Lain kali"</string>
- <string name="hotseat_prediction_settings" msgid="6246554993566070818">"Setelan"</string>
- <string name="hotseat_auto_enrolled" msgid="522100018967146807">"Aplikasi yang paling sering digunakan muncul di sini, dan berubah berdasarkan rutinitas"</string>
- <string name="hotseat_tip_no_empty_slots" msgid="1325212677738179185">"Tarik aplikasi dari baris paling bawah untuk mendapatkan saran aplikasi"</string>
- <string name="hotseat_tip_gaps_filled" msgid="3035673010274223538">"Saran aplikasi ditambahkan ke ruang kosong"</string>
- <string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Saran aplikasi diaktifkan"</string>
- <string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Saran aplikasi dinonaktifkan"</string>
- <string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Aplikasi yang diprediksi: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Pastikan Anda menggeser dari tepi ujung kanan atau ujung kiri."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Pastikan Anda menggeser dari tepi kanan atau kiri ke tengah layar, lalu lepaskan."</string>
- <string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Anda telah belajar cara geser dari kanan untuk kembali. Berikutnya, pelajari cara beralih aplikasi."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"Anda telah menyelesaikan gestur kembali."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Pastikan Anda tidak menggeser terlalu dekat ke bagian bawah layar."</string>
- <string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"Untuk mengubah sensitivitas gestur kembali, buka Setelan"</string>
- <string name="back_gesture_intro_title" msgid="19551256430224428">"Geser untuk kembali"</string>
- <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"Untuk kembali ke layar terakhir, geser dari tepi kiri atau kanan ke tengah layar."</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Pastikan Anda menggeser ke atas dari tepi bawah layar."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Pastikan Anda tidak menjeda sebelum melepaskan."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Pastikan Anda menggeser lurus ke atas."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"Anda telah menyelesaikan gestur menuju Layar utama. Selanjutnya, pelajari cara beralih kembali."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"Anda telah menyelesaikan gestur menuju Layar utama."</string>
- <string name="home_gesture_intro_title" msgid="836590312858441830">"Geser untuk beralih ke layar utama"</string>
- <string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Geser ke atas dari bagian bawah layar. Gestur ini akan selalu membawa Anda ke Layar utama."</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Pastikan Anda menggeser ke atas dari tepi bawah layar."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Coba tahan jendela lebih lama sebelum melepaskan."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Pastikan Anda menggeser lurus ke atas, lalu menjedanya."</string>
- <string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Anda telah mempelajari cara menggunakan gestur. Untuk menonaktifkan gestur, buka Setelan."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"Anda telah menyelesaikan gestur beralih aplikasi."</string>
- <string name="overview_gesture_intro_title" msgid="2902054412868489378">"Geser untuk beralih aplikasi"</string>
- <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Untuk beralih antar-aplikasi, geser ke atas dari bagian bawah layar, tahan, lalu lepaskan."</string>
- <string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"Semua siap"</string>
- <string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Selesai"</string>
- <string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Setelan"</string>
- <string name="gesture_tutorial_try_again" msgid="65962545858556697">"Coba lagi"</string>
- <string name="gesture_tutorial_nice" msgid="2936275692616928280">"Bagus!"</string>
- <string name="gesture_tutorial_step" msgid="1279786122817620968">"Tutorial <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
- <string name="allset_title" msgid="5021126669778966707">"Semua siap."</string>
- <string name="allset_hint" msgid="2384632994739392447">"Geser ke atas untuk beralih ke Layar utama"</string>
- <string name="allset_description" msgid="6350320429953234580">"Anda sudah siap untuk mulai menggunakan ponsel"</string>
- <string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"Setelan navigasi sistem"</annotation></string>
- <string name="action_share" msgid="2648470652637092375">"Bagikan"</string>
- <string name="action_screenshot" msgid="8171125848358142917">"Screenshot"</string>
- <string name="action_split" msgid="2098009717623550676">"Pisahkan"</string>
- <string name="toast_split_select_app" msgid="5453865907322018352">"Ketuk aplikasi lain untuk menggunakan layar terpisah"</string>
- <string name="toast_split_app_unsupported" msgid="3271526028981899666">"Aplikasi tidak mendukung layar terpisah."</string>
- <string name="blocked_by_policy" msgid="2071401072261365546">"Tindakan ini tidak diizinkan oleh aplikasi atau organisasi Anda"</string>
- <string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Lewati tutorial navigasi?"</string>
- <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Anda dapat menemukan tutorial ini di lain waktu di aplikasi <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Batal"</string>
- <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Lewati"</string>
- <string name="accessibility_rotate_button" msgid="4771825231336502943">"Putar layar"</string>
- <string name="taskbar_edu_opened" msgid="3950252793551919129">"Edukasi taskbar ditampilkan"</string>
- <string name="taskbar_edu_closed" msgid="126643734478892862">"Edukasi taskbar ditutup"</string>
- <string name="taskbar_edu_switch_apps" msgid="6942863327845784813">"Gunakan taskbar untuk beralih aplikasi"</string>
- <string name="taskbar_edu_splitscreen" msgid="2663361731630346489">"Tarik ke samping untuk menggunakan dua aplikasi sekaligus"</string>
- <string name="taskbar_edu_stashing" msgid="5212374387411764031">"Sentuh lama untuk menyembunyikan taskbar"</string>
- <string name="taskbar_edu_next" msgid="4007618274426775841">"Berikutnya"</string>
- <string name="taskbar_edu_previous" msgid="459202320127201702">"Kembali"</string>
- <string name="taskbar_edu_close" msgid="887022990168191073">"Tutup"</string>
- <string name="taskbar_edu_done" msgid="6880178093977704569">"Selesai"</string>
- <string name="taskbar_button_home" msgid="2151398979630664652">"Layar utama"</string>
- <string name="taskbar_button_a11y" msgid="5241161324875094465">"Aksesibilitas"</string>
- <string name="taskbar_button_back" msgid="8558862226461164514">"Kembali"</string>
- <string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"Pengalih IME"</string>
- <string name="taskbar_button_recents" msgid="7273376136216613134">"Terbaru"</string>
- <string name="taskbar_button_notifications" msgid="7471740351507357318">"Notifikasi"</string>
- <string name="taskbar_button_quick_settings" msgid="227662894293189391">"Setelan Cepat"</string>
- <string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Pindahkan ke atas/kiri"</string>
- <string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Pindahkan ke bawah/kanan"</string>
</resources>
diff --git a/quickstep/res/values-is/strings.xml b/quickstep/res/values-is/strings.xml
index 13275522a1..f60a2c6802 100644
--- a/quickstep/res/values-is/strings.xml
+++ b/quickstep/res/values-is/strings.xml
@@ -19,93 +19,19 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Skipta skjá"</string>
<string name="recent_task_option_pin" msgid="7929860679018978258">"Festa"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Frjálst snið"</string>
+ <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Yfirlit"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"Engin nýleg atriði"</string>
+ <string name="accessibility_close_task" msgid="5354563209433803643">"Loka"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Notkunarstillingar forrits"</string>
<string name="recents_clear_all" msgid="5328176793634888831">"Hreinsa allt"</string>
<string name="accessibility_recent_apps" msgid="4058661986695117371">"Nýleg forrit"</string>
- <string name="task_view_closed" msgid="9170038230110856166">"Verkefni lokað"</string>
<string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
<string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 mín."</string>
<string name="time_left_for_app" msgid="3111996412933644358">"<xliff:g id="TIME">%1$s</xliff:g> eftir í dag"</string>
<string name="title_app_suggestions" msgid="4185902664111965088">"Tillögur að forritum"</string>
+ <string name="all_apps_label" msgid="8542784161730910663">"Öll forrit"</string>
<string name="all_apps_prediction_tip" msgid="2672336544844936186">"Spáð forrit"</string>
- <string name="hotseat_edu_title_migrate" msgid="306578144424489980">"Fáðu tillögur að forritum í neðstu röð heimaskjásins"</string>
- <string name="hotseat_edu_title_migrate_landscape" msgid="3633942953997845243">"Fáðu tillögur að forritum á eftirlætissvæði heimaskjásins"</string>
- <string name="hotseat_edu_message_migrate" msgid="8927179260533775320">"Nálgastu forritin sem þú notar mest auðveldlega á heimaskjánum. Tillögurnar breytast í samræmi við notkun þína. Forrit í neðstu röð færast upp á heimaskjáinn."</string>
- <string name="hotseat_edu_message_migrate_landscape" msgid="4248943380443387697">"Nálgastu forritin sem þú notar mest á einfaldan hátt á heimaskjánum. Tillögurnar breytast í samræmi við notkun þína. Forrit á eftirlætissvæði færast á heimaskjáinn."</string>
- <string name="hotseat_edu_message_migrate_alt" msgid="3042360119039646356">"Nálgastu forritin sem þú notar mest auðveldlega á heimaskjánum. Tillögurnar breytast í samræmi við notkun þína. Forrit í neðstu röð færast í nýja möppu."</string>
- <string name="hotseat_edu_accept" msgid="1611544083278999837">"Fá tillögur að forritum"</string>
- <string name="hotseat_edu_dismiss" msgid="2781161822780201689">"Nei, takk"</string>
- <string name="hotseat_prediction_settings" msgid="6246554993566070818">"Stillingar"</string>
- <string name="hotseat_auto_enrolled" msgid="522100018967146807">"Mest notuðu forritin birtast hér og breytast í samræmi við rútínur"</string>
- <string name="hotseat_tip_no_empty_slots" msgid="1325212677738179185">"Dragðu forrit af neðstu röð til að fá tillögð forrit"</string>
- <string name="hotseat_tip_gaps_filled" msgid="3035673010274223538">"Tillögðum forritum bætt við autt svæði"</string>
- <string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Kveikt á tillögum að forritum"</string>
- <string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Slökkt er á tillögðum forritum"</string>
- <string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Tillaga að forriti: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Passaðu að strjúka frá jaðri hægri eða vinstri brúnar."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Passaðu að strjúka frá jaðri hægri eða vinstri brúnar að miðju skjásins og sleppa síðan."</string>
- <string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Þú lærðir að strjúka frá hægri til að bakka. Næst skaltu læra hvernig þú skiptir á milli forrita."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"Þú laukst við að kynna þér bendinguna „til baka“."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Passaðu að strjúka ekki of nálægt neðri brún skjásins."</string>
- <string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"Til að breyta næmi til baka-bendingar ferðu í stillingar"</string>
- <string name="back_gesture_intro_title" msgid="19551256430224428">"Strjúktu til að fara til baka"</string>
- <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"Til að fara til baka á síðasta skjá skaltu strjúka frá vinstri eða hægri brún að miðju skjásins."</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Passaðu að strjúka upp frá neðri brún skjásins."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Passaðu að stoppa ekki áður en þú sleppir."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Passaðu að strjúka beint upp."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"Þú laukst við að kynna þér bendinguna „heim“. Næst skaltu læra hvernig þú ferð „til baka“."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"Þú laukst við að kynna þér bendinguna „heim“."</string>
- <string name="home_gesture_intro_title" msgid="836590312858441830">"Strjúktu til að fara heim"</string>
- <string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Strjúktu upp frá neðri hluta skjásins. Þetta flytur þig alltaf á heimaskjáinn."</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Passaðu að strjúka upp frá neðri brún skjásins."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Prófaðu að halda fingrinum lengur á glugganum áður en þú sleppir."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Passaðu að strjúka beint upp og stoppa svo."</string>
- <string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Þú kynntir þér hvernig á að nota bendingar. Opnaðu stillingar til að slökkva á bendingum."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"Þú laukst við að kynna þér bendinguna „skipta um forrit“."</string>
- <string name="overview_gesture_intro_title" msgid="2902054412868489378">"Strjúktu til að skipta á milli forrita"</string>
- <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Strjúktu upp frá neðri hluta skjásins, haltu og slepptu svo til að skipta á milli forrita."</string>
- <string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"Allt til reiðu"</string>
- <string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Lokið"</string>
- <string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Stillingar"</string>
- <string name="gesture_tutorial_try_again" msgid="65962545858556697">"Reyna aftur"</string>
- <string name="gesture_tutorial_nice" msgid="2936275692616928280">"Flott!"</string>
- <string name="gesture_tutorial_step" msgid="1279786122817620968">"Leiðsögn <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
- <string name="allset_title" msgid="5021126669778966707">"Allt tilbúið!"</string>
- <string name="allset_hint" msgid="2384632994739392447">"Strjúktu upp til að fara á heimaskjáinn"</string>
- <string name="allset_description" msgid="6350320429953234580">"Þú getur byrjað að nota símann"</string>
- <string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"Stillingar kerfisstjórnunar"</annotation></string>
- <string name="action_share" msgid="2648470652637092375">"Deila"</string>
- <string name="action_screenshot" msgid="8171125848358142917">"Skjámynd"</string>
- <string name="action_split" msgid="2098009717623550676">"Skipta"</string>
- <string name="toast_split_select_app" msgid="5453865907322018352">"Ýttu á annað forrit til að nota skjáskiptingu"</string>
- <string name="toast_split_app_unsupported" msgid="3271526028981899666">"Forritið styður ekki að skjánum sé skipt."</string>
- <string name="blocked_by_policy" msgid="2071401072261365546">"Forritið eða fyrirtækið leyfir ekki þessa aðgerð"</string>
- <string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Sleppa flettileiðsögn?"</string>
- <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Þú getur fundið þetta síðar í forritinu <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Hætta við"</string>
- <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Sleppa"</string>
- <string name="accessibility_rotate_button" msgid="4771825231336502943">"Snúa skjánum"</string>
- <string name="taskbar_edu_opened" msgid="3950252793551919129">"Leiðsögn verkefnastiku sýnileg"</string>
- <string name="taskbar_edu_closed" msgid="126643734478892862">"Leiðsögn verkefnastiku lokað"</string>
- <string name="taskbar_edu_switch_apps" msgid="6942863327845784813">"Notaðu verkefnastikuna til að skipta á milli forrita"</string>
- <string name="taskbar_edu_splitscreen" msgid="2663361731630346489">"Dragðu til hliðar til að nota tvö forrit í einu"</string>
- <string name="taskbar_edu_stashing" msgid="5212374387411764031">"Haltu inni til að fela verkefnastikuna"</string>
- <string name="taskbar_edu_next" msgid="4007618274426775841">"Áfram"</string>
- <string name="taskbar_edu_previous" msgid="459202320127201702">"Til baka"</string>
- <string name="taskbar_edu_close" msgid="887022990168191073">"Loka"</string>
- <string name="taskbar_edu_done" msgid="6880178093977704569">"Lokið"</string>
- <string name="taskbar_button_home" msgid="2151398979630664652">"Heim"</string>
- <string name="taskbar_button_a11y" msgid="5241161324875094465">"Aðgengi"</string>
- <string name="taskbar_button_back" msgid="8558862226461164514">"Til baka"</string>
- <string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"Breyta innsláttaraðferð"</string>
- <string name="taskbar_button_recents" msgid="7273376136216613134">"Nýlegt"</string>
- <!-- no translation found for taskbar_button_notifications (7471740351507357318) -->
- <skip />
- <!-- no translation found for taskbar_button_quick_settings (227662894293189391) -->
- <skip />
- <string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Færa efst/til vinstri"</string>
- <string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Færa neðst/til hægri"</string>
</resources>
diff --git a/quickstep/res/values-it/strings.xml b/quickstep/res/values-it/strings.xml
index a555636db1..559fdb4b6e 100644
--- a/quickstep/res/values-it/strings.xml
+++ b/quickstep/res/values-it/strings.xml
@@ -19,93 +19,19 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="recent_task_option_pin" msgid="7929860679018978258">"Blocca su schermo"</string>
+ <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Schermo diviso"</string>
+ <string name="recent_task_option_pin" msgid="7929860679018978258">"Blocca"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Forma libera"</string>
+ <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Panoramica"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"Nessun elemento recente"</string>
+ <string name="accessibility_close_task" msgid="5354563209433803643">"Chiudi"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Impostazioni di utilizzo delle app"</string>
<string name="recents_clear_all" msgid="5328176793634888831">"Cancella tutto"</string>
<string name="accessibility_recent_apps" msgid="4058661986695117371">"App recenti"</string>
- <string name="task_view_closed" msgid="9170038230110856166">"Attività chiusa"</string>
<string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
<string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 min"</string>
<string name="time_left_for_app" msgid="3111996412933644358">"Rimanente oggi: <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="title_app_suggestions" msgid="4185902664111965088">"App suggerite"</string>
- <string name="all_apps_prediction_tip" msgid="2672336544844936186">"App previste per te"</string>
- <string name="hotseat_edu_title_migrate" msgid="306578144424489980">"Visualizza app suggerite nella riga inferiore della schermata Home"</string>
- <string name="hotseat_edu_title_migrate_landscape" msgid="3633942953997845243">"Visualizza app suggerite nella riga dei Preferiti della schermata Home"</string>
- <string name="hotseat_edu_message_migrate" msgid="8927179260533775320">"Accedi facilmente alle app più utilizzate direttamente dalla schermata Home. I suggerimenti varieranno in base alle tue routine. Le app nella riga inferiore verranno spostate più in alto sulla schermata Home."</string>
- <string name="hotseat_edu_message_migrate_landscape" msgid="4248943380443387697">"Accedi facilmente alle app più utilizzate direttamente dalla schermata Home. I suggerimenti varieranno in base alle tue routine. Le app nella riga dei Preferiti verranno spostate nella schermata Home."</string>
- <string name="hotseat_edu_message_migrate_alt" msgid="3042360119039646356">"Accedi facilmente alle app più utilizzate direttamente dalla schermata Home. I suggerimenti varieranno in base alle tue routine. Le app nella riga inferiore verranno spostate in una nuova cartella."</string>
- <string name="hotseat_edu_accept" msgid="1611544083278999837">"Visualizza app suggerite"</string>
- <string name="hotseat_edu_dismiss" msgid="2781161822780201689">"No, grazie"</string>
- <string name="hotseat_prediction_settings" msgid="6246554993566070818">"Impostazioni"</string>
- <string name="hotseat_auto_enrolled" msgid="522100018967146807">"Le app più utilizzate vengono visualizzate qui e variano in base alle routine"</string>
- <string name="hotseat_tip_no_empty_slots" msgid="1325212677738179185">"Trascina le app fuori dalla riga inferiore per visualizzare le app suggerite"</string>
- <string name="hotseat_tip_gaps_filled" msgid="3035673010274223538">"App suggerite aggiunte a uno spazio vuoto"</string>
- <string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"La funzionalità app suggerite è attiva"</string>
- <string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"La funzionalità app suggerite è disattivata"</string>
- <string name="hotseat_prediction_content_description" msgid="4582028296938078419">"App prevista: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Assicurati di scorrere dal bordo all\'estrema destra o all\'estrema sinistra."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Assicurati di scorrere dal bordo destro o sinistro verso il centro dello schermo e solleva il dito."</string>
- <string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Hai imparato a scorrere da destra per tornare indietro. Ora impara come passare da un\'app all\'altra."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"Hai completato il gesto Indietro."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Assicurati di non scorrere troppo vicino alla parte inferiore dello schermo."</string>
- <string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"Usa Impostazioni per cambiare sensibilità del gesto Indietro"</string>
- <string name="back_gesture_intro_title" msgid="19551256430224428">"Scorri per tornare indietro"</string>
- <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"Per tornare all\'ultima schermata, scorri dal bordo sinistro o destro verso il centro dello schermo."</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Assicurati di scorrere verso l\'alto dal bordo inferiore dello schermo."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Assicurati di non fare pause prima di sollevare il dito."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Assicurati di scorrere verso l\'alto senza fermarti."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"Hai completato il gesto per andare alla schermata Home. Ora, impara come tornare indietro."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"Hai completato il gesto Vai alla schermata Home."</string>
- <string name="home_gesture_intro_title" msgid="836590312858441830">"Scorri per andare alla schermata Home"</string>
- <string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Scorri verso l\'alto dalla parte inferiore dello schermo. Questo gesto ti porta sempre alla schermata Home."</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Assicurati di scorrere verso l\'alto dal bordo inferiore dello schermo."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Prova a tenere premuta la finestra più a lungo prima di rilasciarla."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Assicurati di scorrere verso l\'alto senza fermarti, poi fai una pausa."</string>
- <string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Hai imparato a usare i gesti. Per disattivarli, vai alle Impostazioni."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"Hai completato il gesto Cambia app."</string>
- <string name="overview_gesture_intro_title" msgid="2902054412868489378">"Scorri per passare da un\'app all\'altra"</string>
- <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Per spostarti tra le app, scorri verso l\'alto dal fondo dello schermo, tieni premuto e rilascia."</string>
- <string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"Fatto"</string>
- <string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Fine"</string>
- <string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Impostazioni"</string>
- <string name="gesture_tutorial_try_again" msgid="65962545858556697">"Riprova"</string>
- <string name="gesture_tutorial_nice" msgid="2936275692616928280">"Bene!"</string>
- <string name="gesture_tutorial_step" msgid="1279786122817620968">"Tutorial <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
- <string name="allset_title" msgid="5021126669778966707">"Finito."</string>
- <string name="allset_hint" msgid="2384632994739392447">"Scorri verso l\'alto per andare alla schermata Home"</string>
- <string name="allset_description" msgid="6350320429953234580">"Puoi iniziare a usare il tuo telefono"</string>
- <string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"Impostazioni Navigazione del sistema"</annotation></string>
- <string name="action_share" msgid="2648470652637092375">"Condividi"</string>
- <string name="action_screenshot" msgid="8171125848358142917">"Screenshot"</string>
- <string name="action_split" msgid="2098009717623550676">"Dividi"</string>
- <string name="toast_split_select_app" msgid="5453865907322018352">"Tocca un\'altra app per usare lo schermo diviso"</string>
- <string name="toast_split_app_unsupported" msgid="3271526028981899666">"L\'app non supporta la modalità Schermo diviso."</string>
- <string name="blocked_by_policy" msgid="2071401072261365546">"Questa azione non è consentita dall\'app o dall\'organizzazione"</string>
- <string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Saltare il tutorial di navigazione?"</string>
- <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Puoi trovarlo in un secondo momento nell\'app <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Annulla"</string>
- <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Salta"</string>
- <string name="accessibility_rotate_button" msgid="4771825231336502943">"Ruota lo schermo"</string>
- <string name="taskbar_edu_opened" msgid="3950252793551919129">"Riquadro Formazione barra delle applicazioni visualizzato"</string>
- <string name="taskbar_edu_closed" msgid="126643734478892862">"Riquadro Formazione barra delle applicazioni chiuso"</string>
- <string name="taskbar_edu_switch_apps" msgid="6942863327845784813">"Usa la barra delle applicazioni per cambiare app"</string>
- <string name="taskbar_edu_splitscreen" msgid="2663361731630346489">"Trascina di lato per usare due app contemporaneamente"</string>
- <string name="taskbar_edu_stashing" msgid="5212374387411764031">"Tocca e tieni premuto per nascondere barra applicazioni"</string>
- <string name="taskbar_edu_next" msgid="4007618274426775841">"Avanti"</string>
- <string name="taskbar_edu_previous" msgid="459202320127201702">"Indietro"</string>
- <string name="taskbar_edu_close" msgid="887022990168191073">"Chiudi"</string>
- <string name="taskbar_edu_done" msgid="6880178093977704569">"Fine"</string>
- <string name="taskbar_button_home" msgid="2151398979630664652">"Home"</string>
- <string name="taskbar_button_a11y" msgid="5241161324875094465">"Accessibilità"</string>
- <string name="taskbar_button_back" msgid="8558862226461164514">"Indietro"</string>
- <string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"Selettore IME"</string>
- <string name="taskbar_button_recents" msgid="7273376136216613134">"Recenti"</string>
- <!-- no translation found for taskbar_button_notifications (7471740351507357318) -->
- <skip />
- <!-- no translation found for taskbar_button_quick_settings (227662894293189391) -->
- <skip />
- <string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Sposta in alto/a sinistra"</string>
- <string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Sposta in basso/a destra"</string>
+ <string name="all_apps_label" msgid="8542784161730910663">"Tutte le app"</string>
+ <string name="all_apps_prediction_tip" msgid="2672336544844936186">"Le app previste"</string>
</resources>
diff --git a/quickstep/res/values-iw/strings.xml b/quickstep/res/values-iw/strings.xml
index cd97903de4..58cab4e0a9 100644
--- a/quickstep/res/values-iw/strings.xml
+++ b/quickstep/res/values-iw/strings.xml
@@ -19,93 +19,19 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="recent_task_option_split_screen" msgid="5353188922202653570">"מסך מפוצל"</string>
<string name="recent_task_option_pin" msgid="7929860679018978258">"הצמדה"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"מצב חופשי"</string>
+ <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"מסכים אחרונים"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"אין פריטים אחרונים"</string>
+ <string name="accessibility_close_task" msgid="5354563209433803643">"סגירה"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"הגדרות שימוש באפליקציה"</string>
<string name="recents_clear_all" msgid="5328176793634888831">"ניקוי הכול"</string>
<string name="accessibility_recent_apps" msgid="4058661986695117371">"אפליקציות אחרונות"</string>
- <string name="task_view_closed" msgid="9170038230110856166">"המשימה סגורה"</string>
<string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
<string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"‏&lt; דקה"</string>
<string name="time_left_for_app" msgid="3111996412933644358">"הזמן שנותר להיום: <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="title_app_suggestions" msgid="4185902664111965088">"הצעות לאפליקציות"</string>
+ <string name="all_apps_label" msgid="8542784161730910663">"כל האפליקציות"</string>
<string name="all_apps_prediction_tip" msgid="2672336544844936186">"האפליקציות החזויות שלך"</string>
- <string name="hotseat_edu_title_migrate" msgid="306578144424489980">"קבלת הצעות לאפליקציות בשורה התחתונה של מסך הבית"</string>
- <string name="hotseat_edu_title_migrate_landscape" msgid="3633942953997845243">"קבלת הצעות לאפליקציות בשורת המועדפות של מסך הבית"</string>
- <string name="hotseat_edu_message_migrate" msgid="8927179260533775320">"גישה נוחה לאפליקציות שנעשה בהן שימוש תכוף – ישירות ממסך הבית. ההצעות ישתנו בהתאם להרגלי השימוש שלך. אפליקציות שמופיעות בשורה התחתונה יעברו למעלה למסך הבית."</string>
- <string name="hotseat_edu_message_migrate_landscape" msgid="4248943380443387697">"גישה נוחה לאפליקציות שהשתמשת בהן הכי הרבה, ישירות ממסך הבית. ההצעות ישתנו בהתאם להרגלי השימוש שלך. אפליקציות בשורת המועדפות יועברו למסך הבית."</string>
- <string name="hotseat_edu_message_migrate_alt" msgid="3042360119039646356">"גישה נוחה לאפליקציות שנעשה בהן שימוש תכוף – ישירות ממסך הבית. ההצעות ישתנו בהתאם להרגלי השימוש שלך. אפליקציות שמופיעות בשורה התחתונה יעברו לתיקייה חדשה."</string>
- <string name="hotseat_edu_accept" msgid="1611544083278999837">"קבלת הצעות לאפליקציות"</string>
- <string name="hotseat_edu_dismiss" msgid="2781161822780201689">"לא, תודה"</string>
- <string name="hotseat_prediction_settings" msgid="6246554993566070818">"הגדרות"</string>
- <string name="hotseat_auto_enrolled" msgid="522100018967146807">"רוב האפליקציות הכי נפוצות מופיעות כאן ומשתנות בהתאם להרגלי השימוש שלך"</string>
- <string name="hotseat_tip_no_empty_slots" msgid="1325212677738179185">"כדי לקבל הצעות נוספות לאפליקציות, צריך לגרור אפליקציות מהשורה התחתונה"</string>
- <string name="hotseat_tip_gaps_filled" msgid="3035673010274223538">"הצעות לאפליקציות נוספו לאזור ריק"</string>
- <string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"התכונה \'הצעות לאפליקציות\' מופעלת"</string>
- <string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"ההצעות לאפליקציות מושבתות"</string>
- <string name="hotseat_prediction_content_description" msgid="4582028296938078419">"האפליקציות החזויות: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"חשוב להקפיד להחליק מהקצה השמאלי או הימני."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"חשוב להקפיד להחליק מהקצה השמאלי או הימני למרכז המסך ואז לשחרר."</string>
- <string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"למדת איך להחליק מצד ימין כדי לחזור אחורה. בשלב הבא לומדים איך לעבור בין אפליקציות."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"השלמת את תנועת \'הקודם\'."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"חשוב להקפיד שלא להחליק קרוב מדי לתחתית המסך."</string>
- <string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"כדי לשנות את מידת הרגישות של תנועת החזרה, יש לעבור להגדרות"</string>
- <string name="back_gesture_intro_title" msgid="19551256430224428">"יש להחליק כדי לחזור"</string>
- <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"כדי לחזור למסך הקודם, יש להחליק מהקצה השמאלי או הימני למרכז המסך."</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"חשוב להקפיד להחליק למעלה מהקצה התחתון של המסך."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"חשוב לוודא שלא מחכים לפני שמשחררים."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"חשוב להקפיד להחליק ישר למעלה."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"השלמת את תנועת המעבר למסך הבית. בשלב הבא לומדים איך לחזור למסך הקודם."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"השלמת את תנועת המעבר למסך הבית."</string>
- <string name="home_gesture_intro_title" msgid="836590312858441830">"יש להחליק כדי לעבור למסך הבית"</string>
- <string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"החלקה למעלה מתחתית המסך תמיד תעביר אותך למסך הבית."</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"חשוב להקפיד להחליק למעלה מהקצה התחתון של המסך."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"אפשר להחזיק את החלון זמן רב יותר לפני שמשחררים."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"חשוב להקפיד להחליק ישר למעלה ואז להמתין."</string>
- <string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"למדת איך להשתמש בתנועות. ניתן להשבית את התנועות ב\'הגדרות\'."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"השלמת את תנועת המעבר בין האפליקציות."</string>
- <string name="overview_gesture_intro_title" msgid="2902054412868489378">"יש להחליק כדי לעבור בין אפליקציות"</string>
- <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"כדי לעבור בין אפלקציות, יש להחליק למעלה מתחתית המסך, להחזיק ולאחר מכן לשחרר."</string>
- <string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"הכול מוכן"</string>
- <string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"סיום"</string>
- <string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"הגדרות"</string>
- <string name="gesture_tutorial_try_again" msgid="65962545858556697">"ניסיון חוזר"</string>
- <string name="gesture_tutorial_nice" msgid="2936275692616928280">"איזה יופי!"</string>
- <string name="gesture_tutorial_step" msgid="1279786122817620968">"מדריך <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
- <string name="allset_title" msgid="5021126669778966707">"הכול מוכן!"</string>
- <string name="allset_hint" msgid="2384632994739392447">"כדי לעבור לדף הבית, מחליקים כלפי מעלה"</string>
- <string name="allset_description" msgid="6350320429953234580">"הכול מוכן ואפשר להתחיל להשתמש בטלפון"</string>
- <string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"הגדרות הניווט של המערכת"</annotation></string>
- <string name="action_share" msgid="2648470652637092375">"שיתוף"</string>
- <string name="action_screenshot" msgid="8171125848358142917">"צילום מסך"</string>
- <string name="action_split" msgid="2098009717623550676">"פיצול"</string>
- <string name="toast_split_select_app" msgid="5453865907322018352">"צריך להקיש על אפליקציה אחרת כדי להשתמש במסך מפוצל"</string>
- <string name="toast_split_app_unsupported" msgid="3271526028981899666">"האפליקציה אינה תומכת במסך מפוצל."</string>
- <string name="blocked_by_policy" msgid="2071401072261365546">"האפליקציה או הארגון שלך אינם מתירים את הפעולה הזאת"</string>
- <string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"לדלג על המדריך לניווט?"</string>
- <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"ניתן למצוא את המדריך מאוחר יותר באפליקציה <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"ביטול"</string>
- <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"דילוג"</string>
- <string name="accessibility_rotate_button" msgid="4771825231336502943">"סיבוב המסך"</string>
- <string name="taskbar_edu_opened" msgid="3950252793551919129">"חלונית ההסברים על שורת המשימות מופיעה"</string>
- <string name="taskbar_edu_closed" msgid="126643734478892862">"חלונית ההסברים על שורת המשימות נסגרה"</string>
- <string name="taskbar_edu_switch_apps" msgid="6942863327845784813">"כדי לעבור בין אפליקציות, משתמשים בשורת המשימות"</string>
- <string name="taskbar_edu_splitscreen" msgid="2663361731630346489">"כדי להשתמש בשתי אפליקציות בו-זמנית, צריך לגרור לצד"</string>
- <string name="taskbar_edu_stashing" msgid="5212374387411764031">"כדי להסתיר את שורת המשימות, לוחצים לחיצה ארוכה"</string>
- <string name="taskbar_edu_next" msgid="4007618274426775841">"הבא"</string>
- <string name="taskbar_edu_previous" msgid="459202320127201702">"חזרה"</string>
- <string name="taskbar_edu_close" msgid="887022990168191073">"סגירה"</string>
- <string name="taskbar_edu_done" msgid="6880178093977704569">"סיום"</string>
- <string name="taskbar_button_home" msgid="2151398979630664652">"בית"</string>
- <string name="taskbar_button_a11y" msgid="5241161324875094465">"נגישות"</string>
- <string name="taskbar_button_back" msgid="8558862226461164514">"חזרה"</string>
- <string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"‏כלי להחלפת IME"</string>
- <string name="taskbar_button_recents" msgid="7273376136216613134">"לאחרונה"</string>
- <!-- no translation found for taskbar_button_notifications (7471740351507357318) -->
- <skip />
- <!-- no translation found for taskbar_button_quick_settings (227662894293189391) -->
- <skip />
- <string name="move_drop_target_top_or_left" msgid="2988702185049595807">"העברה לפינה השמאלית/העליונה"</string>
- <string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"העברה לפינה הימנית/התחתונה"</string>
</resources>
diff --git a/quickstep/res/values-ja/strings.xml b/quickstep/res/values-ja/strings.xml
index 9a4ce01544..d3fecde208 100644
--- a/quickstep/res/values-ja/strings.xml
+++ b/quickstep/res/values-ja/strings.xml
@@ -19,91 +19,19 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="recent_task_option_split_screen" msgid="5353188922202653570">"分割画面"</string>
<string name="recent_task_option_pin" msgid="7929860679018978258">"固定"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"フリーフォーム"</string>
+ <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"概要"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"最近のアイテムはありません"</string>
+ <string name="accessibility_close_task" msgid="5354563209433803643">"閉じる"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"アプリの使用状況の設定"</string>
<string name="recents_clear_all" msgid="5328176793634888831">"すべてクリア"</string>
<string name="accessibility_recent_apps" msgid="4058661986695117371">"最近使ったアプリ"</string>
- <string name="task_view_closed" msgid="9170038230110856166">"タスクを閉じました"</string>
<string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>、<xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
<string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"1 分未満"</string>
<string name="time_left_for_app" msgid="3111996412933644358">"今日はあと <xliff:g id="TIME">%1$s</xliff:g>です"</string>
<string name="title_app_suggestions" msgid="4185902664111965088">"アプリの候補"</string>
+ <string name="all_apps_label" msgid="8542784161730910663">"すべてのアプリ"</string>
<string name="all_apps_prediction_tip" msgid="2672336544844936186">"予測されたアプリ"</string>
- <string name="hotseat_edu_title_migrate" msgid="306578144424489980">"ホーム画面の一番下にアプリの候補を表示できます"</string>
- <string name="hotseat_edu_title_migrate_landscape" msgid="3633942953997845243">"ホーム画面のお気に入りの行でアプリの候補を利用できます"</string>
- <string name="hotseat_edu_message_migrate" msgid="8927179260533775320">"ホーム画面で、使用頻度の高いアプリに簡単にアクセスできるようになります。アプリの候補はルーティンに応じて変わります。一番下の行にあるアプリは上に移動します。"</string>
- <string name="hotseat_edu_message_migrate_landscape" msgid="4248943380443387697">"ホーム画面で、使用頻度の高いアプリに簡単にアクセスできるようになります。アプリの候補はルーティンに応じて変わります。お気に入りの行にあるアプリがホーム画面に移動します。"</string>
- <string name="hotseat_edu_message_migrate_alt" msgid="3042360119039646356">"ホーム画面で、使用頻度の高いアプリに簡単にアクセスできるようになります。アプリの候補はルーティンに応じて変わります。一番下の行にあるアプリが新しいフォルダに移動します。"</string>
- <string name="hotseat_edu_accept" msgid="1611544083278999837">"アプリの候補を利用"</string>
- <string name="hotseat_edu_dismiss" msgid="2781161822780201689">"使用しない"</string>
- <string name="hotseat_prediction_settings" msgid="6246554993566070818">"設定"</string>
- <string name="hotseat_auto_enrolled" msgid="522100018967146807">"使用頻度の高いアプリがここに表示されます(ルーティンに応じて変わります)"</string>
- <string name="hotseat_tip_no_empty_slots" msgid="1325212677738179185">"一番下の行からアプリをドラッグするとアプリの候補が表示されます"</string>
- <string name="hotseat_tip_gaps_filled" msgid="3035673010274223538">"空いたスペースにアプリの候補が追加されます"</string>
- <string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"アプリの候補表示が有効です"</string>
- <string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"アプリの候補は無効です"</string>
- <string name="hotseat_prediction_content_description" msgid="4582028296938078419">"予測されたアプリ: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"右端または左端からスワイプしてください。"</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"画面の右端または左端から中央に向かってスワイプし、指を離してください。"</string>
- <string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"右側からスワイプして前の画面に戻る方法を学習しました。次は、アプリを切り替える方法を覚えましょう。"</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"「戻る」操作を学習しました。"</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"スワイプする際は画面の下部に近づきすぎないようにしましょう。"</string>
- <string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"「戻る」操作の感度を変更するには [設定] に移動します"</string>
- <string name="back_gesture_intro_title" msgid="19551256430224428">"スワイプで戻る"</string>
- <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"直前の画面に戻るには、画面の左端または右端から中央に向かってスワイプします。"</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"画面の下端から上にスワイプしてください。"</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"指を離す前にいったん止めないでください。"</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"まっすぐ上にスワイプしてください。"</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"「ホームに戻る」操作を学習しました。次は、前の画面に戻る方法を覚えましょう。"</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"「ホームに戻る」操作を学習しました。"</string>
- <string name="home_gesture_intro_title" msgid="836590312858441830">"スワイプでホームに戻る"</string>
- <string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"画面を下から上にスワイプします。この操作でいつでもホーム画面に戻れます。"</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"画面の下端から上にスワイプしてください。"</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"ウィンドウをもう少し長く押してから指を離すようにしてみましょう。"</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"まっすぐ上にスワイプしてから、いったん指を止めてください。"</string>
- <string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"主な操作方法を覚えました。操作を OFF にするには、設定に移動してください。"</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"「アプリを切り替える」操作を完了しました。"</string>
- <string name="overview_gesture_intro_title" msgid="2902054412868489378">"スワイプでアプリを切り替える"</string>
- <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"アプリを切り替えるには、画面を下から上にスワイプして長押しし、指を離します。"</string>
- <string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"設定完了"</string>
- <string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"完了"</string>
- <string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"設定"</string>
- <string name="gesture_tutorial_try_again" msgid="65962545858556697">"もう一度"</string>
- <string name="gesture_tutorial_nice" msgid="2936275692616928280">"成功しました"</string>
- <string name="gesture_tutorial_step" msgid="1279786122817620968">"チュートリアル <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
- <string name="allset_title" msgid="5021126669778966707">"設定完了"</string>
- <string name="allset_hint" msgid="2384632994739392447">"ホームに移動するには上にスワイプします"</string>
- <string name="allset_description" msgid="6350320429953234580">"スマートフォンを使い始めることができます"</string>
- <string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"システム ナビゲーションの設定"</annotation></string>
- <string name="action_share" msgid="2648470652637092375">"共有"</string>
- <string name="action_screenshot" msgid="8171125848358142917">"スクリーンショット"</string>
- <string name="action_split" msgid="2098009717623550676">"分割"</string>
- <string name="toast_split_select_app" msgid="5453865907322018352">"分割画面を使用するには、他のアプリをタップします"</string>
- <string name="toast_split_app_unsupported" msgid="3271526028981899666">"アプリで分割画面がサポートされていません。"</string>
- <string name="blocked_by_policy" msgid="2071401072261365546">"この操作はアプリまたは組織で許可されていません"</string>
- <string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"操作チュートリアルをスキップしますか?"</string>
- <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"チュートリアルは後から <xliff:g id="NAME">%1$s</xliff:g> アプリで確認できます"</string>
- <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"キャンセル"</string>
- <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"スキップ"</string>
- <string name="accessibility_rotate_button" msgid="4771825231336502943">"画面を回転"</string>
- <string name="taskbar_edu_opened" msgid="3950252793551919129">"タスクバーの説明を開きました"</string>
- <string name="taskbar_edu_closed" msgid="126643734478892862">"タスクバーの説明を閉じました"</string>
- <string name="taskbar_edu_switch_apps" msgid="6942863327845784813">"アプリを切り替えるには、タスクバーを使用します"</string>
- <string name="taskbar_edu_splitscreen" msgid="2663361731630346489">"2 個のアプリを同時に使用するには、横にドラッグします"</string>
- <string name="taskbar_edu_stashing" msgid="5212374387411764031">"タスクバーを長押しすると非表示になります"</string>
- <string name="taskbar_edu_next" msgid="4007618274426775841">"次へ"</string>
- <string name="taskbar_edu_previous" msgid="459202320127201702">"戻る"</string>
- <string name="taskbar_edu_close" msgid="887022990168191073">"閉じる"</string>
- <string name="taskbar_edu_done" msgid="6880178093977704569">"完了"</string>
- <string name="taskbar_button_home" msgid="2151398979630664652">"ホーム"</string>
- <string name="taskbar_button_a11y" msgid="5241161324875094465">"ユーザー補助"</string>
- <string name="taskbar_button_back" msgid="8558862226461164514">"戻る"</string>
- <string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"IME の切り替え"</string>
- <string name="taskbar_button_recents" msgid="7273376136216613134">"最近"</string>
- <string name="taskbar_button_notifications" msgid="7471740351507357318">"通知"</string>
- <string name="taskbar_button_quick_settings" msgid="227662894293189391">"クイック設定"</string>
- <string name="move_drop_target_top_or_left" msgid="2988702185049595807">"上 / 左に移動"</string>
- <string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"下 / 右に移動"</string>
</resources>
diff --git a/quickstep/res/values-ka/strings.xml b/quickstep/res/values-ka/strings.xml
index 250148911f..67b03a754f 100644
--- a/quickstep/res/values-ka/strings.xml
+++ b/quickstep/res/values-ka/strings.xml
@@ -19,91 +19,19 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="recent_task_option_split_screen" msgid="5353188922202653570">"ეკრანის გაყოფა"</string>
<string name="recent_task_option_pin" msgid="7929860679018978258">"ჩამაგრება"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"თავისუფალი ფორმა"</string>
+ <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"მიმოხილვა"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"ბოლოს გამოყენებული ერთეულები არ არის"</string>
+ <string name="accessibility_close_task" msgid="5354563209433803643">"დახურვა"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"აპების გამოყენების პარამეტრები"</string>
<string name="recents_clear_all" msgid="5328176793634888831">"ყველას გასუფთავება"</string>
<string name="accessibility_recent_apps" msgid="4058661986695117371">"ბოლოდროინდელი აპები"</string>
- <string name="task_view_closed" msgid="9170038230110856166">"ამოცანა დაიხურა"</string>
<string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
<string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 წუთი"</string>
<string name="time_left_for_app" msgid="3111996412933644358">"დღეს დარჩენილია <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <string name="title_app_suggestions" msgid="4185902664111965088">"აპის შემოთავაზებები"</string>
+ <string name="title_app_suggestions" msgid="4185902664111965088">"აპების შემოთავაზებები"</string>
+ <string name="all_apps_label" msgid="8542784161730910663">"ყველა აპი"</string>
<string name="all_apps_prediction_tip" msgid="2672336544844936186">"თქვენი პროგნოზირებული აპები"</string>
- <string name="hotseat_edu_title_migrate" msgid="306578144424489980">"მიიღეთ აპის შეთავაზებები მთავარი ეკრანის ქვედა რიგში"</string>
- <string name="hotseat_edu_title_migrate_landscape" msgid="3633942953997845243">"მიიღეთ აპების შემოთავაზებები მთავარი ეკრანის რჩეულების მწკრივში"</string>
- <string name="hotseat_edu_message_migrate" msgid="8927179260533775320">"მარტივად იქონიეთ ყველაზე ხშირად გამოყენებულ აპებზე წვდომა მთავარი ეკრანიდან. შეთავაზებები შეიცვლება თქვენი რუტინების მიხედვით. მოხდება ქვედა რიგში არსებული აპების მთავარ ეკრანზე გადატანა."</string>
- <string name="hotseat_edu_message_migrate_landscape" msgid="4248943380443387697">"მარტივად იქონიეთ წვდომა ყველაზე ხშირად გამოყენებულ აპებზე მთავარი ეკრანიდან. შეთავაზებები შეიცვლება თქვენი რუტინების მიხედვით. რჩეულების მწკრივში არსებული აპები თქვენს მთავარ ეკრანზე გადავა."</string>
- <string name="hotseat_edu_message_migrate_alt" msgid="3042360119039646356">"მარტივად იქონიეთ ყველაზე ხშირად გამოყენებულ აპებზე წვდომა მთავარი ეკრანიდან. შეთავაზებები შეიცვლება თქვენი რუტინების მიხედვით. მოხდება ქვედა რიგში არსებული აპების ახალ საქაღალდეში გადატანა."</string>
- <string name="hotseat_edu_accept" msgid="1611544083278999837">"აპის შეთავაზებების მიღება"</string>
- <string name="hotseat_edu_dismiss" msgid="2781161822780201689">"არა, გმადლობთ"</string>
- <string name="hotseat_prediction_settings" msgid="6246554993566070818">"პარამეტრები"</string>
- <string name="hotseat_auto_enrolled" msgid="522100018967146807">"ყველაზე ხშირად გამოყენებული აპები აქ ჩანს და ცვალებადობს რუტინების მიხედვით"</string>
- <string name="hotseat_tip_no_empty_slots" msgid="1325212677738179185">"გადაიტანეთ აპები ეკრანის ქვედა რიგში, რათა აპის შეთავაზებები მიიღოთ"</string>
- <string name="hotseat_tip_gaps_filled" msgid="3035673010274223538">"აპის შეთავაზებები დამატებულია ცარიელ სივრცეში"</string>
- <string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"აპის შეთავაზებები ჩართულია"</string>
- <string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"აპის შეთავაზებები გათიშულია"</string>
- <string name="hotseat_prediction_content_description" msgid="4582028296938078419">"ნაწინასწარმეტყველები აპი: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"გადაფურცლეთ უკიდურესი მარჯვენა ან მარცხენა ბოლოდან."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"გადაფურცლეთ მარჯვენა ან მარცხენა კიდიდან ეკრანის ცენტრისკენ და თითი აუშვით."</string>
- <string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"თქვენ ისწავლეთ მარჯვნიდან გადაფურცვლა უკან დასაბრუნებლად. ახლა კი შეიტყვეთ, როგორ გადართოთ აპები."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"თქვენ შეასრულეთ უკან დაბრუნების ჟესტი."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"არ გადაფურცლოთ ეკრანის ბოლოსთან ახლოს."</string>
- <string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"დაბრუნების ჟესტის მგრძნობელობის შესაცვლელად გადადით პარამეტრებზე"</string>
- <string name="back_gesture_intro_title" msgid="19551256430224428">"უკან დასაბრუნებლად გადაფურცლეთ"</string>
- <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"ბოლო ეკრანზე დასაბრუნებლად გადაფურცლეთ მარცხენა ან მარჯვენა კიდიდან ეკრანის ცენტრისკენ."</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"გადაფურცლეთ ეკრანის ქვედა კიდიდან ზემოთ."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"არ დააპაუზოთ თითის აშვებამდე."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"გადაფურცლეთ ზემოთ."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"თქვენ შეასრულეთ მთავარ ეკრანზე დაბრუნების ჟესტი. ახლა კი შევიტყოთ, თუ როგორ დავბრუნდეთ უკან."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"თქვენ შეასრულეთ მთავარ ეკრანზე დაბრუნების ჟესტი."</string>
- <string name="home_gesture_intro_title" msgid="836590312858441830">"მთავარი გვერდის სანახავად გადაფურცლეთ"</string>
- <string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"გადაფურცლეთ ეკრანის ქვედა კიდიდან ზემოთ. ამ ჟესტს ყოველთვის მთავარი გვერდის ეკრანზე გადაყავხართ."</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"გადაფურცლეთ ეკრანის ქვედა კიდიდან ზემოთ."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"უფრო ხანგრძლივად დააჭირეთ თითი ფანჯარას, რომ არ დაიხუროს."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"გადაფურცლეთ პირდაპირ ზემოთ და შემდეგ დააპაუზეთ."</string>
- <string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"თქვენ ისწავლეთ ჟესტების გამოყენება. ჟესტების გამოსართავად გადადით პარამეტრებში."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"თქვენ შეასრულეთ აპების გადართვის ჟესტი."</string>
- <string name="overview_gesture_intro_title" msgid="2902054412868489378">"აპების გადასართავად გადაფურცლეთ"</string>
- <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"აპების გადასართავად, გადაფურცლეთ ეკრანის ქვედა კიდიდან ზემოთ, დააყოვნეთ, შემდეგ თითი აუშვით."</string>
- <string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"მზად არის"</string>
- <string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"მზადაა"</string>
- <string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"პარამეტრები"</string>
- <string name="gesture_tutorial_try_again" msgid="65962545858556697">"ხელახლა ცდა"</string>
- <string name="gesture_tutorial_nice" msgid="2936275692616928280">"მშვენიერია!"</string>
- <string name="gesture_tutorial_step" msgid="1279786122817620968">"სახელმძღვანელო <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
- <string name="allset_title" msgid="5021126669778966707">"მზადაა!"</string>
- <string name="allset_hint" msgid="2384632994739392447">"მთავარ გვერდზე გადასასვლელად გადაფურცლეთ ზევით"</string>
- <string name="allset_description" msgid="6350320429953234580">"მზად ხართ ტელეფონის გამოსაყენებლად"</string>
- <string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"სისტემის ნავიგაციის პარამეტრები"</annotation></string>
- <string name="action_share" msgid="2648470652637092375">"გაზიარება"</string>
- <string name="action_screenshot" msgid="8171125848358142917">"ეკრანის ანაბეჭდი"</string>
- <string name="action_split" msgid="2098009717623550676">"გაყოფა"</string>
- <string name="toast_split_select_app" msgid="5453865907322018352">"შეეხეთ სხვა აპს ეკრანის გასაყოფად"</string>
- <string name="toast_split_app_unsupported" msgid="3271526028981899666">"ეკრანის გაყოფა არ არის მხარდაჭერილი აპის მიერ."</string>
- <string name="blocked_by_policy" msgid="2071401072261365546">"ეს მოქმედება არ არის დაშვებული აპის ან თქვენი ორგანიზაციის მიერ"</string>
- <string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"გსურთ, გამოტოვოთ ნავიგაციის სახელმძღვანელო?"</string>
- <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"ამის მოგვიანებით პოვნა <xliff:g id="NAME">%1$s</xliff:g> აპში შეგიძლიათ"</string>
- <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"გაუქმება"</string>
- <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"გამოტოვება"</string>
- <string name="accessibility_rotate_button" msgid="4771825231336502943">"ეკრანის შეტრიალება"</string>
- <string name="taskbar_edu_opened" msgid="3950252793551919129">"ამოცანების ზოლის სასწავლო არე გამოჩნდა"</string>
- <string name="taskbar_edu_closed" msgid="126643734478892862">"ამოცანების ზოლის სასწავლო არე დაიხურა"</string>
- <string name="taskbar_edu_switch_apps" msgid="6942863327845784813">"აპების გადასართავად გამოიყენეთ ამოცანათა ზოლი"</string>
- <string name="taskbar_edu_splitscreen" msgid="2663361731630346489">"გადაათრიეთ კიდეზე ორი აპის ერთდოულად გამოსაყენებლად"</string>
- <string name="taskbar_edu_stashing" msgid="5212374387411764031">"ხანგრძლივად შეეხეთ ამოცანების ზოლის დასამალად"</string>
- <string name="taskbar_edu_next" msgid="4007618274426775841">"შემდეგი"</string>
- <string name="taskbar_edu_previous" msgid="459202320127201702">"უკან"</string>
- <string name="taskbar_edu_close" msgid="887022990168191073">"დახურვა"</string>
- <string name="taskbar_edu_done" msgid="6880178093977704569">"მზადაა"</string>
- <string name="taskbar_button_home" msgid="2151398979630664652">"მთავარი"</string>
- <string name="taskbar_button_a11y" msgid="5241161324875094465">"მარტივი წვდომა"</string>
- <string name="taskbar_button_back" msgid="8558862226461164514">"უკან"</string>
- <string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"IME გადამრთველი"</string>
- <string name="taskbar_button_recents" msgid="7273376136216613134">"ბოლოდროინდელი"</string>
- <string name="taskbar_button_notifications" msgid="7471740351507357318">"შეტყობინებები"</string>
- <string name="taskbar_button_quick_settings" msgid="227662894293189391">"სწრაფი პარამეტრები"</string>
- <string name="move_drop_target_top_or_left" msgid="2988702185049595807">"ზემოთ/მარცხნივ გადატანა"</string>
- <string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"ქვემოთ/მარჯვნივ გადატანა"</string>
</resources>
diff --git a/quickstep/res/values-kk/strings.xml b/quickstep/res/values-kk/strings.xml
index 9d3ca2d17a..a9fcbedb20 100644
--- a/quickstep/res/values-kk/strings.xml
+++ b/quickstep/res/values-kk/strings.xml
@@ -19,91 +19,19 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Экранды бөлу"</string>
<string name="recent_task_option_pin" msgid="7929860679018978258">"Бекіту"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Еркін форма"</string>
+ <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Шолу"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"Соңғы элементтер жоқ"</string>
+ <string name="accessibility_close_task" msgid="5354563209433803643">"Жабу"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Қолданбаны пайдалану параметрлері"</string>
<string name="recents_clear_all" msgid="5328176793634888831">"Барлығын өшіру"</string>
<string name="accessibility_recent_apps" msgid="4058661986695117371">"Соңғы пайдаланылған қолданбалар"</string>
- <string name="task_view_closed" msgid="9170038230110856166">"Тапсырма жабылды."</string>
<string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
<string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 мин"</string>
<string name="time_left_for_app" msgid="3111996412933644358">"Бүгін <xliff:g id="TIME">%1$s</xliff:g> қалды"</string>
- <string name="title_app_suggestions" msgid="4185902664111965088">"Ұсынылған қолданбалар"</string>
+ <string name="title_app_suggestions" msgid="4185902664111965088">"Қолданба ұсыныстары"</string>
+ <string name="all_apps_label" msgid="8542784161730910663">"Барлық қолданбалар"</string>
<string name="all_apps_prediction_tip" msgid="2672336544844936186">"Ұсынылатын қолданбалар"</string>
- <string name="hotseat_edu_title_migrate" msgid="306578144424489980">"Негізгі экранның төменгі жолында қолданбаларды ұсыну"</string>
- <string name="hotseat_edu_title_migrate_landscape" msgid="3633942953997845243">"Ұсынылған қолданбалар негізгі экранда таңдаулылар арасында көрсетілетін болады"</string>
- <string name="hotseat_edu_message_migrate" msgid="8927179260533775320">"Жиі пайдаланылатын қолданбаларға негізгі экраннан кіруге болады. Ұсыныстар күнделікті әрекеттеріңізге сәйкес өзгереді. Төменгі қатардағы қолданбалар негізгі экранға қарай жоғары жылжиды."</string>
- <string name="hotseat_edu_message_migrate_landscape" msgid="4248943380443387697">"Жиі пайдаланылатын қолданбаларға негізгі экраннан оңай кіре аласыз. Ұсыныстар күнделікті әрекеттеріңізге сәйкес өзгереді. Таңдаулылар жолындағы қолданбалар негізгі экранға ауысады."</string>
- <string name="hotseat_edu_message_migrate_alt" msgid="3042360119039646356">"Жиі пайдаланылатын қолданбаларға негізгі экраннан кіруге болады. Ұсыныстар күнделікті әрекеттеріңізге сәйкес өзгереді. Төменгі қатардағы қолданбалар жаңа қалтаға жылжиды."</string>
- <string name="hotseat_edu_accept" msgid="1611544083278999837">"Ұсынылған қолданбаларды көру"</string>
- <string name="hotseat_edu_dismiss" msgid="2781161822780201689">"Жоқ, рақмет"</string>
- <string name="hotseat_prediction_settings" msgid="6246554993566070818">"Параметрлер"</string>
- <string name="hotseat_auto_enrolled" msgid="522100018967146807">"Жиі пайдаланылатын қолданбалар осы жерде көрсетіледі. Олар күнделікті әрекеттеріңізге сәйкес өзгереді."</string>
- <string name="hotseat_tip_no_empty_slots" msgid="1325212677738179185">"Ұсынылған қолданбаларды көру үшін төменгі қатардан керектерін сүйреп шығарыңыз."</string>
- <string name="hotseat_tip_gaps_filled" msgid="3035673010274223538">"Ұсынылған қолданбалар бос орынға қосылды."</string>
- <string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Ұсынылған қолданбалар функциясы қосылды."</string>
- <string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"\"Ұсынылған қолданбалар\" функциясы өшірулі."</string>
- <string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Болжалды қолданба: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Экранның оң немесе сол жиегінен сырғытыңыз."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Экранның оң немесе сол жиегінен ортасына қарай сырғытып, саусағыңызды жіберіңіз."</string>
- <string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Оңнан солға сырғыту арқылы артқа қайтуды үйрендіңіз. Енді қолданбаларды ауыстыруды үйреніңіз."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"Артқа қайту қимылын аяқтадыңыз."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Саусағыңызбен сырғыту кезінде экранның төменгі жағына тым жақындамаңыз."</string>
- <string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"Артқа қайту қимылы сезгіштігін параметрлерден өзгертіңіз."</string>
- <string name="back_gesture_intro_title" msgid="19551256430224428">"Артқа қайту үшін сырғытыңыз"</string>
- <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"Соңғы ашылған экранға оралу үшін экранның сол немесе оң жақ шетінен ортасына қарай сырғытыңыз."</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Экранның төменгі шетінен жоғары қарай сырғытыңыз."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Жіберер алдында кідіріс жасамаңыз."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Тігінен жоғары қарай сырғытыңыз."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"Негізгі экранға қайту қимылын аяқтадыңыз. Енді артқа қайтуды үйреніңіз."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"Негізгі экранға қайту қимылын аяқтадыңыз."</string>
- <string name="home_gesture_intro_title" msgid="836590312858441830">"Негізгі экранға өту үшін сырғытыңыз"</string>
- <string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Экранның төменгі жағынан жоғары қарай сырғытыңыз. Сонда негізгі экран ашылады."</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Экранның төменгі шетінен жоғары қарай сырғытыңыз."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Жіберер алдында терезені ұзағырақ ұстап тұруға тырысыңыз."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Тігінен жоғары қарай сырғытыңыз да, кідіріңіз."</string>
- <string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Қимылдарды қолдануды үйрендіңіз. Қимылдарды өшіру үшін \"Параметрлер\" бөліміне өтіңіз."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"Қолданбаларды ауыстыру қимылын аяқтадыңыз."</string>
- <string name="overview_gesture_intro_title" msgid="2902054412868489378">"Қолданбаларды ауыстыру үшін сырғытыңыз"</string>
- <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Бір қолданбадан екіншісіне ауысу үшін экранның төменгі жағынан жоғары қарай сырғытып, ұстап тұрып жіберіңіз."</string>
- <string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"Бәрі дайын"</string>
- <string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Дайын"</string>
- <string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Параметрлер"</string>
- <string name="gesture_tutorial_try_again" msgid="65962545858556697">"Қайталау"</string>
- <string name="gesture_tutorial_nice" msgid="2936275692616928280">"Жақсы!"</string>
- <string name="gesture_tutorial_step" msgid="1279786122817620968">"Оқулық: <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
- <string name="allset_title" msgid="5021126669778966707">"Бәрі дайын!"</string>
- <string name="allset_hint" msgid="2384632994739392447">"Негізгі экранға өту үшін жоғары қарай сырғытыңыз."</string>
- <string name="allset_description" msgid="6350320429953234580">"Телефоныңыз пайдалануға дайын."</string>
- <string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"Навигацияның жүйелік параметрлері"</annotation></string>
- <string name="action_share" msgid="2648470652637092375">"Бөлісу"</string>
- <string name="action_screenshot" msgid="8171125848358142917">"Скриншот"</string>
- <string name="action_split" msgid="2098009717623550676">"Бөлу"</string>
- <string name="toast_split_select_app" msgid="5453865907322018352">"Экранды бөлу режимін пайдалану үшін басқа қолданбаны түртіңіз."</string>
- <string name="toast_split_app_unsupported" msgid="3271526028981899666">"Қолданбада экранды бөлу мүмкін емес."</string>
- <string name="blocked_by_policy" msgid="2071401072261365546">"Бұл әрекетке қолданба не ұйым рұқсат етпейді."</string>
- <string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Қимылдар оқулығын өткізіп жіберу керек пе?"</string>
- <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Мұны кейін <xliff:g id="NAME">%1$s</xliff:g> қолданбасынан таба аласыз."</string>
- <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Бас тарту"</string>
- <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Өткізіп жіберу"</string>
- <string name="accessibility_rotate_button" msgid="4771825231336502943">"Экранды бұру"</string>
- <string name="taskbar_edu_opened" msgid="3950252793551919129">"Тапсырмалар тақтасы бойынша нұсқаулық ашылды."</string>
- <string name="taskbar_edu_closed" msgid="126643734478892862">"Тапсырмалар тақтасы бойынша нұсқаулық жабылды."</string>
- <string name="taskbar_edu_switch_apps" msgid="6942863327845784813">"Қолданбаларды ауыстыру үшін тапсырма тақтасын пайдаланыңыз."</string>
- <string name="taskbar_edu_splitscreen" msgid="2663361731630346489">"Екі қолданбаны бір уақытта пайдалану үшін шетке сүйреңіз."</string>
- <string name="taskbar_edu_stashing" msgid="5212374387411764031">"Тапсырмалар тақтасын жасыру үшін басып тұрыңыз."</string>
- <string name="taskbar_edu_next" msgid="4007618274426775841">"Келесі"</string>
- <string name="taskbar_edu_previous" msgid="459202320127201702">"Артқа"</string>
- <string name="taskbar_edu_close" msgid="887022990168191073">"Жабу"</string>
- <string name="taskbar_edu_done" msgid="6880178093977704569">"Дайын"</string>
- <string name="taskbar_button_home" msgid="2151398979630664652">"Негізгі экран"</string>
- <string name="taskbar_button_a11y" msgid="5241161324875094465">"Арнайы мүмкіндік"</string>
- <string name="taskbar_button_back" msgid="8558862226461164514">"Артқа"</string>
- <string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"IME ауыстырғышы"</string>
- <string name="taskbar_button_recents" msgid="7273376136216613134">"Соңғылары"</string>
- <string name="taskbar_button_notifications" msgid="7471740351507357318">"Хабарландырулар"</string>
- <string name="taskbar_button_quick_settings" msgid="227662894293189391">"Жылдам параметрлер"</string>
- <string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Жоғары/солға жылжыту"</string>
- <string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Төмен/оңға жылжыту"</string>
</resources>
diff --git a/quickstep/res/values-km/strings.xml b/quickstep/res/values-km/strings.xml
index 3295a636ef..c422041e7a 100644
--- a/quickstep/res/values-km/strings.xml
+++ b/quickstep/res/values-km/strings.xml
@@ -19,93 +19,19 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="recent_task_option_pin" msgid="7929860679018978258">"ខ្ទាស់"</string>
+ <string name="recent_task_option_split_screen" msgid="5353188922202653570">"មុខងារ​បំបែកអេក្រង់"</string>
+ <string name="recent_task_option_pin" msgid="7929860679018978258">"ដៅ"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"មុខងារទម្រង់សេរី"</string>
+ <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"ទិដ្ឋភាពរួម"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"មិនមានធាតុថ្មីៗទេ"</string>
+ <string name="accessibility_close_task" msgid="5354563209433803643">"បិទ"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"ការកំណត់​ការប្រើប្រាស់​កម្មវិធី"</string>
<string name="recents_clear_all" msgid="5328176793634888831">"សម្អាត​ទាំងអស់"</string>
<string name="accessibility_recent_apps" msgid="4058661986695117371">"កម្មវិធី​ថ្មីៗ"</string>
- <string name="task_view_closed" msgid="9170038230110856166">"បានបិទ​កិច្ចការ"</string>
<string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
<string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 នាទី"</string>
<string name="time_left_for_app" msgid="3111996412933644358">"នៅសល់ <xliff:g id="TIME">%1$s</xliff:g> ទៀត​នៅថ្ងៃនេះ"</string>
<string name="title_app_suggestions" msgid="4185902664111965088">"ការណែនាំកម្មវិធី"</string>
+ <string name="all_apps_label" msgid="8542784161730910663">"កម្មវិធី​ទាំងអស់"</string>
<string name="all_apps_prediction_tip" msgid="2672336544844936186">"កម្មវិធី​ដែលបាន​ព្យាករ​របស់អ្នក"</string>
- <string name="hotseat_edu_title_migrate" msgid="306578144424489980">"ទទួលបាន​ការណែនាំកម្មវិធី​នៅជួរខាងក្រោម​នៃអេក្រង់ដើម​របស់អ្នក"</string>
- <string name="hotseat_edu_title_migrate_landscape" msgid="3633942953997845243">"ទទួលបាន​ការណែនាំកម្មវិធី​នៅលើ​ជួរដេកសំណព្វ​នៃអេក្រង់ដើម​របស់អ្នក"</string>
- <string name="hotseat_edu_message_migrate" msgid="8927179260533775320">"ចូលប្រើ​កម្មវិធី​ដែលអ្នកប្រើ​ញឹកញាប់បំផុត​បានយ៉ាង​ងាយស្រួល​នៅលើ​អេក្រង់ដើម​ផ្ទាល់។ ការណែនាំ​នឹងប្រែប្រួល​ទៅតាម​ទម្លាប់​របស់អ្នក។ កម្មវិធី​នៅជួរ​ខាងក្រោម​នឹងផ្លាស់ទីឡើង​ទៅអេក្រង់ដើម​របស់អ្នក។"</string>
- <string name="hotseat_edu_message_migrate_landscape" msgid="4248943380443387697">"ចូលប្រើ​កម្មវិធី​ដែលអ្នកប្រើ​ញឹកញាប់បំផុត​បានយ៉ាង​ងាយស្រួល​នៅលើ​អេក្រង់ដើមដោយផ្ទាល់។ ការណែនាំ​នឹងប្រែប្រួល​ទៅតាម​ទម្លាប់​របស់អ្នក។ កម្មវិធី​នៅក្នុង​ជួរដេក​សំណព្វ​នឹងផ្លាស់ទី​ទៅអេក្រង់ដើម​របស់អ្នក។"</string>
- <string name="hotseat_edu_message_migrate_alt" msgid="3042360119039646356">"ចូលប្រើ​កម្មវិធី​ដែលអ្នកប្រើ​ញឹកញាប់បំផុត​បានយ៉ាង​ងាយស្រួល​នៅលើ​អេក្រង់ដើម​ផ្ទាល់។ ការណែនាំ​នឹងប្រែប្រួល​ទៅតាម​ទម្លាប់​របស់អ្នក។ កម្មវិធី​នៅជួរ​ខាងក្រោម​នឹងផ្លាស់ទី​ទៅថតថ្មី។"</string>
- <string name="hotseat_edu_accept" msgid="1611544083278999837">"ទទួលការណែនាំ​កម្មវិធី"</string>
- <string name="hotseat_edu_dismiss" msgid="2781161822780201689">"ទេ អរគុណ"</string>
- <string name="hotseat_prediction_settings" msgid="6246554993566070818">"ការកំណត់"</string>
- <string name="hotseat_auto_enrolled" msgid="522100018967146807">"កម្មវិធី​ដែលប្រើ​ញឹកញាប់បំផុត​បង្ហាញ​នៅទីនេះ និង​ប្រែប្រួល​ទៅតាមទម្លាប់"</string>
- <string name="hotseat_tip_no_empty_slots" msgid="1325212677738179185">"អូស​កម្មវិធី​ចេញពី​ជួរខាងក្រោម ដើម្បី​ទទួលបាន​ការណែនាំ​កម្មវិធី"</string>
- <string name="hotseat_tip_gaps_filled" msgid="3035673010274223538">"បានបញ្ចូល​ការណែនាំកម្មវិធី​ទៅក្នុង​កន្លែងទំនេរ"</string>
- <string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"បានបើក​ការណែនាំ​កម្មវិធី"</string>
- <string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"បានបិទ​ការណែនាំ​កម្មវិធី"</string>
- <string name="hotseat_prediction_content_description" msgid="4582028296938078419">"កម្មវិធី​ដែលបាន​ព្យាករ៖ <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"ត្រូវប្រាកដថា​អ្នកអូសពី​គែមខាងស្ដាំ ឬ​ខាងឆ្វេង។"</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"ត្រូវប្រាកដថា​អ្នកអូសពី​គែមខាងស្ដាំ ឬខាងឆ្វេង​ទៅផ្នែកកណ្ដាល​នៃអេក្រង់ រួច​ដកដៃ។"</string>
- <string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"អ្នកបានស្វែងយល់ពីរបៀបអូសពីខាងស្ដាំ ដើម្បីថយក្រោយ។ បន្ទាប់​ទៀត សូមស្វែងយល់​ពីរបៀប​ប្ដូរកម្មវិធី​។"</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"អ្នក​បានបញ្ចប់​ចលនា​ថយក្រោយ​ហើយ។"</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"ត្រូវប្រាកដថា​អ្នកមិនអូស​ទៅជិត​ផ្នែកខាងក្រោម​នៃអេក្រង់ពេក​។"</string>
- <string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"ដើម្បីប្ដូរកម្រិត​រំញោចនឹង​ចលនាថយក្រោយ សូមចូលទៅកាន់​ការកំណត់"</string>
- <string name="back_gesture_intro_title" msgid="19551256430224428">"អូស​ដើម្បី​ត្រឡប់​ទៅវិញ"</string>
- <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"ដើម្បី​ត្រឡប់ទៅ​អេក្រង់​ចុងក្រោយវិញ សូមអូស​ពីគែម​ខាងឆ្វេង ឬខាងស្ដាំ​ទៅផ្នែកកណ្ដាល​នៃអេក្រង់​។"</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"ត្រូវប្រាកដថា​អ្នកអូសឡើងលើ​ពីគែមខាងក្រោម​នៃអេក្រង់​។"</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"ត្រូវប្រាកដថា​អ្នកមិនផ្អាក មុនពេល​ដកដៃ​។"</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"ត្រូវប្រាកដថា​អ្នកអូស​ត្រង់ឡើងលើ​។"</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"អ្នក​បានបញ្ចប់​ចលនា​ចូលទៅកាន់​ទំព័រដើម​ហើយ។ បន្ទាប់​មកទៀត សូមស្វែងយល់​ពីរបៀប​ថយក្រោយ​។"</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"អ្នក​បានបញ្ចប់​ចលនា​ចូលទៅកាន់​ទំព័រដើម​ហើយ។"</string>
- <string name="home_gesture_intro_title" msgid="836590312858441830">"អូស​ដើម្បីចូល​ទៅកាន់​អេក្រង់ដើម"</string>
- <string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"អូស​ឡើងលើ​ពីផ្នែកខាងក្រោម​នៃ​អេក្រង់របស់អ្នក។ ចលនា​នេះ​នាំ​អ្នក​ទៅ​អេក្រង់ដើម​ជានិច្ច។"</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"ត្រូវប្រាកដថា​អ្នកអូសឡើងលើ​ពីគែមខាងក្រោម​នៃអេក្រង់​។"</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"សាកល្បង​សង្កត់វិនដូ​ឱ្យបានយូរ​ជាងនេះ មុនពេល​ដកដៃ​។"</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"ត្រូវប្រាកដថា​អ្នកអូស​ត្រង់ឡើងលើ រួចផ្អាក។"</string>
- <string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"អ្នក​បានស្វែងយល់អំពី​របៀបប្រើចលនា​ហើយ។ ដើម្បីបិទ​ចលនា សូមចូល​ទៅកាន់​ការកំណត់។"</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"អ្នក​បានបញ្ចប់​ចលនា​ប្ដូរកម្មវិធី​ហើយ។"</string>
- <string name="overview_gesture_intro_title" msgid="2902054412868489378">"អូស​ដើម្បីប្ដូរ​កម្មវិធី"</string>
- <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"ដើម្បីប្ដូររវាងកម្មវិធី សូមអូសឡើងលើពីផ្នែកខាងក្រោមនៃអេក្រង់របស់អ្នក រួចចុចឱ្យជាប់ បន្ទាប់មកដកដៃចេញ។"</string>
- <string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"រួចហើយ"</string>
- <string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"រួចរាល់"</string>
- <string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"ការកំណត់"</string>
- <string name="gesture_tutorial_try_again" msgid="65962545858556697">"ព្យាយាមម្ដងទៀត"</string>
- <string name="gesture_tutorial_nice" msgid="2936275692616928280">"ល្អ!"</string>
- <string name="gesture_tutorial_step" msgid="1279786122817620968">"មេរៀនទី <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
- <string name="allset_title" msgid="5021126669778966707">"រួចហើយ!"</string>
- <string name="allset_hint" msgid="2384632994739392447">"អូសឡើងលើ ដើម្បី​ទៅកាន់​អេក្រង់ដើម"</string>
- <string name="allset_description" msgid="6350320429953234580">"អ្នក​អាច​ចាប់ផ្ដើម​ប្រើ​ទូរសព្ទ​របស់អ្នក​បានហើយ"</string>
- <string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"ការកំណត់​ការរុករក​ប្រព័ន្ធ"</annotation></string>
- <string name="action_share" msgid="2648470652637092375">"ចែករំលែក"</string>
- <string name="action_screenshot" msgid="8171125848358142917">"រូបថតអេក្រង់"</string>
- <string name="action_split" msgid="2098009717623550676">"បំបែក"</string>
- <string name="toast_split_select_app" msgid="5453865907322018352">"ចុចកម្មវិធី​ផ្សេងទៀត ដើម្បីប្រើមុខងារ​បំបែកអេក្រង់"</string>
- <string name="toast_split_app_unsupported" msgid="3271526028981899666">"កម្មវិធីមិនអាចប្រើមុខងារ​បំបែកអេក្រង់បានទេ។"</string>
- <string name="blocked_by_policy" msgid="2071401072261365546">"សកម្មភាពនេះ​មិនត្រូវបានអនុញ្ញាតដោយកម្មវិធី​ ឬ​ស្ថាប័ន​របស់អ្នកទេ"</string>
- <string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"រំលង​មេរៀន​អំពី​ការរុករក​ឬ?"</string>
- <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"អ្នកអាចស្វែងរកមេរៀននេះនៅពេលក្រោយក្នុងកម្មវិធី <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"បោះបង់"</string>
- <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"រំលង"</string>
- <string name="accessibility_rotate_button" msgid="4771825231336502943">"បង្វិលអេក្រង់"</string>
- <string name="taskbar_edu_opened" msgid="3950252793551919129">"ការបង្រៀនអំពីរបារកិច្ចការបានបង្ហាញ"</string>
- <string name="taskbar_edu_closed" msgid="126643734478892862">"ការបង្រៀនអំពីរបារកិច្ចការត្រូវបានបិទ"</string>
- <string name="taskbar_edu_switch_apps" msgid="6942863327845784813">"ប្រើ​របារកិច្ចការ ដើម្បី​ប្ដូរកម្មវិធី"</string>
- <string name="taskbar_edu_splitscreen" msgid="2663361731630346489">"អូស​ទៅចំហៀង ដើម្បីប្រើ​កម្មវិធីពីរ​ក្នុងពេលតែមួយ"</string>
- <string name="taskbar_edu_stashing" msgid="5212374387411764031">"ចុចឱ្យជាប់ ដើម្បីលាក់របារកិច្ចការ"</string>
- <string name="taskbar_edu_next" msgid="4007618274426775841">"បន្ទាប់"</string>
- <string name="taskbar_edu_previous" msgid="459202320127201702">"ថយក្រោយ"</string>
- <string name="taskbar_edu_close" msgid="887022990168191073">"បិទ"</string>
- <string name="taskbar_edu_done" msgid="6880178093977704569">"រួចរាល់"</string>
- <string name="taskbar_button_home" msgid="2151398979630664652">"ទំព័រដើម"</string>
- <string name="taskbar_button_a11y" msgid="5241161324875094465">"ភាពងាយស្រួល"</string>
- <string name="taskbar_button_back" msgid="8558862226461164514">"ថយក្រោយ"</string>
- <string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"ប៊ូតុងប្ដូរ IME"</string>
- <string name="taskbar_button_recents" msgid="7273376136216613134">"ថ្មីៗ"</string>
- <!-- no translation found for taskbar_button_notifications (7471740351507357318) -->
- <skip />
- <!-- no translation found for taskbar_button_quick_settings (227662894293189391) -->
- <skip />
- <string name="move_drop_target_top_or_left" msgid="2988702185049595807">"ផ្លាស់ទីទៅខាងលើ/ឆ្វេង"</string>
- <string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"ផ្លាស់ទីទៅខាងក្រោម/ស្ដាំ"</string>
</resources>
diff --git a/quickstep/res/values-kn/strings.xml b/quickstep/res/values-kn/strings.xml
index 01c7dd5bbb..52782610b9 100644
--- a/quickstep/res/values-kn/strings.xml
+++ b/quickstep/res/values-kn/strings.xml
@@ -19,91 +19,19 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="recent_task_option_split_screen" msgid="5353188922202653570">"ಪರದೆಯನ್ನು ಬೇರ್ಪಡಿಸಿ"</string>
<string name="recent_task_option_pin" msgid="7929860679018978258">"ಪಿನ್ ಮಾಡಿ"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"ಮುಕ್ತಸ್ವರೂಪ"</string>
+ <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"ಅವಲೋಕನ"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"ಯಾವುದೇ ಇತ್ತೀಚಿನ ಐಟಂಗಳಿಲ್ಲ"</string>
+ <string name="accessibility_close_task" msgid="5354563209433803643">"ಮುಚ್ಚಿ"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"ಆ್ಯಪ್‌ ಬಳಕೆಯ ಸೆಟ್ಟಿಂಗ್‌ಗಳು"</string>
<string name="recents_clear_all" msgid="5328176793634888831">"ಎಲ್ಲವನ್ನೂ ತೆರವುಗೊಳಿಸಿ"</string>
<string name="accessibility_recent_apps" msgid="4058661986695117371">"ಇತ್ತೀಚಿನ ಅಪ್ಲಿಕೇಶನ್‌ಗಳು"</string>
- <string name="task_view_closed" msgid="9170038230110856166">"ಕಾರ್ಯವನ್ನು ಮುಚ್ಚಲಾಗಿದೆ"</string>
<string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
<string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 ನಿ"</string>
<string name="time_left_for_app" msgid="3111996412933644358">"ಇಂದು <xliff:g id="TIME">%1$s</xliff:g> ಸಮಯ ಉಳಿದಿದೆ"</string>
<string name="title_app_suggestions" msgid="4185902664111965088">"ಆ್ಯಪ್ ಸಲಹೆಗಳು"</string>
- <string name="all_apps_prediction_tip" msgid="2672336544844936186">"ನಿಮ್ಮ ಮುನ್ಸೂಚಿತ ಆ್ಯಪ್‌ಗಳು"</string>
- <string name="hotseat_edu_title_migrate" msgid="306578144424489980">"ನಿಮ್ಮ ಹೋಮ್ ಸ್ಕ್ರೀನ್‌ನ ಕೆಳಭಾಗದ ಸಾಲಿನಲ್ಲಿ ಆ್ಯಪ್ ಸಲಹೆಗಳನ್ನು ಪಡೆಯಿರಿ"</string>
- <string name="hotseat_edu_title_migrate_landscape" msgid="3633942953997845243">"ನಿಮ್ಮ ಹೋಮ್ ಸ್ಕ್ರೀನ್‌ನ ಮೆಚ್ಚಿನವುಗಳ ಸಾಲಿನಲ್ಲಿ ಆ್ಯಪ್ ಸಲಹೆಗಳನ್ನು ಪಡೆಯಿರಿ"</string>
- <string name="hotseat_edu_message_migrate" msgid="8927179260533775320">"ನೀವು ಹೆಚ್ಚು ಬಳಸಿದ ಆ್ಯಪ್‌ಗಳನ್ನು ಹೋಮ್ ಸ್ಕ್ರೀನ್‌ನಲ್ಲಿಯೇ ಸುಲಭವಾಗಿ ಪ್ರವೇಶಿಸಿ. ನಿಮ್ಮ ದಿನಚರಿಯನ್ನು ಆಧರಿಸಿ ಸಲಹೆಗಳು ಬದಲಾಗುತ್ತವೆ. ಕೆಳಭಾಗದ ಸಾಲಿನಲ್ಲಿನ ಆ್ಯಪ್‌ಗಳು ನಿಮ್ಮ ಹೋಮ್ ಸ್ಕ್ರೀನ್‌ ಚಲಿಸುತ್ತವೆ."</string>
- <string name="hotseat_edu_message_migrate_landscape" msgid="4248943380443387697">"ನೀವು ಹೆಚ್ಚು ಬಳಸಿದ ಆ್ಯಪ್‌ಗಳನ್ನು ಹೋಮ್ ಸ್ಕ್ರೀನ್‌ನಲ್ಲಿಯೇ ಸುಲಭವಾಗಿ ಪ್ರವೇಶಿಸಿ. ನಿಮ್ಮ ದಿನಚರಿಯನ್ನು ಆಧರಿಸಿ ಸಲಹೆಗಳು ಬದಲಾಗುತ್ತವೆ. ಮೆಚ್ಚಿನವುಗಳ ಸಾಲಿನಲ್ಲಿನ ಆ್ಯಪ್‌ಗಳು ನಿಮ್ಮ ಹೋಮ್ ಸ್ಕ್ರೀನ್‌ಗೆ ಚಲಿಸುತ್ತವೆ."</string>
- <string name="hotseat_edu_message_migrate_alt" msgid="3042360119039646356">"ನೀವು ಹೆಚ್ಚು ಬಳಸಿದ ಆ್ಯಪ್‌ಗಳನ್ನು ಹೋಮ್ ಸ್ಕ್ರೀನ್‌ನಲ್ಲಿಯೇ ಸುಲಭವಾಗಿ ಪ್ರವೇಶಿಸಿ. ನಿಮ್ಮ ದಿನಚರಿಯನ್ನು ಆಧರಿಸಿ ಸಲಹೆಗಳು ಬದಲಾಗುತ್ತವೆ. ಕೆಳಭಾಗದ ಸಾಲಿನಲ್ಲಿನ ಆ್ಯಪ್‌ಗಳು ಹೊಸ ಫೋಲ್ಡರ್‌ಗೆ ಚಲಿಸುತ್ತವೆ."</string>
- <string name="hotseat_edu_accept" msgid="1611544083278999837">"ಆ್ಯಪ್ ಸಲಹೆಗಳನ್ನು ಪಡೆಯಿರಿ"</string>
- <string name="hotseat_edu_dismiss" msgid="2781161822780201689">"ಬೇಡ"</string>
- <string name="hotseat_prediction_settings" msgid="6246554993566070818">"ಸೆಟ್ಟಿಂಗ್‌ಗಳು"</string>
- <string name="hotseat_auto_enrolled" msgid="522100018967146807">"ಹೆಚ್ಚು ಬಳಸಿದ ಆ್ಯಪ್‌ಗಳು ಇಲ್ಲಿ ಕಾಣಿಸುತ್ತವೆ ಮತ್ತು ದಿನಚರಿಯನ್ನು ಆಧರಿಸಿ ಬದಲಾಗುತ್ತದೆ"</string>
- <string name="hotseat_tip_no_empty_slots" msgid="1325212677738179185">"ಆ್ಯಪ್ ಸಲಹೆಗಳನ್ನು ಪಡೆಯಲು, ಆ್ಯಪ್‌ಗಳನ್ನು ಕೆಳಭಾಗದ ಸಾಲಿನಿಂದ ಡ್ರ್ಯಾಗ್ ಮಾಡಿ"</string>
- <string name="hotseat_tip_gaps_filled" msgid="3035673010274223538">"ಆ್ಯಪ್ ಸಲಹೆಗಳನ್ನು ಖಾಲಿ ಸ್ಥಳಕ್ಕೆ ಸೇರಿಸಲಾಗಿದೆ"</string>
- <string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"ಆ್ಯಪ್ ಸಲಹೆಗಳನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ"</string>
- <string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"ಆ್ಯಪ್ ಸಲಹೆಗಳನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ"</string>
- <string name="hotseat_prediction_content_description" msgid="4582028296938078419">"ಶಿಫಾರಸು ಮಾಡಿದ ಆ್ಯಪ್: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"ನೀವು ಬಲಕೊನೆಯ ಅಂಚಿನಿಂದ ಅಥವಾ ಎಡಕೊನೆಯ ಅಂಚಿನಿಂದ ಸ್ವೈಪ್ ಮಾಡುತ್ತಿದ್ದೀರಿ ಎಂದು ಖಚಿತಪಡಿಸಿಕೊಳ್ಳಿ."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"ನೀವು ಬಲ ಅಥವಾ ಎಡ ಅಂಚಿನಿಂದ ಸ್ಕ್ರೀನ್‌ನ ಮಧ್ಯಕ್ಕೆ ಸ್ವೈಪ್ ಮಾಡುತ್ತಿದ್ದೀರಿ ಎಂದು ಖಚಿತಪಡಿಸಿಕೊಂಡು ಬಿಟ್ಟುಬಿಡಿ."</string>
- <string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"ಹಿಂದೆ ಹೋಗಲು ಬಲದಿಂದ ಸ್ವೈಪ್ ಮಾಡುವುದು ಹೇಗೆಂದು ಕಲಿತಿರಿ. ಮುಂದೆ, ಆ್ಯಪ್‌ಗಳನ್ನು ಬದಲಿಸುವುದು ಹೇಗೆಂದು ತಿಳಿಯಿರಿ."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"ನೀವು ಗೋ ಬ್ಯಾಕ್ ಗೆಸ್ಚರ್ ಅನ್ನು ಪೂರ್ಣಗೊಳಿಸಿದ್ದೀರಿ."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"ನೀವು ಸ್ಕ್ರೀನ್‌ನ ಕೆಳಭಾಗಕ್ಕೆ ಹೆಚ್ಚು ಹತ್ತಿರ ಸ್ವೈಪ್ ಮಾಡದಂತೆ ನೋಡಿಕೊಳ್ಳಿ."</string>
- <string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"ಬ್ಯಾಕ್ ಗೆಸ್ಚರ್‌ನ ಸೂಕ್ಷ್ಮತೆ ಬದಲಾಯಿಸಲು, ಸೆಟ್ಟಿಂಗ್‌ಗಳಿಗೆ ಹೋಗಿ"</string>
- <string name="back_gesture_intro_title" msgid="19551256430224428">"ಹಿಂದಕ್ಕೆ ಹೋಗಲು ಸ್ವೈಪ್ ಮಾಡಿ"</string>
- <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"ಕೊನೆಯ ಸ್ಕ್ರೀನ್‌ಗೆ ಹಿಂತಿರುಗಲು, ಎಡ ಅಥವಾ ಬಲ ಅಂಚಿನಿಂದ ಸ್ಕ್ರೀನ್ ಮಧ್ಯಕ್ಕೆ ಸ್ವೈಪ್ ಮಾಡಿ."</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"ಸ್ಕ್ರೀನ್‌ನ ಕೆಳಗಿನ ಅಂಚಿನಿಂದ ನೀವು ಸ್ವೈಪ್ ಮಾಡುತ್ತಿದ್ದೀರಿ ಎಂದು ಖಚಿತಪಡಿಸಿಕೊಳ್ಳಿ."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"ವಿರಾಮಗೊಳಿಸದೆ ನಿಮ್ಮ ಬೆರಳನ್ನು ಸ್ಕ್ರೀನ್‌ನಿಂದ ಮೇಲೆತ್ತಿ."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"ನೀವು ನೇರವಾಗಿ ಸ್ವೈಪ್ ಮಾಡುತ್ತಿದ್ದೀರಿ ಎಂದು ಖಚಿತಪಡಿಸಿಕೊಳ್ಳಿ."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"ನೀವು ಗೋ ಹೋಮ್ ಗೆಸ್ಚರ್ ಅನ್ನು ಪೂರ್ಣಗೊಳಿಸಿದ್ದೀರಿ. ಮುಂದೆ, ಹಿಂದಕ್ಕೆ ಹೋಗುವುದು ಹೇಗೆ ಎಂದು ತಿಳಿಯಿರಿ."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"ನೀವು ಗೋ ಹೋಮ್ ಗೆಸ್ಚರ್ ಅನ್ನು ಪೂರ್ಣಗೊಳಿಸಿದ್ದೀರಿ."</string>
- <string name="home_gesture_intro_title" msgid="836590312858441830">"ಹೋಮ್ ಸ್ಕ್ರೀನ್‌ಗೆ ಹಿಂತಿರುಗಲು ಸ್ವೈಪ್ ಮಾಡಿ"</string>
- <string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"ಸ್ಕ್ರೀನ್‌ನ ಕೆಳಗಿನಿಂದ ಮೇಲೆ ಸ್ವೈಪ್ ಮಾಡಿ. ಈ ಗೆಸ್ಚರ್ ಯಾವಾಗಲೂ ನಿಮ್ಮನ್ನು ಹೋಮ್‌ ಸ್ಕ್ರೀನ್‌ಗೆ ಕರೆದೊಯ್ಯುತ್ತದೆ."</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"ಸ್ಕ್ರೀನ್‌ನ ಕೆಳಗಿನ ಅಂಚಿನಿಂದ ನೀವು ಸ್ವೈಪ್ ಮಾಡುತ್ತಿದ್ದೀರಿ ಎಂದು ಖಚಿತಪಡಿಸಿಕೊಳ್ಳಿ."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"ಬೆರಳನ್ನು ಮೇಲೆತ್ತುವ ಮೊದಲು ವಿಂಡೋವನ್ನು ಹೆಚ್ಚು ಸಮಯ ಹಿಡಿದಿಡಲು ಪ್ರಯತ್ನಿಸಿ."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"ನೀವು ನೇರವಾಗಿ ಸ್ವೈಪ್ ಮಾಡಿ ಎಂದು ಖಚಿತಪಡಿಸಿಕೊಳ್ಳಿ, ನಂತರ ವಿರಾಮಗೊಳಿಸಿ."</string>
- <string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"ಗೆಶ್ಚರ್‌ಗಳನ್ನು ಬಳಸುವುದು ಹೇಗೆಂದು ನೀವು ತಿಳಿದುಕೊಂಡಿರುವಿರಿ. ಗೆಶ್ಚರ್‌ಗಳನ್ನು ಆಫ್ ಮಾಡಲು, ಸೆಟ್ಟಿಂಗ್‌ಗಳಿಗೆ ಹೋಗಿ."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"ನೀವು ಆ್ಯಪ್‌ಗಳನ್ನು ಬದಲಾಯಿಸುವ ಗೆಸ್ಚರ್ ಅನ್ನು ಪೂರ್ಣಗೊಳಿಸಿದ್ದೀರಿ."</string>
- <string name="overview_gesture_intro_title" msgid="2902054412868489378">"ಆ್ಯಪ್‌ಗಳನ್ನು ಬದಲಾಯಿಸಲು ಸ್ವೈಪ್ ಮಾಡಿ"</string>
- <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"ಆ್ಯಪ್‌ಗಳ ನಡುವೆ ಬದಲಿಸಲು, ನಿಮ್ಮ ಸ್ಕ್ರೀನ್‌ನ ಕೆಳಭಾಗದಿಂದ ಮೇಲಕ್ಕೆ ಸ್ವೈಪ್ ಮಾಡಿ, ಹಿಡಿದಿಟ್ಟುಕೊಳ್ಳಿ, ನಂತರ ಬಿಟ್ಟುಬಿಡಿ."</string>
- <string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"ಸಂಪೂರ್ಣ ಸಿದ್ಧವಾಗಿದೆ"</string>
- <string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"ಮುಗಿದಿದೆ"</string>
- <string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"ಸೆಟ್ಟಿಂಗ್‌ಗಳು"</string>
- <string name="gesture_tutorial_try_again" msgid="65962545858556697">"ಪುನಃ ಪ್ರಯತ್ನಿಸಿ"</string>
- <string name="gesture_tutorial_nice" msgid="2936275692616928280">"ಚೆನ್ನಾಗಿದೆ!"</string>
- <string name="gesture_tutorial_step" msgid="1279786122817620968">"ಟ್ಯುಟೋರಿಯಲ್ <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
- <string name="allset_title" msgid="5021126669778966707">"ಎಲ್ಲವೂ ಸಿದ್ಧವಾಗಿದೆ!"</string>
- <string name="allset_hint" msgid="2384632994739392447">"ಮುಖಪುಟಕ್ಕೆ ಹೋಗಲು ಮೇಲಕ್ಕೆ ಸ್ವೈಪ್ ಮಾಡಿ"</string>
- <string name="allset_description" msgid="6350320429953234580">"ನಿಮ್ಮ ಫೋನ್ ಬಳಸುವುದನ್ನು ಪ್ರಾರಂಭಿಸಲು ನೀವು ಸಿದ್ದರಾಗಿರುವಿರಿ"</string>
- <string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"ಸಿಸ್ಟಂ ನ್ಯಾವಿಗೇಶನ್ ಸೆಟ್ಟಿಂಗ್‌ಗಳು"</annotation></string>
- <string name="action_share" msgid="2648470652637092375">"ಹಂಚಿಕೊಳ್ಳಿ"</string>
- <string name="action_screenshot" msgid="8171125848358142917">"ಸ್ಕ್ರೀನ್‌ಶಾಟ್"</string>
- <string name="action_split" msgid="2098009717623550676">"ವಿಭಜಿಸಿ"</string>
- <string name="toast_split_select_app" msgid="5453865907322018352">"ಸ್ಪ್ಲಿಟ್ ಸ್ಕ್ರೀನ್ ಅನ್ನು ಬಳಸಲು ಬೇರೊಂದು ಆ್ಯಪ್ ಮೇಲೆ ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
- <string name="toast_split_app_unsupported" msgid="3271526028981899666">"ಸ್ಪ್ಲಿಟ್ ಸ್ಕ್ರೀನ್ ಅನ್ನು ಆ್ಯಪ್ ಬೆಂಬಲಿಸುವುದಿಲ್ಲ."</string>
- <string name="blocked_by_policy" msgid="2071401072261365546">"ಆ್ಯಪ್ ಅಥವಾ ನಿಮ್ಮ ಸಂಸ್ಥೆಯು ಈ ಕ್ರಿಯೆಯನ್ನು ಅನುಮತಿಸುವುದಿಲ್ಲ"</string>
- <string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"ನ್ಯಾವಿಗೇಷನ್ ಟ್ಯುಟೋರಿಯಲ್ ಸ್ಕಿಪ್ ಮಾಡಿ?"</string>
- <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"<xliff:g id="NAME">%1$s</xliff:g> ಆ್ಯಪ್‌ನಲ್ಲಿ ಇದನ್ನು ನಂತರ ಕಾಣಬಹುದು"</string>
- <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"ರದ್ದುಮಾಡಿ"</string>
- <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"ಸ್ಕಿಪ್ ಮಾಡಿ"</string>
- <string name="accessibility_rotate_button" msgid="4771825231336502943">"ಸ್ಕ್ರೀನ್ ತಿರುಗಿಸಿ"</string>
- <string name="taskbar_edu_opened" msgid="3950252793551919129">"ಟಾಸ್ಕ್‌ಬಾರ್ ಶಿಕ್ಷಣ ಕಾಣಿಸಿಕೊಂಡಿದೆ"</string>
- <string name="taskbar_edu_closed" msgid="126643734478892862">"ಟಾಸ್ಕ್‌ಬಾರ್ ಶಿಕ್ಷಣ ಮುಚ್ಚಿದೆ"</string>
- <string name="taskbar_edu_switch_apps" msgid="6942863327845784813">"ಆ್ಯಪ್‌ಗಳನ್ನು ಬದಲಾಯಿಸಲು ಟಾಸ್ಕ್ ಬಾರ್ ಬಳಸಿ"</string>
- <string name="taskbar_edu_splitscreen" msgid="2663361731630346489">"ಏಕಕಾಲದಲ್ಲಿ ಎರಡು ಆ್ಯಪ್‌ಗಳನ್ನು ಬಳಸಲು, ಬದಿಗೆ ಡ್ರ್ಯಾಗ್ ಮಾಡಿ"</string>
- <string name="taskbar_edu_stashing" msgid="5212374387411764031">"ಟಾಸ್ಕ್‌ಬಾರ್ ಅನ್ನು ಮರೆಮಾಡಲು ಸ್ಪರ್ಶಿಸಿ ಮತ್ತು ಹೋಲ್ಡ್ ಮಾಡಿ"</string>
- <string name="taskbar_edu_next" msgid="4007618274426775841">"ಮುಂದೆ"</string>
- <string name="taskbar_edu_previous" msgid="459202320127201702">"ಹಿಂದೆ"</string>
- <string name="taskbar_edu_close" msgid="887022990168191073">"ಮುಚ್ಚಿರಿ"</string>
- <string name="taskbar_edu_done" msgid="6880178093977704569">"ಮುಗಿದಿದೆ"</string>
- <string name="taskbar_button_home" msgid="2151398979630664652">"ಮುಖಪುಟ"</string>
- <string name="taskbar_button_a11y" msgid="5241161324875094465">"ಪ್ರವೇಶಿಸುವಿಕೆ"</string>
- <string name="taskbar_button_back" msgid="8558862226461164514">"ಹಿಂದೆ"</string>
- <string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"IME ಪರಿವರ್ತಕ"</string>
- <string name="taskbar_button_recents" msgid="7273376136216613134">"ಇತ್ತೀಚಿನವು"</string>
- <string name="taskbar_button_notifications" msgid="7471740351507357318">"ಅಧಿಸೂಚನೆಗಳು"</string>
- <string name="taskbar_button_quick_settings" msgid="227662894293189391">"ತ್ವರಿತ ಸೆಟ್ಟಿಂಗ್‍ಗಳು"</string>
- <string name="move_drop_target_top_or_left" msgid="2988702185049595807">"ಮೇಲಿನ/ಎಡಭಾಗಕ್ಕೆ ಸರಿಸಿ"</string>
- <string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"ಕೆಳಗಿನ/ಬಲಭಾಗಕ್ಕೆ ಸರಿಸಿ"</string>
+ <string name="all_apps_label" msgid="8542784161730910663">"ಎಲ್ಲಾ ಆ್ಯಪ್‌ಗಳು"</string>
+ <string name="all_apps_prediction_tip" msgid="2672336544844936186">"ನಿಮ್ಮ ಸಂಭವನೀಯ ಆ್ಯಪ್‌ಗಳು"</string>
</resources>
diff --git a/quickstep/res/values-ko/strings.xml b/quickstep/res/values-ko/strings.xml
index 08e5642068..7a8e6a1f9a 100644
--- a/quickstep/res/values-ko/strings.xml
+++ b/quickstep/res/values-ko/strings.xml
@@ -19,93 +19,19 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="recent_task_option_split_screen" msgid="5353188922202653570">"화면 분할"</string>
<string name="recent_task_option_pin" msgid="7929860679018978258">"고정"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"자유 형식"</string>
+ <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"최근 사용"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"최근 항목이 없습니다."</string>
+ <string name="accessibility_close_task" msgid="5354563209433803643">"닫기"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"앱 사용 설정"</string>
<string name="recents_clear_all" msgid="5328176793634888831">"모두 삭제"</string>
<string name="accessibility_recent_apps" msgid="4058661986695117371">"최근 앱"</string>
- <string name="task_view_closed" msgid="9170038230110856166">"작업 종료됨"</string>
<string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
<string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1분"</string>
<string name="time_left_for_app" msgid="3111996412933644358">"오늘 <xliff:g id="TIME">%1$s</xliff:g> 남음"</string>
- <string name="title_app_suggestions" msgid="4185902664111965088">"앱 제안"</string>
+ <string name="title_app_suggestions" msgid="4185902664111965088">"앱 추천"</string>
+ <string name="all_apps_label" msgid="8542784161730910663">"모든 앱"</string>
<string name="all_apps_prediction_tip" msgid="2672336544844936186">"추천 앱"</string>
- <string name="hotseat_edu_title_migrate" msgid="306578144424489980">"홈 화면 하단에서 앱 제안 보기"</string>
- <string name="hotseat_edu_title_migrate_landscape" msgid="3633942953997845243">"홈 화면의 즐겨찾기 행에서 앱 제안 보기"</string>
- <string name="hotseat_edu_message_migrate" msgid="8927179260533775320">"홈 화면에서 자주 사용하는 앱에 바로 액세스할 수 있습니다. 제안은 사용 습관에 따라 바뀌며, 하단의 앱들은 홈 화면으로 이동합니다."</string>
- <string name="hotseat_edu_message_migrate_landscape" msgid="4248943380443387697">"홈 화면에서 가장 많이 사용한 앱에 바로 액세스할 수 있습니다. 제안은 루틴에 따라 달라집니다. 즐겨찾기 행의 앱이 홈 화면으로 이동합니다."</string>
- <string name="hotseat_edu_message_migrate_alt" msgid="3042360119039646356">"홈 화면에서 자주 사용하는 앱에 바로 액세스할 수 있습니다. 제안은 사용 습관에 따라 바뀌며, 하단의 앱들은 새 폴더로 이동합니다."</string>
- <string name="hotseat_edu_accept" msgid="1611544083278999837">"앱 제안받기"</string>
- <string name="hotseat_edu_dismiss" msgid="2781161822780201689">"나중에"</string>
- <string name="hotseat_prediction_settings" msgid="6246554993566070818">"설정"</string>
- <string name="hotseat_auto_enrolled" msgid="522100018967146807">"가장 많이 사용한 앱이 여기에 표시되며 루틴에 따라 달라짐"</string>
- <string name="hotseat_tip_no_empty_slots" msgid="1325212677738179185">"하단 행에서 앱을 드래그하여 앱 제안 받기"</string>
- <string name="hotseat_tip_gaps_filled" msgid="3035673010274223538">"빈 공간에 앱 제안이 추가됨"</string>
- <string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"앱 제안이 사용 설정됨"</string>
- <string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"앱 제안이 사용 중지됨"</string>
- <string name="hotseat_prediction_content_description" msgid="4582028296938078419">"예상 앱: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"오른쪽 또는 왼쪽 가장자리 끝에서 스와이프하세요."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"오른쪽 또는 왼쪽 가장자리에서 화면 중앙으로 스와이프한 후 손가락을 떼세요."</string>
- <string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"오른쪽에서 스와이프하여 뒤로 돌아가는 방법을 배웠습니다. 이번에는 앱 전환 방법을 알아보겠습니다."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"돌아가기 동작을 완료했습니다."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"화면 하단에 지나치게 가까운 곳에서 스와이프하면 안 됩니다."</string>
- <string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"돌아가기 동작의 민감도를 변경하려면 설정으로 이동하세요"</string>
- <string name="back_gesture_intro_title" msgid="19551256430224428">"스와이프하여 돌아가기"</string>
- <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"마지막 화면으로 돌아가려면 왼쪽 또는 오른쪽 가장자리에서 화면 중앙으로 스와이프하세요."</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"화면 하단 가장자리에서 위로 스와이프하세요."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"손가락을 떼기 전에 멈추지 않아야 합니다."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"위로 똑바르게 스와이프하세요."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"홈으로 이동 동작을 완료했습니다. 이번에는 뒤로 돌아가는 방법을 알아보겠습니다."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"홈으로 이동 동작을 완료했습니다."</string>
- <string name="home_gesture_intro_title" msgid="836590312858441830">"스와이프하여 홈으로 이동"</string>
- <string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"화면 하단에서 위로 스와이프합니다. 이 동작을 사용하면 언제든지 홈 화면으로 이동할 수 있습니다."</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"화면 하단 가장자리에서 위로 스와이프하세요."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"창을 더 오래 누르고 있다가 손가락을 떼 보세요."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"위로 똑바르게 스와이프한 후 잠깐 멈추세요."</string>
- <string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"동작 사용 방법을 알아봤습니다. 동작을 사용 중지하려면 설정으로 이동하세요."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"앱 전환 동작을 완료했습니다."</string>
- <string name="overview_gesture_intro_title" msgid="2902054412868489378">"스와이프로 앱 전환"</string>
- <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"앱 간에 전환하려면 화면 하단에서 위로 스와이프하고 잠시 멈춘 다음 손가락을 떼세요."</string>
- <string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"설정 완료"</string>
- <string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"완료"</string>
- <string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"설정"</string>
- <string name="gesture_tutorial_try_again" msgid="65962545858556697">"다시 시도"</string>
- <string name="gesture_tutorial_nice" msgid="2936275692616928280">"잘하셨습니다"</string>
- <string name="gesture_tutorial_step" msgid="1279786122817620968">"튜토리얼 <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
- <string name="allset_title" msgid="5021126669778966707">"설정 완료"</string>
- <string name="allset_hint" msgid="2384632994739392447">"위로 스와이프하여 홈으로 이동"</string>
- <string name="allset_description" msgid="6350320429953234580">"휴대전화를 사용할 준비가 되었습니다."</string>
- <string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"시스템 탐색 설정"</annotation></string>
- <string name="action_share" msgid="2648470652637092375">"공유"</string>
- <string name="action_screenshot" msgid="8171125848358142917">"스크린샷"</string>
- <string name="action_split" msgid="2098009717623550676">"분할"</string>
- <string name="toast_split_select_app" msgid="5453865907322018352">"다른 앱을 탭하여 화면 분할 사용"</string>
- <string name="toast_split_app_unsupported" msgid="3271526028981899666">"앱이 화면 분할을 지원하지 않습니다."</string>
- <string name="blocked_by_policy" msgid="2071401072261365546">"이 작업은 앱 또는 조직에서 허용되지 않습니다."</string>
- <string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"이동 방법 튜토리얼을 건너뛰시겠습니까?"</string>
- <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"이 튜토리얼은 <xliff:g id="NAME">%1$s</xliff:g> 앱에서 다시 볼 수 있습니다"</string>
- <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"취소"</string>
- <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"건너뛰기"</string>
- <string name="accessibility_rotate_button" msgid="4771825231336502943">"화면 회전"</string>
- <string name="taskbar_edu_opened" msgid="3950252793551919129">"작업 표시줄 튜토리얼 패널 표시됨"</string>
- <string name="taskbar_edu_closed" msgid="126643734478892862">"작업 표시줄 튜토리얼 패널 닫힘"</string>
- <string name="taskbar_edu_switch_apps" msgid="6942863327845784813">"작업 표시줄을 사용하여 앱 전환"</string>
- <string name="taskbar_edu_splitscreen" msgid="2663361731630346489">"옆으로 드래그하여 한 번에 앱 두 개 사용"</string>
- <string name="taskbar_edu_stashing" msgid="5212374387411764031">"작업 표시줄을 숨기려면 길게 터치하세요."</string>
- <string name="taskbar_edu_next" msgid="4007618274426775841">"다음"</string>
- <string name="taskbar_edu_previous" msgid="459202320127201702">"뒤로"</string>
- <string name="taskbar_edu_close" msgid="887022990168191073">"닫기"</string>
- <string name="taskbar_edu_done" msgid="6880178093977704569">"완료"</string>
- <string name="taskbar_button_home" msgid="2151398979630664652">"홈"</string>
- <string name="taskbar_button_a11y" msgid="5241161324875094465">"접근성"</string>
- <string name="taskbar_button_back" msgid="8558862226461164514">"뒤로"</string>
- <string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"IME 전환기"</string>
- <string name="taskbar_button_recents" msgid="7273376136216613134">"최근 항목"</string>
- <!-- no translation found for taskbar_button_notifications (7471740351507357318) -->
- <skip />
- <!-- no translation found for taskbar_button_quick_settings (227662894293189391) -->
- <skip />
- <string name="move_drop_target_top_or_left" msgid="2988702185049595807">"상단/왼쪽으로 이동"</string>
- <string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"하단/오른쪽으로 이동"</string>
</resources>
diff --git a/quickstep/res/values-ky/strings.xml b/quickstep/res/values-ky/strings.xml
index c1ca8b3cc6..4018e57dcc 100644
--- a/quickstep/res/values-ky/strings.xml
+++ b/quickstep/res/values-ky/strings.xml
@@ -19,91 +19,19 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Экранды бөлүү"</string>
<string name="recent_task_option_pin" msgid="7929860679018978258">"Кадап коюу"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Эркин форма режими"</string>
+ <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Сереп салуу"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"Акыркы колдонмолор жок"</string>
+ <string name="accessibility_close_task" msgid="5354563209433803643">"Жабуу"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Колдонмону пайдалануу жөндөөлөрү"</string>
<string name="recents_clear_all" msgid="5328176793634888831">"Баарын тазалоо"</string>
<string name="accessibility_recent_apps" msgid="4058661986695117371">"Акыркы колдонмолор"</string>
- <string name="task_view_closed" msgid="9170038230110856166">"Тапшырма жабылды"</string>
<string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
<string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 мүнөт"</string>
<string name="time_left_for_app" msgid="3111996412933644358">"Бүгүн <xliff:g id="TIME">%1$s</xliff:g> мүнөт калды"</string>
- <string name="title_app_suggestions" msgid="4185902664111965088">"Сунушталган колдонмолор"</string>
+ <string name="title_app_suggestions" msgid="4185902664111965088">"Колдонмо сунуштары"</string>
+ <string name="all_apps_label" msgid="8542784161730910663">"Бардык колдонмолор"</string>
<string name="all_apps_prediction_tip" msgid="2672336544844936186">"Божомолдонгон колдонмолоруңуз"</string>
- <string name="hotseat_edu_title_migrate" msgid="306578144424489980">"Сунушталган колдонмолор башкы экрандын ылдый жагында көрүнөт."</string>
- <string name="hotseat_edu_title_migrate_landscape" msgid="3633942953997845243">"Сунушталган колдонмолор башкы экрандагы тандалмалардын катарында көрүнөт."</string>
- <string name="hotseat_edu_message_migrate" msgid="8927179260533775320">"Көп колдонулган колдонмолор башкы экранда жайгашып, алардын тизмеси маал-маалы менен өзгөрүп турат. Ылдый жакта жайгашкан тилкедеги колдонмолор башкы экранга жылдырылат."</string>
- <string name="hotseat_edu_message_migrate_landscape" msgid="4248943380443387697">"Көп иштетилген колдонмолорго Башкы экрандан оңой кириңиз. Сунуштар тартиптин негизинде өзгөрөт. Тандалмалардын катарындагы колдонмолор башкы экраныңызга жылдырылат."</string>
- <string name="hotseat_edu_message_migrate_alt" msgid="3042360119039646356">"Көп колдонулган колдонмолор башкы экранда жайгашып, алардын тизмеси маал-маалы менен өзгөрүп турат. Ылдый жакта жайгашкан тилкедеги колдонмолор жаңы папкага жылдырылат."</string>
- <string name="hotseat_edu_accept" msgid="1611544083278999837">"Сунушталган колдонолорду алуу"</string>
- <string name="hotseat_edu_dismiss" msgid="2781161822780201689">"Жок, рахмат"</string>
- <string name="hotseat_prediction_settings" msgid="6246554993566070818">"Жөндөөлөр"</string>
- <string name="hotseat_auto_enrolled" msgid="522100018967146807">"Көп иштетилген колдонмолор ушул жерде көрүнүп, тартиптин негизинде өзгөрөт"</string>
- <string name="hotseat_tip_no_empty_slots" msgid="1325212677738179185">"Сунуштарды алып туруу үчүн ылдый жактагы тилкедеги колдонмолорду сүйрөп келиңиз"</string>
- <string name="hotseat_tip_gaps_filled" msgid="3035673010274223538">"Сунушталган колдонмолор бош жерге кошулат"</string>
- <string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Сунушталган колдонмолор функциясы иштетилди"</string>
- <string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Сунушталган колдонмолор функциясы өчүрүлгөн"</string>
- <string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Божомолдонгон колдонмо: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Экранды эң четинен оңдон солго же солдон оңго карай сүрүңүз."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Экранды оң же сол жагынан ортосуна карай сүрүп, манжаңызды алыңыз."</string>
- <string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Артка кайтуу үчүн экранды оңдон солго карай сүрүүнү үйрөндүңүз. Эми колдонмолорду которуштурганды үйрөнүп алыңыз."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"\"Артка\" жаңсоосун үйрөндүңүз."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Манжаңызды экрандын ылдый жагына өтө жакындатпай сүрүңүз."</string>
- <string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"\"Артка\" жаң-нун сезгичтигин өзгөртүү үчүн жөндөөлөргө өтүңүз"</string>
- <string name="back_gesture_intro_title" msgid="19551256430224428">"Артка кайтуу үчүн сүрүңүз"</string>
- <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"Акыркы экранга кайтуу үчүн экранды сол же оң жагынан ортосуна карай сүрүңүз."</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Экранды ылдыйдан өйдө сүрүңүз."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Манжаңызды алганга чейин токтотпоңуз."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Экранды өйдө сүрүңүз."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"\"Башкы бетке өтүү\" жаңсоосун үйрөндүңүз. Эми артка кайтууну үйрөнүп алыңыз."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"\"Башкы бетке өтүү\" жаңсоосун үйрөндүңүз."</string>
- <string name="home_gesture_intro_title" msgid="836590312858441830">"Башкы бетке өтүү үчүн сүрүп коюңуз"</string>
- <string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Экранды ылдый жагынан өйдө сүрүңүз. Бул жаңсоо сизди ар дайым Башкы экранга алып барат."</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Экранды ылдыйдан өйдө сүрүңүз."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Манжаңызды алуудан мурун экранда узагыраак кармаңыз."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Экранды өйдө карай сүрүп, токтоп туруңуз."</string>
- <string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Жаңсоолорду колдонгонду үйрөндүңүз. Жаңсоолорду өчүрүү үчүн жөндөөлөргө өтүңүз."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"\"Колдонмолорду которуштуруу\" жаңсоосун үйрөндүңүз."</string>
- <string name="overview_gesture_intro_title" msgid="2902054412868489378">"Колдонмолорду которуштуруу үчүн сүрүңүз"</string>
- <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Бир колдонмодон экинчисине өтүү үчүн экранды ылдыйдан өйдө карай сүрүп, бир аз коё бербей туруңуз."</string>
- <string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"Дапдаяр!"</string>
- <string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Бүттү"</string>
- <string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Жөндөөлөр"</string>
- <string name="gesture_tutorial_try_again" msgid="65962545858556697">"Кайталап көрүңүз"</string>
- <string name="gesture_tutorial_nice" msgid="2936275692616928280">"Сонун!"</string>
- <string name="gesture_tutorial_step" msgid="1279786122817620968">"Үйрөткүч: <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
- <string name="allset_title" msgid="5021126669778966707">"Бүттү!"</string>
- <string name="allset_hint" msgid="2384632994739392447">"Башкы бетке өтүү үчүн экранды өйдө сүрүңүз"</string>
- <string name="allset_description" msgid="6350320429953234580">"Телефонуңузду колдоно берсеңиз болот"</string>
- <string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"Өтүү аракетинин тутумдук жөндөөлөрү"</annotation></string>
- <string name="action_share" msgid="2648470652637092375">"Бөлүшүү"</string>
- <string name="action_screenshot" msgid="8171125848358142917">"Скриншот"</string>
- <string name="action_split" msgid="2098009717623550676">"Бөлүү"</string>
- <string name="toast_split_select_app" msgid="5453865907322018352">"Экранды бөлүү үчүн башка колдонмону таптап коюңуз"</string>
- <string name="toast_split_app_unsupported" msgid="3271526028981899666">"Колдонмодо экран бөлүнбөйт."</string>
- <string name="blocked_by_policy" msgid="2071401072261365546">"Бул аракетти аткарууга колдонмо же ишканаңыз тыюу салган"</string>
- <string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Жаңсоолор үйрөткүчүн өткөрүп жибересизби?"</string>
- <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Аны кийин <xliff:g id="NAME">%1$s</xliff:g> колдонмосунан табасыз"</string>
- <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Жокко чыгаруу"</string>
- <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Өткрп жиберүү"</string>
- <string name="accessibility_rotate_button" msgid="4771825231336502943">"Экранды буруу"</string>
- <string name="taskbar_edu_opened" msgid="3950252793551919129">"Тапшырмалар тактасынын окутуу панели көрсөтүлдү"</string>
- <string name="taskbar_edu_closed" msgid="126643734478892862">"Тапшырмалар тактасынын окутуу панели жабылды"</string>
- <string name="taskbar_edu_switch_apps" msgid="6942863327845784813">"Тапшырмалар тактасы аркылуу башка колдонмого которула аласыз"</string>
- <string name="taskbar_edu_splitscreen" msgid="2663361731630346489">"Эки колдонмону бир убакта пайдалануу үчүн капталга сүрүңүз"</string>
- <string name="taskbar_edu_stashing" msgid="5212374387411764031">"Тапшырмалар тактасын жашыруу үчүн коё бербей басып туруңуз"</string>
- <string name="taskbar_edu_next" msgid="4007618274426775841">"Кийинки"</string>
- <string name="taskbar_edu_previous" msgid="459202320127201702">"Артка"</string>
- <string name="taskbar_edu_close" msgid="887022990168191073">"Жабуу"</string>
- <string name="taskbar_edu_done" msgid="6880178093977704569">"Бүттү"</string>
- <string name="taskbar_button_home" msgid="2151398979630664652">"Башкы бет"</string>
- <string name="taskbar_button_a11y" msgid="5241161324875094465">"Атайын мүмкүнчүлүктөр"</string>
- <string name="taskbar_button_back" msgid="8558862226461164514">"Артка"</string>
- <string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"IME которгучу"</string>
- <string name="taskbar_button_recents" msgid="7273376136216613134">"Акыркылар"</string>
- <string name="taskbar_button_notifications" msgid="7471740351507357318">"Билдирмелер"</string>
- <string name="taskbar_button_quick_settings" msgid="227662894293189391">"Ыкчам жөндөөлөр"</string>
- <string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Жогорку/сол бурчка жылдыруу"</string>
- <string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Төмөнкү/оң бурчка жылдыруу"</string>
</resources>
diff --git a/quickstep/res/values-land/dimens.xml b/quickstep/res/values-land/dimens.xml
index f233bde73a..668aea2c9e 100644
--- a/quickstep/res/values-land/dimens.xml
+++ b/quickstep/res/values-land/dimens.xml
@@ -16,61 +16,4 @@
-->
<resources>
<dimen name="overview_task_margin">8dp</dimen>
-
- <!-- Tips Gesture Tutorial -->
- <dimen name="gesture_tutorial_feedback_margin_start_end">126dp</dimen>
- <dimen name="gesture_tutorial_feedback_margin_top">24dp</dimen>
-
- <!-- Gesture Tutorial mock conversations -->
- <dimen name="gesture_tutorial_message_padding_start">42dp</dimen>
- <dimen name="gesture_tutorial_message_padding_end">60dp</dimen>
- <dimen name="gesture_tutorial_top_bar_margin_start">42dp</dimen>
- <dimen name="gesture_tutorial_top_bar_margin_end">683dp</dimen>
- <dimen name="gesture_tutorial_top_bar_button_margin_end">42dp</dimen>
- <dimen name="gesture_tutorial_conversation_bottom_padding">35dp</dimen>
- <integer name="gesture_tutorial_extra_messages_visibility">2</integer> <!-- GONE -->
- <dimen name="gesture_tutorial_message_margin_start">505dp</dimen>
- <dimen name="gesture_tutorial_reply_margin_end">462dp</dimen>
- <dimen name="gesture_tutorial_input_margin_start">103dp</dimen>
- <dimen name="gesture_tutorial_input_margin_end">103dp</dimen>
- <dimen name="gesture_tutorial_tablet_message_1_margin">345dp</dimen>
- <dimen name="gesture_tutorial_tablet_reply_1_margin">341dp</dimen>
- <dimen name="gesture_tutorial_tablet_message_2_margin">501dp</dimen>
- <dimen name="gesture_tutorial_tablet_message_3_margin">345dp</dimen>
- <dimen name="gesture_tutorial_tablet_reply_2_margin">373dp</dimen>
-
- <!-- Gesture Tutorial mock conversation lists -->
- <dimen name="gesture_tutorial_conversation_line_1_margin_end">607dp</dimen>
- <dimen name="gesture_tutorial_conversation_line_2_margin_end">460dp</dimen>
- <dimen name="gesture_tutorial_conversation_line_3_margin_end">554dp</dimen>
- <dimen name="gesture_tutorial_conversation_line_4_margin_end">517dp</dimen>
- <dimen name="gesture_tutorial_conversation_line_5_margin_end">570dp</dimen>
- <dimen name="gesture_tutorial_conversation_line_6_margin_end">336dp</dimen>
- <dimen name="gesture_tutorial_conversation_line_7_margin_end">523dp</dimen>
- <dimen name="gesture_tutorial_conversation_line_8_margin_end">500dp</dimen>
- <dimen name="gesture_tutorial_tablet_conversation_line_6_margin_end">15dp</dimen>
- <dimen name="gesture_tutorial_tablet_conversation_line_8_margin_end">72dp</dimen>
- <dimen name="gesture_tutorial_tablet_conversation_line_10_margin_end">111dp</dimen>
- <integer name="gesture_tutorial_extra_conversations_visibility">2</integer> <!-- GONE -->
- <dimen name="gesture_tutorial_mock_button_margin_end">34dp</dimen>
- <dimen name="gesture_tutorial_mock_button_margin_bottom">42dp</dimen>
-
- <!-- Gesture Tutorial mock hotseats -->
- <dimen name="gesture_tutorial_hotseat_width">-2px</dimen> <!-- wrap_content -->
- <dimen name="gesture_tutorial_hotseat_height">-1px</dimen> <!-- match_parent -->
- <dimen name="gesture_tutorial_hotseat_padding_start_end">170dp</dimen>
-
- <!-- Gesture Tutorial mock webpages -->
- <dimen name="gesture_tutorial_webpage_url_margin_start_end">24dp</dimen>
- <dimen name="gesture_tutorial_webpage_top_bar_button_margin_start">48dp</dimen>
- <dimen name="gesture_tutorial_webpage_top_bar_margin_start">121dp</dimen>
- <dimen name="gesture_tutorial_webpage_top_bar_margin_end">355dp</dimen>
- <dimen name="gesture_tutorial_webpage_line_1_margin_end">355dp</dimen>
- <dimen name="gesture_tutorial_webpage_line_2_margin_end">208dp</dimen>
- <dimen name="gesture_tutorial_webpage_line_3_margin_end">439dp</dimen>
- <dimen name="gesture_tutorial_webpage_block_margin_end">311dp</dimen>
- <integer name="gesture_tutorial_webpage_extra_lines_visibility">2</integer> <!-- GONE -->
-
- <!-- Gesture Tutorial mock taskbar -->
- <dimen name="gesture_tutorial_taskbar_padding_start_end">218dp</dimen>
</resources> \ No newline at end of file
diff --git a/quickstep/res/values-lo/strings.xml b/quickstep/res/values-lo/strings.xml
index 4c1791f112..e406b7083d 100644
--- a/quickstep/res/values-lo/strings.xml
+++ b/quickstep/res/values-lo/strings.xml
@@ -19,93 +19,19 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="recent_task_option_split_screen" msgid="5353188922202653570">"ແບ່ງໜ້າຈໍ"</string>
<string name="recent_task_option_pin" msgid="7929860679018978258">"ປັກໝຸດ"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"ຮູບແບບອິດສະຫລະ"</string>
+ <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"ພາບຮວມ"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"ບໍ່ມີລາຍການຫຼ້າສຸດ"</string>
+ <string name="accessibility_close_task" msgid="5354563209433803643">"ປິດ"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"ການຕັ້ງຄ່າການນຳໃຊ້ແອັບ"</string>
<string name="recents_clear_all" msgid="5328176793634888831">"ລຶບລ້າງທັງໝົດ"</string>
<string name="accessibility_recent_apps" msgid="4058661986695117371">"ແອັບຫຼ້າສຸດ"</string>
- <string name="task_view_closed" msgid="9170038230110856166">"ປິດໜ້າວຽກແລ້ວ"</string>
<string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
<string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 ນາທີ"</string>
<string name="time_left_for_app" msgid="3111996412933644358">"ເຫຼືອ <xliff:g id="TIME">%1$s</xliff:g> ມື້ນີ້"</string>
<string name="title_app_suggestions" msgid="4185902664111965088">"ການແນະນຳແອັບ"</string>
+ <string name="all_apps_label" msgid="8542784161730910663">"ແອັບທັງໝົດ"</string>
<string name="all_apps_prediction_tip" msgid="2672336544844936186">"ແອັບທີ່ຄາດເດົາໄວ້ແລ້ວຂອງທ່ານ"</string>
- <string name="hotseat_edu_title_migrate" msgid="306578144424489980">"ຮັບການແນະນຳແອັບຢູ່ແຖວລຸ່ມສຸດຂອງໜ້າຈໍຫຼັກທ່ານ"</string>
- <string name="hotseat_edu_title_migrate_landscape" msgid="3633942953997845243">"ຮັບການແນະນຳແອັບຢູ່ແຖວລາຍການທີ່ມັກຂອງໜ້າຈໍຫຼັກຂອງທ່ານ"</string>
- <string name="hotseat_edu_message_migrate" msgid="8927179260533775320">"ເຂົ້າເຖິງແອັບທີ່ທ່ານໃຊ້ຫຼາຍທີ່ສຸດໄດ້ຢ່າງງ່າຍດາຍທັນທີຈາກໜ້າຈໍຫຼັກ. ການແນະນຳຈະປ່ຽນແປງຕາມການນຳໃຊ້ປະຈຳຂອງທ່ານ. ແອັບຢູ່ແຖວລຸ່ມສຸດຈະຍ້າຍຂຶ້ນໄປໃສ່ໜ້າຈໍຫຼັກຂອງທ່ານ."</string>
- <string name="hotseat_edu_message_migrate_landscape" msgid="4248943380443387697">"ເຂົ້າເຖິງແອັບທີ່ທ່ານໃຊ້ຫຼາຍທີ່ສຸດໄດ້ຢ່າງງ່າຍດາຍທັນທີຈາກໜ້າຈໍຫຼັກ. ການແນະນຳຈະປ່ຽນແປງຕາມການນຳໃຊ້ປະຈຳຂອງທ່ານ. ຕອນນີ້ແອັບໃນລາຍການທີ່ມັກຈະຍ້າຍໄປໃສ່ໜ້າຈໍຫຼັກຂອງທ່ານ."</string>
- <string name="hotseat_edu_message_migrate_alt" msgid="3042360119039646356">"ເຂົ້າເຖິງແອັບທີ່ທ່ານໃຊ້ຫຼາຍທີ່ສຸດໄດ້ຢ່າງງ່າຍດາຍທັນທີຈາກໜ້າຈໍຫຼັກ. ການແນະນຳຈະປ່ຽນແປງຕາມການນຳໃຊ້ປະຈຳຂອງທ່ານ. ແອັບຢູ່ແຖວລຸ່ມສຸດຈະຍ້າຍໄປໂຟນເດີໃໝ່."</string>
- <string name="hotseat_edu_accept" msgid="1611544083278999837">"ຮັບການແນະນຳແອັບ"</string>
- <string name="hotseat_edu_dismiss" msgid="2781161822780201689">"ບໍ່, ຂອບໃຈ"</string>
- <string name="hotseat_prediction_settings" msgid="6246554993566070818">"ການຕັ້ງຄ່າ"</string>
- <string name="hotseat_auto_enrolled" msgid="522100018967146807">"ແອັບທີ່ໃຊ້ຫຼາຍທີ່ສຸດຈະປາກົດຢູ່ບ່ອນນີ້ ແລະ ປ່ຽນໄປຕາມການນຳໃຊ້ປະຈຳ"</string>
- <string name="hotseat_tip_no_empty_slots" msgid="1325212677738179185">"ລາກແອັບຈາກແຖບລຸ່ມສຸດເພື່ອຮັບການແນະນຳແອັບ"</string>
- <string name="hotseat_tip_gaps_filled" msgid="3035673010274223538">"ເພີ່ມການແນະນຳແອັບໃສ່ພື້ນທີ່ຫວ່າງແລ້ວ"</string>
- <string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"ເປີດການນຳໃຊ້ການແນະນຳແອັບແລ້ວ"</string>
- <string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"ປິດການນຳໃຊ້ການແນະນຳແອັບແລ້ວ"</string>
- <string name="hotseat_prediction_content_description" msgid="4582028296938078419">"ແອັບທີ່ຄາດເດົາໄວ້: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"ກະລຸນາກວດສອບວ່າທ່ານປັດຈາກຂອບຂວາສຸດ ຫຼື ຊ້າຍສຸດ."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"ກະລຸນາກວດສອບວ່າທ່ານປັດຈາກຂອບຂວາ ຫຼື ຊ້າຍໄປຫາທາງກາງຂອງໜ້າຈໍແລ້ວປ່ອຍນິ້ວ."</string>
- <string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"ທ່ານຮຽນຮູ້ວິທີປັດຈາກຂວາເພື່ອກັບຄືນແລ້ວ. ຕໍ່ໄປ, ມາສຶກສາວິທີສະຫຼັບແອັບ."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"ທ່ານໃຊ້ທ່າທາງກັບຄືນສຳເລັດແລ້ວ."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"ກະລຸນາກວດສອບວ່າທ່ານບໍ່ໄດ້ປັດໃກ້ກັບທາງລຸ່ມຂອງໜ້າຈໍເກີນໄປ."</string>
- <string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"ເພື່ອປ່ຽນຄວາມລະອຽດອ່ອນຂອງທ່າທາງກັບຄືນ, ໃຫ້ໄປຫາການຕັ້ງຄ່າ"</string>
- <string name="back_gesture_intro_title" msgid="19551256430224428">"ປັດເພື່ອກັບຄືນ"</string>
- <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"ເພື່ອກັບໄປໜ້າຈໍຫຼ້າສຸດ, ໃຫ້ປັດຈາກຂອບຊ້າຍ ຫຼື ຂວາໄປຫາທາງກາງຂອງໜ້າຈໍ."</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"ກະລຸນາກວດສອບວ່າທ່ານປັດຂຶ້ນຈາກຂອບລຸ່ມສຸດຂອງໜ້າຈໍ."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"ກະລຸນາກວດສອບວ່າທ່ານບໍ່ຢຸດຊົ່ວຄາວກ່ອນປ່ອຍນິ້ວ."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"ກະລຸນາກວດສອບວ່າທ່ານປັດຂຶ້ນໄປຊື່ໆ."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"ທ່ານໃຊ້ທ່າທາງໄປໜ້າຫຼັກສຳເລັດແລ້ວ. ຕໍ່ໄປ, ມາສຶກສາວິທີກັບຄືນ."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"ທ່ານໃຊ້ທ່າທາງໄປໜ້າຫຼັກສຳເລັດແລ້ວ."</string>
- <string name="home_gesture_intro_title" msgid="836590312858441830">"ປັດເພື່ອໄປໜ້າຫຼັກ"</string>
- <string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"ປັດຂຶ້ນມາຈາກລຸ່ມສຸດຂອງໜ້າຈໍທ່ານ. ທ່າທາງນີ້ຈະພາທ່ານໄປໂຮມສະກຣີນສະເໝີ."</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"ກະລຸນາກວດສອບວ່າທ່ານປັດຂຶ້ນຈາກຂອບລຸ່ມສຸດຂອງໜ້າຈໍ."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"ລອງກົດໃສ່ໜ້າຈໍຄ້າງໄວ້ດົນຂຶ້ນກ່ອນປ່ອຍນິ້ວ."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"ກະລຸນາກວດສອບວ່າທ່ານປັດຂຶ້ນຊື່ໆ, ຈາກນັ້ນຢຸດຊົ່ວຄາວ."</string>
- <string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"ທ່ານໄດ້ສຶກສາວິທີໃຊ້ທ່າທາງແລ້ວ. ເພື່ອປິດທ່າທາງຕ່າງໆ, ໃຫ້ເຂົ້າໄປຫາການຕັ້ງຄ່າ."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"ທ່ານໃຊ້ທ່າທາງສະຫຼັບແອັບສຳເລັດແລ້ວ."</string>
- <string name="overview_gesture_intro_title" msgid="2902054412868489378">"ປັດເພື່ອສະຫຼັບແອັບ"</string>
- <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"ເພື່ອສະຫຼັບລະຫວ່າງແອັບ, ໃຫ້ປັດຂຶ້ນຈາກລຸ່ມສຸດຂອງໜ້າຈໍທ່ານ, ກົດຄ້າງໄວ້, ຈາກນັ້ນປ່ອຍ."</string>
- <string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"ທຸກຢ່າງພ້ອມແລ້ວ"</string>
- <string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"ແລ້ວໆ"</string>
- <string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"ການຕັ້ງຄ່າ"</string>
- <string name="gesture_tutorial_try_again" msgid="65962545858556697">"ລອງໃໝ່"</string>
- <string name="gesture_tutorial_nice" msgid="2936275692616928280">"ດີ!"</string>
- <string name="gesture_tutorial_step" msgid="1279786122817620968">"ການສອນການນຳໃຊ້ທີ <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
- <string name="allset_title" msgid="5021126669778966707">"ຮຽບຮ້ອຍໝົດແລ້ວ!"</string>
- <string name="allset_hint" msgid="2384632994739392447">"ປັດຂຶ້ນເພື່ອໄປຫາໜ້າຫຼັກ"</string>
- <string name="allset_description" msgid="6350320429953234580">"ທ່ານພ້ອມເລີ່ມຕົ້ນໃຊ້ໂທລະສັບຂອງທ່ານແລ້ວ"</string>
- <string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"ການຕັ້ງຄ່າການນຳທາງລະບົບ"</annotation></string>
- <string name="action_share" msgid="2648470652637092375">"ແບ່ງປັນ"</string>
- <string name="action_screenshot" msgid="8171125848358142917">"ຮູບໜ້າຈໍ"</string>
- <string name="action_split" msgid="2098009717623550676">"ແບ່ງ"</string>
- <string name="toast_split_select_app" msgid="5453865907322018352">"ແຕະແອັບອື່ນເພື່ອໃຊ້ການແຍກໜ້າຈໍ"</string>
- <string name="toast_split_app_unsupported" msgid="3271526028981899666">"ແອັບບໍ່ຮອງຮັບການແບ່ງໜ້າຈໍ."</string>
- <string name="blocked_by_policy" msgid="2071401072261365546">"ແອັບ ຫຼື ອົງການຂອງທ່ານບໍ່ອະນຸຍາດໃຫ້ໃຊ້ຄຳສັ່ງນີ້"</string>
- <string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"ຂ້າມການສອນການນຳໃຊ້ການນຳທາງບໍ?"</string>
- <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"ທ່ານສາມາດຊອກສ່ວນນີ້ພາຍຫຼັງໄດ້ໃນແອັບ <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"ຍົກເລີກ"</string>
- <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"ຂ້າມ"</string>
- <string name="accessibility_rotate_button" msgid="4771825231336502943">"ໝຸນໜ້າຈໍ"</string>
- <string name="taskbar_edu_opened" msgid="3950252793551919129">"ສະແດງການສຶກສາແຖບໜ້າວຽກແລ້ວ"</string>
- <string name="taskbar_edu_closed" msgid="126643734478892862">"ປິດການສຶກສາແຖບໜ້າວຽກແລ້ວ"</string>
- <string name="taskbar_edu_switch_apps" msgid="6942863327845784813">"ໃຊ້ແຖບໜ້າວຽກເພື່ອສະຫຼັບແອັບ"</string>
- <string name="taskbar_edu_splitscreen" msgid="2663361731630346489">"ລາກໄປທາງຂ້າງເພື່ອໃຊ້ສອງແອັບພ້ອມກັນ"</string>
- <string name="taskbar_edu_stashing" msgid="5212374387411764031">"ແຕະຄ້າງໄວ້ເພື່ອເຊື່ອງແຖບໜ້າວຽກ"</string>
- <string name="taskbar_edu_next" msgid="4007618274426775841">"ຕໍ່ໄປ"</string>
- <string name="taskbar_edu_previous" msgid="459202320127201702">"ກັບຄືນ"</string>
- <string name="taskbar_edu_close" msgid="887022990168191073">"ປິດ"</string>
- <string name="taskbar_edu_done" msgid="6880178093977704569">"ແລ້ວໆ"</string>
- <string name="taskbar_button_home" msgid="2151398979630664652">"ໜ້າຫຼັກ"</string>
- <string name="taskbar_button_a11y" msgid="5241161324875094465">"ການຊ່ວຍເຂົ້າເຖິງ"</string>
- <string name="taskbar_button_back" msgid="8558862226461164514">"ກັບຄືນ"</string>
- <string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"ຕົວສະຫຼັບ IME"</string>
- <string name="taskbar_button_recents" msgid="7273376136216613134">"ຫຼ້າສຸດ"</string>
- <!-- no translation found for taskbar_button_notifications (7471740351507357318) -->
- <skip />
- <!-- no translation found for taskbar_button_quick_settings (227662894293189391) -->
- <skip />
- <string name="move_drop_target_top_or_left" msgid="2988702185049595807">"ຍ້າຍໄປຊ້າຍ/ເທິງ"</string>
- <string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"ຍ້າຍໄປຂວາ/ລຸ່ມ"</string>
</resources>
diff --git a/quickstep/res/values-lt/strings.xml b/quickstep/res/values-lt/strings.xml
index 95a7e86a9a..ed1fc373e2 100644
--- a/quickstep/res/values-lt/strings.xml
+++ b/quickstep/res/values-lt/strings.xml
@@ -19,93 +19,19 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Skaidyti ekraną"</string>
<string name="recent_task_option_pin" msgid="7929860679018978258">"Prisegti"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Laisva forma"</string>
+ <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Apžvalga"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"Nėra jokių naujausių elementų"</string>
+ <string name="accessibility_close_task" msgid="5354563209433803643">"Uždaryti"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Programos naudojimo nustatymai"</string>
<string name="recents_clear_all" msgid="5328176793634888831">"Išvalyti viską"</string>
<string name="accessibility_recent_apps" msgid="4058661986695117371">"Naujausios programos"</string>
- <string name="task_view_closed" msgid="9170038230110856166">"Užduotis uždaryta"</string>
<string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
<string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 min."</string>
<string name="time_left_for_app" msgid="3111996412933644358">"Šiandien liko: <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="title_app_suggestions" msgid="4185902664111965088">"Programų pasiūlymai"</string>
+ <string name="all_apps_label" msgid="8542784161730910663">"Visos programos"</string>
<string name="all_apps_prediction_tip" msgid="2672336544844936186">"Numatomos programos"</string>
- <string name="hotseat_edu_title_migrate" msgid="306578144424489980">"Gaukite programų pasiūlymų apatinėje pagrindinio ekrano eilutėje"</string>
- <string name="hotseat_edu_title_migrate_landscape" msgid="3633942953997845243">"Gaukite programų pasiūlymų pagrindinio ekrano eilutėje „Mėgstamiausios“"</string>
- <string name="hotseat_edu_message_migrate" msgid="8927179260533775320">"Lengvai pasiekite dažniausiai naudojamas programas iškart pagrindiniame ekrane. Pasiūlymai keisis atsižvelgiant į tai, kaip jas naudojate. Apatinėje eilutėje esančios programos bus perkeltos į pagrindinį ekraną."</string>
- <string name="hotseat_edu_message_migrate_landscape" msgid="4248943380443387697">"Lengvai pasiekite dažniausiai naudojamas programas iškart pagrindiniame ekrane. Pasiūlymai keisis atsižvelgiant į tai, kaip jas naudojate. Eilutėje „Mėgstamiausios“ rodomos programos bus perkeltos į pagrindinį ekraną."</string>
- <string name="hotseat_edu_message_migrate_alt" msgid="3042360119039646356">"Lengvai pasiekite dažniausiai naudojamas programas iškart pagrindiniame ekrane. Pasiūlymai keisis atsižvelgiant į tai, kaip jas naudojate. Apatinėje eilutėje esančios programos bus perkeltos į naują aplanką."</string>
- <string name="hotseat_edu_accept" msgid="1611544083278999837">"Gauti programų pasiūlymų"</string>
- <string name="hotseat_edu_dismiss" msgid="2781161822780201689">"Ne, ačiū"</string>
- <string name="hotseat_prediction_settings" msgid="6246554993566070818">"Nustatymai"</string>
- <string name="hotseat_auto_enrolled" msgid="522100018967146807">"Dažniausiai naudojamos programos rodomos čia ir keičiasi pagal tai, kaip jas naudojate"</string>
- <string name="hotseat_tip_no_empty_slots" msgid="1325212677738179185">"Nuvilkę programas į apatinę eilutę gausite programų pasiūlymų"</string>
- <string name="hotseat_tip_gaps_filled" msgid="3035673010274223538">"Programų pasiūlymai pridedami tuščioje vietoje"</string>
- <string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Siūlomų programų funkcija įgalinta"</string>
- <string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Siūlomų programų funkcija išjungta"</string>
- <string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Numatoma programa: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Turite perbraukti nuo dešiniojo ar kairiojo krašto."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Turite perbraukti nuo dešiniojo ar kairiojo krašto link ekrano vidurio ir pakelti pirštą."</string>
- <string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Išmokote, kaip sugrįžti perbraukiant iš dešinės. Toliau sužinosite, kaip perjungti programas."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"Atlikote grįžimo atgal gestą."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Nebraukite per arti ekrano apačios."</string>
- <string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"Norėd. pak. grįžimo gesto jautr., eikite į sk. „Nustatymai“"</string>
- <string name="back_gesture_intro_title" msgid="19551256430224428">"Norėdami grįžti, perbraukite"</string>
- <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"Norėdami grįžti į ankstesnį ekraną, perbr. nuo kairiojo arba dešinio krašto link ekrano vidurio."</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Turite perbraukti aukštyn nuo apatinio ekrano krašto."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Nepristabdykite prieš pakeldami pirštą."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Turite tiesiai perbraukti aukštyn."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"Atlikote perėjimo į pagrindinį ekraną gestą. Toliau sužinosite, kaip grįžti atgal."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"Atlikote perėjimo į pagrindinį ekraną gestą."</string>
- <string name="home_gesture_intro_title" msgid="836590312858441830">"Perbraukite, kad pereitumėte į pagrindinį ekraną"</string>
- <string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Perbraukite aukštyn nuo ekrano apačios. Atlikus šį gestą, visada nukreipiama į pagrindinį ekraną."</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Turite perbraukti aukštyn nuo apatinio ekrano krašto."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Pabandykite palaikyti langą ilgiau prieš pakeldami pirštą."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Turite tiesiai perbraukti aukštyn, o tada pristabdyti."</string>
- <string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"išmokote naudotis gestais. Gestus galite išjungti nustatymuose."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"Atlikote programų perjungimo gestą."</string>
- <string name="overview_gesture_intro_title" msgid="2902054412868489378">"Perbraukite, kad perjungtumėte programas"</string>
- <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Norėdami perjungti programas, perbraukite aukštyn nuo ekrano apačios, palaikykite ir paleiskite."</string>
- <string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"Viskas nustatyta"</string>
- <string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Atlikta"</string>
- <string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Nustatymai"</string>
- <string name="gesture_tutorial_try_again" msgid="65962545858556697">"Bandykite dar kartą"</string>
- <string name="gesture_tutorial_nice" msgid="2936275692616928280">"Šaunu!"</string>
- <string name="gesture_tutorial_step" msgid="1279786122817620968">"Mokymo programa: <xliff:g id="CURRENT">%1$d</xliff:g> iš <xliff:g id="TOTAL">%2$d</xliff:g>"</string>
- <string name="allset_title" msgid="5021126669778966707">"Paruošta!"</string>
- <string name="allset_hint" msgid="2384632994739392447">"Perbraukite aukštyn, kad grįžtumėte į pagrindinį ekraną"</string>
- <string name="allset_description" msgid="6350320429953234580">"Esate pasiruošę pradėti naudoti telefoną"</string>
- <string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"Sistemos naršymo nustatymai"</annotation></string>
- <string name="action_share" msgid="2648470652637092375">"Bendrinti"</string>
- <string name="action_screenshot" msgid="8171125848358142917">"Ekrano kopija"</string>
- <string name="action_split" msgid="2098009717623550676">"Išskaidymo režimas"</string>
- <string name="toast_split_select_app" msgid="5453865907322018352">"Pal. kitą progr., kad gal. naud. išsk. ekr. rež."</string>
- <string name="toast_split_app_unsupported" msgid="3271526028981899666">"Programoje nepalaikomas išskaidyto ekrano režimas."</string>
- <string name="blocked_by_policy" msgid="2071401072261365546">"Jūsų organizacijoje arba naudojant šią programą neleidžiama atlikti šio veiksmo"</string>
- <string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Praleisti naršymo mokymo programą?"</string>
- <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Tai galėsite rasti vėliau programoje „<xliff:g id="NAME">%1$s</xliff:g>“"</string>
- <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Atšaukti"</string>
- <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Praleisti"</string>
- <string name="accessibility_rotate_button" msgid="4771825231336502943">"Pasukti ekraną"</string>
- <string name="taskbar_edu_opened" msgid="3950252793551919129">"Užduočių juostos patarimai rodomi"</string>
- <string name="taskbar_edu_closed" msgid="126643734478892862">"Užduočių juostos patarimai uždaryti"</string>
- <string name="taskbar_edu_switch_apps" msgid="6942863327845784813">"Naudokite užduočių juostą, kad gal. perjungti programas"</string>
- <string name="taskbar_edu_splitscreen" msgid="2663361731630346489">"Nuvilkite į šoną, kad gal. vienu metu naudoti dvi programas"</string>
- <string name="taskbar_edu_stashing" msgid="5212374387411764031">"Palieskite ir palaikykite, kad paslėptumėte užduočių juostą"</string>
- <string name="taskbar_edu_next" msgid="4007618274426775841">"Kitas"</string>
- <string name="taskbar_edu_previous" msgid="459202320127201702">"Atgal"</string>
- <string name="taskbar_edu_close" msgid="887022990168191073">"Uždaryti"</string>
- <string name="taskbar_edu_done" msgid="6880178093977704569">"Atlikta"</string>
- <string name="taskbar_button_home" msgid="2151398979630664652">"Pagrindinis"</string>
- <string name="taskbar_button_a11y" msgid="5241161324875094465">"Pritaikomumas"</string>
- <string name="taskbar_button_back" msgid="8558862226461164514">"Atgal"</string>
- <string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"IMRP perjungiklis"</string>
- <string name="taskbar_button_recents" msgid="7273376136216613134">"Naujausi"</string>
- <!-- no translation found for taskbar_button_notifications (7471740351507357318) -->
- <skip />
- <!-- no translation found for taskbar_button_quick_settings (227662894293189391) -->
- <skip />
- <string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Perkelti aukštyn, kairėn"</string>
- <string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Perkelti žemyn, dešinėn"</string>
</resources>
diff --git a/quickstep/res/values-lv/strings.xml b/quickstep/res/values-lv/strings.xml
index f3de0b7f5c..85ce0e017d 100644
--- a/quickstep/res/values-lv/strings.xml
+++ b/quickstep/res/values-lv/strings.xml
@@ -19,93 +19,19 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Sadalīt ekrānu"</string>
<string name="recent_task_option_pin" msgid="7929860679018978258">"Piespraust"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Brīva forma"</string>
+ <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Pārskats"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"Nav nesenu vienumu."</string>
+ <string name="accessibility_close_task" msgid="5354563209433803643">"Aizvērt"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Lietotņu izmantošanas iestatījumi"</string>
<string name="recents_clear_all" msgid="5328176793634888831">"Notīrīt visu"</string>
<string name="accessibility_recent_apps" msgid="4058661986695117371">"Pēdējās izmantotās lietotnes"</string>
- <string name="task_view_closed" msgid="9170038230110856166">"Uzdevums ir aizvērts"</string>
<string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
<string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt;1 minūte"</string>
<string name="time_left_for_app" msgid="3111996412933644358">"Šodien atlicis: <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="title_app_suggestions" msgid="4185902664111965088">"Ieteicamās lietotnes"</string>
+ <string name="all_apps_label" msgid="8542784161730910663">"Visas lietotnes"</string>
<string name="all_apps_prediction_tip" msgid="2672336544844936186">"Jūsu prognozētās lietotnes"</string>
- <string name="hotseat_edu_title_migrate" msgid="306578144424489980">"Sākuma ekrāna apakšējā rindā tiks rādītas ieteicamās lietotnes"</string>
- <string name="hotseat_edu_title_migrate_landscape" msgid="3633942953997845243">"Saņemiet lietotņu ieteikumus izlases rindā sākuma ekrānā"</string>
- <string name="hotseat_edu_message_migrate" msgid="8927179260533775320">"Varat sākuma ekrānā ērti piekļūt savām visbiežāk izmantotajām lietotnēm. Ieteikumi mainīsies atkarībā no jūsu paradumiem. Apakšējā rindā esošās lietotnes tiks pārvietotas uz augšu — uz sākuma ekrānu."</string>
- <string name="hotseat_edu_message_migrate_landscape" msgid="4248943380443387697">"Varat sākuma ekrānā ērti piekļūt savām visbiežāk izmantotajām lietotnēm. Ieteikumi mainīsies atkarībā no jūsu paradumiem. Lietotnes no izlases rindas tiks pārvietotas uz sākuma ekrānu."</string>
- <string name="hotseat_edu_message_migrate_alt" msgid="3042360119039646356">"Varat sākuma ekrānā ērti piekļūt savām visbiežāk izmantotajām lietotnēm. Ieteikumi mainīsies atkarībā no jūsu paradumiem. Apakšējā rindā esošās lietotnes tiks pārvietotas uz jaunu mapi."</string>
- <string name="hotseat_edu_accept" msgid="1611544083278999837">"Rādīt ieteicamās lietotnes"</string>
- <string name="hotseat_edu_dismiss" msgid="2781161822780201689">"Nē, paldies"</string>
- <string name="hotseat_prediction_settings" msgid="6246554993566070818">"Iestatījumi"</string>
- <string name="hotseat_auto_enrolled" msgid="522100018967146807">"Šeit tiek rādītas visbiežāk izmantotās lietotnes, un tās mainās atkarībā no jūsu paradumiem"</string>
- <string name="hotseat_tip_no_empty_slots" msgid="1325212677738179185">"Lai skatītu ieteicamās lietotnes, velciet lietotnes prom no apakšējās rindas"</string>
- <string name="hotseat_tip_gaps_filled" msgid="3035673010274223538">"Ieteicamās lietotnes tika pievienotas tukšajā vietā"</string>
- <string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Ieteicamās lietotnes ir iespējotas"</string>
- <string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Ieteicamās lietotnes ir atspējotas"</string>
- <string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Prognozētā lietotne: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Velciet no pašas labās vai kreisās malas."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Velciet no ekrāna labās vai kreisās malas uz vidu un atlaidiet."</string>
- <string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Jūs esat apguvis, kā vilkt no labās malas, lai pārietu atpakaļ. Tagad mācieties pārslēgt lietotnes."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"Jūs sekmīgi veicāt atgriešanās žestu."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Nevelciet pārāk tuvu ekrāna apakšdaļai."</string>
- <string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"Atgriešanās žesta jutīguma līmeni varat mainīt iestatījumos."</string>
- <string name="back_gesture_intro_title" msgid="19551256430224428">"Vilkšana, lai atgrieztos"</string>
- <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"Lai atgrieztos iepriekšējā ekrānā, velciet no kreisās vai labās malas uz ekrāna vidu."</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Jāvelk augšup no ekrāna apakšmalas."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Pirms atlaišanas nepārtrauciet kustību."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Jāvelk tieši uz augšu."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"Jūs sekmīgi veicāt sākuma ekrāna atvēršanas žestu. Tagad varat iemācīties, kā pāriet atpakaļ."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"Jūs sekmīgi veicāt sākuma ekrāna atvēršanas žestu."</string>
- <string name="home_gesture_intro_title" msgid="836590312858441830">"Vilkšana, lai pārietu uz sākumu"</string>
- <string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Velciet augšup no ekrāna apakšdaļas. Ar šo žestu vienmēr varat atvērt sākuma ekrānu."</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Jāvelk augšup no ekrāna apakšmalas."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Mēģiniet ilgāk turēt logu, pirms atlaižat."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Jāvelk tieši uz augšu un pēc tam jāaptur kustība."</string>
- <string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Jūs esat apguvis žestu izmantošanu. Lai izslēgtu žestus, pārejiet uz sadaļu Iestatījumi."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"Jūs sekmīgi veicāt lietotņu pārslēgšanas žestu."</string>
- <string name="overview_gesture_intro_title" msgid="2902054412868489378">"Vilkšana, lai pārslēgtu lietotnes"</string>
- <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Lai pārslēgtu lietotnes, velciet augšup no ekrāna apakšdaļas, turiet un pēc tam atlaidiet."</string>
- <string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"Gatavs"</string>
- <string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Gatavs"</string>
- <string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Iestatījumi"</string>
- <string name="gesture_tutorial_try_again" msgid="65962545858556697">"Mēģināt vēlreiz"</string>
- <string name="gesture_tutorial_nice" msgid="2936275692616928280">"Lieliski!"</string>
- <string name="gesture_tutorial_step" msgid="1279786122817620968">"<xliff:g id="CURRENT">%1$d</xliff:g>. mācību darbība no <xliff:g id="TOTAL">%2$d</xliff:g>"</string>
- <string name="allset_title" msgid="5021126669778966707">"Gatavs!"</string>
- <string name="allset_hint" msgid="2384632994739392447">"Velciet augšup, lai pārietu uz sākuma ekrānu."</string>
- <string name="allset_description" msgid="6350320429953234580">"Varat sākt izmantot savu tālruni"</string>
- <string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"Sistēmas navigācijas iestatījumi"</annotation></string>
- <string name="action_share" msgid="2648470652637092375">"Kopīgot"</string>
- <string name="action_screenshot" msgid="8171125848358142917">"Veikt ekrānuzņēmumu"</string>
- <string name="action_split" msgid="2098009717623550676">"Sadalīt"</string>
- <string name="toast_split_select_app" msgid="5453865907322018352">"Piesk. citai lietotnei, lai izm. ekrāna sadalīšanu"</string>
- <string name="toast_split_app_unsupported" msgid="3271526028981899666">"Lietotnē netiek atbalstīta ekrāna sadalīšana."</string>
- <string name="blocked_by_policy" msgid="2071401072261365546">"Lietotne vai jūsu organizācija neatļauj veikt šo darbību."</string>
- <string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Vai izlaist navigācijas mācības?"</string>
- <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Varēsiet to vēlāk atrast lietotnē <xliff:g id="NAME">%1$s</xliff:g>."</string>
- <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Atcelt"</string>
- <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Izlaist"</string>
- <string name="accessibility_rotate_button" msgid="4771825231336502943">"Pagriezt ekrānu"</string>
- <string name="taskbar_edu_opened" msgid="3950252793551919129">"Tika atvērta uzdevumjoslas apmācība"</string>
- <string name="taskbar_edu_closed" msgid="126643734478892862">"Tika aizvērta uzdevumjoslas apmācība"</string>
- <string name="taskbar_edu_switch_apps" msgid="6942863327845784813">"Izmantojiet uzdevumjoslu, lai pārslēgtu lietotnes."</string>
- <string name="taskbar_edu_splitscreen" msgid="2663361731630346489">"Velciet uz malu, lai izmantotu divas lietotnes vienlaikus."</string>
- <string name="taskbar_edu_stashing" msgid="5212374387411764031">"Pieskarieties un turiet, lai paslēptu uzdevumjoslu."</string>
- <string name="taskbar_edu_next" msgid="4007618274426775841">"Tālāk"</string>
- <string name="taskbar_edu_previous" msgid="459202320127201702">"Atpakaļ"</string>
- <string name="taskbar_edu_close" msgid="887022990168191073">"Aizvērt"</string>
- <string name="taskbar_edu_done" msgid="6880178093977704569">"Gatavs"</string>
- <string name="taskbar_button_home" msgid="2151398979630664652">"Sākums"</string>
- <string name="taskbar_button_a11y" msgid="5241161324875094465">"Pieejamība"</string>
- <string name="taskbar_button_back" msgid="8558862226461164514">"Atpakaļ"</string>
- <string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"IME pārslēdzējs"</string>
- <string name="taskbar_button_recents" msgid="7273376136216613134">"Nesenie"</string>
- <!-- no translation found for taskbar_button_notifications (7471740351507357318) -->
- <skip />
- <!-- no translation found for taskbar_button_quick_settings (227662894293189391) -->
- <skip />
- <string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Pārvietot uz augšējo/kreiso stūri"</string>
- <string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Pārvietot uz apakšējo/labo stūri"</string>
</resources>
diff --git a/quickstep/res/values-mk/strings.xml b/quickstep/res/values-mk/strings.xml
index dc0732f24c..9f11521df3 100644
--- a/quickstep/res/values-mk/strings.xml
+++ b/quickstep/res/values-mk/strings.xml
@@ -19,91 +19,19 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="recent_task_option_pin" msgid="7929860679018978258">"Закачи"</string>
+ <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Поделен екран"</string>
+ <string name="recent_task_option_pin" msgid="7929860679018978258">"Прикачување"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Freeform"</string>
+ <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Преглед"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"Нема неодамнешни ставки"</string>
+ <string name="accessibility_close_task" msgid="5354563209433803643">"Затвори"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Поставки за користење на апликациите"</string>
- <string name="recents_clear_all" msgid="5328176793634888831">"Избриши ги сите"</string>
+ <string name="recents_clear_all" msgid="5328176793634888831">"Исчисти ги сите"</string>
<string name="accessibility_recent_apps" msgid="4058661986695117371">"Неодамнешни апликации"</string>
- <string name="task_view_closed" msgid="9170038230110856166">"Задачата е затворена"</string>
<string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
<string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 минута"</string>
<string name="time_left_for_app" msgid="3111996412933644358">"Уште <xliff:g id="TIME">%1$s</xliff:g> за денес"</string>
<string name="title_app_suggestions" msgid="4185902664111965088">"Предлози за апликации"</string>
+ <string name="all_apps_label" msgid="8542784161730910663">"Сите апликации"</string>
<string name="all_apps_prediction_tip" msgid="2672336544844936186">"Вашите предвидени апликации"</string>
- <string name="hotseat_edu_title_migrate" msgid="306578144424489980">"Добивајте предлози за апликации на долниот ред од почетниот екран"</string>
- <string name="hotseat_edu_title_migrate_landscape" msgid="3633942953997845243">"Добивајте предлози за апликации во редот со омилени на почетниот екран"</string>
- <string name="hotseat_edu_message_migrate" msgid="8927179260533775320">"Лесно пристапувајте до најкористените апликации директно на почетниот екран. Предлозите ќе се менуваат според рутините. Апликациите од последниот ред ќе се поместуваат нагоре до почетниот екран."</string>
- <string name="hotseat_edu_message_migrate_landscape" msgid="4248943380443387697">"Лесно пристапувајте до најкористените апликации на почетниот екран. Предлозите ќе се менуваат според рутините. Апликациите од редот со омилени ќе се преместат на почетниот екран."</string>
- <string name="hotseat_edu_message_migrate_alt" msgid="3042360119039646356">"Лесно пристапувајте до најкористените апликации директно на почетниот екран. Предлозите ќе се менуваат според рутините. Апликациите од последниот ред ќе се преместуваат во нова папка."</string>
- <string name="hotseat_edu_accept" msgid="1611544083278999837">"Добивајте предлози за апликации"</string>
- <string name="hotseat_edu_dismiss" msgid="2781161822780201689">"Не, фала"</string>
- <string name="hotseat_prediction_settings" msgid="6246554993566070818">"Поставки"</string>
- <string name="hotseat_auto_enrolled" msgid="522100018967146807">"Најкористените апликации се појавуваат тука и се менуваат според рутините"</string>
- <string name="hotseat_tip_no_empty_slots" msgid="1325212677738179185">"Отстранете апликации од долниот ред со повлекување за да добивате предлози за апликации"</string>
- <string name="hotseat_tip_gaps_filled" msgid="3035673010274223538">"Предлозите за апликации се додадени во празен простор"</string>
- <string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Предлозите за апликации се овозможени"</string>
- <string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Предлозите за апликации се оневозможени"</string>
- <string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Предвидена апликација: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Повлечете од крајниот десен или крајниот лев раб."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Повлечете од десниот или левиот раб кон средината на екранот и пуштете."</string>
- <string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Научивте како да повлекувате оддесно за да одите назад. Следно, дознајте како да се префрлате помеѓу апликации."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"Завршивте со упатството за враќање назад."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Не повлекувајте преблиску до долниот раб на екранот."</string>
- <string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"За да ја промените чувствителноста, одете во „Поставки“"</string>
- <string name="back_gesture_intro_title" msgid="19551256430224428">"Повлечете за да се вратите назад"</string>
- <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"За да се вратите на последниот екран, повлечете од левиот или десниот раб кон средината на екранот."</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Повлечете нагоре од долниот раб на екранот."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Не правете пауза пред да пуштите."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Повлечете право нагоре."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"Завршивте со упатството за почетната страница. Следно, дознајте како да се вратите назад."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"Завршивте со упатството за почетната страница."</string>
- <string name="home_gesture_intro_title" msgid="836590312858441830">"Повлечете за да одите на почетната страница"</string>
- <string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Повлечете нагоре од долниот раб на екранот. Ова движење секогаш ќе ве одведе на почетниот екран."</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Повлечете нагоре од долниот раб на екранот."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Задржете го прозорецот подолго пред да го пуштите."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Повлечете право нагоре, а потоа застанете."</string>
- <string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Дознавте како се користат движењата. За да ги исклучите движењата, одете во „Поставки“."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"Завршивте со упатството за префрлање помеѓу апликации."</string>
- <string name="overview_gesture_intro_title" msgid="2902054412868489378">"Повлечете за префрлање помеѓу апликации"</string>
- <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"За да смените апликација, повлечете нагоре од дното на екранот и задржете, па пуштете."</string>
- <string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"Готово"</string>
- <string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Готово"</string>
- <string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Поставки"</string>
- <string name="gesture_tutorial_try_again" msgid="65962545858556697">"Обиди се пак"</string>
- <string name="gesture_tutorial_nice" msgid="2936275692616928280">"Одлично!"</string>
- <string name="gesture_tutorial_step" msgid="1279786122817620968">"Упатство <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
- <string name="allset_title" msgid="5021126669778966707">"Готово!"</string>
- <string name="allset_hint" msgid="2384632994739392447">"Повлечете нагоре за да појдете на почетниот екран"</string>
- <string name="allset_description" msgid="6350320429953234580">"Спремни сте да почнете да го користите телефонот"</string>
- <string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"Поставки за системска навигација"</annotation></string>
- <string name="action_share" msgid="2648470652637092375">"Сподели"</string>
- <string name="action_screenshot" msgid="8171125848358142917">"Слика од екранот"</string>
- <string name="action_split" msgid="2098009717623550676">"Раздели"</string>
- <string name="toast_split_select_app" msgid="5453865907322018352">"Допрете друга апликација за да користите поделен екран"</string>
- <string name="toast_split_app_unsupported" msgid="3271526028981899666">"Апликацијата не поддржува поделен екран."</string>
- <string name="blocked_by_policy" msgid="2071401072261365546">"Апликацијата или вашата организација не го дозволува дејствово"</string>
- <string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Да се прескокне упатството за навигација?"</string>
- <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Ова може да го најдете подоцна во апликацијата <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Откажи"</string>
- <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Прескокни"</string>
- <string name="accessibility_rotate_button" msgid="4771825231336502943">"Ротирајте го екранот"</string>
- <string name="taskbar_edu_opened" msgid="3950252793551919129">"Се појави лентата за задачи за образование"</string>
- <string name="taskbar_edu_closed" msgid="126643734478892862">"Затворена е лентата за задачи за образование"</string>
- <string name="taskbar_edu_switch_apps" msgid="6942863327845784813">"Префрлувајте се меѓу апликации преку лентата за задачи"</string>
- <string name="taskbar_edu_splitscreen" msgid="2663361731630346489">"Повлечете кон страната за да користите две апликации одеднаш"</string>
- <string name="taskbar_edu_stashing" msgid="5212374387411764031">"Допрете и задржете за да се сокрие лентата за задачи"</string>
- <string name="taskbar_edu_next" msgid="4007618274426775841">"Следна"</string>
- <string name="taskbar_edu_previous" msgid="459202320127201702">"Назад"</string>
- <string name="taskbar_edu_close" msgid="887022990168191073">"Затвори"</string>
- <string name="taskbar_edu_done" msgid="6880178093977704569">"Готово"</string>
- <string name="taskbar_button_home" msgid="2151398979630664652">"Дома"</string>
- <string name="taskbar_button_a11y" msgid="5241161324875094465">"Пристапност"</string>
- <string name="taskbar_button_back" msgid="8558862226461164514">"Назад"</string>
- <string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"IME менувач"</string>
- <string name="taskbar_button_recents" msgid="7273376136216613134">"Неодамнешни"</string>
- <string name="taskbar_button_notifications" msgid="7471740351507357318">"Известувања"</string>
- <string name="taskbar_button_quick_settings" msgid="227662894293189391">"Брзи поставки"</string>
- <string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Премести горе лево"</string>
- <string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Премести долу десно"</string>
</resources>
diff --git a/quickstep/res/values-ml/strings.xml b/quickstep/res/values-ml/strings.xml
index 4ac251c97d..2e02e80fa8 100644
--- a/quickstep/res/values-ml/strings.xml
+++ b/quickstep/res/values-ml/strings.xml
@@ -19,91 +19,19 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="recent_task_option_split_screen" msgid="5353188922202653570">"സ്‌ക്രീൻ വിഭജിക്കുക"</string>
<string name="recent_task_option_pin" msgid="7929860679018978258">"പിൻ ചെയ്യുക"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"ഫ്രീഫോം"</string>
+ <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"അവലോകനം"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"സമീപകാല ഇനങ്ങൾ ഒന്നുമില്ല"</string>
+ <string name="accessibility_close_task" msgid="5354563209433803643">"അവസാനിപ്പിക്കുക"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"ആപ്പ് ഉപയോഗ ക്രമീകരണം"</string>
<string name="recents_clear_all" msgid="5328176793634888831">"എല്ലാം മായ്‌ക്കുക"</string>
<string name="accessibility_recent_apps" msgid="4058661986695117371">"സമീപകാല ആപ്പുകൾ"</string>
- <string name="task_view_closed" msgid="9170038230110856166">"ടാസ്ക്ക് അടച്ചു"</string>
<string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
<string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 മിനിറ്റ്"</string>
<string name="time_left_for_app" msgid="3111996412933644358">"ഇന്ന് <xliff:g id="TIME">%1$s</xliff:g> ശേഷിക്കുന്നു"</string>
<string name="title_app_suggestions" msgid="4185902664111965088">"ആപ്പ് നിർദ്ദേശങ്ങൾ"</string>
+ <string name="all_apps_label" msgid="8542784161730910663">"എല്ലാ ആപ്പുകളും"</string>
<string name="all_apps_prediction_tip" msgid="2672336544844936186">"നിങ്ങളുടെ പ്രവചിക്കപ്പെട്ട ആപ്പുകൾ"</string>
- <string name="hotseat_edu_title_migrate" msgid="306578144424489980">"നിങ്ങളുടെ ഹോം സ്‌ക്രീനിന്റെ താഴത്തെ നിരയിൽ ആപ്പ് നിർദ്ദേശങ്ങൾ നേടുക"</string>
- <string name="hotseat_edu_title_migrate_landscape" msgid="3633942953997845243">"നിങ്ങളുടെ ഹോം സ്‌ക്രീനിന്റെ \'പ്രിയപ്പെട്ടവ\' വരിയിൽ ആപ്പ് നിർദ്ദേശങ്ങൾ നേടുക"</string>
- <string name="hotseat_edu_message_migrate" msgid="8927179260533775320">"നിങ്ങൾ ഏറ്റവും കൂടുതൽ ഉപയോഗിച്ച ആപ്പുകൾ ഹോം സ്ക്രീനിൽ നിന്ന് തന്നെ എളുപ്പത്തിൽ ആക്‌സസ് ചെയ്യൂ. നിങ്ങളുടെ ദിനചര്യകളുടെ അടിസ്ഥാനത്തിൽ നിർദ്ദേശങ്ങൾ മാറും. താഴത്തെ നിരയിലുള്ള ആപ്പുകൾ നിങ്ങളുടെ ഹോം സ്‌ക്രീനിലേക്ക് നീങ്ങും."</string>
- <string name="hotseat_edu_message_migrate_landscape" msgid="4248943380443387697">"നിങ്ങൾ ഏറ്റവും കൂടുതൽ ഉപയോഗിച്ച ആപ്പുകൾ ഹോം സ്ക്രീനിൽ നിന്ന് തന്നെ എളുപ്പത്തിൽ ആക്‌സസ് ചെയ്യൂ. നിങ്ങളുടെ ദിനചര്യകളുടെ അടിസ്ഥാനത്തിൽ നിർദ്ദേശങ്ങൾ മാറും. \'പ്രിയപ്പെട്ടവ\' വരിയിലുള്ള ആപ്പുകൾ നിങ്ങളുടെ ഹോം സ്‌ക്രീനിലേക്ക് നീങ്ങും."</string>
- <string name="hotseat_edu_message_migrate_alt" msgid="3042360119039646356">"നിങ്ങൾ ഏറ്റവും കൂടുതൽ ഉപയോഗിച്ച ആപ്പുകൾ ഹോം സ്ക്രീനിൽ നിന്ന് തന്നെ എളുപ്പത്തിൽ ആക്‌സസ് ചെയ്യൂ. നിങ്ങളുടെ ദിനചര്യകളുടെ അടിസ്ഥാനത്തിൽ നിർദ്ദേശങ്ങൾ മാറും. താഴത്തെ നിരയിലുള്ള ആപ്പുകൾ പുതിയൊരു ഫോൾഡറിലേക്ക് നീങ്ങും."</string>
- <string name="hotseat_edu_accept" msgid="1611544083278999837">"ആപ്പ് നിർദ്ദേശങ്ങൾ നേടുക"</string>
- <string name="hotseat_edu_dismiss" msgid="2781161822780201689">"വേണ്ട"</string>
- <string name="hotseat_prediction_settings" msgid="6246554993566070818">"ക്രമീകരണം"</string>
- <string name="hotseat_auto_enrolled" msgid="522100018967146807">"ഏറ്റവുമധികം ഉപയോഗിക്കുന്ന ആപ്പുകൾ ഇവിടെ ദൃശ്യമാകും, ദിനചര്യയ്ക്ക് അനുസരിച്ച് അത് മാറുകയും ചെയ്യും"</string>
- <string name="hotseat_tip_no_empty_slots" msgid="1325212677738179185">"ആപ്പ് നിർദ്ദേശങ്ങൾ നേടാൻ താഴത്തെ നിരയിലെ ആപ്പുകൾ വലിച്ചിടുക"</string>
- <string name="hotseat_tip_gaps_filled" msgid="3035673010274223538">"ആപ്പ് നിർദ്ദേശങ്ങൾ ഒഴിഞ്ഞ സ്ഥലത്തേക്ക് ചേർത്തു"</string>
- <string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"ആപ്പ് നിർദ്ദേശങ്ങൾ പ്രവർത്തനക്ഷമമാക്കി"</string>
- <string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"ആപ്പ് നിർദ്ദേശങ്ങൾ പ്രവർത്തനരഹിതമാക്കി"</string>
- <string name="hotseat_prediction_content_description" msgid="4582028296938078419">"പ്രവചിച്ച ആപ്പ്: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"വലത്തേയറ്റത്തെയോ ഇടത്തേയറ്റത്തെയോ അരികിൽ നിന്ന് സ്വെെപ്പ് ചെയ്യുന്നുണ്ടെന്ന് ഉറപ്പാക്കുക."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"വലതോ ഇടതോ അരികിൽ നിന്ന് സ്‌ക്രീനിന്റെ മധ്യഭാഗത്തേക്ക് സ്വെെപ്പ് ചെയ്‌ത് വിടുക."</string>
- <string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"മടങ്ങാൻ വലതുഭാഗത്ത് നിന്ന് സ്വൈപ്പ് ചെയ്യുന്ന രീതി മനസ്സിലായി. ഇനി, ആപ്പുകൾ മാറുന്ന രീതി അറിയുക."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"മടങ്ങുക ജെസ്ച്ചർ നിങ്ങൾ പൂർത്തിയാക്കി."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"സ്‌ക്രീനിന്റെ ഏറ്റവും അടിഭാഗത്തേക്ക് സ്വെെപ്പ് ചെയ്യുന്നില്ലെന്ന് ഉറപ്പാക്കുക."</string>
- <string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"ബാക്ക്ജെസ്റ്ററിന്റെ സെൻസിറ്റിവിറ്റി മാറ്റാൻ ക്രമീകരണത്തിൽ പോകൂ"</string>
- <string name="back_gesture_intro_title" msgid="19551256430224428">"മടങ്ങാൻ സ്വെെപ്പ് ചെയ്യുക"</string>
- <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"മുൻ സ്‌ക്രീനിലേക്ക് മടങ്ങാൻ, ഇടതോ വലതോ അരികിൽ നിന്ന് സ്‌ക്രീനിന്റെ നടുവിലേക്ക് സ്വെെപ്പ് ചെയ്യുക."</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"സ്‌ക്രീനിന്റെ താഴത്തെ അരികിൽ നിന്ന് മുകളിലേക്ക് സ്വെെപ്പ് ചെയ്യുന്നുണ്ടെന്ന് ഉറപ്പാക്കുക."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"വിടുന്നതിന് മുമ്പ് നിങ്ങൾ താൽക്കാലികമായി നിർത്തുന്നില്ലെന്ന് ഉറപ്പാക്കുക."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"നേരെ മുകളിലേക്ക് സ്വെെപ്പ് ചെയ്യുന്നുണ്ടെന്ന് ഉറപ്പിക്കുക."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"ഹോമിലേക്ക് പോകുക ജെസ്ച്ചർ പൂർത്തിയാക്കി. അടുത്തത്, എങ്ങനെ മടങ്ങാമെന്ന് അറിയുക."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"ഹോമിലേക്ക് പോകുക ജെസ്ച്ചർ നിങ്ങൾ പൂർത്തിയാക്കി."</string>
- <string name="home_gesture_intro_title" msgid="836590312858441830">"ഹോമിലേക്ക് പോകാൻ സ്വെെപ്പ് ചെയ്യുക"</string>
- <string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"സ്‌ക്രീനിന്റെ താഴെ നിന്ന് മുകളിലേക്ക് സ്വൈപ്പ് ചെയ്യൂ. ഈ ജെസ്ച്ചർ എപ്പോഴും ഹോം സ്‌ക്രീനിലേക്ക് നയിക്കുന്നു."</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"സ്‌ക്രീനിന്റെ താഴത്തെ അരികിൽ നിന്ന് മുകളിലേക്ക് സ്വെെപ്പ് ചെയ്യുന്നുണ്ടെന്ന് ഉറപ്പാക്കുക."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"റിലീസ് ചെയ്യുന്നതിന് മുമ്പ് വിൻഡോ കൂടുതൽ സമയം ഹോൾഡ് ചെയ്യാൻ ശ്രമിക്കുക."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"നേരെ മുകളിലേക്ക് സ്വെെപ്പ് ചെയ്യുന്നുണ്ടെന്ന് ഉറപ്പാക്കുക, ശേഷം താൽക്കാലികമായി നിർത്തുക."</string>
- <string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"ജെസ്ച്ചറുകൾ ഉപയോഗിക്കുന്ന രീതി നിങ്ങൾ മനസ്സിലാക്കി. ജെസ്ച്ചറുകൾ ഓഫാക്കാൻ ക്രമീകരണത്തിലേക്ക് പോകുക."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"ആപ്പുകൾ തമ്മിൽ മാറുക ജെസ്‌ച്ചർ നിങ്ങൾ പൂർത്തിയാക്കി."</string>
- <string name="overview_gesture_intro_title" msgid="2902054412868489378">"ആപ്പുകൾ മാറാൻ സ്വെെപ്പ് ചെയ്യുക"</string>
- <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"ആപ്പുകൾക്കിടയിൽ മാറാൻ സ്‌ക്രീനിന്റെ താഴെ നിന്ന് മുകളിലേക്ക് സ്വൈപ്പ് ചെയ്‌ത് പിടിച്ച ശേഷം വിടുക."</string>
- <string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"എല്ലാം സജ്ജീകരിച്ചു"</string>
- <string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"പൂർത്തിയായി"</string>
- <string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"ക്രമീകരണം"</string>
- <string name="gesture_tutorial_try_again" msgid="65962545858556697">"വീണ്ടും ശ്രമിക്കുക"</string>
- <string name="gesture_tutorial_nice" msgid="2936275692616928280">"കൊള്ളാം!"</string>
- <string name="gesture_tutorial_step" msgid="1279786122817620968">"ട്യൂട്ടോറിയൽ <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
- <string name="allset_title" msgid="5021126669778966707">"എല്ലാം സജ്ജീകരിച്ചു!"</string>
- <string name="allset_hint" msgid="2384632994739392447">"ഹോമിലേക്ക് പോകാൻ മുകളിലേക്ക് സ്വൈപ്പ് ചെയ്യുക"</string>
- <string name="allset_description" msgid="6350320429953234580">"ഫോൺ ഉപയോഗിച്ച് തുടങ്ങാൻ നിങ്ങൾ തയ്യാറാണ്"</string>
- <string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"സിസ്‌റ്റം നാവിഗേഷൻ ക്രമീകരണം"</annotation></string>
- <string name="action_share" msgid="2648470652637092375">"പങ്കിടുക"</string>
- <string name="action_screenshot" msgid="8171125848358142917">"സ്ക്രീൻഷോട്ട്"</string>
- <string name="action_split" msgid="2098009717623550676">"വിഭജിക്കുക"</string>
- <string name="toast_split_select_app" msgid="5453865907322018352">"സ്പ്ലിറ്റ് സ്ക്രീനിനായി മറ്റൊരു ആപ്പ് ടാപ്പുചെയ്യൂ"</string>
- <string name="toast_split_app_unsupported" msgid="3271526028981899666">"സ്പ്ലിറ്റ്-സ്ക്രീനിനെ ആപ്പ് പിന്തുണയ്ക്കുന്നില്ല."</string>
- <string name="blocked_by_policy" msgid="2071401072261365546">"ഈ നടപടി എടുക്കുന്നത് ആപ്പോ നിങ്ങളുടെ സ്ഥാപനമോ അനുവദിക്കുന്നില്ല"</string>
- <string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"നാവിഗേഷൻ ട്യൂട്ടോറിയൽ ഒഴിവാക്കണോ?"</string>
- <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"<xliff:g id="NAME">%1$s</xliff:g> ആപ്പിൽ നിങ്ങൾക്ക് ഇത് പിന്നീട് കാണാനാകും"</string>
- <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"റദ്ദാക്കുക"</string>
- <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"ഒഴിവാക്കുക"</string>
- <string name="accessibility_rotate_button" msgid="4771825231336502943">"സ്‌ക്രീൻ റൊട്ടേറ്റ് ചെയ്യുക"</string>
- <string name="taskbar_edu_opened" msgid="3950252793551919129">"ടാസ്ക്ക്ബാർ വിവര പാനൽ ദൃശ്യമായി"</string>
- <string name="taskbar_edu_closed" msgid="126643734478892862">"ടാസ്ക്ക്ബാർ വിവര പാനൽ അടച്ചു"</string>
- <string name="taskbar_edu_switch_apps" msgid="6942863327845784813">"ആപ്പുകൾ മാറാൻ ടാസ്ക്ക്ബാർ ഉപയോഗിക്കുക"</string>
- <string name="taskbar_edu_splitscreen" msgid="2663361731630346489">"രണ്ട് ആപ്പുകൾ ഒരുമിച്ച് ഉപയോഗിക്കാൻ അരികിലേക്ക് വലിച്ചിടുക"</string>
- <string name="taskbar_edu_stashing" msgid="5212374387411764031">"ടാസ്ക്ക്ബാർ മറയ്ക്കാൻ സ്‌പർശിച്ച് പിടിക്കുക"</string>
- <string name="taskbar_edu_next" msgid="4007618274426775841">"അടുത്തത്"</string>
- <string name="taskbar_edu_previous" msgid="459202320127201702">"മടങ്ങുക"</string>
- <string name="taskbar_edu_close" msgid="887022990168191073">"അടയ്ക്കുക"</string>
- <string name="taskbar_edu_done" msgid="6880178093977704569">"പൂർത്തിയായി"</string>
- <string name="taskbar_button_home" msgid="2151398979630664652">"ഹോം"</string>
- <string name="taskbar_button_a11y" msgid="5241161324875094465">"ഉപയോഗസഹായി"</string>
- <string name="taskbar_button_back" msgid="8558862226461164514">"മടങ്ങുക"</string>
- <string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"IME സ്വിച്ചർ"</string>
- <string name="taskbar_button_recents" msgid="7273376136216613134">"അടുത്തിടെയുള്ളവ"</string>
- <string name="taskbar_button_notifications" msgid="7471740351507357318">"അറിയിപ്പുകൾ"</string>
- <string name="taskbar_button_quick_settings" msgid="227662894293189391">"ദ്രുത ക്രമീകരണം"</string>
- <string name="move_drop_target_top_or_left" msgid="2988702185049595807">"മുകളിലേക്കോ ഇടത്തേക്കോ നീക്കുക"</string>
- <string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"താഴേക്കോ വലത്തേക്കോ നീക്കുക"</string>
</resources>
diff --git a/quickstep/res/values-mn/strings.xml b/quickstep/res/values-mn/strings.xml
index 6d918f6eef..5de8602022 100644
--- a/quickstep/res/values-mn/strings.xml
+++ b/quickstep/res/values-mn/strings.xml
@@ -19,91 +19,19 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="recent_task_option_pin" msgid="7929860679018978258">"Бэхлэх"</string>
+ <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Дэлгэцийг хуваах"</string>
+ <string name="recent_task_option_pin" msgid="7929860679018978258">"Тогтоох"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Чөлөөтэй хувьсах"</string>
+ <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Тойм"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"Сүүлийн үеийн зүйл алга"</string>
+ <string name="accessibility_close_task" msgid="5354563209433803643">"Хаах"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Апп ашиглалтын тохиргоо"</string>
<string name="recents_clear_all" msgid="5328176793634888831">"Бүгдийг устгах"</string>
<string name="accessibility_recent_apps" msgid="4058661986695117371">"Саяхны аппууд"</string>
- <string name="task_view_closed" msgid="9170038230110856166">"Ажлыг хаасан"</string>
<string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
<string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 минут"</string>
<string name="time_left_for_app" msgid="3111996412933644358">"Өнөөдөр <xliff:g id="TIME">%1$s</xliff:g> үлдсэн"</string>
- <string name="title_app_suggestions" msgid="4185902664111965088">"Санал болгож буй аппууд"</string>
+ <string name="title_app_suggestions" msgid="4185902664111965088">"Аппын зөвлөмж"</string>
+ <string name="all_apps_label" msgid="8542784161730910663">"Бүх апп"</string>
<string name="all_apps_prediction_tip" msgid="2672336544844936186">"Таны таамагласан аппууд"</string>
- <string name="hotseat_edu_title_migrate" msgid="306578144424489980">"Үндсэн нүүрнийхээ доод мөрд санал болгож буй аппуудыг аваарай"</string>
- <string name="hotseat_edu_title_migrate_landscape" msgid="3633942953997845243">"Үндсэн нүүрний дуртай мөрнөөсөө санал болгож буй аппуудыг аваарай"</string>
- <string name="hotseat_edu_message_migrate" msgid="8927179260533775320">"Хамгийн их ашигладаг аппууддаа Үндсэн нүүрнээс хялбархан хандаарай. Санал болгож буй аппуудыг таны хэвшлээс хамаарч өөрчилнө. Доод мөрд буй аппуудыг таны Үндсэн нүүр лүү дээш зөөнө."</string>
- <string name="hotseat_edu_message_migrate_landscape" msgid="4248943380443387697">"Хамгийн их ашигладаг аппууддаа Үндсэн нүүрнээсээ хялбархан хандаарай. Санал болголтыг таны хэвшлээс хамааран өөрчилнө. Дуртай мөрөнд буй аппуудыг таны үндсэн нүүр лүү зөөнө."</string>
- <string name="hotseat_edu_message_migrate_alt" msgid="3042360119039646356">"Хамгийн их ашигладаг аппууддаа Үндсэн нүүрнээс хялбархан хандаарай. Санал болгож буй аппуудыг таны хэвшлээс хамаарч өөрчилнө. Доод мөрөнд буй аппуудыг шинэ фолдер луу зөөнө."</string>
- <string name="hotseat_edu_accept" msgid="1611544083278999837">"Санал болгож буй аппуудыг авах"</string>
- <string name="hotseat_edu_dismiss" msgid="2781161822780201689">"Үгүй, баярлалаа"</string>
- <string name="hotseat_prediction_settings" msgid="6246554993566070818">"Тохиргоо"</string>
- <string name="hotseat_auto_enrolled" msgid="522100018967146807">"Хамгийн их ашигладаг аппуудыг энд харуулах бөгөөд хэвшлээс хамаарч өөрчилдөг"</string>
- <string name="hotseat_tip_no_empty_slots" msgid="1325212677738179185">"Санал болгож буй аппуудыг авахын тулд доод мөрөөс аппуудыг чирж гаргаарай"</string>
- <string name="hotseat_tip_gaps_filled" msgid="3035673010274223538">"Санал болгож буй аппуудыг хоосон зайд нэмсэн"</string>
- <string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Санал болгож буй аппуудыг идэвхжүүлсэн"</string>
- <string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Санал болгож буй аппуудыг идэвхгүй болгосон"</string>
- <string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Таамаглаж буй апп: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Та баруун зах эсвэл зүүн захын булангаас шударна уу."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Та баруун эсвэл зүүн булангаас дэлгэцийн дунд хэсэг хүртэл шударч, суллана уу."</string>
- <string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Та буцахын тулд баруунаас хэрхэн шудрахыг мэдэж авлаа. Дараа нь аппууд хооронд хэрхэн сэлгэхийг мэдэж аваарай."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"Та буцах зангааг гүйцэтгэлээ."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Та дэлгэцийн доод хэсэгтэй хэт ойр бүү шудраарай."</string>
- <string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"Буцах зангааны мэдрэгшлийг өөрчлөх бол Тохиргоо руу очно уу"</string>
- <string name="back_gesture_intro_title" msgid="19551256430224428">"Буцахын тулд шудрах"</string>
- <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"Сүүлийн дэлгэц рүү буцахын тулд дэлгэцийн зүүн эсвэл баруун булангаас дунд хэсэг рүү шударна уу."</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Та дэлгэцийн доод булангаас дээш шударна уу."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Та суллахаасаа өмнө түр зогсоож болохгүй."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Та чигээрээ шударна уу."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"Та Нүүр лүү очих зангааг гүйцэтгэлээ. Дараа нь хэрхэн буцахыг мэдэж авна уу."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"Та Нүүр лүү очих зангааг гүйцэтгэлээ."</string>
- <string name="home_gesture_intro_title" msgid="836590312858441830">"Нүүр лүү очихын тулд шудрах"</string>
- <string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Дэлгэцийнхээ доороос дээш шударна уу. Энэ зангаа таныг тогтмол Үндсэн нүүрэнд аваачна."</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Та дэлгэцийн доод булангаас дээш шударна уу."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Суллахаасаа өмнө цонхыг илүү удаан дарж үзнэ үү."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Та чигээрээ шударч, дараа нь түр зогсооно уу."</string>
- <string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Та зангааг хэрхэн ашиглахыг мэдэж авлаа. Зангааг унтраахын тулд Тохиргоо руу очно уу."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"Та аппуудыг сэлгэх зангааг гүйцэтгэлээ."</string>
- <string name="overview_gesture_intro_title" msgid="2902054412868489378">"Аппуудыг сэлгэхийн тулд шудрах"</string>
- <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Аппуудын хооронд сэлгэхийн тулд дэлгэцийнхээ доод хэсгээс дээш шударч, удаан дараад, суллана уу."</string>
- <string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"Бүгдийг тохируулсан"</string>
- <string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Дууссан"</string>
- <string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Тохиргоо"</string>
- <string name="gesture_tutorial_try_again" msgid="65962545858556697">"Дахин оролдох"</string>
- <string name="gesture_tutorial_nice" msgid="2936275692616928280">"Янзтай!"</string>
- <string name="gesture_tutorial_step" msgid="1279786122817620968">"<xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g> практик хичээл"</string>
- <string name="allset_title" msgid="5021126669778966707">"Тохируулж дууслаа!"</string>
- <string name="allset_hint" msgid="2384632994739392447">"Нүүр хуудас руу очихын тулд дээш шударна уу"</string>
- <string name="allset_description" msgid="6350320429953234580">"Та утсаа ашиглаж эхлэхэд бэлэн боллоо"</string>
- <string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"Системийн навигацын тохиргоо"</annotation></string>
- <string name="action_share" msgid="2648470652637092375">"Хуваалцах"</string>
- <string name="action_screenshot" msgid="8171125848358142917">"Дэлгэцийн агшин дарах"</string>
- <string name="action_split" msgid="2098009717623550676">"Хуваах"</string>
- <string name="toast_split_select_app" msgid="5453865907322018352">"Дэлгэц хуваахыг ашиглах бол өөр аппыг товшино уу"</string>
- <string name="toast_split_app_unsupported" msgid="3271526028981899666">"Апп дэлгэцийг хуваах горимыг дэмждэггүй."</string>
- <string name="blocked_by_policy" msgid="2071401072261365546">"Энэ үйлдлийг апп эсвэл танай байгууллага зөвшөөрдөггүй"</string>
- <string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Навигацын практик хичээлийг алгасах уу?"</string>
- <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Та үүнийг дараа нь <xliff:g id="NAME">%1$s</xliff:g> аппаас олох боломжтой"</string>
- <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Цуцлах"</string>
- <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Алгасах"</string>
- <string name="accessibility_rotate_button" msgid="4771825231336502943">"Дэлгэцийг эргүүлэх"</string>
- <string name="taskbar_edu_opened" msgid="3950252793551919129">"Боловсролын ажлын талбар гарч ирсэн"</string>
- <string name="taskbar_edu_closed" msgid="126643734478892862">"Боловсролын ажлын талбарыг хаасан"</string>
- <string name="taskbar_edu_switch_apps" msgid="6942863327845784813">"Аппуудыг сэлгэхийн тулд талбарыг ашиглана уу"</string>
- <string name="taskbar_edu_splitscreen" msgid="2663361731630346489">"Хоёр аппыг зэрэг ашиглахын тулд хажуу тал руу чирнэ үү"</string>
- <string name="taskbar_edu_stashing" msgid="5212374387411764031">"Ажлын талбарыг нуухын тулд хүрээд удаан дарна уу"</string>
- <string name="taskbar_edu_next" msgid="4007618274426775841">"Дараах"</string>
- <string name="taskbar_edu_previous" msgid="459202320127201702">"Буцах"</string>
- <string name="taskbar_edu_close" msgid="887022990168191073">"Хаах"</string>
- <string name="taskbar_edu_done" msgid="6880178093977704569">"Дууссан"</string>
- <string name="taskbar_button_home" msgid="2151398979630664652">"Гэр"</string>
- <string name="taskbar_button_a11y" msgid="5241161324875094465">"Хандалт"</string>
- <string name="taskbar_button_back" msgid="8558862226461164514">"Буцах"</string>
- <string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"IME сэлгэгч"</string>
- <string name="taskbar_button_recents" msgid="7273376136216613134">"Саяхны"</string>
- <string name="taskbar_button_notifications" msgid="7471740351507357318">"Мэдэгдэл"</string>
- <string name="taskbar_button_quick_settings" msgid="227662894293189391">"Шуурхай тохиргоо"</string>
- <string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Зүүн дээд хэсэг рүү зөөх"</string>
- <string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Баруун доод хэсэг рүү зөөх"</string>
</resources>
diff --git a/quickstep/res/values-mr/strings.xml b/quickstep/res/values-mr/strings.xml
index aa374b4fc5..cccece749c 100644
--- a/quickstep/res/values-mr/strings.xml
+++ b/quickstep/res/values-mr/strings.xml
@@ -19,91 +19,19 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="recent_task_option_split_screen" msgid="5353188922202653570">"विभाजित स्क्रीन"</string>
<string name="recent_task_option_pin" msgid="7929860679018978258">"पिन करा"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"फ्रीफॉर्म"</string>
+ <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"अवलोकन"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"कोणतेही अलीकडील आयटम नाहीत"</string>
+ <string name="accessibility_close_task" msgid="5354563209433803643">"बंद"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"अ‍ॅप वापर सेटिंग्ज"</string>
<string name="recents_clear_all" msgid="5328176793634888831">"सर्व साफ करा"</string>
<string name="accessibility_recent_apps" msgid="4058661986695117371">"अलीकडील अ‍ॅप्स"</string>
- <string name="task_view_closed" msgid="9170038230110856166">"टास्क बंद केली"</string>
<string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
<string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"१मिहून कमी"</string>
<string name="time_left_for_app" msgid="3111996412933644358">"आज <xliff:g id="TIME">%1$s</xliff:g>शिल्लक आहे"</string>
<string name="title_app_suggestions" msgid="4185902664111965088">"अ‍ॅप सूचना"</string>
+ <string name="all_apps_label" msgid="8542784161730910663">"सर्व अ‍ॅप्स"</string>
<string name="all_apps_prediction_tip" msgid="2672336544844936186">"तुमची पूर्वानुमानीत अ‍ॅप्स"</string>
- <string name="hotseat_edu_title_migrate" msgid="306578144424489980">"तुमच्या होम स्क्रीनच्या तळाशी अ‍ॅप सूचना मिळवा"</string>
- <string name="hotseat_edu_title_migrate_landscape" msgid="3633942953997845243">"तुमच्या होम स्क्रीनच्या पसंतीच्या पंक्तीवर अ‍ॅप सूचना मिळवा"</string>
- <string name="hotseat_edu_message_migrate" msgid="8927179260533775320">"तुमची सर्वाधिक वापरली जाणारी अ‍ॅप्स होम स्क्रीनवरच सहजपणे अ‍ॅक्सेस करा. तुमच्या दिनक्रमानुसार तुम्हाला मिळणाऱ्या सूचना बदलतील. तळाशी असणारी अ‍ॅप्स तुमच्या होम स्क्रीनवर जातील."</string>
- <string name="hotseat_edu_message_migrate_landscape" msgid="4248943380443387697">"तुमची सर्वाधिक वापरली जाणारी अ‍ॅप्स होम स्क्रीनवर सहजपणे अ‍ॅक्सेस करा. सूचना तुमच्या दिनक्रमांनुसार बदलतील. पसंतीच्या पंक्तीमधील अ‍ॅप्स तुमच्या होम स्क्रीनवर हलवली जातील."</string>
- <string name="hotseat_edu_message_migrate_alt" msgid="3042360119039646356">"तुमची सर्वाधिक वापरली जाणारी अ‍ॅप्स होम स्क्रीनवरच सहजपणे अ‍ॅक्सेस करा. सूचना तुमच्या दिनक्रमांच्या आधारावर बदलतील. तळाच्या पंक्तीवरील अ‍ॅप्स नवीन फोल्डरवर जातील."</string>
- <string name="hotseat_edu_accept" msgid="1611544083278999837">"अ‍ॅप सूचना मिळवा"</string>
- <string name="hotseat_edu_dismiss" msgid="2781161822780201689">"नाही, नको"</string>
- <string name="hotseat_prediction_settings" msgid="6246554993566070818">"सेटिंग्ज"</string>
- <string name="hotseat_auto_enrolled" msgid="522100018967146807">"सर्वाधिक वापरली जाणारी अ‍ॅप्स येथे दिसतात आणि दिनक्रमांच्या आधारावर बदलतात"</string>
- <string name="hotseat_tip_no_empty_slots" msgid="1325212677738179185">"अ‍ॅप सूचना मिळवण्यासाठी तळाच्या पंक्तीवरून अ‍ॅप्स ड्रॅग करा"</string>
- <string name="hotseat_tip_gaps_filled" msgid="3035673010274223538">"रिकाम्या जागेवर जोडलेल्या अ‍ॅप सूचना"</string>
- <string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"अ‍ॅप सूचना सुरू केल्या आहेत"</string>
- <string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"अ‍ॅप सूचना बंद केल्या आहेत"</string>
- <string name="hotseat_prediction_content_description" msgid="4582028296938078419">"पूर्वानुमान केलेले अ‍ॅप: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"तुम्ही स्क्रीनच्या अगदी उजव्या किंवा अगदी डाव्या कडेला स्‍वाइप केल्याची खात्री करा."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"तुम्ही स्क्रीनच्या उजव्या किंवा डाव्या कडेपासून मध्यभागी स्‍वाइप करून सोडून दिल्याची खात्री करा."</string>
- <string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"मागे जाण्यासाठी उजवीकडून कसे स्‍वाइप करावे ते शिकलात. आता पुढे, ॲप्स कशी स्विच करायची ते जाणून घ्या."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"तुम्ही गो बॅक जेश्चर पूर्ण केले."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"तुम्ही स्क्रीनच्या तळाच्या अगदी जवळून स्‍वाइप करत नाही याची खात्री करा."</string>
- <string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"बॅक जेश्चरची संवेदनशीलता बदलण्यासाठी, सेटिंग्ज वर जा"</string>
- <string name="back_gesture_intro_title" msgid="19551256430224428">"परत जाण्यासाठी स्वाइप करा"</string>
- <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"मागील स्क्रीनवर परत जाण्यासाठी, स्क्रीनच्या डाव्या किंवा उजव्या कडेपासून मध्यावर स्‍वाइप करा."</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"तुम्ही स्क्रीनच्या तळाच्या कडेपासून वर स्वाइप करत आहात याची खात्री करा."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"तुम्ही स्क्रीनवरून बोट उचलण्यापूर्वी ते थांबवत नाही याची खात्री करा."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"तुम्ही सरळ वर स्वाइप करत आहात याची खात्री करा."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"तुम्ही गो होम जेश्चर पूर्ण केले. आता, मागे कसे जायचे ते जाणून घ्या."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"तुम्ही गो होम जेश्चर पूर्ण केले."</string>
- <string name="home_gesture_intro_title" msgid="836590312858441830">"होमवर जाण्यासाठी स्‍वाइप करा"</string>
- <string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"तुमच्या स्क्रीनच्या तळाकडून वर स्वाइप करा. हे जेश्चर तुम्हाला नेहमी होम स्क्रीनवर घेऊन जाते."</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"तुम्ही स्क्रीनच्या तळाच्या कडेपासून वर स्वाइप करत आहात याची खात्री करा."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"विंडोवरून बोट उचलण्यापूर्वी थोडा वेळ ते तेथेच धरून ठेवा."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"तुम्ही सरळ वर स्वाइप करून, त्यानंतर बोट थांबवत आहात याची खात्री करा."</string>
- <string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"तुम्ही जेश्चर कसे वापरायचे हे शिकलात. जेश्चर बंद करण्यासाठी, सेटिंग्ज वर जा."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"तुम्ही ॲप्स स्विच करण्याचे जेश्चर पूर्ण केले."</string>
- <string name="overview_gesture_intro_title" msgid="2902054412868489378">"अ‍ॅप्स स्विच करण्यासाठी स्वाइप करा"</string>
- <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"ॲप्सदरम्यान स्विच करण्यासाठी, स्क्रीनच्या तळापासून वर स्वाइप करा, धरून ठेवा, त्यानंतर सोडून द्या."</string>
- <string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"सर्व तयार आहे"</string>
- <string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"पूर्ण झाले"</string>
- <string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"सेटिंग्ज"</string>
- <string name="gesture_tutorial_try_again" msgid="65962545858556697">"पुन्हा प्रयत्न करा"</string>
- <string name="gesture_tutorial_nice" msgid="2936275692616928280">"छान!"</string>
- <string name="gesture_tutorial_step" msgid="1279786122817620968">"ट्यूटोरियल <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
- <string name="allset_title" msgid="5021126669778966707">"सर्व तयार आहे!"</string>
- <string name="allset_hint" msgid="2384632994739392447">"होम वर जाण्यासाठी वरती स्वाइप करा"</string>
- <string name="allset_description" msgid="6350320429953234580">"तुम्ही तुमचा फोन वापरण्यास सुरुवात करू शकता"</string>
- <string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"सिस्टम नेव्हिगेशन सेटिंग्ज"</annotation></string>
- <string name="action_share" msgid="2648470652637092375">"शेअर करा"</string>
- <string name="action_screenshot" msgid="8171125848358142917">"स्क्रीनशॉट"</string>
- <string name="action_split" msgid="2098009717623550676">"स्प्लिट"</string>
- <string name="toast_split_select_app" msgid="5453865907322018352">"स्प्लिटस्क्रीन वापरण्यासाठी दुसऱ्या ॲपवर टॅप करा"</string>
- <string name="toast_split_app_unsupported" msgid="3271526028981899666">"अ‍ॅप हे स्प्लिट-स्क्रीनला सपोर्ट करत नाही."</string>
- <string name="blocked_by_policy" msgid="2071401072261365546">"अ‍ॅप किंवा तुमच्या संस्थेद्वारे ही क्रिया करण्याची अनुमती नाही"</string>
- <string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"नेव्हिगेशन ट्यूटोरियल वगळायचे आहे का?"</string>
- <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"तुम्हाला हे नंतर <xliff:g id="NAME">%1$s</xliff:g> ॲपमध्ये मिळेल"</string>
- <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"रद्द करा"</string>
- <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"वगळा"</string>
- <string name="accessibility_rotate_button" msgid="4771825231336502943">"स्क्रीन फिरवा"</string>
- <string name="taskbar_edu_opened" msgid="3950252793551919129">"टास्कबारशी संबंधित माहिती देणारे पॅनल उघडले आहे"</string>
- <string name="taskbar_edu_closed" msgid="126643734478892862">"टास्कबारशी संबंधित माहिती देणारे पॅनल बंद केले आहे"</string>
- <string name="taskbar_edu_switch_apps" msgid="6942863327845784813">"ॲप्स स्विच करण्यासाठी टास्कबार वापरा"</string>
- <string name="taskbar_edu_splitscreen" msgid="2663361731630346489">"दोन ॲप्स एकत्र वापरण्यासाठी, त्यांना बाजूला नेऊन ड्रॅग करा"</string>
- <string name="taskbar_edu_stashing" msgid="5212374387411764031">"टास्कबार लपवण्यासाठी स्पर्श करा आणि धरून ठेवा"</string>
- <string name="taskbar_edu_next" msgid="4007618274426775841">"पुढे"</string>
- <string name="taskbar_edu_previous" msgid="459202320127201702">"मागे जा"</string>
- <string name="taskbar_edu_close" msgid="887022990168191073">"बंद करा"</string>
- <string name="taskbar_edu_done" msgid="6880178093977704569">"पूर्ण झाले"</string>
- <string name="taskbar_button_home" msgid="2151398979630664652">"होम"</string>
- <string name="taskbar_button_a11y" msgid="5241161324875094465">"अ‍ॅक्सेसिबिलिटी"</string>
- <string name="taskbar_button_back" msgid="8558862226461164514">"मागे जा"</string>
- <string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"IME स्विचर"</string>
- <string name="taskbar_button_recents" msgid="7273376136216613134">"अलीकडील"</string>
- <string name="taskbar_button_notifications" msgid="7471740351507357318">"सूचना"</string>
- <string name="taskbar_button_quick_settings" msgid="227662894293189391">"क्विक सेटिंग्ज"</string>
- <string name="move_drop_target_top_or_left" msgid="2988702185049595807">"सर्वात वरती/डावीकडे हलवा"</string>
- <string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"तळाशी/उजवीकडे हलवा"</string>
</resources>
diff --git a/quickstep/res/values-ms/strings.xml b/quickstep/res/values-ms/strings.xml
index 8b9165dea6..2542963769 100644
--- a/quickstep/res/values-ms/strings.xml
+++ b/quickstep/res/values-ms/strings.xml
@@ -19,91 +19,19 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Skrin pisah"</string>
<string name="recent_task_option_pin" msgid="7929860679018978258">"Semat"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Bentuk bebas"</string>
+ <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Ikhtisar"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"Tiada item terbaharu"</string>
+ <string name="accessibility_close_task" msgid="5354563209433803643">"Tutup"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Tetapan penggunaan apl"</string>
<string name="recents_clear_all" msgid="5328176793634888831">"Kosongkan semua"</string>
<string name="accessibility_recent_apps" msgid="4058661986695117371">"Apl terbaharu"</string>
- <string name="task_view_closed" msgid="9170038230110856166">"Tugas Ditutup"</string>
<string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
<string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 minit"</string>
<string name="time_left_for_app" msgid="3111996412933644358">"<xliff:g id="TIME">%1$s</xliff:g> lagi hari ini"</string>
<string name="title_app_suggestions" msgid="4185902664111965088">"Cadangan apl"</string>
+ <string name="all_apps_label" msgid="8542784161730910663">"Semua apl"</string>
<string name="all_apps_prediction_tip" msgid="2672336544844936186">"Apl ramalan anda"</string>
- <string name="hotseat_edu_title_migrate" msgid="306578144424489980">"Dapatkan cadangan apl di baris bawah Skrin utama anda"</string>
- <string name="hotseat_edu_title_migrate_landscape" msgid="3633942953997845243">"Dapatkan cadangan apl di baris kegemaran Skrin utama anda"</string>
- <string name="hotseat_edu_message_migrate" msgid="8927179260533775320">"Akses apl yang paling kerap anda gunakan dengan mudah pada Skrin utama. Cadangan akan berubah berdasarkan rutin anda. Apl di baris bawah akan beralih ke atas, ke Skrin utama anda."</string>
- <string name="hotseat_edu_message_migrate_landscape" msgid="4248943380443387697">"Akses apl yang paling kerap anda gunakan dengan mudah pada Skrin utama. Cadangan akan berubah berdasarkan rutin anda. Apl di baris kegemaran akan beralih ke Skrin utama anda."</string>
- <string name="hotseat_edu_message_migrate_alt" msgid="3042360119039646356">"Akses apl yang paling kerap anda gunakan dengan mudah, terus pada Skrin utama. Cadangan akan berubah berdasarkan rutin anda. Apl di baris bawah akan beralih ke folder baharu."</string>
- <string name="hotseat_edu_accept" msgid="1611544083278999837">"Dapatkan cadangan apl"</string>
- <string name="hotseat_edu_dismiss" msgid="2781161822780201689">"Tidak perlu"</string>
- <string name="hotseat_prediction_settings" msgid="6246554993566070818">"Tetapan"</string>
- <string name="hotseat_auto_enrolled" msgid="522100018967146807">"Apl yang paling kerap digunakan dipaparkan di sini dan berubah berdasarkan rutin"</string>
- <string name="hotseat_tip_no_empty_slots" msgid="1325212677738179185">"Seret apl keluar dari baris bawah untuk mendapatkan cadangan apl"</string>
- <string name="hotseat_tip_gaps_filled" msgid="3035673010274223538">"Cadangan apl ditambahkan pada ruang kosong"</string>
- <string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Cadangan apl didayakan"</string>
- <string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Cadangan apl dilumpuhkan"</string>
- <string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Apl yang diramalkan: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Pastikan anda meleret dari hujung sebelah kanan atau sebelah kiri."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Pastikan anda meleret dari tepi sebelah kanan atau kiri ke tengah skrin dan lepaskan."</string>
- <string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Anda belajar cara meleret dari kanan untuk kembali. Seterusnya, ketahui cara menukar apl."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"Anda telah melengkapkan gerak isyarat undur."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Pastikan anda tidak meleret terlalu dekat dengan bahagian bawah skrin."</string>
- <string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"Utk mengubah kepekaan gerak isyarat undur, pergi ke Tetapan"</string>
- <string name="back_gesture_intro_title" msgid="19551256430224428">"Leret untuk kembali"</string>
- <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"Untuk kembali ke skrin terakhir, leret dari tepi sebelah kiri atau kanan ke tengah skrin."</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Pastikan anda meleret ke atas dari tepi sebelah bawah skrin."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Pastikan anda tidak menjeda sebelum melepaskan gerak isyarat tersebut."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Pastikan anda meleret terus ke atas."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"Anda telah melengkapkan gerak isyarat pergi ke Laman Utama. Seterusnya, ketahui cara kembali."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"Anda telah melengkapkan gerak isyarat pergi ke Laman Utama."</string>
- <string name="home_gesture_intro_title" msgid="836590312858441830">"Leret untuk kembali ke laman utama"</string>
- <string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Leret ke atas dari bahagian bawah skrin. Gerak isyarat ini sentiasa membawa anda ke Skrin utama."</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Pastikan anda meleret ke atas dari tepi sebelah bawah skrin."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Cuba tahan tetingkap untuk tempoh yang lebih lama sebelum melepaskan."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Pastikan anda meleret ke atas, kemudian menjeda."</string>
- <string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Anda mempelajari cara menggunakan gerak isyarat. Untuk mematikan gerak isyarat, pergi ke Tetapan."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"Anda telah melengkapkan gerak isyarat menukar apl."</string>
- <string name="overview_gesture_intro_title" msgid="2902054412868489378">"Leret untuk menukar apl"</string>
- <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Untuk beralih antara apl, leret ke atas dari bahagian bawah skrin anda, tahan, kemudian lepaskan."</string>
- <string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"Selesai"</string>
- <string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Selesai"</string>
- <string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Tetapan"</string>
- <string name="gesture_tutorial_try_again" msgid="65962545858556697">"Cuba lagi"</string>
- <string name="gesture_tutorial_nice" msgid="2936275692616928280">"Bagus!"</string>
- <string name="gesture_tutorial_step" msgid="1279786122817620968">"Tutorial <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
- <string name="allset_title" msgid="5021126669778966707">"Siap!"</string>
- <string name="allset_hint" msgid="2384632994739392447">"Leret ke atas untuk kembali ke Laman Utama"</string>
- <string name="allset_description" msgid="6350320429953234580">"Anda sudah sedia untuk mula menggunakan telefon anda"</string>
- <string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"Tetapan navigasi sistem"</annotation></string>
- <string name="action_share" msgid="2648470652637092375">"Kongsi"</string>
- <string name="action_screenshot" msgid="8171125848358142917">"Tangkapan skrin"</string>
- <string name="action_split" msgid="2098009717623550676">"Pisah"</string>
- <string name="toast_split_select_app" msgid="5453865907322018352">"Ketik apl lain untuk menggunakan skrin pisah"</string>
- <string name="toast_split_app_unsupported" msgid="3271526028981899666">"Apl tidak menyokong skrin pisah."</string>
- <string name="blocked_by_policy" msgid="2071401072261365546">"Tindakan ini tidak dibenarkan oleh apl atau organisasi anda"</string>
- <string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Langkau tutorial navigasi?"</string>
- <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Anda boleh mendapatkan tutorial ini kemudian dalam apl <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Batal"</string>
- <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Langkau"</string>
- <string name="accessibility_rotate_button" msgid="4771825231336502943">"Putar skrin"</string>
- <string name="taskbar_edu_opened" msgid="3950252793551919129">"Pendidikan bar tugas muncul"</string>
- <string name="taskbar_edu_closed" msgid="126643734478892862">"Pendidikan bar tugas ditutup"</string>
- <string name="taskbar_edu_switch_apps" msgid="6942863327845784813">"Gunakan bar tugas untuk menukar apl"</string>
- <string name="taskbar_edu_splitscreen" msgid="2663361731630346489">"Seret ke tepi untuk menggunakan dua apl serentak"</string>
- <string name="taskbar_edu_stashing" msgid="5212374387411764031">"Sentuh &amp; tahan untuk menyembunyikan bar tugas"</string>
- <string name="taskbar_edu_next" msgid="4007618274426775841">"Seterusnya"</string>
- <string name="taskbar_edu_previous" msgid="459202320127201702">"Kembali"</string>
- <string name="taskbar_edu_close" msgid="887022990168191073">"Tutup"</string>
- <string name="taskbar_edu_done" msgid="6880178093977704569">"Selesai"</string>
- <string name="taskbar_button_home" msgid="2151398979630664652">"Laman Utama"</string>
- <string name="taskbar_button_a11y" msgid="5241161324875094465">"Kebolehaksesan"</string>
- <string name="taskbar_button_back" msgid="8558862226461164514">"Kembali"</string>
- <string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"Penukar IME"</string>
- <string name="taskbar_button_recents" msgid="7273376136216613134">"Terbaharu"</string>
- <string name="taskbar_button_notifications" msgid="7471740351507357318">"Pemberitahuan"</string>
- <string name="taskbar_button_quick_settings" msgid="227662894293189391">"Tetapan Pantas"</string>
- <string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Alihkan ke atas/kiri"</string>
- <string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Alihkan ke bawah/kanan"</string>
</resources>
diff --git a/quickstep/res/values-my/strings.xml b/quickstep/res/values-my/strings.xml
index d09165aa02..7683e05990 100644
--- a/quickstep/res/values-my/strings.xml
+++ b/quickstep/res/values-my/strings.xml
@@ -19,93 +19,19 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="recent_task_option_pin" msgid="7929860679018978258">"ပင်ထိုးရန်"</string>
+ <string name="recent_task_option_split_screen" msgid="5353188922202653570">"မျက်နှာပြင် ခွဲ၍ပြသခြင်း"</string>
+ <string name="recent_task_option_pin" msgid="7929860679018978258">"ပင်ထိုးခြင်း"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"အလွတ်ပုံစံ"</string>
+ <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"အနှစ်ချုပ်"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"မကြာမီကဖွင့်ထားသည်များ မရှိပါ"</string>
+ <string name="accessibility_close_task" msgid="5354563209433803643">"ပိတ်ရန်"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"အက်ပ်အသုံးပြုမှု ဆက်တင်များ"</string>
- <string name="recents_clear_all" msgid="5328176793634888831">"အားလုံးရှင်းရန်"</string>
+ <string name="recents_clear_all" msgid="5328176793634888831">"အားလုံးကို ရှင်းရန်"</string>
<string name="accessibility_recent_apps" msgid="4058661986695117371">"လတ်တလောသုံး အက်ပ်များ"</string>
- <string name="task_view_closed" msgid="9170038230110856166">"လုပ်ဆောင်စရာ ပိတ်ထားသည်"</string>
<string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>၊ <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
<string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; ၁ မိနစ်"</string>
<string name="time_left_for_app" msgid="3111996412933644358">"ယနေ့ <xliff:g id="TIME">%1$s</xliff:g> ခု ကျန်သည်"</string>
<string name="title_app_suggestions" msgid="4185902664111965088">"အက်ပ်အကြံပြုချက်များ"</string>
+ <string name="all_apps_label" msgid="8542784161730910663">"အက်ပ်အားလုံး"</string>
<string name="all_apps_prediction_tip" msgid="2672336544844936186">"သင်၏ ခန့်မှန်းအက်ပ်များ"</string>
- <string name="hotseat_edu_title_migrate" msgid="306578144424489980">"သင်၏ \'ပင်မစာမျက်နှာ\' အောက်ခြေအတန်းတွင် အက်ပ်အကြံပြုချက်များ ရယူခြင်း"</string>
- <string name="hotseat_edu_title_migrate_landscape" msgid="3633942953997845243">"သင်၏ \'ပင်မစာမျက်နှာ\' ၏ အနှစ်သက်ဆုံးများအတန်းတွင် အက်ပ်အကြံပြုချက်များ ရယူခြင်း"</string>
- <string name="hotseat_edu_message_migrate" msgid="8927179260533775320">"အသုံးအများဆုံးအက်ပ်များကို \'ပင်မစာမျက်နှာ\' တွင် အလွယ်တကူ ဖွင့်နိုင်သည်။ သင်၏ ပုံမှန်လုပ်ဆောင်ချက်များပေါ် အခြေခံ၍ အကြံပြုချက်များ ပြောင်းလဲပါမည်။ အောက်ခြေအတန်းရှိ အက်ပ်များကို သင်၏ \'ပင်မစာမျက်နှာ\' သို့ရွှေ့လိုက်မည်။"</string>
- <string name="hotseat_edu_message_migrate_landscape" msgid="4248943380443387697">"အသုံးအများဆုံးအက်ပ်များကို \'ပင်မစာမျက်နှာ\' တွင် အလွယ်တကူ သုံးနိုင်သည်။ သင်၏ ပုံမှန်အစီအစဉ်များပေါ် အခြေခံ၍ အကြံပြုချက်များ ပြောင်းလဲပါမည်။ အနှစ်သက်ဆုံးများအတန်းရှိ အက်ပ်များကို သင်၏ \'ပင်မစာမျက်နှာ\' သို့ရွှေ့လိုက်မည်။"</string>
- <string name="hotseat_edu_message_migrate_alt" msgid="3042360119039646356">"အသုံးအများဆုံးအက်ပ်များကို \'ပင်မစာမျက်နှာ\' တွင် အလွယ်တကူ သုံးနိုင်သည်။ သင်၏ ပုံမှန်အစီအစဉ်များပေါ် အခြေခံ၍ အကြံပြုချက်များ ပြောင်းလဲပါမည်။ အောက်ခြေအတန်းရှိ အက်ပ်များကို ဖိုင်တွဲအသစ်သို့ ရွှေ့လိုက်မည်။"</string>
- <string name="hotseat_edu_accept" msgid="1611544083278999837">"အက်ပ်အကြံပြုချက်များ ရယူရန်"</string>
- <string name="hotseat_edu_dismiss" msgid="2781161822780201689">"မလိုပါ"</string>
- <string name="hotseat_prediction_settings" msgid="6246554993566070818">"ဆက်တင်များ"</string>
- <string name="hotseat_auto_enrolled" msgid="522100018967146807">"အသုံးအများဆုံးအက်ပ်များကို ဤနေရာတွင် ပြပြီး ပုံမှန်အစီအစဉ်များပေါ် အခြေခံ၍ ပြောင်းလဲသည်"</string>
- <string name="hotseat_tip_no_empty_slots" msgid="1325212677738179185">"အက်ပ်အကြံပြုချက်များ ရယူရန် အောက်ခြေအတန်းရှိ အက်ပ်များကို ဖိဆွဲထုတ်လိုက်ပါ"</string>
- <string name="hotseat_tip_gaps_filled" msgid="3035673010274223538">"အက်ပ်အကြံပြုချက်များကို နေရာလွတ်သို့ ထည့်လိုက်သည်"</string>
- <string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"အက်ပ်အကြံပြုချက်များ ဖွင့်ထားသည်"</string>
- <string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"အက်ပ်အကြံပြုချက်များကို ပိတ်ထားသည်"</string>
- <string name="hotseat_prediction_content_description" msgid="4582028296938078419">"ကြိုတင်မှန်းဆထားသော အက်ပ်− <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"ညာ သို့မဟုတ် ဘယ်ဘက်အစွန် ခပ်လှမ်းလှမ်းမှ ပွတ်ဆွဲကြောင်း သေချာပါစေ။"</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"စခရင်၏ ညာ သို့မဟုတ် ဘက်ဘက်အစွန်မှ အလယ်သို့ ပွတ်ဆွဲပြီး လွှတ်လိုက်ကြောင်း သေချာပါစေ။"</string>
- <string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"နောက်ပြန်သွားရန် ညာဘက်မှပွတ်ဆွဲနည်းကို သိသွားပါပြီ။ နောက်အဆင့်တွင် အက်ပ်များပြောင်းနည်းကို လေ့လာပါ။"</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"နောက်ဆုတ်လက်ဟန် ရှင်းလင်းပို့ချချက် ပြီးပါပြီ။"</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"ဖန်သားပြင် အောက်ခြေနှင့် အလွန်နီးကပ်စွာ ပွတ်ဆွဲခြင်းမရှိကြောင်း သေချာပါစေ။"</string>
- <string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"နောက်ဆုတ်လက်ဟန်၏ အာရုံခံစွမ်းကိုပြောင်းရန် ‘ဆက်တင်များ’ သို့ သွားပါ"</string>
- <string name="back_gesture_intro_title" msgid="19551256430224428">"နောက်ပြန်သွားရန် ပွတ်ဆွဲပါ"</string>
- <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"နောက်ဆုံးဖန်သားပြင်သို့ ပြန်သွားရန် ဘယ်ဘက် (သို့) ညာဘက်အစွန်မှ ဖန်သားပြင်အလယ်သို့ ပွတ်ဆွဲပါ။"</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"ဖန်သားပြင် အောက်ခြေအစွန်မှ အပေါ်သို့ ပွတ်ဆွဲကြောင်း သေချာပါစေ။"</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"လက်မလွှတ်ခင် ခဏရပ်ခြင်းမရှိကြောင်း သေချာပါစေ။"</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"အပေါ်တည့်တည့်သို့ ပွတ်ဆွဲကြောင်း သေချာပါစေ။"</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"ပင်မစာမျက်နှာသို့သွားသည့် လက်ဟန် ရှင်းလင်းပို့ချချက် ပြီးပါပြီ။ နောက်အဆင့်တွင် နောက်သို့ပြန်သွားနည်းကို လေ့လာပါ။"</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"ပင်မစာမျက်နှာသို့သွားသည့် လက်ဟန် ရှင်းလင်းပို့ချချက် ပြီးပါပြီ။"</string>
- <string name="home_gesture_intro_title" msgid="836590312858441830">"ပင်မစာမျက်နှာသို့သွားရန် ပွတ်ဆွဲပါ"</string>
- <string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"သင့်ဖန်သားပြင် အောက်ခြေမှ အပေါ်သို့ပွတ်ဆွဲပါ။ ဤလက်ဟန်ဖြင့် ပင်မစာမျက်နှာသို့ အမြဲပြန်သွားနိုင်သည်။"</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"ဖန်သားပြင် အောက်ခြေအစွန်မှ အပေါ်သို့ ပွတ်ဆွဲကြောင်း သေချာပါစေ။"</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"မလွှတ်ခင် ဝင်းဒိုးကို အချိန်ကြာကြာ ဖိထားကြည့်ပါ။"</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"အပေါ်တည့်တည့်သို့ ပွတ်ဆွဲပြီးနောက် ခဏရပ်ကြောင်း သေချာပါစေ။"</string>
- <string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"လက်ဟန်များသုံးနည်းကို သင်သိသွားပါပြီ။ လက်ဟန်များကို ပိတ်ရန် ဆက်တင်များသို့ သွားပါ။"</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"အက်ပ်များပြောင်းသည့် လက်ဟန် ရှင်းလင်းပို့ချချက် ပြီးပါပြီ။"</string>
- <string name="overview_gesture_intro_title" msgid="2902054412868489378">"အက်ပ်များပြောင်းရန် ပွတ်ဆွဲပါ"</string>
- <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"အက်ပ်တစ်ခုမှတစ်ခုသို့ ပြောင်းရန် စခရင်အောက်ခြေမှ အပေါ်သို့ ပွတ်ဆွဲ၍ ဖိထားပြီးနောက် လွှတ်ပါ။"</string>
- <string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"အားလုံးအဆင်သင့်ဖြစ်ပါပြီ"</string>
- <string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"ပြီးပြီ"</string>
- <string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"ဆက်တင်များ"</string>
- <string name="gesture_tutorial_try_again" msgid="65962545858556697">"ထပ်စမ်းကြည့်ရန်"</string>
- <string name="gesture_tutorial_nice" msgid="2936275692616928280">"ကောင်းသည်။"</string>
- <string name="gesture_tutorial_step" msgid="1279786122817620968">"ရှင်းလင်းပို့ချချက် <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
- <string name="allset_title" msgid="5021126669778966707">"အားလုံး အဆင်သင့်ပါ။"</string>
- <string name="allset_hint" msgid="2384632994739392447">"ပင်မစာမျက်နှာသို့သွားရန် အပေါ်သို့ ပွတ်ဆွဲပါ"</string>
- <string name="allset_description" msgid="6350320429953234580">"သင့်ဖုန်းကို စတင်အသုံးပြုရန် အသင့်ဖြစ်ပါပြီ"</string>
- <string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"စနစ် လမ်းညွှန် ဆက်တင်များ"</annotation></string>
- <string name="action_share" msgid="2648470652637092375">"မျှဝေရန်"</string>
- <string name="action_screenshot" msgid="8171125848358142917">"ဖန်သားပြင်ဓာတ်ပုံ"</string>
- <string name="action_split" msgid="2098009717623550676">"ခွဲထုတ်ရန်"</string>
- <string name="toast_split_select_app" msgid="5453865907322018352">"မျက်နှာပြင်ခွဲ၍ပြသရန် အက်ပ်နောက်တစ်ခုကို တို့ပါ"</string>
- <string name="toast_split_app_unsupported" msgid="3271526028981899666">"အက်ပ်တွင် မျက်နှာပြင် ခွဲ၍ပြသခြင်း သုံး၍မရပါ။"</string>
- <string name="blocked_by_policy" msgid="2071401072261365546">"ဤလုပ်ဆောင်ချက်ကို အက်ပ် သို့မဟုတ် သင်၏အဖွဲ့အစည်းက ခွင့်မပြုပါ"</string>
- <string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"လမ်းညွှန်ခြင်း ရှင်းလင်းပို့ချချက်ကို ကျော်မလား။"</string>
- <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"၎င်းကို နောက်မှ <xliff:g id="NAME">%1$s</xliff:g> အက်ပ်တွင် ရှာနိုင်သည်"</string>
- <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"မလုပ်တော့"</string>
- <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"ကျော်ရန်"</string>
- <string name="accessibility_rotate_button" msgid="4771825231336502943">"ဖန်သားပြင်လှည့်ရန်"</string>
- <string name="taskbar_edu_opened" msgid="3950252793551919129">"ပညာရေး လုပ်ဆောင်စရာဘား ပြထားသည်"</string>
- <string name="taskbar_edu_closed" msgid="126643734478892862">"ပညာရေး လုပ်ဆောင်စရာဘား ပိတ်ထားသည်"</string>
- <string name="taskbar_edu_switch_apps" msgid="6942863327845784813">"အက်ပ်များပြောင်းရန် လုပ်ဆောင်စရာဘားကို သုံးပါ"</string>
- <string name="taskbar_edu_splitscreen" msgid="2663361731630346489">"အက်ပ်နှစ်ခု တစ်ပြိုင်တည်းသုံးရန် တစ်ဖက်သို့ ဖိဆွဲပါ"</string>
- <string name="taskbar_edu_stashing" msgid="5212374387411764031">"လုပ်ဆောင်စရာဘားကို ဖျောက်ရန် ထိပြီးဖိထားနိုင်သည်"</string>
- <string name="taskbar_edu_next" msgid="4007618274426775841">"ရှေ့သို့"</string>
- <string name="taskbar_edu_previous" msgid="459202320127201702">"နောက်သို့"</string>
- <string name="taskbar_edu_close" msgid="887022990168191073">"ပိတ်ရန်"</string>
- <string name="taskbar_edu_done" msgid="6880178093977704569">"ပြီးပြီ"</string>
- <string name="taskbar_button_home" msgid="2151398979630664652">"ပင်မစာမျက်နှာ"</string>
- <string name="taskbar_button_a11y" msgid="5241161324875094465">"အများသုံးစွဲနိုင်မှု"</string>
- <string name="taskbar_button_back" msgid="8558862226461164514">"နောက်သို့"</string>
- <string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"IME ပြောင်းစနစ်"</string>
- <string name="taskbar_button_recents" msgid="7273376136216613134">"လတ်တလောများ"</string>
- <!-- no translation found for taskbar_button_notifications (7471740351507357318) -->
- <skip />
- <!-- no translation found for taskbar_button_quick_settings (227662894293189391) -->
- <skip />
- <string name="move_drop_target_top_or_left" msgid="2988702185049595807">"အပေါ်/ဘယ်ဘက်သို့ ရွှေ့ရန်"</string>
- <string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"အောက်ခြေ/ညာဘက်သို့ ရွှေ့ရန်"</string>
</resources>
diff --git a/quickstep/res/values-nb/strings.xml b/quickstep/res/values-nb/strings.xml
index 6d143bdc7f..01bbb6a75d 100644
--- a/quickstep/res/values-nb/strings.xml
+++ b/quickstep/res/values-nb/strings.xml
@@ -19,93 +19,19 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Delt skjerm"</string>
<string name="recent_task_option_pin" msgid="7929860679018978258">"Fest"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Fritt format"</string>
+ <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Oversikt"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"Ingen nylige elementer"</string>
+ <string name="accessibility_close_task" msgid="5354563209433803643">"Lukk"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Innstillinger for appbruk"</string>
<string name="recents_clear_all" msgid="5328176793634888831">"Fjern alt"</string>
<string name="accessibility_recent_apps" msgid="4058661986695117371">"Nylige apper"</string>
- <string name="task_view_closed" msgid="9170038230110856166">"Oppgaven er lukket"</string>
<string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
<string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 minutt"</string>
<string name="time_left_for_app" msgid="3111996412933644358">"<xliff:g id="TIME">%1$s</xliff:g> gjenstår i dag"</string>
<string name="title_app_suggestions" msgid="4185902664111965088">"Appanbefalinger"</string>
+ <string name="all_apps_label" msgid="8542784161730910663">"Alle apper"</string>
<string name="all_apps_prediction_tip" msgid="2672336544844936186">"Forslag til apper"</string>
- <string name="hotseat_edu_title_migrate" msgid="306578144424489980">"Få appforslag i den nederste raden på startskjermen"</string>
- <string name="hotseat_edu_title_migrate_landscape" msgid="3633942953997845243">"Få appforslag i favoritter-raden på startskjermen"</string>
- <string name="hotseat_edu_message_migrate" msgid="8927179260533775320">"Få enkel tilgang til appene du bruker oftest, rett fra startskjermen. Forslagene endres basert på rutinene dine. Appene i den nederste raden flyttes opp til startskjermen."</string>
- <string name="hotseat_edu_message_migrate_landscape" msgid="4248943380443387697">"Få enkel tilgang til appene du bruker oftest, rett fra startskjermen. Forslagene endres basert på rutinene dine. Apper i favoritter-raden blir flyttet til startskjermen."</string>
- <string name="hotseat_edu_message_migrate_alt" msgid="3042360119039646356">"Få enkel tilgang til appene du bruker oftest, rett fra startskjermen. Forslagene endres basert på rutinene dine. Appene i den nederste raden flyttes til en ny mappe."</string>
- <string name="hotseat_edu_accept" msgid="1611544083278999837">"Få appforslag"</string>
- <string name="hotseat_edu_dismiss" msgid="2781161822780201689">"Nei takk"</string>
- <string name="hotseat_prediction_settings" msgid="6246554993566070818">"Innstillinger"</string>
- <string name="hotseat_auto_enrolled" msgid="522100018967146807">"Appene som brukes oftest, vises her og endres basert på rutiner"</string>
- <string name="hotseat_tip_no_empty_slots" msgid="1325212677738179185">"Dra appene vekk fra den nederste raden for å få appforslag."</string>
- <string name="hotseat_tip_gaps_filled" msgid="3035673010274223538">"Appforslag er lagt til på et tomt område"</string>
- <string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Appforslag er på"</string>
- <string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Appforslag er slått av"</string>
- <string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Foreslått app: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Sørg for at du sveiper fra kanten helt til høyre eller venstre."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Sørg for at du sveiper fra den høyre eller venstre kanten til midten av skjermen og slipper."</string>
- <string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Du har lært hvordan du sveiper fra høyre for å gå tilbake. I neste trinn lærer du å bytte app."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"Du har fullført bevegelsen for å gå tilbake."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Sørg for at du ikke sveiper for nær bunnen av skjermen."</string>
- <string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"Gå til Innstillinger for å endre tilbakebevegelsefølsomheten"</string>
- <string name="back_gesture_intro_title" msgid="19551256430224428">"Sveip for å gå tilbake"</string>
- <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"For å gå tilbake til forrige skjerm, sveip fra venstre eller høyre kant til midten av skjermen."</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Sørg for at du sveiper opp fra den nederste kanten av skjermen."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Sørg for at du ikke setter på pause før du slipper."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Sørg for at du sveiper rett opp."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"Du har fullført bevegelsen for å gå til startskjermen. I neste trinn ser du hvordan du går tilbake."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"Du har fullført bevegelsen for å gå til startskjermen."</string>
- <string name="home_gesture_intro_title" msgid="836590312858441830">"Sveip for å gå til startskjermen"</string>
- <string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Sveip opp fra bunnen av skjermen. Denne bevegelsen tar deg alltid til startskjermen."</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Sørg for at du sveiper opp fra den nederste kanten av skjermen."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Prøv å holde vinduet lenger før du slipper."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Sørg for at du sveiper rett opp, og så stopper du."</string>
- <string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Du har lært hvordan du bruker bevegelser. For å slå av bevegelser, gå til Innstillinger."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"Du har fullført bevegelsen for å bytte app."</string>
- <string name="overview_gesture_intro_title" msgid="2902054412868489378">"Sveip for å bytte app"</string>
- <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"For å bytte mellom apper, sveip opp fra bunnen av skjermen, hold, og slipp"</string>
- <string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"Ferdig"</string>
- <string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Ferdig"</string>
- <string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Innstillinger"</string>
- <string name="gesture_tutorial_try_again" msgid="65962545858556697">"Prøv igjen"</string>
- <string name="gesture_tutorial_nice" msgid="2936275692616928280">"Bra!"</string>
- <string name="gesture_tutorial_step" msgid="1279786122817620968">"Veiledning <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
- <string name="allset_title" msgid="5021126669778966707">"Alt er klart!"</string>
- <string name="allset_hint" msgid="2384632994739392447">"Sveip opp for å gå til startskjermen"</string>
- <string name="allset_description" msgid="6350320429953234580">"Du er klar til å begynne å bruke telefonen"</string>
- <string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"Innstillinger for systemnavigasjon"</annotation></string>
- <string name="action_share" msgid="2648470652637092375">"Del"</string>
- <string name="action_screenshot" msgid="8171125848358142917">"Skjermdump"</string>
- <string name="action_split" msgid="2098009717623550676">"Del opp"</string>
- <string name="toast_split_select_app" msgid="5453865907322018352">"Trykk på en annen app for å bruke delt skjerm"</string>
- <string name="toast_split_app_unsupported" msgid="3271526028981899666">"Appen støtter ikke delt skjerm."</string>
- <string name="blocked_by_policy" msgid="2071401072261365546">"Appen eller organisasjonen din tillater ikke denne handlingen"</string>
- <string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Vil du hoppe over navigeringsveiledning?"</string>
- <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Du kan finne dette i <xliff:g id="NAME">%1$s</xliff:g>-appen senere"</string>
- <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Avbryt"</string>
- <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Hopp over"</string>
- <string name="accessibility_rotate_button" msgid="4771825231336502943">"Rotér skjermen"</string>
- <string name="taskbar_edu_opened" msgid="3950252793551919129">"Opplæringen for oppgavelinjen vises"</string>
- <string name="taskbar_edu_closed" msgid="126643734478892862">"Opplæringen for oppgavelinjen er lukket"</string>
- <string name="taskbar_edu_switch_apps" msgid="6942863327845784813">"Bruk oppgavelinjen for å bytte app"</string>
- <string name="taskbar_edu_splitscreen" msgid="2663361731630346489">"Dra til siden for å bruke to apper samtidig"</string>
- <string name="taskbar_edu_stashing" msgid="5212374387411764031">"Trykk og hold for å skjule oppgavelinjen"</string>
- <string name="taskbar_edu_next" msgid="4007618274426775841">"Neste"</string>
- <string name="taskbar_edu_previous" msgid="459202320127201702">"Tilbake"</string>
- <string name="taskbar_edu_close" msgid="887022990168191073">"Lukk"</string>
- <string name="taskbar_edu_done" msgid="6880178093977704569">"Ferdig"</string>
- <string name="taskbar_button_home" msgid="2151398979630664652">"Hjem"</string>
- <string name="taskbar_button_a11y" msgid="5241161324875094465">"Tilgjengelighet"</string>
- <string name="taskbar_button_back" msgid="8558862226461164514">"Tilbake"</string>
- <string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"IME-veksler"</string>
- <string name="taskbar_button_recents" msgid="7273376136216613134">"Nylige"</string>
- <!-- no translation found for taskbar_button_notifications (7471740351507357318) -->
- <skip />
- <!-- no translation found for taskbar_button_quick_settings (227662894293189391) -->
- <skip />
- <string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Flytt til øverst/venstre"</string>
- <string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Flytt til nederst/høyre"</string>
</resources>
diff --git a/quickstep/res/values-ne/strings.xml b/quickstep/res/values-ne/strings.xml
index cd3383b5fe..60e9bd5313 100644
--- a/quickstep/res/values-ne/strings.xml
+++ b/quickstep/res/values-ne/strings.xml
@@ -19,93 +19,19 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="recent_task_option_split_screen" msgid="5353188922202653570">"स्क्रिन विभाजन गर्नुहोस्"</string>
<string name="recent_task_option_pin" msgid="7929860679018978258">"पिन गर्नुहोस्"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"फ्रिफर्म"</string>
+ <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"परिदृश्य"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"हालसालैको कुनै पनि वस्तु छैन"</string>
- <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"एपको उपयोगका सेटिङहरू"</string>
- <string name="recents_clear_all" msgid="5328176793634888831">"सबै मेटाउनुहोस्"</string>
- <string name="accessibility_recent_apps" msgid="4058661986695117371">"हालसालैका एपहरू"</string>
- <string name="task_view_closed" msgid="9170038230110856166">"कार्य बन्द गरियो"</string>
+ <string name="accessibility_close_task" msgid="5354563209433803643">"बन्द गर्नुहोस्"</string>
+ <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"अनुप्रयोगको उपयोगका सेटिङहरू"</string>
+ <string name="recents_clear_all" msgid="5328176793634888831">"सबै खाली गर्नुहोस्"</string>
+ <string name="accessibility_recent_apps" msgid="4058661986695117371">"हालसालैका अनुप्रयोगहरू"</string>
<string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
<string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; १ मिनेट"</string>
<string name="time_left_for_app" msgid="3111996412933644358">"आज: <xliff:g id="TIME">%1$s</xliff:g> बाँकी"</string>
- <string name="title_app_suggestions" msgid="4185902664111965088">"एपसम्बन्धी सुझावहरू"</string>
- <string name="all_apps_prediction_tip" msgid="2672336544844936186">"तपाईंलाई चाहिने एपहरू"</string>
- <string name="hotseat_edu_title_migrate" msgid="306578144424489980">"आफ्नो होम स्क्रिनको पुछारको रोमा एपसम्बन्धी सिफारिस प्राप्त गर्नुहोस्"</string>
- <string name="hotseat_edu_title_migrate_landscape" msgid="3633942953997845243">"आफ्नो होम स्क्रिनको मन पर्ने नामक पङ्क्तिमा एपसम्बन्धी सिफारिस प्राप्त गर्नुहोस्"</string>
- <string name="hotseat_edu_message_migrate" msgid="8927179260533775320">"आफूले सबैभन्दा बढी प्रयोग गर्ने एप होम स्क्रिनबाट सजिलै चलाउनुहोस्। सिफारिस गरिने एपहरूको क्रम तपाईंले एप प्रयोग गर्ने समयतालिकाअनुसार बदलिने छ। फेदको रोमा रहेका एपहरू तपाईंको होम स्क्रिनको सिरानमा सर्ने छन्।"</string>
- <string name="hotseat_edu_message_migrate_landscape" msgid="4248943380443387697">"आफूले सबैभन्दा बढी प्रयोग गर्ने एपहरू गृह स्क्रिनबाटै सजिलैसँग खोल्नुहोस्। सिफारिस गरिने एपहरूको क्रम तपाईंको दिनचर्याअनुसार बदलिने छ। मन पर्ने नामक पङ्क्तिमा रहेका एपहरू सारेर होम स्क्रिनमा लगिने छन्।"</string>
- <string name="hotseat_edu_message_migrate_alt" msgid="3042360119039646356">"गृह स्क्रिनबाटै आफूले सबैभन्दा बढी प्रयोग गर्ने एप सजिलै चलाउनुहोस्। सिफारिस गरिने एपहरूको क्रम तपाईंले एप प्रयोग गर्ने समयतालिकाअनुसार बदलिने छ। फेदको पङ्क्तिमा रहेका एपहरू एउटा नयाँ फोल्डरमा सर्ने छन्।"</string>
- <string name="hotseat_edu_accept" msgid="1611544083278999837">"एपसम्बन्धी सिफारिस प्राप्त गर्नुहोस्"</string>
- <string name="hotseat_edu_dismiss" msgid="2781161822780201689">"पर्दैन धन्यवाद"</string>
- <string name="hotseat_prediction_settings" msgid="6246554993566070818">"सेटिङ"</string>
- <string name="hotseat_auto_enrolled" msgid="522100018967146807">"सबैभन्दा बढी प्रयोग हुने एपहरू यहाँ देखिन्छन् र यी एपहरूको क्रम तपाईंले एप प्रयोग गर्ने समयतालिकाअनुसार बदलिरहन्छ"</string>
- <string name="hotseat_tip_no_empty_slots" msgid="1325212677738179185">"एपसम्बन्धी सिफारिस प्राप्त गर्न फेदको रोमा रहेका एपहरू ड्र्याग गरी हटाउनुहोस्"</string>
- <string name="hotseat_tip_gaps_filled" msgid="3035673010274223538">"खाली ठाउँमा सिफारिस गरिएका एपहरू थपिए"</string>
- <string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"सिफारिस गरिएका एपहरू देखाउने सुविधा सक्षम पारिएका छन्"</string>
- <string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"सिफारिस गरिएका एपहरू देखाउने सुविधा असक्षम पारिएको छ"</string>
- <string name="hotseat_prediction_content_description" msgid="4582028296938078419">"पूर्वानुमान गरिएको एप: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"स्क्रिनको सबैभन्दा दायाँ किनारा वा सबैभन्दा बायाँ किनाराबाट स्वाइप गर्नुहोस्।"</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"स्क्रिनको दायाँ वा बायाँ किनाराबाट मध्य भागसम्म स्वाइप गर्नुहोस् अनि औँला उठाउनुहोस्।"</string>
- <string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"तपाईंले स्क्रिनको दायाँ किनाराबाट स्वाइप गरेर अघिल्लो स्क्रिनमा फर्कने तरिका सिक्नुभयो। अब एउटा एपबाट अर्को एपमा जाने तरिका सिक्नुहोस्।"</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"तपाईंले \'पछाडि जानुहोस्\' नामक इसारा प्रयोग गर्ने तरिका सिक्नुभयो।"</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"स्क्रिनको फेदको धेरै नजिकसम्म स्वाइप नगर्नुहोस्।"</string>
- <string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"\'पछाडि\' नामक इसाराको संवेदनशीलता बदल्न सेटिङमा जानुहोस्"</string>
- <string name="back_gesture_intro_title" msgid="19551256430224428">"पछाडि जान स्वाइप गर्नुहोस्"</string>
- <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"यसअघिको स्क्रिनमा फर्कन स्क्रिनको बायाँ वा दायाँ किनाराबाट मध्य भागसम्म स्वाइप गर्नुहोस्।"</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"स्क्रिनको फेदबाट माथितिर स्वाइप गर्नुहोस्।"</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"औँला उठाउनुअघि नरोकिनुहोस्।"</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"सीधै माथितिर स्वाइप गर्नुहोस्।"</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"तपाईंले \'होम स्क्रिनमा जानुहोस्\' नामक इसारा प्रयोग गर्ने तरिका सिक्नुभयो। अब पछाडि जाने तरिका सिक्नुहोस्।"</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"तपाईंले \'होम स्क्रिनमा जानुहोस्\' नामक इसारा प्रयोग गर्ने तरिका सिक्नुभयो।"</string>
- <string name="home_gesture_intro_title" msgid="836590312858441830">"होम स्क्रिनमा जान स्वाइप गर्नुहोस्"</string>
- <string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"स्क्रिनको फेदबाट माथितिर स्वाइप गर्नुहोस्। यो इसारा प्रयोग गर्दा सधैँ होम स्क्रिन खुल्छ।"</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"स्क्रिनको फेदबाट माथितिर स्वाइप गर्नुहोस्।"</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"स्क्रिनबाट औँला उठाउनुअघि एपको विन्डोमा केही बेर छोइराख्नुहोस्।"</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"सीधै माथितिर स्वाइप गर्नुहोस् अनि रोकिनुहोस्।"</string>
- <string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"तपाईंले इसाराहरू प्रयोग गर्ने तरिका सिक्नुभयो। इसारा अफ गर्न सेटिङमा जानुहोस्।"</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"तपाईंले \'एउटा एपबाट अर्को एपमा जानुहोस्\' नामक इसारा प्रयोग गर्ने तरिका सिक्नुभयो।"</string>
- <string name="overview_gesture_intro_title" msgid="2902054412868489378">"एउटा एपबाट अर्को एपमा जान स्वाइप गर्नुहोस्"</string>
- <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"एउटा एपबाट अर्कोमा जान स्क्रिनको फेदबाट माथितिर स्वाइप गर्नुहोस्, छोइराख्नुहोस् अनि औँला उठाउनुहोस्।"</string>
- <string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"सबै तयार छ"</string>
- <string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"सम्पन्न भयो"</string>
- <string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"सेटिङ"</string>
- <string name="gesture_tutorial_try_again" msgid="65962545858556697">"फेरि प्रयास गर्नुहोस्"</string>
- <string name="gesture_tutorial_nice" msgid="2936275692616928280">"राम्रो!"</string>
- <string name="gesture_tutorial_step" msgid="1279786122817620968">"ट्युटोरियल <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
- <string name="allset_title" msgid="5021126669778966707">"सबै तयार भयो!"</string>
- <string name="allset_hint" msgid="2384632994739392447">"होममा जान माथितिर स्वाइप गर्नुहोस्"</string>
- <string name="allset_description" msgid="6350320429953234580">"तपाईं आफ्नो फोन चलाउन थाल्न सक्नुहुन्छ"</string>
- <string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"सिस्टम नेभिगेसनसम्बन्धी सेटिङ"</annotation></string>
- <string name="action_share" msgid="2648470652637092375">"सेयर गर्नुहोस्"</string>
- <string name="action_screenshot" msgid="8171125848358142917">"स्क्रिनसट"</string>
- <string name="action_split" msgid="2098009717623550676">"स्प्लिट गर्नुहोस्"</string>
- <string name="toast_split_select_app" msgid="5453865907322018352">"स्प्लिटक्रिन प्रयोग गर्न अर्को एपमा ट्याप गर्नुहोस्"</string>
- <string name="toast_split_app_unsupported" msgid="3271526028981899666">"यो एपको स्क्रिन विभाजन गर्न मिल्दैन।"</string>
- <string name="blocked_by_policy" msgid="2071401072261365546">"यो एप वा तपाईंको सङ्गठनले यो कारबाही गर्ने अनुमति दिँदैन"</string>
- <string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"नेभिगेसन ट्युटोरियल स्किप गर्ने हो?"</string>
- <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"तपाईं पछि <xliff:g id="NAME">%1$s</xliff:g> नामक एपमा गई यो ट्युटोरियल भेट्टाउन सक्नुहुन्छ"</string>
- <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"रद्द गर्नुहोस्"</string>
- <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"स्किप गर्नु…"</string>
- <string name="accessibility_rotate_button" msgid="4771825231336502943">"स्क्रिन घुमाउनुहोस्"</string>
- <string name="taskbar_edu_opened" msgid="3950252793551919129">"टास्कबार एजुकेसन देखिएको छ"</string>
- <string name="taskbar_edu_closed" msgid="126643734478892862">"टास्कबार एजुकेसन बन्द गरिएको छ"</string>
- <string name="taskbar_edu_switch_apps" msgid="6942863327845784813">"एउटा एपबाट अर्को एपमा जान टास्कबार प्रयोग गर्नुहोस्"</string>
- <string name="taskbar_edu_splitscreen" msgid="2663361731630346489">"टास्कबार छेउतिर ड्र्याग गरेर एकै पटक दुई वटा एप चलाउनुहोस्"</string>
- <string name="taskbar_edu_stashing" msgid="5212374387411764031">"टास्कबार लुकाउन टास्कबार थिचिराख्नुहोस्"</string>
- <string name="taskbar_edu_next" msgid="4007618274426775841">"अर्को"</string>
- <string name="taskbar_edu_previous" msgid="459202320127201702">"पछाडि"</string>
- <string name="taskbar_edu_close" msgid="887022990168191073">"बन्द गर्नुहोस्"</string>
- <string name="taskbar_edu_done" msgid="6880178093977704569">"सम्पन्न भयो"</string>
- <string name="taskbar_button_home" msgid="2151398979630664652">"होम"</string>
- <string name="taskbar_button_a11y" msgid="5241161324875094465">"सर्वसुलभता"</string>
- <string name="taskbar_button_back" msgid="8558862226461164514">"पछाडि जानुहोस्"</string>
- <string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"IME स्विचर"</string>
- <string name="taskbar_button_recents" msgid="7273376136216613134">"हालसालैका बटनहरू"</string>
- <!-- no translation found for taskbar_button_notifications (7471740351507357318) -->
- <skip />
- <!-- no translation found for taskbar_button_quick_settings (227662894293189391) -->
- <skip />
- <string name="move_drop_target_top_or_left" msgid="2988702185049595807">"सिरान/बायाँतिर सार्नुहोस्"</string>
- <string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"फेद/दायाँतिर सार्नुहोस्"</string>
+ <string name="title_app_suggestions" msgid="4185902664111965088">"अनुप्रयोगसम्बन्धी सुझावहरू"</string>
+ <string name="all_apps_label" msgid="8542784161730910663">"सबै अनुप्रयोगहरू"</string>
+ <string name="all_apps_prediction_tip" msgid="2672336544844936186">"तपाईंका पूर्वानुमानित अनुप्रयोगहरू"</string>
</resources>
diff --git a/quickstep/res/values-night/colors.xml b/quickstep/res/values-night/colors.xml
deleted file mode 100644
index af6e0647a1..0000000000
--- a/quickstep/res/values-night/colors.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2021 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.
--->
-<resources>
-
- <color name="gesture_tutorial_back_arrow_color">#99000000</color>
-
- <color name="gesture_tutorial_fake_wallpaper_color">#000000</color> <!-- Black -->
-
- <color name="mock_webpage_url_bar">#202124</color>
- <color name="mock_webpage_url_bar_item">#3c4043</color>
-
- <color name="all_set_page_background">#FF000000</color>
-
-</resources> \ No newline at end of file
diff --git a/quickstep/res/values-night/styles.xml b/quickstep/res/values-night/styles.xml
index e6b345010d..1bd3f5d138 100644
--- a/quickstep/res/values-night/styles.xml
+++ b/quickstep/res/values-night/styles.xml
@@ -21,7 +21,7 @@
<item name="android:statusBarColor">@android:color/transparent</item>
<item name="android:enforceNavigationBarContrast">false</item>
<item name="android:windowLightStatusBar">false</item>
- <item name="android:windowBackground">@android:color/transparent</item>
+ <item name="android:windowBackground">#FF000000</item>
</style>
</resources> \ No newline at end of file
diff --git a/quickstep/res/values-nl/strings.xml b/quickstep/res/values-nl/strings.xml
index 7772aae71c..8032567e1c 100644
--- a/quickstep/res/values-nl/strings.xml
+++ b/quickstep/res/values-nl/strings.xml
@@ -19,91 +19,19 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Gesplitst scherm"</string>
<string name="recent_task_option_pin" msgid="7929860679018978258">"Vastzetten"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Vrije vorm"</string>
+ <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Overzicht"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"Geen recente items"</string>
+ <string name="accessibility_close_task" msgid="5354563209433803643">"Sluiten"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Instellingen voor app-gebruik"</string>
<string name="recents_clear_all" msgid="5328176793634888831">"Alles wissen"</string>
<string name="accessibility_recent_apps" msgid="4058661986695117371">"Recente apps"</string>
- <string name="task_view_closed" msgid="9170038230110856166">"Taak gesloten"</string>
<string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
<string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 minuut"</string>
<string name="time_left_for_app" msgid="3111996412933644358">"Nog <xliff:g id="TIME">%1$s</xliff:g> vandaag"</string>
<string name="title_app_suggestions" msgid="4185902664111965088">"App-suggesties"</string>
+ <string name="all_apps_label" msgid="8542784161730910663">"Alle apps"</string>
<string name="all_apps_prediction_tip" msgid="2672336544844936186">"Je voorspelde apps"</string>
- <string name="hotseat_edu_title_migrate" msgid="306578144424489980">"App-suggesties ontvangen op de onderste rij van je startscherm"</string>
- <string name="hotseat_edu_title_migrate_landscape" msgid="3633942953997845243">"App-suggesties ontvangen op de rij met favorieten op het startscherm"</string>
- <string name="hotseat_edu_message_migrate" msgid="8927179260533775320">"Open je meestgebruikte apps gemakkelijk vanaf het startscherm. De suggesties veranderen op basis van je routines. Apps op de onderste rij worden naar je startscherm verplaatst."</string>
- <string name="hotseat_edu_message_migrate_landscape" msgid="4248943380443387697">"Open je meestgebruikte apps gemakkelijk vanaf het startscherm. De suggesties veranderen op basis van je routines. Apps op de rij met favorieten worden naar het startscherm verplaatst."</string>
- <string name="hotseat_edu_message_migrate_alt" msgid="3042360119039646356">"Open je meestgebruikte apps gemakkelijk vanaf het startscherm. De suggesties veranderen op basis van je routines. Apps op de onderste rij worden naar een nieuwe map verplaatst."</string>
- <string name="hotseat_edu_accept" msgid="1611544083278999837">"App-suggesties ontvangen"</string>
- <string name="hotseat_edu_dismiss" msgid="2781161822780201689">"Nee, bedankt"</string>
- <string name="hotseat_prediction_settings" msgid="6246554993566070818">"Instellingen"</string>
- <string name="hotseat_auto_enrolled" msgid="522100018967146807">"De meestgebruikte apps worden hier weergegeven en kunnen veranderen op basis van je routines"</string>
- <string name="hotseat_tip_no_empty_slots" msgid="1325212677738179185">"Sleep apps weg van de onderste rij om app-suggesties te ontvangen"</string>
- <string name="hotseat_tip_gaps_filled" msgid="3035673010274223538">"App-suggesties toegevoegd aan lege ruimte"</string>
- <string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"App-suggesties staan aan"</string>
- <string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"App-suggesties staan uit"</string>
- <string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Voorspelde app: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Swipe helemaal vanaf de rechter- of linkerrand."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Swipe vanaf de rechter- of linkerrand naar het midden van het scherm en laat los."</string>
- <string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Je weet nu hoe je vanaf rechts kunt swipen om terug te gaan. Ontdek nu hoe je tussen apps schakelt."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"Je weet nu hoe je het gebaar Terug maakt."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Swipe niet te dicht bij de onderkant van het scherm."</string>
- <string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"Open Instellingen om de gevoeligheid van Terug te wijzigen"</string>
- <string name="back_gesture_intro_title" msgid="19551256430224428">"Swipe om terug te gaan"</string>
- <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"Swipe vanaf de linker- of rechterrand naar het midden om terug te gaan naar het vorige scherm."</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Swipe vanaf de onderrand van het scherm omhoog."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Pauzeer niet voordat je loslaat."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Swipe recht omhoog."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"Je weet nu hoe je weer naar het startscherm gaat. Ontdek als volgende hoe je weer teruggaat."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"Je weet nu hoe je teruggaat naar het startscherm."</string>
- <string name="home_gesture_intro_title" msgid="836590312858441830">"Swipe om naar het startscherm te gaan"</string>
- <string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Swipe omhoog vanaf de onderkant van het scherm. Met dit gebaar ga je altijd naar het startscherm."</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Swipe vanaf de onderrand van het scherm omhoog."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Houd het venster langer vast voordat je loslaat."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Swipe recht omhoog en pauzeer dan."</string>
- <string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Je weet nu hoe je gebaren gebruikt. Als je gebaren wilt uitzetten, kun je dat via Instellingen doen."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"Je weet nu hoe je het gebaar Schakelen tussen apps maakt."</string>
- <string name="overview_gesture_intro_title" msgid="2902054412868489378">"Swipe om tussen apps te schakelen"</string>
- <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Swipe omhoog vanaf de onderkant van het scherm, houd vast en laat los om tussen apps te schakelen."</string>
- <string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"Klaar"</string>
- <string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Klaar"</string>
- <string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Instellingen"</string>
- <string name="gesture_tutorial_try_again" msgid="65962545858556697">"Probeer opnieuw"</string>
- <string name="gesture_tutorial_nice" msgid="2936275692616928280">"Dat gaat lekker."</string>
- <string name="gesture_tutorial_step" msgid="1279786122817620968">"Tutorial <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
- <string name="allset_title" msgid="5021126669778966707">"Klaar"</string>
- <string name="allset_hint" msgid="2384632994739392447">"Swipe omhoog om naar het startscherm te gaan"</string>
- <string name="allset_description" msgid="6350320429953234580">"Je bent klaar om je telefoon te gebruiken"</string>
- <string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"Navigatie-instellingen van systeem"</annotation></string>
- <string name="action_share" msgid="2648470652637092375">"Delen"</string>
- <string name="action_screenshot" msgid="8171125848358142917">"Screenshot"</string>
- <string name="action_split" msgid="2098009717623550676">"Splitsen"</string>
- <string name="toast_split_select_app" msgid="5453865907322018352">"Tik op nog een app om je scherm te splitsen"</string>
- <string name="toast_split_app_unsupported" msgid="3271526028981899666">"App ondersteunt geen gesplitst scherm."</string>
- <string name="blocked_by_policy" msgid="2071401072261365546">"Deze actie wordt niet toegestaan door de app of je organisatie"</string>
- <string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Navigatietutorial overslaan?"</string>
- <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Je vindt dit later terug in de app <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Annuleren"</string>
- <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Overslaan"</string>
- <string name="accessibility_rotate_button" msgid="4771825231336502943">"Scherm draaien"</string>
- <string name="taskbar_edu_opened" msgid="3950252793551919129">"Uitleg van taakbalk geopend"</string>
- <string name="taskbar_edu_closed" msgid="126643734478892862">"Uitleg van taakbalk gesloten"</string>
- <string name="taskbar_edu_switch_apps" msgid="6942863327845784813">"Gebruik de taakbalk om van app te wisselen"</string>
- <string name="taskbar_edu_splitscreen" msgid="2663361731630346489">"Sleep naar de zijkant om 2 apps tegelijk te gebruiken"</string>
- <string name="taskbar_edu_stashing" msgid="5212374387411764031">"Tik en houd vast om de taakbalk te verbergen"</string>
- <string name="taskbar_edu_next" msgid="4007618274426775841">"Volgende"</string>
- <string name="taskbar_edu_previous" msgid="459202320127201702">"Terug"</string>
- <string name="taskbar_edu_close" msgid="887022990168191073">"Sluiten"</string>
- <string name="taskbar_edu_done" msgid="6880178093977704569">"Klaar"</string>
- <string name="taskbar_button_home" msgid="2151398979630664652">"Home"</string>
- <string name="taskbar_button_a11y" msgid="5241161324875094465">"Toegankelijkheid"</string>
- <string name="taskbar_button_back" msgid="8558862226461164514">"Terug"</string>
- <string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"IME-schakelaar"</string>
- <string name="taskbar_button_recents" msgid="7273376136216613134">"Recent"</string>
- <string name="taskbar_button_notifications" msgid="7471740351507357318">"Meldingen"</string>
- <string name="taskbar_button_quick_settings" msgid="227662894293189391">"Snelle instellingen"</string>
- <string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Naar boven/links verplaatsen"</string>
- <string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Naar beneden/rechts verplaatsen"</string>
</resources>
diff --git a/quickstep/res/values-or/strings.xml b/quickstep/res/values-or/strings.xml
index 77407833f3..2ebec4e7c7 100644
--- a/quickstep/res/values-or/strings.xml
+++ b/quickstep/res/values-or/strings.xml
@@ -19,93 +19,19 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="recent_task_option_split_screen" msgid="5353188922202653570">"ସ୍କ୍ରୀନ୍‌କୁ ଭାଗ କରନ୍ତୁ"</string>
<string name="recent_task_option_pin" msgid="7929860679018978258">"ପିନ୍‍"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"ଫ୍ରିଫର୍ମ"</string>
+ <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"ସଂକ୍ଷିପ୍ତ ବିବରଣ"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"କୌଣସି ସାମ୍ପ୍ରତିକ ଆଇଟମ୍ ନାହିଁ"</string>
+ <string name="accessibility_close_task" msgid="5354563209433803643">"ବନ୍ଦ କରନ୍ତୁ"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"ଆପ୍‍ ବ୍ୟବହାର ସେଟିଂସ୍‍"</string>
<string name="recents_clear_all" msgid="5328176793634888831">"ସବୁ ଖାଲି କରନ୍ତୁ"</string>
<string name="accessibility_recent_apps" msgid="4058661986695117371">"ବର୍ତ୍ତମାନର ଆପ୍‌"</string>
- <string name="task_view_closed" msgid="9170038230110856166">"ଟାସ୍କ ବନ୍ଦ ହୋଇଯାଇଛି"</string>
<string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g> <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
<string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 ମିନିଟ୍"</string>
<string name="time_left_for_app" msgid="3111996412933644358">"ଆଜି <xliff:g id="TIME">%1$s</xliff:g> ବାକି ଅଛି"</string>
<string name="title_app_suggestions" msgid="4185902664111965088">"ଆପ୍ ପରାମର୍ଶଗୁଡ଼ିକ"</string>
+ <string name="all_apps_label" msgid="8542784161730910663">"ସମସ୍ତ ଆପ୍ସ"</string>
<string name="all_apps_prediction_tip" msgid="2672336544844936186">"ଆପଣ ପୂର୍ବାନୁମାନ କରିଥିବା ଆପ୍ସ"</string>
- <string name="hotseat_edu_title_migrate" msgid="306578144424489980">"ଆପଣଙ୍କ ମୂଳ ସ୍କ୍ରିନର ତଳ ଧାଡ଼ିରେ ଆପ୍ ପରାମର୍ଶଗୁଡ଼ିକ ପାଆନ୍ତୁ"</string>
- <string name="hotseat_edu_title_migrate_landscape" msgid="3633942953997845243">"ଆପଣଙ୍କ ମୂଳ ସ୍କ୍ରିନର ପସନ୍ଦର ଧାଡ଼ିରେ ଆପ୍ ପରାମର୍ଶଗୁଡ଼ିକ ପାଆନ୍ତୁ"</string>
- <string name="hotseat_edu_message_migrate" msgid="8927179260533775320">"ଆପଣଙ୍କର ସବୁଠାରୁ ଅଧିକ-ବ୍ୟବହୃତ ଆପଗୁଡ଼ିକୁ ସିଧା ମୂଳ ସ୍କ୍ରିନରେ ସହଜରେ ଆକ୍ସେସ୍ କରନ୍ତୁ। ଆପଣଙ୍କ ରୁଟିନଗୁଡ଼ିକ ଆଧାରରେ ପରାମର୍ଶଗୁଡ଼ିକ ପରିବର୍ତ୍ତିତ ହେବ। ତଳ ଧାଡ଼ିରେ ଥିବା ଆପଗୁଡ଼ିକ ଆପଣଙ୍କ ମୂଳ ସ୍କ୍ରିନକୁ ମୁଭ୍ କରିଯିବ।"</string>
- <string name="hotseat_edu_message_migrate_landscape" msgid="4248943380443387697">"ମୂଳ ସ୍କ୍ରିନରେ ହିଁ ଆପଣଙ୍କର ସବୁଠାରୁ ଅଧିକ-ବ୍ୟବହୃତ ଆପଗୁଡ଼ିକୁ ସହଜରେ ଆକ୍ସେସ୍ କରନ୍ତୁ। ଆପଣଙ୍କ ରୁଟିନଗୁଡ଼ିକ ଆଧାରରେ ପରାମର୍ଶଗୁଡ଼ିକ ବଦଳିବ। ଆପଣଙ୍କ ମୂଳ ସ୍କ୍ରିନକୁ ପସନ୍ଦର ଧାଡ଼ିରେ ଥିବା ଆପଗୁଡ଼ିକ ମୁଭ୍ ହେବ।"</string>
- <string name="hotseat_edu_message_migrate_alt" msgid="3042360119039646356">"ଆପଣଙ୍କର ସବୁଠାରୁ ଅଧିକ-ବ୍ୟବହୃତ ଆପଗୁଡ଼ିକୁ, ସିଧା ମୂଳ ସ୍କ୍ରିନରେ ସହଜରେ ଆକ୍ସେସ୍ କରନ୍ତୁ। ଆପଣଙ୍କ ରୁଟିନଗୁଡ଼ିକ ଆଧାରରେ ପରାମର୍ଶଗୁଡ଼ିକ ପରିବର୍ତ୍ତିତ ହେବ। ତଳ ଧାଡ଼ିରେ ଥିବା ଆପଗୁଡ଼ିକ ଏକ ନୂଆ ଫୋଲ୍ଡରକୁ ମୁଭ୍ କରିଯିବ।"</string>
- <string name="hotseat_edu_accept" msgid="1611544083278999837">"ଆପ୍ ପରାମର୍ଶଗୁଡ଼ିକ ପାଆନ୍ତୁ"</string>
- <string name="hotseat_edu_dismiss" msgid="2781161822780201689">"ନାହିଁ, ଥାଉ"</string>
- <string name="hotseat_prediction_settings" msgid="6246554993566070818">"ସେଟିଂସ୍"</string>
- <string name="hotseat_auto_enrolled" msgid="522100018967146807">"ସବୁଠାରୁ ଅଧିକ-ବ୍ୟବହୃତ ଆପଗୁଡ଼ିକ ଏଠାରେ ଦେଖାଯାଏ ଏବଂ ରୁଟିନଗୁଡ଼ିକ ଆଧାରରେ ପରିବର୍ତ୍ତିତ ହୋଇଥାଏ"</string>
- <string name="hotseat_tip_no_empty_slots" msgid="1325212677738179185">"ଆପ୍ ପରାମର୍ଶଗୁଡ଼ିକ ପାଇବାକୁ ଆପଗୁଡ଼ିକୁ ତଳ ଧାଡ଼ିରୁ ଟାଣି ଆଣନ୍ତୁ"</string>
- <string name="hotseat_tip_gaps_filled" msgid="3035673010274223538">"ଆପ୍ ପରାମର୍ଶଗୁଡ଼ିକ ଖାଲି ସ୍ଥାନରେ ଯୋଗ କରାଯାଇଛି"</string>
- <string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"ଆପ୍ ପରାମର୍ଶଗୁଡ଼ିକୁ ସକ୍ଷମ କରାଯାଇଛି"</string>
- <string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"ଆପ୍ ପରାମର୍ଶଗୁଡ଼ିକୁ ଅକ୍ଷମ କରାଯାଇଛି"</string>
- <string name="hotseat_prediction_content_description" msgid="4582028296938078419">"ପୂର୍ବାନୁମାନ କରାଯାଇଥିବା ଆପ୍: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"ଆପଣ ସ୍କ୍ରିନର ଏକଦମ୍-ଡାହାଣ ବା ବାମ ଧାରରୁ ସ୍ୱାଇପ୍ କରୁଥିବା ସୁନିଶ୍ଚିତ କରନ୍ତୁ।"</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"ଆପଣ ସ୍କ୍ରିନର ଡାହାଣ ବା ବାମ ଧାରରୁ ମଝିକୁ ସ୍ୱାଇପ୍ କରି ଛାଡ଼ି ଦେଉଥିବା ସୁନିଶ୍ଚିତ କରନ୍ତୁ।"</string>
- <string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"ଆପଣ ଡାହାଣରୁ ସ୍ୱାଇପ୍ କରି ପଛକୁ କିପରି ଫେରିବେ ତାହା ଜାଣିଲେ। ତା\'ପରେ, ଆପକୁ କିପରି ସ୍ୱିଚ୍ କରିବେ ତାହା ଜାଣନ୍ତୁ।"</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"ଆପଣ \'ପଛକୁ ଫେରନ୍ତୁ\' ଜେଶ୍ଚର୍ ସମ୍ପୂର୍ଣ୍ଣ କରିଛନ୍ତି।"</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"ଆପଣ ସ୍କ୍ରିନର ତଳଭାଗର ଅତି ନିକଟରୁ ସ୍ୱାଇପ୍ କରୁନଥିବା ସୁନିଶ୍ଚିତ କରନ୍ତୁ।"</string>
- <string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"ପଛକୁ ଫେରିବା ଜେଶ୍ଚରର ସମ୍ବେଦନଶୀଳତା ବଦଳାଇବାକୁ ସେଟିଂସକୁ ଯାଆନ୍ତୁ"</string>
- <string name="back_gesture_intro_title" msgid="19551256430224428">"ପଛକୁ ଫେରିବା ପାଇଁ ସ୍ୱାଇପ୍ କରନ୍ତୁ"</string>
- <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"ପୂର୍ବବର୍ତ୍ତୀ ସ୍କ୍ରିନକୁ ଫେରିବା ପାଇଁ, ସ୍କ୍ରିନର ବାମ କିମ୍ବା ଡାହାଣ ଧାରରୁ ମଝିକୁ ସ୍ୱାଇପ୍ କରନ୍ତୁ।"</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"ଆପଣ ସ୍କ୍ରିନର ତଳ ଧାରରୁ ଉପରକୁ ସ୍ୱାଇପ୍ କରୁଥିବା ସୁନିଶ୍ଚିତ କରନ୍ତୁ।"</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"ଆପଣ ଛାଡ଼ିବା ପୂର୍ବରୁ ବିରତ କରୁନଥିବା ସୁନିଶ୍ଚିତ କରନ୍ତୁ।"</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"ଆପଣ ସିଧା ଉପରକୁ ସ୍ୱାଇପ୍ କରୁଥିବା ସୁନିଶ୍ଚିତ କରନ୍ତୁ।"</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"ଆପଣ \'ମୂଳପୃଷ୍ଠାକୁ ଯାଆନ୍ତୁ\' ଜେଶ୍ଚର୍ ସମ୍ପୂର୍ଣ୍ଣ କରିଛନ୍ତି। ତା\'ପରେ, ପଛକୁ କିପରି ଫେରିବେ ତାହା ଜାଣନ୍ତୁ।"</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"ଆପଣ \'ମୂଳପୃଷ୍ଠାକୁ ଯାଆନ୍ତୁ\' ଜେଶ୍ଚର୍ ସମ୍ପୂର୍ଣ୍ଣ କରିଛନ୍ତି।"</string>
- <string name="home_gesture_intro_title" msgid="836590312858441830">"ମୂଳପୃଷ୍ଠାକୁ ଯିବା ପାଇଁ ସ୍ୱାଇପ୍ କରନ୍ତୁ"</string>
- <string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"ଆପଣଙ୍କ ସ୍କ୍ରିନର ତଳୁ ଉପରକୁ ସ୍ୱାଇପ୍ କରନ୍ତୁ। ଏହି ଜେଶ୍ଚର୍ ସର୍ବଦା ଆପଣଙ୍କୁ ମୂଳସ୍କ୍ରିନକୁ ନେଇଥାଏ।"</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"ଆପଣ ସ୍କ୍ରିନର ତଳ ଧାରରୁ ଉପରକୁ ସ୍ୱାଇପ୍ କରୁଥିବା ସୁନିଶ୍ଚିତ କରନ୍ତୁ।"</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"ୱିଣ୍ଡୋକୁ ରିଲିଜ୍ କରିବା ପୂର୍ବରୁ ଅଧିକ ସମୟ ଧରି ରଖିବାକୁ ଚେଷ୍ଟା କରନ୍ତୁ।"</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"ଆପଣ ସିଧା ଉପରକୁ ସ୍ୱାଇପ୍ କରି ତା\'ପରେ ବିରତ କରୁଥିବା ସୁନିଶ୍ଚିତ କରନ୍ତୁ।"</string>
- <string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"ଜେଶ୍ଚରଗୁଡ଼ିକୁ କିପରି ବ୍ୟବହାର କରାଯିବ ଆପଣ ତାହା ଶିଖିଛନ୍ତି। ଜେଶ୍ଚରଗୁଡ଼ିକୁ ବନ୍ଦ କରିବାକୁ, ସେଟିଂସକୁ ଯାଆନ୍ତୁ।"</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"ଆପଣ \'ଆପଗୁଡ଼ିକୁ ସ୍ୱିଚ୍ କରନ୍ତୁ\' ଜେଶ୍ଚର୍ ସମ୍ପୂର୍ଣ୍ଣ କରିଛନ୍ତି।"</string>
- <string name="overview_gesture_intro_title" msgid="2902054412868489378">"ଆପଗୁଡ଼ିକୁ ସ୍ୱିଚ୍ କରିବା ପାଇଁ ସ୍ୱାଇପ୍ କରନ୍ତୁ"</string>
- <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"ଆପଗୁଡ଼ିକ ମଧ୍ୟରେ ସ୍ୱିଚ୍ କରିବାକୁ, ସ୍କ୍ରିନର ତଳୁ ଉପରକୁ ସ୍ୱାଇପ୍ କରନ୍ତୁ, ଧରି ରଖନ୍ତୁ, ତା\'ପରେ ରିଲିଜ୍ କରନ୍ତୁ।"</string>
- <string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"ସବୁ ପ୍ରସ୍ତୁତ"</string>
- <string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"ହୋଇଗଲା"</string>
- <string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"ସେଟିଂସ୍"</string>
- <string name="gesture_tutorial_try_again" msgid="65962545858556697">"ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ"</string>
- <string name="gesture_tutorial_nice" msgid="2936275692616928280">"ବଢ଼ିଆ!"</string>
- <string name="gesture_tutorial_step" msgid="1279786122817620968">"ଟ୍ୟୁଟୋରିଆଲ୍ <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
- <string name="allset_title" msgid="5021126669778966707">"ସମ୍ପୂର୍ଣ୍ଣ ଭାବେ ପ୍ରସ୍ତୁତ!"</string>
- <string name="allset_hint" msgid="2384632994739392447">"ମୂଳପୃଷ୍ଠାକୁ ଯିବା ପାଇଁ ଉପରକୁ ସ୍ୱାଇପ୍ କରନ୍ତୁ"</string>
- <string name="allset_description" msgid="6350320429953234580">"ଆପଣ ଆପଣଙ୍କ ଫୋନ୍ ବ୍ୟବହାର କରିବା ପାଇଁ ପ୍ରସ୍ତୁତ ଅଛନ୍ତି"</string>
- <string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"ସିଷ୍ଟମ୍ ନାଭିଗେସନ୍ ସେଟିଂସ୍"</annotation></string>
- <string name="action_share" msgid="2648470652637092375">"ସେୟାର୍ କରନ୍ତୁ"</string>
- <string name="action_screenshot" msgid="8171125848358142917">"ସ୍କ୍ରିନସଟ୍"</string>
- <string name="action_split" msgid="2098009717623550676">"ସ୍ପ୍ଲିଟ୍"</string>
- <string name="toast_split_select_app" msgid="5453865907322018352">"ସ୍ପ୍ଲିଟସ୍କ୍ରିନ ବ୍ୟବହାର କରିବାକୁ ଅନ୍ୟ ଏକ ଆପରେ ଟାପ କର"</string>
- <string name="toast_split_app_unsupported" msgid="3271526028981899666">"ସ୍ପ୍ଲିଟ-ସ୍କ୍ରିନକୁ ଆପ ସମର୍ଥନ କରେ ନାହିଁ।"</string>
- <string name="blocked_by_policy" msgid="2071401072261365546">"ଆପ୍ କିମ୍ବା ଆପଣଙ୍କ ସଂସ୍ଥା ଦ୍ୱାରା ଏହି କାର୍ଯ୍ୟକୁ ଅନୁମତି ଦିଆଯାଇ ନାହିଁ"</string>
- <string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"ନାଭିଗେସନ୍ ଟ୍ୟୁଟୋରିଆଲକୁ ବାଦ୍ ଦେବେ?"</string>
- <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"ଆପଣ ପରେ ଏହାକୁ <xliff:g id="NAME">%1$s</xliff:g> ଆପରେ ପାଇପାରିବେ"</string>
- <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"ବାତିଲ୍ କରନ୍ତୁ"</string>
- <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"ବାଦ୍ ଦିଅନ୍ତୁ"</string>
- <string name="accessibility_rotate_button" msgid="4771825231336502943">"ସ୍କ୍ରିନ ଘୂରାନ୍ତୁ"</string>
- <string name="taskbar_edu_opened" msgid="3950252793551919129">"ଟାସ୍କବାର୍ ଶିକ୍ଷା ଦେଖାଯାଇଛି"</string>
- <string name="taskbar_edu_closed" msgid="126643734478892862">"ଟାସ୍କବାର୍ ଶିକ୍ଷା ବନ୍ଦ ହୋଇଯାଇଛି"</string>
- <string name="taskbar_edu_switch_apps" msgid="6942863327845784813">"ଆପଗୁଡ଼ିକୁ ସ୍ୱିଚ କରିବା ପାଇଁ ଟାସ୍କବାର ବ୍ୟବହାର କରନ୍ତୁ"</string>
- <string name="taskbar_edu_splitscreen" msgid="2663361731630346489">"ଥରକେ ଦୁଇଟି ଆପ ବ୍ୟବହାର କରିବା ପାଇଁ ପାର୍ଶ୍ୱକୁ ଡ୍ରାଗ କରନ୍ତୁ"</string>
- <string name="taskbar_edu_stashing" msgid="5212374387411764031">"ଟାସ୍କବାରକୁ ଲୁଚାଇବା ପାଇଁ ସ୍ପର୍ଶ କରି ଧରି ରଖନ୍ତୁ"</string>
- <string name="taskbar_edu_next" msgid="4007618274426775841">"ପରବର୍ତ୍ତୀ"</string>
- <string name="taskbar_edu_previous" msgid="459202320127201702">"ପଛକୁ ଫେରନ୍ତୁ"</string>
- <string name="taskbar_edu_close" msgid="887022990168191073">"ବନ୍ଦ କରନ୍ତୁ"</string>
- <string name="taskbar_edu_done" msgid="6880178093977704569">"ହୋଇଗଲା"</string>
- <string name="taskbar_button_home" msgid="2151398979630664652">"ମୂଳପୃଷ୍ଠା"</string>
- <string name="taskbar_button_a11y" msgid="5241161324875094465">"ଆକ୍ସେସିବିଲିଟୀ"</string>
- <string name="taskbar_button_back" msgid="8558862226461164514">"ପଛକୁ ଫେରନ୍ତୁ"</string>
- <string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"IME ସ୍ୱିଚର"</string>
- <string name="taskbar_button_recents" msgid="7273376136216613134">"ବର୍ତ୍ତମାନର"</string>
- <!-- no translation found for taskbar_button_notifications (7471740351507357318) -->
- <skip />
- <!-- no translation found for taskbar_button_quick_settings (227662894293189391) -->
- <skip />
- <string name="move_drop_target_top_or_left" msgid="2988702185049595807">"ଶୀର୍ଷ/ବାମକୁ ମୁଭ କରନ୍ତୁ"</string>
- <string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"ନିମ୍ନ/ଡାହାଣକୁ ମୁଭ କରନ୍ତୁ"</string>
</resources>
diff --git a/quickstep/res/values-pa/strings.xml b/quickstep/res/values-pa/strings.xml
index 0173ee2f5e..58c0d2afa4 100644
--- a/quickstep/res/values-pa/strings.xml
+++ b/quickstep/res/values-pa/strings.xml
@@ -19,91 +19,19 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="recent_task_option_split_screen" msgid="5353188922202653570">"ਸਪਲਿਟ ਸਕ੍ਰੀਨ"</string>
<string name="recent_task_option_pin" msgid="7929860679018978258">"ਪਿੰਨ ਕਰੋ"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"ਫ੍ਰੀਫਾਰਮ"</string>
+ <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"ਰੂਪ-ਰੇਖਾ"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"ਕੋਈ ਹਾਲੀਆ ਆਈਟਮਾਂ ਨਹੀਂ"</string>
+ <string name="accessibility_close_task" msgid="5354563209433803643">"ਬੰਦ ਕਰੋ"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"ਐਪ ਵਰਤੋਂ ਦੀਆਂ ਸੈਟਿੰਗਾਂ"</string>
<string name="recents_clear_all" msgid="5328176793634888831">"ਸਭ ਕਲੀਅਰ ਕਰੋ"</string>
<string name="accessibility_recent_apps" msgid="4058661986695117371">"ਹਾਲੀਆ ਐਪਾਂ"</string>
- <string name="task_view_closed" msgid="9170038230110856166">"ਕਾਰਜ ਬੰਦ"</string>
<string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
<string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 ਮਿੰਟ"</string>
<string name="time_left_for_app" msgid="3111996412933644358">"ਅੱਜ <xliff:g id="TIME">%1$s</xliff:g> ਬਾਕੀ"</string>
- <string name="title_app_suggestions" msgid="4185902664111965088">"ਐਪ ਸੁਝਾਅ"</string>
+ <string name="title_app_suggestions" msgid="4185902664111965088">"ਐਪ ਸੰਬੰਧੀ ਸੁਝਾਅ"</string>
+ <string name="all_apps_label" msgid="8542784161730910663">"ਸਾਰੀਆਂ ਐਪਾਂ"</string>
<string name="all_apps_prediction_tip" msgid="2672336544844936186">"ਤੁਹਾਡੀਆਂ ਪੂਰਵ ਅਨੁਮਾਨਿਤ ਐਪਾਂ"</string>
- <string name="hotseat_edu_title_migrate" msgid="306578144424489980">"ਆਪਣੀ ਹੋਮ ਸਕ੍ਰੀਨ ਦੀ ਹੇਠਲੀ ਕਤਾਰ \'ਤੇ ਐਪ ਸੁਝਾਅ ਪ੍ਰਾਪਤ ਕਰੋ"</string>
- <string name="hotseat_edu_title_migrate_landscape" msgid="3633942953997845243">"ਆਪਣੀ ਹੋਮ ਸਕ੍ਰੀਨ ਦੀ ਮਨਪਸੰਦ ਕਤਾਰ \'ਤੇ ਐਪ ਸੁਝਾਅ ਹਾਸਲ ਕਰੋ"</string>
- <string name="hotseat_edu_message_migrate" msgid="8927179260533775320">"ਹੋਮ ਸਕ੍ਰੀਨ \'ਤੇ ਆਪਣੀਆਂ ਸਭ ਤੋਂ ਵੱਧ ਵਰਤੀਆਂ ਗਈਆਂ ਐਪਾਂ ਤੱਕ ਆਸਾਨੀ ਨਾਲ ਪਹੁੰਚ ਕਰੋ। ਸੁਝਾਅ ਤੁਹਾਡੇ ਨਿਯਮਬੱਧ ਕੰਮਾਂ ਦੇ ਆਧਾਰ \'ਤੇ ਬਦਲਣਗੇ। ਹੇਠਲੀ ਕਤਾਰ ਵਾਲੀਆਂ ਐਪਾਂ ਤੁਹਾਡੀ ਹੋਮ ਸਕ੍ਰੀਨ ਵੱਲ ਉੱਪਰ ਆ ਜਾਣਗੀਆਂ।"</string>
- <string name="hotseat_edu_message_migrate_landscape" msgid="4248943380443387697">"ਹੋਮ ਸਕ੍ਰੀਨ \'ਤੇ ਆਪਣੀਆਂ ਸਭ ਤੋਂ ਵੱਧ ਵਰਤੀਆਂ ਗਈਆਂ ਐਪਾਂ ਤੱਕ ਆਸਾਨੀ ਨਾਲ ਪਹੁੰਚ ਕਰੋ। ਸੁਝਾਅ ਤੁਹਾਡੇ ਨਿਯਮਬੱਧ ਕੰਮਾਂ ਦੇ ਆਧਾਰ \'ਤੇ ਬਦਲਣਗੇ। ਮਨਪਸੰਦ ਕਤਾਰ ਵਿਚਲੀਆਂ ਐਪਾਂ ਤੁਹਾਡੀ ਹੋਮ ਸਕ੍ਰੀਨ ਉੱਪਰ ਆ ਜਾਣਗੀਆਂ।"</string>
- <string name="hotseat_edu_message_migrate_alt" msgid="3042360119039646356">"ਹੋਮ ਸਕ੍ਰੀਨ \'ਤੇ ਆਪਣੀਆਂ ਸਭ ਤੋਂ ਵੱਧ ਵਰਤੀਆਂ ਗਈਆਂ ਐਪਾਂ ਤੱਕ ਆਸਾਨੀ ਨਾਲ ਪਹੁੰਚ ਕਰੋ। ਸੁਝਾਅ ਤੁਹਾਡੇ ਨਿਯਮਬੱਧ ਕੰਮਾਂ ਦੇ ਆਧਾਰ \'ਤੇ ਬਦਲਣਗੇ। ਹੇਠਲੀ ਕਤਾਰ ਵਾਲੀਆਂ ਐਪਾਂ ਇੱਕ ਨਵੇਂ ਫੋਲਡਰ ਵਿੱਚ ਚਲੀਆਂ ਜਾਣਗੀਆਂ।"</string>
- <string name="hotseat_edu_accept" msgid="1611544083278999837">"ਐਪ ਸੁਝਾਅ ਪ੍ਰਾਪਤ ਕਰੋ"</string>
- <string name="hotseat_edu_dismiss" msgid="2781161822780201689">"ਨਹੀਂ ਧੰਨਵਾਦ"</string>
- <string name="hotseat_prediction_settings" msgid="6246554993566070818">"ਸੈਟਿੰਗਾਂ"</string>
- <string name="hotseat_auto_enrolled" msgid="522100018967146807">"ਸਭ ਤੋਂ ਵੱਧ ਵਰਤੀਆਂ ਗਈਆਂ ਐਪਾਂ ਇੱਥੇ ਦਿਸਦੀਆਂ ਹਨ, ਅਤੇ ਨਿਯਮਬੱਧ ਕੰਮਾਂ ਦੇ ਆਧਾਰ \'ਤੇ ਬਦਲਦੀਆਂ ਹਨ"</string>
- <string name="hotseat_tip_no_empty_slots" msgid="1325212677738179185">"ਐਪ ਸੁਝਾਅ ਪ੍ਰਾਪਤ ਕਰਨ ਲਈ ਹੇਠਲੀ ਕਤਾਰ ਤੋਂ ਐਪਾਂ ਨੂੰ ਘਸੀਟੋ"</string>
- <string name="hotseat_tip_gaps_filled" msgid="3035673010274223538">"ਐਪ ਸੁਝਾਅ ਖਾਲੀ ਜਗ੍ਹਾ ਵਿੱਚ ਸ਼ਾਮਲ ਕੀਤੇ ਗਏ"</string>
- <string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"ਐਪ ਸੁਝਾਵਾਂ ਨੂੰ ਚਾਲੂ ਕੀਤਾ ਗਿਆ"</string>
- <string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"ਐਪ ਸੁਝਾਵਾਂ ਨੂੰ ਬੰਦ ਕੀਤਾ ਗਿਆ"</string>
- <string name="hotseat_prediction_content_description" msgid="4582028296938078419">"ਪੂਰਵ ਅਨੁਮਾਨਿਤ ਐਪ: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"ਇਹ ਪੱਕਾ ਕਰੋ ਕਿ ਤੁਸੀਂ ਸੱਜੇ ਜਾਂ ਖੱਬੇ ਪਾਸੇ ਦੇ ਬਿਲਕੁਲ ਕਿਨਾਰੇ ਤੋਂ ਸਵਾਈਪ ਕਰਦੇ ਹੋ।"</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"ਇਹ ਪੱਕਾ ਕਰੋ ਕਿ ਤੁਸੀਂ ਸੱਜੇ ਜਾਂ ਖੱਬੇ ਕਿਨਾਰੇ ਤੋਂ ਸਕ੍ਰੀਨ ਦੇ ਵਿਚਕਾਰ ਤੱਕ ਸਵਾਈਪ ਕਰਦੇ ਹੋ ਅਤੇ ਛੱਡ ਦਿੰਦੇ ਹੋ।"</string>
- <string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"ਤੁਸੀਂ ਪਿੱਛੇ ਜਾਣ ਲਈ ਸੱਜੇ ਪਾਸੇ ਤੋਂ ਸਵਾਈਪ ਕਰਨ ਦਾ ਤਰੀਕਾ ਜਾਣਿਆ। ਅੱਗੇ, ਐਪਾਂ ਵਿਚਾਲੇ ਅਦਲਾ-ਬਦਲੀ ਕਰਨ ਦਾ ਤਰੀਕਾ ਜਾਣੋ।"</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"ਤੁਸੀਂ \'ਵਾਪਸ ਜਾਓ\' ਦਾ ਇਸ਼ਾਰਾ ਪੂਰਾ ਕੀਤਾ।"</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"ਇਹ ਪੱਕਾ ਕਰੋ ਕਿ ਤੁਸੀਂ ਸਕ੍ਰੀਨ ਦੇ ਹੇਠਲੇ ਹਿੱਸੇ ਦੇ ਬਹੁਤ ਨੇੜੇ ਸਵਾਈਪ ਨਾ ਕਰੋ।"</string>
- <string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"ਪਿੱਛੇ ਜਾਣ ਦੇ ਸੰਕੇਤ ਦੀ ਸੰਵੇਦਨਸ਼ੀਲਤਾ ਬਦਲਣ ਲਈ, ਸੈਟਿੰਗਾਂ \'ਤੇ ਜਾਓ"</string>
- <string name="back_gesture_intro_title" msgid="19551256430224428">"ਪਿੱਛੇ ਜਾਣ ਲਈ ਸਵਾਈਪ ਕਰੋ"</string>
- <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"ਪਿਛਲੀ ਸਕ੍ਰੀਨ \'ਤੇ ਵਾਪਸ ਜਾਣ ਲਈ, ਖੱਬੇ ਜਾਂ ਸੱਜੇ ਕਿਨਾਰੇ ਤੋਂ ਸਕ੍ਰੀਨ ਦੇ ਵਿਚਕਾਰ ਤੱਕ ਸਵਾਈਪ ਕਰੋ।"</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"ਇਹ ਪੱਕਾ ਕਰੋ ਕਿ ਤੁਸੀਂ ਸਕ੍ਰੀਨ ਦੇ ਹੇਠਲੇ ਕਿਨਾਰੇ ਤੋਂ ਉੱਪਰ ਵੱਲ ਸਵਾਈਪ ਕਰਦੇ ਹੋ।"</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"ਪੱਕਾ ਕਰੋ ਕਿ ਸਕ੍ਰੀਨ ਨੂੰ ਛੱਡਣ ਤੋਂ ਪਹਿਲਾਂ ਰੁਕੋ ਨਾ।"</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"ਇਹ ਪੱਕਾ ਕਰੋ ਕਿ ਤੁਸੀਂ ਸਿੱਧੇ ਉੱਪਰ ਵੱਲ ਸਵਾਈਪ ਕਰਦੇ ਹੋ।"</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"ਤੁਸੀਂ \'ਹੋਮ \'ਤੇ ਜਾਓ\' ਦਾ ਇਸ਼ਾਰਾ ਪੂਰਾ ਕੀਤਾ। ਅੱਗੇ, ਜਾਣੋ ਕਿ ਪਿੱਛੇ ਕਿਵੇਂ ਜਾਣਾ ਹੈ।"</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"ਤੁਸੀਂ \'ਹੋਮ \'ਤੇ ਜਾਓ\' ਦਾ ਇਸ਼ਾਰਾ ਪੂਰਾ ਕੀਤਾ।"</string>
- <string name="home_gesture_intro_title" msgid="836590312858441830">"ਹੋਮ \'ਤੇ ਜਾਣ ਲਈ ਸਵਾਈਪ ਕਰੋ"</string>
- <string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"ਆਪਣੀ ਸਕ੍ਰੀਨ ਦੇ ਹੇਠਾਂ ਤੋਂ ਉੱਪਰ ਵੱਲ ਸਵਾਈਪ ਕਰੋ। ਇਹ ਇਸ਼ਾਰਾ ਹਮੇਸ਼ਾਂ ਤੁਹਾਨੂੰ ਹੋਮ ਸਕ੍ਰੀਨ \'ਤੇ ਲੈ ਜਾਂਦਾ ਹੈ।"</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"ਇਹ ਪੱਕਾ ਕਰੋ ਕਿ ਤੁਸੀਂ ਸਕ੍ਰੀਨ ਦੇ ਹੇਠਲੇ ਕਿਨਾਰੇ ਤੋਂ ਉੱਪਰ ਵੱਲ ਸਵਾਈਪ ਕਰਦੇ ਹੋ।"</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"ਛੱਡਣ ਤੋਂ ਪਹਿਲਾਂ ਵਿੰਡੋ ਨੂੰ ਕੁਝ ਸਮੇਂ ਲਈ ਦਬਾ ਕੇ ਰੱਖੋ।"</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"ਇਹ ਪੱਕਾ ਕਰੋ ਕਿ ਤੁਸੀਂ ਸਿੱਧੇ ਉੱਪਰ ਵੱਲ ਸਵਾਈਪ ਕਰਦੇ ਹੋ, ਫਿਰ ਰੋਕੋ।"</string>
- <string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"ਤੁਸੀਂ ਇਸ਼ਾਰੇ ਵਰਤਣ ਬਾਰੇ ਜਾਣਿਆ। ਇਸ਼ਾਰੇ ਬੰਦ ਕਰਨ ਲਈ, ਸੈਟਿੰਗਾਂ \'ਤੇ ਜਾਓ।"</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"ਤੁਸੀਂ \'ਐਪਾਂ ਵਿਚਾਲੇ ਅਦਲਾ-ਬਦਲੀ ਕਰੋ\' ਦਾ ਇਸ਼ਾਰਾ ਪੂਰਾ ਕੀਤਾ।"</string>
- <string name="overview_gesture_intro_title" msgid="2902054412868489378">"ਐਪਾਂ ਵਿਚਾਲੇ ਅਦਲਾ-ਬਦਲੀ ਕਰਨ ਲਈ ਸਵਾਈਪ ਕਰੋ"</string>
- <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"ਐਪਾਂ ਵਿਚਾਲੇ ਅਦਲਾ-ਬਦਲੀ ਕਰਨ ਲਈ, ਆਪਣੀ ਸਕ੍ਰੀਨ ਦੇ ਹੇਠਾਂ ਤੋਂ ਉੱਪਰ ਵੱਲ ਸਵਾਈਪ ਕਰਕੇ ਦਬਾਈ ਰੱਖੋ ਅਤੇ ਫਿਰ ਛੱਡੋ।"</string>
- <string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"ਪੂਰੀ ਤਰ੍ਹਾਂ ਤਿਆਰ"</string>
- <string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"ਹੋ ਗਿਆ"</string>
- <string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"ਸੈਟਿੰਗਾਂ"</string>
- <string name="gesture_tutorial_try_again" msgid="65962545858556697">"ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ"</string>
- <string name="gesture_tutorial_nice" msgid="2936275692616928280">"ਵਧੀਆ!"</string>
- <string name="gesture_tutorial_step" msgid="1279786122817620968">"ਟਿਊਟੋਰੀਅਲ <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
- <string name="allset_title" msgid="5021126669778966707">"ਪੂਰੀ ਤਰ੍ਹਾਂ ਤਿਆਰ!"</string>
- <string name="allset_hint" msgid="2384632994739392447">"ਹੋਮ \'ਤੇ ਜਾਣ ਲਈ ਉੱਪਰ ਵੱਲ ਸਵਾਈਪ ਕਰੋ"</string>
- <string name="allset_description" msgid="6350320429953234580">"ਤੁਸੀਂ ਆਪਣਾ ਫ਼ੋਨ ਵਰਤਣ ਲਈ ਤਿਆਰ ਹੋ"</string>
- <string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"ਸਿਸਟਮ ਨੈਵੀਗੇਸ਼ਨ ਸੈਟਿੰਗਾਂ"</annotation></string>
- <string name="action_share" msgid="2648470652637092375">"ਸਾਂਝਾ ਕਰੋ"</string>
- <string name="action_screenshot" msgid="8171125848358142917">"ਸਕ੍ਰੀਨਸ਼ਾਟ"</string>
- <string name="action_split" msgid="2098009717623550676">"ਸਪਲਿਟ"</string>
- <string name="toast_split_select_app" msgid="5453865907322018352">"ਸਪਲਿਟ ਸਕ੍ਰੀਨ ਵਰਤਣ ਲਈ ਕਿਸੇ ਹੋਰ ਐਪ \'ਤੇ ਟੈਪ ਕਰੋ"</string>
- <string name="toast_split_app_unsupported" msgid="3271526028981899666">"ਐਪ ਸਪਲਿਟ-ਸਕ੍ਰੀਨ ਦਾ ਸਮਰਥਨ ਨਹੀਂ ਕਰਦੀ।"</string>
- <string name="blocked_by_policy" msgid="2071401072261365546">"ਐਪ ਜਾਂ ਤੁਹਾਡੀ ਸੰਸਥਾ ਵੱਲੋਂ ਇਸ ਕਾਰਵਾਈ ਦੀ ਇਜਾਜ਼ਤ ਨਹੀਂ ਹੈ"</string>
- <string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"ਕੀ ਨੈਵੀਗੇਸ਼ਨ ਟਿਊਟੋਰੀਅਲ ਨੂੰ ਛੱਡਣਾ ਹੈ?"</string>
- <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"ਤੁਸੀਂ ਇਸਨੂੰ ਬਾਅਦ ਵਿੱਚ <xliff:g id="NAME">%1$s</xliff:g> ਐਪ ਵਿੱਚ ਲੱਭ ਸਕਦੇ ਹੋ"</string>
- <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"ਰੱਦ ਕਰੋ"</string>
- <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"ਛੱਡੋ"</string>
- <string name="accessibility_rotate_button" msgid="4771825231336502943">"ਸਕ੍ਰੀਨ ਘੁਮਾਓ"</string>
- <string name="taskbar_edu_opened" msgid="3950252793551919129">"ਟਾਸਕਵਾਰ ਸਿੱਖਿਆ ਪੈਨਲ ਦਿਖਾਇਆ ਗਿਆ"</string>
- <string name="taskbar_edu_closed" msgid="126643734478892862">"ਟਾਸਕਵਾਰ ਸਿੱਖਿਆ ਪੈਨਲ ਬੰਦ ਕੀਤਾ ਗਿਆ"</string>
- <string name="taskbar_edu_switch_apps" msgid="6942863327845784813">"ਐਪਾਂ ਸਵਿੱਚ ਕਰਨ ਲਈ ਟਾਸਕਬਾਰ ਵਰਤੋ"</string>
- <string name="taskbar_edu_splitscreen" msgid="2663361731630346489">"ਇੱਕ ਵਾਰ ਵਿੱਚ ਦੋ ਐਪਾਂ ਵਰਤਣ ਲਈ ਉਨ੍ਹਾਂ ਨੂੰ ਸਾਈਡ ਵੱਲ ਘਸੀਟੋ"</string>
- <string name="taskbar_edu_stashing" msgid="5212374387411764031">"ਟਾਸਕਬਾਰ ਨੂੰ ਲੁਕਾਉਣ ਲਈ ਸਪਰਸ਼ ਕਰਕੇ ਰੱਖੋ"</string>
- <string name="taskbar_edu_next" msgid="4007618274426775841">"ਅੱਗੇ"</string>
- <string name="taskbar_edu_previous" msgid="459202320127201702">"ਪਿੱਛੇ"</string>
- <string name="taskbar_edu_close" msgid="887022990168191073">"ਬੰਦ ਕਰੋ"</string>
- <string name="taskbar_edu_done" msgid="6880178093977704569">"ਹੋ ਗਿਆ"</string>
- <string name="taskbar_button_home" msgid="2151398979630664652">"ਘਰ"</string>
- <string name="taskbar_button_a11y" msgid="5241161324875094465">"ਪਹੁੰਚਯੋਗਤਾ"</string>
- <string name="taskbar_button_back" msgid="8558862226461164514">"ਪਿੱਛੇ"</string>
- <string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"IME ਸਵਿੱਚਰ"</string>
- <string name="taskbar_button_recents" msgid="7273376136216613134">"ਹਾਲੀਆ"</string>
- <string name="taskbar_button_notifications" msgid="7471740351507357318">"ਸੂਚਨਾਵਾਂ"</string>
- <string name="taskbar_button_quick_settings" msgid="227662894293189391">"ਤਤਕਾਲ ਸੈਟਿੰਗਾਂ"</string>
- <string name="move_drop_target_top_or_left" msgid="2988702185049595807">"ਸਿਖਰਲੇ/ਖੱਬੇ ਪਾਸੇ ਲੈ ਕੇ ਜਾਓ"</string>
- <string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"ਹੇਠਾਂ/ਸੱਜੇ ਪਾਸੇ ਲੈ ਕੇ ਜਾਓ"</string>
</resources>
diff --git a/quickstep/res/values-pl/strings.xml b/quickstep/res/values-pl/strings.xml
index 19b666a704..d83160dffb 100644
--- a/quickstep/res/values-pl/strings.xml
+++ b/quickstep/res/values-pl/strings.xml
@@ -19,91 +19,19 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Podziel ekran"</string>
<string name="recent_task_option_pin" msgid="7929860679018978258">"Przypnij"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Tryb dowolny"</string>
+ <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Przegląd"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"Brak ostatnich elementów"</string>
+ <string name="accessibility_close_task" msgid="5354563209433803643">"Zamknij"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Ustawienia użycia aplikacji"</string>
<string name="recents_clear_all" msgid="5328176793634888831">"Wyczyść wszystko"</string>
<string name="accessibility_recent_apps" msgid="4058661986695117371">"Ostatnie aplikacje"</string>
- <string name="task_view_closed" msgid="9170038230110856166">"Zadanie zamknięte"</string>
<string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
<string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&gt; 1 min"</string>
<string name="time_left_for_app" msgid="3111996412933644358">"Na dziś zostało <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <string name="title_app_suggestions" msgid="4185902664111965088">"Sugestie aplikacji"</string>
+ <string name="title_app_suggestions" msgid="4185902664111965088">"Sugerowane aplikacje"</string>
+ <string name="all_apps_label" msgid="8542784161730910663">"Wszystkie aplikacje"</string>
<string name="all_apps_prediction_tip" msgid="2672336544844936186">"Przewidywane aplikacje"</string>
- <string name="hotseat_edu_title_migrate" msgid="306578144424489980">"Otrzymuj sugestie aplikacji w dolnym wierszu ekranu głównego"</string>
- <string name="hotseat_edu_title_migrate_landscape" msgid="3633942953997845243">"Otrzymuj sugestie aplikacji w wierszu ulubionych na ekranie głównym"</string>
- <string name="hotseat_edu_message_migrate" msgid="8927179260533775320">"Łatwo uruchamiaj najczęściej używane aplikacje z ekranu głównego. Sugestie będą zmieniać się w zależności od Twoich nawyków. Aplikacje z dolnych wierszy będą przesuwane w górę, do ekranu głównego."</string>
- <string name="hotseat_edu_message_migrate_landscape" msgid="4248943380443387697">"Zyskaj łatwy dostęp do najczęściej używanych aplikacji na ekranie głównym. Sugestie będą się zmieniać na podstawie Twojej rutyny. Aplikacje z wiersza ulubionych zostaną przeniesione na ekran główny."</string>
- <string name="hotseat_edu_message_migrate_alt" msgid="3042360119039646356">"Korzystaj z najczęściej używanych aplikacji na ekranie głównym w łatwy sposób. Sugestie będą się zmieniać na podstawie Twojej rutyny. Aplikacje z dolnych wierszy będą się przenosić do nowego folderu."</string>
- <string name="hotseat_edu_accept" msgid="1611544083278999837">"Otrzymuj sugestie aplikacji"</string>
- <string name="hotseat_edu_dismiss" msgid="2781161822780201689">"Nie, dziękuję"</string>
- <string name="hotseat_prediction_settings" msgid="6246554993566070818">"Ustawienia"</string>
- <string name="hotseat_auto_enrolled" msgid="522100018967146807">"Najczęściej używane aplikacje wyświetlają się tutaj i zmieniają się w zależności od rutyny"</string>
- <string name="hotseat_tip_no_empty_slots" msgid="1325212677738179185">"Przeciągnij aplikacje z dolnego wiersza, aby otrzymać sugestie aplikacji"</string>
- <string name="hotseat_tip_gaps_filled" msgid="3035673010274223538">"Sugestie aplikacji dodane w pustym obszarze"</string>
- <string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Włączono sugestie aplikacji"</string>
- <string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Sugestie aplikacji są wyłączone"</string>
- <string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Przewidywana aplikacja: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Pamiętaj, aby przesuwać palcem od samej prawej lub lewej krawędzi."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Pamiętaj, aby przesuwać palcem od prawej lub lewej krawędzi do środka ekranu i podnieść palec."</string>
- <string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Wiesz już, jak przesuwać palcem, aby przejść wstecz. Poćwicz teraz przełączanie aplikacji."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"Gest przejścia wstecz został opanowany."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Pamiętaj, aby nie przesuwać palcem zbyt blisko dolnej części ekranu."</string>
- <string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"Czułość gestu cofania możesz zmienić w Ustawieniach"</string>
- <string name="back_gesture_intro_title" msgid="19551256430224428">"Przesuń palcem, aby przejść wstecz"</string>
- <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"Aby wrócić do ostatniego ekranu, przesuń palcem od lewej lub prawej krawędzi do środka ekranu."</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Pamiętaj, aby przesuwać palcem od dolnej krawędzi ekranu."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Pamiętaj, aby przed podniesieniem palca nie było przerwy."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Pamiętaj, aby przesuwać palcem prosto do góry."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"Potrafisz już przejść na ekran główny. Poćwicz teraz powrót do wcześniejszego ekranu."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"Gest przechodzenia na ekran główny został opanowany."</string>
- <string name="home_gesture_intro_title" msgid="836590312858441830">"Przesuń palcem, aby przejść na ekran główny"</string>
- <string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Przesuń palcem z dołu ekranu. Ten gest zawsze powoduje przejście na ekran główny."</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Pamiętaj, aby przesuwać palcem od dolnej krawędzi ekranu."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Przytrzymaj okno dłużej, zanim podniesiesz palec."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Pamiętaj, aby przesuwać palcem prosto do góry, a potem przerwać ruch."</string>
- <string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Wiesz już, jak używać gestów. Aby wyłączyć gesty, przejdź do Ustawień."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"Gest przełączania aplikacji został opanowany."</string>
- <string name="overview_gesture_intro_title" msgid="2902054412868489378">"Przesuń palcem, aby przełączać aplikacje"</string>
- <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Aby przełączać się między aplikacjami, przesuń palcem od dołu ekranu, przytrzymaj i puść."</string>
- <string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"Wszystko gotowe"</string>
- <string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Gotowe"</string>
- <string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Ustawienia"</string>
- <string name="gesture_tutorial_try_again" msgid="65962545858556697">"Spróbuj ponownie"</string>
- <string name="gesture_tutorial_nice" msgid="2936275692616928280">"Super!"</string>
- <string name="gesture_tutorial_step" msgid="1279786122817620968">"Samouczek <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
- <string name="allset_title" msgid="5021126669778966707">"Wszystko gotowe"</string>
- <string name="allset_hint" msgid="2384632994739392447">"Aby przejść na stronę główną, przesuń palcem w górę"</string>
- <string name="allset_description" msgid="6350320429953234580">"Teraz możesz zacząć używać telefonu"</string>
- <string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"Ustawienia nawigacji w systemie"</annotation></string>
- <string name="action_share" msgid="2648470652637092375">"Udostępnij"</string>
- <string name="action_screenshot" msgid="8171125848358142917">"Zrzut ekranu"</string>
- <string name="action_split" msgid="2098009717623550676">"Podziel"</string>
- <string name="toast_split_select_app" msgid="5453865907322018352">"Kliknij drugą aplikację, aby podzielić ekran"</string>
- <string name="toast_split_app_unsupported" msgid="3271526028981899666">"Aplikacja nie obsługuje podzielonego ekranu."</string>
- <string name="blocked_by_policy" msgid="2071401072261365546">"Nie możesz wykonać tego działania, bo nie zezwala na to aplikacja lub Twoja organizacja"</string>
- <string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Pominąć samouczek nawigacji?"</string>
- <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Znajdziesz to później w aplikacji <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Anuluj"</string>
- <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Pomiń"</string>
- <string name="accessibility_rotate_button" msgid="4771825231336502943">"Obróć ekran"</string>
- <string name="taskbar_edu_opened" msgid="3950252793551919129">"Wskazówki na temat paska zadań zostały wyświetlone"</string>
- <string name="taskbar_edu_closed" msgid="126643734478892862">"Wskazówki na temat paska zadań zostały zamknięte"</string>
- <string name="taskbar_edu_switch_apps" msgid="6942863327845784813">"Używaj paska zadań, aby przełączać aplikacje"</string>
- <string name="taskbar_edu_splitscreen" msgid="2663361731630346489">"Przeciągnij w bok, aby używać 2 aplikacji jednocześnie"</string>
- <string name="taskbar_edu_stashing" msgid="5212374387411764031">"Naciśnij i przytrzymaj, aby ukryć pasek zadań"</string>
- <string name="taskbar_edu_next" msgid="4007618274426775841">"Dalej"</string>
- <string name="taskbar_edu_previous" msgid="459202320127201702">"Wstecz"</string>
- <string name="taskbar_edu_close" msgid="887022990168191073">"Zamknij"</string>
- <string name="taskbar_edu_done" msgid="6880178093977704569">"Gotowe"</string>
- <string name="taskbar_button_home" msgid="2151398979630664652">"Ekran główny"</string>
- <string name="taskbar_button_a11y" msgid="5241161324875094465">"Ułatwienia dostępu"</string>
- <string name="taskbar_button_back" msgid="8558862226461164514">"Wstecz"</string>
- <string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"Przełącznik IME"</string>
- <string name="taskbar_button_recents" msgid="7273376136216613134">"Ostatnie"</string>
- <string name="taskbar_button_notifications" msgid="7471740351507357318">"Powiadomienia"</string>
- <string name="taskbar_button_quick_settings" msgid="227662894293189391">"Szybkie ustawienia"</string>
- <string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Przesuń w górny lewy róg"</string>
- <string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Przesuń w dolny prawy róg"</string>
</resources>
diff --git a/quickstep/res/values-pt-rPT/strings.xml b/quickstep/res/values-pt-rPT/strings.xml
index 4e7b7a6351..2fd34d636c 100644
--- a/quickstep/res/values-pt-rPT/strings.xml
+++ b/quickstep/res/values-pt-rPT/strings.xml
@@ -19,91 +19,19 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Ecrã dividido"</string>
<string name="recent_task_option_pin" msgid="7929860679018978258">"Fixar"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Forma livre"</string>
+ <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Vista geral"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"Nenhum item recente"</string>
+ <string name="accessibility_close_task" msgid="5354563209433803643">"Fechar"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Definições de utilização de aplicações"</string>
<string name="recents_clear_all" msgid="5328176793634888831">"Limpar tudo"</string>
- <string name="accessibility_recent_apps" msgid="4058661986695117371">"Apps recentes"</string>
- <string name="task_view_closed" msgid="9170038230110856166">"Tarefa fechada"</string>
+ <string name="accessibility_recent_apps" msgid="4058661986695117371">"Aplicações recentes"</string>
<string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
<string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 minuto"</string>
<string name="time_left_for_app" msgid="3111996412933644358">"Resta(m) <xliff:g id="TIME">%1$s</xliff:g> hoje."</string>
- <string name="title_app_suggestions" msgid="4185902664111965088">"Sugestões de apps"</string>
- <string name="all_apps_prediction_tip" msgid="2672336544844936186">"As suas apps previstas"</string>
- <string name="hotseat_edu_title_migrate" msgid="306578144424489980">"Obtenha sugestões de apps na última fila do ecrã principal"</string>
- <string name="hotseat_edu_title_migrate_landscape" msgid="3633942953997845243">"Obtenha sugestões de apps na fila dos favoritos do ecrã principal"</string>
- <string name="hotseat_edu_message_migrate" msgid="8927179260533775320">"Aceda facilmente às suas apps mais utilizadas, diretamente no ecrã principal. As sugestões mudam em função das suas rotinas. As apps na última fila passam para o ecrã principal."</string>
- <string name="hotseat_edu_message_migrate_landscape" msgid="4248943380443387697">"Aceda facilmente às suas apps mais utilizadas no ecrã principal. As sugestões mudam em função das suas rotinas. As apps na fila dos favoritos passam para o ecrã principal."</string>
- <string name="hotseat_edu_message_migrate_alt" msgid="3042360119039646356">"Aceda facilmente às suas apps mais utilizadas, diretamente no ecrã principal. As sugestões mudam em função das suas rotinas. As apps na última fila passam para uma nova pasta."</string>
- <string name="hotseat_edu_accept" msgid="1611544083278999837">"Obter sugestões de apps"</string>
- <string name="hotseat_edu_dismiss" msgid="2781161822780201689">"Não, obrigado"</string>
- <string name="hotseat_prediction_settings" msgid="6246554993566070818">"Definições"</string>
- <string name="hotseat_auto_enrolled" msgid="522100018967146807">"As apps mais utilizadas aparecem aqui e mudam em função das rotinas."</string>
- <string name="hotseat_tip_no_empty_slots" msgid="1325212677738179185">"Arraste as apps para fora da última fila para obter sugestões de apps."</string>
- <string name="hotseat_tip_gaps_filled" msgid="3035673010274223538">"Sugestões de apps adicionadas a um espaço vazio."</string>
- <string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Sugestões de apps ativadas"</string>
- <string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"As sugestões de apps estão desativadas"</string>
- <string name="hotseat_prediction_content_description" msgid="4582028296938078419">"App prevista: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Deslize rapidamente a partir da extremidade mais à direita ou mais à esquerda."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Deslize rapidamente a partir da extremidade esquerda ou direita até ao centro do ecrã e solte."</string>
- <string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Aprendeu a deslizar a partir da direita para retroceder. A seguir, saiba como alternar entre apps."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"Concluiu o gesto para retroceder."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Garanta que não desliza rapidamente com o dedo demasiado perto da parte inferior do ecrã."</string>
- <string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"Altere a sensibilidade do gesto para voltar nas Definições."</string>
- <string name="back_gesture_intro_title" msgid="19551256430224428">"Deslize rapidamente com o dedo para retroceder"</string>
- <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"Para voltar ao último ecrã, deslize rapidamente do limite esquerdo ou direito até ao centro do ecrã."</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Garanta que desliza rapidamente com o dedo a partir do limite inferior do ecrã."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Garanta que não faz uma pausa antes de soltar."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Garanta que desliza rapidamente com o dedo para cima."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"Concluiu o gesto para aceder ao ecrã principal. A seguir, saiba como retroceder."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"Concluiu o gesto para aceder ao ecrã principal."</string>
- <string name="home_gesture_intro_title" msgid="836590312858441830">"Deslize rapidamente com o dedo para aceder ao ecrã principal"</string>
- <string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Deslize rapidamente para cima a partir da parte inferior. Este gesto abre sempre o ecrã principal."</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Deslize rapidamente com o dedo a partir do limite inferior do ecrã."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Experimente premir a janela durante mais tempo antes de soltar."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Garanta que desliza rapidamente com o dedo para cima e, em seguida, faz uma pausa."</string>
- <string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Aprendeu a utilizar gestos. Para desativar os gestos, aceda às Definições."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"Concluiu o gesto para alternar entre apps."</string>
- <string name="overview_gesture_intro_title" msgid="2902054412868489378">"Deslize rapidamente com o dedo para alternar entre apps"</string>
- <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Para alternar entre apps, deslize para cima sem soltar a partir da parte inferior do ecrã e solte."</string>
- <string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"Está tudo pronto"</string>
- <string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Concluído"</string>
- <string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Definições"</string>
- <string name="gesture_tutorial_try_again" msgid="65962545858556697">"Tente novamente"</string>
- <string name="gesture_tutorial_nice" msgid="2936275692616928280">"Boa!"</string>
- <string name="gesture_tutorial_step" msgid="1279786122817620968">"Tutorial <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
- <string name="allset_title" msgid="5021126669778966707">"Tudo pronto!"</string>
- <string name="allset_hint" msgid="2384632994739392447">"Deslize rapidamente para cima para aceder ao ecrã principal"</string>
- <string name="allset_description" msgid="6350320429953234580">"Já pode começar a utilizar o seu telemóvel"</string>
- <string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"Definições de navegação do sistema"</annotation></string>
- <string name="action_share" msgid="2648470652637092375">"Partilhar"</string>
- <string name="action_screenshot" msgid="8171125848358142917">"Fazer captura de ecrã"</string>
- <string name="action_split" msgid="2098009717623550676">"Dividir"</string>
- <string name="toast_split_select_app" msgid="5453865907322018352">"Toque noutra app para utilizar o ecrã dividido"</string>
- <string name="toast_split_app_unsupported" msgid="3271526028981899666">"A app não é compatível com o ecrã dividido."</string>
- <string name="blocked_by_policy" msgid="2071401072261365546">"Esta ação não é permitida pela app ou a sua entidade."</string>
- <string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Ignorar o tutorial de navegação?"</string>
- <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Pode encontrar isto mais tarde na app <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Cancelar"</string>
- <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Ignorar"</string>
- <string name="accessibility_rotate_button" msgid="4771825231336502943">"Rodar ecrã"</string>
- <string name="taskbar_edu_opened" msgid="3950252793551919129">"Informação da barra de tarefas apresentada"</string>
- <string name="taskbar_edu_closed" msgid="126643734478892862">"Informação da barra de tarefas fechada"</string>
- <string name="taskbar_edu_switch_apps" msgid="6942863327845784813">"Utilize a barra de ferramentas para alternar entre apps"</string>
- <string name="taskbar_edu_splitscreen" msgid="2663361731630346489">"Arraste para o lado para utilizar duas apps em simultâneo"</string>
- <string name="taskbar_edu_stashing" msgid="5212374387411764031">"Toque sem soltar para ocultar a barra de tarefas"</string>
- <string name="taskbar_edu_next" msgid="4007618274426775841">"Seguinte"</string>
- <string name="taskbar_edu_previous" msgid="459202320127201702">"Anterior"</string>
- <string name="taskbar_edu_close" msgid="887022990168191073">"Fechar"</string>
- <string name="taskbar_edu_done" msgid="6880178093977704569">"Concluir"</string>
- <string name="taskbar_button_home" msgid="2151398979630664652">"Início"</string>
- <string name="taskbar_button_a11y" msgid="5241161324875094465">"Acessibilidade"</string>
- <string name="taskbar_button_back" msgid="8558862226461164514">"Voltar"</string>
- <string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"Comutador IME"</string>
- <string name="taskbar_button_recents" msgid="7273376136216613134">"Recentes"</string>
- <string name="taskbar_button_notifications" msgid="7471740351507357318">"Notificações"</string>
- <string name="taskbar_button_quick_settings" msgid="227662894293189391">"Definiç. rápidas"</string>
- <string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Mover para a parte superior esquerda"</string>
- <string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Mover para a part superior direita"</string>
+ <string name="title_app_suggestions" msgid="4185902664111965088">"Sugestões de aplicações"</string>
+ <string name="all_apps_label" msgid="8542784161730910663">"Todas as aplicações"</string>
+ <string name="all_apps_prediction_tip" msgid="2672336544844936186">"As suas aplicações previstas"</string>
</resources>
diff --git a/quickstep/res/values-pt/strings.xml b/quickstep/res/values-pt/strings.xml
index d4a56acb20..673dfe2e73 100644
--- a/quickstep/res/values-pt/strings.xml
+++ b/quickstep/res/values-pt/strings.xml
@@ -19,91 +19,19 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Tela dividida"</string>
<string name="recent_task_option_pin" msgid="7929860679018978258">"Fixar"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Forma livre"</string>
+ <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Visão geral"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"Nenhum item recente"</string>
+ <string name="accessibility_close_task" msgid="5354563209433803643">"Fechar"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Configurações de uso do app"</string>
<string name="recents_clear_all" msgid="5328176793634888831">"Limpar tudo"</string>
<string name="accessibility_recent_apps" msgid="4058661986695117371">"Apps recentes"</string>
- <string name="task_view_closed" msgid="9170038230110856166">"Tarefa encerrada"</string>
<string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
<string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 min"</string>
<string name="time_left_for_app" msgid="3111996412933644358">"<xliff:g id="TIME">%1$s</xliff:g> restante(s) hoje"</string>
<string name="title_app_suggestions" msgid="4185902664111965088">"Sugestões de apps"</string>
+ <string name="all_apps_label" msgid="8542784161730910663">"Todos os apps"</string>
<string name="all_apps_prediction_tip" msgid="2672336544844936186">"Suas predições de apps"</string>
- <string name="hotseat_edu_title_migrate" msgid="306578144424489980">"Receba sugestões de apps na linha inferior da tela inicial"</string>
- <string name="hotseat_edu_title_migrate_landscape" msgid="3633942953997845243">"Receba sugestões de apps na linha \"Favoritos\" da tela inicial"</string>
- <string name="hotseat_edu_message_migrate" msgid="8927179260533775320">"Acesse diretamente na tela inicial os apps que você mais usa. As sugestões mudarão de acordo com sua rotina. Os apps na linha inferior serão movidos para a tela inicial."</string>
- <string name="hotseat_edu_message_migrate_landscape" msgid="4248943380443387697">"Acesse os apps mais usados na tela inicial de forma simples. As sugestões mudarão de acordo com sua rotina. Os apps na linha \"Favoritos\" serão movidos para a tela inicial."</string>
- <string name="hotseat_edu_message_migrate_alt" msgid="3042360119039646356">"Acesse diretamente na tela inicial os apps que você mais usa. As sugestões mudarão de acordo com sua rotina. Os apps na linha inferior serão movidos para uma nova pasta."</string>
- <string name="hotseat_edu_accept" msgid="1611544083278999837">"Receber sugestões de apps"</string>
- <string name="hotseat_edu_dismiss" msgid="2781161822780201689">"Não"</string>
- <string name="hotseat_prediction_settings" msgid="6246554993566070818">"Configurações"</string>
- <string name="hotseat_auto_enrolled" msgid="522100018967146807">"Os apps mais usados aparecem aqui e mudam de acordo com sua rotina"</string>
- <string name="hotseat_tip_no_empty_slots" msgid="1325212677738179185">"Arraste apps da linha inferior para receber sugestões de apps"</string>
- <string name="hotseat_tip_gaps_filled" msgid="3035673010274223538">"Sugestões de apps adicionadas a um espaço vazio"</string>
- <string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"O recurso \"sugestões de apps\" está ativado"</string>
- <string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"O recurso \"sugestões de apps\" está desativado"</string>
- <string name="hotseat_prediction_content_description" msgid="4582028296938078419">"App previsto: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Deslize da borda direita ou esquerda."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Deslize da borda direita ou esquerda até o meio da tela e solte."</string>
- <string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Você aprendeu a deslizar da direita para voltar. A seguir, aprenda a trocar de app."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"Você concluiu o gesto para voltar."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Não deslize perto demais da parte inferior da tela."</string>
- <string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"Mude a sensibilidade do gesto de voltar nas configurações"</string>
- <string name="back_gesture_intro_title" msgid="19551256430224428">"Deslize para voltar"</string>
- <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"Para voltar à tela anterior, deslize da borda esquerda ou direita até o meio da tela."</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Deslize da borda inferior da tela para cima."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Não pare antes de soltar."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Deslize para cima."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"Você concluiu o gesto para acessar a tela inicial. A seguir, aprenda a voltar."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"Você concluiu o gesto para acessar a tela inicial."</string>
- <string name="home_gesture_intro_title" msgid="836590312858441830">"Deslizar para voltar à tela inicial"</string>
- <string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Deslize de baixo para cima na tela. Esse gesto sempre leva você para a tela inicial."</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Deslize da borda inferior da tela para cima."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Mantenha a janela pressionada por mais tempo antes de soltar."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Deslize para cima e pare."</string>
- <string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Você aprendeu a usar gestos. Para desativá-los, acesse as Configurações."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"Você concluiu o gesto para trocar de app."</string>
- <string name="overview_gesture_intro_title" msgid="2902054412868489378">"Deslizar para trocar de app"</string>
- <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Para mudar de app, deslize de baixo para cima na tela, mantenha-a pressionada por um tempo e solte."</string>
- <string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"Tudo pronto"</string>
- <string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Concluído"</string>
- <string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Configurações"</string>
- <string name="gesture_tutorial_try_again" msgid="65962545858556697">"Tentar novamente"</string>
- <string name="gesture_tutorial_nice" msgid="2936275692616928280">"Muito bem!"</string>
- <string name="gesture_tutorial_step" msgid="1279786122817620968">"Tutorial <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
- <string name="allset_title" msgid="5021126669778966707">"Tudo pronto!"</string>
- <string name="allset_hint" msgid="2384632994739392447">"Deslize para cima para acessar a tela inicial"</string>
- <string name="allset_description" msgid="6350320429953234580">"Você já pode começar a usar seu smartphone"</string>
- <string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"Configurações de navegação do sistema"</annotation></string>
- <string name="action_share" msgid="2648470652637092375">"Compartilhar"</string>
- <string name="action_screenshot" msgid="8171125848358142917">"Capturar tela"</string>
- <string name="action_split" msgid="2098009717623550676">"Dividir"</string>
- <string name="toast_split_select_app" msgid="5453865907322018352">"Toque em outro app para dividir a tela"</string>
- <string name="toast_split_app_unsupported" msgid="3271526028981899666">"O app não tem suporte para a divisão de tela."</string>
- <string name="blocked_by_policy" msgid="2071401072261365546">"Essa ação não é permitida pelo app ou pela organização"</string>
- <string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Pular o tutorial de navegação?"</string>
- <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Veja o tutorial mais tarde no app <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Cancelar"</string>
- <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Pular"</string>
- <string name="accessibility_rotate_button" msgid="4771825231336502943">"Girar a tela"</string>
- <string name="taskbar_edu_opened" msgid="3950252793551919129">"As dicas sobre a barra de tarefas foram abertas"</string>
- <string name="taskbar_edu_closed" msgid="126643734478892862">"As dicas sobre a barra de tarefas foram fechadas"</string>
- <string name="taskbar_edu_switch_apps" msgid="6942863327845784813">"Use a barra de tarefas para alternar entre apps"</string>
- <string name="taskbar_edu_splitscreen" msgid="2663361731630346489">"Arraste para o lado e use dois apps ao mesmo tempo"</string>
- <string name="taskbar_edu_stashing" msgid="5212374387411764031">"Mantenha a barra de tarefas pressionada para ocultá-la"</string>
- <string name="taskbar_edu_next" msgid="4007618274426775841">"Próxima"</string>
- <string name="taskbar_edu_previous" msgid="459202320127201702">"Voltar"</string>
- <string name="taskbar_edu_close" msgid="887022990168191073">"Fechar"</string>
- <string name="taskbar_edu_done" msgid="6880178093977704569">"Concluído"</string>
- <string name="taskbar_button_home" msgid="2151398979630664652">"Início"</string>
- <string name="taskbar_button_a11y" msgid="5241161324875094465">"Acessibilidade"</string>
- <string name="taskbar_button_back" msgid="8558862226461164514">"Voltar"</string>
- <string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"Alternador do IME"</string>
- <string name="taskbar_button_recents" msgid="7273376136216613134">"Recentes"</string>
- <string name="taskbar_button_notifications" msgid="7471740351507357318">"Notificações"</string>
- <string name="taskbar_button_quick_settings" msgid="227662894293189391">"Config. rápidas"</string>
- <string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Mover para cima/para a esquerda"</string>
- <string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Mover para baixo/para a direita"</string>
</resources>
diff --git a/quickstep/res/values-ro/strings.xml b/quickstep/res/values-ro/strings.xml
index 38d596cd4b..2ac783eb0e 100644
--- a/quickstep/res/values-ro/strings.xml
+++ b/quickstep/res/values-ro/strings.xml
@@ -19,91 +19,19 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Ecran împărțit"</string>
<string name="recent_task_option_pin" msgid="7929860679018978258">"Fixați"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Formă liberă"</string>
+ <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Recente"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"Niciun element recent"</string>
+ <string name="accessibility_close_task" msgid="5354563209433803643">"Închideți"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Setări de utilizare a aplicației"</string>
<string name="recents_clear_all" msgid="5328176793634888831">"Ștergeți tot"</string>
<string name="accessibility_recent_apps" msgid="4058661986695117371">"Aplicații recente"</string>
- <string name="task_view_closed" msgid="9170038230110856166">"Activitatea s-a încheiat"</string>
<string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
<string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 minut"</string>
<string name="time_left_for_app" msgid="3111996412933644358">"Au mai rămas <xliff:g id="TIME">%1$s</xliff:g> astăzi"</string>
<string name="title_app_suggestions" msgid="4185902664111965088">"Sugestii de aplicații"</string>
+ <string name="all_apps_label" msgid="8542784161730910663">"Toate aplicațiile"</string>
<string name="all_apps_prediction_tip" msgid="2672336544844936186">"Aplicațiile estimate"</string>
- <string name="hotseat_edu_title_migrate" msgid="306578144424489980">"Primiți sugestii de aplicații în rândul de jos al ecranului de pornire"</string>
- <string name="hotseat_edu_title_migrate_landscape" msgid="3633942953997845243">"Primiți sugestii de aplicații în rândul de preferințe al ecranului de pornire"</string>
- <string name="hotseat_edu_message_migrate" msgid="8927179260533775320">"Accesați cu ușurință cele mai folosite aplicații direct din ecranul de pornire. Sugestiile se vor modifica în funcție de rutine. Aplicațiile din rândul de jos se vor muta în sus pe ecranul de pornire."</string>
- <string name="hotseat_edu_message_migrate_landscape" msgid="4248943380443387697">"Accesați cu ușurință cele mai folosite aplicații direct din ecranul de pornire. Sugestiile se vor schimba în funcție de rutina dvs. Aplicațiile din rândul de preferințe se vor muta în ecranul de pornire."</string>
- <string name="hotseat_edu_message_migrate_alt" msgid="3042360119039646356">"Accesați cu ușurință cele mai folosite aplicații, direct din ecranul de pornire. Sugestiile se vor modifica în funcție de rutine. Aplicațiile din rândul de jos se vor muta într-un dosar nou."</string>
- <string name="hotseat_edu_accept" msgid="1611544083278999837">"Primiți sugestii de aplicații"</string>
- <string name="hotseat_edu_dismiss" msgid="2781161822780201689">"Nu, mulțumesc"</string>
- <string name="hotseat_prediction_settings" msgid="6246554993566070818">"Setări"</string>
- <string name="hotseat_auto_enrolled" msgid="522100018967146807">"Cele mai folosite aplicații apar aici și se modifică în funcție de rutine"</string>
- <string name="hotseat_tip_no_empty_slots" msgid="1325212677738179185">"Trageți aplicații din rândul de jos pentru a primi sugestii de aplicații"</string>
- <string name="hotseat_tip_gaps_filled" msgid="3035673010274223538">"Sugestiile de aplicații sunt adăugate în spațiile goale"</string>
- <string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Sugestiile de aplicații au fost activate"</string>
- <string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Sugestiile de aplicații au fost dezactivate"</string>
- <string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Aplicația estimată: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Glisați dinspre marginea dreaptă îndepărtată sau dinspre marginea stângă îndepărtată."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Glisați dinspre marginea dreaptă sau stângă spre mijlocul ecranului și eliberați."</string>
- <string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Ați învățat cum să glisați dinspre dreapta pentru a reveni. În continuare, aflați cum să comutați aplicațiile."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"Ați finalizat gestul „înapoi”."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Nu glisați prea aproape de partea de jos a ecranului."</string>
- <string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"Schimbați sensibilitatea gestului „Înapoi” accesând Setările"</string>
- <string name="back_gesture_intro_title" msgid="19551256430224428">"Glisați pentru a reveni"</string>
- <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"Pentru a reveni la ultimul ecran, glisați de la marginea stângă sau dreaptă spre mijlocul ecranului."</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Glisați în sus dinspre marginea de jos a ecranului."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Nu întrerupeți gestul înainte de a elibera."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Glisați direct în sus."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"Ați finalizat gestul „accesați ecranul de pornire”. În continuare, aflați cum să reveniți."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"Ați finalizat gestul „accesați ecranul de pornire”."</string>
- <string name="home_gesture_intro_title" msgid="836590312858441830">"Glisați pentru a accesa ecranul de pornire"</string>
- <string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Glisați în sus din partea de jos a ecranului. Cu acest gest accesați întotdeauna ecranul de pornire."</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Glisați în sus dinspre marginea de jos a ecranului."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Încercați să țineți fereastra mai mult înainte s-o eliberați."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Glisați direct în sus, apoi întrerupeți."</string>
- <string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Ați învățat cum să folosiți gesturi. Pentru a dezactiva gesturile, accesați Setările."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"Ați finalizat gestul „comutați între aplicații”."</string>
- <string name="overview_gesture_intro_title" msgid="2902054412868489378">"Glisați pentru a comuta între aplicații"</string>
- <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Ca să comutați între aplicații, glisați în sus din partea de jos a ecranului, așteptați și eliberați."</string>
- <string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"Gata"</string>
- <string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Gata"</string>
- <string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Setări"</string>
- <string name="gesture_tutorial_try_again" msgid="65962545858556697">"Reîncercați"</string>
- <string name="gesture_tutorial_nice" msgid="2936275692616928280">"Bravo!"</string>
- <string name="gesture_tutorial_step" msgid="1279786122817620968">"Tutorialul <xliff:g id="CURRENT">%1$d</xliff:g> / <xliff:g id="TOTAL">%2$d</xliff:g>"</string>
- <string name="allset_title" msgid="5021126669778966707">"Gata!"</string>
- <string name="allset_hint" msgid="2384632994739392447">"Glisați în sus pentru a accesa ecranul de pornire"</string>
- <string name="allset_description" msgid="6350320429953234580">"Sunteți gata să folosiți telefonul"</string>
- <string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"Setările de navigare ale sistemului"</annotation></string>
- <string name="action_share" msgid="2648470652637092375">"Distribuiți"</string>
- <string name="action_screenshot" msgid="8171125848358142917">"Captură de ecran"</string>
- <string name="action_split" msgid="2098009717623550676">"Împărțit"</string>
- <string name="toast_split_select_app" msgid="5453865907322018352">"Atingeți altă aplicație pentru a folosi ecranul împărțit"</string>
- <string name="toast_split_app_unsupported" msgid="3271526028981899666">"Aplicația nu acceptă ecranul împărțit."</string>
- <string name="blocked_by_policy" msgid="2071401072261365546">"Această acțiune nu este permisă de aplicație sau de organizația dvs."</string>
- <string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Omiteți tutorialul de navigare?"</string>
- <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Îl puteți găsi mai târziu în aplicația <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Anulați"</string>
- <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Omiteți"</string>
- <string name="accessibility_rotate_button" msgid="4771825231336502943">"Rotiți ecranul"</string>
- <string name="taskbar_edu_opened" msgid="3950252793551919129">"Panoul cu informații despre bara de activități s-a afișat"</string>
- <string name="taskbar_edu_closed" msgid="126643734478892862">"Panoul cu informații despre bara de activități s-a închis"</string>
- <string name="taskbar_edu_switch_apps" msgid="6942863327845784813">"Folosiți bara de activități ca să comutați între aplicații"</string>
- <string name="taskbar_edu_splitscreen" msgid="2663361731630346489">"Trageți în lateral ca să folosiți două aplicații deodată"</string>
- <string name="taskbar_edu_stashing" msgid="5212374387411764031">"Atingeți lung oricând pentru a ascunde bara de activități"</string>
- <string name="taskbar_edu_next" msgid="4007618274426775841">"Înainte"</string>
- <string name="taskbar_edu_previous" msgid="459202320127201702">"Înapoi"</string>
- <string name="taskbar_edu_close" msgid="887022990168191073">"Închideți"</string>
- <string name="taskbar_edu_done" msgid="6880178093977704569">"Gata"</string>
- <string name="taskbar_button_home" msgid="2151398979630664652">"Ecran de pornire"</string>
- <string name="taskbar_button_a11y" msgid="5241161324875094465">"Accesibilitate"</string>
- <string name="taskbar_button_back" msgid="8558862226461164514">"Înapoi"</string>
- <string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"Comutator IME"</string>
- <string name="taskbar_button_recents" msgid="7273376136216613134">"Recente"</string>
- <string name="taskbar_button_notifications" msgid="7471740351507357318">"Notificări"</string>
- <string name="taskbar_button_quick_settings" msgid="227662894293189391">"Setări rapide"</string>
- <string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Mutați în stânga sus"</string>
- <string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Mutați în dreapta jos"</string>
</resources>
diff --git a/quickstep/res/values-ru/strings.xml b/quickstep/res/values-ru/strings.xml
index 7d27436abf..5dd89a644b 100644
--- a/quickstep/res/values-ru/strings.xml
+++ b/quickstep/res/values-ru/strings.xml
@@ -19,91 +19,19 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="recent_task_option_pin" msgid="7929860679018978258">"Закрепить"</string>
+ <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Разделить экран"</string>
+ <string name="recent_task_option_pin" msgid="7929860679018978258">"Блокировать"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Произвольная форма"</string>
+ <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Обзор"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"Здесь пока ничего нет."</string>
+ <string name="accessibility_close_task" msgid="5354563209433803643">"Закрыть"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Настройки использования приложения"</string>
<string name="recents_clear_all" msgid="5328176793634888831">"Очистить все"</string>
<string name="accessibility_recent_apps" msgid="4058661986695117371">"Недавние приложения"</string>
- <string name="task_view_closed" msgid="9170038230110856166">"Задача закрыта"</string>
<string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>: <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
<string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 мин."</string>
<string name="time_left_for_app" msgid="3111996412933644358">"Осталось сегодня: <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="title_app_suggestions" msgid="4185902664111965088">"Рекомендуемые приложения"</string>
+ <string name="all_apps_label" msgid="8542784161730910663">"Все приложения"</string>
<string name="all_apps_prediction_tip" msgid="2672336544844936186">"Ваши рекомендуемые приложения"</string>
- <string name="hotseat_edu_title_migrate" msgid="306578144424489980">"Рекомендуемые приложения будут появляться в нижнем ряду на главном экране"</string>
- <string name="hotseat_edu_title_migrate_landscape" msgid="3633942953997845243">"Рекомендуемые приложения будут появляться в разделе избранных на главном экране"</string>
- <string name="hotseat_edu_message_migrate" msgid="8927179260533775320">"Приложения, которыми вы часто пользуетесь, будут доступны прямо на главном экране. Их список может меняться с учетом ваших предпочтений. Приложения из нижнего ряда будут перемещены выше на главном экране."</string>
- <string name="hotseat_edu_message_migrate_landscape" msgid="4248943380443387697">"Включите функцию для быстрого доступа к часто используемым приложениям на главном экране. Список меняется с учетом ваших действий. Приложения из раздела избранных будут перемещены на главный экран."</string>
- <string name="hotseat_edu_message_migrate_alt" msgid="3042360119039646356">"Приложения, которыми вы часто пользуетесь, будут доступны прямо на главном экране. Их список может меняться с учетом ваших предпочтений. Приложения из нижнего ряда будут перемещены в новую папку."</string>
- <string name="hotseat_edu_accept" msgid="1611544083278999837">"Показывать рекомендации"</string>
- <string name="hotseat_edu_dismiss" msgid="2781161822780201689">"Отмена"</string>
- <string name="hotseat_prediction_settings" msgid="6246554993566070818">"Настройки"</string>
- <string name="hotseat_auto_enrolled" msgid="522100018967146807">"Здесь появляются часто используемые приложения. Список меняется с учетом ваших привычек."</string>
- <string name="hotseat_tip_no_empty_slots" msgid="1325212677738179185">"Перетащите приложения из нижнего ряда, чтобы получить рекомендации."</string>
- <string name="hotseat_tip_gaps_filled" msgid="3035673010274223538">"Рекомендуемые приложения будут появляться на свободных местах."</string>
- <string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Функция \"Рекомендуемые приложения\" включена."</string>
- <string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Функция \"Рекомендуемые приложения\" отключена."</string>
- <string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Рекомендуемое приложение: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Проведите справа налево или слева направо от самого края экрана."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Проведите от правого или левого края экрана до середины дисплея и отпустите палец."</string>
- <string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Теперь вы знаете, как вернуться, проведя справа налево. Далее мы расскажем, как переключаться между приложениями."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"Вы выполнили жест для перехода назад."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Проведите пальцем не слишком близко к нижнему краю экрана."</string>
- <string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"Уровень чувствительности можно изменить в настройках."</string>
- <string name="back_gesture_intro_title" msgid="19551256430224428">"Возврат к предыдущему экрану"</string>
- <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"Чтобы вернуться к предыдущему экрану, проведите от левого или правого края дисплея к центру."</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Проведите снизу вверх от самого края экрана."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Не приостанавливайтесь перед тем, как отпустить палец."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Проведите по экрану ровно вверх."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"Вы выполнили жест для перехода на главный экран. Далее мы расскажем, как вернуться назад."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"Вы выполнили жест для перехода на главный экран."</string>
- <string name="home_gesture_intro_title" msgid="836590312858441830">"Переход на главный экран"</string>
- <string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Проведите вверх от нижнего края дисплея. Этот жест открывает главный экран."</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Проведите снизу вверх от самого края экрана."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Прежде чем отпускать палец, задержите его на дисплее подольше."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Проведите по экрану ровно вверх, а затем задержите палец в крайнем положении."</string>
- <string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Теперь вы знаете, как использовать жесты. Чтобы отключить их, перейдите в настройки."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"Вы выполнили жест для переключения между приложениями."</string>
- <string name="overview_gesture_intro_title" msgid="2902054412868489378">"Переключение между приложениями"</string>
- <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Чтобы переключиться между приложениями‚ проведите по экрану снизу вверх, задержите палец, а затем отпустите."</string>
- <string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"Готово"</string>
- <string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Готово"</string>
- <string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Настройки"</string>
- <string name="gesture_tutorial_try_again" msgid="65962545858556697">"Повторите попытку"</string>
- <string name="gesture_tutorial_nice" msgid="2936275692616928280">"Поздравляем!"</string>
- <string name="gesture_tutorial_step" msgid="1279786122817620968">"Руководство (шаг <xliff:g id="CURRENT">%1$d</xliff:g> из <xliff:g id="TOTAL">%2$d</xliff:g>)"</string>
- <string name="allset_title" msgid="5021126669778966707">"Готово!"</string>
- <string name="allset_hint" msgid="2384632994739392447">"Чтобы перейти на главный экран, проведите вверх."</string>
- <string name="allset_description" msgid="6350320429953234580">"Теперь вы можете использовать телефон."</string>
- <string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"Системные настройки навигации"</annotation></string>
- <string name="action_share" msgid="2648470652637092375">"Поделиться"</string>
- <string name="action_screenshot" msgid="8171125848358142917">"Скриншот"</string>
- <string name="action_split" msgid="2098009717623550676">"Разделить"</string>
- <string name="toast_split_select_app" msgid="5453865907322018352">"Для разделения экрана нажмите на другое приложение."</string>
- <string name="toast_split_app_unsupported" msgid="3271526028981899666">"Приложение не поддерживает разделение экрана."</string>
- <string name="blocked_by_policy" msgid="2071401072261365546">"Это действие заблокировано приложением или организацией."</string>
- <string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Пропустить руководство по жестам?"</string>
- <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Его можно найти в приложении \"<xliff:g id="NAME">%1$s</xliff:g>\"."</string>
- <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Отмена"</string>
- <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Пропустить"</string>
- <string name="accessibility_rotate_button" msgid="4771825231336502943">"Повернуть экран"</string>
- <string name="taskbar_edu_opened" msgid="3950252793551919129">"Обучение по работе с панелью задач показано"</string>
- <string name="taskbar_edu_closed" msgid="126643734478892862">"Обучение по работе с панелью задач скрыто"</string>
- <string name="taskbar_edu_switch_apps" msgid="6942863327845784813">"Используйте панель задач, чтобы переключать приложения."</string>
- <string name="taskbar_edu_splitscreen" msgid="2663361731630346489">"Перетащите в сторону, чтобы использовать два приложения сразу."</string>
- <string name="taskbar_edu_stashing" msgid="5212374387411764031">"Чтобы скрыть панель задач, коснитесь ее и удерживайте."</string>
- <string name="taskbar_edu_next" msgid="4007618274426775841">"Далее"</string>
- <string name="taskbar_edu_previous" msgid="459202320127201702">"Назад"</string>
- <string name="taskbar_edu_close" msgid="887022990168191073">"Закрыть"</string>
- <string name="taskbar_edu_done" msgid="6880178093977704569">"Готово"</string>
- <string name="taskbar_button_home" msgid="2151398979630664652">"Главный экран"</string>
- <string name="taskbar_button_a11y" msgid="5241161324875094465">"Спец. возмож."</string>
- <string name="taskbar_button_back" msgid="8558862226461164514">"Назад"</string>
- <string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"Переключат. IME"</string>
- <string name="taskbar_button_recents" msgid="7273376136216613134">"Недавние"</string>
- <string name="taskbar_button_notifications" msgid="7471740351507357318">"Уведомления"</string>
- <string name="taskbar_button_quick_settings" msgid="227662894293189391">"Быстрые настройки"</string>
- <string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Переместить вверх или влево"</string>
- <string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Переместить вниз или вправо"</string>
</resources>
diff --git a/quickstep/res/values-si/strings.xml b/quickstep/res/values-si/strings.xml
index 990017e0ce..f6584c4dca 100644
--- a/quickstep/res/values-si/strings.xml
+++ b/quickstep/res/values-si/strings.xml
@@ -19,93 +19,19 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="recent_task_option_split_screen" msgid="5353188922202653570">"බෙදුම් තිරය"</string>
<string name="recent_task_option_pin" msgid="7929860679018978258">"අමුණන්න"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Freeform"</string>
+ <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"දළ විශ්ලේෂණය"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"මෑත අයිතම නැත"</string>
+ <string name="accessibility_close_task" msgid="5354563209433803643">"වසන්න"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"යෙදුම් භාවිත සැකසීම්"</string>
<string name="recents_clear_all" msgid="5328176793634888831">"සියල්ල හිස් කරන්න"</string>
<string name="accessibility_recent_apps" msgid="4058661986695117371">"මෑත යෙදුම්"</string>
- <string name="task_view_closed" msgid="9170038230110856166">"කාර්යය අවසන් කරන ලදි"</string>
<string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
<string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 විනාඩියක්"</string>
<string name="time_left_for_app" msgid="3111996412933644358">"අද <xliff:g id="TIME">%1$s</xliff:g>ක් ඉතුරුයි"</string>
<string name="title_app_suggestions" msgid="4185902664111965088">"යෙදුම් යෝජනා"</string>
+ <string name="all_apps_label" msgid="8542784161730910663">"සියලු යෙදුම්"</string>
<string name="all_apps_prediction_tip" msgid="2672336544844936186">"ඔබේ පුරෝකථන කළ යෙදුම්"</string>
- <string name="hotseat_edu_title_migrate" msgid="306578144424489980">"ඔබගේ මුල් තිරයේ පහළ පේළියේ යෙදුම් යෝජනා ලබා ගන්න"</string>
- <string name="hotseat_edu_title_migrate_landscape" msgid="3633942953997845243">"ඔබේ මුල් තිරයේ ප්‍රියතම පේළියේ යෙදුම් යෝජනා ලබා ගන්න"</string>
- <string name="hotseat_edu_message_migrate" msgid="8927179260533775320">"ඔබගේ වැඩිපුරම භාවිත කරන යෙදුම්වලට මුල් තිරයේ සිටම පහසුවෙන් ප්‍රවේශ වන්න. ඔබගේ දිනචරියා මත පදනම්ව යෝජනා වෙනස් වනු ඇත. පහළ පේළියේ යෙදුම් ඔබගේ මුල් තිරය දක්වා ගෙන යනු ඇත."</string>
- <string name="hotseat_edu_message_migrate_landscape" msgid="4248943380443387697">"ඔබගේ වැඩිපුරම භාවිත කරන යෙදුම්වලට මුල් තිරයේ සිටම පහසුවෙන් ප්‍රවේශ වන්න. ඔබගේ දිනචරියා මත පදනම්ව යෝජනා වෙනස් වනු ඇත. ප්‍රියතම තුළ යෙදුම් ඔබේ මුල් තිරය වෙත ගෙන යනු ඇත."</string>
- <string name="hotseat_edu_message_migrate_alt" msgid="3042360119039646356">"ඔබගේ වැඩිපුරම භාවිත කරන යෙදුම්වලට මුල් තිරයේ සිටම පහසුවෙන් ප්‍රවේශ වන්න. ඔබගේ දිනචරියා මත පදනම්ව යෝජනා වෙනස් වනු ඇත. පහළ පේළියේ යෙදුම් නව ෆෝල්ඩරයකට ගෙන යනු ඇත."</string>
- <string name="hotseat_edu_accept" msgid="1611544083278999837">"යෙදුම් යෝජනා ලබා ගන්න"</string>
- <string name="hotseat_edu_dismiss" msgid="2781161822780201689">"එපා ස්තුතියි"</string>
- <string name="hotseat_prediction_settings" msgid="6246554993566070818">"සැකසීම්"</string>
- <string name="hotseat_auto_enrolled" msgid="522100018967146807">"වැඩිපුරම භාවිත කළ යෙදුම් මෙහි දිස්වන අතර දිනචරියා මත පදනම්ව වෙනස් වේ"</string>
- <string name="hotseat_tip_no_empty_slots" msgid="1325212677738179185">"යෙදුම් යෝජනා ලබා ගැනීමට පහළ පේළියෙන් ඉවතට යෙදුම් ඇදගෙන යන්න"</string>
- <string name="hotseat_tip_gaps_filled" msgid="3035673010274223538">"යෙදුම් යෝජනා හිස් අවකාශයට එක් කර ඇත"</string>
- <string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"යෙදුම් යෝජනා සබලිතයි"</string>
- <string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"යෙදුම් යෝජනා අබල කර ඇත"</string>
- <string name="hotseat_prediction_content_description" msgid="4582028296938078419">"පුරෝකථනය කළ යෙදුම: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"ඔබ ඈත දකුණු හෝ ඈත වම් දාරයේ ස්වයිප් කරන බව සහතික කර ගන්න."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"ඔබ දකුණු හෝ වම් දාරයේ සිට තිරයේ මැදට ස්වයිප් කර අත හරින බව සහතික කර ගන්න."</string>
- <string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"ආපසු යාමට දකුණේ සිට ස්වයිප් කරන්නේ කෙසේදැයි ඔබ දැන ගත්තේය. ඊළඟට, යෙදුම් මාරු කරන ආකාරය දැන ගන්න."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"ඔබ ආපසු යාමේ ඉංගිතය සම්පූර්ණ කරන ලදි."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"ඔබ තිරයේ පහළට ඉතාම සමීපව ස්වයිප් නොකරන බවට සහතික කර ගන්න."</string>
- <string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"ආපසු ඉංගිතයෙහි සංවේදීතාව වෙනස් කිරීමට, සැකසීම් වෙත යන්න"</string>
- <string name="back_gesture_intro_title" msgid="19551256430224428">"ආපසු යාමට ස්වයිප් කරන්න"</string>
- <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"අවසාන තිරයට ආපසු යාමට, වම් හෝ දකුණු දාරයෙන් තිරයේ මැදට ස්වයිප් කරන්න."</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"ඔබ තිරයේ පහළ දාරයේ සිට ඉහළට ස්වයිප් කරන බව සහතික කර ගන්න."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"යාමට ඉඩ හැරීමට පෙර ඔබ විරාමයක් නොගන්නා බව සහතික කර ගන්න."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"ඔබ කෙලින්ම ඉහළට ස්වයිප් කරන බව සහතික කර ගන්න."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"ඔබ මුල් පිටුවට යාමේ ඉංගිතය සම්පූර්ණ කරන ලදි. ඊළඟට, ආපසු යන ආකාරය දැන ගන්න."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"ඔබ මුල් පිටුවට යාමේ ඉංගිතය සම්පූර්ණ කරන ලදි."</string>
- <string name="home_gesture_intro_title" msgid="836590312858441830">"මුල් පිටුවට යාමට ස්වයිප් කරන්න"</string>
- <string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"ඔබගේ තිරයේ පහළින් උඩට ස්වයිප් කරන්න.මෙම ඉංගිතය සැම විටම ඔබව මුල් තිරයට ගෙන යයි."</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"ඔබ තිරයේ පහළ දාරයේ සිට ඉහළට ස්වයිප් කරන බව සහතික කර ගන්න."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"මුදා හැරීමට පෙර කවුළුව වැඩි වේලාවක් රඳවා තබා ගැනීමට උත්සාහ කරන්න."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"ඔබ කෙලින්ම ඉහළට ස්වයිප් කර, අනතුරුව විරාම කරන බව සහතික කර ගන්න."</string>
- <string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"ඔබ ඉංගිත භාවිත කරන ආකාරය දැන ගෙන ඇත. ඉංගිත ක්‍රියාවිරහිත කිරීමට, සැකසීම් වෙත යන්න."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"ඔබ යෙදුම් මාරු කිරීමේ ඉංගිතය සම්පූර්ණ කර ඇත."</string>
- <string name="overview_gesture_intro_title" msgid="2902054412868489378">"යෙදුම් මාරු කිරීමට ස්වයිප් කරන්න"</string>
- <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"යෙදුම් අතර මාරු වීමට, ඔබගේ තිරයේ පහළම සිට උඩට ස්වයිප් කර, අල්ලාගෙන සිට, අනතුරුව මුදා හරින්න."</string>
- <string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"සියල්ල සකසා ඇත"</string>
- <string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"නිමයි"</string>
- <string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"සැකසීම්"</string>
- <string name="gesture_tutorial_try_again" msgid="65962545858556697">"නැවත උත්සාහ කරන්න"</string>
- <string name="gesture_tutorial_nice" msgid="2936275692616928280">"කදිමයි!"</string>
- <string name="gesture_tutorial_step" msgid="1279786122817620968">"නිබන්ධනය <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
- <string name="allset_title" msgid="5021126669778966707">"සියල්ල සූදානම්!"</string>
- <string name="allset_hint" msgid="2384632994739392447">"මුල් පිටුවට යාමට ඉහළට ස්වයිප් කරන්න"</string>
- <string name="allset_description" msgid="6350320429953234580">"ඔබ ඔබගේ දුරකථනය භාවිත කිරීම පටන් ගැනීමට සූදානම්"</string>
- <string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"පද්ධති සංචාලන සැකසීම්"</annotation></string>
- <string name="action_share" msgid="2648470652637092375">"බෙදා ගන්න"</string>
- <string name="action_screenshot" msgid="8171125848358142917">"තිර රුව"</string>
- <string name="action_split" msgid="2098009717623550676">"බෙදන්න"</string>
- <string name="toast_split_select_app" msgid="5453865907322018352">"බෙදුම් තිරය භාවිත කිරීමට තවත් යෙදුමක් තට්ටු කරන්න"</string>
- <string name="toast_split_app_unsupported" msgid="3271526028981899666">"යෙදුම බෙදුම් තිරය සඳහා සහාය නොදක්වයි."</string>
- <string name="blocked_by_policy" msgid="2071401072261365546">"මෙම ක්‍රියාව යෙදුම හෝ ඔබේ සංවිධානය මගින් ඉඩ නොදේ"</string>
- <string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"නිබන්ධනය සංචාලනය මඟ හරින්නද?"</string>
- <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"ඔබට මෙය පසුව <xliff:g id="NAME">%1$s</xliff:g> යෙදුම තුළ සොයා ගත හැකිය"</string>
- <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"අවලංගු කරන්න"</string>
- <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"මඟ හරින්න"</string>
- <string name="accessibility_rotate_button" msgid="4771825231336502943">"තිරය කරකවන්න"</string>
- <string name="taskbar_edu_opened" msgid="3950252793551919129">"කාර්ය තීරු අධ්‍යාපනය දිස් විය"</string>
- <string name="taskbar_edu_closed" msgid="126643734478892862">"කාර්ය තීරු අධ්‍යාපනය වසා ඇත"</string>
- <string name="taskbar_edu_switch_apps" msgid="6942863327845784813">"යෙදුම් මාරු කිරීමට කාර්ය තීරුව භාවිත කරන්න"</string>
- <string name="taskbar_edu_splitscreen" msgid="2663361731630346489">"එකවර යෙදුම් දෙකක් භාවිතා කිරීමට පැත්තට අදින්න"</string>
- <string name="taskbar_edu_stashing" msgid="5212374387411764031">"කාර්ය තීරුව සැඟවීමට ස්පර්ශ කර අල්ලා ගෙන සිටින්න"</string>
- <string name="taskbar_edu_next" msgid="4007618274426775841">"ඊළඟ"</string>
- <string name="taskbar_edu_previous" msgid="459202320127201702">"ආපසු"</string>
- <string name="taskbar_edu_close" msgid="887022990168191073">"වසන්න"</string>
- <string name="taskbar_edu_done" msgid="6880178093977704569">"නිමයි"</string>
- <string name="taskbar_button_home" msgid="2151398979630664652">"මුල් පිටුව"</string>
- <string name="taskbar_button_a11y" msgid="5241161324875094465">"ප්‍රවේශ්‍යතාව"</string>
- <string name="taskbar_button_back" msgid="8558862226461164514">"ආපසු"</string>
- <string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"IME මාරුව"</string>
- <string name="taskbar_button_recents" msgid="7273376136216613134">"මෑත"</string>
- <!-- no translation found for taskbar_button_notifications (7471740351507357318) -->
- <skip />
- <!-- no translation found for taskbar_button_quick_settings (227662894293189391) -->
- <skip />
- <string name="move_drop_target_top_or_left" msgid="2988702185049595807">"ඉහළ/වම වෙත ගෙන යන්න"</string>
- <string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"පහළ/දකුණ වෙත ගෙන යන්න"</string>
</resources>
diff --git a/quickstep/res/values-sk/strings.xml b/quickstep/res/values-sk/strings.xml
index a18f72ca6d..8a9c7365f2 100644
--- a/quickstep/res/values-sk/strings.xml
+++ b/quickstep/res/values-sk/strings.xml
@@ -19,93 +19,19 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Rozdeliť obrazovku"</string>
<string name="recent_task_option_pin" msgid="7929860679018978258">"Pripnúť"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Voľný režim"</string>
+ <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Prehľad"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"Žiadne nedávne položky"</string>
+ <string name="accessibility_close_task" msgid="5354563209433803643">"Zavrieť"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Nastavenia využívania aplikácie"</string>
<string name="recents_clear_all" msgid="5328176793634888831">"Vymazať všetko"</string>
<string name="accessibility_recent_apps" msgid="4058661986695117371">"Nedávne aplikácie"</string>
- <string name="task_view_closed" msgid="9170038230110856166">"Úloha bola zavretá"</string>
<string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
<string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"Menej ako 1 minúta"</string>
<string name="time_left_for_app" msgid="3111996412933644358">"Dnes ešte zostáva: <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="title_app_suggestions" msgid="4185902664111965088">"Návrhy aplikácií"</string>
+ <string name="all_apps_label" msgid="8542784161730910663">"Všetky aplikácie"</string>
<string name="all_apps_prediction_tip" msgid="2672336544844936186">"Vaše predpovedané aplikácie"</string>
- <string name="hotseat_edu_title_migrate" msgid="306578144424489980">"Nechajte si v spodnom riadku na ploche zobrazovať návrhy aplikácií"</string>
- <string name="hotseat_edu_title_migrate_landscape" msgid="3633942953997845243">"Nechajte si na ploche na riadku obľúbených zobrazovať návrhy aplikácií"</string>
- <string name="hotseat_edu_message_migrate" msgid="8927179260533775320">"Získajte jednoduchý prístup k najpoužívanejším aplikáciám priamo na ploche. Návrhy sa budú meniť podľa vašich zvyklostí. Aplikácie v spodnom riadku sa presunú nahor na plochu."</string>
- <string name="hotseat_edu_message_migrate_landscape" msgid="4248943380443387697">"Získajte jednoduchý prístup k najpoužívanejším aplikáciám priamo na ploche. Návrhy sa budú meniť podľa vašich postupov. Aplikácie v riadku s obľúbenými sa presunú na plochu."</string>
- <string name="hotseat_edu_message_migrate_alt" msgid="3042360119039646356">"Získajte jednoduchý prístup k najpoužívanejším aplikáciám priamo na ploche. Návrhy sa budú meniť podľa vašich zvyklostí. Aplikácie v spodnom riadku sa presunú do nového priečinka."</string>
- <string name="hotseat_edu_accept" msgid="1611544083278999837">"Zobrazovať návrhy aplikácií"</string>
- <string name="hotseat_edu_dismiss" msgid="2781161822780201689">"Nie, ďakujem"</string>
- <string name="hotseat_prediction_settings" msgid="6246554993566070818">"Nastavenia"</string>
- <string name="hotseat_auto_enrolled" msgid="522100018967146807">"Tu sú zobrazené najpoužívanejšie aplikácie a menia sa podľa postupov"</string>
- <string name="hotseat_tip_no_empty_slots" msgid="1325212677738179185">"Ak chcete získať návrhy aplikácií, presuňte aplikácie zo spodného riadka"</string>
- <string name="hotseat_tip_gaps_filled" msgid="3035673010274223538">"Na prázdne miesto pridané návrhy aplikácií"</string>
- <string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Návrhy aplikácií zapnuté"</string>
- <string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Návrhy aplikácií vypnuté"</string>
- <string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Predpovedaná aplikácia: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Musite potiahnuť z úplne krajného pravého alebo ľavého okraja."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Musíte potiahnuť z pravého alebo ľavého okraja do stredu obrazovky a potom uvoľniť."</string>
- <string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Naučili ste sa prejsť späť potiahnutím sprava. V ďalšom kroku sa naučíte prepínať aplikácie."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"Dokončili ste gesto na prechod späť."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Nesmiete potiahnuť príliš blízko dolnej časti obrazovky."</string>
- <string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"Ak chcete zmeniť citlivosť gesta Späť, prejdite do Nastavení"</string>
- <string name="back_gesture_intro_title" msgid="19551256430224428">"Prejdite späť potiahnutím"</string>
- <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"Na poslednú obrazovku prejdete potiahnutím z ľavého alebo pravého okraja do stredu obrazovky."</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Musíte potiahnuť nahor z dolného okraja obrazovky."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Pred uvoľnením nesmiete zastať."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Musíte potiahnuť priamo hore."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"Dokončili ste gesto na prechod na plochu. V ďalšom kroku sa naučíte, ako sa vrátiť späť."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"Dokončili ste gesto na prechod na plochu."</string>
- <string name="home_gesture_intro_title" msgid="836590312858441830">"Prechod na plochu potiahnutím"</string>
- <string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Potiahnite nahor zdola obrazovky. Týmto gestom sa vždy vrátite na plochu."</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Musíte potiahnuť nahor z dolného okraja obrazovky."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Skúste okno pred uvoľnením podržať dlhšie."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Musite potiahnuť priamo hore a potom zastať."</string>
- <string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Naučili ste sa používať gestá. Ak ich chcete vypnúť, prejdite do Nastavení."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"Dokončili ste gesto na prepnutie aplikácií."</string>
- <string name="overview_gesture_intro_title" msgid="2902054412868489378">"Prepínanie aplikácií potiahnutím"</string>
- <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Aplikácie môžete prepínať potiahnutím obrazovky zdola nahor, pridržaním a následným uvoľnením."</string>
- <string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"Hotovo"</string>
- <string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Hotovo"</string>
- <string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Nastavenia"</string>
- <string name="gesture_tutorial_try_again" msgid="65962545858556697">"Skúste to znova"</string>
- <string name="gesture_tutorial_nice" msgid="2936275692616928280">"Výborne!"</string>
- <string name="gesture_tutorial_step" msgid="1279786122817620968">"Návod <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
- <string name="allset_title" msgid="5021126669778966707">"Hotovo"</string>
- <string name="allset_hint" msgid="2384632994739392447">"Potiahnutím nahor prejdete na plochu"</string>
- <string name="allset_description" msgid="6350320429953234580">"Telefón môžete začať používať"</string>
- <string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"Nastavenia navigácie systémom"</annotation></string>
- <string name="action_share" msgid="2648470652637092375">"Zdieľať"</string>
- <string name="action_screenshot" msgid="8171125848358142917">"Snímka obrazovky"</string>
- <string name="action_split" msgid="2098009717623550676">"Rozdeliť"</string>
- <string name="toast_split_select_app" msgid="5453865907322018352">"Rozdel. obrazovku spustíte klepnutím na inú aplik."</string>
- <string name="toast_split_app_unsupported" msgid="3271526028981899666">"Aplikácia nepodporuje rozdelenú obrazovku."</string>
- <string name="blocked_by_policy" msgid="2071401072261365546">"Aplikácia alebo vaša organizácia túto akciu nepovoľuje"</string>
- <string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Chcete preskočiť návod na navigáciu?"</string>
- <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Tento návod nájdete v aplikácii <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Zrušiť"</string>
- <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Preskočiť"</string>
- <string name="accessibility_rotate_button" msgid="4771825231336502943">"Otočiť obrazovku"</string>
- <string name="taskbar_edu_opened" msgid="3950252793551919129">"Zobrazila sa výuka k hlavnému panelu"</string>
- <string name="taskbar_edu_closed" msgid="126643734478892862">"Výuka k hlavnému panelu bola zatvorená"</string>
- <string name="taskbar_edu_switch_apps" msgid="6942863327845784813">"Aplikácie je možné prepínať pomocou panela úloh"</string>
- <string name="taskbar_edu_splitscreen" msgid="2663361731630346489">"Po presunutí na stranu je možné používať dve aplikácie naraz"</string>
- <string name="taskbar_edu_stashing" msgid="5212374387411764031">"Panel úloh skryjete pridržaním"</string>
- <string name="taskbar_edu_next" msgid="4007618274426775841">"Ďalej"</string>
- <string name="taskbar_edu_previous" msgid="459202320127201702">"Späť"</string>
- <string name="taskbar_edu_close" msgid="887022990168191073">"Zavrieť"</string>
- <string name="taskbar_edu_done" msgid="6880178093977704569">"Hotovo"</string>
- <string name="taskbar_button_home" msgid="2151398979630664652">"Plocha"</string>
- <string name="taskbar_button_a11y" msgid="5241161324875094465">"Dostupnosť"</string>
- <string name="taskbar_button_back" msgid="8558862226461164514">"Späť"</string>
- <string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"Prepínač IME"</string>
- <string name="taskbar_button_recents" msgid="7273376136216613134">"Nedávne"</string>
- <!-- no translation found for taskbar_button_notifications (7471740351507357318) -->
- <skip />
- <!-- no translation found for taskbar_button_quick_settings (227662894293189391) -->
- <skip />
- <string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Presunúť hore alebo doľava"</string>
- <string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Presunúť dole alebo doprava"</string>
</resources>
diff --git a/quickstep/res/values-sl/strings.xml b/quickstep/res/values-sl/strings.xml
index 82035280b6..15f8f89cc7 100644
--- a/quickstep/res/values-sl/strings.xml
+++ b/quickstep/res/values-sl/strings.xml
@@ -19,91 +19,19 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Razdeljen zaslon"</string>
<string name="recent_task_option_pin" msgid="7929860679018978258">"Pripni"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Prosta oblika"</string>
+ <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Pregled"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"Ni nedavnih elementov"</string>
+ <string name="accessibility_close_task" msgid="5354563209433803643">"Zapri"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Nastavitve uporabe aplikacij"</string>
<string name="recents_clear_all" msgid="5328176793634888831">"Počisti vse"</string>
<string name="accessibility_recent_apps" msgid="4058661986695117371">"Nedavne aplikacije"</string>
- <string name="task_view_closed" msgid="9170038230110856166">"Opravilo je zaprto"</string>
<string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
<string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 min"</string>
<string name="time_left_for_app" msgid="3111996412933644358">"Danes je ostalo še <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <string name="title_app_suggestions" msgid="4185902664111965088">"Predlagane aplikacije"</string>
+ <string name="title_app_suggestions" msgid="4185902664111965088">"Predlogi za aplikacije"</string>
+ <string name="all_apps_label" msgid="8542784161730910663">"Vse aplikacije"</string>
<string name="all_apps_prediction_tip" msgid="2672336544844936186">"Predvidene aplikacije"</string>
- <string name="hotseat_edu_title_migrate" msgid="306578144424489980">"Oglejte si predlagane aplikacije v spodnji vrstici začetnega zaslona"</string>
- <string name="hotseat_edu_title_migrate_landscape" msgid="3633942953997845243">"Prejemajte predloge aplikacij v vrstici s priljubljenimi na začetnem zaslonu"</string>
- <string name="hotseat_edu_message_migrate" msgid="8927179260533775320">"Preprosto dostopajte do najpogosteje uporabljenih aplikacij kar na začetnem zaslonu. Predlogi se spreminjajo na podlagi dejanj, ki jih pogosto izvajate. Aplikacije iz spodnje vrstice se premaknejo na začetni zaslon."</string>
- <string name="hotseat_edu_message_migrate_landscape" msgid="4248943380443387697">"Preprosto dostopajte do najpogosteje uporabljenih aplikacij kar na začetnem zaslonu. Predlogi se spreminjajo na podlagi dejanj, ki jih pogosto izvajate. Aplikacije v vrstici s priljubljenimi bodo premaknjene na začetni zaslon."</string>
- <string name="hotseat_edu_message_migrate_alt" msgid="3042360119039646356">"Preprosto dostopajte do najpogosteje uporabljenih aplikacij kar na začetnem zaslonu. Predlogi se spreminjajo na podlagi dejanj, ki jih pogosto izvajate. Aplikacije iz spodnje vrstice se premaknejo v novo mapo."</string>
- <string name="hotseat_edu_accept" msgid="1611544083278999837">"Prikaži predlagane aplikacije"</string>
- <string name="hotseat_edu_dismiss" msgid="2781161822780201689">"Ne, hvala"</string>
- <string name="hotseat_prediction_settings" msgid="6246554993566070818">"Nastavitve"</string>
- <string name="hotseat_auto_enrolled" msgid="522100018967146807">"Tukaj so navedene najpogosteje uporabljene aplikacije in spremembe na podlagi rutin"</string>
- <string name="hotseat_tip_no_empty_slots" msgid="1325212677738179185">"Če si želite ogledati predlagane aplikacije, povlecite aplikacije iz spodnje vrstice."</string>
- <string name="hotseat_tip_gaps_filled" msgid="3035673010274223538">"Predlagane aplikacije so bile dodane v prazni prostor"</string>
- <string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Predlogi aplikacij so omogočeni."</string>
- <string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Predlogi aplikacij so onemogočeni."</string>
- <string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Predvidena aplikacija: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Pazite, da povlečete s skrajno desnega ali skrajno levega roba."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Pazite, da povlečete z desnega ali levega roba do sredine zaslona in dvignete prst."</string>
- <string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Naučili ste se, kako povlečete z desne za vrnitev. Zdaj se naučite preklapljanja med aplikacijami."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"Izvedli ste potezo za pomik nazaj."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Pazite, da ne povlečete preblizu dna zaslona."</string>
- <string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"Občutljivost poteze za nazaj lahko spremenite v nastavitvah."</string>
- <string name="back_gesture_intro_title" msgid="19551256430224428">"Povlecite za vrnitev"</string>
- <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"Če se želite vrniti na zadnji zaslon, povlecite z levega ali desnega roba do sredine zaslona."</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Pazite, da povlečete s spodnjega roba zaslona navzgor."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Pazite, da ne zaustavite prsta, preden ga dvignete."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Pazite, da povlečete naravnost navzgor."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"Izvedli ste potezo za pomik na začetni zaslon. Zdaj se naučite, kako se pomaknete nazaj."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"Izvedli ste potezo za pomik na začetni zaslon."</string>
- <string name="home_gesture_intro_title" msgid="836590312858441830">"Povlecite za pomik na začetni zaslon"</string>
- <string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Z dna zaslona s prstom povlecite navzgor. S to potezo lahko vedno odprete začetni zaslon."</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Pazite, da povlečete s spodnjega roba zaslona navzgor."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Poskusite okno pridržati dalj časa, preden ga izpustite."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Pazite, da povlečete naravnost navzgor in nato zaustavite prst."</string>
- <string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Naučili ste se uporabljati poteze. Poteze lahko izklopite v nastavitvah."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"Izvedli ste potezo za preklapljanje med aplikacijami."</string>
- <string name="overview_gesture_intro_title" msgid="2902054412868489378">"Povlecite za preklapljanje med aplikacijami"</string>
- <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Za preklapljanje med aplikacijami povlecite navzgor z dna zaslona, pridržite in nato izpustite."</string>
- <string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"Zdaj znate"</string>
- <string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Končano"</string>
- <string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Nastavitve"</string>
- <string name="gesture_tutorial_try_again" msgid="65962545858556697">"Poskusite znova"</string>
- <string name="gesture_tutorial_nice" msgid="2936275692616928280">"Odlično!"</string>
- <string name="gesture_tutorial_step" msgid="1279786122817620968">"Vadnica <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
- <string name="allset_title" msgid="5021126669778966707">"Končano"</string>
- <string name="allset_hint" msgid="2384632994739392447">"Povlecite navzgor za začetni zaslon"</string>
- <string name="allset_description" msgid="6350320429953234580">"Pripravljeni ste, da začnete uporabljati telefon"</string>
- <string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"Nastavitve krmarjenja po sistemu"</annotation></string>
- <string name="action_share" msgid="2648470652637092375">"Deli"</string>
- <string name="action_screenshot" msgid="8171125848358142917">"Posnetek zaslona"</string>
- <string name="action_split" msgid="2098009717623550676">"Razdeli"</string>
- <string name="toast_split_select_app" msgid="5453865907322018352">"Za uporabo razdeljenega zaslona se dotaknite še ene aplikacije."</string>
- <string name="toast_split_app_unsupported" msgid="3271526028981899666">"Aplikacija ne podpira načina razdeljenega zaslona."</string>
- <string name="blocked_by_policy" msgid="2071401072261365546">"Aplikacija ali vaša organizacija ne dovoljuje tega dejanja"</string>
- <string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Želite preskočiti vadnico za krmarjenje?"</string>
- <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"To lahko pozneje najdete v aplikaciji <xliff:g id="NAME">%1$s</xliff:g>."</string>
- <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Prekliči"</string>
- <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Preskoči"</string>
- <string name="accessibility_rotate_button" msgid="4771825231336502943">"Sukanje zaslona"</string>
- <string name="taskbar_edu_opened" msgid="3950252793551919129">"Poučni nasveti o opravilni vrstici so prikazani."</string>
- <string name="taskbar_edu_closed" msgid="126643734478892862">"Poučni nasveti o opravilni vrstici so zaprti."</string>
- <string name="taskbar_edu_switch_apps" msgid="6942863327845784813">"Za preklop aplikacij uporabite opravilno vrstico."</string>
- <string name="taskbar_edu_splitscreen" msgid="2663361731630346489">"Povlecite vstran za uporabo dveh aplikacij hkrati."</string>
- <string name="taskbar_edu_stashing" msgid="5212374387411764031">"Pridržite, če želite opravilno vrstico skriti."</string>
- <string name="taskbar_edu_next" msgid="4007618274426775841">"Naprej"</string>
- <string name="taskbar_edu_previous" msgid="459202320127201702">"Nazaj"</string>
- <string name="taskbar_edu_close" msgid="887022990168191073">"Zapri"</string>
- <string name="taskbar_edu_done" msgid="6880178093977704569">"Končano"</string>
- <string name="taskbar_button_home" msgid="2151398979630664652">"Začetni zaslon"</string>
- <string name="taskbar_button_a11y" msgid="5241161324875094465">"Dostopnost"</string>
- <string name="taskbar_button_back" msgid="8558862226461164514">"Nazaj"</string>
- <string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"Menjava UNV"</string>
- <string name="taskbar_button_recents" msgid="7273376136216613134">"Nedavno"</string>
- <string name="taskbar_button_notifications" msgid="7471740351507357318">"Obvestila"</string>
- <string name="taskbar_button_quick_settings" msgid="227662894293189391">"Hitre nastavitve"</string>
- <string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Premakni na vrh/levo"</string>
- <string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Premakni na dno/desno"</string>
</resources>
diff --git a/quickstep/res/values-sq/strings.xml b/quickstep/res/values-sq/strings.xml
index f2b2fa8520..d8f5f28b42 100644
--- a/quickstep/res/values-sq/strings.xml
+++ b/quickstep/res/values-sq/strings.xml
@@ -19,93 +19,19 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Ekrani i ndarë"</string>
<string name="recent_task_option_pin" msgid="7929860679018978258">"Gozhdo"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Formë e lirë"</string>
+ <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Përmbledhja"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"Nuk ka asnjë artikull të fundit"</string>
+ <string name="accessibility_close_task" msgid="5354563209433803643">"Mbyll"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Cilësimet e përdorimit të aplikacionit"</string>
<string name="recents_clear_all" msgid="5328176793634888831">"Pastroji të gjitha"</string>
<string name="accessibility_recent_apps" msgid="4058661986695117371">"Aplikacionet e fundit"</string>
- <string name="task_view_closed" msgid="9170038230110856166">"Detyra u mbyll"</string>
<string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
<string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 minutë"</string>
<string name="time_left_for_app" msgid="3111996412933644358">"<xliff:g id="TIME">%1$s</xliff:g> të mbetura sot"</string>
- <string name="title_app_suggestions" msgid="4185902664111965088">"Aplikacionet e sugjeruara"</string>
+ <string name="title_app_suggestions" msgid="4185902664111965088">"Sugjerimet e aplikacioneve"</string>
+ <string name="all_apps_label" msgid="8542784161730910663">"Të gjitha aplikacionet"</string>
<string name="all_apps_prediction_tip" msgid="2672336544844936186">"Aplikacionet e tua të parashikuara"</string>
- <string name="hotseat_edu_title_migrate" msgid="306578144424489980">"Merr aplikacione të sugjeruara në rreshtin e poshtëm të ekranit tënd bazë"</string>
- <string name="hotseat_edu_title_migrate_landscape" msgid="3633942953997845243">"Merr aplikacione të sugjeruara në rreshtin e të preferuarave të ekranit tënd bazë"</string>
- <string name="hotseat_edu_message_migrate" msgid="8927179260533775320">"Qasu me lehtësi në aplikacionet më të përdorura direkt në ekranin bazë. Sugjerimet do të ndryshojnë bazuar në rutinat e tua. Aplikacionet në rreshtin e poshtëm do të zhvendosen lart në ekranin tënd bazë."</string>
- <string name="hotseat_edu_message_migrate_landscape" msgid="4248943380443387697">"Qasu me lehtësi në aplikacionet më të përdorura direkt në ekranin bazë. Sugjerimet do të ndryshojnë bazuar në rutinat e tua. Aplikacionet në rreshtin e të preferuarave do të zhvendosen në ekranin tënd bazë."</string>
- <string name="hotseat_edu_message_migrate_alt" msgid="3042360119039646356">"Qasu me lehtësi në aplikacionet më të përdorura, direkt në ekranin bazë. Sugjerimet do të ndryshojnë bazuar në rutinat e tua. Aplikacionet në rreshtin e poshtëm do të zhvendosen në një dosje tjetër."</string>
- <string name="hotseat_edu_accept" msgid="1611544083278999837">"Merr aplikacione të sugjeruara"</string>
- <string name="hotseat_edu_dismiss" msgid="2781161822780201689">"Jo, faleminderit"</string>
- <string name="hotseat_prediction_settings" msgid="6246554993566070818">"Cilësimet"</string>
- <string name="hotseat_auto_enrolled" msgid="522100018967146807">"Aplikacionet më të përdorura shfaqen këtu dhe ndryshojnë bazuar në rutinat"</string>
- <string name="hotseat_tip_no_empty_slots" msgid="1325212677738179185">"Zvarrit aplikacionet jashtë rreshtit të poshtëm për të marrë aplikacione të sugjeruara"</string>
- <string name="hotseat_tip_gaps_filled" msgid="3035673010274223538">"Aplikacionet e sugjeruara u shtuan në hapësirën bosh"</string>
- <string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Aplikacionet e sugjeruara janë aktivizuar"</string>
- <string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Sugjerimet e aplikacioneve janë çaktivizuar"</string>
- <string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Aplikacioni i parashikuar: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Sigurohu që të rrëshqasësh shpejt nga skaji më i djathtë ose më i majtë."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Sigurohu që të rrëshqasësh shpejt nga skaji i djathtë ose i majtë drejt mesit të ekranit dhe lëshoje."</string>
- <string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Ke mësuar si të rrëshqasësh shpejt nga e djathta për t\'u kthyer prapa. Në vijim do të mësosh se si t\'i ndërrosh aplikacionet."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"E ke përfunduar gjestin e kthimit prapa."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Sigurohu që të mos rrëshqasësh shumë afër fundit të ekranit."</string>
- <string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"Për të ndryshuar ndjeshmërinë e gjestit të kthimit prapa, shko te \"Cilësimet\""</string>
- <string name="back_gesture_intro_title" msgid="19551256430224428">"Rrëshqit shpejt për t\'u kthyer prapa"</string>
- <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"Për t\'u kthyer prapa tek ekrani i fundit, rrëshqit shpejt nga skaji i majtë ose i djathtë drejt mesit të ekranit"</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Sigurohu që të rrëshqasësh shpejt lart nga skaji i poshtëm i ekranit."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Sigurohu që të mos ndalosh para se ta lëshosh."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Sigurohu që të rrëshqasësh shpejt drejt lart."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"E ke përfunduar gjestin e kalimit tek ekrani bazë. Në vijim do të mësosh si të kthehesh prapa."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"E ke përfunduar gjestin e kalimit tek ekrani bazë."</string>
- <string name="home_gesture_intro_title" msgid="836590312858441830">"Rrëshqit shpejt për të kaluar tek ekrani bazë"</string>
- <string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Rrëshqit shpejt lart nga fundi i ekranit tënd. Ky gjest të dërgon gjithmonë tek ekrani bazë."</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Sigurohu që të rrëshqasësh shpejt lart nga skaji i poshtëm i ekranit."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Provo ta mbash shtypur dritaren për një kohë më të gjatë para se ta lëshosh."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Sigurohu që të rrëshqasësh shpejt drejt lart dhe më pas ndalo."</string>
- <string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Ke mësuar si të përdorësh gjestet. Për t\'i çaktivizuar gjestet, shko te \"Cilësimet\"."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"E ke përfunduar gjestin e ndërrimit të aplikacioneve."</string>
- <string name="overview_gesture_intro_title" msgid="2902054412868489378">"Rrëshqit shpejt për të ndërruar aplikacionet"</string>
- <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Për të ndërruar mes aplikacioneve, rrëshqit shpejt lart nga fundi i ekranit tënd, mbaj dhe pastaj lësho."</string>
- <string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"Plotësisht gati"</string>
- <string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"U krye"</string>
- <string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Cilësimet"</string>
- <string name="gesture_tutorial_try_again" msgid="65962545858556697">"Provo përsëri"</string>
- <string name="gesture_tutorial_nice" msgid="2936275692616928280">"Bukur!"</string>
- <string name="gesture_tutorial_step" msgid="1279786122817620968">"Udhëzuesi <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
- <string name="allset_title" msgid="5021126669778966707">"Plotësisht gati!"</string>
- <string name="allset_hint" msgid="2384632994739392447">"Rrëshqit shpejt lart për të shkuar tek \"Ekrani bazë\""</string>
- <string name="allset_description" msgid="6350320429953234580">"Je gati për të filluar përdorimin e telefonit tënd"</string>
- <string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"Cilësimet e navigimit të sistemit"</annotation></string>
- <string name="action_share" msgid="2648470652637092375">"Ndaj"</string>
- <string name="action_screenshot" msgid="8171125848358142917">"Pamja e ekranit"</string>
- <string name="action_split" msgid="2098009717623550676">"Ndaj"</string>
- <string name="toast_split_select_app" msgid="5453865907322018352">"Trokit aplikacion tjetër e përdor ekranin e ndarë"</string>
- <string name="toast_split_app_unsupported" msgid="3271526028981899666">"Aplikacioni nuk mbështet ekranin e ndarë."</string>
- <string name="blocked_by_policy" msgid="2071401072261365546">"Ky veprim nuk lejohet nga aplikacioni ose organizata jote"</string>
- <string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Të kapërcehet udhëzuesi i navigimit?"</string>
- <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Këtë mund ta gjesh më vonë tek aplikacioni <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Anulo"</string>
- <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Kapërce"</string>
- <string name="accessibility_rotate_button" msgid="4771825231336502943">"Rrotullo ekranin"</string>
- <string name="taskbar_edu_opened" msgid="3950252793551919129">"Edukimi i shiritit të detyrave u shfaq"</string>
- <string name="taskbar_edu_closed" msgid="126643734478892862">"Edukimi nga shiriti i detyrave u mbyll"</string>
- <string name="taskbar_edu_switch_apps" msgid="6942863327845784813">"Përdor shiritin e detyrave për të ndryshuar aplikacionet"</string>
- <string name="taskbar_edu_splitscreen" msgid="2663361731630346489">"Zvarrit anash për të përdorur të dyja aplikacionet njëherësh"</string>
- <string name="taskbar_edu_stashing" msgid="5212374387411764031">"Preke dhe mbaje prekur për ta fshehur shiritin e detyrave"</string>
- <string name="taskbar_edu_next" msgid="4007618274426775841">"Para"</string>
- <string name="taskbar_edu_previous" msgid="459202320127201702">"Pas"</string>
- <string name="taskbar_edu_close" msgid="887022990168191073">"Mbyll"</string>
- <string name="taskbar_edu_done" msgid="6880178093977704569">"U krye"</string>
- <string name="taskbar_button_home" msgid="2151398979630664652">"Faqja kryesore"</string>
- <string name="taskbar_button_a11y" msgid="5241161324875094465">"Qasshmëria"</string>
- <string name="taskbar_button_back" msgid="8558862226461164514">"Pas"</string>
- <string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"Çelësi IME"</string>
- <string name="taskbar_button_recents" msgid="7273376136216613134">"Të fundit"</string>
- <!-- no translation found for taskbar_button_notifications (7471740351507357318) -->
- <skip />
- <!-- no translation found for taskbar_button_quick_settings (227662894293189391) -->
- <skip />
- <string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Lëviz në krye/majtas"</string>
- <string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Lëviz në fund/djathtas"</string>
</resources>
diff --git a/quickstep/res/values-sr/strings.xml b/quickstep/res/values-sr/strings.xml
index 309aaeb75a..b721641446 100644
--- a/quickstep/res/values-sr/strings.xml
+++ b/quickstep/res/values-sr/strings.xml
@@ -19,91 +19,19 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Подељени екран"</string>
<string name="recent_task_option_pin" msgid="7929860679018978258">"Закачи"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Слободни облик"</string>
+ <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Преглед"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"Нема недавних ставки"</string>
+ <string name="accessibility_close_task" msgid="5354563209433803643">"Затвори"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Подешавања коришћења апликације"</string>
<string name="recents_clear_all" msgid="5328176793634888831">"Обриши све"</string>
<string name="accessibility_recent_apps" msgid="4058661986695117371">"Недавне апликације"</string>
- <string name="task_view_closed" msgid="9170038230110856166">"Задатак је затворен"</string>
<string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
<string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 мин"</string>
<string name="time_left_for_app" msgid="3111996412933644358">"Још <xliff:g id="TIME">%1$s</xliff:g> данас"</string>
<string name="title_app_suggestions" msgid="4185902664111965088">"Предлози апликација"</string>
+ <string name="all_apps_label" msgid="8542784161730910663">"Све апликације"</string>
<string name="all_apps_prediction_tip" msgid="2672336544844936186">"Предвиђене апликације"</string>
- <string name="hotseat_edu_title_migrate" msgid="306578144424489980">"Добијајте предлоге апликација у доњем реду почетног екрана"</string>
- <string name="hotseat_edu_title_migrate_landscape" msgid="3633942953997845243">"Добијајте предлоге апликација у реду са омиљеним ставкама на почетном екрану"</string>
- <string name="hotseat_edu_message_migrate" msgid="8927179260533775320">"Лако приступајте апликацијама које најчешће користите директно са почетног екрана. Предлози се мењају на основу употребе. Апликације из доњег реда се премештају нагоре на почетни екран."</string>
- <string name="hotseat_edu_message_migrate_landscape" msgid="4248943380443387697">"Лако приступајте апликацијама које најчешће користите директно са почетног екрана. Предлози се мењају на основу ваших рутина. Апликације из реда са омиљеним ставкама се премештају на почетни екран."</string>
- <string name="hotseat_edu_message_migrate_alt" msgid="3042360119039646356">"Лако приступајте апликацијама које најчешће користите директно са почетног екрана. Предлози се мењају на основу употребе. Апликације из доњег реда се премештају у нов фолдер."</string>
- <string name="hotseat_edu_accept" msgid="1611544083278999837">"Приказуј предлоге апликација"</string>
- <string name="hotseat_edu_dismiss" msgid="2781161822780201689">"Не, хвала"</string>
- <string name="hotseat_prediction_settings" msgid="6246554993566070818">"Подешавања"</string>
- <string name="hotseat_auto_enrolled" msgid="522100018967146807">"Овде се приказују најчешће коришћене апликације и мењају се у зависности од употребе"</string>
- <string name="hotseat_tip_no_empty_slots" msgid="1325212677738179185">"Превуците апликације из доњег реда да бисте добили предлоге"</string>
- <string name="hotseat_tip_gaps_filled" msgid="3035673010274223538">"Предлози апликација се додају на празно место"</string>
- <string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Предлози апликација су омогућени"</string>
- <string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Предлози апликација су онемогућени"</string>
- <string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Предвиђамо апликацију: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Обавезно превуците од саме десне или леве ивице."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Обавезно превуците од десне или леве ивице до средине екрана и отпустите."</string>
- <string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Научили сте како да превлачите здесна да бисте се вратили уназад. Сада научите да замените апликације."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"Довршили сте покрет за повратак."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Никако не превлачите превише близу дна екрана."</string>
- <string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"Осетљивост пок. за назад можете да промените у Подешавањима"</string>
- <string name="back_gesture_intro_title" msgid="19551256430224428">"Превуците да бисте се вратили уназад"</string>
- <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"Да бисте се вратили на последњи екран, превуците од леве или десне ивице до средине екрана."</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Обавезно превуците нагоре од доње ивице екрана."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Никако не стајте пре отпуштања."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Обавезно превуците право нагоре."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"Довршили сте покрет за повратак на почетну страницу. Сада сазнајте како да се вратите."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"Довршили сте покрет за повратак на почетну страницу."</string>
- <string name="home_gesture_intro_title" msgid="836590312858441830">"Превуците да бисте отишли на почетну страницу"</string>
- <string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Превуците нагоре од дна екрана. Овај покрет вас увек води на почетни екран."</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Обавезно превуците нагоре од доње ивице екрана."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Пробајте да држите прозор дуже пре отпуштања."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Обавезно превуците право нагоре, па застаните."</string>
- <string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Научили сте како да користите покрете. Да бисте искључили покрете, идите на подешавања."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"Довршили сте покрет за промену апликација."</string>
- <string name="overview_gesture_intro_title" msgid="2902054412868489378">"Превуците да бисте заменили апликације"</string>
- <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"За прелазак са једне апликације на другу превуците нагоре од дна екрана, задржите, па пустите."</string>
- <string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"То је то"</string>
- <string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Готово"</string>
- <string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Подешавања"</string>
- <string name="gesture_tutorial_try_again" msgid="65962545858556697">"Пробајте поново"</string>
- <string name="gesture_tutorial_nice" msgid="2936275692616928280">"Свака част!"</string>
- <string name="gesture_tutorial_step" msgid="1279786122817620968">"Водич <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
- <string name="allset_title" msgid="5021126669778966707">"Готово!"</string>
- <string name="allset_hint" msgid="2384632994739392447">"Превуците нагоре да бисте отворили почетни екран"</string>
- <string name="allset_description" msgid="6350320429953234580">"Спремни сте да почнете да користите телефон"</string>
- <string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"Подешавања кретања кроз систем"</annotation></string>
- <string name="action_share" msgid="2648470652637092375">"Дели"</string>
- <string name="action_screenshot" msgid="8171125848358142917">"Снимак екрана"</string>
- <string name="action_split" msgid="2098009717623550676">"Подели"</string>
- <string name="toast_split_select_app" msgid="5453865907322018352">"Додирните другу апликацију за подељени екран"</string>
- <string name="toast_split_app_unsupported" msgid="3271526028981899666">"Апликација не подржава подељени екран."</string>
- <string name="blocked_by_policy" msgid="2071401072261365546">"Апликација или организација не дозвољавају ову радњу"</string>
- <string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Желите да прескочите водич за кретање?"</string>
- <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Можете да пронађете ово касније у апликацији <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Откажи"</string>
- <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Прескочи"</string>
- <string name="accessibility_rotate_button" msgid="4771825231336502943">"Ротирајте екран"</string>
- <string name="taskbar_edu_opened" msgid="3950252793551919129">"Едукативно окно из траке задатака се појавило"</string>
- <string name="taskbar_edu_closed" msgid="126643734478892862">"Едукативно окно из траке задатака је затворено"</string>
- <string name="taskbar_edu_switch_apps" msgid="6942863327845784813">"Користите траку задатака да бисте мењали апликације"</string>
- <string name="taskbar_edu_splitscreen" msgid="2663361731630346489">"Превуците на страну да користите две апликације одједном"</string>
- <string name="taskbar_edu_stashing" msgid="5212374387411764031">"Додирните и задржите за скривање траке задатака"</string>
- <string name="taskbar_edu_next" msgid="4007618274426775841">"Даље"</string>
- <string name="taskbar_edu_previous" msgid="459202320127201702">"Назад"</string>
- <string name="taskbar_edu_close" msgid="887022990168191073">"Затвори"</string>
- <string name="taskbar_edu_done" msgid="6880178093977704569">"Готово"</string>
- <string name="taskbar_button_home" msgid="2151398979630664652">"Почетна"</string>
- <string name="taskbar_button_a11y" msgid="5241161324875094465">"Приступачност"</string>
- <string name="taskbar_button_back" msgid="8558862226461164514">"Назад"</string>
- <string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"IME пребацивач"</string>
- <string name="taskbar_button_recents" msgid="7273376136216613134">"Недавно"</string>
- <string name="taskbar_button_notifications" msgid="7471740351507357318">"Обавештења"</string>
- <string name="taskbar_button_quick_settings" msgid="227662894293189391">"Брза подешавања"</string>
- <string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Премести горе лево"</string>
- <string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Премести доле десно"</string>
</resources>
diff --git a/quickstep/res/values-sv/strings.xml b/quickstep/res/values-sv/strings.xml
index 2f1b75af4e..ba7ebcdec7 100644
--- a/quickstep/res/values-sv/strings.xml
+++ b/quickstep/res/values-sv/strings.xml
@@ -19,93 +19,19 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Delad skärm"</string>
<string name="recent_task_option_pin" msgid="7929860679018978258">"Fäst"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Fritt format"</string>
+ <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Översikt"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"Listan med de senaste åtgärderna är tom"</string>
+ <string name="accessibility_close_task" msgid="5354563209433803643">"Stäng"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Inställningar för appanvändning"</string>
<string name="recents_clear_all" msgid="5328176793634888831">"Rensa alla"</string>
<string name="accessibility_recent_apps" msgid="4058661986695117371">"Senaste apparna"</string>
- <string name="task_view_closed" msgid="9170038230110856166">"Uppgiften har stängts"</string>
<string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
<string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 min"</string>
<string name="time_left_for_app" msgid="3111996412933644358">"<xliff:g id="TIME">%1$s</xliff:g> kvar i dag"</string>
<string name="title_app_suggestions" msgid="4185902664111965088">"Appförslag"</string>
+ <string name="all_apps_label" msgid="8542784161730910663">"Alla appar"</string>
<string name="all_apps_prediction_tip" msgid="2672336544844936186">"Föreslagna appar"</string>
- <string name="hotseat_edu_title_migrate" msgid="306578144424489980">"Få appförslag på den nedersta raden på startskärmen"</string>
- <string name="hotseat_edu_title_migrate_landscape" msgid="3633942953997845243">"Få appförslag på raden Favoriter på startskärmen"</string>
- <string name="hotseat_edu_message_migrate" msgid="8927179260533775320">"Kom enkelt åt de appar du använder mest, direkt från startskärmen. Förslagen ändras efter dina rutiner. Appar på nedersta raden flyttas upp till startskärmen."</string>
- <string name="hotseat_edu_message_migrate_landscape" msgid="4248943380443387697">"Kom enkelt åt de appar du använder mest, direkt från startskärmen. Förslagen ändras efter dina rutiner. Appar på raden Favoriter flyttas till startskärmen."</string>
- <string name="hotseat_edu_message_migrate_alt" msgid="3042360119039646356">"Kom enkelt åt de appar du använder mest, direkt från startskärmen. Förslagen ändras efter dina rutiner. Appar på nedersta raden flyttas till en ny mapp."</string>
- <string name="hotseat_edu_accept" msgid="1611544083278999837">"Få appförslag"</string>
- <string name="hotseat_edu_dismiss" msgid="2781161822780201689">"Nej tack"</string>
- <string name="hotseat_prediction_settings" msgid="6246554993566070818">"Inställningar"</string>
- <string name="hotseat_auto_enrolled" msgid="522100018967146807">"De appar som används mest visas här och ändras efter dina rutiner"</string>
- <string name="hotseat_tip_no_empty_slots" msgid="1325212677738179185">"Dra appar till den nedersta raden om du vill få appförslag"</string>
- <string name="hotseat_tip_gaps_filled" msgid="3035673010274223538">"Appförslag har lagts till på tom yta"</string>
- <string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Appförslag har aktiverats"</string>
- <string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Appförslag har inaktiverats"</string>
- <string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Appförslag: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Se till att du sveper ända från högerkanten eller vänsterkanten."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Se till att du sveper från den högra eller vänstra kanten till mitten av skärmen och sedan släpper."</string>
- <string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Nu kan du svepa från höger för att gå tillbaka. Nu ska du få lära dig hur du byter mellan appar."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"Du är klar med rörelsen för att gå tillbaka."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Se till att du inte sveper för nära skärmens nederkant."</string>
- <string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"Öppna inställningarna om du vill ändra rörelsens känslighet"</string>
- <string name="back_gesture_intro_title" msgid="19551256430224428">"Svep för att återgå"</string>
- <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"Återgå till den senaste skärmen genom att svepa från skärmens vänster- eller högerkant till mitten."</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Se till att du sveper från nederkanten på skärmen."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Se till att du sveper i en jämn rörelse innan du släpper."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Se till att du sveper rakt uppåt."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"Du är klar med rörelsen för att öppna startskärmen. Nu ska du få lära dig hur du går tillbaka."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"Du är klar med rörelsen för att öppna startskärmen."</string>
- <string name="home_gesture_intro_title" msgid="836590312858441830">"Svep för att öppna startskärmen"</string>
- <string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Svep uppåt från skärmens nederkant. Du kan alltid återgå till startskärmen med den här rörelsen."</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Se till att du sveper från nederkanten på skärmen."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Testa att trycka längre på fönstret innan du släpper."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Se till att du sveper rakt uppåt och sedan pausar."</string>
- <string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Du har lärt dig hur du använder rörelser. Om du vill inaktivera rörelser öppnar du inställningarna."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"Du är klar med rörelsen för att byta mellan appar."</string>
- <string name="overview_gesture_intro_title" msgid="2902054412868489378">"Svep för att byta mellan appar"</string>
- <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Byt mellan appar genom att svepa uppåt från skärmens nederkant. Håll fingret nedtryckt och släpp."</string>
- <string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"Klart"</string>
- <string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Klar"</string>
- <string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Inställningar"</string>
- <string name="gesture_tutorial_try_again" msgid="65962545858556697">"Försök igen"</string>
- <string name="gesture_tutorial_nice" msgid="2936275692616928280">"Bra!"</string>
- <string name="gesture_tutorial_step" msgid="1279786122817620968">"Självstudie <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
- <string name="allset_title" msgid="5021126669778966707">"Klart!"</string>
- <string name="allset_hint" msgid="2384632994739392447">"Svep uppåt för att öppna startskärmen"</string>
- <string name="allset_description" msgid="6350320429953234580">"Nu kan du börja använda telefonen"</string>
- <string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"Systemnavigeringsinställningar"</annotation></string>
- <string name="action_share" msgid="2648470652637092375">"Dela"</string>
- <string name="action_screenshot" msgid="8171125848358142917">"Skärmbild"</string>
- <string name="action_split" msgid="2098009717623550676">"Delat"</string>
- <string name="toast_split_select_app" msgid="5453865907322018352">"Tryck på en annan app för att använda delad skärm"</string>
- <string name="toast_split_app_unsupported" msgid="3271526028981899666">"Appen har inte stöd för delad skärm."</string>
- <string name="blocked_by_policy" msgid="2071401072261365546">"Appen eller organisationen tillåter inte den här åtgärden"</string>
- <string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Vill du hoppa över självstudierna?"</string>
- <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Du hittar det här igen i <xliff:g id="NAME">%1$s</xliff:g>-appen"</string>
- <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Avbryt"</string>
- <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Hoppa över"</string>
- <string name="accessibility_rotate_button" msgid="4771825231336502943">"Rotera skärmen"</string>
- <string name="taskbar_edu_opened" msgid="3950252793551919129">"Information om aktivitetsfältet visades"</string>
- <string name="taskbar_edu_closed" msgid="126643734478892862">"Information om aktivitetsfältet stängdes"</string>
- <string name="taskbar_edu_switch_apps" msgid="6942863327845784813">"Använd aktivitetsfältet för att byta mellan appar"</string>
- <string name="taskbar_edu_splitscreen" msgid="2663361731630346489">"Dra till sidan om du vill använda två appar samtidigt"</string>
- <string name="taskbar_edu_stashing" msgid="5212374387411764031">"Tryck länge för att dölja aktivitetsfältet"</string>
- <string name="taskbar_edu_next" msgid="4007618274426775841">"Nästa"</string>
- <string name="taskbar_edu_previous" msgid="459202320127201702">"Tillbaka"</string>
- <string name="taskbar_edu_close" msgid="887022990168191073">"Stäng"</string>
- <string name="taskbar_edu_done" msgid="6880178093977704569">"Klar"</string>
- <string name="taskbar_button_home" msgid="2151398979630664652">"Startsida"</string>
- <string name="taskbar_button_a11y" msgid="5241161324875094465">"Tillgänglighet"</string>
- <string name="taskbar_button_back" msgid="8558862226461164514">"Tillbaka"</string>
- <string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"IME-väljare"</string>
- <string name="taskbar_button_recents" msgid="7273376136216613134">"Senaste"</string>
- <!-- no translation found for taskbar_button_notifications (7471740351507357318) -->
- <skip />
- <!-- no translation found for taskbar_button_quick_settings (227662894293189391) -->
- <skip />
- <string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Flytta högst upp/till vänster"</string>
- <string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Flytta längst ned/till höger"</string>
</resources>
diff --git a/quickstep/res/values-sw/strings.xml b/quickstep/res/values-sw/strings.xml
index e10d447a38..24db429093 100644
--- a/quickstep/res/values-sw/strings.xml
+++ b/quickstep/res/values-sw/strings.xml
@@ -19,91 +19,19 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Gawa skrini"</string>
<string name="recent_task_option_pin" msgid="7929860679018978258">"Bandika"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Muundo huru"</string>
+ <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Muhtasari"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"Hakuna vipengee vya hivi karibuni"</string>
+ <string name="accessibility_close_task" msgid="5354563209433803643">"Funga"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Mipangilio ya matumizi ya programu"</string>
<string name="recents_clear_all" msgid="5328176793634888831">"Ondoa zote"</string>
<string name="accessibility_recent_apps" msgid="4058661986695117371">"Programu za hivi karibuni"</string>
- <string name="task_view_closed" msgid="9170038230110856166">"Jukumu Limefungwa"</string>
<string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
<string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; dak 1"</string>
<string name="time_left_for_app" msgid="3111996412933644358">"Umebakisha <xliff:g id="TIME">%1$s</xliff:g> leo"</string>
<string name="title_app_suggestions" msgid="4185902664111965088">"Mapendekezo ya programu"</string>
+ <string name="all_apps_label" msgid="8542784161730910663">"Programu zote"</string>
<string name="all_apps_prediction_tip" msgid="2672336544844936186">"Programu zako zinazopendekezwa"</string>
- <string name="hotseat_edu_title_migrate" msgid="306578144424489980">"Pata mapendekezo ya programu kwenye sehemu ya chini ya Skrini yako ya kwanza"</string>
- <string name="hotseat_edu_title_migrate_landscape" msgid="3633942953997845243">"Pata mapendekezo ya programu katika safu ya vipendwa ya Skrini yako ya kwanza"</string>
- <string name="hotseat_edu_message_migrate" msgid="8927179260533775320">"Fikia kwa urahisi programu unazotumia sana moja kwa moja kwenye Skrini ya kwanza. Mapendekezo yatabadilika kulingana na ratiba zako. Programu zilizo kwenye sehemu ya chini zitahamishiwa kwenye Skrini yako ya kwanza."</string>
- <string name="hotseat_edu_message_migrate_landscape" msgid="4248943380443387697">"Fikia kwa urahisi programu unazotumia sana moja kwa moja kwenye Skrini ya kwanza. Mapendekezo yatabadilika kulingana na utumiaji wako. Programu zilizo katika safu ya vipendwa zitahamishiwa kwenye Skrini yako ya kwanza."</string>
- <string name="hotseat_edu_message_migrate_alt" msgid="3042360119039646356">"Fikia kwa urahisi programu unazotumia zaidi, moja kwa moja kwenye Skrini ya kwanza. Mapendekezo yatabadilika kulingana na ratiba zako. Programu zilizo kwenye safu ya chini zitahamishiwa kwenye folda mpya."</string>
- <string name="hotseat_edu_accept" msgid="1611544083278999837">"Pata mapendekezo ya programu"</string>
- <string name="hotseat_edu_dismiss" msgid="2781161822780201689">"Hapana"</string>
- <string name="hotseat_prediction_settings" msgid="6246554993566070818">"Mipangilio"</string>
- <string name="hotseat_auto_enrolled" msgid="522100018967146807">"Programu zinazotumiwa zaidi huonekana hapa na hubadilika kulingana na ratiba"</string>
- <string name="hotseat_tip_no_empty_slots" msgid="1325212677738179185">"Buruta programu kutoka kwenye safu ya chini ili upate mapendekezo ya programu"</string>
- <string name="hotseat_tip_gaps_filled" msgid="3035673010274223538">"Mapendekezo ya programu yamewekwa kwenye nafasi isiyo na kitu"</string>
- <string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Mapendekezo ya programu yamewashwa"</string>
- <string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Umezima mapendekezo ya programu"</string>
- <string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Programu iliyotabiriwa: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Hakikisha unatelezesha kidole kuanzia ukingo wa kulia kabisa au ukingo wa kushoto kabisa."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Hakikisha unatelezesha kidole kuanzia ukingo wa kulia au kushoto kuelekea katikati ya skrini na uachilie."</string>
- <string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Umejifunza jinsi ya kutelezesha kidole kuanzia kulia ili kurudi nyuma. Sasa jifunze jinsi ya kubadilisha programu."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"Umekamilisha ishara ya kurudi nyuma."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Hakikisha hutelezeshi kidole karibu sana na sehemu ya chini ya skrini."</string>
- <string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"Kubadilisha hisi ya ishara ya nyuma, nenda kwenye Mipangilio"</string>
- <string name="back_gesture_intro_title" msgid="19551256430224428">"Telezesha kidole ili urudi nyuma"</string>
- <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"Ili urudi kwenye skrini iliyotangulia, telezesha kidole kuanzia ukingo wa kushoto au wa kulia kuelekea katikati ya skrini."</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Hakikisha unatelezesha kidole juu kuanzia ukingo wa chini wa skrini."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Hakikisha kuwa husimamishi kabla ya kuachilia."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Hakikisha unatelezesha kidole kuelekea juu."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"Umekamilisha ishara ya kwenda kwenye Skrini ya kwanza. Sasa jifunze jinsi ya kurudi nyuma."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"Umekamilisha ishara ya kwenda kwenye Skrini ya kwanza."</string>
- <string name="home_gesture_intro_title" msgid="836590312858441830">"Telezesha kidole ili uende kwenye skrini ya kwanza"</string>
- <string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Telezesha kidole juu kuanzia chini ya skrini yako. Ishara hii kila wakati hukupeleka kwenye Skrini ya kwanza."</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Hakikisha unatelezesha kidole juu kuanzia ukingo wa chini wa skrini."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Jaribu kushikilia dirisha kwa muda mrefu kabla ya kuachilia."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Hakikisha unatelezesha kidole kuelekea juu, kisha usimamishe."</string>
- <string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Umejifunza jinsi ya kutumia ishara. Ili uzime ishara, nenda kwenye Mipangilio."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"Umekamilisha ishara ya kubadilisha programu."</string>
- <string name="overview_gesture_intro_title" msgid="2902054412868489378">"Telezesha kidole ili ubadilishe programu"</string>
- <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Ili ubadili kati ya programu, telezesha kidole juu kuanzia sehemu ya chini ya skrini yako, ushikilie, kisha uachilie."</string>
- <string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"Kila kitu kiko tayari"</string>
- <string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Nimemaliza"</string>
- <string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Mipangilio"</string>
- <string name="gesture_tutorial_try_again" msgid="65962545858556697">"Jaribu tena"</string>
- <string name="gesture_tutorial_nice" msgid="2936275692616928280">"Safi!"</string>
- <string name="gesture_tutorial_step" msgid="1279786122817620968">"Mafunzo ya <xliff:g id="CURRENT">%1$d</xliff:g> kati ya <xliff:g id="TOTAL">%2$d</xliff:g>"</string>
- <string name="allset_title" msgid="5021126669778966707">"Tayari!"</string>
- <string name="allset_hint" msgid="2384632994739392447">"Telezesha kidole juu ili uende kwenye skrini ya kwanza"</string>
- <string name="allset_description" msgid="6350320429953234580">"Uko tayari kuanza kutumia simu yako"</string>
- <string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"Mipangilio ya usogezaji kwenye mfumo"</annotation></string>
- <string name="action_share" msgid="2648470652637092375">"Shiriki"</string>
- <string name="action_screenshot" msgid="8171125848358142917">"Picha ya skrini"</string>
- <string name="action_split" msgid="2098009717623550676">"Iliyogawanywa"</string>
- <string name="toast_split_select_app" msgid="5453865907322018352">"Gusa programu nyingine ili utumie skrini iliyogawanywa"</string>
- <string name="toast_split_app_unsupported" msgid="3271526028981899666">"Programu haiwezi kutumia skrini iliyogawanywa."</string>
- <string name="blocked_by_policy" msgid="2071401072261365546">"Kitendo hiki hakiruhusiwi na programu au shirika lako"</string>
- <string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Ungependa kuruka mafunzo ya usogezaji?"</string>
- <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Utapata mafunzo haya baadaye katika programu ya <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Ghairi"</string>
- <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Ruka"</string>
- <string name="accessibility_rotate_button" msgid="4771825231336502943">"Zungusha skrini"</string>
- <string name="taskbar_edu_opened" msgid="3950252793551919129">"Paneli ya elimu kwenye upau wa shughuli inaonyeshwa"</string>
- <string name="taskbar_edu_closed" msgid="126643734478892862">"Paneli ya elimu kwenye upau wa shughuli imefungwa"</string>
- <string name="taskbar_edu_switch_apps" msgid="6942863327845784813">"Tumia upau wa shughuli kubadilisha programu"</string>
- <string name="taskbar_edu_splitscreen" msgid="2663361731630346489">"Buruta pembeni ili utumie programu mbili kwa wakati mmoja"</string>
- <string name="taskbar_edu_stashing" msgid="5212374387411764031">"Gusa na ushikilie ili ufiche upau wa shughuli"</string>
- <string name="taskbar_edu_next" msgid="4007618274426775841">"Endelea"</string>
- <string name="taskbar_edu_previous" msgid="459202320127201702">"Nyuma"</string>
- <string name="taskbar_edu_close" msgid="887022990168191073">"Funga"</string>
- <string name="taskbar_edu_done" msgid="6880178093977704569">"Imemaliza"</string>
- <string name="taskbar_button_home" msgid="2151398979630664652">"Mwanzo"</string>
- <string name="taskbar_button_a11y" msgid="5241161324875094465">"Ufikivu"</string>
- <string name="taskbar_button_back" msgid="8558862226461164514">"Nyuma"</string>
- <string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"Kibadilishaji cha IME"</string>
- <string name="taskbar_button_recents" msgid="7273376136216613134">"Vilivyotumika majuzi"</string>
- <string name="taskbar_button_notifications" msgid="7471740351507357318">"Arifa"</string>
- <string name="taskbar_button_quick_settings" msgid="227662894293189391">"Mipangilio ya Haraka"</string>
- <string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Sogeza juu/kushoto"</string>
- <string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Sogeza chini/kulia"</string>
</resources>
diff --git a/quickstep/res/values-sw600dp-land/dimens.xml b/quickstep/res/values-sw600dp-land/dimens.xml
deleted file mode 100644
index 0cd9b2b700..0000000000
--- a/quickstep/res/values-sw600dp-land/dimens.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?><!--
- * Copyright (c) 2022, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
-*/
--->
-<resources>
- <!-- Overview actions -->
- <dimen name="overview_actions_top_margin">12dp</dimen>
-</resources>
diff --git a/quickstep/res/values-sw600dp/dimens.xml b/quickstep/res/values-sw600dp/dimens.xml
deleted file mode 100644
index 7494683880..0000000000
--- a/quickstep/res/values-sw600dp/dimens.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?><!--
- * Copyright (c) 2021, 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.
-*/
--->
-<resources>
- <dimen name="navigation_key_padding">25dp</dimen>
-
- <!-- Task View -->
- <dimen name="task_thumbnail_icon_size">48dp</dimen>
- <dimen name="task_thumbnail_icon_drawable_size">44dp</dimen>
- <dimen name="overview_task_margin">12dp</dimen>
- <dimen name="task_thumbnail_icon_drawable_size_grid">44dp</dimen>
- <dimen name="overview_task_margin_grid">12dp</dimen>
- <dimen name="overview_grid_row_spacing">28dp</dimen>
- <dimen name="overview_page_spacing">36dp</dimen>
- <dimen name="overview_grid_side_margin">64dp</dimen>
-</resources>
diff --git a/quickstep/res/values-sw720dp-land/dimens.xml b/quickstep/res/values-sw720dp-land/dimens.xml
deleted file mode 100644
index 02d11892dd..0000000000
--- a/quickstep/res/values-sw720dp-land/dimens.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?><!--
- * Copyright (c) 2022, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
-*/
--->
-<resources>
- <!-- Overview actions -->
- <dimen name="overview_actions_top_margin">20dp</dimen>
-</resources>
diff --git a/quickstep/res/values-sw720dp/dimens.xml b/quickstep/res/values-sw720dp/dimens.xml
deleted file mode 100644
index ceaa8f866b..0000000000
--- a/quickstep/res/values-sw720dp/dimens.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?><!--
- * Copyright (c) 2021, 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.
-*/
--->
-<resources>
- <!-- Task View -->
- <dimen name="task_thumbnail_icon_size">48dp</dimen>
- <dimen name="task_thumbnail_icon_drawable_size">44dp</dimen>
- <dimen name="overview_task_margin">16dp</dimen>
- <dimen name="task_thumbnail_icon_drawable_size_grid">44dp</dimen>
- <dimen name="overview_task_margin_grid">16dp</dimen>
- <dimen name="overview_grid_row_spacing">36dp</dimen>
- <dimen name="overview_page_spacing">44dp</dimen>
- <dimen name="overview_grid_side_margin">64dp</dimen>
-</resources>
diff --git a/quickstep/res/values-sw900dp/dimens.xml b/quickstep/res/values-sw900dp/dimens.xml
deleted file mode 100644
index 3efa5e3ecf..0000000000
--- a/quickstep/res/values-sw900dp/dimens.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?><!--
- * Copyright (c) 2021, 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.
-*/
--->
-<resources>
- <!-- The maximum width of the navigation bar ripples. -->
- <dimen name="key_button_ripple_max_width">76dp</dimen>
-
- <!-- The padding around the navigation buttons -->
- <dimen name="navigation_key_padding">0dp</dimen>
-</resources> \ No newline at end of file
diff --git a/quickstep/res/values-ta/strings.xml b/quickstep/res/values-ta/strings.xml
index ebf5eb2627..97d51cd35f 100644
--- a/quickstep/res/values-ta/strings.xml
+++ b/quickstep/res/values-ta/strings.xml
@@ -19,91 +19,19 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="recent_task_option_split_screen" msgid="5353188922202653570">"திரைப் பிரிப்பு"</string>
<string name="recent_task_option_pin" msgid="7929860679018978258">"பின் செய்தல்"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"குறிப்பிட்ட வடிவமில்லாத பயன்முறை"</string>
+ <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"மேலோட்டப் பார்வை"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"சமீபத்தியவை எதுவுமில்லை"</string>
+ <string name="accessibility_close_task" msgid="5354563209433803643">"மூடும்"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"ஆப்ஸ் உபயோக அமைப்புகள்"</string>
<string name="recents_clear_all" msgid="5328176793634888831">"எல்லாம் அழி"</string>
<string name="accessibility_recent_apps" msgid="4058661986695117371">"சமீபத்திய ஆப்ஸ்"</string>
- <string name="task_view_closed" msgid="9170038230110856166">"பணி முடிந்தது"</string>
<string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
<string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 நி"</string>
<string name="time_left_for_app" msgid="3111996412933644358">"இன்று <xliff:g id="TIME">%1$s</xliff:g> மீதமுள்ளது"</string>
<string name="title_app_suggestions" msgid="4185902664111965088">"ஆப்ஸ் பரிந்துரைகள்"</string>
+ <string name="all_apps_label" msgid="8542784161730910663">"அனைத்து ஆப்ஸும்"</string>
<string name="all_apps_prediction_tip" msgid="2672336544844936186">"நீங்கள் கணித்த ஆப்ஸ்"</string>
- <string name="hotseat_edu_title_migrate" msgid="306578144424489980">"முகப்புத் திரையின் கடைசி வரிசையில் ஆப்ஸ் பரிந்துரைகளைப் பெறலாம்"</string>
- <string name="hotseat_edu_title_migrate_landscape" msgid="3633942953997845243">"உங்கள் முகப்புத் திரையின் \'பிடித்தவை\' வரிசையில் ஆப்ஸ் பரிந்துரைகளைப் பெறலாம்"</string>
- <string name="hotseat_edu_message_migrate" msgid="8927179260533775320">"அதிகமாகப் பயன்படுத்திய ஆப்ஸை முகப்புத் திரையிலேயே அணுகலாம். உங்கள் வழக்கங்களின் அடிப்படையில் பரிந்துரைகள் மாறும். கடைசி வரிசையிலுள்ள ஆப்ஸ் உங்கள் முகப்புத் திரைக்கு நகர்த்தப்படும்."</string>
- <string name="hotseat_edu_message_migrate_landscape" msgid="4248943380443387697">"அதிகமாகப் பயன்படுத்திய ஆப்ஸை முகப்புத் திரையிலேயே எளிதாக அணுகலாம். உங்கள் வழக்கங்களின் அடிப்படையில் பரிந்துரைகள் மாறும். பிடித்தவை வரிசையில் உள்ள ஆப்ஸ் உங்கள் முகப்புத் திரைக்கு நகர்த்தப்படும்."</string>
- <string name="hotseat_edu_message_migrate_alt" msgid="3042360119039646356">"அதிகமாகப் பயன்படுத்திய ஆப்ஸை முகப்புத் திரையிலேயே அணுகலாம். உங்கள் வழக்கங்களின் அடிப்படையில் பரிந்துரைகள் மாறும். கடைசி வரிசையிலுள்ள ஆப்ஸ் புதிய ஃபோல்டருக்கு நகர்த்தப்படும்."</string>
- <string name="hotseat_edu_accept" msgid="1611544083278999837">"ஆப்ஸ் பரிந்துரைகளைப் பெறுக"</string>
- <string name="hotseat_edu_dismiss" msgid="2781161822780201689">"வேண்டாம்"</string>
- <string name="hotseat_prediction_settings" msgid="6246554993566070818">"அமைப்புகள்"</string>
- <string name="hotseat_auto_enrolled" msgid="522100018967146807">"அதிகமாகப் பயன்படுத்திய ஆப்ஸ் இங்கே தோன்றும், வழக்கங்களின் அடிப்படையில் அவை மாறும்"</string>
- <string name="hotseat_tip_no_empty_slots" msgid="1325212677738179185">"ஆப்ஸ் பரிந்துரைகளைப் பெற கடைசி வரிசையிலிருந்து ஆப்ஸை இழுக்கவும்"</string>
- <string name="hotseat_tip_gaps_filled" msgid="3035673010274223538">"ஆப்ஸ் பரிந்துரைகள் காலி இடத்தில் சேர்க்கப்பட்டன"</string>
- <string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"ஆப்ஸ் பரிந்துரைகள் இயக்கப்பட்டுள்ளன"</string>
- <string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"ஆப்ஸ் பரிந்துரைகள் முடக்கப்பட்டுள்ளன"</string>
- <string name="hotseat_prediction_content_description" msgid="4582028296938078419">"கணித்த ஆப்ஸ்: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"வலது அல்லது இடது ஓரத்தின் விளிம்பிலிருந்து ஸ்வைப் செய்வதை உறுதிசெய்க."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"வலது அல்லது இடது ஓரத்திலிருந்து திரையின் மையப் பகுதிக்கு ஸ்வைப் செய்தபிறகு விடுவிப்பதை உறுதிசெய்க."</string>
- <string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"பின்செல்வதற்கு எப்படி வலதுபுறத்திலிருந்து ஸ்வைப் செய்வதென்று கற்றுக்கொண்டீர்கள். அடுத்து ஆப்ஸுக்கிடையே எப்படி மாறுவது என்பதை அறிக."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"பின்செல் சைகைப் பயிற்சியை முடித்துவிட்டீர்கள்."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"திரையின் கீழ்பகுதிக்கு மிக நெருக்கமாக ஸ்வைப் செய்யவில்லை என்பதை உறுதிசெய்துகொள்ளுங்கள்."</string>
- <string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"பின்செல் சைகையின் உணர்திறனை மாற்ற அமைப்புகளுக்குச் செல்க"</string>
- <string name="back_gesture_intro_title" msgid="19551256430224428">"பின்செல்ல ஸ்வைப் செய்யுங்கள்"</string>
- <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"முந்தைய திரைக்கு மீண்டும் செல்ல, இடது/வலது ஓரத்திலிருந்து திரையின் மையப் பகுதிக்கு ஸ்வைப் செய்க."</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"திரையின் கீழ் ஓரத்திலிருந்து மேல்நோக்கி ஸ்வைப் செய்வதை உறுதிசெய்துகொள்ளுங்கள்."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"விடுவிப்பதற்கு முன்பாக இடைநிறுத்தவில்லை என்பதை உறுதிசெய்துகொள்ளுங்கள்."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"மேல்நோக்கி நேராக ஸ்வைப் செய்வதை உறுதிசெய்துகொள்ளுங்கள்."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"முகப்புக்குச் செல் சைகைப் பயிற்சியை முடித்துவிட்டீர்கள். அடுத்து, பின்செல்வது எப்படி என்பதை அறிக."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"முகப்புக்குச் செல் சைகைப் பயிற்சியை முடித்துவிட்டீர்கள்."</string>
- <string name="home_gesture_intro_title" msgid="836590312858441830">"முகப்புக்குச் செல்ல ஸ்வைப் செய்யுங்கள்"</string>
- <string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"திரையின் கீழிருந்து மேலாக ஸ்வைப் செய்க. இந்தச் சைகை எப்போதும் முகப்புத் திரைக்கு அழைத்துச் செல்லும்."</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"திரையின் கீழ் ஓரத்திலிருந்து மேல்நோக்கி ஸ்வைப் செய்வதை உறுதிசெய்துகொள்ளுங்கள்."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"விடுவிப்பதற்கு முன்பாக நீண்டநேரம் சாளரத்தை அழுத்திப் பிடித்திருங்கள்."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"மேல்நோக்கி நேராக ஸ்வைப் செய்தபிறகு இடைநிறுத்துவதை உறுதிசெய்துகொள்ளுங்கள்."</string>
- <string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"சைகைகளை எப்படி உபயோகிப்பது என்று கற்றுக்கொண்டீர்கள். சைகைகளை முடக்க அமைப்புகளுக்குச் செல்லுங்கள்."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"ஆப்ஸுக்கிடையே மாறும் சைகைப் பயிற்சியை முடித்துவிட்டீர்கள்."</string>
- <string name="overview_gesture_intro_title" msgid="2902054412868489378">"ஆப்ஸுக்கிடையே மாற ஸ்வைப் செய்யுங்கள்"</string>
- <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"ஆப்ஸுக்கு இடையே மாற, திரையின் கீழிலிருந்து மேலாக ஸ்வைப் செய்து, பிடித்திருந்து, பிறகு விடுவிக்கவும்."</string>
- <string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"எல்லாம் தயார்"</string>
- <string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"முடிந்தது"</string>
- <string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"அமைப்புகள்"</string>
- <string name="gesture_tutorial_try_again" msgid="65962545858556697">"மீண்டும் முயல்க"</string>
- <string name="gesture_tutorial_nice" msgid="2936275692616928280">"அருமை!"</string>
- <string name="gesture_tutorial_step" msgid="1279786122817620968">"பயிற்சி <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
- <string name="allset_title" msgid="5021126669778966707">"அனைத்தையும் அமைத்துவிட்டீர்கள்!"</string>
- <string name="allset_hint" msgid="2384632994739392447">"முகப்புத் திரைக்குச் செல்ல மேல்நோக்கி ஸ்வைப் செய்யுங்கள்"</string>
- <string name="allset_description" msgid="6350320429953234580">"மொபைலைப் பயன்படுத்தத் தயாராகிவிட்டீர்கள்"</string>
- <string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"சிஸ்டம் வழிசெலுத்தல் அமைப்புகள்"</annotation></string>
- <string name="action_share" msgid="2648470652637092375">"பகிர்"</string>
- <string name="action_screenshot" msgid="8171125848358142917">"ஸ்கிரீன்ஷாட்"</string>
- <string name="action_split" msgid="2098009717623550676">"பிரி"</string>
- <string name="toast_split_select_app" msgid="5453865907322018352">"ஸ்பிளிட் ஸ்கிரீனுக்கு மற்றொரு ஆப்ஸைத் தட்டவும்"</string>
- <string name="toast_split_app_unsupported" msgid="3271526028981899666">"திரைப் பிரிப்பு அம்சத்தை ஆப்ஸ் ஆதரிக்கவில்லை."</string>
- <string name="blocked_by_policy" msgid="2071401072261365546">"ஆப்ஸோ உங்கள் நிறுவனமோ இந்த செயலை அனுமதிப்பதில்லை"</string>
- <string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"வழிகாட்டுதல் பயிற்சியைத் தவிர்க்கவா?"</string>
- <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"<xliff:g id="NAME">%1$s</xliff:g> ஆப்ஸில் பிறகு இதைக் கண்டறியலாம்"</string>
- <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"ரத்துசெய்"</string>
- <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"தவிர்"</string>
- <string name="accessibility_rotate_button" msgid="4771825231336502943">"திரையைச் சுழற்றும்"</string>
- <string name="taskbar_edu_opened" msgid="3950252793551919129">"பணிப்பட்டியை எவ்வாறு பயன்படுத்துவது என்பது பற்றிய பலகம் காட்டப்படுகிறது"</string>
- <string name="taskbar_edu_closed" msgid="126643734478892862">"பணிப்பட்டியை எவ்வாறு பயன்படுத்துவது என்பது பற்றிய பலகம் மூடப்பட்டது"</string>
- <string name="taskbar_edu_switch_apps" msgid="6942863327845784813">"ஆப்ஸிற்கு இடையே மாற பணிப்பட்டியைப் பயன்படுத்தவும்"</string>
- <string name="taskbar_edu_splitscreen" msgid="2663361731630346489">"ஒரே நேரத்தில் இரு ஆப்ஸை உபயோகிக்க பக்கவாட்டிற்கு இழுக்கவும்"</string>
- <string name="taskbar_edu_stashing" msgid="5212374387411764031">"பணிப்பட்டியை மறைக்கத் தொட்டுப் பிடிக்கவும்"</string>
- <string name="taskbar_edu_next" msgid="4007618274426775841">"அடுத்து"</string>
- <string name="taskbar_edu_previous" msgid="459202320127201702">"பின்செல்"</string>
- <string name="taskbar_edu_close" msgid="887022990168191073">"மூடுக"</string>
- <string name="taskbar_edu_done" msgid="6880178093977704569">"முடிந்தது"</string>
- <string name="taskbar_button_home" msgid="2151398979630664652">"முகப்பு"</string>
- <string name="taskbar_button_a11y" msgid="5241161324875094465">"அணுகல்தன்மை"</string>
- <string name="taskbar_button_back" msgid="8558862226461164514">"பின்செல்லும்"</string>
- <string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"IME சுவிட்ச்சர்"</string>
- <string name="taskbar_button_recents" msgid="7273376136216613134">"சமீபத்தியவை"</string>
- <string name="taskbar_button_notifications" msgid="7471740351507357318">"அறிவிப்புகள்"</string>
- <string name="taskbar_button_quick_settings" msgid="227662894293189391">"விரைவு அமைப்புகள்"</string>
- <string name="move_drop_target_top_or_left" msgid="2988702185049595807">"மேலே/இடதுபுறம் நகர்த்தும்"</string>
- <string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"கீழே/வலதுபுறம் நகர்த்தும்"</string>
</resources>
diff --git a/quickstep/res/values-te/strings.xml b/quickstep/res/values-te/strings.xml
index 8f43b3c385..24b37f75d4 100644
--- a/quickstep/res/values-te/strings.xml
+++ b/quickstep/res/values-te/strings.xml
@@ -19,91 +19,19 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="recent_task_option_split_screen" msgid="5353188922202653570">"స్క్రీన్‌ని విభజించు"</string>
<string name="recent_task_option_pin" msgid="7929860679018978258">"పిన్ చేయి"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"సంప్రదాయేతర"</string>
+ <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"అవలోకనం"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"ఇటీవలి అంశాలు ఏవీ లేవు"</string>
+ <string name="accessibility_close_task" msgid="5354563209433803643">"మూసివేయండి"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"యాప్ వినియోగ సెట్టింగ్‌లు"</string>
<string name="recents_clear_all" msgid="5328176793634888831">"అన్నీ తీసివేయండి"</string>
<string name="accessibility_recent_apps" msgid="4058661986695117371">"ఇటీవలి యాప్‌లు"</string>
- <string name="task_view_closed" msgid="9170038230110856166">"టాస్క్ మూసివేయబడింది"</string>
<string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
<string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 నిమిషం"</string>
<string name="time_left_for_app" msgid="3111996412933644358">"నేటికి <xliff:g id="TIME">%1$s</xliff:g> మిగిలి ఉంది"</string>
- <string name="title_app_suggestions" msgid="4185902664111965088">"యాప్ సలహాలు"</string>
+ <string name="title_app_suggestions" msgid="4185902664111965088">"యాప్ సూచనలు"</string>
+ <string name="all_apps_label" msgid="8542784161730910663">"అన్ని యాప్‌లు"</string>
<string name="all_apps_prediction_tip" msgid="2672336544844936186">"మీ సూచించబడిన యాప్‌లు"</string>
- <string name="hotseat_edu_title_migrate" msgid="306578144424489980">"మీ మొదటి స్క్రీన్‌ దిగువ వరుసలో యాప్ సలహాలను పొందండి"</string>
- <string name="hotseat_edu_title_migrate_landscape" msgid="3633942953997845243">"మీ హోమ్ స్క్రీన్‌లోని ఇష్టమైన వాటి వరుసలో యాప్ సూచ‌న‌లు పొందండి"</string>
- <string name="hotseat_edu_message_migrate" msgid="8927179260533775320">"మీరు ఎక్కువగా ఉపయోగించే యాప్‌లను నేరుగా మొదటి స్క్రీన్‌లోనే సులభంగా యాక్సెస్ చేయండి. మీ రోజువారీ యాక్టివిటీలను బట్టి సూచనలు మారతాయి. దిగువ వరుసలోని యాప్‌లు మీ మొదటి స్క్రీన్ పైకి చేరుకుంటాయి."</string>
- <string name="hotseat_edu_message_migrate_landscape" msgid="4248943380443387697">"మీరు ఎక్కువగా ఉపయోగించే యాప్‌లను నేరుగా మొదటి స్క్రీన్‌లోనే సులభంగా యాక్సెస్ చేయండి. మీ రోజువారీ యాక్టివిటీలను బట్టి సూచనలు మారతాయి. ఇష్టమైన వాటి వరుసలోని యాప్‌లు మీ మొదటి స్క్రీన్‌కు చేరుకుంటాయి."</string>
- <string name="hotseat_edu_message_migrate_alt" msgid="3042360119039646356">"మీరు ఎక్కువగా ఉపయోగించే యాప్‌లను నేరుగా మొదటి స్క్రీన్‌లోనే సులభంగా యాక్సెస్ చేయండి. మీ రోజువారీ యాక్టివిటీలను బట్టి సూచనలు మారతాయి. దిగువ వరుసలోని యాప్‌లు కొత్త ఫోల్డర్‌కు తరలించబడతాయి."</string>
- <string name="hotseat_edu_accept" msgid="1611544083278999837">"యాప్ సూచ‌న‌లను పొందండి"</string>
- <string name="hotseat_edu_dismiss" msgid="2781161822780201689">"వద్దు"</string>
- <string name="hotseat_prediction_settings" msgid="6246554993566070818">"సెట్టింగ్‌లు"</string>
- <string name="hotseat_auto_enrolled" msgid="522100018967146807">"ఎక్కువగా ఉపయోగించిన యాప్‌లు ఇక్కడ కనిపిస్తాయి, అవి రోజువారీ యాక్టివిటీలను బట్టి మారుతూ ఉంటాయి"</string>
- <string name="hotseat_tip_no_empty_slots" msgid="1325212677738179185">"యాప్ సలహాలను పొందడానికి దిగువ వరుస నుండి యాప్‌లను లాగండి"</string>
- <string name="hotseat_tip_gaps_filled" msgid="3035673010274223538">"యాప్ సూచ‌న‌లు ఖాళీ స్పేస్‌కు జోడించబడ్డాయి"</string>
- <string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"యాప్ సలహాలు ఎనేబుల్ చేయబడ్డాయి"</string>
- <string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"యాప్ సూచ‌న‌లు డిజేబుల్‌ చేయబడ్డాయి"</string>
- <string name="hotseat_prediction_content_description" msgid="4582028296938078419">"సూచించబడిన యాప్: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"కుడి వైపు చిట్ట చివరి లేదా ఎడమ వైపు చిట్ట చివరి అంచు నుండి స్వైప్ చేస్తున్నారని నిర్ధారించుకోండి."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"మీరు కుడి లేదా ఎడమ అంచు నుండి స్క్రీన్ మధ్యలోకి స్వైప్ చేశారని నిర్ధారించుకోని, మీ వేలిని ఎత్తండి."</string>
- <string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"వెనుకకు వెళ్లడానికి కుడి నుండి స్వైప్ ఎలానో మీకు తెలుసు. తర్వాత, యాప్‌ల మధ్య ఎలా మారాలో తెలుసుకోండి."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"మీరు తిరిగి వెనక్కు వెళ్లే సంజ్ఞను పూర్తి చేశారు."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"మీరు స్క్రీన్ దిగువకు చాలా దగ్గరగా స్వైప్ చేయలేదని నిర్ధారించుకోండి."</string>
- <string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"వెనుక సంజ్ఞ సున్నితత్వం మార్చడానికి, సెట్టింగ్‌లకు వెళ్లండి"</string>
- <string name="back_gesture_intro_title" msgid="19551256430224428">"వెనుకకు వెళ్ళడం కోసం స్వైప్ చేయండి"</string>
- <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"మునుపటి స్క్రీన్‌కు తిరిగి వెళ్లడానికి, ఎడమ లేదా కుడి అంచు నుండి స్క్రీన్ మధ్యలోకి స్వైప్ చేయండి."</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"మీరు స్క్రీన్ దిగువ అంచు నుండి పైకి స్వయిప్ చేస్తున్నారని నిర్ధారించుకోండి."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"బయలుదేరే ముందు మీరు పాజ్ చేయకుండా చూసుకోండి."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"మీరు నేరుగా పైకి స్వైప్ చేశారని నిర్ధారించుకోండి."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"మీరు మొదటి స్క్రీన్‌కు వెళ్లే సంజ్ఞను పూర్తి చేశారు. తర్వాత, వెనుకకు ఎలా వెళ్లాలో తెలుసుకోండి."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"మీరు మొదటి ట్యాబ్‌కు వెళ్లే సంజ్ఞను పూర్తి చేశారు."</string>
- <string name="home_gesture_intro_title" msgid="836590312858441830">"మొదటి స్క్రీన్‌కు వెళ్లడానికి స్వైప్ చేయండి"</string>
- <string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"స్క్రీన్ కింది నుండి పైకి స్వైప్ చేయండి. ఈ సంజ్ఞ ఎప్పుడూ మిమ్మల్ని మొదటి స్క్రీన్‌కు తీసుకెళ్తుంది."</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"మీరు స్క్రీన్ దిగువ అంచు నుండి పైకి స్వయిప్ చేస్తున్నారని నిర్ధారించుకోండి."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"రిలీజ్ చేయడానికి ముందు విండోను ఎక్కువసేపు పట్టుకోడానికి ట్రై చేయండి."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"మీరు నేరుగా స్వైప్ చేశారని నిర్ధారించుకోండి, ఆపై పాజ్ చేయండి."</string>
- <string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"మీరు సంజ్ఞలను ఎలా ఉపయోగించాలో నేర్చుకున్నారు. సంజ్ఞలను ఆఫ్ చేయడానికి, సెట్టింగ్‌లకు వెళ్లండి."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"మీరు \'యాప్‌ల మధ్య మార్పు\' సంజ్ఞను పూర్తి చేశారు."</string>
- <string name="overview_gesture_intro_title" msgid="2902054412868489378">"యాప్‌ల మధ్య మార్చడం కోసం స్వైప్ చేయండి"</string>
- <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"యాప్‌ల మధ్య మారడానికి, మీ స్క్రీన్ కింది వైపు నుండి పైకి స్వైప్ చేసి, పట్టుకుని, తర్వాత వదలండి."</string>
- <string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"అంతా సిద్ధంగా ఉంది"</string>
- <string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"పూర్తయింది"</string>
- <string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"సెట్టింగ్‌లు"</string>
- <string name="gesture_tutorial_try_again" msgid="65962545858556697">"మళ్లీ ట్రై చేయండి"</string>
- <string name="gesture_tutorial_nice" msgid="2936275692616928280">"పనితీరు బాగుంది!"</string>
- <string name="gesture_tutorial_step" msgid="1279786122817620968">"ట్యుటోరియల్ <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
- <string name="allset_title" msgid="5021126669778966707">"అంతా సెట్ అయింది!"</string>
- <string name="allset_hint" msgid="2384632994739392447">"మొదటి స్క్రీన్‌కు వెళ్లడానికి పైకి స్వైప్ చేయండి"</string>
- <string name="allset_description" msgid="6350320429953234580">"మీరు మీ ఫోన్‌ను ఉపయోగించడానికి సిద్ధంగా ఉన్నారు"</string>
- <string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"సిస్టమ్ నావిగేషన్ సెట్టింగ్‌లు"</annotation></string>
- <string name="action_share" msgid="2648470652637092375">"షేర్ చేయండి"</string>
- <string name="action_screenshot" msgid="8171125848358142917">"స్క్రీన్‌షాట్"</string>
- <string name="action_split" msgid="2098009717623550676">"స్ప్లిట్ చేయండి"</string>
- <string name="toast_split_select_app" msgid="5453865907322018352">"స్క్రీన్ విభజనను ఉపయోగించడానికి మరొక యాప్ నొక్కండి"</string>
- <string name="toast_split_app_unsupported" msgid="3271526028981899666">"యాప్‌లో స్ప్లిట్-స్క్రీన్ పని చేయదు."</string>
- <string name="blocked_by_policy" msgid="2071401072261365546">"ఈ చర్యను యాప్ గానీ, మీ సంస్థ గానీ అనుమతించవు"</string>
- <string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"నావిగేషన్ ట్యుటోరియల్‌ను స్కిప్ చేయాలా?"</string>
- <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"<xliff:g id="NAME">%1$s</xliff:g> యాప్‌లో మీరు తర్వాత కనుగొనవచ్చు"</string>
- <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"రద్దు చేయి"</string>
- <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"స్కిప్ చేయి"</string>
- <string name="accessibility_rotate_button" msgid="4771825231336502943">"స్క్రీన్‌ను తిప్పండి"</string>
- <string name="taskbar_edu_opened" msgid="3950252793551919129">"టాస్క్‌బార్ శిక్షణకు సంబంధించిన ప్యానెల్ కనిపించింది"</string>
- <string name="taskbar_edu_closed" msgid="126643734478892862">"టాస్క్‌బార్ శిక్షణకు సంబంధించిన ప్యానెల్ మూసివేయబడింది"</string>
- <string name="taskbar_edu_switch_apps" msgid="6942863327845784813">"యాప్‌లను స్విచ్ చేయడానికి టాస్క్‌బార్‌ను ఉపయోగించండి"</string>
- <string name="taskbar_edu_splitscreen" msgid="2663361731630346489">"ఒకేసారి రెండు యాప్‌లను ఉపయోగించడానికి పక్కకు లాగండి"</string>
- <string name="taskbar_edu_stashing" msgid="5212374387411764031">"టాస్క్‌బార్‌ను దాచడానికి తాకి, నొక్కి ఉంచండి"</string>
- <string name="taskbar_edu_next" msgid="4007618274426775841">"తర్వాత"</string>
- <string name="taskbar_edu_previous" msgid="459202320127201702">"వెనుకకు"</string>
- <string name="taskbar_edu_close" msgid="887022990168191073">"మూసివేయండి"</string>
- <string name="taskbar_edu_done" msgid="6880178093977704569">"పూర్తయింది"</string>
- <string name="taskbar_button_home" msgid="2151398979630664652">"మొదటి ట్యాబ్"</string>
- <string name="taskbar_button_a11y" msgid="5241161324875094465">"యాక్సెసిబిలిటీ"</string>
- <string name="taskbar_button_back" msgid="8558862226461164514">"వెనుకకు"</string>
- <string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"IME స్విచ్చర్"</string>
- <string name="taskbar_button_recents" msgid="7273376136216613134">"ఇటీవలివి"</string>
- <string name="taskbar_button_notifications" msgid="7471740351507357318">"నోటిఫికేషన్‌లు"</string>
- <string name="taskbar_button_quick_settings" msgid="227662894293189391">"క్విక్ సెట్టింగ్‌లు"</string>
- <string name="move_drop_target_top_or_left" msgid="2988702185049595807">"ఎగువ/ఎడమ వైపునకు తరలించండి"</string>
- <string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"దిగువ/కుడి వైపునకు తరలించండి"</string>
</resources>
diff --git a/quickstep/res/values-th/strings.xml b/quickstep/res/values-th/strings.xml
index 62ab2d2c6c..0f6821bf19 100644
--- a/quickstep/res/values-th/strings.xml
+++ b/quickstep/res/values-th/strings.xml
@@ -19,91 +19,19 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="recent_task_option_pin" msgid="7929860679018978258">"ปักหมุด"</string>
+ <string name="recent_task_option_split_screen" msgid="5353188922202653570">"แยกหน้าจอ"</string>
+ <string name="recent_task_option_pin" msgid="7929860679018978258">"ตรึง"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"รูปแบบอิสระ"</string>
+ <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"ภาพรวม"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"ไม่มีรายการล่าสุด"</string>
+ <string name="accessibility_close_task" msgid="5354563209433803643">"ปิด"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"การตั้งค่าการใช้แอป"</string>
<string name="recents_clear_all" msgid="5328176793634888831">"ล้างทั้งหมด"</string>
<string name="accessibility_recent_apps" msgid="4058661986695117371">"แอปล่าสุด"</string>
- <string name="task_view_closed" msgid="9170038230110856166">"ปิดงานแล้ว"</string>
<string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g> <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
<string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt;1 นาที"</string>
<string name="time_left_for_app" msgid="3111996412933644358">"วันนี้เหลืออีก <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="title_app_suggestions" msgid="4185902664111965088">"คำแนะนำเกี่ยวกับแอป"</string>
+ <string name="all_apps_label" msgid="8542784161730910663">"แอปทั้งหมด"</string>
<string name="all_apps_prediction_tip" msgid="2672336544844936186">"แอปที่คาดการณ์ไว้"</string>
- <string name="hotseat_edu_title_migrate" msgid="306578144424489980">"ดูแอปแนะนำที่แถวล่างของหน้าจอหลัก"</string>
- <string name="hotseat_edu_title_migrate_landscape" msgid="3633942953997845243">"รับคำแนะนำเกี่ยวกับแอปในแถวรายการโปรดของหน้าจอหลัก"</string>
- <string name="hotseat_edu_message_migrate" msgid="8927179260533775320">"เข้าถึงแอปที่คุณใช้มากที่สุดได้อย่างง่ายดายจากหน้าจอหลัก คำแนะนำจะเปลี่ยนไปตามแอปที่ใช้งานเป็นประจำ แอปในแถวล่างจะย้ายขึ้นมาอยู่ในหน้าจอหลัก"</string>
- <string name="hotseat_edu_message_migrate_landscape" msgid="4248943380443387697">"เข้าถึงแอปที่ใช้มากที่สุดได้อย่างง่ายดายในหน้าจอหลัก คำแนะนำจะเปลี่ยนไปตามการใช้งานประจำ แอปในแถวรายการโปรดจะย้ายไปอยู่ในหน้าจอหลัก"</string>
- <string name="hotseat_edu_message_migrate_alt" msgid="3042360119039646356">"เข้าถึงแอปที่คุณใช้มากที่สุดได้อย่างง่ายดายจากหน้าจอหลัก คำแนะนำจะเปลี่ยนไปตามแอปที่ใช้งานเป็นประจำ แอปในแถวล่างจะย้ายไปอยู่ในโฟลเดอร์ใหม่"</string>
- <string name="hotseat_edu_accept" msgid="1611544083278999837">"ดูแอปแนะนำ"</string>
- <string name="hotseat_edu_dismiss" msgid="2781161822780201689">"ไม่เป็นไร"</string>
- <string name="hotseat_prediction_settings" msgid="6246554993566070818">"การตั้งค่า"</string>
- <string name="hotseat_auto_enrolled" msgid="522100018967146807">"แอปที่ใช้มากที่สุดจะปรากฎที่นี่และจะเปลี่ยนไปตามการใช้งานประจำ"</string>
- <string name="hotseat_tip_no_empty_slots" msgid="1325212677738179185">"ลากแอปออกจากแถวล่างเพื่อดูแอปแนะนำ"</string>
- <string name="hotseat_tip_gaps_filled" msgid="3035673010274223538">"เพิ่มคำแนะนำเกี่ยวกับแอปในพื้นที่ว่างแล้ว"</string>
- <string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"เปิดใช้แอปแนะนำแล้ว"</string>
- <string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"ปิดใช้คำแนะนำเกี่ยวกับแอปอยู่"</string>
- <string name="hotseat_prediction_content_description" msgid="4582028296938078419">"แอปที่คาดว่าจะใช้: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"ตรวจสอบว่าปัดจากขอบด้านขวาสุดหรือซ้ายสุด"</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"ตรวจสอบว่าปัดจากขอบด้านขวาหรือซ้ายไปตรงกลางหน้าจอ แล้วยกนิ้วขึ้น"</string>
- <string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"คุณรู้วิธีปัดจากด้านขวาเพื่อย้อนกลับแล้ว ต่อไปดูวิธีสลับแอป"</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"คุณทำท่าทางสัมผัสเพื่อย้อนกลับเสร็จแล้ว"</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"ตรวจสอบว่าไม่ได้ปัดใกล้กับด้านล่างของหน้าจอมากเกินไป"</string>
- <string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"เปลี่ยนความไวของท่าทางสัมผัสเพื่อย้อนกลับได้ที่การตั้งค่า"</string>
- <string name="back_gesture_intro_title" msgid="19551256430224428">"ปัดเพื่อย้อนกลับ"</string>
- <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"หากต้องการย้อนกลับไปที่หน้าจอล่าสุด ให้ปัดจากขอบด้านซ้ายหรือขวาไปตรงกลางหน้าจอ"</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"ปัดขึ้นจากขอบด้านล่างของหน้าจอ"</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"ตรวจสอบว่าไม่มีการหยุดชั่วคราวก่อนยกนิ้วขึ้น"</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"ตรวจสอบว่าปัดขึ้นในแนวตรง"</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"คุณทำท่าทางสัมผัสเพื่อไปที่หน้าแรกเสร็จแล้ว ต่อไปดูวิธีย้อนกลับ"</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"คุณทำท่าทางสัมผัสเพื่อไปที่หน้าแรกเสร็จแล้ว"</string>
- <string name="home_gesture_intro_title" msgid="836590312858441830">"ปัดเพื่อไปที่หน้าแรก"</string>
- <string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"ปัดขึ้นจากด้านล่างของหน้าจอ ท่าทางสัมผัสนี้จะนำคุณไปที่หน้าจอหลักเสมอ"</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"ปัดขึ้นจากขอบด้านล่างของหน้าจอ"</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"ลองแตะหน้าต่างค้างไว้นานขึ้นก่อนปล่อยนิ้ว"</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"ตรวจสอบว่าปัดขึ้นในแนวตรง แล้วหยุดชั่วคราว"</string>
- <string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"คุณรู้วิธีใช้ท่าทางสัมผัสแล้ว หากต้องการปิดท่าทางสัมผัส ให้ไปที่การตั้งค่า"</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"คุณทำท่าทางสัมผัสเพื่อสลับแอปเสร็จแล้ว"</string>
- <string name="overview_gesture_intro_title" msgid="2902054412868489378">"ปัดเพื่อสลับแอป"</string>
- <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"หากต้องการสลับระหว่างแอปต่างๆ ให้ปัดขึ้นจากด้านล่างของหน้าจอ ค้างไว้ แล้วปล่อย"</string>
- <string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"เรียบร้อย"</string>
- <string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"เสร็จสิ้น"</string>
- <string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"การตั้งค่า"</string>
- <string name="gesture_tutorial_try_again" msgid="65962545858556697">"ลองอีกครั้ง"</string>
- <string name="gesture_tutorial_nice" msgid="2936275692616928280">"ดีมาก"</string>
- <string name="gesture_tutorial_step" msgid="1279786122817620968">"บทแนะนำ <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
- <string name="allset_title" msgid="5021126669778966707">"เรียบร้อยแล้ว"</string>
- <string name="allset_hint" msgid="2384632994739392447">"ปัดขึ้นเพื่อไปที่หน้าแรก"</string>
- <string name="allset_description" msgid="6350320429953234580">"คุณเริ่มใช้โทรศัพท์ได้แล้ว"</string>
- <string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"การตั้งค่าการนำทางของระบบ"</annotation></string>
- <string name="action_share" msgid="2648470652637092375">"แชร์"</string>
- <string name="action_screenshot" msgid="8171125848358142917">"ภาพหน้าจอ"</string>
- <string name="action_split" msgid="2098009717623550676">"แยก"</string>
- <string name="toast_split_select_app" msgid="5453865907322018352">"แตะที่แอปอื่นเพื่อใช้แบ่งหน้าจอ"</string>
- <string name="toast_split_app_unsupported" msgid="3271526028981899666">"แอปไม่รองรับการแบ่งหน้าจอ"</string>
- <string name="blocked_by_policy" msgid="2071401072261365546">"แอปหรือองค์กรของคุณไม่อนุญาตการดำเนินการนี้"</string>
- <string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"ข้ามบทแนะนำการนำทางไหม"</string>
- <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"คุณดูบทแนะนำนี้ได้ภายหลังในแอป \"<xliff:g id="NAME">%1$s</xliff:g>\""</string>
- <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"ยกเลิก"</string>
- <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"ข้าม"</string>
- <string name="accessibility_rotate_button" msgid="4771825231336502943">"หมุนหน้าจอ"</string>
- <string name="taskbar_edu_opened" msgid="3950252793551919129">"แถบงาน Education ปรากฎขึ้น"</string>
- <string name="taskbar_edu_closed" msgid="126643734478892862">"ปิดแถบงาน Education แล้ว"</string>
- <string name="taskbar_edu_switch_apps" msgid="6942863327845784813">"ใช้แถบงานเพื่อเปลี่ยนแอป"</string>
- <string name="taskbar_edu_splitscreen" msgid="2663361731630346489">"ลากไปด้านข้างเพื่อใช้ 2 แอปพร้อมกัน"</string>
- <string name="taskbar_edu_stashing" msgid="5212374387411764031">"แตะค้างไว้เพื่อซ่อนแถบงาน"</string>
- <string name="taskbar_edu_next" msgid="4007618274426775841">"ถัดไป"</string>
- <string name="taskbar_edu_previous" msgid="459202320127201702">"กลับ"</string>
- <string name="taskbar_edu_close" msgid="887022990168191073">"ปิด"</string>
- <string name="taskbar_edu_done" msgid="6880178093977704569">"เสร็จ"</string>
- <string name="taskbar_button_home" msgid="2151398979630664652">"หน้าแรก"</string>
- <string name="taskbar_button_a11y" msgid="5241161324875094465">"การช่วยเหลือพิเศษ"</string>
- <string name="taskbar_button_back" msgid="8558862226461164514">"กลับ"</string>
- <string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"ตัวเปลี่ยน IME"</string>
- <string name="taskbar_button_recents" msgid="7273376136216613134">"ล่าสุด"</string>
- <string name="taskbar_button_notifications" msgid="7471740351507357318">"การแจ้งเตือน"</string>
- <string name="taskbar_button_quick_settings" msgid="227662894293189391">"การตั้งค่าด่วน"</string>
- <string name="move_drop_target_top_or_left" msgid="2988702185049595807">"ย้ายไปที่ด้านบนหรือด้านซ้าย"</string>
- <string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"ย้ายไปที่ด้านล่างหรือด้านขวา"</string>
</resources>
diff --git a/quickstep/res/values-tl/strings.xml b/quickstep/res/values-tl/strings.xml
index 3ecae96b30..491bac5bd9 100644
--- a/quickstep/res/values-tl/strings.xml
+++ b/quickstep/res/values-tl/strings.xml
@@ -19,93 +19,19 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Hatiin ang screen"</string>
<string name="recent_task_option_pin" msgid="7929860679018978258">"I-pin"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Freeform"</string>
+ <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Overview"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"Walang kamakailang item"</string>
+ <string name="accessibility_close_task" msgid="5354563209433803643">"Isara"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Mga setting ng paggamit ng app"</string>
<string name="recents_clear_all" msgid="5328176793634888831">"I-clear lahat"</string>
<string name="accessibility_recent_apps" msgid="4058661986695117371">"Mga kamakailang app"</string>
- <string name="task_view_closed" msgid="9170038230110856166">"Isinara ang Gawain"</string>
<string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
<string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 min"</string>
<string name="time_left_for_app" msgid="3111996412933644358">"<xliff:g id="TIME">%1$s</xliff:g> na lang ngayon"</string>
<string name="title_app_suggestions" msgid="4185902664111965088">"Mga iminumungkahing app"</string>
+ <string name="all_apps_label" msgid="8542784161730910663">"Lahat ng app"</string>
<string name="all_apps_prediction_tip" msgid="2672336544844936186">"Iyong mga nahulaang app"</string>
- <string name="hotseat_edu_title_migrate" msgid="306578144424489980">"Makakuha ng mga suhestyon sa app sa ibabang row ng iyong Home screen"</string>
- <string name="hotseat_edu_title_migrate_landscape" msgid="3633942953997845243">"Makakuha ng mga iminumungkahing app sa row ng mga paborito ng iyong Home screen"</string>
- <string name="hotseat_edu_message_migrate" msgid="8927179260533775320">"Madaling ma-access ang mga pinakaginagamit mong app nang direkta sa Home screen. Magbabago ang mga suhestyon batay sa iyong mga routine. Mapupunta sa iyong Home screen ang mga app na nasa ibabang row."</string>
- <string name="hotseat_edu_message_migrate_landscape" msgid="4248943380443387697">"Madaling ma-access ang mga pinakaginagamit mong app nang direkta sa Home screen. Magbabago ang mga suhestyon batay sa iyong mga routine. Mapupunta sa iyong Home screen ang mga app sa row ng mga paborito."</string>
- <string name="hotseat_edu_message_migrate_alt" msgid="3042360119039646356">"Madaling ma-access ang mga pinakaginagamit mong app, direkta sa Home screen. Magbabago ang mga suhestyon batay sa iyong mga routine. Mapupunta sa isang bagong folder ang mga app na nasa ibabang row."</string>
- <string name="hotseat_edu_accept" msgid="1611544083278999837">"Kumuha ng mga suhestiyon sa app"</string>
- <string name="hotseat_edu_dismiss" msgid="2781161822780201689">"Huwag na lang"</string>
- <string name="hotseat_prediction_settings" msgid="6246554993566070818">"Mga Setting"</string>
- <string name="hotseat_auto_enrolled" msgid="522100018967146807">"Ipinapakita ang mga pinakaginagamit na app dito, at nababago ito batay sa mga routine"</string>
- <string name="hotseat_tip_no_empty_slots" msgid="1325212677738179185">"I-drag ang mga app mula sa ibabang row para makakuha ng mga suhestyon sa app"</string>
- <string name="hotseat_tip_gaps_filled" msgid="3035673010274223538">"Idinagdag sa bakanteng espasyo ang mga iminumungkahing app"</string>
- <string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Naka-enable ang mga iminumungkahing app"</string>
- <string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Naka-disable ang mga iminumungkahing app"</string>
- <string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Hinulaang app: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Tiyaking magsa-swipe ka mula sa dulong kanan o dulong kaliwang gilid."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Tiyaking mag-swipe mula sa kanan o kaliwang gilid papunta sa gitna ng screen at iangat ang daliri."</string>
- <string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Natuto kang mag-swipe mula sa kanan para bumalik. Sunod, alamin kung paano magpalipat-lipat ng app."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"Nakumpleto mo na ang galaw para bumalik."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Tiyaking hindi ka magsa-swipe nang masyadong malapit sa ibaba ng screen."</string>
- <string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"Pumunta sa Settings para baguhin ang sensitivity ng pagbalik"</string>
- <string name="back_gesture_intro_title" msgid="19551256430224428">"Mag-swipe para bumalik"</string>
- <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"Para bumalik sa nakaraang screen, mag-swipe mula sa kaliwa o kanang gilid patungo sa gitna ng screen."</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Tiyaking magsa-swipe ka pataas mula sa pinakaibaba ng screen."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Tiyaking hindi ka magpo-pause bago iangat ang iyong daliri."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Tiyaking magsa-swipe ka nang diretso pataas."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"Nakumpleto mo na ang galaw para pumunta sa Home. Susunod, alamin kung paano bumalik."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"Nakumpleto mo na ang galaw para pumunta sa Home."</string>
- <string name="home_gesture_intro_title" msgid="836590312858441830">"Mag-swipe para pumunta sa home"</string>
- <string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Mag-swipe pataas mula sa ibaba ng iyong screen. Dadalhin ka palagi ng galaw na ito sa Home screen."</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Tiyaking magsa-swipe ka pataas mula sa pinakaibaba ng screen."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Subukang pindutin nang mas matagal ang window bago ito bitawan."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Tiyaking magsa-swipe ka nang diretso pataas, pagkatapos ay mag-pause."</string>
- <string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Alam mo na kung paano gumamit ng mga galaw. Para i-off ang mga galaw, pumunta sa Mga Setting."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"Nakumpleto mo na ang galaw para magpalipat-lipat sa mga app."</string>
- <string name="overview_gesture_intro_title" msgid="2902054412868489378">"Mag-swipe para lumipat ng app"</string>
- <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Para lumipat ng app, mag-swipe pataas mula sa ibaba ng iyong screen, mag-hold, at iangat ang daliri."</string>
- <string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"Handa na ang lahat"</string>
- <string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Tapos na"</string>
- <string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Mga Setting"</string>
- <string name="gesture_tutorial_try_again" msgid="65962545858556697">"Subukan ulit"</string>
- <string name="gesture_tutorial_nice" msgid="2936275692616928280">"Magaling!"</string>
- <string name="gesture_tutorial_step" msgid="1279786122817620968">"Tutorial <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
- <string name="allset_title" msgid="5021126669778966707">"Handa na ang lahat!"</string>
- <string name="allset_hint" msgid="2384632994739392447">"Mag-swipe pataas para pumunta sa Home"</string>
- <string name="allset_description" msgid="6350320429953234580">"Handa mo nang simulan ang paggamit sa iyong telepono"</string>
- <string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"Mga setting ng navigation ng system"</annotation></string>
- <string name="action_share" msgid="2648470652637092375">"Ibahagi"</string>
- <string name="action_screenshot" msgid="8171125848358142917">"Screenshot"</string>
- <string name="action_split" msgid="2098009717623550676">"Split"</string>
- <string name="toast_split_select_app" msgid="5453865907322018352">"Mag-tap ng ibang app para gamitin ang splitscreen"</string>
- <string name="toast_split_app_unsupported" msgid="3271526028981899666">"Hindi sinusuportahan ng app ang split-screen."</string>
- <string name="blocked_by_policy" msgid="2071401072261365546">"Hindi pinapayagan ng app o ng iyong organisasyon ang pagkilos na ito"</string>
- <string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Laktawan ang tutorial sa pag-navigate?"</string>
- <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Makikita mo ito sa <xliff:g id="NAME">%1$s</xliff:g> app sa ibang pagkakataon"</string>
- <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Kanselahin"</string>
- <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Laktawan"</string>
- <string name="accessibility_rotate_button" msgid="4771825231336502943">"I-rotate ang screen"</string>
- <string name="taskbar_edu_opened" msgid="3950252793551919129">"Lumabas ang edukasyon sa taskbar"</string>
- <string name="taskbar_edu_closed" msgid="126643734478892862">"Sarado ang edukasyon sa taskbar"</string>
- <string name="taskbar_edu_switch_apps" msgid="6942863327845784813">"Gamitin ang taskbar para magpalipat-lipat sa mga app"</string>
- <string name="taskbar_edu_splitscreen" msgid="2663361731630346489">"I-drag sa gilid para makagamit ng dalawang app nang sabay"</string>
- <string name="taskbar_edu_stashing" msgid="5212374387411764031">"Pindutin nang matagal para itago ang taskbar"</string>
- <string name="taskbar_edu_next" msgid="4007618274426775841">"Susunod"</string>
- <string name="taskbar_edu_previous" msgid="459202320127201702">"Bumalik"</string>
- <string name="taskbar_edu_close" msgid="887022990168191073">"Isara"</string>
- <string name="taskbar_edu_done" msgid="6880178093977704569">"Tapos na"</string>
- <string name="taskbar_button_home" msgid="2151398979630664652">"Home"</string>
- <string name="taskbar_button_a11y" msgid="5241161324875094465">"Accessibility"</string>
- <string name="taskbar_button_back" msgid="8558862226461164514">"Bumalik"</string>
- <string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"IME switcher"</string>
- <string name="taskbar_button_recents" msgid="7273376136216613134">"Mga Kamakailan"</string>
- <!-- no translation found for taskbar_button_notifications (7471740351507357318) -->
- <skip />
- <!-- no translation found for taskbar_button_quick_settings (227662894293189391) -->
- <skip />
- <string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Ilipat sa itaas/kaliwa"</string>
- <string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Ilipat sa ibaba/kanan"</string>
</resources>
diff --git a/quickstep/res/values-tr/strings.xml b/quickstep/res/values-tr/strings.xml
index 19ced47d01..ec6d88405c 100644
--- a/quickstep/res/values-tr/strings.xml
+++ b/quickstep/res/values-tr/strings.xml
@@ -19,93 +19,19 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Bölünmüş ekran"</string>
<string name="recent_task_option_pin" msgid="7929860679018978258">"Sabitle"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Serbest çalışma"</string>
+ <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Genel bakış"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"Yeni öğe yok"</string>
+ <string name="accessibility_close_task" msgid="5354563209433803643">"Kapat"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Uygulama kullanım ayarları"</string>
<string name="recents_clear_all" msgid="5328176793634888831">"Tümünü temizle"</string>
<string name="accessibility_recent_apps" msgid="4058661986695117371">"Son uygulamalar"</string>
- <string name="task_view_closed" msgid="9170038230110856166">"Görev Kapatıldı"</string>
<string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
<string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 dk."</string>
<string name="time_left_for_app" msgid="3111996412933644358">"Bugün <xliff:g id="TIME">%1$s</xliff:g> kaldı"</string>
- <string name="title_app_suggestions" msgid="4185902664111965088">"Önerilen uygulamalar"</string>
+ <string name="title_app_suggestions" msgid="4185902664111965088">"Uygulama önerileri"</string>
+ <string name="all_apps_label" msgid="8542784161730910663">"Tüm uygulamalar"</string>
<string name="all_apps_prediction_tip" msgid="2672336544844936186">"Tahmin edilen uygulamalarınız"</string>
- <string name="hotseat_edu_title_migrate" msgid="306578144424489980">"Ana ekranınızın alt satırında uygulama önerileri alın"</string>
- <string name="hotseat_edu_title_migrate_landscape" msgid="3633942953997845243">"Ana ekranınızın favoriler satırında uygulama önerileri alın"</string>
- <string name="hotseat_edu_message_migrate" msgid="8927179260533775320">"En çok kullanılan uygulamalarınıza Ana ekranda kolayca erişin. Öneriler, rutinlerinize dayalı olarak değişir. Alt satırdaki uygulamalar, yukarı taşınarak Ana ekranınıza alınır."</string>
- <string name="hotseat_edu_message_migrate_landscape" msgid="4248943380443387697">"En çok kullanılan uygulamalarınıza Ana ekrandan kolayca erişin. Öneriler rutinlerinize dayalı olarak değişir. Favoriler satırındaki uygulamalar Ana ekranınıza taşınır."</string>
- <string name="hotseat_edu_message_migrate_alt" msgid="3042360119039646356">"En çok kullanılan uygulamalarınıza Ana ekranda kolayca erişin. Öneriler, rutinlerinize dayalı olarak değişir. Alt satırdaki uygulamalar yeni bir klasöre taşınır."</string>
- <string name="hotseat_edu_accept" msgid="1611544083278999837">"Uygulama önerileri al"</string>
- <string name="hotseat_edu_dismiss" msgid="2781161822780201689">"Hayır, teşekkürler"</string>
- <string name="hotseat_prediction_settings" msgid="6246554993566070818">"Ayarlar"</string>
- <string name="hotseat_auto_enrolled" msgid="522100018967146807">"En çok kullanılan uygulamalar burada görünür ve rutinlere dayalı olarak değişir"</string>
- <string name="hotseat_tip_no_empty_slots" msgid="1325212677738179185">"Önerilen uygulamaları almak için alt satırdaki uygulamaları dışarı sürükleyin"</string>
- <string name="hotseat_tip_gaps_filled" msgid="3035673010274223538">"Önerilen uygulamalar boş alana eklendi"</string>
- <string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Uygulama önerileri etkinleştirildi"</string>
- <string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Uygulama önerileri devre dışı bırakıldı"</string>
- <string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Tahmin edilen uygulama: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"En sağ veya en sol kenardan kaydırdığınızdan emin olun."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Ekranın sağ veya sol kenarından ortasına doğru sürükleyip bıraktığınızdan emin olun."</string>
- <string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Geri dönmek için sağdan kaydırmayı öğrendiniz. Sırada uygulamalar arasında geçiş yapma var."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"Geri dön hareketini tamamladınız."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Ekranın alt kısmına çok yakın bir şekilde kaydırmadığınızdan emin olun."</string>
- <string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"Geri hareketinin hassasiyetini değiştirmek için Ayarlar\'a gidin"</string>
- <string name="back_gesture_intro_title" msgid="19551256430224428">"Geri dönmek için kaydırma"</string>
- <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"Son ekrana geri gitmek için sol veya sağ kenardan ekranın ortasına doğru kaydırın."</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Ekranın alt kenarından yukarı kaydırdığınızdan emin olun."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Bırakmadan önce parmağınızı duraklatmadığınızdan emin olun."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Düz bir şekilde yukarı kaydırdığınızdan emin olun."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"Ana ekrana git hareketini tamamladınız. Şimdi nasıl geri döneceğinizi öğreneceksiniz."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"Ana ekrana git hareketini tamamladınız."</string>
- <string name="home_gesture_intro_title" msgid="836590312858441830">"Ana ekrana gitmek için kaydırma"</string>
- <string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Ekranın alt kısmından yukarıya doğru kaydırın. Bu hareket sizi her zaman Ana ekrana götürür."</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Ekranın alt kenarından yukarı kaydırdığınızdan emin olun."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Bırakmadan önce pencereyi daha uzun süre tutmayı deneyin."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Düz bir şekilde yukarı kaydırıp ardından parmağınızı duraklattığınızdan emin olun."</string>
- <string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Hareketleri nasıl kullanacağınızı öğrendiniz. Hareketleri kapatmak için Ayarlar\'a gidin."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"Uygulamalar arasında geçiş yapma hareketini tamamladınız."</string>
- <string name="overview_gesture_intro_title" msgid="2902054412868489378">"Uygulamalar arasında geçiş yapmak için kaydırma"</string>
- <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Uygulamalar arasında geçiş yapmak için ekranınızın altından yukarı kaydırıp basılı tutun ve sonra bırakın."</string>
- <string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"Hepsi bu kadar"</string>
- <string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Bitti"</string>
- <string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Ayarlar"</string>
- <string name="gesture_tutorial_try_again" msgid="65962545858556697">"Tekrar deneyin"</string>
- <string name="gesture_tutorial_nice" msgid="2936275692616928280">"Güzel!"</string>
- <string name="gesture_tutorial_step" msgid="1279786122817620968">"Eğitim <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
- <string name="allset_title" msgid="5021126669778966707">"İşlem tamam!"</string>
- <string name="allset_hint" msgid="2384632994739392447">"Ana ekrana gitmek için yukarı kaydırın"</string>
- <string name="allset_description" msgid="6350320429953234580">"Telefonunuzu kullanmaya hazırsınız"</string>
- <string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"Sistem gezinme ayarları"</annotation></string>
- <string name="action_share" msgid="2648470652637092375">"Paylaş"</string>
- <string name="action_screenshot" msgid="8171125848358142917">"Ekran görüntüsü"</string>
- <string name="action_split" msgid="2098009717623550676">"Böl"</string>
- <string name="toast_split_select_app" msgid="5453865907322018352">"Bölünmüş ekran için başka bir uygulamaya dokunun"</string>
- <string name="toast_split_app_unsupported" msgid="3271526028981899666">"Uygulama bölünmüş ekranı desteklemiyor."</string>
- <string name="blocked_by_policy" msgid="2071401072261365546">"Uygulamanız veya kuruluşunuz bu işleme izin vermiyor"</string>
- <string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Gezinme eğitimi atlansın mı?"</string>
- <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Bunu daha sonra <xliff:g id="NAME">%1$s</xliff:g> uygulamasında bulabilirsiniz"</string>
- <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"İptal"</string>
- <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Atla"</string>
- <string name="accessibility_rotate_button" msgid="4771825231336502943">"Ekranı döndür"</string>
- <string name="taskbar_edu_opened" msgid="3950252793551919129">"Görev çubuğu eğitimi görüntülendi"</string>
- <string name="taskbar_edu_closed" msgid="126643734478892862">"Görev çubuğu eğitimi kapatıldı"</string>
- <string name="taskbar_edu_switch_apps" msgid="6942863327845784813">"Görev çubuğundan uygulamalar arasında geçiş yapabilirsiniz"</string>
- <string name="taskbar_edu_splitscreen" msgid="2663361731630346489">"Tek seferde iki uygulamayı kullanmak için yana sürükleyin"</string>
- <string name="taskbar_edu_stashing" msgid="5212374387411764031">"Görev çubuğunu gizlemek için basılı tutun"</string>
- <string name="taskbar_edu_next" msgid="4007618274426775841">"İleri"</string>
- <string name="taskbar_edu_previous" msgid="459202320127201702">"Geri"</string>
- <string name="taskbar_edu_close" msgid="887022990168191073">"Kapat"</string>
- <string name="taskbar_edu_done" msgid="6880178093977704569">"Bitti"</string>
- <string name="taskbar_button_home" msgid="2151398979630664652">"Ana ekran"</string>
- <string name="taskbar_button_a11y" msgid="5241161324875094465">"Erişilebilirlik"</string>
- <string name="taskbar_button_back" msgid="8558862226461164514">"Geri"</string>
- <string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"IME değiştirici"</string>
- <string name="taskbar_button_recents" msgid="7273376136216613134">"Son Kullanılanlar"</string>
- <!-- no translation found for taskbar_button_notifications (7471740351507357318) -->
- <skip />
- <!-- no translation found for taskbar_button_quick_settings (227662894293189391) -->
- <skip />
- <string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Sol üste taşı"</string>
- <string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Sağ alta taşı"</string>
</resources>
diff --git a/quickstep/res/values-uk/strings.xml b/quickstep/res/values-uk/strings.xml
index 231d128aca..77360625db 100644
--- a/quickstep/res/values-uk/strings.xml
+++ b/quickstep/res/values-uk/strings.xml
@@ -19,93 +19,19 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Розділити екран"</string>
<string name="recent_task_option_pin" msgid="7929860679018978258">"Закріпити"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Довільна форма"</string>
+ <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Огляд"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"Немає нещодавніх додатків"</string>
+ <string name="accessibility_close_task" msgid="5354563209433803643">"Закрити"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Налаштування використання додатка"</string>
<string name="recents_clear_all" msgid="5328176793634888831">"Очистити все"</string>
<string name="accessibility_recent_apps" msgid="4058661986695117371">"Нещодавні додатки"</string>
- <string name="task_view_closed" msgid="9170038230110856166">"Завдання закрито"</string>
<string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
<string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 хв"</string>
<string name="time_left_for_app" msgid="3111996412933644358">"Сьогодні залишилося <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <string name="title_app_suggestions" msgid="4185902664111965088">"Рекомендовані додатки"</string>
+ <string name="title_app_suggestions" msgid="4185902664111965088">"Пропозиції додатків"</string>
+ <string name="all_apps_label" msgid="8542784161730910663">"Усі додатки"</string>
<string name="all_apps_prediction_tip" msgid="2672336544844936186">"Передбачені додатки"</string>
- <string name="hotseat_edu_title_migrate" msgid="306578144424489980">"Рекомендовані додатки з\'являтимуться в нижньому рядку головного екрана"</string>
- <string name="hotseat_edu_title_migrate_landscape" msgid="3633942953997845243">"Рекомендовані додатки з\'являтимуться в рядку \"Вибране\" на головному екрані"</string>
- <string name="hotseat_edu_message_migrate" msgid="8927179260533775320">"З легкістю відкривайте на головному екрані ті додатки, які використовуєте найчастіше. Рекомендації змінюватимуться залежно від ваших дій. Додатки в нижньому рядку перемістяться на головний екран."</string>
- <string name="hotseat_edu_message_migrate_landscape" msgid="4248943380443387697">"З легкістю відкривайте найпотрібніші додатки просто з головного екрана. Рекомендації змінюватимуться залежно від ваших дій. Додатки з рядка \"Вибране\" буде переміщено на головний екран."</string>
- <string name="hotseat_edu_message_migrate_alt" msgid="3042360119039646356">"З легкістю відкривайте найвикористовуваніші додатки просто з головного екрана. Рекомендації змінюватимуться залежно від ваших дій. Додатки в нижньому рядку буде переміщено в нову папку."</string>
- <string name="hotseat_edu_accept" msgid="1611544083278999837">"Показувати рекомендації"</string>
- <string name="hotseat_edu_dismiss" msgid="2781161822780201689">"Не потрібно"</string>
- <string name="hotseat_prediction_settings" msgid="6246554993566070818">"Налаштування"</string>
- <string name="hotseat_auto_enrolled" msgid="522100018967146807">"Тут з\'являються найвикористовуваніші додатки, список яких змінюється залежно від ваших дій"</string>
- <string name="hotseat_tip_no_empty_slots" msgid="1325212677738179185">"Щоб побачити рекомендовані додатки, перетягніть наявні з нижнього рядка"</string>
- <string name="hotseat_tip_gaps_filled" msgid="3035673010274223538">"Рекомендовані додатки додано у вільну область"</string>
- <string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Рекомендовані додатки ввімкнено"</string>
- <string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Рекомендовані додатки вимкнено"</string>
- <string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Передбачений додаток: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Проведіть пальцем саме від правого або лівого краю екрана."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Проведіть пальцем від правого або лівого краю до середини екрана й підніміть палець."</string>
- <string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Тепер ви знаєте, як повернутися на попередній екран, провівши пальцем справа наліво. Дізнайтеся, як переключатися між додатками."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"Ви виконали жест \"Назад\"."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Не проводьте пальцем надто близько до нижнього краю екрана."</string>
- <string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"Щоб змінити чутливість жесту \"Назад\", відкрийте налаштування"</string>
- <string name="back_gesture_intro_title" msgid="19551256430224428">"Щоб повернутися, проведіть пальцем по екрану"</string>
- <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"Щоб перейти на попередній екран, проведіть пальцем від лівого чи правого краю до середини екрана."</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Проведіть пальцем угору від нижнього краю екрана."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Не робіть паузу перед тим, як відірвати палець від екрана."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Проводьте пальцем вертикально вгору."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"Ви виконали жест переходу на головний екран. Тепер дізнайтеся, як повернутися."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"Ви виконали жест переходу на головний екран."</string>
- <string name="home_gesture_intro_title" msgid="836590312858441830">"Проведіть пальцем, щоб перейти на головний екран"</string>
- <string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Проведіть пальцем по екрану знизу вгору. Цей жест завжди повертатиме вас на головний екран."</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Проведіть пальцем угору від нижнього краю екрана."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Спробуйте втримувати вікно довше, перш ніж відпустити."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Проведіть пальцем вертикально вгору, а тоді зробіть паузу."</string>
- <string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Ви вивчили жести. Щоб вимкнути їх, перейдіть у налаштування."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"Ви виконали жест переходу в інший додаток."</string>
- <string name="overview_gesture_intro_title" msgid="2902054412868489378">"Проведіть пальцем, щоб перейти в інший додаток"</string>
- <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Щоб переключатися між додатками, проведіть знизу вгору по екрану, утримуйте палець, а потім відпустіть."</string>
- <string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"Усе готово!"</string>
- <string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Готово"</string>
- <string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Налаштування"</string>
- <string name="gesture_tutorial_try_again" msgid="65962545858556697">"Спробуйте ще"</string>
- <string name="gesture_tutorial_nice" msgid="2936275692616928280">"Чудово!"</string>
- <string name="gesture_tutorial_step" msgid="1279786122817620968">"Навчальний посібник <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
- <string name="allset_title" msgid="5021126669778966707">"Готово."</string>
- <string name="allset_hint" msgid="2384632994739392447">"Щоб перейти на головний екран, проведіть пальцем угору"</string>
- <string name="allset_description" msgid="6350320429953234580">"Тепер ви можете користуватися телефоном"</string>
- <string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"Системні налаштування навігації"</annotation></string>
- <string name="action_share" msgid="2648470652637092375">"Поділитися"</string>
- <string name="action_screenshot" msgid="8171125848358142917">"Знімок екрана"</string>
- <string name="action_split" msgid="2098009717623550676">"Розділити"</string>
- <string name="toast_split_select_app" msgid="5453865907322018352">"Щоб розділити екран, виберіть ще один додаток"</string>
- <string name="toast_split_app_unsupported" msgid="3271526028981899666">"Додаток не підтримує розділення екрана."</string>
- <string name="blocked_by_policy" msgid="2071401072261365546">"Ця дія заборонена додатком або адміністратором організації"</string>
- <string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Пропустити посібник із навігації?"</string>
- <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Ви знайдете його пізніше в додатку <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Скасувати"</string>
- <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Пропустити"</string>
- <string name="accessibility_rotate_button" msgid="4771825231336502943">"Обернути екран"</string>
- <string name="taskbar_edu_opened" msgid="3950252793551919129">"Панель завдань Education відкрито"</string>
- <string name="taskbar_edu_closed" msgid="126643734478892862">"Панель завдань Education закрито"</string>
- <string name="taskbar_edu_switch_apps" msgid="6942863327845784813">"Переходьте між додатками за допомогою панелі завдань"</string>
- <string name="taskbar_edu_splitscreen" msgid="2663361731630346489">"Перетягніть убік, щоб використовувати два додатки одночасно"</string>
- <string name="taskbar_edu_stashing" msgid="5212374387411764031">"Натисніть і втримуйте панель завдань, щоб сховати її"</string>
- <string name="taskbar_edu_next" msgid="4007618274426775841">"Далі"</string>
- <string name="taskbar_edu_previous" msgid="459202320127201702">"Назад"</string>
- <string name="taskbar_edu_close" msgid="887022990168191073">"Закрити"</string>
- <string name="taskbar_edu_done" msgid="6880178093977704569">"Готово"</string>
- <string name="taskbar_button_home" msgid="2151398979630664652">"Головний екран"</string>
- <string name="taskbar_button_a11y" msgid="5241161324875094465">"Спеціальні можливості"</string>
- <string name="taskbar_button_back" msgid="8558862226461164514">"Назад"</string>
- <string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"Перемикач IME"</string>
- <string name="taskbar_button_recents" msgid="7273376136216613134">"Нещодавні"</string>
- <!-- no translation found for taskbar_button_notifications (7471740351507357318) -->
- <skip />
- <!-- no translation found for taskbar_button_quick_settings (227662894293189391) -->
- <skip />
- <string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Перемістити вгору або вліво"</string>
- <string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Перемістити вниз або вправо"</string>
</resources>
diff --git a/quickstep/res/values-ur/strings.xml b/quickstep/res/values-ur/strings.xml
index 2b055acf02..87b303f2af 100644
--- a/quickstep/res/values-ur/strings.xml
+++ b/quickstep/res/values-ur/strings.xml
@@ -19,91 +19,19 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="recent_task_option_split_screen" msgid="5353188922202653570">"اسپلٹ اسکرین وضع"</string>
<string name="recent_task_option_pin" msgid="7929860679018978258">"پن کریں"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"فری فارم"</string>
+ <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"مجموعی جائزہ"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"کوئی حالیہ آئٹم نہیں"</string>
+ <string name="accessibility_close_task" msgid="5354563209433803643">"بند کریں"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"ایپ کے استعمال کی ترتیبات"</string>
<string name="recents_clear_all" msgid="5328176793634888831">"سبھی کو صاف کریں"</string>
<string name="accessibility_recent_apps" msgid="4058661986695117371">"حالیہ ایپس"</string>
- <string name="task_view_closed" msgid="9170038230110856166">"ٹاسک بند ہے"</string>
<string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>،<xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
<string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"‏&lt; 1 منٹ"</string>
<string name="time_left_for_app" msgid="3111996412933644358">"آج <xliff:g id="TIME">%1$s</xliff:g> بچا ہے"</string>
- <string name="title_app_suggestions" msgid="4185902664111965088">"ایپس کی تجاویز"</string>
+ <string name="title_app_suggestions" msgid="4185902664111965088">"ایپ کی تجاویز"</string>
+ <string name="all_apps_label" msgid="8542784161730910663">"تمام ایپس"</string>
<string name="all_apps_prediction_tip" msgid="2672336544844936186">"آپ کی پیشن گوئی کردہ ایپس"</string>
- <string name="hotseat_edu_title_migrate" msgid="306578144424489980">"اپنی ہوم اسکرین کی نچلی قطار پر ایپ کی تجاویز حاصل کریں"</string>
- <string name="hotseat_edu_title_migrate_landscape" msgid="3633942953997845243">"اپنی ہوم اسکرین کی پسندیدہ قطار پر ایپ کی تجاویز حاصل کریں"</string>
- <string name="hotseat_edu_message_migrate" msgid="8927179260533775320">"ہوم اسکرین پر آسانی سے اپنی سب سے زیادہ مستعمل ایپس تک رسائی حاصل کریں۔ آپ کی روٹینز کی بنیاد پر تجاویز تبدیل ہوں گی۔ نچلی قطار میں موجود ایپس آپ کی ہوم اسکرین کے اوپر منتقل ہوں گی۔"</string>
- <string name="hotseat_edu_message_migrate_landscape" msgid="4248943380443387697">"ہوم اسکرین پر آسانی سے اپنی سب سے زیادہ مستعمل ایپس تک رسائی حاصل کریں۔ آپ کی روٹینز کی بنیاد پر تجاویز تبدیل ہوں گی۔ پسندیدہ میں موجود ایپس آپ کی ہوم اسکرین کے اوپر منتقل ہوں گی۔"</string>
- <string name="hotseat_edu_message_migrate_alt" msgid="3042360119039646356">"ہوم اسکرین پر، آسانی سے اپنی سب سے زیادہ مستعمل ایپس تک رسائی حاصل کریں۔ آپ کی روٹینز کی بنیاد پر تجاویز تبدیل ہوں گی۔ نچلی قطار میں موجود ایپس نئے فولڈر میں منتقل ہوں گی۔"</string>
- <string name="hotseat_edu_accept" msgid="1611544083278999837">"ایپس کی تجاویز حاصل کریں"</string>
- <string name="hotseat_edu_dismiss" msgid="2781161822780201689">"نہیں شکریہ"</string>
- <string name="hotseat_prediction_settings" msgid="6246554993566070818">"ترتیبات"</string>
- <string name="hotseat_auto_enrolled" msgid="522100018967146807">"سب سے زیادہ مستعمل ایپس یہاں ظاہر ہوتی ہیں، اور روٹینز کی بنیاد پر تبدیل ہوتی ہیں"</string>
- <string name="hotseat_tip_no_empty_slots" msgid="1325212677738179185">"ایپس کی تجاویز حاصل کرنے کیلئے ایپس کو نچلی قطار سے نیچے گھسیٹیں"</string>
- <string name="hotseat_tip_gaps_filled" msgid="3035673010274223538">"ایپس کی تجاویز کو خالی اسپیس میں شامل کر دیا گیا"</string>
- <string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"ایپ کی تجاویز فعال ہیں"</string>
- <string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"ایپ کی تجاویز غیر فعال ہیں"</string>
- <string name="hotseat_prediction_content_description" msgid="4582028296938078419">"پیشن گوئی کردہ ایپ: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"یقینی بنائیں کہ آپ دائیں یا بائیں کنارے سے دور سے سوئپ کریں۔"</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"یقینی بنائیں کہ آپ دائیں یا بائیں کنارے سے اسکرین کے وسط تک سوائپ کریں اور پھر اپنی انگلی اٹھا لیں۔"</string>
- <string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"آپ نے واپس جانے کے لیے دائیں کنارے سے سوائپ کرنے کا طریقہ سیکھ لیا۔ اس کے بعد ایپس سوئچ کرنے کا طریقہ جانیں۔"</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"آپ نے واپس جائیں اشارے کو مکمل کر لیا۔"</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"اس بات کو یقینی بنائیں کہ آپ اسکرین کے نچلے حصے سے زیادہ قریب سے سوائپ نہ کریں۔"</string>
- <string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"پچھلے اشارے کی حساسیت تبدیل کرنے کے لیے ترتیبات پر جائیں"</string>
- <string name="back_gesture_intro_title" msgid="19551256430224428">"واپس جانے کے لیے سوائپ کریں"</string>
- <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"پچھلی اسکرین پر واپس جانے کے لیے بائیں یا دائیں کنارے سے اسکرین کے وسط تک سوائپ کریں۔"</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"اس بات کو یقینی بنائیں کہ آپ اسکرین کے نچلے کنارے سے اوپر کی طرف سوائپ کریں۔"</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"اس بات کو یقینی بنائیں کہ آپ اپنی انگلی اوپر اٹھانے سے پہلے موقوف نہ کریں۔"</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"اس بات کو یقینی بنائیں کہ آپ سیدھا اوپر کی طرف سوائپ کریں۔"</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"آپ نے ہوم پر جانے کا اشارہ مکمل کر لیا۔ اس کے بعد واپس جانے کا طریقہ جانیں۔"</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"آپ نے ہوم پر جانے کا اشارہ مکمل کر لیا۔"</string>
- <string name="home_gesture_intro_title" msgid="836590312858441830">"ہوم پر جانے کے لیے سوائپ کریں"</string>
- <string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"اپنی اسکرین کے نیچے سے اوپر کی طرف سوائپ کریں۔ یہ اشارہ آپ کو ہمیشہ ہوم اسکرین پر لے جاتا ہے۔"</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"اس بات کو یقینی بنائیں کہ آپ اسکرین کے نچلے کنارے سے اوپر کی طرف سوائپ کریں۔"</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"انگلی اٹھانے سے پہلے ونڈو کو زیادہ دیر تک پکڑنے کی کوشش کریں۔"</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"اس بات کو یقینی بنائیں کہ آپ سیدھا اوپر کی طرف سوائپ کریں، پھر موقوف کریں۔"</string>
- <string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"آپ نے اشاروں کو استعمال کرنے کا طریقہ سیکھ لیا۔ اشاروں کو آف کرنے کے لیے ترتیبات پر جائیں۔"</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"آپ نے ایپس کو سوئچ کرنے کا اشارہ مکمل کر لیا۔"</string>
- <string name="overview_gesture_intro_title" msgid="2902054412868489378">"ایپس سوئچ کرنے کے لیے سوائپ کریں"</string>
- <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"ایپس کے مابین سوئچ کرنے کے لیے، اپنی اسکرین کے نچلے حصے سے اوپر کی جانب سوائپ کریں، پکڑے رکھیں، پھر چھوڑ دیں۔"</string>
- <string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"سب ہو گیا"</string>
- <string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"ہو گیا"</string>
- <string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"ترتیبات"</string>
- <string name="gesture_tutorial_try_again" msgid="65962545858556697">"پھر کوشش کریں"</string>
- <string name="gesture_tutorial_nice" msgid="2936275692616928280">"عمدہ!"</string>
- <string name="gesture_tutorial_step" msgid="1279786122817620968">"ٹیوٹوریل <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
- <string name="allset_title" msgid="5021126669778966707">"سب کچھ تیار ہے!"</string>
- <string name="allset_hint" msgid="2384632994739392447">"ہوم پر جانے کے لیے اوپر سوائپ کریں"</string>
- <string name="allset_description" msgid="6350320429953234580">"آپ اپنا فون استعمال شروع کرنے کے لیے تیار ہیں"</string>
- <string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"سسٹم نیویگیشن کی ترتیبات"</annotation></string>
- <string name="action_share" msgid="2648470652637092375">"اشتراک کریں"</string>
- <string name="action_screenshot" msgid="8171125848358142917">"اسکرین شاٹ"</string>
- <string name="action_split" msgid="2098009717623550676">"اسپلٹ"</string>
- <string name="toast_split_select_app" msgid="5453865907322018352">"اسپلٹ اسکرین کا استعمال کرنے کیلئے دوسری ایپ پر تھپتھپائیں"</string>
- <string name="toast_split_app_unsupported" msgid="3271526028981899666">"ایپ سپلٹ اسکرین کو سپورٹ نہیں کرتی۔"</string>
- <string name="blocked_by_policy" msgid="2071401072261365546">"ایپ یا آپ کی تنظیم کی جانب سے اس کارروائی کی اجازت نہیں ہے"</string>
- <string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"نیویگیشن کا ٹیوٹوریل نظر انداز کریں؟"</string>
- <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"آپ اسے بعد میں <xliff:g id="NAME">%1$s</xliff:g> ایپ میں تلاش کر سکتے ہیں"</string>
- <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"منسوخ کریں"</string>
- <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"نظر انداز کریں"</string>
- <string name="accessibility_rotate_button" msgid="4771825231336502943">"اسکرین کو گھمائیں"</string>
- <string name="taskbar_edu_opened" msgid="3950252793551919129">"ٹاکس بار کا تعلیمی پینل ظاہر ہو گیا"</string>
- <string name="taskbar_edu_closed" msgid="126643734478892862">"ٹاسک بار کا تعلیمی پینل بند ہو گیا"</string>
- <string name="taskbar_edu_switch_apps" msgid="6942863327845784813">"ایپس کو سوئچ کرنے کیلئے ٹاسک بار کا استعمال کریں"</string>
- <string name="taskbar_edu_splitscreen" msgid="2663361731630346489">"ایک وقت میں دو ایپس استعمال کرنے کے لیے سائیڈ پر گھسیٹیں"</string>
- <string name="taskbar_edu_stashing" msgid="5212374387411764031">"ٹاسک بار کو کسی بھی وقت چھپانے کیلئے ٹچ کریں اور دبائے رکھیں"</string>
- <string name="taskbar_edu_next" msgid="4007618274426775841">"آگے"</string>
- <string name="taskbar_edu_previous" msgid="459202320127201702">"پیچھے"</string>
- <string name="taskbar_edu_close" msgid="887022990168191073">"بند کریں"</string>
- <string name="taskbar_edu_done" msgid="6880178093977704569">"ہو گیا"</string>
- <string name="taskbar_button_home" msgid="2151398979630664652">"ہوم"</string>
- <string name="taskbar_button_a11y" msgid="5241161324875094465">"ایکسیسبیلٹی"</string>
- <string name="taskbar_button_back" msgid="8558862226461164514">"پیچھے"</string>
- <string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"‏IME سوئچر"</string>
- <string name="taskbar_button_recents" msgid="7273376136216613134">"حالیہ"</string>
- <string name="taskbar_button_notifications" msgid="7471740351507357318">"اطلاعات"</string>
- <string name="taskbar_button_quick_settings" msgid="227662894293189391">"فوری ترتیبات"</string>
- <string name="move_drop_target_top_or_left" msgid="2988702185049595807">"اوپر/بائیں طرف منتقل کریں"</string>
- <string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"نیچے/دائیں طرف منتقل کریں"</string>
</resources>
diff --git a/quickstep/res/values-uz/strings.xml b/quickstep/res/values-uz/strings.xml
index 3b9853f787..67c8e91c00 100644
--- a/quickstep/res/values-uz/strings.xml
+++ b/quickstep/res/values-uz/strings.xml
@@ -19,91 +19,19 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Ekranni ikkiga ajratish"</string>
<string name="recent_task_option_pin" msgid="7929860679018978258">"Mahkamlash"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Erkin shakl"</string>
+ <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Nazar"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"Yaqinda ishlatilgan ilovalar yo‘q"</string>
+ <string name="accessibility_close_task" msgid="5354563209433803643">"Yopish"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Ilovadan foydalanish sozlamalari"</string>
<string name="recents_clear_all" msgid="5328176793634888831">"Hammasini tozalash"</string>
<string name="accessibility_recent_apps" msgid="4058661986695117371">"Yaqinda ishlatilgan ilovalar"</string>
- <string name="task_view_closed" msgid="9170038230110856166">"Vazifalar yopildi"</string>
<string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
<string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 daqiqa"</string>
<string name="time_left_for_app" msgid="3111996412933644358">"Bugun <xliff:g id="TIME">%1$s</xliff:g> qoldi"</string>
<string name="title_app_suggestions" msgid="4185902664111965088">"Tavsiya etiladigan ilovalar"</string>
- <string name="all_apps_prediction_tip" msgid="2672336544844936186">"Taklif qilingan ilovalar"</string>
- <string name="hotseat_edu_title_migrate" msgid="306578144424489980">"Tavsiya etiladigan ilovalar bosh ekran pastidagi qatorda chiqadi"</string>
- <string name="hotseat_edu_title_migrate_landscape" msgid="3633942953997845243">"Tavsiya etiladigan ilovalar bosh ekranning saralanganlar ruknida chiqadi"</string>
- <string name="hotseat_edu_message_migrate" msgid="8927179260533775320">"Faol ishlatiladigan ilovalarga bosh ekrandan osongina kira olasiz. Tavsiyalar oxirgi faoliyatingiz asosida almashib boradi. Pastki qatordagi ilovalar bosh ekranga chiqadi."</string>
- <string name="hotseat_edu_message_migrate_landscape" msgid="4248943380443387697">"Faol ishlatiladigan ilovalarga bosh ekrandan osongina kira olasiz. Tavsiyalar oxirgi faoliyatingiz asosida almashib boradi. Saralanganlar qatoridagi ilovalar bosh ekranga chiqadi."</string>
- <string name="hotseat_edu_message_migrate_alt" msgid="3042360119039646356">"Faol ishlatiladigan ilovalarga bosh ekrandan osongina kira olasiz. Tavsiyalar oxirgi faoliyatingiz asosida almashib boradi. Pastki qatordagi ilovalar yangi jildga chiqadi."</string>
- <string name="hotseat_edu_accept" msgid="1611544083278999837">"Tavsiyalarni chiqarish"</string>
- <string name="hotseat_edu_dismiss" msgid="2781161822780201689">"Kerak emas"</string>
- <string name="hotseat_prediction_settings" msgid="6246554993566070818">"Sozlamalar"</string>
- <string name="hotseat_auto_enrolled" msgid="522100018967146807">"Faol ishlatiladigan ilovalar bu yerda chiqadi va oxirgi faoliyatingiz asosida almashadi"</string>
- <string name="hotseat_tip_no_empty_slots" msgid="1325212677738179185">"Tavsiyalar olish uchun ilovalarni pastki qatordan tashqariga oling"</string>
- <string name="hotseat_tip_gaps_filled" msgid="3035673010274223538">"Tavsiya etilgan ilovalarni ochiq joylarga kiriting"</string>
- <string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Ilova tavsiyalari yoqildi"</string>
- <string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Endi ilova takliflari chiqmaydi"</string>
- <string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Taklif etilgan ilova: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Ekran chetidan boshlab oʻngdan yoki chapdan suring."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Ekranning oʻng yoki chap chetidan oʻrtasiga suring va qoʻyib yuboring."</string>
- <string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Ortga qaytish uchun oʻngdan surishni oʻrgandingiz. Endi ilovalarni almashtirishni oʻrganamiz."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"Ortga qaytish ishorasi darsini tamomladingiz."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Barmoqni ekran pastiga yaqin surmaslikka harakat qiling."</string>
- <string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"Orqaga ishorasi sezuvchanligi Sozlamalardan oʻzgartiriladi"</string>
- <string name="back_gesture_intro_title" msgid="19551256430224428">"Orqaga qaytish"</string>
- <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"Ortga qaytish uchun barmoqni ekranning yon chekkalaridan oʻrtasigacha suring."</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Barmoqni ekranning pastki chetidan yuqoriga suring."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Barmoqni ekrandan pauzasiz qoʻyib uzing."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Barmoqni tik tepaga suring."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"Bosh ekranni ochish ishorasi darsini tamomladingiz. Endi orqaga qaytishni oʻrganamiz."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"Bosh ekranni ochish ishorasi darsini tamomladingiz."</string>
- <string name="home_gesture_intro_title" msgid="836590312858441830">"Svayp bilan bosh ekranni ochish"</string>
- <string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Ekranning pastidan tepaga qarab suring. Bu ishora doim Bosh ekranni ochadi."</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Barmoqni ekranning pastki chetidan yuqoriga suring."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Barmoqni uzishdan oldin oynani biroz bosib turing."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Avval tik tepaga surib, keyin pauza qiling."</string>
- <string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Ishoralardan qanday foydalanishni oʻrganib oldingiz. Ishoralarni oʻchirish uchun Sozlamalarga kiring."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"Ilovalarni almashtirish darsini tamomladingiz."</string>
- <string name="overview_gesture_intro_title" msgid="2902054412868489378">"Ilovalar orasida almashish"</string>
- <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Ilovalarni ochish uchun ekranning pastidan tepaga qarab suring, biroz ushlab turing va qoʻyib yuboring"</string>
- <string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"Tayyor"</string>
- <string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Tayyor"</string>
- <string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Sozlamalar"</string>
- <string name="gesture_tutorial_try_again" msgid="65962545858556697">"Qayta urinish"</string>
- <string name="gesture_tutorial_nice" msgid="2936275692616928280">"Yaxshi!"</string>
- <string name="gesture_tutorial_step" msgid="1279786122817620968">"Darslik: <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
- <string name="allset_title" msgid="5021126669778966707">"Hammasi tayyor!"</string>
- <string name="allset_hint" msgid="2384632994739392447">"Boshiga qaytish uchun tepaga suring"</string>
- <string name="allset_description" msgid="6350320429953234580">"Telefoningiz xizmatga tayyor"</string>
- <string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"Tizim navigatsiya sozlamalari"</annotation></string>
- <string name="action_share" msgid="2648470652637092375">"Ulashish"</string>
- <string name="action_screenshot" msgid="8171125848358142917">"Skrinshot"</string>
- <string name="action_split" msgid="2098009717623550676">"Ajratish"</string>
- <string name="toast_split_select_app" msgid="5453865907322018352">"Ekranni ikkiga ajratish uchun boshqa ilovani bosing"</string>
- <string name="toast_split_app_unsupported" msgid="3271526028981899666">"Bu ilovada ekranni ikkiga ajratish ishlamaydi."</string>
- <string name="blocked_by_policy" msgid="2071401072261365546">"Bu amal ilova yoki tashkilotingiz tomonidan taqiqlangan"</string>
- <string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Navigatsiya darsi yopilsinmi?"</string>
- <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Bu darslar <xliff:g id="NAME">%1$s</xliff:g> ilovasida chiqadi"</string>
- <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Bekor qilish"</string>
- <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Tashlab ketish"</string>
- <string name="accessibility_rotate_button" msgid="4771825231336502943">"Ekranni burish"</string>
- <string name="taskbar_edu_opened" msgid="3950252793551919129">"Taʼlim vazifalar paneli chiqdi"</string>
- <string name="taskbar_edu_closed" msgid="126643734478892862">"Taʼlim vazifalar paneli yopildi"</string>
- <string name="taskbar_edu_switch_apps" msgid="6942863327845784813">"Ilovalarni vazifalar panelida almashtirish mumkin"</string>
- <string name="taskbar_edu_splitscreen" msgid="2663361731630346489">"Bir vaqtda ikkita ilova ochish uchun birini yoniga torting"</string>
- <string name="taskbar_edu_stashing" msgid="5212374387411764031">"Vazifalar panelini ustiga bosib turib yashirish mumkin"</string>
- <string name="taskbar_edu_next" msgid="4007618274426775841">"Keyingisi"</string>
- <string name="taskbar_edu_previous" msgid="459202320127201702">"Orqaga"</string>
- <string name="taskbar_edu_close" msgid="887022990168191073">"Yopish"</string>
- <string name="taskbar_edu_done" msgid="6880178093977704569">"Tayyor"</string>
- <string name="taskbar_button_home" msgid="2151398979630664652">"Bosh ekran"</string>
- <string name="taskbar_button_a11y" msgid="5241161324875094465">"Maxsus imkoniyatlar"</string>
- <string name="taskbar_button_back" msgid="8558862226461164514">"Orqaga"</string>
- <string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"IME tugmasi"</string>
- <string name="taskbar_button_recents" msgid="7273376136216613134">"Oxirgilar"</string>
- <string name="taskbar_button_notifications" msgid="7471740351507357318">"Bildirishnomalar"</string>
- <string name="taskbar_button_quick_settings" msgid="227662894293189391">"Tezkor sozlamalar"</string>
- <string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Yuqoriga yoki chapga oʻtkazish"</string>
- <string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Pastga yoki oʻngga oʻtkazish"</string>
+ <string name="all_apps_label" msgid="8542784161730910663">"Barcha ilovalar"</string>
+ <string name="all_apps_prediction_tip" msgid="2672336544844936186">"Taklif qilingan ilovalaringiz"</string>
</resources>
diff --git a/quickstep/res/values-vi/strings.xml b/quickstep/res/values-vi/strings.xml
index 1072c3a17a..34c89efcf1 100644
--- a/quickstep/res/values-vi/strings.xml
+++ b/quickstep/res/values-vi/strings.xml
@@ -19,93 +19,19 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Chia đôi màn hình"</string>
<string name="recent_task_option_pin" msgid="7929860679018978258">"Ghim"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"Dạng tự do"</string>
+ <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Tổng quan"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"Không có mục gần đây nào"</string>
+ <string name="accessibility_close_task" msgid="5354563209433803643">"Đóng"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Cài đặt mức sử dụng ứng dụng"</string>
<string name="recents_clear_all" msgid="5328176793634888831">"Xóa tất cả"</string>
<string name="accessibility_recent_apps" msgid="4058661986695117371">"Ứng dụng gần đây"</string>
- <string name="task_view_closed" msgid="9170038230110856166">"Đã đóng tác vụ"</string>
<string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
<string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 phút"</string>
<string name="time_left_for_app" msgid="3111996412933644358">"Hôm nay còn <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="title_app_suggestions" msgid="4185902664111965088">"Các ứng dụng đề xuất"</string>
+ <string name="all_apps_label" msgid="8542784161730910663">"Tất cả ứng dụng"</string>
<string name="all_apps_prediction_tip" msgid="2672336544844936186">"Các ứng dụng gợi ý của bạn"</string>
- <string name="hotseat_edu_title_migrate" msgid="306578144424489980">"Nhận các ứng dụng đề xuất ở cuối Màn hình chính"</string>
- <string name="hotseat_edu_title_migrate_landscape" msgid="3633942953997845243">"Nhận các ứng dụng đề xuất trên hàng mục ưa thích của Màn hình chính"</string>
- <string name="hotseat_edu_message_migrate" msgid="8927179260533775320">"Ngay từ Màn hình chính, bạn có thể dễ dàng truy cập vào những ứng dụng mà mình dùng thường xuyên nhất. Các ứng dụng đề xuất sẽ thay đổi dựa trên thói quen của bạn. Các ứng dụng ở hàng dưới cùng sẽ chuyển lên phía trên của Màn hình chính."</string>
- <string name="hotseat_edu_message_migrate_landscape" msgid="4248943380443387697">"Ngay trên Màn hình chính, bạn có thể dễ dàng mở những ứng dụng mà mình dùng thường xuyên nhất. Các ứng dụng đề xuất sẽ thay đổi dựa trên thói quen của bạn. Các ứng dụng ở hàng mục ưa thích sẽ chuyển sang Màn hình chính."</string>
- <string name="hotseat_edu_message_migrate_alt" msgid="3042360119039646356">"Ngay từ Màn hình chính, bạn có thể dễ dàng truy cập vào những ứng dụng mà mình dùng thường xuyên nhất. Các ứng dụng đề xuất sẽ thay đổi dựa trên thói quen của bạn. Các ứng dụng ở hàng dưới cùng sẽ chuyển đến một thư mục mới."</string>
- <string name="hotseat_edu_accept" msgid="1611544083278999837">"Nhận ứng dụng đề xuất"</string>
- <string name="hotseat_edu_dismiss" msgid="2781161822780201689">"Không, cảm ơn"</string>
- <string name="hotseat_prediction_settings" msgid="6246554993566070818">"Cài đặt"</string>
- <string name="hotseat_auto_enrolled" msgid="522100018967146807">"Các ứng dụng dùng thường xuyên nhất sẽ hiển thị ở đây và thay đổi dựa trên thói quen"</string>
- <string name="hotseat_tip_no_empty_slots" msgid="1325212677738179185">"Kéo ứng dụng ra khỏi hàng dưới cùng để xem ứng dụng đề xuất"</string>
- <string name="hotseat_tip_gaps_filled" msgid="3035673010274223538">"Thêm ứng dụng đề xuất vào không gian trống"</string>
- <string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Đã bật tính năng Ứng dụng đề xuất"</string>
- <string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Tính năng Ứng dụng đề xuất bị tắt"</string>
- <string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Ứng dụng dự đoán: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Hãy vuốt từ mép ngoài cùng bên phải hoặc ngoài cùng bên trái."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Hãy vuốt từ mép phải hoặc mép trái tới giữa màn hình rồi thả tay ra."</string>
- <string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Bạn đã học được cách vuốt từ mép phải để quay lại. Tiếp theo, hãy tìm hiểu cách chuyển đổi ứng dụng."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"Bạn đã thực hiện xong cử chỉ quay lại."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Hãy nhớ không được vuốt quá gần phần cuối màn hình."</string>
- <string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"Để thay đổi độ nhạy của cử chỉ quay lại, hãy vào mục Cài đặt"</string>
- <string name="back_gesture_intro_title" msgid="19551256430224428">"Vuốt để quay lại"</string>
- <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"Để quay lại màn hình gần đây nhất, hãy vuốt từ mép trái hoặc mép phải tới chính giữa màn hình."</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Hãy vuốt lên từ mép dưới cùng của màn hình."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Hãy nhớ không được tạm dừng trước khi nhấc ngón tay."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Hãy vuốt thẳng lên."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"Bạn đã thực hiện xong cử chỉ chuyển đến Màn hình chính. Tiếp theo, hãy tìm hiểu cách quay lại."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"Bạn đã thực hiện xong cử chỉ chuyển đến Màn hình chính."</string>
- <string name="home_gesture_intro_title" msgid="836590312858441830">"Vuốt để chuyển đến Màn hình chính"</string>
- <string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Vuốt lên từ cuối màn hình. Cử chỉ này luôn đưa bạn đến Màn hình chính."</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Hãy vuốt lên từ mép dưới cùng của màn hình."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Hãy thử giữ cửa sổ lâu hơn trước khi thả tay ra."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Hãy vuốt thẳng lên, sau đó tạm dừng."</string>
- <string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Bạn đã tìm hiểu cách sử dụng cử chỉ. Để tắt cử chỉ, hãy chuyển đến phần Cài đặt."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"Bạn đã thực hiện xong cử chỉ chuyển đổi ứng dụng."</string>
- <string name="overview_gesture_intro_title" msgid="2902054412868489378">"Vuốt để chuyển đổi ứng dụng"</string>
- <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Để chuyển đổi giữa các ứng dụng, hãy vuốt lên từ cuối màn hình, giữ rồi thả ra."</string>
- <string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"Đã hoàn tất"</string>
- <string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Xong"</string>
- <string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Cài đặt"</string>
- <string name="gesture_tutorial_try_again" msgid="65962545858556697">"Thử lại"</string>
- <string name="gesture_tutorial_nice" msgid="2936275692616928280">"Tuyệt vời!"</string>
- <string name="gesture_tutorial_step" msgid="1279786122817620968">"Hướng dẫn <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
- <string name="allset_title" msgid="5021126669778966707">"Đã hoàn tất!"</string>
- <string name="allset_hint" msgid="2384632994739392447">"Vuốt lên để chuyển đến Màn hình chính"</string>
- <string name="allset_description" msgid="6350320429953234580">"Vậy là bạn đã sẵn sàng sử dụng điện thoại của mình"</string>
- <string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"Chế độ cài đặt di chuyển trên hệ thống"</annotation></string>
- <string name="action_share" msgid="2648470652637092375">"Chia sẻ"</string>
- <string name="action_screenshot" msgid="8171125848358142917">"Chụp ảnh màn hình"</string>
- <string name="action_split" msgid="2098009717623550676">"Chia đôi màn hình"</string>
- <string name="toast_split_select_app" msgid="5453865907322018352">"Nhấn vào một ứng dụng khác để dùng màn hình chia đôi"</string>
- <string name="toast_split_app_unsupported" msgid="3271526028981899666">"Ứng dụng không hỗ trợ chia đôi màn hình."</string>
- <string name="blocked_by_policy" msgid="2071401072261365546">"Ứng dụng hoặc tổ chức của bạn không cho phép thực hiện hành động này"</string>
- <string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Bỏ qua phần hướng dẫn thao tác?"</string>
- <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Bạn có thể tìm lại phần hướng dẫn này trong ứng dụng <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Hủy"</string>
- <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Bỏ qua"</string>
- <string name="accessibility_rotate_button" msgid="4771825231336502943">"Xoay màn hình"</string>
- <string name="taskbar_edu_opened" msgid="3950252793551919129">"Đã hiện bảng hướng dẫn trên thanh tác vụ"</string>
- <string name="taskbar_edu_closed" msgid="126643734478892862">"Đã đóng bảng hướng dẫn trên thanh tác vụ"</string>
- <string name="taskbar_edu_switch_apps" msgid="6942863327845784813">"Dùng thanh tác vụ để chuyển đổi ứng dụng"</string>
- <string name="taskbar_edu_splitscreen" msgid="2663361731630346489">"Kéo sang bên để dùng hai ứng dụng cùng một lúc"</string>
- <string name="taskbar_edu_stashing" msgid="5212374387411764031">"Chạm và giữ để ẩn thanh tác vụ"</string>
- <string name="taskbar_edu_next" msgid="4007618274426775841">"Tiếp theo"</string>
- <string name="taskbar_edu_previous" msgid="459202320127201702">"Quay lại"</string>
- <string name="taskbar_edu_close" msgid="887022990168191073">"Đóng"</string>
- <string name="taskbar_edu_done" msgid="6880178093977704569">"Xong"</string>
- <string name="taskbar_button_home" msgid="2151398979630664652">"Màn hình chính"</string>
- <string name="taskbar_button_a11y" msgid="5241161324875094465">"Hỗ trợ tiếp cận"</string>
- <string name="taskbar_button_back" msgid="8558862226461164514">"Quay lại"</string>
- <string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"Trình chuyển đổi IME"</string>
- <string name="taskbar_button_recents" msgid="7273376136216613134">"Gần đây"</string>
- <!-- no translation found for taskbar_button_notifications (7471740351507357318) -->
- <skip />
- <!-- no translation found for taskbar_button_quick_settings (227662894293189391) -->
- <skip />
- <string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Chuyển lên trên cùng/sang bên trái"</string>
- <string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Chuyển xuống dưới cùng/sang bên phải"</string>
</resources>
diff --git a/quickstep/res/values-zh-rCN/strings.xml b/quickstep/res/values-zh-rCN/strings.xml
index 4587d58778..0e83977fa3 100644
--- a/quickstep/res/values-zh-rCN/strings.xml
+++ b/quickstep/res/values-zh-rCN/strings.xml
@@ -19,93 +19,19 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="recent_task_option_split_screen" msgid="5353188922202653570">"分屏"</string>
<string name="recent_task_option_pin" msgid="7929860679018978258">"固定"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"自由窗口"</string>
+ <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"概览"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"近期没有任何内容"</string>
+ <string name="accessibility_close_task" msgid="5354563209433803643">"关闭"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"应用使用设置"</string>
<string name="recents_clear_all" msgid="5328176793634888831">"全部清除"</string>
<string name="accessibility_recent_apps" msgid="4058661986695117371">"最近用过的应用"</string>
- <string name="task_view_closed" msgid="9170038230110856166">"任务已关闭"</string>
<string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>(<xliff:g id="REMAINING_TIME">%2$s</xliff:g>)"</string>
<string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"不到 1 分钟"</string>
<string name="time_left_for_app" msgid="3111996412933644358">"今天还可使用 <xliff:g id="TIME">%1$s</xliff:g>"</string>
- <string name="title_app_suggestions" msgid="4185902664111965088">"应用建议"</string>
- <string name="all_apps_prediction_tip" msgid="2672336544844936186">"您可能想要使用的应用"</string>
- <string name="hotseat_edu_title_migrate" msgid="306578144424489980">"在主屏幕底部获取应用建议"</string>
- <string name="hotseat_edu_title_migrate_landscape" msgid="3633942953997845243">"在主屏幕的收藏行获取应用建议"</string>
- <string name="hotseat_edu_message_migrate" msgid="8927179260533775320">"直接在主屏幕上轻松访问您最常用的应用。系统会根据您的日常安排提供不同的建议。最下面一排中的应用会向上移动到主屏幕中。"</string>
- <string name="hotseat_edu_message_migrate_landscape" msgid="4248943380443387697">"直接在主屏幕上轻松访问您最常用的应用。建议会因您的日常安排而变化,收藏行中的应用将移到主屏幕上。"</string>
- <string name="hotseat_edu_message_migrate_alt" msgid="3042360119039646356">"直接在主屏幕上轻松访问您最常用的应用。系统会根据您的日常安排提供不同的建议。最下面一排中的应用会移到新文件夹中。"</string>
- <string name="hotseat_edu_accept" msgid="1611544083278999837">"获取应用建议"</string>
- <string name="hotseat_edu_dismiss" msgid="2781161822780201689">"不用了"</string>
- <string name="hotseat_prediction_settings" msgid="6246554993566070818">"设置"</string>
- <string name="hotseat_auto_enrolled" msgid="522100018967146807">"最常用的应用会显示在此处,显示的项目会根据日常安排而发生变化"</string>
- <string name="hotseat_tip_no_empty_slots" msgid="1325212677738179185">"将应用拖离底部,以获取应用建议"</string>
- <string name="hotseat_tip_gaps_filled" msgid="3035673010274223538">"应用建议已添加到空白区域"</string>
- <string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"已启用应用建议"</string>
- <string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"已停用应用建议"</string>
- <string name="hotseat_prediction_content_description" msgid="4582028296938078419">"预测的应用:<xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"请从最右侧或最左侧边缘开始滑动。"</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"请从右侧或左侧边缘滑动到屏幕中间位置后再松开手指。"</string>
- <string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"您已了解如何使用“从右侧向左滑动”手势返回。接下来了解如何切换应用。"</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"您完成了“返回”手势教程。"</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"请确保滑动时手的位置不要太靠近屏幕底部。"</string>
- <string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"如要调节“返回”手势的灵敏度,请转到“设置”"</string>
- <string name="back_gesture_intro_title" msgid="19551256430224428">"滑动即可返回"</string>
- <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"如要返回上一个屏幕,请从左侧或右侧边缘滑动到屏幕中间位置。"</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"请确保从屏幕底部边缘向上滑动。"</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"松开手指前,请确保不要停下来。"</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"请确保直接向上滑动。"</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"您完成了“转到主屏幕”手势教程。接下来了解如何返回。"</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"您完成了“转到主屏幕”手势教程。"</string>
- <string name="home_gesture_intro_title" msgid="836590312858441830">"上滑可转到主屏幕"</string>
- <string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"从屏幕底部向上滑动。这个手势会一律将您转到主屏幕。"</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"请确保从屏幕底部边缘向上滑动。"</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"请尝试按住窗口较长时间,然后再松开手指。"</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"请确保直接向上滑动,然后停住。"</string>
- <string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"您已了解如何使用手势了。如要关闭手势,请转到“设置”。"</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"您完成了“切换应用”手势教程。"</string>
- <string name="overview_gesture_intro_title" msgid="2902054412868489378">"滑动即可切换应用"</string>
- <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"如需在应用之间切换,请从屏幕底部向上滑动后按住,然后松开。"</string>
- <string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"大功告成"</string>
- <string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"完成"</string>
- <string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"设置"</string>
- <string name="gesture_tutorial_try_again" msgid="65962545858556697">"重试"</string>
- <string name="gesture_tutorial_nice" msgid="2936275692616928280">"很好!"</string>
- <string name="gesture_tutorial_step" msgid="1279786122817620968">"教程 <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
- <string name="allset_title" msgid="5021126669778966707">"大功告成!"</string>
- <string name="allset_hint" msgid="2384632994739392447">"向上滑动即可转到主屏幕"</string>
- <string name="allset_description" msgid="6350320429953234580">"您可以开始使用手机了"</string>
- <string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"系统导航设置"</annotation></string>
- <string name="action_share" msgid="2648470652637092375">"分享"</string>
- <string name="action_screenshot" msgid="8171125848358142917">"屏幕截图"</string>
- <string name="action_split" msgid="2098009717623550676">"拆分"</string>
- <string name="toast_split_select_app" msgid="5453865907322018352">"点按另一个应用即可使用分屏"</string>
- <string name="toast_split_app_unsupported" msgid="3271526028981899666">"应用不支持分屏。"</string>
- <string name="blocked_by_policy" msgid="2071401072261365546">"该应用或您所在的单位不允许执行此操作"</string>
- <string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"要跳过导航教程吗?"</string>
- <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"您之后可以在“<xliff:g id="NAME">%1$s</xliff:g>”应用中找到此教程"</string>
- <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"取消"</string>
- <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"跳过"</string>
- <string name="accessibility_rotate_button" msgid="4771825231336502943">"旋转屏幕"</string>
- <string name="taskbar_edu_opened" msgid="3950252793551919129">"任务栏教程已显示"</string>
- <string name="taskbar_edu_closed" msgid="126643734478892862">"任务栏教程已关闭"</string>
- <string name="taskbar_edu_switch_apps" msgid="6942863327845784813">"使用任务栏切换应用"</string>
- <string name="taskbar_edu_splitscreen" msgid="2663361731630346489">"拖动到一侧,以便一次使用两个应用"</string>
- <string name="taskbar_edu_stashing" msgid="5212374387411764031">"轻触并按住即可隐藏任务栏"</string>
- <string name="taskbar_edu_next" msgid="4007618274426775841">"继续"</string>
- <string name="taskbar_edu_previous" msgid="459202320127201702">"返回"</string>
- <string name="taskbar_edu_close" msgid="887022990168191073">"关闭"</string>
- <string name="taskbar_edu_done" msgid="6880178093977704569">"完成"</string>
- <string name="taskbar_button_home" msgid="2151398979630664652">"主屏幕"</string>
- <string name="taskbar_button_a11y" msgid="5241161324875094465">"无障碍"</string>
- <string name="taskbar_button_back" msgid="8558862226461164514">"返回"</string>
- <string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"IME 切换器"</string>
- <string name="taskbar_button_recents" msgid="7273376136216613134">"最近用过"</string>
- <!-- no translation found for taskbar_button_notifications (7471740351507357318) -->
- <skip />
- <!-- no translation found for taskbar_button_quick_settings (227662894293189391) -->
- <skip />
- <string name="move_drop_target_top_or_left" msgid="2988702185049595807">"移到顶部/左侧"</string>
- <string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"移到底部/右侧"</string>
+ <string name="title_app_suggestions" msgid="4185902664111965088">"应用推荐"</string>
+ <string name="all_apps_label" msgid="8542784161730910663">"所有应用"</string>
+ <string name="all_apps_prediction_tip" msgid="2672336544844936186">"您的预测应用"</string>
</resources>
diff --git a/quickstep/res/values-zh-rHK/strings.xml b/quickstep/res/values-zh-rHK/strings.xml
index 2810771d2f..ac7e8e9002 100644
--- a/quickstep/res/values-zh-rHK/strings.xml
+++ b/quickstep/res/values-zh-rHK/strings.xml
@@ -19,93 +19,19 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="recent_task_option_split_screen" msgid="5353188922202653570">"分割畫面"</string>
<string name="recent_task_option_pin" msgid="7929860679018978258">"固定"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"自由形式"</string>
+ <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"概覽"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"最近沒有任何項目"</string>
+ <string name="accessibility_close_task" msgid="5354563209433803643">"關閉"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"應用程式使用情況設定"</string>
<string name="recents_clear_all" msgid="5328176793634888831">"全部清除"</string>
<string name="accessibility_recent_apps" msgid="4058661986695117371">"最近使用的應用程式"</string>
- <string name="task_view_closed" msgid="9170038230110856166">"閂咗工作"</string>
<string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>,<xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
<string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"少於 1 分鐘"</string>
<string name="time_left_for_app" msgid="3111996412933644358">"今天剩餘時間:<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="title_app_suggestions" msgid="4185902664111965088">"應用程式建議"</string>
+ <string name="all_apps_label" msgid="8542784161730910663">"所有應用程式"</string>
<string name="all_apps_prediction_tip" msgid="2672336544844936186">"您的預測應用程式"</string>
- <string name="hotseat_edu_title_migrate" msgid="306578144424489980">"在主畫面底部取得應用程式建議"</string>
- <string name="hotseat_edu_title_migrate_landscape" msgid="3633942953997845243">"在主畫面「我的最愛」列取得應用程式建議"</string>
- <string name="hotseat_edu_message_migrate" msgid="8927179260533775320">"在主畫面輕鬆存取常用的應用程式。系統會根據您的日常安排更改建議,並將底部的應用程式移到主畫面。"</string>
- <string name="hotseat_edu_message_migrate_landscape" msgid="4248943380443387697">"在主畫面輕鬆存取最常用的應用程式。系統會根據您的日常安排變更建議,「我的最愛」列中的應用程式會移至主畫面。"</string>
- <string name="hotseat_edu_message_migrate_alt" msgid="3042360119039646356">"在主畫面輕鬆存取最常用的應用程式。系統會根據您的日常安排變更建議,並將底列的應用程式移至新資料夾。"</string>
- <string name="hotseat_edu_accept" msgid="1611544083278999837">"取得應用程式建議"</string>
- <string name="hotseat_edu_dismiss" msgid="2781161822780201689">"不用了,謝謝"</string>
- <string name="hotseat_prediction_settings" msgid="6246554993566070818">"設定"</string>
- <string name="hotseat_auto_enrolled" msgid="522100018967146807">"最常用的應用程式會在這裡顯示,並會根據日常安排變更"</string>
- <string name="hotseat_tip_no_empty_slots" msgid="1325212677738179185">"將應用程式從底列拖曳出來,即可獲取應用程式建議"</string>
- <string name="hotseat_tip_gaps_filled" msgid="3035673010274223538">"系統會將應用程式建議新增至空白位置"</string>
- <string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"已啟用應用程式建議"</string>
- <string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"已停用應用程式建議"</string>
- <string name="hotseat_prediction_content_description" msgid="4582028296938078419">"預測應用程式:<xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"請從螢幕右側或左側邊緣滑動。"</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"請從螢幕右側或左側邊緣往中央滑動,然後放開手指。"</string>
- <string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"您已瞭解如何透過「由右向左滑動」手勢返回。接下來一起瞭解如何切換應用程式。"</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"您已完成「返回」手勢的教學課程。"</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"滑動時,手的位置不要太接近螢幕底部。"</string>
- <string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"如要變更「返回」手勢的敏感度,請前往「設定」"</string>
- <string name="back_gesture_intro_title" msgid="19551256430224428">"滑動即可返回"</string>
- <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"如要返回上一個畫面,請從螢幕左側或右側邊緣往中央滑動。"</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"請從螢幕底部邊緣向上滑動。"</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"放開手指前請勿停下來。"</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"請向上滑動。"</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"您已完成「返回主畫面」手勢的教學課程。接著,一起來瞭解如何返回上一個畫面。"</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"您已完成「返回主畫面」手勢的教學課程。"</string>
- <string name="home_gesture_intro_title" msgid="836590312858441830">"向上滑動即可返回主畫面"</string>
- <string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"從螢幕底部向上滑動。這個手勢在所有畫面下都可讓您返回主畫面。"</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"請從螢幕底部邊緣向上滑動。"</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"請嘗試按住視窗更長時間,然後再放開。"</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"請向上滑動,然後停住。"</string>
- <string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"您已學會如何使用手勢。如要關閉手勢,請前往「設定」。"</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"您已完成「切換應用程式」手勢的教學課程。"</string>
- <string name="overview_gesture_intro_title" msgid="2902054412868489378">"滑動即可切換應用程式"</string>
- <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"如要切換應用程式,請從螢幕底部向上滑動並按住,然後放開。"</string>
- <string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"大功告成"</string>
- <string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"完成"</string>
- <string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"設定"</string>
- <string name="gesture_tutorial_try_again" msgid="65962545858556697">"再試一次"</string>
- <string name="gesture_tutorial_nice" msgid="2936275692616928280">"做得好!"</string>
- <string name="gesture_tutorial_step" msgid="1279786122817620968">"教學課程 <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
- <string name="allset_title" msgid="5021126669778966707">"設定完成!"</string>
- <string name="allset_hint" msgid="2384632994739392447">"向上滑動即可前往主畫面"</string>
- <string name="allset_description" msgid="6350320429953234580">"您可以開始使用手機了"</string>
- <string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"系統導覽設定"</annotation></string>
- <string name="action_share" msgid="2648470652637092375">"分享"</string>
- <string name="action_screenshot" msgid="8171125848358142917">"螢幕截圖"</string>
- <string name="action_split" msgid="2098009717623550676">"分割"</string>
- <string name="toast_split_select_app" msgid="5453865907322018352">"輕按其他應用程式以使用分割螢幕"</string>
- <string name="toast_split_app_unsupported" msgid="3271526028981899666">"應用程式不支援分割螢幕。"</string>
- <string name="blocked_by_policy" msgid="2071401072261365546">"應用程式或您的機構不允許此操作"</string>
- <string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"要略過手勢操作教學課程嗎?"</string>
- <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"您之後可以在「<xliff:g id="NAME">%1$s</xliff:g>」應用程式找到這些說明"</string>
- <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"取消"</string>
- <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"略過"</string>
- <string name="accessibility_rotate_button" msgid="4771825231336502943">"旋轉螢幕"</string>
- <string name="taskbar_edu_opened" msgid="3950252793551919129">"顯示咗工作列教學"</string>
- <string name="taskbar_edu_closed" msgid="126643734478892862">"閂咗工作列教學"</string>
- <string name="taskbar_edu_switch_apps" msgid="6942863327845784813">"使用工作列即可切換應用程式"</string>
- <string name="taskbar_edu_splitscreen" msgid="2663361731630346489">"拖曳至一側即可同時使用兩個應用程式"</string>
- <string name="taskbar_edu_stashing" msgid="5212374387411764031">"按住即可隱藏工作列"</string>
- <string name="taskbar_edu_next" msgid="4007618274426775841">"繼續"</string>
- <string name="taskbar_edu_previous" msgid="459202320127201702">"返回"</string>
- <string name="taskbar_edu_close" msgid="887022990168191073">"關閉"</string>
- <string name="taskbar_edu_done" msgid="6880178093977704569">"完成"</string>
- <string name="taskbar_button_home" msgid="2151398979630664652">"住宅"</string>
- <string name="taskbar_button_a11y" msgid="5241161324875094465">"無障礙功能"</string>
- <string name="taskbar_button_back" msgid="8558862226461164514">"返回"</string>
- <string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"輸入法編輯器切換工具"</string>
- <string name="taskbar_button_recents" msgid="7273376136216613134">"最近"</string>
- <!-- no translation found for taskbar_button_notifications (7471740351507357318) -->
- <skip />
- <!-- no translation found for taskbar_button_quick_settings (227662894293189391) -->
- <skip />
- <string name="move_drop_target_top_or_left" msgid="2988702185049595807">"移至上方/左側"</string>
- <string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"移至底部/右側"</string>
</resources>
diff --git a/quickstep/res/values-zh-rTW/strings.xml b/quickstep/res/values-zh-rTW/strings.xml
index 847cb91507..3323bfd57d 100644
--- a/quickstep/res/values-zh-rTW/strings.xml
+++ b/quickstep/res/values-zh-rTW/strings.xml
@@ -19,93 +19,19 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="recent_task_option_split_screen" msgid="5353188922202653570">"分割畫面"</string>
<string name="recent_task_option_pin" msgid="7929860679018978258">"固定"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"自由形式"</string>
+ <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"總覽"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"最近沒有任何項目"</string>
+ <string name="accessibility_close_task" msgid="5354563209433803643">"關閉"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"應用程式使用情況設定"</string>
<string name="recents_clear_all" msgid="5328176793634888831">"全部清除"</string>
<string name="accessibility_recent_apps" msgid="4058661986695117371">"最近使用的應用程式"</string>
- <string name="task_view_closed" msgid="9170038230110856166">"工作已關閉"</string>
<string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g> (<xliff:g id="REMAINING_TIME">%2$s</xliff:g>)"</string>
<string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 分鐘"</string>
<string name="time_left_for_app" msgid="3111996412933644358">"今天還能使用 <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="title_app_suggestions" msgid="4185902664111965088">"應用程式建議"</string>
+ <string name="all_apps_label" msgid="8542784161730910663">"所有應用程式"</string>
<string name="all_apps_prediction_tip" msgid="2672336544844936186">"系統預測你會使用的應用程式"</string>
- <string name="hotseat_edu_title_migrate" msgid="306578144424489980">"在主畫面底部顯示應用程式建議"</string>
- <string name="hotseat_edu_title_migrate_landscape" msgid="3633942953997845243">"在主畫面的收藏列取得應用程式建議"</string>
- <string name="hotseat_edu_message_migrate" msgid="8927179260533775320">"你可以輕鬆地在主畫面上找到自己常用的應用程式。應用程式建議會依據你的日常使用習慣而有所不同。系統會將底部列出的應用程式上移到主畫面。"</string>
- <string name="hotseat_edu_message_migrate_landscape" msgid="4248943380443387697">"你可以輕鬆地在主畫面上找到自己常用的應用程式。系統會根據你的日常使用習慣提供不同的應用程式建議,並在主畫面顯示收藏列中的應用程式。"</string>
- <string name="hotseat_edu_message_migrate_alt" msgid="3042360119039646356">"你可以輕鬆地在主畫面上找到自己常用的應用程式。應用程式建議會根據日常安排有所不同。系統會將底部列出的應用程式移到新的資料夾。"</string>
- <string name="hotseat_edu_accept" msgid="1611544083278999837">"取得應用程式建議"</string>
- <string name="hotseat_edu_dismiss" msgid="2781161822780201689">"不用了,謝謝"</string>
- <string name="hotseat_prediction_settings" msgid="6246554993566070818">"設定"</string>
- <string name="hotseat_auto_enrolled" msgid="522100018967146807">"最常使用的應用程式會顯示在這裡,顯示的項目會根據日常安排有所不同"</string>
- <string name="hotseat_tip_no_empty_slots" msgid="1325212677738179185">"將底部列中顯示的應用程式拖曳出來,即可取得應用程式建議"</string>
- <string name="hotseat_tip_gaps_filled" msgid="3035673010274223538">"應用程式建議已新增到空白位置"</string>
- <string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"應用程式建議功能已啟用"</string>
- <string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"應用程式建議功能已停用"</string>
- <string name="hotseat_prediction_content_description" msgid="4582028296938078419">"預測的應用程式:<xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"請從螢幕右側或左側邊緣滑動。"</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"請從螢幕右側或左側邊緣往中央滑動,然後放開手指。"</string>
- <string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"你已瞭解如何透過「由右向左滑動」手勢返回。接著,一起來瞭解如何切換應用程式。"</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"你已完成「返回」手勢的教學課程。"</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"滑動時,手的位置不要太接近螢幕底部。"</string>
- <string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"如要變更「返回」手勢的敏感度,請前往「設定」"</string>
- <string name="back_gesture_intro_title" msgid="19551256430224428">"滑動即可返回"</string>
- <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"如要返回上一個畫面,請從螢幕左側或右側邊緣往中央滑動。"</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"請從螢幕底部邊緣向上滑動。"</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"放開手指前請勿停下來。"</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"請向上滑動。"</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"你已完成「返回主畫面」手勢的教學課程。接著,一起來瞭解如何返回上一個畫面。"</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"你已完成「返回主畫面」手勢的教學課程。"</string>
- <string name="home_gesture_intro_title" msgid="836590312858441830">"使用滑動手勢返回主畫面"</string>
- <string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"從螢幕底部向上滑動,即可返回主畫面。"</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"請從螢幕底部邊緣向上滑動。"</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"請按住視窗久一點,然後再放開。"</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"請向上滑動,然後停住。"</string>
- <string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"你已瞭解如何使用手勢了。如要關閉手勢,請前往「設定」。"</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"你已完成「切換應用程式」手勢的教學課程。"</string>
- <string name="overview_gesture_intro_title" msgid="2902054412868489378">"使用滑動手勢切換應用程式"</string>
- <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"如要切換不同的應用程式,請從螢幕底部向上滑動並按住,然後放開手指。"</string>
- <string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"大功告成"</string>
- <string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"完成"</string>
- <string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"設定"</string>
- <string name="gesture_tutorial_try_again" msgid="65962545858556697">"重試"</string>
- <string name="gesture_tutorial_nice" msgid="2936275692616928280">"很好!"</string>
- <string name="gesture_tutorial_step" msgid="1279786122817620968">"教學課程 <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
- <string name="allset_title" msgid="5021126669778966707">"設定完成!"</string>
- <string name="allset_hint" msgid="2384632994739392447">"向上滑動即可前往主畫面"</string>
- <string name="allset_description" msgid="6350320429953234580">"你可以開始使用手機了"</string>
- <string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"系統操作機制設定"</annotation></string>
- <string name="action_share" msgid="2648470652637092375">"分享"</string>
- <string name="action_screenshot" msgid="8171125848358142917">"螢幕截圖"</string>
- <string name="action_split" msgid="2098009717623550676">"分割"</string>
- <string name="toast_split_select_app" msgid="5453865907322018352">"輕觸另一個應用程式即可使用分割畫面"</string>
- <string name="toast_split_app_unsupported" msgid="3271526028981899666">"這個應用程式不支援分割畫面。"</string>
- <string name="blocked_by_policy" msgid="2071401072261365546">"這個應用程式或貴機構不允許執行這個動作"</string>
- <string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"要略過手勢操作教學課程嗎?"</string>
- <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"你之後可以在「<xliff:g id="NAME">%1$s</xliff:g>」應用程式找到這些說明"</string>
- <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"取消"</string>
- <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"略過"</string>
- <string name="accessibility_rotate_button" msgid="4771825231336502943">"旋轉螢幕"</string>
- <string name="taskbar_edu_opened" msgid="3950252793551919129">"工作列教學課程已顯示"</string>
- <string name="taskbar_edu_closed" msgid="126643734478892862">"工作列教學課程已關閉"</string>
- <string name="taskbar_edu_switch_apps" msgid="6942863327845784813">"使用工作列即可切換應用程式"</string>
- <string name="taskbar_edu_splitscreen" msgid="2663361731630346489">"拖曳到一邊即可同時使用兩個應用程式"</string>
- <string name="taskbar_edu_stashing" msgid="5212374387411764031">"按住即可隱藏工作列"</string>
- <string name="taskbar_edu_next" msgid="4007618274426775841">"繼續"</string>
- <string name="taskbar_edu_previous" msgid="459202320127201702">"返回"</string>
- <string name="taskbar_edu_close" msgid="887022990168191073">"關閉"</string>
- <string name="taskbar_edu_done" msgid="6880178093977704569">"完成"</string>
- <string name="taskbar_button_home" msgid="2151398979630664652">"主畫面"</string>
- <string name="taskbar_button_a11y" msgid="5241161324875094465">"無障礙工具"</string>
- <string name="taskbar_button_back" msgid="8558862226461164514">"返回"</string>
- <string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"輸入法編輯器切換器"</string>
- <string name="taskbar_button_recents" msgid="7273376136216613134">"最近使用"</string>
- <!-- no translation found for taskbar_button_notifications (7471740351507357318) -->
- <skip />
- <!-- no translation found for taskbar_button_quick_settings (227662894293189391) -->
- <skip />
- <string name="move_drop_target_top_or_left" msgid="2988702185049595807">"移到上方/左側"</string>
- <string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"移到底部/右側"</string>
</resources>
diff --git a/quickstep/res/values-zu/strings.xml b/quickstep/res/values-zu/strings.xml
index 98ea6d7b96..0f1d99d7b6 100644
--- a/quickstep/res/values-zu/strings.xml
+++ b/quickstep/res/values-zu/strings.xml
@@ -19,91 +19,19 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Hlukanisa isikrini"</string>
<string name="recent_task_option_pin" msgid="7929860679018978258">"Phina"</string>
<string name="recent_task_option_freeform" msgid="48863056265284071">"I-Freeform"</string>
+ <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Buka konke"</string>
<string name="recents_empty_message" msgid="7040467240571714191">"Azikho izinto zakamuva"</string>
+ <string name="accessibility_close_task" msgid="5354563209433803643">"Vala"</string>
<string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Izilungiselelo zokusetshenziswa kohlelo lokusebenza"</string>
<string name="recents_clear_all" msgid="5328176793634888831">"Sula konke"</string>
<string name="accessibility_recent_apps" msgid="4058661986695117371">"Izinhlelo zokusebenza zakamuva"</string>
- <string name="task_view_closed" msgid="9170038230110856166">"Umsebenzi Uvaliwe"</string>
<string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
<string name="shorter_duration_less_than_one_minute" msgid="4722015666335015336">"&lt; 1 iminithi"</string>
<string name="time_left_for_app" msgid="3111996412933644358">"<xliff:g id="TIME">%1$s</xliff:g> esele namhlanje"</string>
<string name="title_app_suggestions" msgid="4185902664111965088">"Iziphakamiso zohlelo lokusebenza"</string>
- <string name="all_apps_prediction_tip" msgid="2672336544844936186">"Ama-app akho aqagelwe"</string>
- <string name="hotseat_edu_title_migrate" msgid="306578144424489980">"Thola iziphakamiso ze-app emgqeni ongezansi wesikrini sakho sasekhaya"</string>
- <string name="hotseat_edu_title_migrate_landscape" msgid="3633942953997845243">"Thola iziphakamiso zohlelo lokusebenza kumugqa wezintandokazi Zesikrini sakho sasekhaya"</string>
- <string name="hotseat_edu_message_migrate" msgid="8927179260533775320">"Finyelela kalula izinhlelo zakho zokusebenza ezisetshenziswa kakhulu khona kusikrini sasekhaya. Iziphakamiso zizoshintsha ngokususelwe kwimijikelezo yakho. Izinhlelo zokusebenza ezisemgqeni ongezansi zizoya phezulu kusikrini sakho sasekhaya."</string>
- <string name="hotseat_edu_message_migrate_landscape" msgid="4248943380443387697">"Finyelela kalula izinhlelo zakho zokusebenza ezisetshenziswa kakhulu khona kusikrini sasekhaya. Iziphakamiso zizoshintsha ngokususelwe kwimijikelezo yakho. Izintandokazi zomugqa wezinhlelo zokusebenza zizoya Kusikrini sakho sasekhaya."</string>
- <string name="hotseat_edu_message_migrate_alt" msgid="3042360119039646356">"Finyelela kalula izinhlelo zakho zokusebenza ezisetshenziswa njalo, kusikrini sasekhaya. Iziphakamiso zizoshintsha ngokususelwe kwimijikelezo yakho. Izinhlelo zokusebenza ezisemgqeni ongezansi zizoya phezulu kufolda entsha."</string>
- <string name="hotseat_edu_accept" msgid="1611544083278999837">"Thola iziphakamiso zohlelo lokusebenza"</string>
- <string name="hotseat_edu_dismiss" msgid="2781161822780201689">"Cha ngiyabonga"</string>
- <string name="hotseat_prediction_settings" msgid="6246554993566070818">"Amasethingi"</string>
- <string name="hotseat_auto_enrolled" msgid="522100018967146807">"Izinhlelo zokusebenza ezisetshenziswa kakhulu zivela lapha, kanye noshintsho olususelwe kwimijikelezo"</string>
- <string name="hotseat_tip_no_empty_slots" msgid="1325212677738179185">"Hudula izinhlelo zokusebenza kusuka emgqeni ongezansi ukuthola iziphakamiso zohlelo lokusebenza"</string>
- <string name="hotseat_tip_gaps_filled" msgid="3035673010274223538">"Iziphakamiso zohlelo lokusebenza ezengezwe esikhaleni esingenalutho"</string>
- <string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"Iziphakamiso zohlelo lokusebenza zinikwe amandla"</string>
- <string name="hotsaet_tip_prediction_disabled" msgid="1506426298884658491">"Iziphakamiso zohlelo lokusebenza zikhutshaziwe"</string>
- <string name="hotseat_prediction_content_description" msgid="4582028296938078419">"Uhlelo lokusebenza olubikezelwe: <xliff:g id="TITLE">%1$s</xliff:g>"</string>
- <string name="back_gesture_feedback_swipe_too_far_from_edge" msgid="1711645592102201538">"Qiniseka ukuthi uswayipha kusuka onqenqemeni olukude ngakwesokudla noma olukude ngakwesokunxele."</string>
- <string name="back_gesture_feedback_cancelled" msgid="3274382913290074496">"Qiniseka ukuthi uswayipha kusuka kunqenqema ongakwesokudla noma ongakwesokunxele kuya maphakathi nesikrini bese uyadedela."</string>
- <string name="back_gesture_feedback_complete_with_overview_follow_up" msgid="9176400654037014471">"Ufunde indlela yokuswayipha kusuka kwesokudla ukuze ubuyele emuva. Ngokulandelayo, funda indlela yokushintsha ama-app."</string>
- <string name="back_gesture_feedback_complete_without_follow_up" msgid="6405649621667113830">"Ukuqedile ukuthinta kokubuyela emuva."</string>
- <string name="back_gesture_feedback_swipe_in_nav_bar" msgid="1148198467090405643">"Qiniseka ukuba awuswayipheli eduze kakhulu naphansi kwesikrini."</string>
- <string name="back_gesture_tutorial_confirm_subtitle" msgid="5181305411668713250">"Ukuze ushintshe ukuzwela kokuthinta emuva, iya Kumasethingi"</string>
- <string name="back_gesture_intro_title" msgid="19551256430224428">"Swayipha ukuze uye emuva"</string>
- <string name="back_gesture_intro_subtitle" msgid="7912576483031802797">"Ukuze ubuyele emuva esikrinini sokugcina, swapha kusuka emngceleni wesobunxele noma wesokudla kuya phakathi kwesikrini."</string>
- <string name="home_gesture_feedback_swipe_too_far_from_edge" msgid="1446774096007065298">"Qiniseka ukuthi uswayiphela phezulu kusuka emngceleni ophansi wesikrini."</string>
- <string name="home_gesture_feedback_overview_detected" msgid="1557523944897393013">"Qiniseka ukuthi awumisi ngaphambi kokudedela."</string>
- <string name="home_gesture_feedback_wrong_swipe_direction" msgid="6993979358080825438">"Qiniseka ukuthi uswayiphela ngqo phezulu."</string>
- <string name="home_gesture_feedback_complete_with_follow_up" msgid="1427872029729605034">"Ukuqedile ukuthinta kokuya Ekhaya. Ngokulandelayo, funda indlela yokuya emuva."</string>
- <string name="home_gesture_feedback_complete_without_follow_up" msgid="8049099486868933882">"Ukuqedile ukuthinta kokuya Ekhaya."</string>
- <string name="home_gesture_intro_title" msgid="836590312858441830">"Swayipha ukuze uye ekhaya"</string>
- <string name="home_gesture_intro_subtitle" msgid="2632238748497975326">"Swayiphela phezulu kusuka phansi kwesikrini sakho.Lokhu kuthinta kuhlala kukusa esikrinini sasekhaya."</string>
- <string name="overview_gesture_feedback_swipe_too_far_from_edge" msgid="3032757898111577225">"Qiniseka ukuthi uswayiphela phezulu kusuka emngceleni ophansi wesikrini."</string>
- <string name="overview_gesture_feedback_home_detected" msgid="1411130969354020489">"Zama ukubamba iwindi isikhashana ngaphambi kokulidedela."</string>
- <string name="overview_gesture_feedback_wrong_swipe_direction" msgid="6725820500906747925">"Qiniseka ukuthi uswayiphela ngqo phezulu bese uyamisa."</string>
- <string name="overview_gesture_feedback_complete_with_follow_up" msgid="3544611727467765026">"Ufunde ukusebenzisa ukuthinta. Ukuze uvale ukuthinta, iya kokuthi Amasethingi."</string>
- <string name="overview_gesture_feedback_complete_without_follow_up" msgid="3199486203448379152">"Ukuqedile ukuthinta kokushintsha ama-app."</string>
- <string name="overview_gesture_intro_title" msgid="2902054412868489378">"Swayipha ukuze ushintshe ama-app"</string>
- <string name="overview_gesture_intro_subtitle" msgid="4968091015637850859">"Ukuze ushintshe phakathi kwama-app, swayiphela phezulu kusuka ngezansi kwesikrini sakho, bese uyadedela."</string>
- <string name="gesture_tutorial_confirm_title" msgid="6201516182040074092">"Konke kusethiwe"</string>
- <string name="gesture_tutorial_action_button_label" msgid="6249846312991332122">"Kwenziwe"</string>
- <string name="gesture_tutorial_action_button_label_settings" msgid="2923621047916486604">"Amasethingi"</string>
- <string name="gesture_tutorial_try_again" msgid="65962545858556697">"Zama futhi"</string>
- <string name="gesture_tutorial_nice" msgid="2936275692616928280">"Kuhle!"</string>
- <string name="gesture_tutorial_step" msgid="1279786122817620968">"Okokufundisa <xliff:g id="CURRENT">%1$d</xliff:g>/<xliff:g id="TOTAL">%2$d</xliff:g>"</string>
- <string name="allset_title" msgid="5021126669778966707">"Konke kusethiwe!"</string>
- <string name="allset_hint" msgid="2384632994739392447">"Swayiphela phezulu ukuze uye Ekhaya"</string>
- <string name="allset_description" msgid="6350320429953234580">"Usulungele ukuqala ukusebenzisa ifoni yakho"</string>
- <string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"Amasethingi wokuzulazula isistimu"</annotation></string>
- <string name="action_share" msgid="2648470652637092375">"Yabelana"</string>
- <string name="action_screenshot" msgid="8171125848358142917">"Isithombe-skrini"</string>
- <string name="action_split" msgid="2098009717623550676">"Hlukanisa"</string>
- <string name="toast_split_select_app" msgid="5453865907322018352">"Thepha enye i-app ukuze usebenzise isikrini sokuhlukanisa"</string>
- <string name="toast_split_app_unsupported" msgid="3271526028981899666">"Uhlelo lokusebenza alusekeli isikrini esihlukanisiwe."</string>
- <string name="blocked_by_policy" msgid="2071401072261365546">"Lesi senzo asivunyelwanga uhlelo lokusebenza noma inhlangano yakho"</string>
- <string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Yeqa isifundo sokuzulazula?"</string>
- <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Lokhu ungakuthola kamuva ku-app ye-<xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Khansela"</string>
- <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Yeqa"</string>
- <string name="accessibility_rotate_button" msgid="4771825231336502943">"Zungezisa isikrini"</string>
- <string name="taskbar_edu_opened" msgid="3950252793551919129">"Imfuno yebha yomsebenzi ivelile"</string>
- <string name="taskbar_edu_closed" msgid="126643734478892862">"Imfundo yebha yomsebenzi ivaliwe"</string>
- <string name="taskbar_edu_switch_apps" msgid="6942863327845784813">"Sebenzisa ibha yomsebenzi ukushintsha ama-app"</string>
- <string name="taskbar_edu_splitscreen" msgid="2663361731630346489">"Hudula ngaseceleni ukuze usebenzise ama-app amabili ngesikhathi esisodwa"</string>
- <string name="taskbar_edu_stashing" msgid="5212374387411764031">"Thinta futhi ubambe, bamba ukuze ufihle ibha yomsebenzi"</string>
- <string name="taskbar_edu_next" msgid="4007618274426775841">"Okulandelayo"</string>
- <string name="taskbar_edu_previous" msgid="459202320127201702">"Emuva"</string>
- <string name="taskbar_edu_close" msgid="887022990168191073">"Vala"</string>
- <string name="taskbar_edu_done" msgid="6880178093977704569">"Kwenziwe"</string>
- <string name="taskbar_button_home" msgid="2151398979630664652">"Ikhaya"</string>
- <string name="taskbar_button_a11y" msgid="5241161324875094465">"Ukufinyeleleka"</string>
- <string name="taskbar_button_back" msgid="8558862226461164514">"Emuva"</string>
- <string name="taskbar_button_ime_switcher" msgid="1730244360907588541">"Isishintshi se-IME"</string>
- <string name="taskbar_button_recents" msgid="7273376136216613134">"Okwakamuva"</string>
- <string name="taskbar_button_notifications" msgid="7471740351507357318">"Izaziso"</string>
- <string name="taskbar_button_quick_settings" msgid="227662894293189391">"Amasethingi Asheshayo"</string>
- <string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Hamba phezulu/kwesokunxele"</string>
- <string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Hamba phansi/kwesokudla"</string>
+ <string name="all_apps_label" msgid="8542784161730910663">"Zonke izinhlelo zokusebenza"</string>
+ <string name="all_apps_prediction_tip" msgid="2672336544844936186">"Izinhlelo zakho zokusebenza eziqagelwe"</string>
</resources>
diff --git a/quickstep/res/values/colors.xml b/quickstep/res/values/colors.xml
index 185c815ea1..167c7c3d0f 100644
--- a/quickstep/res/values/colors.xml
+++ b/quickstep/res/values/colors.xml
@@ -13,7 +13,9 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<resources xmlns:android="http://schemas.android.com/apk/res/android">
+<resources>
+ <color name="back_arrow_color_light">#FFFFFFFF</color>
+ <color name="back_arrow_color_dark">#99000000</color>
<color name="chip_hint_foreground_color">#fff</color>
<color name="chip_scrim_start_color">#39000000</color>
@@ -24,56 +26,6 @@
<color name="all_apps_prediction_row_separator_dark">#3cffffff</color>
<!-- Taskbar -->
- <color name="taskbar_nav_icon_selection_ripple">#E0E0E0</color>
- <color name="taskbar_nav_icon_light_color">#ffffff</color>
- <!-- The dark navigation button color is only used in the rare cases that taskbar isn't drawing
- its background and the underlying app has requested dark buttons. -->
- <color name="taskbar_nav_icon_dark_color">#99000000</color>
- <color name="taskbar_stashed_handle_light_color">#EBffffff</color>
- <color name="taskbar_stashed_handle_dark_color">#99000000</color>
-
- <!-- Gesture navigation tutorial -->
- <color name="gesture_tutorial_back_arrow_color">#FFFFFFFF</color>
-
- <color name="gesture_tutorial_fake_wallpaper_color">#f9f9f9</color> <!-- White -->
- <color name="gesture_tutorial_ripple_color">#A0C2F9</color> <!-- Light Blue -->
- <color name="gesture_tutorial_fake_task_view_color">#6DA1FF</color> <!-- Light Blue -->
- <!-- Must contrast gesture_tutorial_fake_wallpaper_color -->
- <color name="gesture_tutorial_fake_previous_task_view_color">#3C4043</color> <!-- Gray -->
- <color name="gesture_tutorial_taskbar_color">#202124</color>
-
- <!-- Mock hotseat -->
- <color name="mock_app_icon_1">#8AB4F8</color>
- <color name="mock_app_icon_2">#F28B82</color>
- <color name="mock_app_icon_3">#FDD663</color>
- <color name="mock_app_icon_4">#81C995</color>
- <color name="mock_search_bar">#3C4043</color>
-
- <!-- Mock conversation -->
- <color name="mock_conversation_background">#f1f3f4</color>
- <color name="mock_conversation_top_bar">#e8eaed</color>
- <color name="mock_conversation_top_bar_item">#dadce0</color>
- <color name="mock_conversation_sent_message">#bdc1c6</color>
- <color name="mock_conversation_received_message">#e8eaed</color>
- <color name="mock_conversation_message_input">#dadce0</color>
- <color name="mock_conversation_profile_icon">#dadce0</color>
-
- <!-- Mock conversations list -->
- <color name="mock_list_background">#dadce0</color>
- <color name="mock_list_top_bar">#e8eaed</color>
- <color name="mock_list_top_bar_item">#f8f9fa</color>
- <color name="mock_list_profile_icon">#9aa0a6</color>
- <color name="mock_list_preview_message">#bdc1c6</color>
- <color name="mock_list_button">#bdc1c6</color>
-
- <!-- Mock web page -->
- <color name="mock_webpage_background">#f1f3f4</color>
- <color name="mock_webpage_url_bar">#6e7175</color>
- <color name="mock_webpage_url_bar_item">#9a9a9a</color>
- <color name="mock_webpage_top_bar">#e8eaed</color>
- <color name="mock_webpage_top_bar_item">#80868b</color>
- <color name="mock_webpage_page_text">#bdc1c6</color>
-
- <color name="all_set_page_background">#FFFFFFFF</color>
-
+ <color name="taskbar_background">#101010</color>
+ <color name="taskbar_icon_selection_ripple">#E0E0E0</color>
</resources> \ No newline at end of file
diff --git a/quickstep/res/values/config.xml b/quickstep/res/values/config.xml
index 3b4a28b39c..d67b23be0a 100644
--- a/quickstep/res/values/config.xml
+++ b/quickstep/res/values/config.xml
@@ -23,14 +23,13 @@
</string-array>
<string name="stats_log_manager_class" translatable="false">com.android.quickstep.logging.StatsLogCompatManager</string>
+
<string name="test_information_handler_class" translatable="false">com.android.quickstep.QuickstepTestInformationHandler</string>
- <string name="window_manager_proxy_class" translatable="false">com.android.quickstep.util.SystemWindowManagerProxy</string>
<!-- The number of thumbnails and icons to keep in the cache. The thumbnail cache size also
determines how many thumbnails will be fetched in the background. -->
<integer name="recentsThumbnailCacheSize">3</integer>
<integer name="recentsIconCacheSize">12</integer>
- <integer name="recentsScrollHapticMinGapMillis">20</integer>
<!-- Assistant Gesture -->
<integer name="assistant_gesture_min_time_threshold">200</integer>
@@ -39,8 +38,4 @@
<string name="wellbeing_provider_pkg" translatable="false"/>
<integer name="max_depth_blur_radius">23</integer>
-
- <!-- Accessibility actions -->
- <item type="id" name="action_move_to_top_or_left" />
- <item type="id" name="action_move_to_bottom_or_right" />
</resources>
diff --git a/quickstep/res/values/dimens.xml b/quickstep/res/values/dimens.xml
index 3072a3ee10..6cc64e0aa7 100644
--- a/quickstep/res/values/dimens.xml
+++ b/quickstep/res/values/dimens.xml
@@ -15,6 +15,8 @@
-->
<resources>
+ <dimen name="task_thumbnail_icon_size">48dp</dimen>
+ <dimen name="task_thumbnail_icon_size_grid">32dp</dimen>
<!-- For screens without rounded corners -->
<dimen name="task_corner_radius_small">2dp</dimen>
<!-- For Launchers that want to override the default dialog corner radius -->
@@ -24,26 +26,24 @@
<dimen name="task_menu_corner_radius">22dp</dimen>
<dimen name="task_menu_item_corner_radius">4dp</dimen>
<dimen name="task_menu_spacing">2dp</dimen>
- <dimen name="task_menu_width_grid">216dp</dimen>
- <dimen name="task_menu_horizontal_padding">8dp</dimen>
<dimen name="overview_proactive_row_height">48dp</dimen>
<dimen name="overview_proactive_row_bottom_margin">16dp</dimen>
<dimen name="overview_minimum_next_prev_size">50dp</dimen>
-
- <!-- Task View -->
- <dimen name="task_thumbnail_icon_size">48dp</dimen>
- <dimen name="task_thumbnail_icon_drawable_size">44dp</dimen>
<dimen name="overview_task_margin">16dp</dimen>
- <dimen name="overview_page_spacing">16dp</dimen>
-
- <item name="overview_max_scale" format="float" type="dimen">0.7</item>
- <item name="overview_modal_max_scale" format="float" type="dimen">1.1</item>
<!-- Overrideable in overlay that provides the Overview Actions. -->
- <dimen name="overview_actions_top_margin">24dp</dimen>
<dimen name="overview_actions_height">48dp</dimen>
- <dimen name="overview_actions_button_spacing">36dp</dimen>
+ <dimen name="overview_actions_bottom_margin_gesture">28dp</dimen>
+ <dimen name="overview_actions_bottom_margin_three_button">8dp</dimen>
+ <dimen name="overview_actions_horizontal_margin">16dp</dimen>
+
+ <dimen name="overview_grid_top_margin">77dp</dimen>
+ <dimen name="overview_grid_bottom_margin">90dp</dimen>
+ <dimen name="overview_grid_side_margin">54dp</dimen>
+ <dimen name="overview_grid_row_spacing">42dp</dimen>
+ <dimen name="overview_grid_focus_vertical_margin">90dp</dimen>
+ <dimen name="split_placeholder_size">110dp</dimen>
<!-- These speeds are in dp/s -->
<dimen name="max_task_dismiss_drag_velocity">2.25dp</dimen>
@@ -51,6 +51,7 @@
<dimen name="default_task_dismiss_drag_velocity_grid">1dp</dimen>
<dimen name="default_task_dismiss_drag_velocity_grid_focus_task">5dp</dimen>
+ <dimen name="recents_page_spacing">16dp</dimen>
<dimen name="recents_clear_all_deadzone_vertical_margin">70dp</dimen>
<!-- The speed in dp/s at which the user needs to be scrolling in recents such that we start
@@ -69,8 +70,6 @@
<item name="content_scale" format="float" type="dimen">0.97</item>
<dimen name="closing_window_trans_y">115dp</dimen>
- <dimen name="quick_switch_scaling_scroll_threshold">100dp</dimen>
-
<dimen name="recents_empty_message_text_size">16sp</dimen>
<dimen name="recents_empty_message_text_padding">16dp</dimen>
@@ -82,7 +81,7 @@
<dimen name="task_menu_vertical_padding">8dp</dimen>
<dimen name="task_card_margin">8dp</dimen>
<dimen name="task_card_menu_shadow_height">3dp</dimen>
- <dimen name="task_menu_option_start_margin">16dp</dimen>
+ <dimen name="task_menu_option_start_margin">12dp</dimen>
<!-- Copied from framework resource:
docked_stack_divider_thickness - 2 * docked_stack_divider_insets -->
<dimen name="multi_window_task_divider_size">10dp</dimen>
@@ -109,99 +108,17 @@
<dimen name="gestures_overscroll_finish_threshold">136dp</dimen>
<!-- Tips Gesture Tutorial -->
- <dimen name="gesture_tutorial_feedback_margin_start_end">8dp</dimen>
- <dimen name="gesture_tutorial_tablet_feedback_margin_start_end">140dp</dimen>
- <dimen name="gesture_tutorial_feedback_margin_top">16dp</dimen>
- <dimen name="gesture_tutorial_tablet_feedback_margin_top">24dp</dimen>
- <dimen name="gesture_tutorial_multi_row_task_view_spacing">72dp</dimen>
- <dimen name="gesture_tutorial_small_task_view_corner_radius">18dp</dimen>
- <dimen name="gesture_tutorial_mock_taskbar_height">80dp</dimen>
-
- <!-- Gesture Tutorial mock conversations -->
- <dimen name="gesture_tutorial_message_icon_size">44dp</dimen>
- <dimen name="gesture_tutorial_message_icon_corner_radius">100dp</dimen>
- <dimen name="gesture_tutorial_message_input_margin_top">36dp</dimen>
- <dimen name="gesture_tutorial_message_large_margin_bottom">32dp</dimen>
- <dimen name="gesture_tutorial_message_small_margin_bottom">4dp</dimen>
- <dimen name="gesture_tutorial_message_padding_start">26dp</dimen>
- <dimen name="gesture_tutorial_message_padding_end">18dp</dimen>
- <dimen name="gesture_tutorial_top_bar_margin_start">34dp</dimen>
- <dimen name="gesture_tutorial_top_bar_margin_end">211dp</dimen>
- <dimen name="gesture_tutorial_top_bar_button_margin_end">24dp</dimen>
- <dimen name="gesture_tutorial_conversation_bottom_padding">66dp</dimen>
- <integer name="gesture_tutorial_extra_messages_visibility">0</integer> <!-- VISIBLE -->
- <dimen name="gesture_tutorial_message_margin_start">124dp</dimen>
- <dimen name="gesture_tutorial_reply_margin_end">144dp</dimen>
- <dimen name="gesture_tutorial_input_margin_start">34dp</dimen>
- <dimen name="gesture_tutorial_input_margin_end">24dp</dimen>
- <dimen name="gesture_tutorial_tablet_message_padding_start_end">126dp</dimen>
- <dimen name="gesture_tutorial_tablet_message_1_margin">245dp</dimen>
- <dimen name="gesture_tutorial_tablet_reply_1_margin">241dp</dimen>
- <dimen name="gesture_tutorial_tablet_message_2_margin">401dp</dimen>
- <dimen name="gesture_tutorial_tablet_message_3_margin">245dp</dimen>
- <dimen name="gesture_tutorial_tablet_reply_2_margin">273dp</dimen>
-
- <!-- Gesture Tutorial mock conversation lists -->
- <dimen name="gesture_tutorial_conversation_icon_size">56dp</dimen>
- <dimen name="gesture_tutorial_conversation_icon_corner_radius">100dp</dimen>
- <dimen name="gesture_tutorial_conversation_list_padding_top">28dp</dimen>
- <dimen name="gesture_tutorial_conversation_line_padding_start">20dp</dimen>
- <dimen name="gesture_tutorial_conversation_line_1_margin_end">217dp</dimen>
- <dimen name="gesture_tutorial_conversation_line_2_margin_end">142dp</dimen>
- <dimen name="gesture_tutorial_conversation_line_3_margin_end">190dp</dimen>
- <dimen name="gesture_tutorial_conversation_line_4_margin_end">171dp</dimen>
- <dimen name="gesture_tutorial_conversation_line_5_margin_end">198dp</dimen>
- <dimen name="gesture_tutorial_conversation_line_6_margin_end">79dp</dimen>
- <dimen name="gesture_tutorial_conversation_line_7_margin_end">174dp</dimen>
- <dimen name="gesture_tutorial_conversation_line_8_margin_end">117dp</dimen>
- <dimen name="gesture_tutorial_tablet_conversation_line_6_margin_end">65dp</dimen>
- <dimen name="gesture_tutorial_tablet_conversation_line_8_margin_end">132dp</dimen>
- <dimen name="gesture_tutorial_tablet_conversation_line_10_margin_end">161dp</dimen>
- <integer name="gesture_tutorial_extra_conversations_visibility">0</integer> <!-- VISIBLE -->
- <dimen name="gesture_tutorial_mock_button_margin_end">24dp</dimen>
- <dimen name="gesture_tutorial_mock_button_margin_bottom">66dp</dimen>
-
- <!-- Gesture Tutorial mock hotseats -->
- <dimen name="gesture_tutorial_hotseat_width">-1px</dimen> <!-- match_parent -->
- <dimen name="gesture_tutorial_hotseat_height">-2px</dimen> <!-- wrap_content -->
- <dimen name="gesture_tutorial_hotseat_padding_start_end">26dp</dimen>
- <dimen name="gesture_tutorial_hotseat_icon_size">60dp</dimen>
- <dimen name="gesture_tutorial_hotseat_icon_corner_radius">100dp</dimen>
- <dimen name="gesture_tutorial_hotseat_search_height">50dp</dimen>
- <dimen name="gesture_tutorial_hotseat_search_corner_radius">100dp</dimen>
- <dimen name="gesture_tutorial_hotseat_icon_search_margin">36dp</dimen>
-
- <!-- Gesture Tutorial mock webpages -->
- <dimen name="gesture_tutorial_webpage_padding_top">32dp</dimen>
- <dimen name="gesture_tutorial_webpage_large_margin_top">24dp</dimen>
- <dimen name="gesture_tutorial_webpage_small_margin_top">8dp</dimen>
- <dimen name="gesture_tutorial_webpage_large_corner_radius">22dp</dimen>
- <dimen name="gesture_tutorial_webpage_medium_corner_radius">8dp</dimen>
- <dimen name="gesture_tutorial_webpage_small_corner_radius">4dp</dimen>
- <dimen name="gesture_tutorial_webpage_large_line_height">36dp</dimen>
- <dimen name="gesture_tutorial_webpage_small_line_height">22dp</dimen>
- <dimen name="gesture_tutorial_webpage_url_margin_start_end">16dp</dimen>
- <dimen name="gesture_tutorial_webpage_top_bar_button_margin_start">24dp</dimen>
- <dimen name="gesture_tutorial_webpage_top_bar_margin_start">97dp</dimen>
- <dimen name="gesture_tutorial_webpage_top_bar_margin_end">97dp</dimen>
- <dimen name="gesture_tutorial_webpage_line_1_margin_end">126dp</dimen>
- <dimen name="gesture_tutorial_webpage_line_2_margin_end">64dp</dimen>
- <dimen name="gesture_tutorial_webpage_line_3_margin_end">151dp</dimen>
- <dimen name="gesture_tutorial_webpage_block_margin_end">24dp</dimen>
- <integer name="gesture_tutorial_webpage_extra_lines_visibility">0</integer> <!-- VISIBLE -->
-
- <!-- Gesture Tutorial mock taskbar -->
- <dimen name="gesture_tutorial_taskbar_icon_size">44dp</dimen>
- <dimen name="gesture_tutorial_taskbar_icon_corner_radius">100dp</dimen>
- <dimen name="gesture_tutorial_taskbar_padding_start_end">52dp</dimen>
+ <dimen name="gesture_tutorial_title_margin_start_end">40dp</dimen>
+ <dimen name="gesture_tutorial_subtitle_margin_start_end">16dp</dimen>
+ <dimen name="gesture_tutorial_feedback_margin_start_end">24dp</dimen>
+ <dimen name="gesture_tutorial_button_margin_start_end">18dp</dimen>
<!-- All Set page -->
<dimen name="allset_page_margin_horizontal">40dp</dimen>
<dimen name="allset_title_margin_top">24dp</dimen>
<dimen name="allset_title_icon_margin_top">32dp</dimen>
+ <dimen name="allset_hint_margin_bottom">52dp</dimen>
<dimen name="allset_subtitle_margin_top">24dp</dimen>
- <dimen name="allset_subtitle_width_max">348dp</dimen>
- <dimen name="allset_swipe_up_shift">10dp</dimen>
<!-- All Apps Education tutorial -->
<dimen name="swipe_edu_padding">8dp</dimen>
@@ -231,41 +148,13 @@
<!-- Minimum distance to swipe to trigger accessibility gesture -->
<dimen name="accessibility_gesture_min_swipe_distance">80dp</dimen>
- <!-- The maximum width of the navigation bar ripples. -->
- <dimen name="key_button_ripple_max_width">95dp</dimen>
-
- <dimen name="rounded_corner_content_padding">0dp</dimen>
-
- <dimen name="navigation_key_padding">0dp</dimen>
-
- <!-- Floating rotation button -->
- <dimen name="floating_rotation_button_diameter">40dp</dimen>
- <dimen name="floating_rotation_button_min_margin">20dp</dimen>
- <dimen name="floating_rotation_button_taskbar_left_margin">20dp</dimen>
- <dimen name="floating_rotation_button_taskbar_bottom_margin">10dp</dimen>
-
<!-- Taskbar -->
- <dimen name="taskbar_size">@*android:dimen/taskbar_frame_height</dimen>
- <dimen name="taskbar_ime_size">48dp</dimen>
+ <dimen name="taskbar_size">60dp</dimen>
+ <dimen name="taskbar_icon_size">44dp</dimen>
<dimen name="taskbar_icon_touch_size">48dp</dimen>
<dimen name="taskbar_icon_drag_icon_size">54dp</dimen>
+ <!-- Note that this applies to both sides of all icons, so visible space is double this. -->
+ <dimen name="taskbar_icon_spacing">8dp</dimen>
<dimen name="taskbar_folder_margin">16dp</dimen>
<dimen name="taskbar_nav_buttons_spacing">16dp</dimen>
- <dimen name="taskbar_contextual_padding_top">8dp</dimen>
- <dimen name="taskbar_nav_buttons_size">44dp</dimen>
- <dimen name="taskbar_contextual_button_margin">40dp</dimen>
- <dimen name="taskbar_hotseat_nav_spacing">42dp</dimen>
- <dimen name="taskbar_contextual_buttons_size">35dp</dimen>
- <dimen name="taskbar_stashed_size">24dp</dimen>
- <dimen name="taskbar_stashed_handle_width">220dp</dimen>
- <dimen name="taskbar_unstash_input_area">316dp</dimen>
- <dimen name="taskbar_stashed_handle_height">4dp</dimen>
- <dimen name="taskbar_edu_wave_anim_trans_y">25dp</dimen>
- <dimen name="taskbar_edu_wave_anim_trans_y_return_overshoot">4dp</dimen>
- <dimen name="taskbar_nav_buttons_width_kids">88dp</dimen>
- <dimen name="taskbar_nav_buttons_height_kids">40dp</dimen>
- <dimen name="taskbar_nav_buttons_corner_radius_kids">40dp</dimen>
- <dimen name="taskbar_back_button_left_margin_kids">48dp</dimen>
- <dimen name="taskbar_home_button_left_margin_kids">48dp</dimen>
- <dimen name="taskbar_icon_size_kids">32dp</dimen>
</resources>
diff --git a/quickstep/res/values/strings.xml b/quickstep/res/values/strings.xml
index 81b0dd297c..4aee2a9ccb 100644
--- a/quickstep/res/values/strings.xml
+++ b/quickstep/res/values/strings.xml
@@ -39,9 +39,6 @@
<!-- Accessibility title for the list of recent apps [CHAR_LIMIT=none] -->
<string name="accessibility_recent_apps">Recent apps</string>
- <!-- Accessibility confirmation for task closed -->
- <string name="task_view_closed">Task Closed</string>
-
<!-- Accessibility title for an app card in Recents for apps that have time limit set
[CHAR_LIMIT=none] -->
<string name="task_contents_description_with_remaining_time"><xliff:g id="task_description" example="GMail">%1$s</xliff:g>, <xliff:g id="remaining_time" example="7 minutes left today">%2$s</xliff:g></string>
@@ -56,6 +53,8 @@
<!-- Accessibility title for the row of all-apps containing app predictions. [CHAR LIMIT=50] -->
<string name="title_app_suggestions">App suggestions</string>
+ <!-- Label for the header text of the All Apps section in All Apps view, used to separate Predicted Apps and Actions section from All Apps section. [CHAR_LIMIT=50] -->
+ <string name="all_apps_label">All apps</string>
<!-- Text of the tip when user lands in all apps view for the first time, indicating where the tip toast points to is the predicted apps section. [CHAR_LIMIT=50] -->
<string name="all_apps_prediction_tip">Your predicted apps</string>
@@ -109,8 +108,6 @@
<string name="back_gesture_intro_title">Swipe to go back</string>
<!-- Introduction subtitle for the Back gesture tutorial. [CHAR LIMIT=200] -->
<string name="back_gesture_intro_subtitle">To go back to the last screen, swipe from the left or right edge to the middle of the screen.</string>
- <!-- Introduction subtitle for the Back gesture tutorial that will be spoken by screen readers. [CHAR LIMIT=200] -->
- <string name="back_gesture_spoken_intro_subtitle">To go back to the last screen, swipe with 2 fingers from the left or right edge to the middle of the screen.</string>
<string name="home_gesture_feedback_swipe_too_far_from_edge">Make sure you swipe up from the bottom edge of the screen.</string>
<!-- Feedback shown during interactive parts of Home gesture tutorial when the Overview gesture is detected. [CHAR LIMIT=100] -->
@@ -125,8 +122,6 @@
<string name="home_gesture_intro_title">Swipe to go home</string>
<!-- Introduction subtitle for the Home gesture tutorial. [CHAR LIMIT=100] -->
<string name="home_gesture_intro_subtitle">Swipe up from the bottom of your screen. This gesture always takes you to the Home screen.</string>
- <!-- Introduction subtitle for the Home gesture tutorial that will be spoken by screen readers. [CHAR LIMIT=100] -->
- <string name="home_gesture_spoken_intro_subtitle">Swipe up with 2 fingers from the bottom of the screen. This gesture always takes you to the Home screen.</string>
<!-- Feedback shown during interactive parts of Overview gesture tutorial when the gesture is started too far from the edge. [CHAR LIMIT=100] -->
<string name="overview_gesture_feedback_swipe_too_far_from_edge">Make sure you swipe up from the bottom edge of the screen.</string>
@@ -142,8 +137,6 @@
<string name="overview_gesture_intro_title">Swipe to switch apps</string>
<!-- Introduction subtitle for the Overview gesture tutorial. [CHAR LIMIT=100] -->
<string name="overview_gesture_intro_subtitle">To switch between apps, swipe up from the bottom of your screen, hold, then release.</string>
- <!-- Introduction subtitle for the Overview gesture tutorial that will be spoken by screen readers. [CHAR LIMIT=100] -->
- <string name="overview_gesture_spoken_intro_subtitle">To switch between apps, swipe up with 2 fingers from the bottom of your screen, hold, then release.</string>
<!-- Title shown during interactive part of Assistant gesture tutorial. [CHAR LIMIT=30] -->
<string name="assistant_gesture_tutorial_playground_title" translatable="false">Tutorial: Assistant</string>
@@ -188,10 +181,8 @@
<string name="allset_title">All set!</string>
<!-- Hint string at the bottom of "All Set" page [CHAR LIMIT=NONE] -->
<string name="allset_hint">Swipe up to go Home</string>
- <!-- Description of "All Set" page on phones [CHAR LIMIT=NONE] -->
+ <!-- Description of "All Set" page [CHAR LIMIT=NONE] -->
<string name="allset_description">You\u2019re ready to start using your phone</string>
- <!-- Description of "All Set" page on tablets [CHAR LIMIT=NONE] -->
- <string name="allset_description_tablet">You\u2019re ready to start using your tablet</string>
<!-- String linking to navigation settings on "All Set" page [CHAR LIMIT=NONE] -->
<string name="allset_navigation_settings"><annotation id="link">System navigation settings</annotation></string>
@@ -200,12 +191,6 @@
<string name="action_share">Share</string>
<!-- Label for a button that causes a screen shot of the current app to be taken. [CHAR_LIMIT=40] -->
<string name="action_screenshot">Screenshot</string>
- <!-- Label for a button that enters split screen selection mode. [CHAR_LIMIT=20] -->
- <string name="action_split">Split</string>
- <!-- Label for toast with instructions for split screen selection mode. [CHAR_LIMIT=50] -->
- <string name="toast_split_select_app">Tap another app to use splitscreen</string>
- <!-- Label for toast when app selected for split isn't supported. [CHAR_LIMIT=50] -->
- <string name="toast_split_app_unsupported">App does not support split-screen.</string>
<!-- Message shown when an action is blocked by a policy enforced by the app or the organization managing the device. [CHAR_LIMIT=NONE] -->
<string name="blocked_by_policy">This action isn\'t allowed by the app or your organization</string>
@@ -218,49 +203,4 @@
<string name="gesture_tutorial_action_button_label_cancel">Cancel</string>
<!-- Button text shown on a button on the tutorial skip dialog to exit the tutorial. [CHAR LIMIT=14] -->
<string name="gesture_tutorial_action_button_label_skip">Skip</string>
-
- <!-- Accessibility label for the rotation suggestion button -->
- <string name="accessibility_rotate_button">Rotate screen</string>
-
- <!-- ******* Taskbar Edu ******* -->
- <!-- Accessibility text spoken when the taskbar education panel appears [CHAR_LIMIT=NONE] -->
- <string name="taskbar_edu_opened">Taskbar education appeared</string>
- <!-- Accessibility text spoken when the taskbar education panel disappears [CHAR_LIMIT=NONE] -->
- <string name="taskbar_edu_closed">Taskbar education closed</string>
- <!-- Text in dialog that lets a user know how they can use the taskbar to switch apps on their device.
- [CHAR_LIMIT=60] -->
- <string name="taskbar_edu_switch_apps">Use the taskbar to switch apps</string>
- <!-- Text in dialog that lets a user know how they can use the taskbar to use multiple apps at once on their device.
- [CHAR_LIMIT=60] -->
- <string name="taskbar_edu_splitscreen">Drag to the side to use two apps at once</string>
- <!-- Text in dialog that lets a user know how they can hide the taskbar on their device.
- [CHAR_LIMIT=60] -->
- <string name="taskbar_edu_stashing">Touch &amp; hold to hide the taskbar</string>
- <!-- Text on button to go to the next screen of a tutorial [CHAR_LIMIT=16] -->
- <string name="taskbar_edu_next">Next</string>
- <!-- Text on button to go to the previous screen of a tutorial [CHAR_LIMIT=16] -->
- <string name="taskbar_edu_previous">Back</string>
- <!-- Text on button to exit a tutorial [CHAR_LIMIT=16] -->
- <string name="taskbar_edu_close">Close</string>
- <!-- Text on button to finish a tutorial [CHAR_LIMIT=16] -->
- <string name="taskbar_edu_done">Done</string>
- <!-- Content description for home button [CHAR_LIMIT=16] -->
- <string name="taskbar_button_home">Home</string>
- <!-- Content description for accessibility button [CHAR_LIMIT=16] -->
- <string name="taskbar_button_a11y">Accessibility</string>
- <!-- Content description for back button [CHAR_LIMIT=16] -->
- <string name="taskbar_button_back">Back</string>
- <!-- Content description for ime switcher button [CHAR_LIMIT=16] -->
- <string name="taskbar_button_ime_switcher">IME switcher</string>
- <!-- Content description for recents button [CHAR_LIMIT=16] -->
- <string name="taskbar_button_recents">Recents</string>
- <!-- Content description for notifications button [CHAR_LIMIT=16] -->
- <string name="taskbar_button_notifications">Notifications</string>
- <!-- Content description for quick settings button [CHAR_LIMIT=16] -->
- <string name="taskbar_button_quick_settings">Quick Settings</string>
-
- <!-- Label for moving drop target to the top or left side of the screen, depending on orientation (from the taskbar only). -->
- <string name="move_drop_target_top_or_left">Move to top&#47;left</string>
- <!-- Label for moving drop target to the bottom or right side of the screen, depending on orientation (from the taskbar only). -->
- <string name="move_drop_target_bottom_or_right">Move to bottom&#47;right</string>
</resources>
diff --git a/quickstep/res/values/styles.xml b/quickstep/res/values/styles.xml
index 7225220876..07c448df9e 100644
--- a/quickstep/res/values/styles.xml
+++ b/quickstep/res/values/styles.xml
@@ -47,12 +47,6 @@
<item name="android:lineHeight">44sp</item>
</style>
- <style name="TextAppearance.GestureTutorial.Feedback.Title.AllSet"
- parent="TextAppearance.GestureTutorial.Feedback.Title">
- <item name="android:letterSpacing">0.03</item>
- <item name="android:lineHeight">44sp</item>
- </style>
-
<style name="TextAppearance.GestureTutorial.Dialog.Title"
parent="TextAppearance.GestureTutorial.Feedback.Title">
<item name="android:gravity">center_horizontal</item>
@@ -67,12 +61,6 @@
<item name="android:textColor">?android:attr/textColorPrimary</item>
<item name="android:fontFamily">google-sans-text</item>
<item name="android:letterSpacing">0.03</item>
- <item name="android:textSize">14sp</item>
- <item name="android:lineHeight">20sp</item>
- </style>
-
- <style name="TextAppearance.GestureTutorial.Feedback.Subtitle.AllSet"
- parent="TextAppearance.GestureTutorial.Feedback.Subtitle">
<item name="android:textSize">18sp</item>
<item name="android:lineHeight">24sp</item>
</style>
@@ -89,8 +77,8 @@
<style name="TextAppearance.GestureTutorial.Feedback.Subtext"
parent="TextAppearance.GestureTutorial.Feedback.Subtitle">
<item name="android:textSize">16sp</item>
- <item name="android:textColor">?android:attr/colorAccent</item>
- <item name="android:gravity">start</item>
+ <item name="android:textColor">@color/gesture_tutorial_primary_color</item>
+ <item name="android:gravity">center</item>
</style>
<style name="TextAppearance.GestureTutorial.Feedback.Subtext.Dark"
@@ -101,7 +89,7 @@
<style name="TextAppearance.GestureTutorial.ButtonLabel"
parent="TextAppearance.GestureTutorial.CallToAction">
<item name="android:gravity">center</item>
- <item name="android:textColor">?android:attr/textColorPrimaryInverse</item>
+ <item name="android:textColor">@color/gesture_tutorial_action_button_label_color</item>
<item name="android:letterSpacing">0.02</item>
<item name="android:textSize">16sp</item>
<item name="android:textAllCaps">false</item>
@@ -109,12 +97,12 @@
<style name="TextAppearance.GestureTutorial.CancelButtonLabel"
parent="TextAppearance.GestureTutorial.ButtonLabel">
- <item name="android:textColor">?android:attr/colorAccent</item>
+ <item name="android:textColor">?android:attr/textColorPrimary</item>
</style>
<style name="TextAppearance.GestureTutorial.TextButtonLabel"
parent="TextAppearance.GestureTutorial.ButtonLabel">
- <item name="android:textColor">?android:attr/colorAccent</item>
+ <item name="android:textColor">@color/gesture_tutorial_primary_color</item>
</style>
<style name="TextAppearance.GestureTutorial.LinkText"
@@ -127,7 +115,7 @@
<item name="android:statusBarColor">@android:color/transparent</item>
<item name="android:enforceNavigationBarContrast">false</item>
<item name="android:windowLightStatusBar">true</item>
- <item name="android:windowBackground">@android:color/transparent</item>
+ <item name="android:windowBackground">#FFFFFFFF</item>
</style>
<!--
@@ -147,39 +135,8 @@
<item name="android:textAllCaps">false</item>
</style>
- <style name="OverviewClearAllButton" parent="@android:style/Widget.DeviceDefault.Button">
- <item name="android:background">@drawable/bg_overview_clear_all_button</item>
- <item name="android:minWidth">96dp</item>
- <item name="android:minHeight">48dp</item>
- <item name="android:stateListAnimator">@null</item>
- </style>
-
<!-- Icon displayed on the taskbar -->
<style name="BaseIcon.Workspace.Taskbar" >
<item name="iconDisplay">taskbar</item>
</style>
-
- <style name="TaskbarEdu.Button.Close" parent="@android:style/Widget.Material.Button">
- <item name="android:background">@drawable/button_taskbar_edu_bordered</item>
- <item name="android:stateListAnimator">@null</item>
- <item name="android:textSize">16sp</item>
- <item name="android:padding">4dp</item>
- </style>
-
- <style name="TaskbarEdu.Button.Next" parent="@android:style/Widget.Material.Button">
- <item name="android:background">@drawable/button_taskbar_edu_colored</item>
- <item name="android:stateListAnimator">@null</item>
- <item name="android:textSize">16sp</item>
- <item name="android:padding">4dp</item>
- </style>
-
- <style name="TextAppearance.TaskbarEdu.Title"
- parent="@android:style/TextAppearance.DeviceDefault.DialogWindowTitle" >
- <item name="android:layout_marginHorizontal">16dp</item>
- <item name="android:gravity">center_horizontal</item>
- <item name="android:fontFamily">google-sans</item>
- <item name="android:textColor">?android:attr/textColorPrimary</item>
- <item name="android:textSize">24sp</item>
- <item name="android:lines">2</item>
- </style>
</resources> \ No newline at end of file
diff --git a/quickstep/tests/src/com/android/launcher3/model/WidgetsPredicationUpdateTaskTest.java b/quickstep/robolectric_tests/src/com/android/launcher3/model/WidgetsPredicationUpdateTaskTest.java
index c1b3beb475..7c97b93b03 100644
--- a/quickstep/tests/src/com/android/launcher3/model/WidgetsPredicationUpdateTaskTest.java
+++ b/quickstep/robolectric_tests/src/com/android/launcher3/model/WidgetsPredicationUpdateTaskTest.java
@@ -15,125 +15,135 @@
*/
package com.android.launcher3.model;
-import static android.os.Process.myUserHandle;
-
import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_WIDGETS_PREDICTION;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
-import static com.android.launcher3.util.WidgetUtils.createAppWidgetProviderInfo;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.doReturn;
+import static org.robolectric.Shadows.shadowOf;
import android.app.prediction.AppTarget;
import android.app.prediction.AppTargetId;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProviderInfo;
import android.content.ComponentName;
+import android.content.Context;
+import android.os.Process;
import android.os.UserHandle;
-import android.text.TextUtils;
-import android.util.Log;
-
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
+import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.icons.ComponentWithLabel;
import com.android.launcher3.icons.IconCache;
import com.android.launcher3.model.BgDataModel.FixedContainerItems;
import com.android.launcher3.model.QuickstepModelDelegate.PredictorState;
+import com.android.launcher3.model.data.AppInfo;
+import com.android.launcher3.model.data.ItemInfo;
+import com.android.launcher3.model.data.LauncherAppWidgetInfo;
+import com.android.launcher3.model.data.WorkspaceItemInfo;
+import com.android.launcher3.shadows.ShadowDeviceFlag;
+import com.android.launcher3.util.ComponentKey;
+import com.android.launcher3.util.IntArray;
+import com.android.launcher3.util.ItemInfoMatcher;
import com.android.launcher3.util.LauncherModelHelper;
+import com.android.launcher3.util.ViewOnDrawExecutor;
import com.android.launcher3.widget.LauncherAppWidgetProviderInfo;
import com.android.launcher3.widget.PendingAddWidgetInfo;
+import com.android.launcher3.widget.model.WidgetsListBaseEntry;
-import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.shadow.api.Shadow;
+import org.robolectric.shadows.ShadowAppWidgetManager;
+import org.robolectric.shadows.ShadowPackageManager;
+import org.robolectric.util.ReflectionHelpers;
-import java.util.Arrays;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
import java.util.stream.Collectors;
-@SmallTest
-@RunWith(AndroidJUnit4.class)
+@RunWith(RobolectricTestRunner.class)
public final class WidgetsPredicationUpdateTaskTest {
- private AppWidgetProviderInfo mApp1Provider1;
- private AppWidgetProviderInfo mApp1Provider2;
- private AppWidgetProviderInfo mApp2Provider1;
- private AppWidgetProviderInfo mApp4Provider1;
- private AppWidgetProviderInfo mApp4Provider2;
- private AppWidgetProviderInfo mApp5Provider1;
- private List<AppWidgetProviderInfo> allWidgets;
+ private AppWidgetProviderInfo mApp1Provider1 = new AppWidgetProviderInfo();
+ private AppWidgetProviderInfo mApp1Provider2 = new AppWidgetProviderInfo();
+ private AppWidgetProviderInfo mApp2Provider1 = new AppWidgetProviderInfo();
+ private AppWidgetProviderInfo mApp4Provider1 = new AppWidgetProviderInfo();
+ private AppWidgetProviderInfo mApp4Provider2 = new AppWidgetProviderInfo();
+ private AppWidgetProviderInfo mApp5Provider1 = new AppWidgetProviderInfo();
private FakeBgDataModelCallback mCallback = new FakeBgDataModelCallback();
+ private Context mContext;
private LauncherModelHelper mModelHelper;
private UserHandle mUserHandle;
+ private InvariantDeviceProfile mTestProfile;
@Mock
private IconCache mIconCache;
@Before
public void setup() throws Exception {
- mModelHelper = new LauncherModelHelper();
MockitoAnnotations.initMocks(this);
doAnswer(invocation -> {
ComponentWithLabel componentWithLabel = invocation.getArgument(0);
return componentWithLabel.getComponent().getShortClassName();
}).when(mIconCache).getTitleNoCache(any());
- mUserHandle = myUserHandle();
- mApp1Provider1 = createAppWidgetProviderInfo(
- ComponentName.createRelative("app1", "provider1"));
- mApp1Provider2 = createAppWidgetProviderInfo(
- ComponentName.createRelative("app1", "provider2"));
- mApp2Provider1 = createAppWidgetProviderInfo(
- ComponentName.createRelative("app2", "provider1"));
- mApp4Provider1 = createAppWidgetProviderInfo(
- ComponentName.createRelative("app4", "provider1"));
- mApp4Provider2 = createAppWidgetProviderInfo(
- ComponentName.createRelative("app4", ".provider2"));
- mApp5Provider1 = createAppWidgetProviderInfo(
- ComponentName.createRelative("app5", "provider1"));
- allWidgets = Arrays.asList(mApp1Provider1, mApp1Provider2, mApp2Provider1,
- mApp4Provider1, mApp4Provider2, mApp5Provider1);
-
- AppWidgetManager manager = mModelHelper.sandboxContext.spyService(AppWidgetManager.class);
- doReturn(allWidgets).when(manager).getInstalledProviders();
- doReturn(allWidgets).when(manager).getInstalledProvidersForProfile(eq(myUserHandle()));
- doAnswer(i -> {
- String pkg = i.getArgument(0);
- Log.e("Hello", "Getting v " + pkg);
- return TextUtils.isEmpty(pkg) ? allWidgets : allWidgets.stream()
- .filter(a -> pkg.equals(a.provider.getPackageName()))
- .collect(Collectors.toList());
- }).when(manager).getInstalledProvidersForPackage(any(), eq(myUserHandle()));
-
+ mContext = RuntimeEnvironment.application;
+ mModelHelper = new LauncherModelHelper();
+ mUserHandle = Process.myUserHandle();
+ mTestProfile = new InvariantDeviceProfile();
// 2 widgets, app4/provider1 & app5/provider1, have already been added to the workspace.
- mModelHelper.initializeData("widgets_predication_update_task_data");
+ mModelHelper.initializeData("/widgets_predication_update_task_data.txt");
- MAIN_EXECUTOR.submit(() -> mModelHelper.getModel().addCallbacks(mCallback)).get();
- MODEL_EXECUTOR.post(() -> mModelHelper.getBgDataModel().widgetsModel.update(
- LauncherAppState.getInstance(mModelHelper.sandboxContext),
- /* packageUser= */ null));
+ ShadowPackageManager packageManager = shadowOf(mContext.getPackageManager());
+ mApp1Provider1.provider = ComponentName.createRelative("app1", "provider1");
+ ReflectionHelpers.setField(mApp1Provider1, "providerInfo",
+ packageManager.addReceiverIfNotPresent(mApp1Provider1.provider));
+ mApp1Provider2.provider = ComponentName.createRelative("app1", "provider2");
+ ReflectionHelpers.setField(mApp1Provider2, "providerInfo",
+ packageManager.addReceiverIfNotPresent(mApp1Provider2.provider));
+ mApp2Provider1.provider = ComponentName.createRelative("app2", "provider1");
+ ReflectionHelpers.setField(mApp2Provider1, "providerInfo",
+ packageManager.addReceiverIfNotPresent(mApp2Provider1.provider));
+ mApp4Provider1.provider = ComponentName.createRelative("app4", "provider1");
+ ReflectionHelpers.setField(mApp4Provider1, "providerInfo",
+ packageManager.addReceiverIfNotPresent(mApp4Provider1.provider));
+ mApp4Provider2.provider = ComponentName.createRelative("app4", ".provider2");
+ ReflectionHelpers.setField(mApp4Provider2, "providerInfo",
+ packageManager.addReceiverIfNotPresent(mApp4Provider2.provider));
+ mApp5Provider1.provider = ComponentName.createRelative("app5", "provider1");
+ ReflectionHelpers.setField(mApp5Provider1, "providerInfo",
+ packageManager.addReceiverIfNotPresent(mApp5Provider1.provider));
- MODEL_EXECUTOR.submit(() -> { }).get();
- MAIN_EXECUTOR.submit(() -> { }).get();
- }
+ ShadowAppWidgetManager shadowAppWidgetManager =
+ shadowOf(mContext.getSystemService(AppWidgetManager.class));
+ shadowAppWidgetManager.addInstalledProvider(mApp1Provider1);
+ shadowAppWidgetManager.addInstalledProvider(mApp1Provider2);
+ shadowAppWidgetManager.addInstalledProvider(mApp2Provider1);
+ shadowAppWidgetManager.addInstalledProvider(mApp4Provider1);
+ shadowAppWidgetManager.addInstalledProvider(mApp4Provider2);
+ shadowAppWidgetManager.addInstalledProvider(mApp5Provider1);
- @After
- public void tearDown() {
- mModelHelper.destroy();
+ mModelHelper.getModel().addCallbacks(mCallback);
+
+ MODEL_EXECUTOR.post(() -> mModelHelper.getBgDataModel().widgetsModel.update(
+ LauncherAppState.getInstance(mContext), /* packageUser= */ null));
+ waitUntilIdle();
}
+
@Test
public void widgetsRecommendationRan_shouldOnlyReturnNotAddedWidgetsInAppPredictionOrder()
throws Exception {
@@ -170,9 +180,9 @@ public final class WidgetsPredicationUpdateTaskTest {
@Test
public void widgetsRecommendationRan_localFilterDisabled_shouldReturnWidgetsInPredicationOrder()
throws Exception {
- if (FeatureFlags.ENABLE_LOCAL_RECOMMENDED_WIDGETS_FILTER.get()) {
- return;
- }
+ ShadowDeviceFlag shadowDeviceFlag = Shadow.extract(
+ FeatureFlags.ENABLE_LOCAL_RECOMMENDED_WIDGETS_FILTER);
+ shadowDeviceFlag.setValue(false);
// WHEN newPredicationTask is executed with 5 predicated widgets.
AppTarget widget1 = new AppTarget(new AppTargetId("app1"), "app1", "provider1",
@@ -208,8 +218,13 @@ public final class WidgetsPredicationUpdateTaskTest {
assertThat(actual.getUser()).isEqualTo(expected.getProfile());
}
+ private void waitUntilIdle() {
+ shadowOf(MODEL_EXECUTOR.getLooper()).idle();
+ shadowOf(MAIN_EXECUTOR.getLooper()).idle();
+ }
+
private WidgetsPredictionUpdateTask newWidgetsPredicationTask(List<AppTarget> appTargets) {
- return new WidgetsPredictionUpdateTask(
+ return new WidgetsPredictionUpdateTask(
new PredictorState(CONTAINER_WIDGETS_PREDICTION, "test_widgets_prediction"),
appTargets);
}
@@ -222,5 +237,65 @@ public final class WidgetsPredicationUpdateTaskTest {
public void bindExtraContainerItems(FixedContainerItems item) {
mRecommendedWidgets = item;
}
+
+ @Override
+ public int getPageToBindSynchronously() {
+ return 0;
+ }
+
+ @Override
+ public void clearPendingBinds() { }
+
+ @Override
+ public void startBinding() { }
+
+ @Override
+ public void bindItems(List<ItemInfo> shortcuts, boolean forceAnimateIcons) { }
+
+ @Override
+ public void bindScreens(IntArray orderedScreenIds) { }
+
+ @Override
+ public void finishFirstPageBind(ViewOnDrawExecutor executor) { }
+
+ @Override
+ public void finishBindingItems(int pageBoundFirst) { }
+
+ @Override
+ public void preAddApps() { }
+
+ @Override
+ public void bindAppsAdded(IntArray newScreens, ArrayList<ItemInfo> addNotAnimated,
+ ArrayList<ItemInfo> addAnimated) { }
+
+ @Override
+ public void bindIncrementalDownloadProgressUpdated(AppInfo app) { }
+
+ @Override
+ public void bindWorkspaceItemsChanged(List<WorkspaceItemInfo> updated) { }
+
+ @Override
+ public void bindWidgetsRestored(ArrayList<LauncherAppWidgetInfo> widgets) { }
+
+ @Override
+ public void bindRestoreItemsChange(HashSet<ItemInfo> updates) { }
+
+ @Override
+ public void bindWorkspaceComponentsRemoved(ItemInfoMatcher matcher) { }
+
+ @Override
+ public void bindAllWidgets(List<WidgetsListBaseEntry> widgets) { }
+
+ @Override
+ public void onPageBoundSynchronously(int page) { }
+
+ @Override
+ public void executeOnNextDraw(ViewOnDrawExecutor executor) { }
+
+ @Override
+ public void bindDeepShortcutMap(HashMap<ComponentKey, Integer> deepShortcutMap) { }
+
+ @Override
+ public void bindAllApplications(AppInfo[] apps, int flags) { }
}
}
diff --git a/quickstep/tests/src/com/android/quickstep/OrientationTouchTransformerTest.java b/quickstep/robolectric_tests/src/com/android/quickstep/OrientationTouchTransformerTest.java
index 9e5d9585af..2b1b57c450 100644
--- a/quickstep/tests/src/com/android/quickstep/OrientationTouchTransformerTest.java
+++ b/quickstep/robolectric_tests/src/com/android/quickstep/OrientationTouchTransformerTest.java
@@ -17,49 +17,53 @@
package com.android.quickstep;
-import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
+import static android.view.Display.DEFAULT_DISPLAY;
-import static com.android.launcher3.util.DisplayController.NavigationMode.NO_BUTTON;
+import static com.android.quickstep.SysUINavigationMode.Mode.NO_BUTTON;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
+import android.content.Context;
import android.content.res.Resources;
import android.graphics.Point;
-import android.graphics.Rect;
-import android.util.ArrayMap;
+import android.hardware.display.DisplayManager;
import android.util.DisplayMetrics;
-import android.util.Size;
import android.view.Display;
import android.view.MotionEvent;
import android.view.Surface;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
-
import com.android.launcher3.ResourceUtils;
import com.android.launcher3.util.DisplayController;
-import com.android.launcher3.util.RotationUtils;
-import com.android.launcher3.util.WindowBounds;
-import com.android.launcher3.util.window.CachedDisplayInfo;
-import com.android.launcher3.util.window.WindowManagerProxy;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
-@SmallTest
-@RunWith(AndroidJUnit4.class)
+@RunWith(RobolectricTestRunner.class)
public class OrientationTouchTransformerTest {
+ static class ScreenSize {
+ int mHeight;
+ int mWidth;
- private static final Size NORMAL_SCREEN_SIZE = new Size(1080, 2280);
- private static final Size LARGE_SCREEN_SIZE = new Size(1080, 3280);
+ ScreenSize(int height, int width) {
+ mHeight = height;
+ mWidth = width;
+ }
+ }
+
+ private static final ScreenSize NORMAL_SCREEN_SIZE = new ScreenSize(2280, 1080);
+ private static final ScreenSize LARGE_SCREEN_SIZE = new ScreenSize(3280, 1080);
private static final float DENSITY_DISPLAY_METRICS = 3.0f;
private OrientationTouchTransformer mTouchTransformer;
@@ -67,6 +71,7 @@ public class OrientationTouchTransformerTest {
Resources mResources;
private DisplayController.Info mInfo;
+
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
@@ -287,24 +292,33 @@ public class OrientationTouchTransformerTest {
assertTrue(mTouchTransformer.touchInValidSwipeRegions(inRegion2.getX(), inRegion2.getY()));
}
- private DisplayController.Info createDisplayInfo(Size screenSize, int rotation) {
- Point displaySize = new Point(screenSize.getWidth(), screenSize.getHeight());
- RotationUtils.rotateSize(displaySize, rotation);
- CachedDisplayInfo cdi = new CachedDisplayInfo(displaySize, rotation);
- WindowBounds wm = new WindowBounds(
- new Rect(0, 0, displaySize.x, displaySize.y),
- new Rect());
- WindowManagerProxy wmProxy = mock(WindowManagerProxy.class);
- doReturn(cdi).when(wmProxy).getDisplayInfo(any(), any());
- doReturn(wm).when(wmProxy).getRealBounds(any(), any(), any());
- return new DisplayController.Info(
- getApplicationContext(), mock(Display.class), wmProxy, new ArrayMap<>());
+ private DisplayController.Info createDisplayInfo(ScreenSize screenSize, int rotation) {
+ Context context = RuntimeEnvironment.application;
+ Display display = spy(context.getSystemService(DisplayManager.class)
+ .getDisplay(DEFAULT_DISPLAY));
+
+ Point p = new Point(screenSize.mWidth, screenSize.mHeight);
+ if (rotation == Surface.ROTATION_90 || rotation == Surface.ROTATION_270) {
+ p.set(screenSize.mHeight, screenSize.mWidth);
+ }
+
+ doReturn(rotation).when(display).getRotation();
+ doAnswer(i -> {
+ ((Point) i.getArgument(0)).set(p.x, p.y);
+ return null;
+ }).when(display).getRealSize(any(Point.class));
+ doAnswer(i -> {
+ ((Point) i.getArgument(0)).set(p.x, p.y);
+ ((Point) i.getArgument(1)).set(p.x, p.y);
+ return null;
+ }).when(display).getCurrentSizeRange(any(Point.class), any(Point.class));
+ return new DisplayController.Info(context, display);
}
- private float generateTouchRegionHeight(Size screenSize, int rotation) {
- float height = screenSize.getHeight();
+ private float generateTouchRegionHeight(ScreenSize screenSize, int rotation) {
+ float height = screenSize.mHeight;
if (rotation == Surface.ROTATION_90 || rotation == Surface.ROTATION_270) {
- height = screenSize.getWidth();
+ height = screenSize.mWidth;
}
return height - ResourceUtils.DEFAULT_NAVBAR_VALUE * DENSITY_DISPLAY_METRICS;
}
diff --git a/quickstep/robolectric_tests/src/com/android/quickstep/RecentsActivityTest.java b/quickstep/robolectric_tests/src/com/android/quickstep/RecentsActivityTest.java
new file mode 100644
index 0000000000..9df9ab1682
--- /dev/null
+++ b/quickstep/robolectric_tests/src/com/android/quickstep/RecentsActivityTest.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2020 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.quickstep;
+
+import static com.android.launcher3.util.LauncherUIHelper.doLayout;
+
+import android.app.ActivityManager.RunningTaskInfo;
+import android.graphics.Bitmap;
+import android.graphics.Bitmap.Config;
+
+import com.android.quickstep.fallback.FallbackRecentsView;
+import com.android.systemui.shared.recents.model.ThumbnailData;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.Robolectric;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.android.controller.ActivityController;
+import org.robolectric.annotation.LooperMode;
+import org.robolectric.annotation.LooperMode.Mode;
+import org.robolectric.shadows.ShadowLooper;
+import org.robolectric.util.ReflectionHelpers;
+
+
+@RunWith(RobolectricTestRunner.class)
+@LooperMode(Mode.PAUSED)
+@org.junit.Ignore
+public class RecentsActivityTest {
+
+ @Test
+ public void testRecentsActivityCreates() {
+ ActivityController<RecentsActivity> controller =
+ Robolectric.buildActivity(RecentsActivity.class);
+
+ RecentsActivity launcher = controller.setup().get();
+ doLayout(launcher);
+
+ // TODO: Ensure that LauncherAppState is not created
+ }
+
+ @Test
+ public void testRecents_showCurrentTask() {
+ ActivityController<RecentsActivity> controller =
+ Robolectric.buildActivity(RecentsActivity.class);
+
+ RecentsActivity activity = controller.setup().get();
+ doLayout(activity);
+
+ FallbackRecentsView frv = activity.getOverviewPanel();
+
+ RunningTaskInfo placeholderTask = new RunningTaskInfo();
+ placeholderTask.taskId = 22;
+ frv.showCurrentTask(placeholderTask);
+ doLayout(activity);
+
+ ThumbnailData thumbnailData = new ThumbnailData();
+ ReflectionHelpers.setField(thumbnailData, "thumbnail",
+ Bitmap.createBitmap(300, 500, Config.ARGB_8888));
+ frv.switchToScreenshot(thumbnailData, () -> { });
+ ShadowLooper.idleMainLooper();
+ }
+}
diff --git a/quickstep/tests/src/com/android/quickstep/util/RecentsOrientedStateTest.java b/quickstep/robolectric_tests/src/com/android/quickstep/util/RecentsOrientedStateTest.java
index 47ef13b42f..656379f10f 100644
--- a/quickstep/tests/src/com/android/quickstep/util/RecentsOrientedStateTest.java
+++ b/quickstep/robolectric_tests/src/com/android/quickstep/util/RecentsOrientedStateTest.java
@@ -19,34 +19,33 @@ import static android.view.Surface.ROTATION_0;
import static android.view.Surface.ROTATION_180;
import static android.view.Surface.ROTATION_90;
-import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
-
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import android.content.Context;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
-
import com.android.quickstep.FallbackActivityInterface;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.LooperMode;
+import org.robolectric.annotation.LooperMode.Mode;
/**
* Tests for {@link RecentsOrientedState}
*/
-@SmallTest
-@RunWith(AndroidJUnit4.class)
+@RunWith(RobolectricTestRunner.class)
+@LooperMode(Mode.PAUSED)
public class RecentsOrientedStateTest {
private RecentsOrientedState mR1, mR2;
@Before
public void setup() {
- Context context = getApplicationContext();
+ Context context = RuntimeEnvironment.application;
mR1 = new RecentsOrientedState(context, FallbackActivityInterface.INSTANCE, i -> { });
mR2 = new RecentsOrientedState(context, FallbackActivityInterface.INSTANCE, i -> { });
assertEquals(mR1.getStateId(), mR2.getStateId());
diff --git a/quickstep/tests/src/com/android/quickstep/util/TaskViewSimulatorTest.java b/quickstep/robolectric_tests/src/com/android/quickstep/util/TaskViewSimulatorTest.java
index 7d414f4910..fd93d98bed 100644
--- a/quickstep/tests/src/com/android/quickstep/util/TaskViewSimulatorTest.java
+++ b/quickstep/robolectric_tests/src/com/android/quickstep/util/TaskViewSimulatorTest.java
@@ -15,34 +15,22 @@
*/
package com.android.quickstep.util;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.doReturn;
+import static android.view.Display.DEFAULT_DISPLAY;
+
import static org.mockito.Mockito.mock;
-import android.graphics.Point;
+import android.content.Context;
import android.graphics.Rect;
import android.graphics.RectF;
-import android.util.ArrayMap;
-import android.util.Pair;
-import android.view.Display;
+import android.hardware.display.DisplayManager;
import android.view.Surface;
import android.view.SurfaceControl;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
-
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.InvariantDeviceProfile;
+import com.android.launcher3.shadows.LShadowDisplay;
import com.android.launcher3.util.DisplayController;
-import com.android.launcher3.util.DisplayController.Info;
-import com.android.launcher3.util.LauncherModelHelper;
-import com.android.launcher3.util.ReflectionHelpers;
-import com.android.launcher3.util.RotationUtils;
-import com.android.launcher3.util.WindowBounds;
-import com.android.launcher3.util.window.CachedDisplayInfo;
-import com.android.launcher3.util.window.WindowManagerProxy;
-import com.android.quickstep.FallbackActivityInterface;
-import com.android.quickstep.SystemUiProxy;
+import com.android.quickstep.LauncherActivityInterface;
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat.SurfaceParams;
@@ -51,9 +39,15 @@ import org.hamcrest.TypeSafeMatcher;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
-
-@SmallTest
-@RunWith(AndroidJUnit4.class)
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.LooperMode;
+import org.robolectric.annotation.LooperMode.Mode;
+import org.robolectric.shadow.api.Shadow;
+import org.robolectric.shadows.ShadowDisplayManager;
+
+@RunWith(RobolectricTestRunner.class)
+@LooperMode(Mode.PAUSED)
public class TaskViewSimulatorTest {
@Test
@@ -110,8 +104,8 @@ public class TaskViewSimulatorTest {
private static class TaskMatrixVerifier extends TransformParams {
- private Point mDisplaySize = new Point();
- private Rect mDisplayInsets = new Rect();
+ private final Context mContext = RuntimeEnvironment.application;
+
private Rect mAppBounds = new Rect();
private Rect mLauncherInsets = new Rect();
@@ -121,7 +115,8 @@ public class TaskViewSimulatorTest {
private DeviceProfile mDeviceProfile;
TaskMatrixVerifier withLauncherSize(int width, int height) {
- mDisplaySize.set(width, height);
+ ShadowDisplayManager.changeDisplay(DEFAULT_DISPLAY,
+ String.format("w%sdp-h%sdp-mdpi", width, height));
if (mAppBounds.isEmpty()) {
mAppBounds.set(0, 0, width, height);
}
@@ -129,7 +124,9 @@ public class TaskViewSimulatorTest {
}
TaskMatrixVerifier withInsets(Rect insets) {
- mDisplayInsets.set(insets);
+ LShadowDisplay shadowDisplay = Shadow.extract(
+ mContext.getSystemService(DisplayManager.class).getDisplay(DEFAULT_DISPLAY));
+ shadowDisplay.setInsets(insets);
mLauncherInsets.set(insets);
return this;
}
@@ -142,68 +139,27 @@ public class TaskViewSimulatorTest {
}
void verifyNoTransforms() {
- LauncherModelHelper helper = new LauncherModelHelper();
- try {
- helper.sandboxContext.allow(SystemUiProxy.INSTANCE);
- int rotation = mDisplaySize.x > mDisplaySize.y
- ? Surface.ROTATION_90 : Surface.ROTATION_0;
- CachedDisplayInfo cdi =
- new CachedDisplayInfo("test-display", mDisplaySize, rotation , new Rect());
- WindowBounds wm = new WindowBounds(
- new Rect(0, 0, mDisplaySize.x, mDisplaySize.y),
- mDisplayInsets);
- WindowBounds[] allBounds = new WindowBounds[4];
- for (int i = 0; i < 4; i++) {
- Rect boundsR = new Rect(wm.bounds);
- Rect insetsR = new Rect(wm.insets);
-
- RotationUtils.rotateRect(insetsR, RotationUtils.deltaRotation(rotation, i));
- RotationUtils.rotateRect(boundsR, RotationUtils.deltaRotation(rotation, i));
- boundsR.set(0, 0, Math.abs(boundsR.width()), Math.abs(boundsR.height()));
- allBounds[i] = new WindowBounds(boundsR, insetsR);
- }
-
- WindowManagerProxy wmProxy = mock(WindowManagerProxy.class);
- doReturn(cdi).when(wmProxy).getDisplayInfo(any(), any());
- doReturn(wm).when(wmProxy).getRealBounds(any(), any(), any());
-
- ArrayMap<String, Pair<CachedDisplayInfo, WindowBounds[]>> perDisplayBoundsCache =
- new ArrayMap<>();
- perDisplayBoundsCache.put(cdi.id, Pair.create(cdi.normalize(), allBounds));
-
- DisplayController.Info mockInfo = new Info(
- helper.sandboxContext, mock(Display.class), wmProxy, perDisplayBoundsCache);
-
- DisplayController controller =
- DisplayController.INSTANCE.get(helper.sandboxContext);
- controller.close();
- ReflectionHelpers.setField(controller, "mInfo", mockInfo);
-
- mDeviceProfile = InvariantDeviceProfile.INSTANCE.get(helper.sandboxContext)
- .getBestMatch(mAppBounds.width(), mAppBounds.height(), rotation);
- mDeviceProfile.updateInsets(mLauncherInsets);
-
- TaskViewSimulator tvs = new TaskViewSimulator(helper.sandboxContext,
- FallbackActivityInterface.INSTANCE);
- tvs.setDp(mDeviceProfile);
-
- int launcherRotation = mockInfo.rotation;
- if (mAppRotation < 0) {
- mAppRotation = launcherRotation;
- }
-
- tvs.getOrientationState().update(launcherRotation, mAppRotation);
- if (mAppInsets == null) {
- mAppInsets = new Rect(mLauncherInsets);
- }
- tvs.setPreviewBounds(mAppBounds, mAppInsets);
-
- tvs.fullScreenProgress.value = 1;
- tvs.recentsViewScale.value = tvs.getFullScreenScale();
- tvs.apply(this);
- } finally {
- helper.destroy();
+ mDeviceProfile = InvariantDeviceProfile.INSTANCE.get(mContext)
+ .getDeviceProfile(mContext);
+ mDeviceProfile.updateInsets(mLauncherInsets);
+
+ TaskViewSimulator tvs = new TaskViewSimulator(mContext,
+ LauncherActivityInterface.INSTANCE);
+ tvs.setDp(mDeviceProfile);
+
+ int launcherRotation = DisplayController.INSTANCE.get(mContext).getInfo().rotation;
+ if (mAppRotation < 0) {
+ mAppRotation = launcherRotation;
}
+ tvs.getOrientationState().update(launcherRotation, mAppRotation);
+ if (mAppInsets == null) {
+ mAppInsets = new Rect(mLauncherInsets);
+ }
+ tvs.setPreviewBounds(mAppBounds, mAppInsets);
+
+ tvs.fullScreenProgress.value = 1;
+ tvs.recentsViewScale.value = tvs.getFullScreenScale();
+ tvs.apply(this);
}
@Override
@@ -226,8 +182,8 @@ public class TaskViewSimulatorTest {
private static class AlmostSame extends TypeSafeMatcher<RectF> {
- // Allow .1% error margin to account for float to int conversions
- private final float mErrorFactor = .001f;
+ // Allow 1px error margin to account for float to int conversions
+ private final float mError = 1f;
private final Rect mExpected;
AlmostSame(Rect expected) {
@@ -236,12 +192,10 @@ public class TaskViewSimulatorTest {
@Override
protected boolean matchesSafely(RectF item) {
- float errorWidth = mErrorFactor * mExpected.width();
- float errorHeight = mErrorFactor * mExpected.height();
- return Math.abs(item.left - mExpected.left) < errorWidth
- && Math.abs(item.top - mExpected.top) < errorHeight
- && Math.abs(item.right - mExpected.right) < errorWidth
- && Math.abs(item.bottom - mExpected.bottom) < errorHeight;
+ return Math.abs(item.left - mExpected.left) < mError
+ && Math.abs(item.top - mExpected.top) < mError
+ && Math.abs(item.right - mExpected.right) < mError
+ && Math.abs(item.bottom - mExpected.bottom) < mError;
}
@Override
diff --git a/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java b/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java
index 2239102c4d..a44de793a3 100644
--- a/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java
+++ b/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java
@@ -21,32 +21,21 @@ import static com.android.launcher3.LauncherState.FLAG_HIDE_BACK_BUTTON;
import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.launcher3.LauncherState.NO_OFFSET;
import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE;
-import static com.android.launcher3.config.FeatureFlags.ENABLE_SPLIT_FROM_WORKSPACE;
import static com.android.launcher3.model.data.ItemInfo.NO_MATCHING_ID;
-import static com.android.launcher3.popup.QuickstepSystemShortcut.getSplitSelectShortcutByPosition;
-import static com.android.launcher3.taskbar.LauncherTaskbarUIController.ALL_APPS_PAGE_PROGRESS_INDEX;
-import static com.android.launcher3.taskbar.LauncherTaskbarUIController.MINUS_ONE_PAGE_PROGRESS_INDEX;
-import static com.android.launcher3.taskbar.LauncherTaskbarUIController.WIDGETS_PAGE_PROGRESS_INDEX;
-import static com.android.launcher3.util.DisplayController.CHANGE_ACTIVE_SCREEN;
-import static com.android.launcher3.util.DisplayController.CHANGE_NAVIGATION_MODE;
-import static com.android.launcher3.util.DisplayController.NavigationMode.TWO_BUTTONS;
-import static com.android.launcher3.util.Executors.THREAD_POOL_EXECUTOR;
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
+import static com.android.quickstep.SysUINavigationMode.Mode.TWO_BUTTONS;
import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_HOME_KEY;
import android.animation.AnimatorSet;
import android.animation.ValueAnimator;
-import android.app.ActivityManager;
import android.app.ActivityOptions;
-import android.content.Context;
+import android.content.ComponentName;
import android.content.Intent;
import android.content.IntentSender;
-import android.hardware.SensorManager;
-import android.hardware.devicestate.DeviceStateManager;
+import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.CancellationSignal;
import android.os.IBinder;
-import android.view.Display;
import android.view.View;
import android.window.SplashScreen;
@@ -64,45 +53,38 @@ import com.android.launcher3.statehandlers.DepthController;
import com.android.launcher3.statemanager.StateManager.StateHandler;
import com.android.launcher3.taskbar.LauncherTaskbarUIController;
import com.android.launcher3.taskbar.TaskbarManager;
+import com.android.launcher3.taskbar.TaskbarStateHandler;
import com.android.launcher3.uioverrides.RecentsViewStateController;
import com.android.launcher3.util.ActivityOptionsWrapper;
-import com.android.launcher3.util.DisplayController;
-import com.android.launcher3.util.DisplayController.NavigationMode;
-import com.android.launcher3.util.IntSet;
import com.android.launcher3.util.ObjectWrapper;
-import com.android.launcher3.util.RunnableList;
-import com.android.launcher3.util.SplitConfigurationOptions.SplitPositionOption;
import com.android.launcher3.util.UiThreadHelper;
import com.android.quickstep.OverviewCommandHelper;
import com.android.quickstep.RecentsModel;
+import com.android.quickstep.SysUINavigationMode;
+import com.android.quickstep.SysUINavigationMode.Mode;
+import com.android.quickstep.SysUINavigationMode.NavigationModeChangeListener;
import com.android.quickstep.SystemUiProxy;
import com.android.quickstep.TaskUtils;
+import com.android.quickstep.TouchInteractionService;
import com.android.quickstep.TouchInteractionService.TISBinder;
-import com.android.quickstep.util.LauncherUnfoldAnimationController;
-import com.android.quickstep.util.ProxyScreenStatusProvider;
import com.android.quickstep.util.RemoteAnimationProvider;
import com.android.quickstep.util.RemoteFadeOutAnimationListener;
import com.android.quickstep.util.SplitSelectStateController;
-import com.android.quickstep.util.TISBindHelper;
import com.android.quickstep.views.OverviewActionsView;
import com.android.quickstep.views.RecentsView;
+import com.android.quickstep.views.SplitPlaceholderView;
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.ActivityOptionsCompat;
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
-import com.android.systemui.unfold.UnfoldTransitionFactory;
-import com.android.systemui.unfold.UnfoldTransitionProgressProvider;
-import com.android.systemui.unfold.config.UnfoldTransitionConfig;
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;
/**
* Extension of Launcher activity to provide quickstep specific functionality
*/
-public abstract class BaseQuickstepLauncher extends Launcher {
+public abstract class BaseQuickstepLauncher extends Launcher
+ implements NavigationModeChangeListener {
private DepthController mDepthController = new DepthController(this);
private QuickstepTransitionManager mAppTransitionManager;
@@ -116,58 +98,45 @@ public abstract class BaseQuickstepLauncher extends Launcher {
private OverviewActionsView mActionsView;
- private TISBindHelper mTISBindHelper;
private @Nullable TaskbarManager mTaskbarManager;
private @Nullable OverviewCommandHelper mOverviewCommandHelper;
private @Nullable LauncherTaskbarUIController mTaskbarUIController;
+ private final ServiceConnection mTisBinderConnection = new ServiceConnection() {
+ @Override
+ public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
+ mTaskbarManager = ((TISBinder) iBinder).getTaskbarManager();
+ mTaskbarManager.setLauncher(BaseQuickstepLauncher.this);
+
+ mOverviewCommandHelper = ((TISBinder) iBinder).getOverviewCommandHelper();
+ }
+
+ @Override
+ public void onServiceDisconnected(ComponentName componentName) { }
+ };
+ private final TaskbarStateHandler mTaskbarStateHandler = new TaskbarStateHandler(this);
// Will be updated when dragging from taskbar.
private @Nullable DragOptions mNextWorkspaceDragOptions = null;
-
- private @Nullable UnfoldTransitionProgressProvider mUnfoldTransitionProgressProvider;
- private @Nullable LauncherUnfoldAnimationController mLauncherUnfoldAnimationController;
+ private SplitPlaceholderView mSplitPlaceholderView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
+ SysUINavigationMode.INSTANCE.get(this).addModeChangeListener(this);
addMultiWindowModeChangedListener(mDepthController);
- initUnfoldTransitionProgressProvider();
- }
-
- @Override
- protected void onResume() {
- super.onResume();
-
- if (mLauncherUnfoldAnimationController != null) {
- mLauncherUnfoldAnimationController.onResume();
- }
- }
-
- @Override
- protected void onPause() {
- if (mLauncherUnfoldAnimationController != null) {
- mLauncherUnfoldAnimationController.onPause();
- }
-
- super.onPause();
}
@Override
public void onDestroy() {
mAppTransitionManager.onActivityDestroyed();
- if (mUnfoldTransitionProgressProvider != null) {
- mUnfoldTransitionProgressProvider.destroy();
- }
- mTISBindHelper.onDestroy();
- if (mTaskbarManager != null) {
- mTaskbarManager.clearActivity(this);
- }
+ SysUINavigationMode.INSTANCE.get(this).removeModeChangeListener(this);
- if (mLauncherUnfoldAnimationController != null) {
- mLauncherUnfoldAnimationController.onDestroy();
- }
+ unbindService(mTisBinderConnection);
+ if (mTaskbarManager != null) {
+ mTaskbarManager.setLauncher(null);
+ }
super.onDestroy();
}
@@ -185,6 +154,14 @@ public abstract class BaseQuickstepLauncher extends Launcher {
}
@Override
+ public void onNavigationModeChanged(Mode newMode) {
+ getDragLayer().recreateControllers();
+ if (mActionsView != null) {
+ mActionsView.updateVerticalMargin(newMode);
+ }
+ }
+
+ @Override
public void onEnterAnimationComplete() {
super.onEnterAnimationComplete();
// After the transition to home, enable the high-res thumbnail loader if it wasn't enabled
@@ -223,39 +200,6 @@ public abstract class BaseQuickstepLauncher extends Launcher {
}
}
- /**
- * {@code LauncherOverlayCallbacks} scroll amount.
- * Indicates transition progress to -1 screen.
- * @param progress From 0 to 1.
- */
- @Override
- public void onScrollChanged(float progress) {
- super.onScrollChanged(progress);
- mDepthController.onOverlayScrollChanged(progress);
- onTaskbarInAppDisplayProgressUpdate(progress, MINUS_ONE_PAGE_PROGRESS_INDEX);
- }
-
- @Override
- public void onAllAppsTransition(float progress) {
- super.onAllAppsTransition(progress);
- onTaskbarInAppDisplayProgressUpdate(progress, ALL_APPS_PAGE_PROGRESS_INDEX);
- }
-
- @Override
- public void onWidgetsTransition(float progress) {
- super.onWidgetsTransition(progress);
- onTaskbarInAppDisplayProgressUpdate(progress, WIDGETS_PAGE_PROGRESS_INDEX);
- }
-
- private void onTaskbarInAppDisplayProgressUpdate(float progress, int flag) {
- if (mTaskbarManager == null
- || mTaskbarManager.getCurrentActivityContext() == null
- || mTaskbarUIController == null) {
- return;
- }
- mTaskbarUIController.onTaskbarInAppDisplayProgressUpdate(progress, flag);
- }
-
@Override
public void startIntentSenderForResult(IntentSender intent, int requestCode,
Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags, Bundle options) {
@@ -315,70 +259,36 @@ public abstract class BaseQuickstepLauncher extends Launcher {
protected void setupViews() {
super.setupViews();
+ SysUINavigationMode.INSTANCE.get(this).updateMode();
mActionsView = findViewById(R.id.overview_actions_view);
+ mSplitPlaceholderView = findViewById(R.id.split_placeholder);
RecentsView overviewPanel = (RecentsView) getOverviewPanel();
- SplitSelectStateController controller =
- new SplitSelectStateController(this, mHandler, getStateManager(),
- getDepthController());
- overviewPanel.init(mActionsView, controller);
- mActionsView.updateDimension(getDeviceProfile(), overviewPanel.getLastComputedTaskSize());
- mActionsView.updateVerticalMargin(DisplayController.getNavigationMode(this));
+ mSplitPlaceholderView.init(
+ new SplitSelectStateController(mHandler, SystemUiProxy.INSTANCE.get(this))
+ );
+ overviewPanel.init(mActionsView, mSplitPlaceholderView);
+ mActionsView.setDp(getDeviceProfile());
+ mActionsView.updateVerticalMargin(SysUINavigationMode.getMode(this));
mAppTransitionManager = new QuickstepTransitionManager(this);
mAppTransitionManager.registerRemoteAnimations();
- mAppTransitionManager.registerRemoteTransitions();
-
- mTISBindHelper = new TISBindHelper(this, this::onTISConnected);
- }
- private void onTISConnected(TISBinder binder) {
- mTaskbarManager = binder.getTaskbarManager();
- mTaskbarManager.setActivity(this);
- mOverviewCommandHelper = binder.getOverviewCommandHelper();
- }
+ bindService(new Intent(this, TouchInteractionService.class), mTisBinderConnection, 0);
- @Override
- public void runOnBindToTouchInteractionService(Runnable r) {
- mTISBindHelper.runOnBindToTouchInteractionService(r);
- }
-
- private void initUnfoldTransitionProgressProvider() {
- final UnfoldTransitionConfig config = UnfoldTransitionFactory.createConfig(this);
- if (config.isEnabled()) {
- mUnfoldTransitionProgressProvider =
- UnfoldTransitionFactory.createUnfoldTransitionProgressProvider(
- this,
- config,
- ProxyScreenStatusProvider.INSTANCE,
- getSystemService(DeviceStateManager.class),
- getSystemService(ActivityManager.class),
- getSystemService(SensorManager.class),
- getMainThreadHandler(),
- getMainExecutor(),
- /* backgroundExecutor= */ THREAD_POOL_EXECUTOR,
- /* tracingTagPrefix= */ "launcher"
- );
-
- mLauncherUnfoldAnimationController = new LauncherUnfoldAnimationController(
- this,
- getWindowManager(),
- mUnfoldTransitionProgressProvider
- );
- }
}
public void setTaskbarUIController(LauncherTaskbarUIController taskbarUIController) {
mTaskbarUIController = taskbarUIController;
}
- public @Nullable LauncherTaskbarUIController getTaskbarUIController() {
- return mTaskbarUIController;
- }
-
public <T extends OverviewActionsView> T getActionsView() {
return (T) mActionsView;
}
+ public SplitPlaceholderView getSplitPlaceholderView() {
+ return mSplitPlaceholderView;
+ }
+
@Override
protected void closeOpenViews(boolean animate) {
super.closeOpenViews(animate);
@@ -391,20 +301,25 @@ public abstract class BaseQuickstepLauncher extends Launcher {
out.add(getDepthController());
out.add(new RecentsViewStateController(this));
out.add(new BackButtonAlphaHandler(this));
+ out.add(getTaskbarStateHandler());
}
public DepthController getDepthController() {
return mDepthController;
}
- @Nullable
- public UnfoldTransitionProgressProvider getUnfoldTransitionProgressProvider() {
- return mUnfoldTransitionProgressProvider;
+ public @Nullable LauncherTaskbarUIController getTaskbarUIController() {
+ return mTaskbarUIController;
+ }
+
+ public TaskbarStateHandler getTaskbarStateHandler() {
+ return mTaskbarStateHandler;
}
@Override
public boolean supportsAdaptiveIconAnimation(View clickedView) {
- return mAppTransitionManager.hasControlRemoteAppTransitionPermission();
+ return mAppTransitionManager.hasControlRemoteAppTransitionPermission()
+ && FeatureFlags.ADAPTIVE_ICON_WINDOW_ANIM.get();
}
@Override
@@ -444,11 +359,19 @@ public abstract class BaseQuickstepLauncher extends Launcher {
@Override
public float[] getNormalOverviewScaleAndOffset() {
- return DisplayController.getNavigationMode(this).hasGestures
+ return SysUINavigationMode.getMode(this).hasGestures
? new float[] {1, 1} : new float[] {1.1f, NO_OFFSET};
}
@Override
+ public float getNormalTaskbarScale() {
+ if (mTaskbarUIController != null) {
+ return mTaskbarUIController.getTaskbarScaleOnHome();
+ }
+ return super.getNormalTaskbarScale();
+ }
+
+ @Override
public void onDragLayerHierarchyChanged() {
onLauncherStateOrFocusChanged();
}
@@ -474,7 +397,7 @@ public abstract class BaseQuickstepLauncher extends Launcher {
}
public boolean shouldBackButtonBeHidden(LauncherState toState) {
- NavigationMode mode = DisplayController.getNavigationMode(this);
+ Mode mode = SysUINavigationMode.getMode(this);
boolean shouldBackButtonBeHidden = mode.hasGestures
&& toState.hasFlag(FLAG_HIDE_BACK_BUTTON)
&& hasWindowFocus()
@@ -492,7 +415,7 @@ public abstract class BaseQuickstepLauncher extends Launcher {
*/
private void onLauncherStateOrFocusChanged() {
boolean shouldBackButtonBeHidden = shouldBackButtonBeHidden(getStateManager().getState());
- if (DisplayController.getNavigationMode(this) == TWO_BUTTONS) {
+ if (SysUINavigationMode.getMode(this) == TWO_BUTTONS) {
UiThreadHelper.setBackButtonAlphaAsync(this, SET_BACK_BUTTON_ALPHA,
shouldBackButtonBeHidden ? 0f : 1f, true /* animate */);
}
@@ -502,8 +425,8 @@ public abstract class BaseQuickstepLauncher extends Launcher {
}
@Override
- public void finishBindingItems(IntSet pagesBoundFirst) {
- super.finishBindingItems(pagesBoundFirst);
+ public void finishBindingItems(int pageBoundFirst) {
+ super.finishBindingItems(pageBoundFirst);
// Instantiate and initialize WellbeingModel now that its loading won't interfere with
// populating workspace.
// TODO: Find a better place for this
@@ -511,35 +434,9 @@ public abstract class BaseQuickstepLauncher extends Launcher {
}
@Override
- public void onInitialBindComplete(IntSet boundPages, RunnableList pendingTasks) {
- pendingTasks.add(() -> {
- // This is added in pending task as we need to wait for views to be positioned
- // correctly before registering them for the animation.
- if (mLauncherUnfoldAnimationController != null) {
- // This is needed in case items are rebound while the unfold animation is in
- // progress.
- mLauncherUnfoldAnimationController.updateRegisteredViewsIfNeeded();
- }
- });
- super.onInitialBindComplete(boundPages, pendingTasks);
- }
-
- @Override
public Stream<SystemShortcut.Factory> getSupportedShortcuts() {
- Stream<SystemShortcut.Factory> base = Stream.of(WellbeingModel.SHORTCUT_FACTORY);
- if (ENABLE_SPLIT_FROM_WORKSPACE.get() && mDeviceProfile.isTablet) {
- RecentsView recentsView = getOverviewPanel();
- // TODO: Pull it out of PagedOrentationHandler for split from workspace.
- List<SplitPositionOption> positions =
- recentsView.getPagedOrientationHandler().getSplitPositionOptions(
- mDeviceProfile);
- List<SystemShortcut.Factory<BaseQuickstepLauncher>> splitShortcuts = new ArrayList<>();
- for (SplitPositionOption position : positions) {
- splitShortcuts.add(getSplitSelectShortcutByPosition(position));
- }
- base = Stream.concat(base, splitShortcuts.stream());
- }
- return Stream.concat(base, super.getSupportedShortcuts());
+ return Stream.concat(Stream.of(WellbeingModel.SHORTCUT_FACTORY),
+ super.getSupportedShortcuts());
}
@Override
@@ -552,35 +449,17 @@ public abstract class BaseQuickstepLauncher extends Launcher {
ActivityOptionsCompat.setLauncherSourceInfo(
activityOptions.options, mLastTouchUpTime);
}
- activityOptions.options.setSplashScreenStyle(SplashScreen.SPLASH_SCREEN_STYLE_ICON);
- activityOptions.options.setLaunchDisplayId(
- (v != null && v.getDisplay() != null) ? v.getDisplay().getDisplayId()
- : Display.DEFAULT_DISPLAY);
+ activityOptions.options.setSplashscreenStyle(SplashScreen.SPLASH_SCREEN_STYLE_ICON);
addLaunchCookie(item, activityOptions.options);
return activityOptions;
}
/**
- * Adds a new launch cookie for the activity launch if supported.
- *
- * @param info the item info for the launch
- * @param opts the options to set the launchCookie on.
+ * Adds a new launch cookie for the activity launch of the given {@param info} if supported.
*/
public void addLaunchCookie(ItemInfo info, ActivityOptions opts) {
- IBinder launchCookie = getLaunchCookie(info);
- if (launchCookie != null) {
- opts.setLaunchCookie(launchCookie);
- }
- }
-
- /**
- * Return a new launch cookie for the activity launch if supported.
- *
- * @param info the item info for the launch
- */
- public IBinder getLaunchCookie(ItemInfo info) {
if (info == null) {
- return null;
+ return;
}
switch (info.container) {
case LauncherSettings.Favorites.CONTAINER_DESKTOP:
@@ -594,7 +473,8 @@ public abstract class BaseQuickstepLauncher extends Launcher {
break;
}
// Reset any existing launch cookies associated with the cookie
- return ObjectWrapper.wrap(NO_MATCHING_ID);
+ opts.setLaunchCookie(ObjectWrapper.wrap(NO_MATCHING_ID));
+ return;
}
switch (info.itemType) {
case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION:
@@ -605,37 +485,13 @@ public abstract class BaseQuickstepLauncher extends Launcher {
break;
default:
// Reset any existing launch cookies associated with the cookie
- return ObjectWrapper.wrap(NO_MATCHING_ID);
+ opts.setLaunchCookie(ObjectWrapper.wrap(NO_MATCHING_ID));
+ return;
}
- return ObjectWrapper.wrap(new Integer(info.id));
+ opts.setLaunchCookie(ObjectWrapper.wrap(new Integer(info.id)));
}
public void setHintUserWillBeActive() {
addActivityFlags(ACTIVITY_STATE_USER_WILL_BE_ACTIVE);
}
-
- @Override
- public void onDisplayInfoChanged(Context context, DisplayController.Info info, int flags) {
- super.onDisplayInfoChanged(context, info, flags);
- // When changing screens, force moving to rest state similar to StatefulActivity.onStop, as
- // StatefulActivity isn't called consistently.
- if ((flags & CHANGE_ACTIVE_SCREEN) != 0) {
- getStateManager().moveToRestState();
- }
-
- if ((flags & CHANGE_NAVIGATION_MODE) != 0) {
- getDragLayer().recreateControllers();
- if (mActionsView != null) {
- mActionsView.updateVerticalMargin(info.navigationMode);
- }
- }
- }
-
- @Override
- public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {
- super.dump(prefix, fd, writer, args);
- if (mDepthController != null) {
- mDepthController.dump(prefix, writer);
- }
- }
}
diff --git a/quickstep/src/com/android/launcher3/LauncherAnimationRunner.java b/quickstep/src/com/android/launcher3/LauncherAnimationRunner.java
index 62603e9d54..661053af18 100644
--- a/quickstep/src/com/android/launcher3/LauncherAnimationRunner.java
+++ b/quickstep/src/com/android/launcher3/LauncherAnimationRunner.java
@@ -16,9 +16,9 @@
package com.android.launcher3;
import static com.android.launcher3.Utilities.postAsyncCallback;
+import static com.android.launcher3.util.DisplayController.getSingleFrameMs;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
-import static com.android.launcher3.util.window.RefreshRateTracker.getSingleFrameMs;
import static com.android.systemui.shared.recents.utilities.Utilities.postAtFrontOfQueueAsynchronously;
import android.animation.Animator;
diff --git a/quickstep/src/com/android/launcher3/LauncherInitListener.java b/quickstep/src/com/android/launcher3/LauncherInitListener.java
index 35151f1a68..5fc79f078f 100644
--- a/quickstep/src/com/android/launcher3/LauncherInitListener.java
+++ b/quickstep/src/com/android/launcher3/LauncherInitListener.java
@@ -17,8 +17,11 @@ package com.android.launcher3;
import android.animation.AnimatorSet;
import android.annotation.TargetApi;
+import android.content.Context;
+import android.content.Intent;
import android.os.Build;
import android.os.CancellationSignal;
+import android.os.Handler;
import com.android.quickstep.util.ActivityInitListener;
import com.android.quickstep.util.RemoteAnimationProvider;
@@ -75,4 +78,11 @@ public class LauncherInitListener extends ActivityInitListener<Launcher> {
mRemoteAnimationProvider = null;
super.unregister();
}
+
+ @Override
+ public void registerAndStartActivity(Intent intent, RemoteAnimationProvider animProvider,
+ Context context, Handler handler, long duration) {
+ mRemoteAnimationProvider = animProvider;
+ super.registerAndStartActivity(intent, animProvider, context, handler, duration);
+ }
}
diff --git a/quickstep/src/com/android/launcher3/QuickstepAccessibilityDelegate.java b/quickstep/src/com/android/launcher3/QuickstepAccessibilityDelegate.java
index 962fd91c2e..96559cbb8a 100644
--- a/quickstep/src/com/android/launcher3/QuickstepAccessibilityDelegate.java
+++ b/quickstep/src/com/android/launcher3/QuickstepAccessibilityDelegate.java
@@ -44,7 +44,7 @@ public class QuickstepAccessibilityDelegate extends LauncherAccessibilityDelegat
@Override
protected boolean performAction(View host, ItemInfo item, int action, boolean fromKeyboard) {
- QuickstepLauncher launcher = (QuickstepLauncher) mContext;
+ QuickstepLauncher launcher = (QuickstepLauncher) mLauncher;
if (action == PIN_PREDICTION) {
if (launcher.getHotseatPredictionController() == null) {
return false;
diff --git a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
index e1a3b729c1..5bb76d6a67 100644
--- a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
+++ b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
@@ -16,7 +16,6 @@
package com.android.launcher3;
-import static android.provider.Settings.Secure.LAUNCHER_TASKBAR_EDUCATION_SHOWING;
import static android.window.StartingWindowInfo.STARTING_WINDOW_TYPE_NONE;
import static android.window.StartingWindowInfo.STARTING_WINDOW_TYPE_SPLASH_SCREEN;
@@ -28,26 +27,20 @@ import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY;
import static com.android.launcher3.LauncherAnimUtils.VIEW_BACKGROUND_COLOR;
import static com.android.launcher3.LauncherState.ALL_APPS;
import static com.android.launcher3.LauncherState.BACKGROUND_APP;
-import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.launcher3.LauncherState.OVERVIEW;
-import static com.android.launcher3.Utilities.mapBoundToRange;
import static com.android.launcher3.Utilities.postAsyncCallback;
-import static com.android.launcher3.anim.Interpolators.ACCEL_1_5;
import static com.android.launcher3.anim.Interpolators.AGGRESSIVE_EASE;
import static com.android.launcher3.anim.Interpolators.DEACCEL_1_5;
import static com.android.launcher3.anim.Interpolators.DEACCEL_1_7;
import static com.android.launcher3.anim.Interpolators.EXAGGERATED_EASE;
import static com.android.launcher3.anim.Interpolators.LINEAR;
-import static com.android.launcher3.config.FeatureFlags.ENABLE_BACK_SWIPE_HOME_ANIMATION;
import static com.android.launcher3.config.FeatureFlags.ENABLE_SCRIM_FOR_APP_LAUNCH;
import static com.android.launcher3.config.FeatureFlags.KEYGUARD_ANIMATION;
import static com.android.launcher3.config.FeatureFlags.SEPARATE_RECENTS_ACTIVITY;
-import static com.android.launcher3.model.data.ItemInfo.NO_MATCHING_ID;
+import static com.android.launcher3.dragndrop.DragLayer.ALPHA_INDEX_TRANSITIONS;
import static com.android.launcher3.statehandlers.DepthController.DEPTH;
-import static com.android.launcher3.testing.TestProtocol.BAD_STATE;
-import static com.android.launcher3.util.window.RefreshRateTracker.getSingleFrameMs;
-import static com.android.launcher3.views.FloatingIconView.SHAPE_PROGRESS_DURATION;
-import static com.android.launcher3.views.FloatingIconView.getFloatingIconView;
+import static com.android.launcher3.util.DisplayController.getSingleFrameMs;
+import static com.android.quickstep.TaskUtils.taskIsATargetWithMode;
import static com.android.quickstep.TaskViewUtils.findTaskViewToLaunch;
import static com.android.systemui.shared.system.QuickStepContract.getWindowCornerRadius;
import static com.android.systemui.shared.system.QuickStepContract.supportsRoundedCornersOnWindows;
@@ -59,33 +52,26 @@ import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
-import android.content.ComponentName;
import android.content.Context;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Point;
-import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.os.CancellationSignal;
import android.os.Handler;
-import android.os.IBinder;
import android.os.Looper;
import android.os.SystemProperties;
-import android.os.UserHandle;
-import android.provider.Settings;
-import android.util.Log;
import android.util.Pair;
import android.util.Size;
import android.view.SurfaceControl;
import android.view.View;
import android.view.ViewRootImpl;
import android.view.ViewTreeObserver;
-import android.view.animation.AnimationUtils;
import android.view.animation.Interpolator;
import android.view.animation.PathInterpolator;
@@ -100,24 +86,18 @@ import com.android.launcher3.dragndrop.DragLayer;
import com.android.launcher3.icons.FastBitmapDrawable;
import com.android.launcher3.shortcuts.DeepShortcutView;
import com.android.launcher3.statehandlers.DepthController;
-import com.android.launcher3.taskbar.LauncherTaskbarUIController;
-import com.android.launcher3.touch.PagedOrientationHandler;
import com.android.launcher3.util.ActivityOptionsWrapper;
-import com.android.launcher3.util.DynamicResource;
-import com.android.launcher3.util.ObjectWrapper;
+import com.android.launcher3.util.MultiValueAlpha.AlphaProperty;
import com.android.launcher3.util.RunnableList;
import com.android.launcher3.util.Themes;
import com.android.launcher3.views.FloatingIconView;
import com.android.launcher3.views.ScrimView;
import com.android.launcher3.widget.LauncherAppWidgetHostView;
-import com.android.quickstep.LauncherBackAnimationController;
import com.android.quickstep.RemoteAnimationTargets;
import com.android.quickstep.SystemUiProxy;
import com.android.quickstep.TaskViewUtils;
import com.android.quickstep.util.MultiValueUpdateListener;
-import com.android.quickstep.util.RectFSpringAnim;
import com.android.quickstep.util.RemoteAnimationProvider;
-import com.android.quickstep.util.StaggeredWorkspaceAnim;
import com.android.quickstep.util.SurfaceTransactionApplier;
import com.android.quickstep.util.WorkspaceRevealAnim;
import com.android.quickstep.views.FloatingWidgetView;
@@ -137,7 +117,6 @@ import com.android.systemui.shared.system.WindowManagerWrapper;
import com.android.wm.shell.startingsurface.IStartingWindowListener;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.List;
@@ -163,11 +142,21 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
private static final String CONTROL_REMOTE_APP_TRANSITION_PERMISSION =
"android.permission.CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS";
- private static final long APP_LAUNCH_DURATION = 500;
-
+ private static final long APP_LAUNCH_DURATION = 450;
+ // Use a shorter duration for x or y translation to create a curve effect
+ private static final long APP_LAUNCH_CURVED_DURATION = 250;
private static final long APP_LAUNCH_ALPHA_DURATION = 50;
private static final long APP_LAUNCH_ALPHA_START_DELAY = 25;
+ // We scale the durations for the downward app launch animations (minus the scale animation).
+ private static final float APP_LAUNCH_DOWN_DUR_SCALE_FACTOR = 0.8f;
+ private static final long APP_LAUNCH_DOWN_DURATION =
+ (long) (APP_LAUNCH_DURATION * APP_LAUNCH_DOWN_DUR_SCALE_FACTOR);
+ private static final long APP_LAUNCH_DOWN_CURVED_DURATION =
+ (long) (APP_LAUNCH_CURVED_DURATION * APP_LAUNCH_DOWN_DUR_SCALE_FACTOR);
+ private static final long APP_LAUNCH_ALPHA_DOWN_DURATION =
+ (long) (APP_LAUNCH_ALPHA_DURATION * APP_LAUNCH_DOWN_DUR_SCALE_FACTOR);
+
public static final int ANIMATION_NAV_FADE_IN_DURATION = 266;
public static final int ANIMATION_NAV_FADE_OUT_DURATION = 133;
public static final long ANIMATION_DELAY_NAV_FADE_IN =
@@ -177,11 +166,12 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
public static final Interpolator NAV_FADE_OUT_INTERPOLATOR =
new PathInterpolator(0.2f, 0f, 1f, 1f);
+ private static final long CROP_DURATION = 375;
+ private static final long RADIUS_DURATION = 375;
+
public static final int RECENTS_LAUNCH_DURATION = 336;
private static final int LAUNCHER_RESUME_START_DELAY = 100;
private static final int CLOSING_TRANSITION_DURATION_MS = 250;
- public static final int SPLIT_LAUNCH_DURATION = 370;
- public static final int SPLIT_DIVIDER_ANIM_DURATION = 100;
public static final int CONTENT_ALPHA_DURATION = 217;
protected static final int CONTENT_SCALE_DURATION = 350;
@@ -193,7 +183,9 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
private static final int WIDGET_CROSSFADE_DURATION_MILLIS = 125;
protected final BaseQuickstepLauncher mLauncher;
+
private final DragLayer mDragLayer;
+ private final AlphaProperty mDragLayerAlpha;
final Handler mHandler;
@@ -214,7 +206,6 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
private RemoteAnimationFactory mWallpaperOpenTransitionRunner;
private RemoteTransitionCompat mLauncherOpenTransition;
- private LauncherBackAnimationController mBackAnimationController;
private final AnimatorListenerAdapter mForceInvisibleListener = new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
@@ -231,15 +222,12 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
// Will never be larger than MAX_NUM_TASKS
private LinkedHashMap<Integer, Pair<Integer, Integer>> mTaskStartParams;
- private final Interpolator mOpeningXInterpolator;
- private final Interpolator mOpeningInterpolator;
-
public QuickstepTransitionManager(Context context) {
mLauncher = Launcher.cast(Launcher.getLauncher(context));
mDragLayer = mLauncher.getDragLayer();
+ mDragLayerAlpha = mDragLayer.getAlphaProperty(ALPHA_INDEX_TRANSITIONS);
mHandler = new Handler(Looper.getMainLooper());
mDeviceProfile = mLauncher.getDeviceProfile();
- mBackAnimationController = new LauncherBackAnimationController(mLauncher, this);
Resources res = mLauncher.getResources();
mContentScale = res.getFloat(R.dimen.content_scale);
@@ -260,10 +248,6 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
SystemUiProxy.INSTANCE.get(mLauncher).setStartingWindowListener(
mStartingWindowListener);
}
-
- mOpeningXInterpolator = AnimationUtils.loadInterpolator(context, R.interpolator.app_open_x);
- mOpeningInterpolator = AnimationUtils.loadInterpolator(context,
- R.interpolator.three_point_fast_out_extra_slow_in);
}
@Override
@@ -291,8 +275,7 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
long statusBarTransitionDelay = duration - STATUS_BAR_TRANSITION_DURATION
- STATUS_BAR_TRANSITION_PRE_DELAY;
RemoteAnimationAdapterCompat adapterCompat =
- new RemoteAnimationAdapterCompat(runner, duration, statusBarTransitionDelay,
- mLauncher.getIApplicationThread());
+ new RemoteAnimationAdapterCompat(runner, duration, statusBarTransitionDelay);
return new ActivityOptionsWrapper(
ActivityOptionsCompat.makeRemoteAnimation(adapterCompat), onEndCallback);
}
@@ -371,7 +354,7 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
if (launcherClosing) {
// Delay animation by a frame to avoid jank.
Pair<AnimatorSet, Runnable> launcherContentAnimator =
- getLauncherContentAnimator(true /* isAppOpening */, startDelay, false);
+ getLauncherContentAnimator(true /* isAppOpening */, startDelay);
anim.play(launcherContentAnimator.first);
anim.addListener(new AnimatorListenerAdapter() {
@Override
@@ -445,10 +428,6 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
4 - rotationChange);
}
}
- if (mDeviceProfile.isTaskbarPresentInApps) {
- // Animate to above the taskbar.
- bounds.bottom -= target.contentInsets.bottom;
- }
return bounds;
}
@@ -468,10 +447,9 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
* @param isAppOpening True when this is called when an app is opening.
* False when this is called when an app is closing.
* @param startDelay Start delay duration.
- * @param skipAllAppsScale True if we want to avoid scaling All Apps
*/
private Pair<AnimatorSet, Runnable> getLauncherContentAnimator(boolean isAppOpening,
- int startDelay, boolean skipAllAppsScale) {
+ int startDelay) {
AnimatorSet launcherAnimator = new AnimatorSet();
Runnable endListener;
@@ -483,15 +461,13 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
? new float[]{1, mContentScale}
: new float[]{mContentScale, 1};
- // Pause expensive view updates as they can lead to layer thrashing and skipped frames.
- mLauncher.pauseExpensiveViewUpdates();
-
if (mLauncher.isInState(ALL_APPS)) {
// All Apps in portrait mode is full screen, so we only animate AllAppsContainerView.
final View appsView = mLauncher.getAppsView();
final float startAlpha = appsView.getAlpha();
final float startScale = SCALE_PROPERTY.get(appsView);
appsView.setAlpha(alphas[0]);
+ SCALE_PROPERTY.set(appsView, scales[0]);
ObjectAnimator alpha = ObjectAnimator.ofFloat(appsView, View.ALPHA, alphas);
alpha.setDuration(CONTENT_ALPHA_DURATION);
@@ -503,16 +479,12 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
appsView.setLayerType(View.LAYER_TYPE_NONE, null);
}
});
-
- if (!skipAllAppsScale) {
- SCALE_PROPERTY.set(appsView, scales[0]);
- ObjectAnimator scale = ObjectAnimator.ofFloat(appsView, SCALE_PROPERTY, scales);
- scale.setInterpolator(AGGRESSIVE_EASE);
- scale.setDuration(CONTENT_SCALE_DURATION);
- launcherAnimator.play(scale);
- }
+ ObjectAnimator scale = ObjectAnimator.ofFloat(appsView, SCALE_PROPERTY, scales);
+ scale.setInterpolator(AGGRESSIVE_EASE);
+ scale.setDuration(CONTENT_SCALE_DURATION);
launcherAnimator.play(alpha);
+ launcherAnimator.play(scale);
endListener = () -> {
appsView.setAlpha(startAlpha);
@@ -523,7 +495,7 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
endListener = composeViewContentAnimator(launcherAnimator, alphas, scales);
} else {
List<View> viewsToAnimate = new ArrayList<>();
- Workspace<?> workspace = mLauncher.getWorkspace();
+ Workspace workspace = mLauncher.getWorkspace();
workspace.forEachVisiblePage(
view -> viewsToAnimate.add(((CellLayout) view).getShortcutsAndWidgets()));
@@ -540,10 +512,7 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
final boolean scrimEnabled = ENABLE_SCRIM_FOR_APP_LAUNCH.get();
if (scrimEnabled) {
- boolean useTaskbarColor = mDeviceProfile.isTaskbarPresentInApps;
- int scrimColor = useTaskbarColor
- ? mLauncher.getResources().getColor(R.color.taskbar_background)
- : Themes.getAttrColor(mLauncher, R.attr.overviewScrimColor);
+ int scrimColor = Themes.getAttrColor(mLauncher, R.attr.overviewScrimColor);
int scrimColorTrans = ColorUtils.setAlphaComponent(scrimColor, 0);
int[] colors = isAppOpening
? new int[]{scrimColorTrans, scrimColor}
@@ -556,34 +525,13 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
colors);
scrim.setDuration(CONTENT_SCRIM_DURATION);
scrim.setInterpolator(DEACCEL_1_5);
-
- if (useTaskbarColor) {
- // Hide the taskbar background color since it would duplicate the scrim.
- scrim.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationStart(Animator animation) {
- LauncherTaskbarUIController taskbarUIController =
- mLauncher.getTaskbarUIController();
- if (taskbarUIController != null) {
- taskbarUIController.forceHideBackground(true);
- }
- }
-
- @Override
- public void onAnimationEnd(Animator animation) {
- LauncherTaskbarUIController taskbarUIController =
- mLauncher.getTaskbarUIController();
- if (taskbarUIController != null) {
- taskbarUIController.forceHideBackground(false);
- }
- }
- });
- }
-
launcherAnimator.play(scrim);
}
}
+ // Pause page indicator animations as they lead to layer trashing.
+ mLauncher.getWorkspace().getPageIndicator().pauseAnimations();
+
endListener = () -> {
viewsToAnimate.forEach(view -> {
SCALE_PROPERTY.set(view, 1f);
@@ -592,7 +540,7 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
if (scrimEnabled) {
mLauncher.getScrimView().setBackgroundColor(Color.TRANSPARENT);
}
- mLauncher.resumeExpensiveViewUpdates();
+ mLauncher.getWorkspace().getPageIndicator().skipAnimationsToEnd();
};
}
@@ -613,28 +561,9 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
RecentsView overview = mLauncher.getOverviewPanel();
ObjectAnimator alpha = ObjectAnimator.ofFloat(overview,
RecentsView.CONTENT_ALPHA, alphas);
- Log.d(BAD_STATE, "QTM composeViewContentAnimator alphas=" + Arrays.toString(alphas));
- alpha.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationStart(Animator animation) {
- Log.d(BAD_STATE, "QTM composeViewContentAnimator onStart");
- }
-
- @Override
- public void onAnimationCancel(Animator animation) {
- float alpha = overview == null ? -1 : RecentsView.CONTENT_ALPHA.get(overview);
- Log.d(BAD_STATE, "QTM composeViewContentAnimator onCancel, alpha=" + alpha);
- }
-
- @Override
- public void onAnimationEnd(Animator animation) {
- Log.d(BAD_STATE, "QTM composeViewContentAnimator onEnd");
- }
- });
alpha.setDuration(CONTENT_ALPHA_DURATION);
alpha.setInterpolator(LINEAR);
anim.play(alpha);
- Log.d(BAD_STATE, "QTM composeViewContentAnimator setFreezeVisibility=true");
overview.setFreezeViewVisibility(true);
ObjectAnimator scaleAnim = ObjectAnimator.ofFloat(overview, SCALE_PROPERTY, scales);
@@ -643,7 +572,6 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
anim.play(scaleAnim);
return () -> {
- Log.d(BAD_STATE, "QTM composeViewContentAnimator onEnd setFreezeVisibility=false");
overview.setFreezeViewVisibility(false);
SCALE_PROPERTY.set(overview, 1f);
mLauncher.getStateManager().reapplyState();
@@ -689,10 +617,10 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
AnimOpenProperties prop = new AnimOpenProperties(mLauncher.getResources(), mDeviceProfile,
windowTargetBounds, launcherIconBounds, v, dragLayerBounds[0], dragLayerBounds[1],
hasSplashScreen, floatingView.isDifferentFromAppIcon());
- int left = prop.cropCenterXStart - prop.cropWidthStart / 2;
- int top = prop.cropCenterYStart - prop.cropHeightStart / 2;
- int right = left + prop.cropWidthStart;
- int bottom = top + prop.cropHeightStart;
+ int left = (int) (prop.cropCenterXStart - prop.cropWidthStart / 2);
+ int top = (int) (prop.cropCenterYStart - prop.cropHeightStart / 2);
+ int right = (int) (left + prop.cropWidthStart);
+ int bottom = (int) (top + prop.cropHeightStart);
// Set the crop here so we can calculate the corner radius below.
crop.set(left, top, right, bottom);
@@ -707,26 +635,10 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
appAnimator.addListener(floatingView);
appAnimator.addListener(new AnimatorListenerAdapter() {
@Override
- public void onAnimationStart(Animator animation) {
- LauncherTaskbarUIController taskbarController = mLauncher.getTaskbarUIController();
- if (taskbarController != null && taskbarController.shouldShowEdu()) {
- // LAUNCHER_TASKBAR_EDUCATION_SHOWING is set to true here, when the education
- // flow is about to start, to avoid a race condition with other components
- // that would show something else to the user as soon as the app is opened.
- Settings.Secure.putInt(mLauncher.getContentResolver(),
- LAUNCHER_TASKBAR_EDUCATION_SHOWING, 1);
- }
- }
-
- @Override
public void onAnimationEnd(Animator animation) {
if (v instanceof BubbleTextView) {
((BubbleTextView) v).setStayPressed(false);
}
- LauncherTaskbarUIController taskbarController = mLauncher.getTaskbarUIController();
- if (taskbarController != null) {
- taskbarController.showEdu();
- }
openingTargets.release();
}
});
@@ -735,33 +647,31 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
? Math.max(crop.width(), crop.height()) / 2f
: 0f;
final float finalWindowRadius = mDeviceProfile.isMultiWindowMode
- ? 0 : getWindowCornerRadius(mLauncher);
+ ? 0 : getWindowCornerRadius(mLauncher.getResources());
final float finalShadowRadius = appTargetsAreTranslucent ? 0 : mMaxShadowRadius;
MultiValueUpdateListener listener = new MultiValueUpdateListener() {
- FloatProp mDx = new FloatProp(0, prop.dX, 0, APP_LAUNCH_DURATION,
- mOpeningXInterpolator);
- FloatProp mDy = new FloatProp(0, prop.dY, 0, APP_LAUNCH_DURATION,
- mOpeningInterpolator);
+ FloatProp mDx = new FloatProp(0, prop.dX, 0, prop.xDuration, AGGRESSIVE_EASE);
+ FloatProp mDy = new FloatProp(0, prop.dY, 0, prop.yDuration, AGGRESSIVE_EASE);
FloatProp mIconScaleToFitScreen = new FloatProp(prop.initialAppIconScale,
- prop.finalAppIconScale, 0, APP_LAUNCH_DURATION, mOpeningInterpolator);
+ prop.finalAppIconScale, 0, APP_LAUNCH_DURATION, EXAGGERATED_EASE);
FloatProp mIconAlpha = new FloatProp(prop.iconAlphaStart, 0f,
- APP_LAUNCH_ALPHA_START_DELAY, APP_LAUNCH_ALPHA_DURATION, LINEAR);
+ APP_LAUNCH_ALPHA_START_DELAY, prop.alphaDuration, LINEAR);
FloatProp mWindowRadius = new FloatProp(initialWindowRadius, finalWindowRadius, 0,
- APP_LAUNCH_DURATION, mOpeningInterpolator);
+ RADIUS_DURATION, EXAGGERATED_EASE);
FloatProp mShadowRadius = new FloatProp(0, finalShadowRadius, 0,
- APP_LAUNCH_DURATION, mOpeningInterpolator);
+ APP_LAUNCH_DURATION, EXAGGERATED_EASE);
FloatProp mCropRectCenterX = new FloatProp(prop.cropCenterXStart, prop.cropCenterXEnd,
- 0, APP_LAUNCH_DURATION, mOpeningInterpolator);
+ 0, CROP_DURATION, EXAGGERATED_EASE);
FloatProp mCropRectCenterY = new FloatProp(prop.cropCenterYStart, prop.cropCenterYEnd,
- 0, APP_LAUNCH_DURATION, mOpeningInterpolator);
+ 0, CROP_DURATION, EXAGGERATED_EASE);
FloatProp mCropRectWidth = new FloatProp(prop.cropWidthStart, prop.cropWidthEnd, 0,
- APP_LAUNCH_DURATION, mOpeningInterpolator);
+ CROP_DURATION, EXAGGERATED_EASE);
FloatProp mCropRectHeight = new FloatProp(prop.cropHeightStart, prop.cropHeightEnd, 0,
- APP_LAUNCH_DURATION, mOpeningInterpolator);
+ CROP_DURATION, EXAGGERATED_EASE);
FloatProp mNavFadeOut = new FloatProp(1f, 0f, 0, ANIMATION_NAV_FADE_OUT_DURATION,
NAV_FADE_OUT_INTERPOLATOR);
@@ -898,13 +808,7 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
// Since we added a start delay, call update here to init the FloatingIconView properly.
listener.onUpdate(0, true /* initOnly */);
- // If app targets are translucent, do not animate the background as it causes a visible
- // flicker when it resets itself at the end of its animation.
- if (appTargetsAreTranslucent) {
- animatorSet.play(appAnimator);
- } else {
- animatorSet.playTogether(appAnimator, getBackgroundAnimator());
- }
+ animatorSet.playTogether(appAnimator, getBackgroundAnimator(appTargets));
return animatorSet;
}
@@ -932,7 +836,7 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
}
final float finalWindowRadius = mDeviceProfile.isMultiWindowMode
- ? 0 : getWindowCornerRadius(mLauncher);
+ ? 0 : getWindowCornerRadius(mLauncher.getResources());
final FloatingWidgetView floatingView = FloatingWidgetView.getFloatingWidgetView(mLauncher,
v, widgetBackgroundBounds,
new Size(windowTargetBounds.width(), windowTargetBounds.height()),
@@ -969,23 +873,22 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
WIDGET_CROSSFADE_DURATION_MILLIS / 2 /* delay */,
WIDGET_CROSSFADE_DURATION_MILLIS / 2 /* duration */, LINEAR);
final FloatProp mWindowRadius = new FloatProp(initialWindowRadius, finalWindowRadius,
- 0 /* start */, APP_LAUNCH_DURATION, mOpeningInterpolator);
- final FloatProp mCornerRadiusProgress = new FloatProp(0, 1, 0, APP_LAUNCH_DURATION,
- mOpeningInterpolator);
+ 0 /* start */, RADIUS_DURATION, LINEAR);
+ final FloatProp mCornerRadiusProgress = new FloatProp(0, 1, 0, RADIUS_DURATION, LINEAR);
// Window & widget background positioning bounds
final FloatProp mDx = new FloatProp(widgetBackgroundBounds.centerX(),
- windowTargetBounds.centerX(), 0 /* delay */, APP_LAUNCH_DURATION,
- mOpeningXInterpolator);
+ windowTargetBounds.centerX(), 0 /* delay */, APP_LAUNCH_CURVED_DURATION,
+ EXAGGERATED_EASE);
final FloatProp mDy = new FloatProp(widgetBackgroundBounds.centerY(),
windowTargetBounds.centerY(), 0 /* delay */, APP_LAUNCH_DURATION,
- mOpeningInterpolator);
+ EXAGGERATED_EASE);
final FloatProp mWidth = new FloatProp(widgetBackgroundBounds.width(),
windowTargetBounds.width(), 0 /* delay */, APP_LAUNCH_DURATION,
- mOpeningInterpolator);
+ EXAGGERATED_EASE);
final FloatProp mHeight = new FloatProp(widgetBackgroundBounds.height(),
windowTargetBounds.height(), 0 /* delay */, APP_LAUNCH_DURATION,
- mOpeningInterpolator);
+ EXAGGERATED_EASE);
final FloatProp mNavFadeOut = new FloatProp(1f, 0f, 0, ANIMATION_NAV_FADE_OUT_DURATION,
NAV_FADE_OUT_INTERPOLATOR);
@@ -1041,20 +944,11 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
}
});
- // If app targets are translucent, do not animate the background as it causes a visible
- // flicker when it resets itself at the end of its animation.
- if (appTargetsAreTranslucent) {
- animatorSet.play(appAnimator);
- } else {
- animatorSet.playTogether(appAnimator, getBackgroundAnimator());
- }
+ animatorSet.playTogether(appAnimator, getBackgroundAnimator(appTargets));
return animatorSet;
}
- /**
- * Returns animator that controls depth/blur of the background.
- */
- private ObjectAnimator getBackgroundAnimator() {
+ private ObjectAnimator getBackgroundAnimator(RemoteAnimationTargetCompat[] appTargets) {
// When launching an app from overview that doesn't map to a task, we still want to just
// blur the wallpaper instead of the launcher surface as well
boolean allowBlurringLauncher = mLauncher.getStateManager().getState() != OVERVIEW;
@@ -1124,8 +1018,7 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
new RemoteAnimationAdapterCompat(
new LauncherAnimationRunner(mHandler, mWallpaperOpenRunner,
false /* startAtFrontOfQueue */),
- CLOSING_TRANSITION_DURATION_MS, 0 /* statusBarTransitionDelay */,
- mLauncher.getIApplicationThread()));
+ CLOSING_TRANSITION_DURATION_MS, 0 /* statusBarTransitionDelay */));
if (KEYGUARD_ANIMATION.get()) {
mKeyguardGoingAwayRunner = createWallpaperOpenRunner(true /* fromUnlock */);
@@ -1135,8 +1028,7 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
new LauncherAnimationRunner(
mHandler, mKeyguardGoingAwayRunner,
true /* startAtFrontOfQueue */),
- CLOSING_TRANSITION_DURATION_MS, 0 /* statusBarTransitionDelay */,
- mLauncher.getIApplicationThread()));
+ CLOSING_TRANSITION_DURATION_MS, 0 /* statusBarTransitionDelay */));
}
new ActivityCompat(mLauncher).registerRemoteAnimations(definition);
@@ -1154,12 +1046,9 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
mWallpaperOpenTransitionRunner = createWallpaperOpenRunner(false /* fromUnlock */);
mLauncherOpenTransition = RemoteAnimationAdapterCompat.buildRemoteTransition(
new LauncherAnimationRunner(mHandler, mWallpaperOpenTransitionRunner,
- false /* startAtFrontOfQueue */), mLauncher.getIApplicationThread());
- mLauncherOpenTransition.addHomeOpenCheck(mLauncher.getComponentName());
- SystemUiProxy.INSTANCE.get(mLauncher).registerRemoteTransition(mLauncherOpenTransition);
- }
- if (mBackAnimationController != null) {
- mBackAnimationController.registerBackCallbacks(mHandler);
+ false /* startAtFrontOfQueue */));
+ mLauncherOpenTransition.addHomeOpenCheck();
+ SystemUiProxy.INSTANCE.getNoCreate().registerRemoteTransition(mLauncherOpenTransition);
}
}
@@ -1167,7 +1056,7 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
unregisterRemoteAnimations();
unregisterRemoteTransitions();
mStartingWindowListener.setTransitionManager(null);
- SystemUiProxy.INSTANCE.get(mLauncher).setStartingWindowListener(null);
+ SystemUiProxy.INSTANCE.getNoCreate().setStartingWindowListener(null);
}
private void unregisterRemoteAnimations() {
@@ -1191,41 +1080,15 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
}
if (hasControlRemoteAppTransitionPermission()) {
if (mLauncherOpenTransition == null) return;
- SystemUiProxy.INSTANCE.get(mLauncher).unregisterRemoteTransition(
+ SystemUiProxy.INSTANCE.getNoCreate().unregisterRemoteTransition(
mLauncherOpenTransition);
mLauncherOpenTransition = null;
mWallpaperOpenTransitionRunner = null;
}
- if (mBackAnimationController != null) {
- mBackAnimationController.unregisterBackCallbacks();
- mBackAnimationController = null;
- }
}
private boolean launcherIsATargetWithMode(RemoteAnimationTargetCompat[] targets, int mode) {
- for (RemoteAnimationTargetCompat target : targets) {
- if (target.mode == mode && target.taskInfo != null
- // Compare component name instead of task-id because transitions will promote
- // the target up to the root task while getTaskId returns the leaf.
- && target.taskInfo.topActivity != null
- && target.taskInfo.topActivity.equals(mLauncher.getComponentName())) {
- return true;
- }
- }
- return false;
- }
-
- private boolean hasMultipleTargetsWithMode(RemoteAnimationTargetCompat[] targets, int mode) {
- int numTargets = 0;
- for (RemoteAnimationTargetCompat target : targets) {
- if (target.mode == mode) {
- numTargets++;
- }
- if (numTargets > 1) {
- return true;
- }
- }
- return false;
+ return taskIsATargetWithMode(targets, mLauncher.getTaskId(), mode);
}
/**
@@ -1245,7 +1108,7 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
ValueAnimator unlockAnimator = ValueAnimator.ofFloat(0, 1);
unlockAnimator.setDuration(CLOSING_TRANSITION_DURATION_MS);
float cornerRadius = mDeviceProfile.isMultiWindowMode ? 0 :
- QuickStepContract.getWindowCornerRadius(mLauncher);
+ QuickStepContract.getWindowCornerRadius(mLauncher.getResources());
unlockAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
@@ -1275,187 +1138,10 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
}
/**
- * Returns view on launcher that corresponds to the closing app in the list of app targets
+ * Animator that controls the transformations of the windows the targets that are closing.
*/
- private @Nullable View findLauncherView(RemoteAnimationTargetCompat[] appTargets) {
- for (RemoteAnimationTargetCompat appTarget : appTargets) {
- if (appTarget.mode == MODE_CLOSING) {
- View launcherView = findLauncherView(appTarget);
- if (launcherView != null) {
- return launcherView;
- }
- }
- }
- return null;
- }
-
- /**
- * Returns view on launcher that corresponds to the {@param runningTaskTarget}.
- */
- private @Nullable View findLauncherView(RemoteAnimationTargetCompat runningTaskTarget) {
- if (runningTaskTarget == null || runningTaskTarget.taskInfo == null) {
- return null;
- }
-
- final ComponentName[] taskInfoActivities = new ComponentName[] {
- runningTaskTarget.taskInfo.baseActivity,
- runningTaskTarget.taskInfo.origActivity,
- runningTaskTarget.taskInfo.realActivity,
- runningTaskTarget.taskInfo.topActivity};
-
- String packageName = null;
- for (ComponentName component : taskInfoActivities) {
- if (component != null && component.getPackageName() != null) {
- packageName = component.getPackageName();
- break;
- }
- }
-
- if (packageName == null) {
- return null;
- }
-
- // Find the associated item info for the launch cookie (if available), note that predicted
- // apps actually have an id of -1, so use another default id here
- final ArrayList<IBinder> launchCookies = runningTaskTarget.taskInfo.launchCookies == null
- ? new ArrayList<>()
- : runningTaskTarget.taskInfo.launchCookies;
-
- int launchCookieItemId = NO_MATCHING_ID;
- for (IBinder cookie : launchCookies) {
- Integer itemId = ObjectWrapper.unwrap(cookie);
- if (itemId != null) {
- launchCookieItemId = itemId;
- break;
- }
- }
-
- return mLauncher.getFirstMatchForAppClose(launchCookieItemId, packageName,
- UserHandle.of(runningTaskTarget.taskInfo.userId), true /* supportsAllAppsState */);
- }
-
- private @NonNull RectF getDefaultWindowTargetRect() {
- RecentsView recentsView = mLauncher.getOverviewPanel();
- PagedOrientationHandler orientationHandler = recentsView.getPagedOrientationHandler();
- DeviceProfile dp = mLauncher.getDeviceProfile();
- final int halfIconSize = dp.iconSizePx / 2;
- float primaryDimension = orientationHandler
- .getPrimaryValue(dp.availableWidthPx, dp.availableHeightPx);
- float secondaryDimension = orientationHandler
- .getSecondaryValue(dp.availableWidthPx, dp.availableHeightPx);
- final float targetX = primaryDimension / 2f;
- final float targetY = secondaryDimension - dp.hotseatBarSizePx;
- return new RectF(targetX - halfIconSize, targetY - halfIconSize,
- targetX + halfIconSize, targetY + halfIconSize);
- }
-
- /**
- * Closing animator that animates the window into its final location on the workspace.
- */
- private RectFSpringAnim getClosingWindowAnimators(AnimatorSet animation,
- RemoteAnimationTargetCompat[] targets, View launcherView, PointF velocityPxPerS,
- RectF closingWindowStartRect, float startWindowCornerRadius) {
- FloatingIconView floatingIconView = null;
- FloatingWidgetView floatingWidget = null;
- RectF targetRect = new RectF();
-
- RemoteAnimationTargetCompat runningTaskTarget = null;
- boolean isTransluscent = false;
- for (RemoteAnimationTargetCompat target : targets) {
- if (target.mode == MODE_CLOSING) {
- runningTaskTarget = target;
- isTransluscent = runningTaskTarget.isTranslucent;
- break;
- }
- }
-
- // Get floating view and target rect.
- if (launcherView instanceof LauncherAppWidgetHostView) {
- Size windowSize = new Size(mDeviceProfile.availableWidthPx,
- mDeviceProfile.availableHeightPx);
- int fallbackBackgroundColor =
- FloatingWidgetView.getDefaultBackgroundColor(mLauncher, runningTaskTarget);
- floatingWidget = FloatingWidgetView.getFloatingWidgetView(mLauncher,
- (LauncherAppWidgetHostView) launcherView, targetRect, windowSize,
- mDeviceProfile.isMultiWindowMode ? 0 : getWindowCornerRadius(mLauncher),
- isTransluscent, fallbackBackgroundColor);
- } else if (launcherView != null) {
- floatingIconView = getFloatingIconView(mLauncher, launcherView,
- true /* hideOriginal */, targetRect, false /* isOpening */);
- } else {
- targetRect.set(getDefaultWindowTargetRect());
- }
-
- RectFSpringAnim anim = new RectFSpringAnim(closingWindowStartRect, targetRect, mLauncher,
- mDeviceProfile);
-
- // Hook up floating views to the closing window animators.
- final int rotationChange = getRotationChange(targets);
- Rect windowTargetBounds = getWindowTargetBounds(targets, rotationChange);
- if (floatingIconView != null) {
- anim.addAnimatorListener(floatingIconView);
- floatingIconView.setOnTargetChangeListener(anim::onTargetPositionChanged);
- floatingIconView.setFastFinishRunnable(anim::end);
- FloatingIconView finalFloatingIconView = floatingIconView;
-
- // We want the window alpha to be 0 once this threshold is met, so that the
- // FolderIconView can be seen morphing into the icon shape.
- final float windowAlphaThreshold = 1f - SHAPE_PROGRESS_DURATION;
-
- RectFSpringAnim.OnUpdateListener runner = new SpringAnimRunner(targets, targetRect,
- windowTargetBounds, startWindowCornerRadius) {
- @Override
- public void onUpdate(RectF currentRectF, float progress) {
- finalFloatingIconView.update(1f, 255 /* fgAlpha */, currentRectF, progress,
- windowAlphaThreshold, getCornerRadius(progress), false);
-
- super.onUpdate(currentRectF, progress);
- }
- };
- anim.addOnUpdateListener(runner);
- } else if (floatingWidget != null) {
- anim.addAnimatorListener(floatingWidget);
- floatingWidget.setOnTargetChangeListener(anim::onTargetPositionChanged);
- floatingWidget.setFastFinishRunnable(anim::end);
-
- final float floatingWidgetAlpha = isTransluscent ? 0 : 1;
- FloatingWidgetView finalFloatingWidget = floatingWidget;
- RectFSpringAnim.OnUpdateListener runner = new SpringAnimRunner(targets, targetRect,
- windowTargetBounds, startWindowCornerRadius) {
- @Override
- public void onUpdate(RectF currentRectF, float progress) {
- final float fallbackBackgroundAlpha =
- 1 - mapBoundToRange(progress, 0.8f, 1, 0, 1, EXAGGERATED_EASE);
- final float foregroundAlpha =
- mapBoundToRange(progress, 0.5f, 1, 0, 1, EXAGGERATED_EASE);
- finalFloatingWidget.update(currentRectF, floatingWidgetAlpha, foregroundAlpha,
- fallbackBackgroundAlpha, 1 - progress);
-
- super.onUpdate(currentRectF, progress);
- }
- };
- anim.addOnUpdateListener(runner);
- } else {
- // If no floating icon or widget is present, animate the to the default window
- // target rect.
- anim.addOnUpdateListener(new SpringAnimRunner(
- targets, targetRect, windowTargetBounds, startWindowCornerRadius));
- }
-
- // Use a fixed velocity to start the animation.
- animation.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationStart(Animator animation) {
- anim.start(mLauncher, velocityPxPerS);
- }
- });
- return anim;
- }
-
- /**
- * Closing window animator that moves the window down and offscreen.
- */
- private Animator getFallbackClosingWindowAnimators(RemoteAnimationTargetCompat[] appTargets) {
+ private Animator getClosingWindowAnimators(RemoteAnimationTargetCompat[] appTargets,
+ RemoteAnimationTargetCompat[] wallpaperTargets) {
final int rotationChange = getRotationChange(appTargets);
SurfaceTransactionApplier surfaceApplier = new SurfaceTransactionApplier(mDragLayer);
Matrix matrix = new Matrix();
@@ -1464,7 +1150,7 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
ValueAnimator closingAnimator = ValueAnimator.ofFloat(0, 1);
int duration = CLOSING_TRANSITION_DURATION_MS;
float windowCornerRadius = mDeviceProfile.isMultiWindowMode
- ? 0 : getWindowCornerRadius(mLauncher);
+ ? 0 : getWindowCornerRadius(mLauncher.getResources());
float startShadowRadius = areAllTargetsTranslucent(appTargets) ? 0 : mMaxShadowRadius;
closingAnimator.setDuration(duration);
closingAnimator.addUpdateListener(new MultiValueUpdateListener() {
@@ -1574,105 +1260,6 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
}
/**
- * Creates the {@link RectFSpringAnim} and {@link AnimatorSet} required to animate
- * the transition.
- */
- public Pair<RectFSpringAnim, AnimatorSet> createWallpaperOpenAnimations(
- RemoteAnimationTargetCompat[] appTargets,
- RemoteAnimationTargetCompat[] wallpaperTargets,
- boolean fromUnlock,
- RectF startRect,
- float startWindowCornerRadius) {
- AnimatorSet anim = null;
- RectFSpringAnim rectFSpringAnim = null;
-
- RemoteAnimationProvider provider = mRemoteAnimationProvider;
- if (provider != null) {
- anim = provider.createWindowAnimation(appTargets, wallpaperTargets);
- }
-
- if (anim == null) {
- anim = new AnimatorSet();
-
- final boolean launcherIsForceInvisibleOrOpening = mLauncher.isForceInvisible()
- || launcherIsATargetWithMode(appTargets, MODE_OPENING);
-
- View launcherView = findLauncherView(appTargets);
- boolean playFallBackAnimation = (launcherView == null
- && launcherIsForceInvisibleOrOpening)
- || mLauncher.getWorkspace().isOverlayShown()
- || hasMultipleTargetsWithMode(appTargets, MODE_CLOSING);
-
- boolean playWorkspaceReveal = true;
- boolean skipAllAppsScale = false;
- if (fromUnlock) {
- anim.play(getUnlockWindowAnimator(appTargets, wallpaperTargets));
- } else if (ENABLE_BACK_SWIPE_HOME_ANIMATION.get()
- && !playFallBackAnimation) {
- // Use a fixed velocity to start the animation.
- float velocityPxPerS = DynamicResource.provider(mLauncher)
- .getDimension(R.dimen.unlock_staggered_velocity_dp_per_s);
- PointF velocity = new PointF(0, -velocityPxPerS);
- rectFSpringAnim = getClosingWindowAnimators(
- anim, appTargets, launcherView, velocity, startRect,
- startWindowCornerRadius);
- if (!mLauncher.isInState(LauncherState.ALL_APPS)) {
- anim.play(new StaggeredWorkspaceAnim(mLauncher, velocity.y,
- true /* animateOverviewScrim */, launcherView).getAnimators());
-
- if (!areAllTargetsTranslucent(appTargets)) {
- anim.play(ObjectAnimator.ofFloat(mLauncher.getDepthController(), DEPTH,
- BACKGROUND_APP.getDepth(mLauncher), NORMAL.getDepth(mLauncher)));
- }
-
- // We play StaggeredWorkspaceAnim as a part of the closing window animation.
- playWorkspaceReveal = false;
- } else {
- // Skip scaling all apps, otherwise FloatingIconView will get wrong
- // layout bounds.
- skipAllAppsScale = true;
- }
- } else {
- anim.play(getFallbackClosingWindowAnimators(appTargets));
- }
-
- // Normally, we run the launcher content animation when we are transitioning
- // home, but if home is already visible, then we don't want to animate the
- // contents of launcher unless we know that we are animating home as a result
- // of the home button press with quickstep, which will result in launcher being
- // started on touch down, prior to the animation home (and won't be in the
- // targets list because it is already visible). In that case, we force
- // invisibility on touch down, and only reset it after the animation to home
- // is initialized.
- if (launcherIsForceInvisibleOrOpening) {
- addCujInstrumentation(
- anim, InteractionJankMonitorWrapper.CUJ_APP_CLOSE_TO_HOME);
- // Only register the content animation for cancellation when state changes
- mLauncher.getStateManager().setCurrentAnimation(anim);
-
- if (mLauncher.isInState(LauncherState.ALL_APPS)) {
- Pair<AnimatorSet, Runnable> contentAnimator =
- getLauncherContentAnimator(false, LAUNCHER_RESUME_START_DELAY,
- skipAllAppsScale);
- anim.play(contentAnimator.first);
- anim.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- contentAnimator.second.run();
- }
- });
- } else {
- if (playWorkspaceReveal) {
- anim.play(new WorkspaceRevealAnim(mLauncher, false).getAnimators());
- }
- }
- }
- }
-
- return new Pair(rectFSpringAnim, anim);
- }
-
- /**
* Remote animation runner for animation from the app to Launcher, including recents.
*/
protected class WallpaperOpenLauncherAnimationRunner implements RemoteAnimationFactory {
@@ -1693,23 +1280,70 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
LauncherAnimationRunner.AnimationResult result) {
if (mLauncher.isDestroyed()) {
AnimatorSet anim = new AnimatorSet();
- anim.play(getFallbackClosingWindowAnimators(appTargets));
+ anim.play(getClosingWindowAnimators(appTargets, wallpaperTargets));
result.setAnimation(anim, mLauncher.getApplicationContext());
return;
}
+ if (!mLauncher.hasBeenResumed()) {
+ // If launcher is not resumed, wait until new async-frame after resume
+ mLauncher.addOnResumeCallback(() ->
+ postAsyncCallback(mHandler, () ->
+ onCreateAnimation(transit, appTargets, wallpaperTargets,
+ nonAppTargets, result)));
+ return;
+ }
+
if (mLauncher.hasSomeInvisibleFlag(PENDING_INVISIBLE_BY_WALLPAPER_ANIMATION)) {
mLauncher.addForceInvisibleFlag(INVISIBLE_BY_PENDING_FLAGS);
mLauncher.getStateManager().moveToRestState();
}
- Pair<RectFSpringAnim, AnimatorSet> pair = createWallpaperOpenAnimations(
- appTargets, wallpaperTargets, mFromUnlock,
- new RectF(0, 0, mDeviceProfile.widthPx, mDeviceProfile.heightPx),
- QuickStepContract.getWindowCornerRadius(mLauncher));
+ AnimatorSet anim = null;
+ RemoteAnimationProvider provider = mRemoteAnimationProvider;
+ if (provider != null) {
+ anim = provider.createWindowAnimation(appTargets, wallpaperTargets);
+ }
+
+ if (anim == null) {
+ anim = new AnimatorSet();
+ anim.play(mFromUnlock
+ ? getUnlockWindowAnimator(appTargets, wallpaperTargets)
+ : getClosingWindowAnimators(appTargets, wallpaperTargets));
+
+ // Normally, we run the launcher content animation when we are transitioning
+ // home, but if home is already visible, then we don't want to animate the
+ // contents of launcher unless we know that we are animating home as a result
+ // of the home button press with quickstep, which will result in launcher being
+ // started on touch down, prior to the animation home (and won't be in the
+ // targets list because it is already visible). In that case, we force
+ // invisibility on touch down, and only reset it after the animation to home
+ // is initialized.
+ if (launcherIsATargetWithMode(appTargets, MODE_OPENING)
+ || mLauncher.isForceInvisible()) {
+ addCujInstrumentation(
+ anim, InteractionJankMonitorWrapper.CUJ_APP_CLOSE_TO_HOME);
+ // Only register the content animation for cancellation when state changes
+ mLauncher.getStateManager().setCurrentAnimation(anim);
+
+ if (mLauncher.isInState(LauncherState.ALL_APPS)) {
+ Pair<AnimatorSet, Runnable> contentAnimator =
+ getLauncherContentAnimator(false, LAUNCHER_RESUME_START_DELAY);
+ anim.play(contentAnimator.first);
+ anim.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ contentAnimator.second.run();
+ }
+ });
+ } else {
+ anim.play(new WorkspaceRevealAnim(mLauncher, false).getAnimators());
+ }
+ }
+ }
mLauncher.clearForceInvisibleFlag(INVISIBLE_ALL);
- result.setAnimation(pair.second, mLauncher);
+ result.setAnimation(anim, mLauncher);
}
}
@@ -1790,6 +1424,10 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
public final float dX;
public final float dY;
+ public final long xDuration;
+ public final long yDuration;
+ public final long alphaDuration;
+
public final float initialAppIconScale;
public final float finalAppIconScale;
@@ -1821,6 +1459,14 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
dX = centerX - launcherIconBounds.centerX();
dY = centerY - launcherIconBounds.centerY();
+ boolean useUpwardAnimation = launcherIconBounds.top > centerY
+ || Math.abs(dY) < dp.cellHeightPx;
+ xDuration = useUpwardAnimation ? APP_LAUNCH_CURVED_DURATION
+ : APP_LAUNCH_DOWN_DURATION;
+ yDuration = useUpwardAnimation ? APP_LAUNCH_DURATION
+ : APP_LAUNCH_DOWN_CURVED_DURATION;
+ alphaDuration = useUpwardAnimation ? APP_LAUNCH_ALPHA_DURATION
+ : APP_LAUNCH_ALPHA_DOWN_DURATION;
iconAlphaStart = hasSplashScreen && !hasDifferentAppIcon ? 0 : 1f;
final int windowIconSize = ResourceUtils.getDimenByName("starting_surface_icon_size",
@@ -1852,101 +1498,4 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
mTransitionManager.mTaskStartParams.put(taskId, Pair.create(supportedType, color));
}
}
-
- /**
- * RectFSpringAnim update listener to be used for app to home animation.
- */
- private class SpringAnimRunner implements RectFSpringAnim.OnUpdateListener {
- private final RemoteAnimationTargetCompat[] mAppTargets;
- private final Matrix mMatrix = new Matrix();
- private final Point mTmpPos = new Point();
- private final Rect mCurrentRect = new Rect();
- private final float mStartRadius;
- private final float mEndRadius;
- private final SurfaceTransactionApplier mSurfaceApplier;
- private final Rect mWindowTargetBounds = new Rect();
-
- private final Rect mTmpRect = new Rect();
-
- SpringAnimRunner(RemoteAnimationTargetCompat[] appTargets, RectF targetRect,
- Rect windowTargetBounds, float startWindowCornerRadius) {
- mAppTargets = appTargets;
- mStartRadius = startWindowCornerRadius;
- mEndRadius = Math.max(1, targetRect.width()) / 2f;
- mSurfaceApplier = new SurfaceTransactionApplier(mDragLayer);
- mWindowTargetBounds.set(windowTargetBounds);
- }
-
- public float getCornerRadius(float progress) {
- return Utilities.mapRange(progress, mStartRadius, mEndRadius);
- }
-
- @Override
- public void onUpdate(RectF currentRectF, float progress) {
- SurfaceParams[] params = new SurfaceParams[mAppTargets.length];
- for (int i = mAppTargets.length - 1; i >= 0; i--) {
- RemoteAnimationTargetCompat target = mAppTargets[i];
- SurfaceParams.Builder builder = new SurfaceParams.Builder(target.leash);
-
- if (target.localBounds != null) {
- mTmpPos.set(target.localBounds.left, target.localBounds.top);
- } else {
- mTmpPos.set(target.position.x, target.position.y);
- }
-
- if (target.mode == MODE_CLOSING) {
- currentRectF.round(mCurrentRect);
-
- // Scale the target window to match the currentRectF.
- final float scale;
-
- // We need to infer the crop (we crop the window to match the currentRectF).
- if (mWindowTargetBounds.height() > mWindowTargetBounds.width()) {
- scale = Math.min(1f, currentRectF.width() / mWindowTargetBounds.width());
-
- int unscaledHeight = (int) (mCurrentRect.height() * (1f / scale));
- int croppedHeight = mWindowTargetBounds.height() - unscaledHeight;
- mTmpRect.set(0, 0, mWindowTargetBounds.width(),
- mWindowTargetBounds.height() - croppedHeight);
- } else {
- scale = Math.min(1f, currentRectF.height() / mWindowTargetBounds.height());
-
- int unscaledWidth = (int) (mCurrentRect.width() * (1f / scale));
- int croppedWidth = mWindowTargetBounds.width() - unscaledWidth;
- mTmpRect.set(0, 0, mWindowTargetBounds.width() - croppedWidth,
- mWindowTargetBounds.height());
- }
-
- // Match size and position of currentRect.
- mMatrix.setScale(scale, scale);
- mMatrix.postTranslate(mCurrentRect.left, mCurrentRect.top);
-
- builder.withMatrix(mMatrix)
- .withWindowCrop(mTmpRect)
- .withAlpha(getWindowAlpha(progress))
- .withCornerRadius(getCornerRadius(progress) / scale);
- } else if (target.mode == MODE_OPENING) {
- mMatrix.setTranslate(mTmpPos.x, mTmpPos.y);
- builder.withMatrix(mMatrix)
- .withAlpha(1f);
- }
- params[i] = builder.build();
- }
- mSurfaceApplier.scheduleApply(params);
- }
-
- protected float getWindowAlpha(float progress) {
- // Alpha interpolates between [1, 0] between progress values [start, end]
- final float start = 0f;
- final float end = 0.85f;
-
- if (progress <= start) {
- return 1f;
- }
- if (progress >= end) {
- return 0f;
- }
- return Utilities.mapToRange(progress, start, end, 1, 0, ACCEL_1_5);
- }
- }
}
diff --git a/quickstep/src/com/android/launcher3/appprediction/AppsDividerView.java b/quickstep/src/com/android/launcher3/appprediction/AppsDividerView.java
index 0284ae4803..63a569a65c 100644
--- a/quickstep/src/com/android/launcher3/appprediction/AppsDividerView.java
+++ b/quickstep/src/com/android/launcher3/appprediction/AppsDividerView.java
@@ -16,7 +16,7 @@
package com.android.launcher3.appprediction;
-import static com.android.launcher3.util.OnboardingPrefs.ALL_APPS_VISITED_COUNT;
+import static com.android.launcher3.LauncherState.ALL_APPS;
import android.annotation.TargetApi;
import android.content.Context;
@@ -34,17 +34,23 @@ import androidx.annotation.ColorInt;
import androidx.core.content.ContextCompat;
import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.Launcher;
+import com.android.launcher3.LauncherState;
import com.android.launcher3.R;
import com.android.launcher3.allapps.FloatingHeaderRow;
import com.android.launcher3.allapps.FloatingHeaderView;
+import com.android.launcher3.statemanager.StateManager.StateListener;
import com.android.launcher3.util.Themes;
-import com.android.launcher3.views.ActivityContext;
/**
* A view which shows a horizontal divider
*/
@TargetApi(Build.VERSION_CODES.O)
-public class AppsDividerView extends View implements FloatingHeaderRow {
+public class AppsDividerView extends View implements StateListener<LauncherState>,
+ FloatingHeaderRow {
+
+ private static final String ALL_APPS_VISITED_COUNT = "launcher.all_apps_visited_count";
+ private static final int SHOW_ALL_APPS_LABEL_ON_ALL_APPS_VISITED_COUNT = 20;
public enum DividerType {
NONE,
@@ -52,6 +58,7 @@ public class AppsDividerView extends View implements FloatingHeaderRow {
ALL_APPS_LABEL
}
+ private final Launcher mLauncher;
private final TextPaint mPaint = new TextPaint();
private DividerType mDividerType = DividerType.NONE;
@@ -79,6 +86,7 @@ public class AppsDividerView extends View implements FloatingHeaderRow {
public AppsDividerView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
+ mLauncher = Launcher.getLauncher(context);
boolean isMainColorDark = Themes.getAttrBoolean(context, R.attr.isMainColorDark);
mDividerSize = new int[]{
@@ -93,9 +101,6 @@ public class AppsDividerView extends View implements FloatingHeaderRow {
mAllAppsLabelTextColor = ContextCompat.getColor(context, isMainColorDark
? R.color.all_apps_label_text_dark
: R.color.all_apps_label_text);
-
- mShowAllAppsLabel = !ActivityContext.lookupContext(
- getContext()).getOnboardingPrefs().hasReachedMaxCount(ALL_APPS_VISITED_COUNT);
}
public void setup(FloatingHeaderView parent, FloatingHeaderRow[] rows, boolean tabsHidden) {
@@ -105,14 +110,6 @@ public class AppsDividerView extends View implements FloatingHeaderRow {
updateDividerType();
}
- /** {@code true} if all apps label should be shown in place of divider. */
- public void setShowAllAppsLabel(boolean showAllAppsLabel) {
- if (showAllAppsLabel != mShowAllAppsLabel) {
- mShowAllAppsLabel = showAllAppsLabel;
- updateDividerType();
- }
- }
-
@Override
public int getExpectedHeight() {
return getPaddingTop() + getPaddingBottom();
@@ -194,7 +191,7 @@ public class AppsDividerView extends View implements FloatingHeaderRow {
@Override
protected void onDraw(Canvas canvas) {
if (mDividerType == DividerType.LINE) {
- int l = (getWidth() - mDividerSize[0]) / 2;
+ int l = (getWidth() - getPaddingLeft() - mDividerSize[0]) / 2;
int t = getHeight() - (getPaddingBottom() / 2);
int radius = mDividerSize[1];
canvas.drawRoundRect(l, t, l + mDividerSize[0], t + mDividerSize[1], radius, radius,
@@ -212,7 +209,7 @@ public class AppsDividerView extends View implements FloatingHeaderRow {
private Layout getAllAppsLabelLayout() {
if (mAllAppsLabelLayout == null) {
mPaint.setAntiAlias(true);
- mPaint.setTypeface(Typeface.create("google-sans", Typeface.NORMAL));
+ mPaint.setTypeface(Typeface.create("sans-serif-medium", Typeface.NORMAL));
mPaint.setTextSize(
getResources().getDimensionPixelSize(R.dimen.all_apps_label_text_size));
@@ -239,8 +236,54 @@ public class AppsDividerView extends View implements FloatingHeaderRow {
}
@Override
+ protected void onAttachedToWindow() {
+ super.onAttachedToWindow();
+
+ if (shouldShowAllAppsLabel()) {
+ mShowAllAppsLabel = true;
+ mLauncher.getStateManager().addStateListener(this);
+ updateDividerType();
+ }
+ }
+
+ @Override
+ protected void onDetachedFromWindow() {
+ super.onDetachedFromWindow();
+ mLauncher.getStateManager().removeStateListener(this);
+ }
+
+ @Override
+ public void onStateTransitionComplete(LauncherState finalState) {
+ if (finalState == ALL_APPS) {
+ setAllAppsVisitedCount(getAllAppsVisitedCount() + 1);
+ } else {
+ if (mShowAllAppsLabel != shouldShowAllAppsLabel()) {
+ mShowAllAppsLabel = !mShowAllAppsLabel;
+ updateDividerType();
+ }
+
+ if (!mShowAllAppsLabel) {
+ mLauncher.getStateManager().removeStateListener(this);
+ }
+ }
+ }
+
+ private void setAllAppsVisitedCount(int count) {
+ mLauncher.getSharedPrefs().edit().putInt(ALL_APPS_VISITED_COUNT, count).apply();
+ }
+
+ private int getAllAppsVisitedCount() {
+ return mLauncher.getSharedPrefs().getInt(ALL_APPS_VISITED_COUNT, 0);
+ }
+
+ private boolean shouldShowAllAppsLabel() {
+ return getAllAppsVisitedCount() < SHOW_ALL_APPS_LABEL_ON_ALL_APPS_VISITED_COUNT;
+ }
+
+ @Override
public void setInsets(Rect insets, DeviceProfile grid) {
- int leftRightPadding = grid.allAppsLeftRightPadding;
+ int leftRightPadding = grid.desiredWorkspaceLeftRightMarginPx
+ + grid.cellLayoutPaddingLeftRightPx;
setPadding(leftRightPadding, getPaddingTop(), leftRightPadding, getPaddingBottom());
}
diff --git a/quickstep/src/com/android/launcher3/appprediction/InstantAppItemInfo.java b/quickstep/src/com/android/launcher3/appprediction/InstantAppItemInfo.java
index 9c3b8816cb..6c4c601b45 100644
--- a/quickstep/src/com/android/launcher3/appprediction/InstantAppItemInfo.java
+++ b/quickstep/src/com/android/launcher3/appprediction/InstantAppItemInfo.java
@@ -19,7 +19,6 @@ package com.android.launcher3.appprediction;
import static com.android.quickstep.InstantAppResolverImpl.COMPONENT_CLASS_MARKER;
import android.content.ComponentName;
-import android.content.Context;
import android.content.Intent;
import com.android.launcher3.LauncherSettings;
@@ -39,8 +38,8 @@ public class InstantAppItemInfo extends AppInfo {
}
@Override
- public WorkspaceItemInfo makeWorkspaceItem(Context context) {
- WorkspaceItemInfo workspaceItemInfo = super.makeWorkspaceItem(context);
+ public WorkspaceItemInfo makeWorkspaceItem() {
+ WorkspaceItemInfo workspaceItemInfo = super.makeWorkspaceItem();
workspaceItemInfo.itemType = LauncherSettings.Favorites.ITEM_TYPE_APPLICATION;
workspaceItemInfo.status = WorkspaceItemInfo.FLAG_AUTOINSTALL_ICON
| WorkspaceItemInfo.FLAG_RESTORE_STARTED
diff --git a/quickstep/src/com/android/launcher3/appprediction/PredictionRowView.java b/quickstep/src/com/android/launcher3/appprediction/PredictionRowView.java
index 1dec73721c..6afbf9a28c 100644
--- a/quickstep/src/com/android/launcher3/appprediction/PredictionRowView.java
+++ b/quickstep/src/com/android/launcher3/appprediction/PredictionRowView.java
@@ -31,8 +31,8 @@ import androidx.annotation.Nullable;
import com.android.launcher3.BubbleTextView;
import com.android.launcher3.DeviceProfile;
-import com.android.launcher3.DeviceProfile.DeviceProfileListenable;
import com.android.launcher3.DeviceProfile.OnDeviceProfileChangeListener;
+import com.android.launcher3.Launcher;
import com.android.launcher3.R;
import com.android.launcher3.allapps.FloatingHeaderRow;
import com.android.launcher3.allapps.FloatingHeaderView;
@@ -43,18 +43,17 @@ import com.android.launcher3.keyboard.FocusIndicatorHelper.SimpleFocusIndicatorH
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.ItemInfoWithIcon;
import com.android.launcher3.model.data.WorkspaceItemInfo;
+import com.android.launcher3.touch.ItemClickHandler;
import com.android.launcher3.touch.ItemLongClickListener;
-import com.android.launcher3.views.ActivityContext;
import java.util.ArrayList;
import java.util.List;
-import java.util.stream.Collectors;
@TargetApi(Build.VERSION_CODES.P)
-public class PredictionRowView<T extends Context & ActivityContext & DeviceProfileListenable>
- extends LinearLayout implements OnDeviceProfileChangeListener, FloatingHeaderRow {
+public class PredictionRowView extends LinearLayout implements
+ OnDeviceProfileChangeListener, FloatingHeaderRow {
- private final T mActivityContext;
+ private final Launcher mLauncher;
private int mNumPredictedAppsPerRow;
// Helper to drawing the focus indicator.
@@ -64,10 +63,12 @@ public class PredictionRowView<T extends Context & ActivityContext & DeviceProfi
private final List<WorkspaceItemInfo> mPredictedApps = new ArrayList<>();
private FloatingHeaderView mParent;
+ private boolean mScrolledOut;
private boolean mPredictionsEnabled = false;
- private @Nullable List<ItemInfo> mPendingPredictedItems;
- private OnLongClickListener mOnIconLongClickListener = ItemLongClickListener.INSTANCE_ALL_APPS;
+
+ @Nullable
+ private List<ItemInfo> mPendingPredictedItems;
public PredictionRowView(@NonNull Context context) {
this(context, null);
@@ -78,9 +79,9 @@ public class PredictionRowView<T extends Context & ActivityContext & DeviceProfi
setOrientation(LinearLayout.HORIZONTAL);
mFocusHelper = new SimpleFocusIndicatorHelper(this);
- mActivityContext = ActivityContext.lookupContext(context);
- mActivityContext.addOnDeviceProfileChangeListener(this);
- mNumPredictedAppsPerRow = mActivityContext.getDeviceProfile().numShownAllAppsColumns;
+ mLauncher = Launcher.getLauncher(context);
+ mLauncher.addOnDeviceProfileChangeListener(this);
+ mNumPredictedAppsPerRow = mLauncher.getDeviceProfile().numShownAllAppsColumns;
updateVisibility();
}
@@ -95,11 +96,11 @@ public class PredictionRowView<T extends Context & ActivityContext & DeviceProfi
private void updateVisibility() {
setVisibility(mPredictionsEnabled ? VISIBLE : GONE);
- if (mActivityContext.getAppsView() != null) {
+ if (mLauncher.getAppsView() != null) {
if (mPredictionsEnabled) {
- mActivityContext.getAppsView().getAppsStore().registerIconContainer(this);
+ mLauncher.getAppsView().getAppsStore().registerIconContainer(this);
} else {
- mActivityContext.getAppsView().getAppsStore().unregisterIconContainer(this);
+ mLauncher.getAppsView().getAppsStore().unregisterIconContainer(this);
}
}
}
@@ -118,9 +119,9 @@ public class PredictionRowView<T extends Context & ActivityContext & DeviceProfi
@Override
public int getExpectedHeight() {
- return getVisibility() == GONE ? 0
- : mActivityContext.getDeviceProfile().allAppsCellHeightPx + getPaddingTop()
- + getPaddingBottom();
+ return getVisibility() == GONE ? 0 :
+ Launcher.getLauncher(getContext()).getDeviceProfile().allAppsCellHeightPx
+ + getPaddingTop() + getPaddingBottom();
}
@Override
@@ -156,33 +157,26 @@ public class PredictionRowView<T extends Context & ActivityContext & DeviceProfi
*/
public void setPredictedApps(List<ItemInfo> items) {
if (!FeatureFlags.ENABLE_APP_PREDICTIONS_WHILE_VISIBLE.get()
- && !mActivityContext.isBindingItems()
+ && !mLauncher.isWorkspaceLoading()
&& isShown()
&& getWindowVisibility() == View.VISIBLE) {
mPendingPredictedItems = items;
return;
}
+
applyPredictedApps(items);
}
private void applyPredictedApps(List<ItemInfo> items) {
mPendingPredictedItems = null;
mPredictedApps.clear();
- mPredictedApps.addAll(items.stream()
+ items.stream()
.filter(itemInfo -> itemInfo instanceof WorkspaceItemInfo)
- .map(itemInfo -> (WorkspaceItemInfo) itemInfo).collect(Collectors.toList()));
+ .map(itemInfo -> (WorkspaceItemInfo) itemInfo)
+ .forEach(mPredictedApps::add);
applyPredictionApps();
}
- /**
- * Sets the long click listener for predictions for any future predictions.
- *
- * Existing predictions in the container are not updated with this new callback.
- */
- public void setOnIconLongClickListener(OnLongClickListener onIconLongClickListener) {
- mOnIconLongClickListener = onIconLongClickListener;
- }
-
@Override
public void onDeviceProfileChanged(DeviceProfile dp) {
mNumPredictedAppsPerRow = dp.numShownAllAppsColumns;
@@ -195,18 +189,18 @@ public class PredictionRowView<T extends Context & ActivityContext & DeviceProfi
while (getChildCount() > mNumPredictedAppsPerRow) {
removeViewAt(0);
}
- LayoutInflater inflater = mActivityContext.getAppsView().getLayoutInflater();
+ LayoutInflater inflater = mLauncher.getAppsView().getLayoutInflater();
while (getChildCount() < mNumPredictedAppsPerRow) {
BubbleTextView icon = (BubbleTextView) inflater.inflate(
R.layout.all_apps_icon, this, false);
- icon.setOnClickListener(mActivityContext.getItemOnClickListener());
- icon.setOnLongClickListener(mOnIconLongClickListener);
+ icon.setOnClickListener(ItemClickHandler.INSTANCE);
+ icon.setOnLongClickListener(ItemLongClickListener.INSTANCE_ALL_APPS);
icon.setLongPressTimeoutFactor(1f);
icon.setOnFocusChangeListener(mFocusHelper);
LayoutParams lp = (LayoutParams) icon.getLayoutParams();
// Ensure the all apps icon height matches the workspace icons in portrait mode.
- lp.height = mActivityContext.getDeviceProfile().allAppsCellHeightPx;
+ lp.height = mLauncher.getDeviceProfile().allAppsCellHeightPx;
lp.width = 0;
lp.weight = 1;
addView(icon);
@@ -229,6 +223,7 @@ public class PredictionRowView<T extends Context & ActivityContext & DeviceProfi
boolean predictionsEnabled = predictionCount > 0;
if (predictionsEnabled != mPredictionsEnabled) {
mPredictionsEnabled = predictionsEnabled;
+ mLauncher.reapplyUi(false /* cancelCurrentAnimation */);
updateVisibility();
}
mParent.onHeightUpdated();
@@ -242,10 +237,11 @@ public class PredictionRowView<T extends Context & ActivityContext & DeviceProfi
@Override
public void setVerticalScroll(int scroll, boolean isScrolledOut) {
+ mScrolledOut = isScrolledOut;
if (!isScrolledOut) {
setTranslationY(scroll);
}
- setAlpha(isScrolledOut ? 0 : 1);
+ setAlpha(mScrolledOut ? 0 : 1);
if (getVisibility() != GONE) {
AlphaUpdateListener.updateVisibility(this);
}
@@ -253,7 +249,8 @@ public class PredictionRowView<T extends Context & ActivityContext & DeviceProfi
@Override
public void setInsets(Rect insets, DeviceProfile grid) {
- int leftRightPadding = grid.allAppsLeftRightPadding;
+ int leftRightPadding = grid.desiredWorkspaceLeftRightMarginPx
+ + grid.cellLayoutPaddingLeftRightPx;
setPadding(leftRightPadding, getPaddingTop(), leftRightPadding, getPaddingBottom());
}
@@ -267,7 +264,6 @@ public class PredictionRowView<T extends Context & ActivityContext & DeviceProfi
return getChildAt(0);
}
-
@Override
public void onVisibilityAggregated(boolean isVisible) {
super.onVisibilityAggregated(isVisible);
diff --git a/quickstep/src/com/android/launcher3/hybridhotseat/HotseatEduActivity.java b/quickstep/src/com/android/launcher3/hybridhotseat/HotseatEduActivity.java
new file mode 100644
index 0000000000..3a7d821ed6
--- /dev/null
+++ b/quickstep/src/com/android/launcher3/hybridhotseat/HotseatEduActivity.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2020 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.launcher3.hybridhotseat;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+
+import com.android.launcher3.BaseActivity;
+import com.android.launcher3.Launcher;
+import com.android.launcher3.uioverrides.QuickstepLauncher;
+import com.android.launcher3.util.ActivityTracker;
+
+/**
+ * Proxy activity to return user to home screen and show halfsheet education
+ */
+public class HotseatEduActivity extends Activity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ Intent homeIntent = new Intent(Intent.ACTION_MAIN)
+ .addCategory(Intent.CATEGORY_HOME)
+ .setPackage(getPackageName())
+ .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+
+ Launcher.ACTIVITY_TRACKER.registerCallback(new HotseatActivityTracker());
+ startActivity(homeIntent);
+ finish();
+ }
+
+ static class HotseatActivityTracker<T extends QuickstepLauncher> implements
+ ActivityTracker.SchedulerCallback {
+
+ @Override
+ public boolean init(BaseActivity activity, boolean alreadyOnHome) {
+ QuickstepLauncher launcher = (QuickstepLauncher) activity;
+ if (launcher != null) {
+ launcher.getHotseatPredictionController().showEdu();
+ }
+ return false;
+ }
+
+ }
+}
diff --git a/quickstep/src/com/android/launcher3/hybridhotseat/HotseatEduController.java b/quickstep/src/com/android/launcher3/hybridhotseat/HotseatEduController.java
index d63bc18a33..a6844e48b7 100644
--- a/quickstep/src/com/android/launcher3/hybridhotseat/HotseatEduController.java
+++ b/quickstep/src/com/android/launcher3/hybridhotseat/HotseatEduController.java
@@ -15,22 +15,18 @@
*/
package com.android.launcher3.hybridhotseat;
-import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_HOTSEAT_EDU_ONLY_TIP;
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent
+ .LAUNCHER_HOTSEAT_EDU_ONLY_TIP;
import android.content.Intent;
-import android.graphics.Rect;
-import android.util.Log;
-import android.view.Gravity;
import android.view.View;
-import com.android.launcher3.BubbleTextView;
import com.android.launcher3.CellLayout;
import com.android.launcher3.Hotseat;
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherSettings;
import com.android.launcher3.R;
-import com.android.launcher3.Utilities;
import com.android.launcher3.Workspace;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.model.data.FolderInfo;
@@ -51,8 +47,6 @@ import java.util.stream.IntStream;
*/
public class HotseatEduController {
- private static final String TAG = "HotseatEduController";
-
public static final String SETTINGS_ACTION =
"android.settings.ACTION_CONTENT_SUGGESTIONS_SETTINGS";
@@ -131,7 +125,7 @@ public class HotseatEduController {
private int placeFoldersInWorkspace(ArrayDeque<FolderInfo> folders) {
if (folders.isEmpty()) return 0;
- Workspace<?> workspace = mLauncher.getWorkspace();
+ Workspace workspace = mLauncher.getWorkspace();
InvariantDeviceProfile idp = mLauncher.getDeviceProfile().inv;
GridOccupancy[] occupancyList = new GridOccupancy[workspace.getChildCount()];
@@ -176,7 +170,7 @@ public class HotseatEduController {
* @return pageId where items are migrated
*/
private int migrateHotseatWhole() {
- Workspace<?> workspace = mLauncher.getWorkspace();
+ Workspace workspace = mLauncher.getWorkspace();
int pageId = -1;
int toRow = 0;
@@ -194,12 +188,8 @@ public class HotseatEduController {
.getInt(LauncherSettings.Settings.EXTRA_VALUE);
mNewScreens = IntArray.wrap(pageId);
}
- boolean isPortrait = !mLauncher.getDeviceProfile().isVerticalBarLayout();
- int hotseatItemsNum = mLauncher.getDeviceProfile().numShownHotseatIcons;
- for (int i = 0; i < hotseatItemsNum; i++) {
- int x = isPortrait ? i : 0;
- int y = isPortrait ? 0 : hotseatItemsNum - i - 1;
- View child = mHotseat.getChildAt(x, y);
+ for (int i = 0; i < mLauncher.getDeviceProfile().numShownHotseatIcons; i++) {
+ View child = mHotseat.getChildAt(i, 0);
if (child == null || child.getTag() == null) continue;
ItemInfo tag = (ItemInfo) child.getTag();
if (tag.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT_PREDICTION) continue;
@@ -239,7 +229,8 @@ public class HotseatEduController {
R.string.hotseat_prediction_settings, null,
() -> mLauncher.startActivity(getSettingsIntent()));
} else {
- showHotseatArrowTip(true, mLauncher.getString(R.string.hotseat_tip_no_empty_slots));
+ new ArrowTipView(mLauncher).show(
+ mLauncher.getString(R.string.hotseat_tip_no_empty_slots), mHotseat.getTop());
}
}
@@ -260,50 +251,15 @@ public class HotseatEduController {
if (requiresMigration && canMigrateToFirstPage) {
showDialog();
} else {
- if (showHotseatArrowTip(requiresMigration, mLauncher.getString(
+ new ArrowTipView(mLauncher).show(mLauncher.getString(
requiresMigration ? R.string.hotseat_tip_no_empty_slots
- : R.string.hotseat_auto_enrolled))) {
- mLauncher.getStatsLogManager().logger().log(LAUNCHER_HOTSEAT_EDU_ONLY_TIP);
- }
+ : R.string.hotseat_auto_enrolled),
+ mHotseat.getTop());
+ mLauncher.getStatsLogManager().logger().log(LAUNCHER_HOTSEAT_EDU_ONLY_TIP);
finishOnboarding();
}
}
- /**
- * Finds a child suitable child in hotseat and shows arrow tip pointing at it.
- *
- * @param usePinned used to determine target view. If true, will use the first matching pinned
- * item. Otherwise, will use the first predicted child
- * @param message String to be shown inside the arrowView
- * @return whether suitable child was found and tip was shown
- */
- private boolean showHotseatArrowTip(boolean usePinned, String message) {
- int childCount = mHotseat.getShortcutsAndWidgets().getChildCount();
- boolean isPortrait = !mLauncher.getDeviceProfile().isVerticalBarLayout();
-
- BubbleTextView tipTargetView = null;
- for (int i = childCount - 1; i > -1; i--) {
- int x = isPortrait ? i : 0;
- int y = isPortrait ? 0 : i;
- View v = mHotseat.getShortcutsAndWidgets().getChildAt(x, y);
- if (v instanceof BubbleTextView && v.getTag() instanceof WorkspaceItemInfo) {
- ItemInfo info = (ItemInfo) v.getTag();
- boolean isPinned = info.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT;
- if (isPinned == usePinned) {
- tipTargetView = (BubbleTextView) v;
- break;
- }
- }
- }
- if (tipTargetView == null) {
- Log.e(TAG, "Unable to find suitable view for ArrowTip");
- return false;
- }
- Rect bounds = Utilities.getViewBounds(tipTargetView);
- new ArrowTipView(mLauncher).show(message, Gravity.END, bounds.centerX(), bounds.top);
- return true;
- }
-
void showDialog() {
if (mPredictedApps == null || mPredictedApps.isEmpty()) {
return;
diff --git a/quickstep/src/com/android/launcher3/hybridhotseat/HotseatEduDialog.java b/quickstep/src/com/android/launcher3/hybridhotseat/HotseatEduDialog.java
index 119ae907f7..14b0c5dd62 100644
--- a/quickstep/src/com/android/launcher3/hybridhotseat/HotseatEduDialog.java
+++ b/quickstep/src/com/android/launcher3/hybridhotseat/HotseatEduDialog.java
@@ -28,20 +28,17 @@ import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
-import android.widget.LinearLayout;
import android.widget.TextView;
import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.CellLayout;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Insettable;
-import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.Launcher;
import com.android.launcher3.R;
import com.android.launcher3.anim.Interpolators;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.model.data.WorkspaceItemInfo;
-import com.android.launcher3.uioverrides.ApiWrapper;
import com.android.launcher3.uioverrides.PredictedAppIcon;
import com.android.launcher3.views.AbstractSlideInView;
@@ -80,11 +77,6 @@ public class HotseatEduDialog extends AbstractSlideInView<Launcher> implements I
mContent = this;
}
- @Override
- protected void onLayout(boolean changed, int l, int t, int r, int b) {
- super.onLayout(changed, l, t, r, b);
- setTranslationShift(TRANSLATION_SHIFT_CLOSED);
- }
@Override
protected void onFinishInflate() {
@@ -92,9 +84,8 @@ public class HotseatEduDialog extends AbstractSlideInView<Launcher> implements I
mHotseatWrapper = findViewById(R.id.hotseat_wrapper);
mSampleHotseat = findViewById(R.id.sample_prediction);
- Context context = getContext();
DeviceProfile grid = mActivityContext.getDeviceProfile();
- Rect padding = grid.getHotseatLayoutPadding(context);
+ Rect padding = grid.getHotseatLayoutPadding();
mSampleHotseat.getLayoutParams().height = grid.cellHeightPx;
mSampleHotseat.setGridSize(grid.numShownHotseatIcons, 1);
@@ -106,15 +97,6 @@ public class HotseatEduDialog extends AbstractSlideInView<Launcher> implements I
mDismissBtn = findViewById(R.id.no_thanks);
mDismissBtn.setOnClickListener(this::onDismiss);
- LinearLayout buttonContainer = findViewById(R.id.button_container);
- int adjustedMarginEnd = ApiWrapper.getHotseatEndOffset(context)
- - buttonContainer.getPaddingEnd();
- if (InvariantDeviceProfile.INSTANCE.get(context)
- .getDeviceProfile(context).isTaskbarPresent && adjustedMarginEnd > 0) {
- ((LinearLayout.LayoutParams) buttonContainer.getLayoutParams()).setMarginEnd(
- adjustedMarginEnd);
- }
-
// update ui to reflect which migration method is going to be used
if (FeatureFlags.HOTSEAT_MIGRATE_TO_FOLDER.get()) {
((TextView) findViewById(R.id.hotseat_edu_content)).setText(
@@ -218,9 +200,9 @@ public class HotseatEduDialog extends AbstractSlideInView<Launcher> implements I
}
AbstractFloatingView.closeAllOpenViews(mActivityContext);
attachToContainer();
+ mActivityContext.getStatsLogManager().logger().log(LAUNCHER_HOTSEAT_EDU_SEEN);
animateOpen();
populatePreview(predictions);
- mActivityContext.getStatsLogManager().logger().log(LAUNCHER_HOTSEAT_EDU_SEEN);
}
/**
diff --git a/quickstep/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java b/quickstep/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java
index 05b81671c3..85e5ab0a9b 100644
--- a/quickstep/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java
+++ b/quickstep/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java
@@ -56,12 +56,12 @@ import com.android.launcher3.touch.ItemLongClickListener;
import com.android.launcher3.uioverrides.PredictedAppIcon;
import com.android.launcher3.uioverrides.QuickstepLauncher;
import com.android.launcher3.util.OnboardingPrefs;
+import com.android.launcher3.views.ArrowTipView;
import com.android.launcher3.views.Snackbar;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
-import java.util.function.Predicate;
import java.util.stream.Collectors;
/**
@@ -152,15 +152,38 @@ public class HotseatPredictionController implements DragController.DragListener,
*/
public void showEdu() {
mLauncher.getStateManager().goToState(NORMAL, true, forSuccessCallback(() -> {
- HotseatEduController eduController = new HotseatEduController(mLauncher);
- eduController.setPredictedApps(mPredictedItems.stream()
- .map(i -> (WorkspaceItemInfo) i)
- .collect(Collectors.toList()));
- eduController.showEdu();
+ if (mPredictedItems.isEmpty()) {
+ // launcher has empty predictions set
+ Snackbar.show(mLauncher, R.string.hotsaet_tip_prediction_disabled,
+ R.string.hotseat_prediction_settings, null,
+ () -> mLauncher.startActivity(getSettingsIntent()));
+ } else if (getPredictedIcons().size() >= (mHotSeatItemsCount + 1) / 2) {
+ showDiscoveryTip();
+ } else {
+ HotseatEduController eduController = new HotseatEduController(mLauncher);
+ eduController.setPredictedApps(mPredictedItems.stream()
+ .map(i -> (WorkspaceItemInfo) i)
+ .collect(Collectors.toList()));
+ eduController.showEdu();
+ }
}));
}
/**
+ * Shows educational tip for hotseat if user does not go through Tips app.
+ */
+ private void showDiscoveryTip() {
+ if (getPredictedIcons().isEmpty()) {
+ new ArrowTipView(mLauncher).show(
+ mLauncher.getString(R.string.hotseat_tip_no_empty_slots), mHotseat.getTop());
+ } else {
+ Snackbar.show(mLauncher, R.string.hotseat_tip_gaps_filled,
+ R.string.hotseat_prediction_settings, null,
+ () -> mLauncher.startActivity(getSettingsIntent()));
+ }
+ }
+
+ /**
* Returns if hotseat client has predictions
*/
public boolean hasPredictions() {
@@ -177,7 +200,6 @@ public class HotseatPredictionController implements DragController.DragListener,
}
int predictionIndex = 0;
- int numViewsAnimated = 0;
ArrayList<WorkspaceItemInfo> newItems = new ArrayList<>();
// make sure predicted icon removal and filling predictions don't step on each other
if (mIconRemoveAnimators != null && mIconRemoveAnimators.isRunning()) {
@@ -211,11 +233,7 @@ public class HotseatPredictionController implements DragController.DragListener,
(WorkspaceItemInfo) mPredictedItems.get(predictionIndex++);
if (isPredictedIcon(child) && child.isEnabled()) {
PredictedAppIcon icon = (PredictedAppIcon) child;
- boolean animateIconChange = icon.shouldAnimateIconChange(predictedItem);
- icon.applyFromWorkspaceItem(predictedItem, animateIconChange, numViewsAnimated);
- if (animateIconChange) {
- numViewsAnimated++;
- }
+ icon.applyFromWorkspaceItem(predictedItem);
icon.finishBinding(mPredictionLongClickListener);
} else {
newItems.add(predictedItem);
@@ -244,6 +262,10 @@ public class HotseatPredictionController implements DragController.DragListener,
} else {
removeOutlineDrawings();
}
+
+ if (mLauncher.getTaskbarUIController() != null) {
+ mLauncher.getTaskbarUIController().onHotseatUpdated();
+ }
}
private void removeOutlineDrawings() {
@@ -409,11 +431,11 @@ public class HotseatPredictionController implements DragController.DragListener,
@Nullable
@Override
public SystemShortcut<QuickstepLauncher> getShortcut(QuickstepLauncher activity,
- ItemInfo itemInfo, View originalView) {
+ ItemInfo itemInfo) {
if (itemInfo.container != LauncherSettings.Favorites.CONTAINER_HOTSEAT_PREDICTION) {
return null;
}
- return new PinPrediction(activity, itemInfo, originalView);
+ return new PinPrediction(activity, itemInfo);
}
private void preparePredictionInfo(WorkspaceItemInfo itemInfo, int rank) {
@@ -474,33 +496,11 @@ public class HotseatPredictionController implements DragController.DragListener,
.log(LAUNCHER_HOTSEAT_RANKED);
}
- /**
- * Called when app/shortcut icon is removed by system. This is used to prune visible stale
- * predictions while while waiting for AppAPrediction service to send new batch of predictions.
- *
- * @param matcher filter matching items that have been removed
- */
- public void onModelItemsRemoved(Predicate<ItemInfo> matcher) {
- if (mPredictedItems.removeIf(matcher)) {
- fillGapsWithPrediction(true);
- }
- }
-
- /**
- * Called when user completes adding item requiring a config activity to the hotseat
- */
- public void onDeferredDrop(int cellX, int cellY) {
- View child = mHotseat.getChildAt(cellX, cellY);
- if (child instanceof PredictedAppIcon) {
- removeIconWithoutNotify((PredictedAppIcon) child);
- }
- }
-
private class PinPrediction extends SystemShortcut<QuickstepLauncher> {
- private PinPrediction(QuickstepLauncher target, ItemInfo itemInfo, View originalView) {
+ private PinPrediction(QuickstepLauncher target, ItemInfo itemInfo) {
super(R.drawable.ic_pin, R.string.pin_prediction, target,
- itemInfo, originalView);
+ itemInfo);
}
@Override
diff --git a/quickstep/src/com/android/launcher3/hybridhotseat/HotseatPredictionModel.java b/quickstep/src/com/android/launcher3/hybridhotseat/HotseatPredictionModel.java
index 56945ba0a6..080633a653 100644
--- a/quickstep/src/com/android/launcher3/hybridhotseat/HotseatPredictionModel.java
+++ b/quickstep/src/com/android/launcher3/hybridhotseat/HotseatPredictionModel.java
@@ -16,25 +16,33 @@
package com.android.launcher3.hybridhotseat;
import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_HOTSEAT_PREDICTION;
-import static com.android.launcher3.model.PredictionHelper.getAppTargetFromItemInfo;
-import static com.android.launcher3.model.PredictionHelper.isTrackedForHotseatPrediction;
-import static com.android.launcher3.model.PredictionHelper.wrapAppTargetWithItemLocation;
import android.app.prediction.AppTarget;
import android.app.prediction.AppTargetEvent;
+import android.app.prediction.AppTargetId;
+import android.content.ComponentName;
import android.content.Context;
import android.os.Bundle;
+import com.android.launcher3.LauncherSettings;
+import com.android.launcher3.Workspace;
import com.android.launcher3.model.BgDataModel;
import com.android.launcher3.model.BgDataModel.FixedContainerItems;
import com.android.launcher3.model.data.ItemInfo;
+import com.android.launcher3.model.data.LauncherAppWidgetInfo;
+import com.android.launcher3.model.data.WorkspaceItemInfo;
+import com.android.launcher3.shortcuts.ShortcutKey;
import java.util.ArrayList;
+import java.util.Locale;
/**
* Model helper for app predictions in workspace
*/
public class HotseatPredictionModel {
+ private static final String APP_LOCATION_HOTSEAT = "hotseat";
+ private static final String APP_LOCATION_WORKSPACE = "workspace";
+
private static final String BUNDLE_KEY_PIN_EVENTS = "pin_events";
private static final String BUNDLE_KEY_CURRENT_ITEMS = "current_items";
@@ -46,15 +54,15 @@ public class HotseatPredictionModel {
ArrayList<AppTargetEvent> events = new ArrayList<>();
ArrayList<ItemInfo> workspaceItems = dataModel.getAllWorkspaceItems();
for (ItemInfo item : workspaceItems) {
- AppTarget target = getAppTargetFromItemInfo(context, item);
- if (target != null && !isTrackedForHotseatPrediction(item)) continue;
- events.add(wrapAppTargetWithItemLocation(target, AppTargetEvent.ACTION_PIN, item));
+ AppTarget target = getAppTargetFromInfo(context, item);
+ if (target != null && !isTrackedForPrediction(item)) continue;
+ events.add(wrapAppTargetWithLocation(target, AppTargetEvent.ACTION_PIN, item));
}
ArrayList<AppTarget> currentTargets = new ArrayList<>();
FixedContainerItems hotseatItems = dataModel.extraItems.get(CONTAINER_HOTSEAT_PREDICTION);
if (hotseatItems != null) {
for (ItemInfo itemInfo : hotseatItems.items) {
- AppTarget target = getAppTargetFromItemInfo(context, itemInfo);
+ AppTarget target = getAppTargetFromInfo(context, itemInfo);
if (target != null) currentTargets.add(target);
}
}
@@ -62,4 +70,56 @@ public class HotseatPredictionModel {
bundle.putParcelableArrayList(BUNDLE_KEY_CURRENT_ITEMS, currentTargets);
return bundle;
}
+
+ /**
+ * Creates and returns for {@link AppTarget} object given an {@link ItemInfo}. Returns null
+ * if item is not supported prediction
+ */
+ public static AppTarget getAppTargetFromInfo(Context context, ItemInfo info) {
+ if (info == null) return null;
+ if (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET
+ && info instanceof LauncherAppWidgetInfo
+ && ((LauncherAppWidgetInfo) info).providerName != null) {
+ ComponentName cn = ((LauncherAppWidgetInfo) info).providerName;
+ return new AppTarget.Builder(new AppTargetId("widget:" + cn.getPackageName()),
+ cn.getPackageName(), info.user).setClassName(cn.getClassName()).build();
+ } else if (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION
+ && info.getTargetComponent() != null) {
+ ComponentName cn = info.getTargetComponent();
+ return new AppTarget.Builder(new AppTargetId("app:" + cn.getPackageName()),
+ cn.getPackageName(), info.user).setClassName(cn.getClassName()).build();
+ } else if (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT
+ && info instanceof WorkspaceItemInfo) {
+ ShortcutKey shortcutKey = ShortcutKey.fromItemInfo(info);
+ //TODO: switch to using full shortcut info
+ return new AppTarget.Builder(new AppTargetId("shortcut:" + shortcutKey.getId()),
+ shortcutKey.componentName.getPackageName(), shortcutKey.user).build();
+ } else if (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_FOLDER) {
+ return new AppTarget.Builder(new AppTargetId("folder:" + info.id),
+ context.getPackageName(), info.user).build();
+ }
+ return null;
+ }
+
+ /**
+ * Creates and returns {@link AppTargetEvent} from an {@link AppTarget}, action, and item
+ * location using {@link ItemInfo}
+ */
+ public static AppTargetEvent wrapAppTargetWithLocation(
+ AppTarget target, int action, ItemInfo info) {
+ String location = String.format(Locale.ENGLISH, "%s/%d/[%d,%d]/[%d,%d]",
+ info.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT
+ ? APP_LOCATION_HOTSEAT : APP_LOCATION_WORKSPACE,
+ info.screenId, info.cellX, info.cellY, info.spanX, info.spanY);
+ return new AppTargetEvent.Builder(target, action).setLaunchLocation(location).build();
+ }
+
+ /**
+ * Helper method to determine if {@link ItemInfo} should be tracked and reported to predictors
+ */
+ public static boolean isTrackedForPrediction(ItemInfo info) {
+ return info.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT || (
+ info.container == LauncherSettings.Favorites.CONTAINER_DESKTOP
+ && info.screenId == Workspace.FIRST_SCREEN_ID);
+ }
}
diff --git a/quickstep/src/com/android/launcher3/model/AppEventProducer.java b/quickstep/src/com/android/launcher3/model/AppEventProducer.java
index 9f3be69a01..eed493d4cf 100644
--- a/quickstep/src/com/android/launcher3/model/AppEventProducer.java
+++ b/quickstep/src/com/android/launcher3/model/AppEventProducer.java
@@ -18,15 +18,11 @@ package com.android.launcher3.model;
import static android.app.prediction.AppTargetEvent.ACTION_DISMISS;
import static android.app.prediction.AppTargetEvent.ACTION_LAUNCH;
import static android.app.prediction.AppTargetEvent.ACTION_PIN;
-import static android.app.prediction.AppTargetEvent.ACTION_UNDISMISS;
import static android.app.prediction.AppTargetEvent.ACTION_UNPIN;
import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_HOTSEAT_PREDICTION;
import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_PREDICTION;
-import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_WIDGETS_PREDICTION;
-import static com.android.launcher3.logger.LauncherAtomExtensions.ExtendedContainers.ContainerCase.DEVICE_SEARCH_RESULT_CONTAINER;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_APP_LAUNCH_TAP;
-import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_DISMISS_PREDICTION_UNDO;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_FOLDER_CONVERTED_TO_ICON;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_HOTSEAT_PREDICTION_PINNED;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ITEM_DRAG_STARTED;
@@ -34,13 +30,10 @@ import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCH
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ITEM_DROPPED_ON_REMOVE;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ITEM_DROP_COMPLETED;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ITEM_DROP_FOLDER_CREATED;
-import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ONRESUME;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_QUICKSWITCH_LEFT;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_QUICKSWITCH_RIGHT;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASK_LAUNCH_SWIPE_DOWN;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASK_LAUNCH_TAP;
-import static com.android.launcher3.model.PredictionHelper.isTrackedForHotseatPrediction;
-import static com.android.launcher3.model.PredictionHelper.isTrackedForWidgetPrediction;
import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
import android.annotation.TargetApi;
@@ -62,13 +55,13 @@ import androidx.annotation.AnyThread;
import androidx.annotation.Nullable;
import androidx.annotation.WorkerThread;
-import com.android.launcher3.Utilities;
import com.android.launcher3.logger.LauncherAtom;
import com.android.launcher3.logger.LauncherAtom.ContainerInfo;
import com.android.launcher3.logger.LauncherAtom.FolderContainer;
import com.android.launcher3.logger.LauncherAtom.HotseatContainer;
import com.android.launcher3.logger.LauncherAtom.WorkspaceContainer;
import com.android.launcher3.logging.StatsLogManager.EventEnum;
+import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.pm.UserCache;
import com.android.launcher3.shortcuts.ShortcutRequest;
import com.android.quickstep.logging.StatsLogCompatManager.StatsLogConsumer;
@@ -117,8 +110,7 @@ public class AppEventProducer implements StatsLogConsumer {
@AnyThread
private void sendEvent(AppTarget target, LauncherAtom.ItemInfo locationInfo, int eventId,
int targetPredictor) {
- // TODO: remove the running test check when b/231648228 is fixed.
- if (target != null && !Utilities.IS_RUNNING_IN_TEST_HARNESS) {
+ if (target != null) {
AppTargetEvent event = new AppTargetEvent.Builder(target, eventId)
.setLaunchLocation(getContainer(locationInfo))
.build();
@@ -142,14 +134,11 @@ public class AppEventProducer implements StatsLogConsumer {
if (mLastDragItem == null) {
return;
}
- if (isTrackedForHotseatPrediction(mLastDragItem)) {
- sendEvent(mLastDragItem, ACTION_UNPIN, CONTAINER_HOTSEAT_PREDICTION);
- }
if (isTrackedForHotseatPrediction(atomInfo)) {
sendEvent(atomInfo, ACTION_PIN, CONTAINER_HOTSEAT_PREDICTION);
}
- if (isTrackedForWidgetPrediction(atomInfo)) {
- sendEvent(atomInfo, ACTION_PIN, CONTAINER_WIDGETS_PREDICTION);
+ if (isTrackedForHotseatPrediction(mLastDragItem)) {
+ sendEvent(mLastDragItem, ACTION_UNPIN, CONTAINER_HOTSEAT_PREDICTION);
}
mLastDragItem = null;
} else if (event == LAUNCHER_ITEM_DROP_FOLDER_CREATED) {
@@ -168,20 +157,10 @@ public class AppEventProducer implements StatsLogConsumer {
if (mLastDragItem != null && isTrackedForHotseatPrediction(mLastDragItem)) {
sendEvent(mLastDragItem, ACTION_UNPIN, CONTAINER_HOTSEAT_PREDICTION);
}
- if (mLastDragItem != null && isTrackedForWidgetPrediction(mLastDragItem)) {
- sendEvent(mLastDragItem, ACTION_UNPIN, CONTAINER_WIDGETS_PREDICTION);
- }
} else if (event == LAUNCHER_HOTSEAT_PREDICTION_PINNED) {
if (isTrackedForHotseatPrediction(atomInfo)) {
sendEvent(atomInfo, ACTION_PIN, CONTAINER_HOTSEAT_PREDICTION);
}
- } else if (event == LAUNCHER_ONRESUME) {
- AppTarget target = new AppTarget.Builder(new AppTargetId("launcher:launcher"),
- mContext.getPackageName(), Process.myUserHandle())
- .build();
- sendEvent(target, atomInfo, ACTION_LAUNCH, CONTAINER_PREDICTION);
- } else if (event == LAUNCHER_DISMISS_PREDICTION_UNDO) {
- sendEvent(atomInfo, ACTION_UNDISMISS, CONTAINER_HOTSEAT_PREDICTION);
}
}
@@ -278,6 +257,9 @@ public class AppEventProducer implements StatsLogConsumer {
case ALL_APPS_CONTAINER: {
return "all-apps";
}
+ case SEARCH_RESULT_CONTAINER: {
+ return "search-results";
+ }
case PREDICTED_HOTSEAT_CONTAINER: {
return "predictions/hotseat";
}
@@ -297,15 +279,6 @@ public class AppEventProducer implements StatsLogConsumer {
}
return "folder";
}
- case SEARCH_RESULT_CONTAINER:
- return "search-results";
- case EXTENDED_CONTAINERS: {
- if (ci.getExtendedContainers().getContainerCase()
- == DEVICE_SEARCH_RESULT_CONTAINER) {
- return "search-results";
- }
- }
- default: // fall out
}
return "";
}
@@ -323,4 +296,19 @@ public class AppEventProducer implements StatsLogConsumer {
return TextUtils.isEmpty(componentNameString)
? null : ComponentName.unflattenFromString(componentNameString);
}
+
+ /**
+ * Helper method to determine if {@link ItemInfo} should be tracked and reported to predictors
+ */
+ private static boolean isTrackedForHotseatPrediction(LauncherAtom.ItemInfo info) {
+ ContainerInfo ci = info.getContainerInfo();
+ switch (ci.getContainerCase()) {
+ case HOTSEAT:
+ return true;
+ case WORKSPACE:
+ return ci.getWorkspace().getPageIndex() == 0;
+ default:
+ return false;
+ }
+ }
}
diff --git a/quickstep/src/com/android/launcher3/model/PredictionHelper.java b/quickstep/src/com/android/launcher3/model/PredictionHelper.java
deleted file mode 100644
index 738dd83cbc..0000000000
--- a/quickstep/src/com/android/launcher3/model/PredictionHelper.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Copyright (C) 2021 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.launcher3.model;
-
-import static com.android.launcher3.logger.LauncherAtom.ContainerInfo.ContainerCase.WORKSPACE;
-
-import android.app.prediction.AppTarget;
-import android.app.prediction.AppTargetEvent;
-import android.app.prediction.AppTargetId;
-import android.content.ComponentName;
-import android.content.Context;
-
-import androidx.annotation.Nullable;
-
-import com.android.launcher3.LauncherSettings;
-import com.android.launcher3.Workspace;
-import com.android.launcher3.logger.LauncherAtom;
-import com.android.launcher3.model.data.ItemInfo;
-import com.android.launcher3.model.data.LauncherAppWidgetInfo;
-import com.android.launcher3.model.data.WorkspaceItemInfo;
-import com.android.launcher3.shortcuts.ShortcutKey;
-
-import java.util.Locale;
-
-/** Helper class with methods for converting launcher items to form usable by predictors */
-public final class PredictionHelper {
- private static final String APP_LOCATION_HOTSEAT = "hotseat";
- private static final String APP_LOCATION_WORKSPACE = "workspace";
-
- /**
- * Creates and returns an {@link AppTarget} object for an {@link ItemInfo}. Returns null
- * if item type is not supported in predictions
- */
- @Nullable
- public static AppTarget getAppTargetFromItemInfo(Context context, ItemInfo info) {
- if (info == null) return null;
- if (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET
- && info instanceof LauncherAppWidgetInfo
- && ((LauncherAppWidgetInfo) info).providerName != null) {
- ComponentName cn = ((LauncherAppWidgetInfo) info).providerName;
- return new AppTarget.Builder(new AppTargetId("widget:" + cn.getPackageName()),
- cn.getPackageName(), info.user).setClassName(cn.getClassName()).build();
- } else if (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION
- && info.getTargetComponent() != null) {
- ComponentName cn = info.getTargetComponent();
- return new AppTarget.Builder(new AppTargetId("app:" + cn.getPackageName()),
- cn.getPackageName(), info.user).setClassName(cn.getClassName()).build();
- } else if (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT
- && info instanceof WorkspaceItemInfo) {
- ShortcutKey shortcutKey = ShortcutKey.fromItemInfo(info);
- //TODO: switch to using full shortcut info
- return new AppTarget.Builder(new AppTargetId("shortcut:" + shortcutKey.getId()),
- shortcutKey.componentName.getPackageName(), shortcutKey.user).build();
- } else if (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_FOLDER) {
- return new AppTarget.Builder(new AppTargetId("folder:" + info.id),
- context.getPackageName(), info.user).build();
- }
- return null;
- }
-
- /**
- * Creates and returns {@link AppTargetEvent} from an {@link AppTarget}, action, and item
- * location using {@link ItemInfo}
- */
- public static AppTargetEvent wrapAppTargetWithItemLocation(
- AppTarget target, int action, ItemInfo info) {
- String location = String.format(Locale.ENGLISH, "%s/%d/[%d,%d]/[%d,%d]",
- info.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT
- ? APP_LOCATION_HOTSEAT : APP_LOCATION_WORKSPACE,
- info.screenId, info.cellX, info.cellY, info.spanX, info.spanY);
- return new AppTargetEvent.Builder(target, action).setLaunchLocation(location).build();
- }
-
- /**
- * Helper method to determine if {@link ItemInfo} should be tracked and reported to hotseat
- * predictors
- */
- public static boolean isTrackedForHotseatPrediction(ItemInfo info) {
- return info.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT || (
- info.container == LauncherSettings.Favorites.CONTAINER_DESKTOP
- && info.screenId == Workspace.FIRST_SCREEN_ID);
- }
-
- /**
- * Helper method to determine if {@link LauncherAtom.ItemInfo} should be tracked and reported to
- * hotseat predictors
- */
- public static boolean isTrackedForHotseatPrediction(LauncherAtom.ItemInfo info) {
- LauncherAtom.ContainerInfo ci = info.getContainerInfo();
- switch (ci.getContainerCase()) {
- case HOTSEAT:
- return true;
- case WORKSPACE:
- return ci.getWorkspace().getPageIndex() == 0;
- default:
- return false;
- }
- }
-
- /**
- * Helper method to determine if {@link ItemInfo} should be tracked and reported to widget
- * predictors
- */
- public static boolean isTrackedForWidgetPrediction(ItemInfo info) {
- return info.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET
- && info.container == LauncherSettings.Favorites.CONTAINER_DESKTOP;
- }
-
- /**
- * Helper method to determine if {@link LauncherAtom.ItemInfo} should be tracked and reported
- * to widget predictors
- */
- public static boolean isTrackedForWidgetPrediction(LauncherAtom.ItemInfo info) {
- return info.getItemCase() == LauncherAtom.ItemInfo.ItemCase.WIDGET
- && info.getContainerInfo().getContainerCase() == WORKSPACE;
- }
-}
diff --git a/quickstep/src/com/android/launcher3/model/PredictionUpdateTask.java b/quickstep/src/com/android/launcher3/model/PredictionUpdateTask.java
index 7e3ee7dada..b0fba3d5ae 100644
--- a/quickstep/src/com/android/launcher3/model/PredictionUpdateTask.java
+++ b/quickstep/src/com/android/launcher3/model/PredictionUpdateTask.java
@@ -34,6 +34,7 @@ import com.android.launcher3.model.QuickstepModelDelegate.PredictorState;
import com.android.launcher3.model.data.AppInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo;
+import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
@@ -59,13 +60,13 @@ public class PredictionUpdateTask extends BaseModelUpdateTask {
Utilities.getDevicePrefs(context).edit()
.putBoolean(LAST_PREDICTION_ENABLED_STATE, !mTargets.isEmpty()).apply();
- Set<UserHandle> usersForChangedShortcuts =
- dataModel.extraItems.get(mPredictorState.containerId).items.stream()
- .filter(info -> info.itemType == ITEM_TYPE_DEEP_SHORTCUT)
- .map(info -> info.user)
- .collect(Collectors.toSet());
+ FixedContainerItems fci = mPredictorState.items;
+ Set<UserHandle> usersForChangedShortcuts = new HashSet<>(fci.items.stream()
+ .filter(info -> info.itemType == ITEM_TYPE_DEEP_SHORTCUT)
+ .map(info -> info.user)
+ .collect(Collectors.toSet()));
+ fci.items.clear();
- FixedContainerItems fci = new FixedContainerItems(mPredictorState.containerId);
for (AppTarget target : mTargets) {
WorkspaceItemInfo itemInfo;
ShortcutInfo si = target.getShortcutInfo();
@@ -85,7 +86,7 @@ public class PredictionUpdateTask extends BaseModelUpdateTask {
.filter(info -> user.equals(info.user) && cn.equals(info.componentName))
.map(ai -> {
app.getIconCache().getTitleAndIcon(ai, false);
- return ai.makeWorkspaceItem(context);
+ return ai.makeWorkspaceItem();
})
.findAny()
.orElseGet(() -> {
@@ -96,7 +97,7 @@ public class PredictionUpdateTask extends BaseModelUpdateTask {
}
AppInfo ai = new AppInfo(context, lai, user);
app.getIconCache().getTitleAndIcon(ai, lai, false);
- return ai.makeWorkspaceItem(context);
+ return ai.makeWorkspaceItem();
});
if (itemInfo == null) {
@@ -108,7 +109,6 @@ public class PredictionUpdateTask extends BaseModelUpdateTask {
fci.items.add(itemInfo);
}
- dataModel.extraItems.put(fci.containerId, fci);
bindExtraContainerItems(fci);
usersForChangedShortcuts.forEach(
u -> dataModel.updateShortcutPinnedState(app.getContext(), u));
diff --git a/quickstep/src/com/android/launcher3/model/QuickstepModelDelegate.java b/quickstep/src/com/android/launcher3/model/QuickstepModelDelegate.java
index 770dfb2e07..a9c2a5e51d 100644
--- a/quickstep/src/com/android/launcher3/model/QuickstepModelDelegate.java
+++ b/quickstep/src/com/android/launcher3/model/QuickstepModelDelegate.java
@@ -25,13 +25,7 @@ import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_APPLICA
import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT;
import static com.android.launcher3.Utilities.getDevicePrefs;
import static com.android.launcher3.hybridhotseat.HotseatPredictionModel.convertDataModelToAppTargetBundle;
-import static com.android.launcher3.model.PredictionHelper.getAppTargetFromItemInfo;
-import static com.android.launcher3.model.PredictionHelper.wrapAppTargetWithItemLocation;
-import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
-import static java.util.stream.Collectors.toCollection;
-
-import android.app.StatsManager;
import android.app.prediction.AppPredictionContext;
import android.app.prediction.AppPredictionManager;
import android.app.prediction.AppPredictor;
@@ -43,17 +37,15 @@ import android.content.SharedPreferences;
import android.content.pm.LauncherActivityInfo;
import android.content.pm.LauncherApps;
import android.content.pm.ShortcutInfo;
-import android.os.Bundle;
import android.os.UserHandle;
import android.util.Log;
-import android.util.StatsEvent;
import androidx.annotation.Nullable;
import androidx.annotation.WorkerThread;
import com.android.launcher3.InvariantDeviceProfile;
+import com.android.launcher3.InvariantDeviceProfile.OnIDPChangeListener;
import com.android.launcher3.LauncherAppState;
-import com.android.launcher3.logger.LauncherAtom;
import com.android.launcher3.logging.InstanceId;
import com.android.launcher3.logging.InstanceIdSequence;
import com.android.launcher3.model.BgDataModel.FixedContainerItems;
@@ -62,13 +54,11 @@ import com.android.launcher3.model.data.FolderInfo;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.launcher3.shortcuts.ShortcutKey;
+import com.android.launcher3.util.Executors;
import com.android.launcher3.util.IntSparseArrayMap;
import com.android.launcher3.util.PersistedItemArray;
-import com.android.quickstep.logging.SettingsChangeLogger;
import com.android.quickstep.logging.StatsLogCompatManager;
-import com.android.systemui.shared.system.SysUiStatsLog;
-import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
@@ -78,11 +68,10 @@ import java.util.stream.IntStream;
/**
* Model delegate which loads prediction items
*/
-public class QuickstepModelDelegate extends ModelDelegate {
+public class QuickstepModelDelegate extends ModelDelegate implements OnIDPChangeListener {
public static final String LAST_PREDICTION_ENABLED_STATE = "last_prediction_enabled_state";
private static final String LAST_SNAPSHOT_TIME_MILLIS = "LAST_SNAPSHOT_TIME_MILLIS";
- private static final String BUNDLE_KEY_ADDED_APP_WIDGETS = "added_app_widgets";
private static final int NUM_OF_RECOMMENDED_WIDGETS_PREDICATION = 20;
private static final boolean IS_DEBUG = false;
@@ -97,18 +86,15 @@ public class QuickstepModelDelegate extends ModelDelegate {
private final InvariantDeviceProfile mIDP;
private final AppEventProducer mAppEventProducer;
- private final StatsManager mStatsManager;
- private final Context mContext;
protected boolean mActive = false;
public QuickstepModelDelegate(Context context) {
- mContext = context;
mAppEventProducer = new AppEventProducer(context, this::onAppTargetEvent);
mIDP = InvariantDeviceProfile.INSTANCE.get(context);
+ mIDP.addOnChangeListener(this);
StatsLogCompatManager.LOGS_CONSUMER.add(mAppEventProducer);
- mStatsManager = context.getSystemService(StatsManager.class);
}
@Override
@@ -119,19 +105,18 @@ public class QuickstepModelDelegate extends ModelDelegate {
WorkspaceItemFactory allAppsFactory = new WorkspaceItemFactory(
mApp, ums, pinnedShortcuts, mIDP.numDatabaseAllAppsColumns);
- FixedContainerItems allAppsItems = new FixedContainerItems(mAllAppsState.containerId,
+ mAllAppsState.items.setItems(
mAllAppsState.storage.read(mApp.getContext(), allAppsFactory, ums.allUsers::get));
- mDataModel.extraItems.put(mAllAppsState.containerId, allAppsItems);
+ mDataModel.extraItems.put(CONTAINER_PREDICTION, mAllAppsState.items);
WorkspaceItemFactory hotseatFactory =
new WorkspaceItemFactory(mApp, ums, pinnedShortcuts, mIDP.numDatabaseHotseatIcons);
- FixedContainerItems hotseatItems = new FixedContainerItems(mHotseatState.containerId,
+ mHotseatState.items.setItems(
mHotseatState.storage.read(mApp.getContext(), hotseatFactory, ums.allUsers::get));
- mDataModel.extraItems.put(mHotseatState.containerId, hotseatItems);
+ mDataModel.extraItems.put(CONTAINER_HOTSEAT_PREDICTION, mHotseatState.items);
// Widgets prediction isn't used frequently. And thus, it is not persisted on disk.
- mDataModel.extraItems.put(mWidgetsRecommendationState.containerId,
- new FixedContainerItems(mWidgetsRecommendationState.containerId));
+ mDataModel.extraItems.put(CONTAINER_WIDGETS_PREDICTION, mWidgetsRecommendationState.items);
mActive = true;
}
@@ -165,82 +150,17 @@ public class QuickstepModelDelegate extends ModelDelegate {
}
InstanceId instanceId = new InstanceIdSequence().newInstanceId();
for (ItemInfo info : itemsIdMap) {
- FolderInfo parent = getContainer(info, itemsIdMap);
+ FolderInfo parent = info.container > 0
+ ? (FolderInfo) itemsIdMap.get(info.container) : null;
StatsLogCompatManager.writeSnapshot(info.buildProto(parent), instanceId);
}
additionalSnapshotEvents(instanceId);
prefs.edit().putLong(LAST_SNAPSHOT_TIME_MILLIS, now).apply();
}
-
- // Only register for launcher snapshot logging if this is the primary ModelDelegate
- // instance, as there will be additional instances that may be destroyed at any time.
- if (mIsPrimaryInstance) {
- registerSnapshotLoggingCallback();
- }
}
protected void additionalSnapshotEvents(InstanceId snapshotInstanceId){}
- /**
- * Registers a callback to log launcher workspace layout using Statsd pulled atom.
- */
- protected void registerSnapshotLoggingCallback() {
- if (mStatsManager == null) {
- Log.d(TAG, "Failed to get StatsManager");
- }
-
- try {
- mStatsManager.setPullAtomCallback(
- SysUiStatsLog.LAUNCHER_LAYOUT_SNAPSHOT,
- null /* PullAtomMetadata */,
- MODEL_EXECUTOR,
- (i, eventList) -> {
- InstanceId instanceId = new InstanceIdSequence().newInstanceId();
- IntSparseArrayMap<ItemInfo> itemsIdMap;
- synchronized (mDataModel) {
- itemsIdMap = mDataModel.itemsIdMap.clone();
- }
-
- for (ItemInfo info : itemsIdMap) {
- FolderInfo parent = getContainer(info, itemsIdMap);
- LauncherAtom.ItemInfo itemInfo = info.buildProto(parent);
- Log.d(TAG, itemInfo.toString());
- StatsEvent statsEvent = StatsLogCompatManager.buildStatsEvent(itemInfo,
- instanceId);
- eventList.add(statsEvent);
- }
- Log.d(TAG,
- String.format(
- "Successfully logged %d workspace items with instanceId=%d",
- itemsIdMap.size(), instanceId.getId()));
- additionalSnapshotEvents(instanceId);
- SettingsChangeLogger.INSTANCE.get(mContext).logSnapshot(instanceId);
- return StatsManager.PULL_SUCCESS;
- }
- );
- Log.d(TAG, "Successfully registered for launcher snapshot logging!");
- } catch (RuntimeException e) {
- Log.e(TAG, "Failed to register launcher snapshot logging callback with StatsManager",
- e);
- }
- }
-
- private static FolderInfo getContainer(ItemInfo info, IntSparseArrayMap<ItemInfo> itemsIdMap) {
- if (info.container > 0) {
- ItemInfo containerInfo = itemsIdMap.get(info.container);
-
- if (!(containerInfo instanceof FolderInfo)) {
- Log.e(TAG, String.format(
- "Item info: %s found with invalid container: %s",
- info,
- containerInfo));
- }
- // Allow crash to help debug b/173838775
- return (FolderInfo) containerInfo;
- }
- return null;
- }
-
@Override
public void validateData() {
super.validateData();
@@ -257,10 +177,9 @@ public class QuickstepModelDelegate extends ModelDelegate {
super.destroy();
mActive = false;
StatsLogCompatManager.LOGS_CONSUMER.remove(mAppEventProducer);
- if (mIsPrimaryInstance) {
- mStatsManager.clearPullAtomCallback(SysUiStatsLog.LAUNCHER_LAYOUT_SNAPSHOT);
- }
+
destroyPredictors();
+ mIDP.removeOnChangeListener(this);
}
private void destroyPredictors() {
@@ -298,7 +217,6 @@ public class QuickstepModelDelegate extends ModelDelegate {
registerWidgetsPredictor(apm.createAppPredictionSession(
new AppPredictionContext.Builder(context)
.setUiSurface("widgets")
- .setExtras(getBundleForWidgetsOnWorkspace(context, mDataModel))
.setPredictedTargetCount(NUM_OF_RECOMMENDED_WIDGETS_PREDICATION)
.build()));
}
@@ -306,7 +224,7 @@ public class QuickstepModelDelegate extends ModelDelegate {
private void registerPredictor(PredictorState state, AppPredictor predictor) {
state.predictor = predictor;
state.predictor.registerPredictionUpdates(
- MODEL_EXECUTOR, t -> handleUpdate(state, t));
+ Executors.MODEL_EXECUTOR, t -> handleUpdate(state, t));
state.predictor.requestPredictionUpdate();
}
@@ -321,7 +239,7 @@ public class QuickstepModelDelegate extends ModelDelegate {
private void registerWidgetsPredictor(AppPredictor predictor) {
mWidgetsRecommendationState.predictor = predictor;
mWidgetsRecommendationState.predictor.registerPredictionUpdates(
- MODEL_EXECUTOR, targets -> {
+ Executors.MODEL_EXECUTOR, targets -> {
if (mWidgetsRecommendationState.setTargets(targets)) {
// No diff, skip
return;
@@ -332,54 +250,29 @@ public class QuickstepModelDelegate extends ModelDelegate {
mWidgetsRecommendationState.predictor.requestPredictionUpdate();
}
+ @Override
+ public void onIdpChanged(InvariantDeviceProfile profile) {
+ // Reinitialize everything
+ Executors.MODEL_EXECUTOR.execute(this::recreatePredictors);
+ }
+
private void onAppTargetEvent(AppTargetEvent event, int client) {
- PredictorState state;
- switch(client) {
- case CONTAINER_PREDICTION:
- state = mAllAppsState;
- break;
- case CONTAINER_WIDGETS_PREDICTION:
- state = mWidgetsRecommendationState;
- break;
- case CONTAINER_HOTSEAT_PREDICTION:
- default:
- state = mHotseatState;
- break;
- }
+ PredictorState state = client == CONTAINER_PREDICTION ? mAllAppsState : mHotseatState;
if (state.predictor != null) {
state.predictor.notifyAppTargetEvent(event);
- Log.d(TAG, "notifyAppTargetEvent action=" + event.getAction()
- + " launchLocation=" + event.getLaunchLocation());
}
}
- private Bundle getBundleForWidgetsOnWorkspace(Context context, BgDataModel dataModel) {
- Bundle bundle = new Bundle();
- ArrayList<AppTargetEvent> widgetEvents =
- dataModel.getAllWorkspaceItems().stream()
- .filter(PredictionHelper::isTrackedForWidgetPrediction)
- .map(item -> {
- AppTarget target = getAppTargetFromItemInfo(context, item);
- if (target == null) return null;
- return wrapAppTargetWithItemLocation(
- target, AppTargetEvent.ACTION_PIN, item);
- })
- .filter(Objects::nonNull)
- .collect(toCollection(ArrayList::new));
- bundle.putParcelableArrayList(BUNDLE_KEY_ADDED_APP_WIDGETS, widgetEvents);
- return bundle;
- }
-
static class PredictorState {
- public final int containerId;
+ public final FixedContainerItems items;
public final PersistedItemArray<ItemInfo> storage;
public AppPredictor predictor;
private List<AppTarget> mLastTargets;
- PredictorState(int containerId, String storageName) {
- this.containerId = containerId;
+ PredictorState(int container, String storageName) {
+ items = new FixedContainerItems(container);
storage = new PersistedItemArray<>(storageName);
mLastTargets = Collections.emptyList();
}
@@ -460,7 +353,7 @@ public class QuickstepModelDelegate extends ModelDelegate {
AppInfo info = new AppInfo(lai, user, mUMS.isUserQuiet(user));
mAppState.getIconCache().getTitleAndIcon(info, lai, false);
mReadCount++;
- return info.makeWorkspaceItem(mAppState.getContext());
+ return info.makeWorkspaceItem();
}
case ITEM_TYPE_DEEP_SHORTCUT: {
ShortcutKey key = ShortcutKey.fromIntent(intent, user);
diff --git a/quickstep/src/com/android/launcher3/model/WellbeingModel.java b/quickstep/src/com/android/launcher3/model/WellbeingModel.java
index 68ed682792..154b78b1b9 100644
--- a/quickstep/src/com/android/launcher3/model/WellbeingModel.java
+++ b/quickstep/src/com/android/launcher3/model/WellbeingModel.java
@@ -40,7 +40,6 @@ import android.os.UserHandle;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.Log;
-import android.view.View;
import androidx.annotation.MainThread;
import androidx.annotation.Nullable;
@@ -194,7 +193,7 @@ public final class WellbeingModel extends BgObjectWithLooper {
@MainThread
private SystemShortcut getShortcutForApp(String packageName, int userId,
- BaseDraggingActivity activity, ItemInfo info, View originalView) {
+ BaseDraggingActivity activity, ItemInfo info) {
Preconditions.assertUIThread();
// Work profile apps are not recognized by digital wellbeing.
if (userId != UserHandle.myUserId()) {
@@ -218,7 +217,7 @@ public final class WellbeingModel extends BgObjectWithLooper {
"getShortcutForApp [" + packageName + "]: action: '" + action.getTitle()
+ "'");
}
- return new RemoteActionShortcut(action, activity, info, originalView);
+ return new RemoteActionShortcut(action, activity, info);
}
}
@@ -378,9 +377,9 @@ public final class WellbeingModel extends BgObjectWithLooper {
/**
* Shortcut factory for generating wellbeing action
*/
- public static final SystemShortcut.Factory<BaseDraggingActivity> SHORTCUT_FACTORY =
- (activity, info, originalView) -> (info.getTargetComponent() == null) ? null
- : INSTANCE.get(activity).getShortcutForApp(
+ public static final SystemShortcut.Factory SHORTCUT_FACTORY =
+ (activity, info) -> (info.getTargetComponent() == null) ? null : INSTANCE.get(activity)
+ .getShortcutForApp(
info.getTargetComponent().getPackageName(), info.user.getIdentifier(),
- activity, info, originalView);
+ activity, info);
}
diff --git a/quickstep/src/com/android/launcher3/model/WidgetsPredictionUpdateTask.java b/quickstep/src/com/android/launcher3/model/WidgetsPredictionUpdateTask.java
index 9cd9d8597c..3d891e8748 100644
--- a/quickstep/src/com/android/launcher3/model/WidgetsPredictionUpdateTask.java
+++ b/quickstep/src/com/android/launcher3/model/WidgetsPredictionUpdateTask.java
@@ -59,8 +59,8 @@ public final class WidgetsPredictionUpdateTask extends BaseModelUpdateTask {
Map<PackageUserKey, List<WidgetItem>> allWidgets =
dataModel.widgetsModel.getAllWidgetsWithoutShortcuts();
- FixedContainerItems fixedContainerItems =
- new FixedContainerItems(mPredictorState.containerId);
+ FixedContainerItems fixedContainerItems = mPredictorState.items;
+ fixedContainerItems.items.clear();
if (FeatureFlags.ENABLE_LOCAL_RECOMMENDED_WIDGETS_FILTER.get()) {
for (AppTarget app : mTargets) {
@@ -83,7 +83,7 @@ public final class WidgetsPredictionUpdateTask extends BaseModelUpdateTask {
}
} else {
Map<ComponentKey, WidgetItem> widgetItems =
- allWidgets.values().stream().flatMap(List::stream).distinct()
+ allWidgets.values().stream().flatMap(List::stream)
.collect(Collectors.toMap(widget -> (ComponentKey) widget,
widget -> widget));
for (AppTarget app : mTargets) {
@@ -100,7 +100,6 @@ public final class WidgetsPredictionUpdateTask extends BaseModelUpdateTask {
}
}
}
- dataModel.extraItems.put(mPredictorState.containerId, fixedContainerItems);
bindExtraContainerItems(fixedContainerItems);
// Don't store widgets prediction to disk because it is not used frequently.
diff --git a/quickstep/src/com/android/launcher3/popup/QuickstepSystemShortcut.java b/quickstep/src/com/android/launcher3/popup/QuickstepSystemShortcut.java
deleted file mode 100644
index 4e59790771..0000000000
--- a/quickstep/src/com/android/launcher3/popup/QuickstepSystemShortcut.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.launcher3.popup;
-
-import android.content.Intent;
-import android.graphics.Bitmap;
-import android.graphics.drawable.BitmapDrawable;
-import android.graphics.drawable.Drawable;
-import android.util.Log;
-import android.view.View;
-
-import com.android.launcher3.BaseQuickstepLauncher;
-import com.android.launcher3.model.data.ItemInfo;
-import com.android.launcher3.model.data.WorkspaceItemInfo;
-import com.android.launcher3.util.SplitConfigurationOptions.SplitPositionOption;
-import com.android.quickstep.views.RecentsView;
-
-public interface QuickstepSystemShortcut {
-
- String TAG = QuickstepSystemShortcut.class.getSimpleName();
-
- static SystemShortcut.Factory<BaseQuickstepLauncher> getSplitSelectShortcutByPosition(
- SplitPositionOption position) {
- return (activity, itemInfo, originalView) ->
- new QuickstepSystemShortcut.SplitSelectSystemShortcut(activity, itemInfo,
- originalView, position);
- }
-
- class SplitSelectSystemShortcut extends SystemShortcut<BaseQuickstepLauncher> {
-
- private final SplitPositionOption mPosition;
-
- public SplitSelectSystemShortcut(BaseQuickstepLauncher launcher, ItemInfo itemInfo,
- View originalView, SplitPositionOption position) {
- super(position.iconResId, position.textResId, launcher, itemInfo, originalView);
-
- mPosition = position;
- }
-
- @Override
- public void onClick(View view) {
- Bitmap bitmap;
- Intent intent;
- if (mItemInfo instanceof WorkspaceItemInfo) {
- final WorkspaceItemInfo workspaceItemInfo = (WorkspaceItemInfo) mItemInfo;
- bitmap = workspaceItemInfo.bitmap.icon;
- intent = workspaceItemInfo.intent;
- } else if (mItemInfo instanceof com.android.launcher3.model.data.AppInfo) {
- final com.android.launcher3.model.data.AppInfo appInfo =
- (com.android.launcher3.model.data.AppInfo) mItemInfo;
- bitmap = appInfo.bitmap.icon;
- intent = appInfo.intent;
- } else {
- Log.e(TAG, "unknown item type");
- return;
- }
-
- RecentsView recentsView = mTarget.getOverviewPanel();
- recentsView.initiateSplitSelect(
- new SplitSelectSource(mOriginalView, new BitmapDrawable(bitmap), intent,
- mPosition));
- }
- }
-
- class SplitSelectSource {
-
- public final View view;
- public final Drawable drawable;
- public final Intent intent;
- public final SplitPositionOption position;
-
- public SplitSelectSource(View view, Drawable drawable, Intent intent,
- SplitPositionOption position) {
- this.view = view;
- this.drawable = drawable;
- this.intent = intent;
- this.position = position;
- }
- }
-}
diff --git a/quickstep/src/com/android/launcher3/proxy/StartActivityParams.java b/quickstep/src/com/android/launcher3/proxy/StartActivityParams.java
index b47ef47423..bee8bb8132 100644
--- a/quickstep/src/com/android/launcher3/proxy/StartActivityParams.java
+++ b/quickstep/src/com/android/launcher3/proxy/StartActivityParams.java
@@ -16,10 +16,6 @@
package com.android.launcher3.proxy;
-import static android.app.PendingIntent.FLAG_MUTABLE;
-import static android.app.PendingIntent.FLAG_ONE_SHOT;
-import static android.app.PendingIntent.FLAG_UPDATE_CURRENT;
-
import android.app.Activity;
import android.app.PendingIntent;
import android.app.PendingIntent.CanceledException;
@@ -49,7 +45,7 @@ public class StartActivityParams implements Parcelable {
public StartActivityParams(Activity activity, int requestCode) {
this(activity.createPendingResult(requestCode, new Intent(),
- FLAG_ONE_SHOT | FLAG_UPDATE_CURRENT | FLAG_MUTABLE), requestCode);
+ PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_UPDATE_CURRENT), requestCode);
}
public StartActivityParams(PendingIntent pendingIntent, int requestCode) {
diff --git a/quickstep/src/com/android/launcher3/statehandlers/BackButtonAlphaHandler.java b/quickstep/src/com/android/launcher3/statehandlers/BackButtonAlphaHandler.java
index 07d3a51603..1f268cc9d9 100644
--- a/quickstep/src/com/android/launcher3/statehandlers/BackButtonAlphaHandler.java
+++ b/quickstep/src/com/android/launcher3/statehandlers/BackButtonAlphaHandler.java
@@ -17,17 +17,17 @@
package com.android.launcher3.statehandlers;
import static com.android.launcher3.anim.Interpolators.LINEAR;
-import static com.android.launcher3.util.DisplayController.NavigationMode.TWO_BUTTONS;
import static com.android.quickstep.AnimatedFloat.VALUE;
+import static com.android.quickstep.SysUINavigationMode.Mode.TWO_BUTTONS;
import com.android.launcher3.BaseQuickstepLauncher;
import com.android.launcher3.LauncherState;
import com.android.launcher3.anim.PendingAnimation;
import com.android.launcher3.statemanager.StateManager.StateHandler;
import com.android.launcher3.states.StateAnimationConfig;
-import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.UiThreadHelper;
import com.android.quickstep.AnimatedFloat;
+import com.android.quickstep.SysUINavigationMode;
import com.android.quickstep.SystemUiProxy;
/**
@@ -48,7 +48,7 @@ public class BackButtonAlphaHandler implements StateHandler<LauncherState> {
@Override
public void setStateWithAnimation(LauncherState toState, StateAnimationConfig config,
PendingAnimation animation) {
- if (DisplayController.getNavigationMode(mLauncher) != TWO_BUTTONS) {
+ if (SysUINavigationMode.getMode(mLauncher) != TWO_BUTTONS) {
return;
}
diff --git a/quickstep/src/com/android/launcher3/statehandlers/DepthController.java b/quickstep/src/com/android/launcher3/statehandlers/DepthController.java
index eda08239d6..8c9ac12bd4 100644
--- a/quickstep/src/com/android/launcher3/statehandlers/DepthController.java
+++ b/quickstep/src/com/android/launcher3/statehandlers/DepthController.java
@@ -23,7 +23,6 @@ import static com.android.launcher3.states.StateAnimationConfig.SKIP_DEPTH_CONTR
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
-import android.app.WallpaperManager;
import android.os.IBinder;
import android.os.SystemProperties;
import android.util.FloatProperty;
@@ -43,8 +42,8 @@ import com.android.launcher3.anim.PendingAnimation;
import com.android.launcher3.statemanager.StateManager.StateHandler;
import com.android.launcher3.states.StateAnimationConfig;
import com.android.systemui.shared.system.BlurUtils;
+import com.android.systemui.shared.system.WallpaperManagerCompat;
-import java.io.PrintWriter;
import java.util.function.Consumer;
/**
@@ -53,7 +52,6 @@ import java.util.function.Consumer;
public class DepthController implements StateHandler<LauncherState>,
BaseActivity.MultiWindowModeChangedListener {
- private static final boolean OVERLAY_SCROLL_ENABLED = false;
public static final FloatProperty<DepthController> DEPTH =
new FloatProperty<DepthController>("depth") {
@Override
@@ -98,11 +96,7 @@ public class DepthController implements StateHandler<LauncherState>,
public void onDraw() {
View view = mLauncher.getDragLayer();
ViewRootImpl viewRootImpl = view.getViewRootImpl();
- boolean applied = setSurface(
- viewRootImpl != null ? viewRootImpl.getSurfaceControl() : null);
- if (!applied) {
- dispatchTransactionSurface(mDepth);
- }
+ setSurface(viewRootImpl != null ? viewRootImpl.getSurfaceControl() : null);
view.post(() -> view.getViewTreeObserver().removeOnDrawListener(this));
}
};
@@ -128,38 +122,21 @@ public class DepthController implements StateHandler<LauncherState>,
*/
private int mMaxBlurRadius;
private boolean mCrossWindowBlursEnabled;
- private WallpaperManager mWallpaperManager;
+ private WallpaperManagerCompat mWallpaperManager;
private SurfaceControl mSurface;
/**
- * How visible the -1 overlay is, from 0 to 1.
- */
- private float mOverlayScrollProgress;
- /**
* Ratio from 0 to 1, where 0 is fully zoomed out, and 1 is zoomed in.
* @see android.service.wallpaper.WallpaperService.Engine#onZoomChanged(float)
*/
private float mDepth;
/**
- * Last blur value, in pixels, that was applied.
- * For debugging purposes.
- */
- private int mCurrentBlur;
- /**
* If we're launching and app and should not be blurring the screen for performance reasons.
*/
private boolean mBlurDisabledForAppLaunch;
- /**
- * If we requested early wake-up offsets to SurfaceFlinger.
- */
- private boolean mInEarlyWakeUp;
// Workaround for animating the depth when multiwindow mode changes.
private boolean mIgnoreStateChangesDuringMultiWindowAnimation = false;
- // Hints that there is potentially content behind Launcher and that we shouldn't optimize by
- // marking the launcher surface as opaque. Only used in certain Launcher states.
- private boolean mHasContentBehindLauncher;
-
private View.OnAttachStateChangeListener mOnAttachListener;
public DepthController(Launcher l) {
@@ -169,7 +146,7 @@ public class DepthController implements StateHandler<LauncherState>,
private void ensureDependencies() {
if (mWallpaperManager == null) {
mMaxBlurRadius = mLauncher.getResources().getInteger(R.integer.max_depth_blur_radius);
- mWallpaperManager = mLauncher.getSystemService(WallpaperManager.class);
+ mWallpaperManager = new WallpaperManagerCompat(mLauncher);
}
if (mLauncher.getRootView() != null && mOnAttachListener == null) {
@@ -203,10 +180,6 @@ public class DepthController implements StateHandler<LauncherState>,
mLauncher.getScrimView().addOpaquenessListener(mOpaquenessListener);
}
- public void setHasContentBehindLauncher(boolean hasContentBehindLauncher) {
- mHasContentBehindLauncher = hasContentBehindLauncher;
- }
-
/**
* Sets if the underlying activity is started or not
*/
@@ -221,22 +194,20 @@ public class DepthController implements StateHandler<LauncherState>,
/**
* Sets the specified app target surface to apply the blur to.
- * @return true when surface was valid and transaction was dispatched.
*/
- public boolean setSurface(SurfaceControl surface) {
+ public void setSurface(SurfaceControl surface) {
// Set launcher as the SurfaceControl when we don't need an external target anymore.
if (surface == null) {
ViewRootImpl viewRootImpl = mLauncher.getDragLayer().getViewRootImpl();
surface = viewRootImpl != null ? viewRootImpl.getSurfaceControl() : null;
}
+
if (mSurface != surface) {
mSurface = surface;
if (surface != null) {
dispatchTransactionSurface(mDepth);
- return true;
}
}
- return false;
}
@Override
@@ -250,8 +221,6 @@ public class DepthController implements StateHandler<LauncherState>,
setDepth(toDepth);
} else if (toState == LauncherState.OVERVIEW) {
dispatchTransactionSurface(mDepth);
- } else if (toState == LauncherState.BACKGROUND_APP) {
- mLauncher.getDragLayer().getViewTreeObserver().addOnDrawListener(mOnDrawListener);
}
}
@@ -290,27 +259,9 @@ public class DepthController implements StateHandler<LauncherState>,
if (Float.compare(mDepth, depthF) == 0) {
return;
}
- dispatchTransactionSurface(depthF);
- mDepth = depthF;
- }
-
- public void onOverlayScrollChanged(float progress) {
- if (!OVERLAY_SCROLL_ENABLED) {
- return;
- }
- // Add some padding to the progress, such we don't change the depth on the last frames of
- // the animation. It's possible that a user flinging the feed quickly would scroll
- // horizontally by accident, causing the device to enter client composition unnecessarily.
- progress = Math.min(progress * 1.1f, 1f);
-
- // Round out the progress to dedupe frequent, non-perceptable updates
- int progressI = (int) (progress * 256);
- float progressF = Utilities.boundToRange(progressI / 256f, 0f, 1f);
- if (Float.compare(mOverlayScrollProgress, progressF) == 0) {
- return;
+ if (dispatchTransactionSurface(depthF)) {
+ mDepth = depthF;
}
- mOverlayScrollProgress = progressF;
- dispatchTransactionSurface(mDepth);
}
private boolean dispatchTransactionSurface(float depth) {
@@ -319,32 +270,22 @@ public class DepthController implements StateHandler<LauncherState>,
return false;
}
ensureDependencies();
- depth = Math.max(depth, mOverlayScrollProgress);
IBinder windowToken = mLauncher.getRootView().getWindowToken();
if (windowToken != null) {
mWallpaperManager.setWallpaperZoomOut(windowToken, depth);
}
if (supportsBlur) {
- boolean hasOpaqueBg = mLauncher.getScrimView().isFullyOpaque();
- boolean isSurfaceOpaque = !mHasContentBehindLauncher && hasOpaqueBg;
+ // We cannot mark the window as opaque in overview because there will be an app window
+ // below the launcher layer, and we need to draw it -- without blurs.
+ boolean isOverview = mLauncher.isInState(LauncherState.OVERVIEW);
+ boolean opaque = mLauncher.getScrimView().isFullyOpaque() && !isOverview;
- mCurrentBlur = !mCrossWindowBlursEnabled || mBlurDisabledForAppLaunch || hasOpaqueBg
- ? 0 : (int) (depth * mMaxBlurRadius);
+ int blur = opaque || isOverview || !mCrossWindowBlursEnabled
+ || mBlurDisabledForAppLaunch ? 0 : (int) (depth * mMaxBlurRadius);
SurfaceControl.Transaction transaction = new SurfaceControl.Transaction()
- .setBackgroundBlurRadius(mSurface, mCurrentBlur)
- .setOpaque(mSurface, isSurfaceOpaque);
-
- // Set early wake-up flags when we know we're executing an expensive operation, this way
- // SurfaceFlinger will adjust its internal offsets to avoid jank.
- boolean wantsEarlyWakeUp = depth > 0 && depth < 1;
- if (wantsEarlyWakeUp && !mInEarlyWakeUp) {
- transaction.setEarlyWakeupStart();
- mInEarlyWakeUp = true;
- } else if (!wantsEarlyWakeUp && mInEarlyWakeUp) {
- transaction.setEarlyWakeupEnd();
- mInEarlyWakeUp = false;
- }
+ .setBackgroundBlurRadius(mSurface, blur)
+ .setOpaque(mSurface, opaque);
AttachedSurfaceControl rootSurfaceControl =
mLauncher.getRootView().getRootSurfaceControl();
@@ -371,18 +312,4 @@ public class DepthController implements StateHandler<LauncherState>,
mwAnimation.setAutoCancel(true);
mwAnimation.start();
}
-
- public void dump(String prefix, PrintWriter writer) {
- writer.println(prefix + this.getClass().getSimpleName());
- writer.println(prefix + "\tmMaxBlurRadius=" + mMaxBlurRadius);
- writer.println(prefix + "\tmCrossWindowBlursEnabled=" + mCrossWindowBlursEnabled);
- writer.println(prefix + "\tmSurface=" + mSurface);
- writer.println(prefix + "\tmOverlayScrollProgress=" + mOverlayScrollProgress);
- writer.println(prefix + "\tmDepth=" + mDepth);
- writer.println(prefix + "\tmCurrentBlur=" + mCurrentBlur);
- writer.println(prefix + "\tmBlurDisabledForAppLaunch=" + mBlurDisabledForAppLaunch);
- writer.println(prefix + "\tmInEarlyWakeUp=" + mInEarlyWakeUp);
- writer.println(prefix + "\tmIgnoreStateChangesDuringMultiWindowAnimation="
- + mIgnoreStateChangesDuringMultiWindowAnimation);
- }
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/BaseTaskbarContext.java b/quickstep/src/com/android/launcher3/taskbar/BaseTaskbarContext.java
deleted file mode 100644
index b4052e3d71..0000000000
--- a/quickstep/src/com/android/launcher3/taskbar/BaseTaskbarContext.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.launcher3.taskbar;
-
-import android.content.Context;
-import android.view.ContextThemeWrapper;
-import android.view.LayoutInflater;
-
-import com.android.launcher3.DeviceProfile.DeviceProfileListenable;
-import com.android.launcher3.DeviceProfile.OnDeviceProfileChangeListener;
-import com.android.launcher3.util.Themes;
-import com.android.launcher3.views.AppLauncher;
-
-import java.util.ArrayList;
-import java.util.List;
-
-// TODO(b/218912746): Share more behavior to avoid all apps context depending directly on taskbar.
-/** Base for common behavior between taskbar window contexts. */
-public abstract class BaseTaskbarContext extends ContextThemeWrapper implements AppLauncher,
- DeviceProfileListenable {
-
- protected final LayoutInflater mLayoutInflater;
- private final List<OnDeviceProfileChangeListener> mDPChangeListeners = new ArrayList<>();
-
- public BaseTaskbarContext(Context windowContext) {
- super(windowContext, Themes.getActivityThemeRes(windowContext));
- mLayoutInflater = LayoutInflater.from(this).cloneInContext(this);
- }
-
- @Override
- public final LayoutInflater getLayoutInflater() {
- return mLayoutInflater;
- }
-
- @Override
- public final List<OnDeviceProfileChangeListener> getOnDeviceProfileChangeListeners() {
- return mDPChangeListeners;
- }
-
- /** Callback invoked when a drag is initiated within this context. */
- public abstract void onDragStart();
-
- /** Callback invoked when a drag is finished within this context. */
- public abstract void onDragEnd();
-
- /** Callback invoked when a popup is shown or closed within this context. */
- public abstract void onPopupVisibilityChanged(boolean isVisible);
-}
diff --git a/quickstep/src/com/android/launcher3/taskbar/ButtonProvider.java b/quickstep/src/com/android/launcher3/taskbar/ButtonProvider.java
new file mode 100644
index 0000000000..540f748313
--- /dev/null
+++ b/quickstep/src/com/android/launcher3/taskbar/ButtonProvider.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2021 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.launcher3.taskbar;
+
+import static com.android.launcher3.taskbar.TaskbarNavButtonController.BUTTON_BACK;
+import static com.android.launcher3.taskbar.TaskbarNavButtonController.BUTTON_HOME;
+import static com.android.launcher3.taskbar.TaskbarNavButtonController.BUTTON_IME_SWITCH;
+import static com.android.launcher3.taskbar.TaskbarNavButtonController.BUTTON_RECENTS;
+
+import android.annotation.DrawableRes;
+import android.view.View;
+import android.widget.ImageView;
+
+import com.android.launcher3.R;
+import com.android.launcher3.taskbar.TaskbarNavButtonController.TaskbarButton;
+
+/**
+ * Creates Buttons for Taskbar for 3 button nav.
+ * Can add animations and state management for buttons in this class as things progress.
+ */
+public class ButtonProvider {
+
+ private final int mMarginLeftRight;
+ private final TaskbarActivityContext mContext;
+
+ public ButtonProvider(TaskbarActivityContext context) {
+ mContext = context;
+ mMarginLeftRight = context.getResources()
+ .getDimensionPixelSize(R.dimen.taskbar_icon_spacing);
+ }
+
+ public View getBack() {
+ // Back button
+ return getButtonForDrawable(R.drawable.ic_sysbar_back, BUTTON_BACK);
+ }
+
+ public View getDown() {
+ // Ime down button
+ return getButtonForDrawable(R.drawable.ic_sysbar_back, BUTTON_BACK);
+ }
+
+ public View getHome() {
+ // Home button
+ return getButtonForDrawable(R.drawable.ic_sysbar_home, BUTTON_HOME);
+ }
+
+ public View getRecents() {
+ // Recents button
+ return getButtonForDrawable(R.drawable.ic_sysbar_recent, BUTTON_RECENTS);
+ }
+
+ public View getImeSwitcher() {
+ // IME Switcher Button
+ return getButtonForDrawable(R.drawable.ic_ime_switcher, BUTTON_IME_SWITCH);
+ }
+
+ private View getButtonForDrawable(@DrawableRes int drawableId, @TaskbarButton int buttonType) {
+ ImageView buttonView = new ImageView(mContext);
+ buttonView.setImageResource(drawableId);
+ buttonView.setBackgroundResource(R.drawable.taskbar_icon_click_feedback_roundrect);
+ buttonView.setPadding(mMarginLeftRight, 0, mMarginLeftRight, 0);
+ buttonView.setOnClickListener(view -> mContext.onNavigationButtonClick(buttonType));
+ return buttonView;
+ }
+
+}
diff --git a/quickstep/src/com/android/launcher3/taskbar/DesktopNavbarButtonsViewController.java b/quickstep/src/com/android/launcher3/taskbar/DesktopNavbarButtonsViewController.java
deleted file mode 100644
index 0ab3cfd547..0000000000
--- a/quickstep/src/com/android/launcher3/taskbar/DesktopNavbarButtonsViewController.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.launcher3.taskbar;
-
-import static com.android.launcher3.taskbar.TaskbarNavButtonController.BUTTON_NOTIFICATIONS;
-import static com.android.launcher3.taskbar.TaskbarNavButtonController.BUTTON_QUICK_SETTINGS;
-
-import android.view.ViewGroup;
-import android.widget.FrameLayout;
-
-import com.android.launcher3.R;
-
-/**
- * Controller for managing buttons and status icons in taskbar in a desktop environment.
- */
-public class DesktopNavbarButtonsViewController extends NavbarButtonsViewController {
-
- private final TaskbarActivityContext mContext;
- private final FrameLayout mNavButtonsView;
- private final ViewGroup mNavButtonContainer;
-
- private TaskbarControllers mControllers;
-
- public DesktopNavbarButtonsViewController(TaskbarActivityContext context,
- FrameLayout navButtonsView) {
- super(context, navButtonsView);
- mContext = context;
- mNavButtonsView = navButtonsView;
- mNavButtonContainer = mNavButtonsView.findViewById(R.id.end_nav_buttons);
- }
-
- /**
- * Initializes the controller
- */
- @Override
- public void init(TaskbarControllers controllers) {
- mControllers = controllers;
- mNavButtonsView.getLayoutParams().height = mContext.getDeviceProfile().taskbarSize;
-
- // Quick settings and notifications buttons
- addButton(R.drawable.ic_sysbar_quick_settings, BUTTON_QUICK_SETTINGS,
- mNavButtonContainer, mControllers.navButtonController,
- R.id.quick_settings_button);
- addButton(R.drawable.ic_sysbar_notifications, BUTTON_NOTIFICATIONS,
- mNavButtonContainer, mControllers.navButtonController,
- R.id.notifications_button);
- }
-
- /** Cleans up on destroy */
- @Override
- public void onDestroy() { }
-}
diff --git a/quickstep/src/com/android/launcher3/taskbar/DesktopTaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/DesktopTaskbarUIController.java
deleted file mode 100644
index e2359c0d5e..0000000000
--- a/quickstep/src/com/android/launcher3/taskbar/DesktopTaskbarUIController.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2021 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.launcher3.taskbar;
-
-import com.android.launcher3.BaseQuickstepLauncher;
-
-/**
- * A data source which integrates with a Launcher instance, used specifically for a
- * desktop environment.
- */
-public class DesktopTaskbarUIController extends TaskbarUIController {
-
- private final BaseQuickstepLauncher mLauncher;
-
- public DesktopTaskbarUIController(BaseQuickstepLauncher launcher) {
- mLauncher = launcher;
- }
-
- @Override
- protected void init(TaskbarControllers taskbarControllers) {
- mLauncher.getHotseat().setIconsAlpha(0f);
- }
-
- @Override
- protected void onDestroy() {
- mLauncher.getHotseat().setIconsAlpha(1f);
- }
-
- @Override
- /** Disable taskbar stashing in desktop environment. */
- public boolean supportsVisualStashing() {
- return false;
- }
-}
diff --git a/quickstep/src/com/android/launcher3/taskbar/FallbackTaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/FallbackTaskbarUIController.java
deleted file mode 100644
index f1e67479f5..0000000000
--- a/quickstep/src/com/android/launcher3/taskbar/FallbackTaskbarUIController.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (C) 2021 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.launcher3.taskbar;
-
-import static com.android.launcher3.taskbar.TaskbarStashController.FLAG_IN_APP;
-import static com.android.launcher3.taskbar.TaskbarStashController.FLAG_IN_STASHED_LAUNCHER_STATE;
-import static com.android.launcher3.taskbar.TaskbarStashController.TASKBAR_STASH_DURATION;
-
-import android.animation.Animator;
-
-import com.android.launcher3.statemanager.StateManager;
-import com.android.quickstep.RecentsActivity;
-import com.android.quickstep.fallback.RecentsState;
-import com.android.quickstep.views.RecentsView;
-
-/**
- * A data source which integrates with the fallback RecentsActivity instance (for 3P launchers).
- */
-public class FallbackTaskbarUIController extends TaskbarUIController {
-
- private final RecentsActivity mRecentsActivity;
-
- private final StateManager.StateListener<RecentsState> mStateListener =
- new StateManager.StateListener<RecentsState>() {
- @Override
- public void onStateTransitionStart(RecentsState toState) {
- animateToRecentsState(toState);
-
- // Handle tapping on live tile.
- RecentsView recentsView = mRecentsActivity.getOverviewPanel();
- recentsView.setTaskLaunchListener(toState == RecentsState.DEFAULT
- ? (() -> animateToRecentsState(RecentsState.BACKGROUND_APP)) : null);
- }
- };
-
- public FallbackTaskbarUIController(RecentsActivity recentsActivity) {
- mRecentsActivity = recentsActivity;
- }
-
- @Override
- protected void init(TaskbarControllers taskbarControllers) {
- super.init(taskbarControllers);
-
- mRecentsActivity.setTaskbarUIController(this);
- mRecentsActivity.getStateManager().addStateListener(mStateListener);
- }
-
- @Override
- protected void onDestroy() {
- super.onDestroy();
- mRecentsActivity.setTaskbarUIController(null);
- mRecentsActivity.getStateManager().removeStateListener(mStateListener);
- }
-
- /**
- * Creates an animation to animate the taskbar for the given state (but does not start it).
- * Currently this animation just force stashes the taskbar in Overview.
- */
- public Animator createAnimToRecentsState(RecentsState toState, long duration) {
- boolean forceStashed = toState.hasOverviewActions();
- TaskbarStashController controller = mControllers.taskbarStashController;
- // Set both FLAG_IN_STASHED_LAUNCHER_STATE and FLAG_IN_APP to ensure the state is respected.
- // For all other states, just use the current stashed-in-app setting (e.g. if long clicked).
- controller.updateStateForFlag(FLAG_IN_STASHED_LAUNCHER_STATE, forceStashed);
- controller.updateStateForFlag(FLAG_IN_APP, !forceStashed);
- return controller.applyStateWithoutStart(duration);
- }
-
- private void animateToRecentsState(RecentsState toState) {
- Animator anim = createAnimToRecentsState(toState, TASKBAR_STASH_DURATION);
- if (anim != null) {
- anim.start();
- }
- }
-}
diff --git a/quickstep/src/com/android/launcher3/taskbar/ImeBarView.java b/quickstep/src/com/android/launcher3/taskbar/ImeBarView.java
new file mode 100644
index 0000000000..287caab44b
--- /dev/null
+++ b/quickstep/src/com/android/launcher3/taskbar/ImeBarView.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2021 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.launcher3.taskbar;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.RelativeLayout;
+
+import com.android.launcher3.views.ActivityContext;
+
+public class ImeBarView extends RelativeLayout {
+
+ private ButtonProvider mButtonProvider;
+ private View mImeView;
+
+ public ImeBarView(Context context) {
+ this(context, null);
+ }
+
+ public ImeBarView(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public ImeBarView(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ }
+
+ public void init(ButtonProvider buttonProvider) {
+ mButtonProvider = buttonProvider;
+
+ ActivityContext context = getActivityContext();
+ RelativeLayout.LayoutParams imeParams = new RelativeLayout.LayoutParams(
+ context.getDeviceProfile().iconSizePx,
+ context.getDeviceProfile().iconSizePx
+ );
+ RelativeLayout.LayoutParams downParams = new RelativeLayout.LayoutParams(imeParams);
+
+ imeParams.addRule(ALIGN_PARENT_END);
+ imeParams.setMarginEnd(context.getDeviceProfile().iconSizePx);
+ downParams.setMarginStart(context.getDeviceProfile().iconSizePx);
+ downParams.addRule(ALIGN_PARENT_START);
+
+ // Down Arrow
+ View downView = mButtonProvider.getDown();
+ downView.setLayoutParams(downParams);
+ downView.setRotation(-90);
+ addView(downView);
+
+ // IME switcher button
+ mImeView = mButtonProvider.getImeSwitcher();
+ mImeView.setLayoutParams(imeParams);
+ addView(mImeView);
+ }
+
+ public void setImeSwitcherVisibility(boolean show) {
+ mImeView.setVisibility(show ? VISIBLE : GONE);
+ }
+
+ private <T extends Context & ActivityContext> T getActivityContext() {
+ return ActivityContext.lookupContext(getContext());
+ }
+}
diff --git a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
index ca30e72609..c2d107c22d 100644
--- a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
@@ -15,22 +15,13 @@
*/
package com.android.launcher3.taskbar;
-import static com.android.launcher3.taskbar.TaskbarLauncherStateController.FLAG_RESUMED;
-import static com.android.systemui.shared.system.WindowManagerWrapper.ITYPE_EXTRA_NAVIGATION_BAR;
-
import android.animation.Animator;
-import android.animation.AnimatorSet;
-import android.annotation.ColorInt;
-import android.os.RemoteException;
-import android.util.Log;
-import android.util.SparseArray;
+import android.animation.AnimatorListenerAdapter;
+import android.graphics.Rect;
+import android.graphics.RectF;
import android.view.MotionEvent;
-import android.view.TaskTransitionSpec;
-import android.view.WindowManagerGlobal;
-import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
-import androidx.annotation.VisibleForTesting;
import com.android.launcher3.BaseQuickstepLauncher;
import com.android.launcher3.DeviceProfile;
@@ -38,350 +29,247 @@ import com.android.launcher3.LauncherState;
import com.android.launcher3.QuickstepTransitionManager;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
-import com.android.launcher3.logging.InstanceId;
-import com.android.launcher3.logging.InstanceIdSequence;
-import com.android.launcher3.model.data.ItemInfo;
-import com.android.launcher3.model.data.ItemInfoWithIcon;
-import com.android.launcher3.util.OnboardingPrefs;
-import com.android.quickstep.AnimatedFloat;
-import com.android.quickstep.RecentsAnimationCallbacks;
-
-import java.io.PrintWriter;
-import java.util.Arrays;
-import java.util.Set;
-import java.util.stream.Stream;
+import com.android.launcher3.anim.PendingAnimation;
+import com.android.launcher3.states.StateAnimationConfig;
+
/**
* A data source which integrates with a Launcher instance
+ * TODO: Rename to have Launcher prefix
*/
-public class LauncherTaskbarUIController extends TaskbarUIController {
- private static final String TAG = "TaskbarUIController";
-
- public static final int MINUS_ONE_PAGE_PROGRESS_INDEX = 0;
- public static final int ALL_APPS_PAGE_PROGRESS_INDEX = 1;
- public static final int WIDGETS_PAGE_PROGRESS_INDEX = 2;
- public static final int SYSUI_SURFACE_PROGRESS_INDEX = 3;
-
- private final SparseArray<Float> mTaskbarInAppDisplayProgress = new SparseArray<>(4);
+public class LauncherTaskbarUIController extends TaskbarUIController {
private final BaseQuickstepLauncher mLauncher;
+ private final TaskbarStateHandler mTaskbarStateHandler;
+ private final TaskbarAnimationController mTaskbarAnimationController;
+ private final TaskbarHotseatController mHotseatController;
- private final DeviceProfile.OnDeviceProfileChangeListener mOnDeviceProfileChangeListener =
- dp -> {
- onStashedInAppChanged(dp);
- if (mControllers != null && mControllers.taskbarViewController != null) {
- mControllers.taskbarViewController.onRotationChanged(dp);
- }
- };
+ private final TaskbarActivityContext mContext;
+ final TaskbarDragLayer mTaskbarDragLayer;
+ final TaskbarView mTaskbarView;
+
+ private @Nullable Animator mAnimator;
+ private boolean mIsAnimatingToLauncher;
- // Initialized in init.
- private AnimatedFloat mTaskbarOverrideBackgroundAlpha;
- private TaskbarKeyguardController mKeyguardController;
- private final TaskbarLauncherStateController
- mTaskbarLauncherStateController = new TaskbarLauncherStateController();
+ public LauncherTaskbarUIController(
+ BaseQuickstepLauncher launcher, TaskbarActivityContext context) {
+ mContext = context;
+ mTaskbarDragLayer = context.getDragLayer();
+ mTaskbarView = mTaskbarDragLayer.findViewById(R.id.taskbar_view);
- public LauncherTaskbarUIController(BaseQuickstepLauncher launcher) {
mLauncher = launcher;
+ mTaskbarStateHandler = mLauncher.getTaskbarStateHandler();
+ mTaskbarAnimationController = new TaskbarAnimationController(mLauncher,
+ createTaskbarAnimationControllerCallbacks());
+ mHotseatController = new TaskbarHotseatController(
+ mLauncher, mTaskbarView::updateHotseatItems);
}
@Override
- protected void init(TaskbarControllers taskbarControllers) {
- super.init(taskbarControllers);
-
- mTaskbarLauncherStateController.init(mControllers, mLauncher);
- mTaskbarOverrideBackgroundAlpha = mControllers.taskbarDragLayerController
- .getOverrideBackgroundAlpha();
-
+ protected void onCreate() {
+ mTaskbarStateHandler.setAnimationController(mTaskbarAnimationController);
+ mTaskbarAnimationController.init();
+ mHotseatController.init();
+ setTaskbarViewVisible(!mLauncher.hasBeenResumed());
+ alignRealHotseatWithTaskbar();
mLauncher.setTaskbarUIController(this);
- mKeyguardController = taskbarControllers.taskbarKeyguardController;
-
- onLauncherResumedOrPaused(mLauncher.hasBeenResumed(), true /* fromInit */);
-
- onStashedInAppChanged(mLauncher.getDeviceProfile());
- mLauncher.addOnDeviceProfileChangeListener(mOnDeviceProfileChangeListener);
}
@Override
protected void onDestroy() {
- super.onDestroy();
- onLauncherResumedOrPaused(false);
- mTaskbarLauncherStateController.onDestroy();
-
+ if (mAnimator != null) {
+ // End this first, in case it relies on properties that are about to be cleaned up.
+ mAnimator.end();
+ }
+ mTaskbarStateHandler.setAnimationController(null);
+ mTaskbarAnimationController.cleanup();
+ mHotseatController.cleanup();
+ setTaskbarViewVisible(true);
+ mLauncher.getHotseat().setIconsAlpha(1f);
mLauncher.setTaskbarUIController(null);
- mLauncher.removeOnDeviceProfileChangeListener(mOnDeviceProfileChangeListener);
- updateTaskTransitionSpec(true);
}
@Override
protected boolean isTaskbarTouchable() {
- return !mTaskbarLauncherStateController.isAnimatingToLauncher();
+ return !mIsAnimatingToLauncher;
}
- public void setShouldDelayLauncherStateAnim(boolean shouldDelayLauncherStateAnim) {
- mTaskbarLauncherStateController.setShouldDelayLauncherStateAnim(
- shouldDelayLauncherStateAnim);
- }
+ private TaskbarAnimationControllerCallbacks createTaskbarAnimationControllerCallbacks() {
+ return new TaskbarAnimationControllerCallbacks() {
+ @Override
+ public void updateTaskbarBackgroundAlpha(float alpha) {
+ mTaskbarDragLayer.setTaskbarBackgroundAlpha(alpha);
+ }
- /**
- * Enables manual taskbar stashing. This method should only be used for tests that need to
- * stash/unstash the taskbar.
- */
- @VisibleForTesting
- public void enableManualStashingForTests(boolean enableManualStashing) {
- mControllers.taskbarStashController.enableManualStashingForTests(enableManualStashing);
- }
+ @Override
+ public void updateTaskbarVisibilityAlpha(float alpha) {
+ mTaskbarView.setAlpha(alpha);
+ }
- /**
- * Unstashes the Taskbar if it is stashed. This method should only be used to unstash the
- * taskbar at the end of a test.
- */
- @VisibleForTesting
- public void unstashTaskbarIfStashed() {
- mControllers.taskbarStashController.onLongPressToUnstashTaskbar();
- }
+ @Override
+ public void updateImeBarVisibilityAlpha(float alpha) {
+ mTaskbarDragLayer.updateImeBarVisibilityAlpha(alpha);
+ }
- /**
- * Adds the Launcher resume animator to the given animator set.
- *
- * This should be used to run a Launcher resume animation whose progress matches a
- * swipe progress.
- *
- * @param placeholderDuration a placeholder duration to be used to ensure all full-length
- * sub-animations are properly coordinated. This duration should not
- * actually be used since this animation tracks a swipe progress.
- */
- protected void addLauncherResumeAnimation(AnimatorSet animation, int placeholderDuration) {
- animation.play(onLauncherResumedOrPaused(
- /* isResumed= */ true,
- /* fromInit= */ false,
- /* startAnimation= */ false,
- placeholderDuration));
+ @Override
+ public void updateTaskbarScale(float scale) {
+ mTaskbarView.setScaleX(scale);
+ mTaskbarView.setScaleY(scale);
+ }
+
+ @Override
+ public void updateTaskbarTranslationY(float translationY) {
+ if (translationY < 0) {
+ // Resize to accommodate the max translation we'll reach.
+ mContext.setTaskbarWindowHeight(mContext.getDeviceProfile().taskbarSize
+ + mLauncher.getHotseat().getTaskbarOffsetY());
+ } else {
+ mContext.setTaskbarWindowHeight(mContext.getDeviceProfile().taskbarSize);
+ }
+ mTaskbarView.setTranslationY(translationY);
+ }
+ };
}
/**
* Should be called from onResume() and onPause(), and animates the Taskbar accordingly.
*/
public void onLauncherResumedOrPaused(boolean isResumed) {
- onLauncherResumedOrPaused(isResumed, false /* fromInit */);
- }
-
- private void onLauncherResumedOrPaused(boolean isResumed, boolean fromInit) {
- onLauncherResumedOrPaused(
- isResumed,
- fromInit,
- /* startAnimation= */ true,
- QuickstepTransitionManager.CONTENT_ALPHA_DURATION);
- }
-
- @Nullable
- private Animator onLauncherResumedOrPaused(
- boolean isResumed, boolean fromInit, boolean startAnimation, int duration) {
- if (mKeyguardController.isScreenOff()) {
- if (!isResumed) {
- return null;
- } else {
- // Resuming implicitly means device unlocked
- mKeyguardController.setScreenOn();
- }
+ long duration = QuickstepTransitionManager.CONTENT_ALPHA_DURATION;
+ if (mAnimator != null) {
+ mAnimator.cancel();
}
-
- mTaskbarLauncherStateController.updateStateForFlag(FLAG_RESUMED, isResumed);
- return mTaskbarLauncherStateController.applyState(fromInit ? 0 : duration, startAnimation);
+ if (isResumed) {
+ mAnimator = createAnimToLauncher(null, duration);
+ } else {
+ mAnimator = createAnimToApp(duration);
+ }
+ mAnimator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mAnimator = null;
+ }
+ });
+ mAnimator.start();
}
/**
- * Create Taskbar animation when going from an app to Launcher as part of recents transition.
+ * Create Taskbar animation when going from an app to Launcher.
* @param toState If known, the state we will end up in when reaching Launcher.
- * @param callbacks callbacks to track the recents animation lifecycle. The state change is
- * automatically reset once the recents animation finishes
*/
- public Animator createAnimToLauncher(@NonNull LauncherState toState,
- @NonNull RecentsAnimationCallbacks callbacks, long duration) {
- return mTaskbarLauncherStateController.createAnimToLauncher(toState, callbacks, duration);
- }
-
- /**
- * @param ev MotionEvent in screen coordinates.
- * @return Whether any Taskbar item could handle the given MotionEvent if given the chance.
- */
- public boolean isEventOverAnyTaskbarItem(MotionEvent ev) {
- return mControllers.taskbarViewController.isEventOverAnyItem(ev)
- || mControllers.navbarButtonsViewController.isEventOverAnyItem(ev);
- }
+ public Animator createAnimToLauncher(@Nullable LauncherState toState, long duration) {
+ PendingAnimation anim = new PendingAnimation(duration);
+ anim.add(mTaskbarAnimationController.createAnimToBackgroundAlpha(0, duration));
+ if (toState != null) {
+ mTaskbarStateHandler.setStateWithAnimation(toState, new StateAnimationConfig(), anim);
+ }
- public boolean isDraggingItem() {
- return mControllers.taskbarDragController.isDragging();
- }
+ anim.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationStart(Animator animation) {
+ mIsAnimatingToLauncher = true;
+ mTaskbarView.setHolesAllowedInLayout(true);
+ mTaskbarView.updateHotseatItemsVisibility();
+ }
- @Override
- protected void onStashedInAppChanged() {
- onStashedInAppChanged(mLauncher.getDeviceProfile());
- }
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mIsAnimatingToLauncher = false;
+ setTaskbarViewVisible(false);
+ }
+ });
- private void onStashedInAppChanged(DeviceProfile deviceProfile) {
- boolean taskbarStashedInApps = mControllers.taskbarStashController.isStashedInApp();
- deviceProfile.isTaskbarPresentInApps = !taskbarStashedInApps;
- updateTaskTransitionSpec(taskbarStashedInApps);
+ return anim.buildAnim();
}
- private void updateTaskTransitionSpec(boolean taskbarIsHidden) {
- try {
- if (taskbarIsHidden) {
- // Clear custom task transition settings when the taskbar is stashed
- WindowManagerGlobal.getWindowManagerService().clearTaskTransitionSpec();
- } else {
- // Adjust task transition spec to account for taskbar being visible
- @ColorInt int taskAnimationBackgroundColor =
- mLauncher.getColor(R.color.taskbar_background);
-
- TaskTransitionSpec customTaskAnimationSpec = new TaskTransitionSpec(
- taskAnimationBackgroundColor,
- Set.of(ITYPE_EXTRA_NAVIGATION_BAR)
- );
- WindowManagerGlobal.getWindowManagerService()
- .setTaskTransitionSpec(customTaskAnimationSpec);
+ private Animator createAnimToApp(long duration) {
+ PendingAnimation anim = new PendingAnimation(duration);
+ anim.add(mTaskbarAnimationController.createAnimToBackgroundAlpha(1, duration));
+ anim.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationStart(Animator animation) {
+ mTaskbarView.updateHotseatItemsVisibility();
+ setTaskbarViewVisible(true);
}
- } catch (RemoteException e) {
- // This shouldn't happen but if it does task animations won't look good until the
- // taskbar stashing state is changed.
- Log.e(TAG, "Failed to update task transition spec to account for new taskbar state",
- e);
- }
- }
- /**
- * Sets whether the background behind the taskbar/nav bar should be hidden.
- */
- public void forceHideBackground(boolean forceHide) {
- mTaskbarOverrideBackgroundAlpha.updateValue(forceHide ? 0 : 1);
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mTaskbarView.setHolesAllowedInLayout(false);
+ }
+ });
+ return anim.buildAnim();
}
@Override
- public Stream<ItemInfoWithIcon> getAppIconsForEdu() {
- return Arrays.stream(mLauncher.getAppsView().getAppsStore().getApps());
+ protected void onImeVisible(TaskbarDragLayer containerView, boolean isVisible) {
+ mTaskbarAnimationController.animateToVisibilityForIme(isVisible ? 0 : 1);
}
/**
- * Starts the taskbar education flow, if the user hasn't seen it yet.
+ * Should be called when one or more items in the Hotseat have changed.
*/
- public void showEdu() {
- if (!shouldShowEdu()) {
- return;
- }
- mLauncher.getOnboardingPrefs().markChecked(OnboardingPrefs.TASKBAR_EDU_SEEN);
-
- mControllers.taskbarEduController.showEdu();
+ public void onHotseatUpdated() {
+ mHotseatController.onHotseatUpdated();
}
/**
- * Whether the taskbar education should be shown.
- */
- public boolean shouldShowEdu() {
- return !Utilities.IS_RUNNING_IN_TEST_HARNESS
- && !mLauncher.getOnboardingPrefs().getBoolean(OnboardingPrefs.TASKBAR_EDU_SEEN);
- }
-
- /**
- * Manually ends the taskbar education flow.
+ * @param ev MotionEvent in screen coordinates.
+ * @return Whether any Taskbar item could handle the given MotionEvent if given the chance.
*/
- public void hideEdu() {
- mControllers.taskbarEduController.hideEdu();
+ public boolean isEventOverAnyTaskbarItem(MotionEvent ev) {
+ return mTaskbarView.isEventOverAnyItem(ev);
}
- @Override
- public void onTaskbarIconLaunched(ItemInfo item) {
- InstanceId instanceId = new InstanceIdSequence().newInstanceId();
- mLauncher.logAppLaunch(mControllers.taskbarActivityContext.getStatsLogManager(), item,
- instanceId);
+ public boolean isDraggingItem() {
+ return mTaskbarView.isDraggingItem();
}
+ /**
+ * Pads the Hotseat to line up exactly with Taskbar's copy of the Hotseat.
+ */
@Override
- public void setSystemGestureInProgress(boolean inProgress) {
- super.setSystemGestureInProgress(inProgress);
- // Launcher's ScrimView will draw the background throughout the gesture. But once the
- // gesture ends, start drawing taskbar's background again since launcher might stop drawing.
- forceHideBackground(inProgress);
+ public void alignRealHotseatWithTaskbar() {
+ Rect hotseatBounds = new Rect();
+ DeviceProfile grid = mLauncher.getDeviceProfile();
+ int hotseatHeight = grid.workspacePadding.bottom + grid.taskbarSize;
+ int taskbarOffset = mLauncher.getHotseat().getTaskbarOffsetY();
+ int hotseatTopDiff = hotseatHeight - grid.taskbarSize - taskbarOffset;
+ int hotseatBottomDiff = taskbarOffset;
+
+ RectF hotseatBoundsF = mTaskbarView.getHotseatBounds();
+ Utilities.scaleRectFAboutPivot(hotseatBoundsF, getTaskbarScaleOnHome(),
+ mTaskbarView.getPivotX(), mTaskbarView.getPivotY());
+ hotseatBoundsF.round(hotseatBounds);
+ mLauncher.getHotseat().setPadding(hotseatBounds.left,
+ hotseatBounds.top + hotseatTopDiff,
+ mTaskbarView.getWidth() - hotseatBounds.right,
+ mTaskbarView.getHeight() - hotseatBounds.bottom + hotseatBottomDiff);
}
/**
- * Animates Taskbar elements during a transition to a Launcher state that should use in-app
- * layouts.
- *
- * @param progress [0, 1]
- * 0 => use home layout
- * 1 => use in-app layout
+ * Returns the ratio of the taskbar icon size on home vs in an app.
*/
- public void onTaskbarInAppDisplayProgressUpdate(float progress, int progressIndex) {
- if (mControllers == null) {
- // This method can be called before init() is called.
- return;
- }
- mTaskbarInAppDisplayProgress.put(progressIndex, progress);
- if (!mControllers.taskbarStashController.isInApp()
- && !mTaskbarLauncherStateController.isAnimatingToLauncher()) {
- // Only animate the nav buttons while home and not animating home, otherwise let
- // the TaskbarViewController handle it.
- mControllers.navbarButtonsViewController
- .getTaskbarNavButtonTranslationYForInAppDisplay()
- .updateValue(mLauncher.getDeviceProfile().getTaskbarOffsetY()
- * getInAppDisplayProgress());
- }
+ public float getTaskbarScaleOnHome() {
+ DeviceProfile inAppDp = mContext.getDeviceProfile();
+ DeviceProfile onHomeDp = mLauncher.getDeviceProfile();
+ return (float) onHomeDp.cellWidthPx / inAppDp.cellWidthPx;
}
- /** Returns true iff any in-app display progress > 0. */
- public boolean shouldUseInAppLayout() {
- return getInAppDisplayProgress() > 0;
- }
-
- private float getInAppDisplayProgress(int index) {
- if (!mTaskbarInAppDisplayProgress.contains(index)) {
- mTaskbarInAppDisplayProgress.put(index, 0f);
- }
- return mTaskbarInAppDisplayProgress.get(index);
+ void setTaskbarViewVisible(boolean isVisible) {
+ mTaskbarView.setIconsVisibility(isVisible);
+ mLauncher.getHotseat().setIconsAlpha(isVisible ? 0f : 1f);
}
- private float getInAppDisplayProgress() {
- return Stream.of(
- getInAppDisplayProgress(MINUS_ONE_PAGE_PROGRESS_INDEX),
- getInAppDisplayProgress(ALL_APPS_PAGE_PROGRESS_INDEX),
- getInAppDisplayProgress(WIDGETS_PAGE_PROGRESS_INDEX),
- getInAppDisplayProgress(SYSUI_SURFACE_PROGRESS_INDEX))
- .max(Float::compareTo)
- .get();
- }
-
- @Override
- public void dumpLogs(String prefix, PrintWriter pw) {
- super.dumpLogs(prefix, pw);
-
- pw.println(String.format(
- "%s\tmTaskbarOverrideBackgroundAlpha=%.2f",
- prefix,
- mTaskbarOverrideBackgroundAlpha.value));
-
- pw.println(String.format("%s\tTaskbar in-app display progress:", prefix));
- if (mControllers == null) {
- pw.println(String.format("%s\t\tMissing mControllers", prefix));
- } else {
- pw.println(String.format(
- "%s\t\tprogress at MINUS_ONE_PAGE_PROGRESS_INDEX=%.2f",
- prefix,
- getInAppDisplayProgress(MINUS_ONE_PAGE_PROGRESS_INDEX)));
- pw.println(String.format(
- "%s\t\tprogress at ALL_APPS_PAGE_PROGRESS_INDEX=%.2f",
- prefix,
- getInAppDisplayProgress(ALL_APPS_PAGE_PROGRESS_INDEX)));
- pw.println(String.format(
- "%s\t\tprogress at WIDGETS_PAGE_PROGRESS_INDEX=%.2f",
- prefix,
- getInAppDisplayProgress(WIDGETS_PAGE_PROGRESS_INDEX)));
- pw.println(String.format(
- "%s\t\tprogress at SYSUI_SURFACE_PROGRESS_INDEX=%.2f",
- prefix,
- getInAppDisplayProgress(SYSUI_SURFACE_PROGRESS_INDEX)));
- }
-
- mTaskbarLauncherStateController.dumpLogs(prefix + "\t", pw);
+ /**
+ * Contains methods that TaskbarAnimationController can call to interface with
+ * TaskbarController.
+ */
+ protected interface TaskbarAnimationControllerCallbacks {
+ void updateTaskbarBackgroundAlpha(float alpha);
+ void updateTaskbarVisibilityAlpha(float alpha);
+ void updateImeBarVisibilityAlpha(float alpha);
+ void updateTaskbarScale(float scale);
+ void updateTaskbarTranslationY(float translationY);
}
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java b/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java
deleted file mode 100644
index 5d576f7bf5..0000000000
--- a/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java
+++ /dev/null
@@ -1,902 +0,0 @@
-/*
- * Copyright (C) 2021 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.launcher3.taskbar;
-
-import static com.android.launcher3.LauncherAnimUtils.VIEW_TRANSLATE_X;
-import static com.android.launcher3.Utilities.getDescendantCoordRelativeToAncestor;
-import static com.android.launcher3.taskbar.LauncherTaskbarUIController.SYSUI_SURFACE_PROGRESS_INDEX;
-import static com.android.launcher3.taskbar.TaskbarNavButtonController.BUTTON_A11Y;
-import static com.android.launcher3.taskbar.TaskbarNavButtonController.BUTTON_BACK;
-import static com.android.launcher3.taskbar.TaskbarNavButtonController.BUTTON_HOME;
-import static com.android.launcher3.taskbar.TaskbarNavButtonController.BUTTON_IME_SWITCH;
-import static com.android.launcher3.taskbar.TaskbarNavButtonController.BUTTON_RECENTS;
-import static com.android.launcher3.taskbar.TaskbarViewController.ALPHA_INDEX_KEYGUARD;
-import static com.android.launcher3.taskbar.Utilities.appendFlag;
-import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_A11Y_BUTTON_CLICKABLE;
-import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE;
-import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_BACK_DISABLED;
-import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_HOME_DISABLED;
-import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_IME_SHOWING;
-import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_IME_SWITCHER_SHOWING;
-import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED;
-import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_OVERVIEW_DISABLED;
-import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_QUICK_SETTINGS_EXPANDED;
-import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_SCREEN_PINNING;
-import static com.android.systemui.shared.system.ViewTreeObserverWrapper.InsetsInfo.TOUCHABLE_INSETS_REGION;
-
-import android.animation.ArgbEvaluator;
-import android.animation.ObjectAnimator;
-import android.annotation.DrawableRes;
-import android.annotation.IdRes;
-import android.annotation.LayoutRes;
-import android.content.pm.ActivityInfo.Config;
-import android.content.res.ColorStateList;
-import android.content.res.Configuration;
-import android.graphics.Color;
-import android.graphics.Rect;
-import android.graphics.Region;
-import android.graphics.Region.Op;
-import android.graphics.drawable.AnimatedVectorDrawable;
-import android.graphics.drawable.PaintDrawable;
-import android.inputmethodservice.InputMethodService;
-import android.os.Handler;
-import android.util.Property;
-import android.view.Gravity;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.View.OnAttachStateChangeListener;
-import android.view.View.OnClickListener;
-import android.view.View.OnHoverListener;
-import android.view.ViewGroup;
-import android.view.WindowManager;
-import android.widget.FrameLayout;
-import android.widget.ImageView;
-import android.widget.LinearLayout;
-
-import com.android.launcher3.LauncherAnimUtils;
-import com.android.launcher3.R;
-import com.android.launcher3.Utilities;
-import com.android.launcher3.anim.AlphaUpdateListener;
-import com.android.launcher3.taskbar.TaskbarNavButtonController.TaskbarButton;
-import com.android.launcher3.util.MultiValueAlpha;
-import com.android.launcher3.util.TouchController;
-import com.android.launcher3.views.BaseDragLayer;
-import com.android.quickstep.AnimatedFloat;
-import com.android.systemui.shared.rotation.FloatingRotationButton;
-import com.android.systemui.shared.rotation.RotationButton;
-import com.android.systemui.shared.rotation.RotationButtonController;
-import com.android.systemui.shared.system.QuickStepContract;
-import com.android.systemui.shared.system.ViewTreeObserverWrapper;
-
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.StringJoiner;
-import java.util.function.IntPredicate;
-
-/**
- * Controller for managing nav bar buttons in taskbar
- */
-public class NavbarButtonsViewController implements TaskbarControllers.LoggableTaskbarController {
-
- private final Rect mTempRect = new Rect();
-
- private static final int FLAG_SWITCHER_SUPPORTED = 1 << 0;
- private static final int FLAG_IME_VISIBLE = 1 << 1;
- private static final int FLAG_ROTATION_BUTTON_VISIBLE = 1 << 2;
- private static final int FLAG_A11Y_VISIBLE = 1 << 3;
- private static final int FLAG_ONLY_BACK_FOR_BOUNCER_VISIBLE = 1 << 4;
- private static final int FLAG_KEYGUARD_VISIBLE = 1 << 5;
- private static final int FLAG_KEYGUARD_OCCLUDED = 1 << 6;
- private static final int FLAG_DISABLE_HOME = 1 << 7;
- private static final int FLAG_DISABLE_RECENTS = 1 << 8;
- private static final int FLAG_DISABLE_BACK = 1 << 9;
- private static final int FLAG_NOTIFICATION_SHADE_EXPANDED = 1 << 10;
- private static final int FLAG_SCREEN_PINNING_ACTIVE = 1 << 11;
-
- private static final int MASK_IME_SWITCHER_VISIBLE = FLAG_SWITCHER_SUPPORTED | FLAG_IME_VISIBLE;
-
- private static final String NAV_BUTTONS_SEPARATE_WINDOW_TITLE = "Taskbar Nav Buttons";
-
- public static final int ALPHA_INDEX_IMMERSIVE_MODE = 0;
- public static final int ALPHA_INDEX_KEYGUARD_OR_DISABLE = 1;
- private static final int NUM_ALPHA_CHANNELS = 2;
-
- private final ArrayList<StatePropertyHolder> mPropertyHolders = new ArrayList<>();
- private final ArrayList<ImageView> mAllButtons = new ArrayList<>();
- private int mState;
-
- private final TaskbarActivityContext mContext;
- private final FrameLayout mNavButtonsView;
- private final ViewGroup mNavButtonContainer;
- // Used for IME+A11Y buttons
- private final ViewGroup mEndContextualContainer;
- private final ViewGroup mStartContextualContainer;
- private final int mLightIconColor;
- private final int mDarkIconColor;
-
- private final AnimatedFloat mTaskbarNavButtonTranslationY = new AnimatedFloat(
- this::updateNavButtonTranslationY);
- private final AnimatedFloat mTaskbarNavButtonTranslationYForInAppDisplay = new AnimatedFloat(
- this::updateNavButtonTranslationY);
- private final AnimatedFloat mTaskbarNavButtonTranslationYForIme = new AnimatedFloat(
- this::updateNavButtonTranslationY);
- // Used for System UI state updates that should translate the nav button for in-app display.
- private final AnimatedFloat mNavButtonInAppDisplayProgressForSysui = new AnimatedFloat(
- this::updateNavButtonInAppDisplayProgressForSysui);
- private final AnimatedFloat mTaskbarNavButtonDarkIntensity = new AnimatedFloat(
- this::updateNavButtonDarkIntensity);
- private final AnimatedFloat mNavButtonDarkIntensityMultiplier = new AnimatedFloat(
- this::updateNavButtonDarkIntensity);
- private final RotationButtonListener mRotationButtonListener = new RotationButtonListener();
-
- private final Rect mFloatingRotationButtonBounds = new Rect();
-
- // Initialized in init.
- private TaskbarControllers mControllers;
- private boolean mIsImeRenderingNavButtons;
- private View mA11yButton;
- private int mSysuiStateFlags;
- private View mBackButton;
- private View mHomeButton;
- private MultiValueAlpha mBackButtonAlpha;
- private MultiValueAlpha mHomeButtonAlpha;
- private FloatingRotationButton mFloatingRotationButton;
-
- // Variables for moving nav buttons to a separate window above IME
- private boolean mAreNavButtonsInSeparateWindow = false;
- private BaseDragLayer<TaskbarActivityContext> mSeparateWindowParent; // Initialized in init.
- private final ViewTreeObserverWrapper.OnComputeInsetsListener mSeparateWindowInsetsComputer =
- this::onComputeInsetsForSeparateWindow;
- private final RecentsHitboxExtender mHitboxExtender = new RecentsHitboxExtender();
-
- public NavbarButtonsViewController(TaskbarActivityContext context, FrameLayout navButtonsView) {
- mContext = context;
- mNavButtonsView = navButtonsView;
- mNavButtonContainer = mNavButtonsView.findViewById(R.id.end_nav_buttons);
- mEndContextualContainer = mNavButtonsView.findViewById(R.id.end_contextual_buttons);
- mStartContextualContainer = mNavButtonsView.findViewById(R.id.start_contextual_buttons);
-
- mLightIconColor = context.getColor(R.color.taskbar_nav_icon_light_color);
- mDarkIconColor = context.getColor(R.color.taskbar_nav_icon_dark_color);
- }
-
- /**
- * Initializes the controller
- */
- public void init(TaskbarControllers controllers) {
- mControllers = controllers;
- mNavButtonsView.getLayoutParams().height = mContext.getDeviceProfile().taskbarSize;
-
- boolean isThreeButtonNav = mContext.isThreeButtonNav();
- mIsImeRenderingNavButtons =
- InputMethodService.canImeRenderGesturalNavButtons() && mContext.imeDrawsImeNavBar();
- if (!mIsImeRenderingNavButtons) {
- // IME switcher
- View imeSwitcherButton = addButton(R.drawable.ic_ime_switcher, BUTTON_IME_SWITCH,
- isThreeButtonNav ? mStartContextualContainer : mEndContextualContainer,
- mControllers.navButtonController, R.id.ime_switcher);
- mPropertyHolders.add(new StatePropertyHolder(imeSwitcherButton,
- flags -> ((flags & MASK_IME_SWITCHER_VISIBLE) == MASK_IME_SWITCHER_VISIBLE)
- && ((flags & FLAG_ROTATION_BUTTON_VISIBLE) == 0)));
- }
-
- mPropertyHolders.add(new StatePropertyHolder(
- mControllers.taskbarViewController.getTaskbarIconAlpha()
- .getProperty(ALPHA_INDEX_KEYGUARD),
- flags -> (flags & FLAG_KEYGUARD_VISIBLE) == 0
- && (flags & FLAG_SCREEN_PINNING_ACTIVE) == 0));
-
- mPropertyHolders.add(new StatePropertyHolder(mControllers.taskbarDragLayerController
- .getKeyguardBgTaskbar(), flags -> (flags & FLAG_KEYGUARD_VISIBLE) == 0));
-
- // Force nav buttons (specifically back button) to be visible during setup wizard.
- boolean isInSetup = !mContext.isUserSetupComplete();
- boolean isInKidsMode = mContext.isNavBarKidsModeActive();
- boolean alwaysShowButtons = isThreeButtonNav || isInSetup;
-
- // Make sure to remove nav bar buttons translation when notification shade is expanded or
- // IME is showing (add separate translation for IME).
- int flagsToRemoveTranslation = FLAG_NOTIFICATION_SHADE_EXPANDED | FLAG_IME_VISIBLE;
- mPropertyHolders.add(new StatePropertyHolder(mNavButtonInAppDisplayProgressForSysui,
- flags -> (flags & flagsToRemoveTranslation) != 0, AnimatedFloat.VALUE,
- 1, 0));
- // Center nav buttons in new height for IME.
- float transForIme = (mContext.getDeviceProfile().taskbarSize
- - mControllers.taskbarInsetsController.getTaskbarHeightForIme()) / 2f;
- // For gesture nav, nav buttons only show for IME anyway so keep them translated down.
- float defaultButtonTransY = alwaysShowButtons ? 0 : transForIme;
- mPropertyHolders.add(new StatePropertyHolder(mTaskbarNavButtonTranslationYForIme,
- flags -> (flags & FLAG_IME_VISIBLE) != 0 && !isInKidsMode, AnimatedFloat.VALUE,
- transForIme, defaultButtonTransY));
-
- if (alwaysShowButtons) {
- initButtons(mNavButtonContainer, mEndContextualContainer,
- mControllers.navButtonController);
-
- if (isInSetup) {
- // Since setup wizard only has back button enabled, it looks strange to be
- // end-aligned, so start-align instead.
- FrameLayout.LayoutParams navButtonsLayoutParams = (FrameLayout.LayoutParams)
- mNavButtonContainer.getLayoutParams();
- navButtonsLayoutParams.setMarginStart(navButtonsLayoutParams.getMarginEnd());
- navButtonsLayoutParams.setMarginEnd(0);
- navButtonsLayoutParams.gravity = Gravity.START;
- mNavButtonContainer.requestLayout();
-
- // TODO(b/210906568) Dark intensity is currently not propagated during setup, so set
- // it based on dark theme for now.
- int mode = mContext.getResources().getConfiguration().uiMode
- & Configuration.UI_MODE_NIGHT_MASK;
- boolean isDarkTheme = mode == Configuration.UI_MODE_NIGHT_YES;
- mTaskbarNavButtonDarkIntensity.updateValue(isDarkTheme ? 0 : 1);
- } else if (isInKidsMode) {
- int iconSize = mContext.getResources().getDimensionPixelSize(
- R.dimen.taskbar_icon_size_kids);
- int buttonWidth = mContext.getResources().getDimensionPixelSize(
- R.dimen.taskbar_nav_buttons_width_kids);
- int buttonHeight = mContext.getResources().getDimensionPixelSize(
- R.dimen.taskbar_nav_buttons_height_kids);
- int buttonRadius = mContext.getResources().getDimensionPixelSize(
- R.dimen.taskbar_nav_buttons_corner_radius_kids);
- int paddingleft = (buttonWidth - iconSize) / 2;
- int paddingRight = paddingleft;
- int paddingTop = (buttonHeight - iconSize) / 2;
- int paddingBottom = paddingTop;
-
- // Update icons
- ((ImageView) mBackButton).setImageDrawable(
- mBackButton.getContext().getDrawable(R.drawable.ic_sysbar_back_kids));
- ((ImageView) mBackButton).setScaleType(ImageView.ScaleType.FIT_CENTER);
- mBackButton.setPadding(paddingleft, paddingTop, paddingRight, paddingBottom);
- ((ImageView) mHomeButton).setImageDrawable(
- mHomeButton.getContext().getDrawable(R.drawable.ic_sysbar_home_kids));
- ((ImageView) mHomeButton).setScaleType(ImageView.ScaleType.FIT_CENTER);
- mHomeButton.setPadding(paddingleft, paddingTop, paddingRight, paddingBottom);
-
- // Home button layout
- LinearLayout.LayoutParams homeLayoutparams = new LinearLayout.LayoutParams(
- buttonWidth,
- buttonHeight
- );
- int homeButtonLeftMargin = mContext.getResources().getDimensionPixelSize(
- R.dimen.taskbar_home_button_left_margin_kids);
- homeLayoutparams.setMargins(homeButtonLeftMargin, 0, 0, 0);
- mHomeButton.setLayoutParams(homeLayoutparams);
-
- // Back button layout
- LinearLayout.LayoutParams backLayoutParams = new LinearLayout.LayoutParams(
- buttonWidth,
- buttonHeight
- );
- int backButtonLeftMargin = mContext.getResources().getDimensionPixelSize(
- R.dimen.taskbar_back_button_left_margin_kids);
- backLayoutParams.setMargins(backButtonLeftMargin, 0, 0, 0);
- mBackButton.setLayoutParams(backLayoutParams);
-
- // Button backgrounds
- int whiteWith10PctAlpha = Color.argb(0.1f, 1, 1, 1);
- PaintDrawable buttonBackground = new PaintDrawable(whiteWith10PctAlpha);
- buttonBackground.setCornerRadius(buttonRadius);
- mHomeButton.setBackground(buttonBackground);
- mBackButton.setBackground(buttonBackground);
-
- // Update alignment within taskbar
- FrameLayout.LayoutParams navButtonsLayoutParams = (FrameLayout.LayoutParams)
- mNavButtonContainer.getLayoutParams();
- navButtonsLayoutParams.setMarginStart(navButtonsLayoutParams.getMarginEnd() / 2);
- navButtonsLayoutParams.setMarginEnd(navButtonsLayoutParams.getMarginStart());
- navButtonsLayoutParams.gravity = Gravity.CENTER;
- mNavButtonContainer.requestLayout();
-
- mHomeButton.setOnLongClickListener(null);
- }
-
- // Animate taskbar background when either..
- // notification shade expanded AND not on keyguard
- // back is visible for bouncer
- mPropertyHolders.add(new StatePropertyHolder(
- mControllers.taskbarDragLayerController.getNavbarBackgroundAlpha(),
- flags -> ((flags & FLAG_NOTIFICATION_SHADE_EXPANDED) != 0
- && (flags & FLAG_KEYGUARD_VISIBLE) == 0)
- || (flags & FLAG_ONLY_BACK_FOR_BOUNCER_VISIBLE) != 0));
-
- // Rotation button
- RotationButton rotationButton = new RotationButtonImpl(
- addButton(mEndContextualContainer, R.id.rotate_suggestion,
- R.layout.taskbar_contextual_button));
- rotationButton.hide();
- mControllers.rotationButtonController.setRotationButton(rotationButton, null);
- } else {
- mFloatingRotationButton = new FloatingRotationButton(mContext,
- R.string.accessibility_rotate_button,
- R.layout.rotate_suggestion,
- R.id.rotate_suggestion,
- R.dimen.floating_rotation_button_min_margin,
- R.dimen.rounded_corner_content_padding,
- R.dimen.floating_rotation_button_taskbar_left_margin,
- R.dimen.floating_rotation_button_taskbar_bottom_margin,
- R.dimen.floating_rotation_button_diameter,
- R.dimen.key_button_ripple_max_width);
- mControllers.rotationButtonController.setRotationButton(mFloatingRotationButton,
- mRotationButtonListener);
-
- if (!mIsImeRenderingNavButtons) {
- View imeDownButton = addButton(R.drawable.ic_sysbar_back, BUTTON_BACK,
- mStartContextualContainer, mControllers.navButtonController, R.id.back);
- imeDownButton.setRotation(Utilities.isRtl(mContext.getResources()) ? 90 : -90);
- // Only show when IME is visible.
- mPropertyHolders.add(new StatePropertyHolder(imeDownButton,
- flags -> (flags & FLAG_IME_VISIBLE) != 0));
- }
- }
-
- applyState();
- mPropertyHolders.forEach(StatePropertyHolder::endAnimation);
-
- // Initialize things needed to move nav buttons to separate window.
- mSeparateWindowParent = new BaseDragLayer<TaskbarActivityContext>(mContext, null, 0) {
- @Override
- public void recreateControllers() {
- mControllers = new TouchController[0];
- }
-
- @Override
- protected boolean canFindActiveController() {
- // We don't have any controllers, but we don't want any floating views such as
- // folder to intercept, either. This ensures nav buttons can always be pressed.
- return false;
- }
- };
- mSeparateWindowParent.recreateControllers();
- }
-
- private void initButtons(ViewGroup navContainer, ViewGroup endContainer,
- TaskbarNavButtonController navButtonController) {
-
- mBackButton = addButton(R.drawable.ic_sysbar_back, BUTTON_BACK,
- mNavButtonContainer, mControllers.navButtonController, R.id.back);
- mBackButtonAlpha = new MultiValueAlpha(mBackButton, NUM_ALPHA_CHANNELS);
- mBackButtonAlpha.setUpdateVisibility(true);
- mPropertyHolders.add(new StatePropertyHolder(
- mBackButtonAlpha.getProperty(ALPHA_INDEX_KEYGUARD_OR_DISABLE),
- flags -> {
- // Show only if not disabled, and if not on the keyguard or otherwise only when
- // the bouncer or a lockscreen app is showing above the keyguard
- boolean showingOnKeyguard = (flags & FLAG_KEYGUARD_VISIBLE) == 0 ||
- (flags & FLAG_ONLY_BACK_FOR_BOUNCER_VISIBLE) != 0 ||
- (flags & FLAG_KEYGUARD_OCCLUDED) != 0;
- return (flags & FLAG_DISABLE_BACK) == 0
- && ((flags & FLAG_KEYGUARD_VISIBLE) == 0 || showingOnKeyguard);
- }));
- boolean isRtl = Utilities.isRtl(mContext.getResources());
- mPropertyHolders.add(new StatePropertyHolder(mBackButton,
- flags -> (flags & FLAG_IME_VISIBLE) != 0 && !mContext.isNavBarKidsModeActive(),
- View.ROTATION, isRtl ? 90 : -90, 0));
- // Translate back button to be at end/start of other buttons for keyguard
- int navButtonSize = mContext.getResources().getDimensionPixelSize(
- R.dimen.taskbar_nav_buttons_size);
- mPropertyHolders.add(new StatePropertyHolder(
- mBackButton, flags -> (flags & FLAG_ONLY_BACK_FOR_BOUNCER_VISIBLE) != 0
- || (flags & FLAG_KEYGUARD_VISIBLE) != 0,
- VIEW_TRANSLATE_X, navButtonSize * (isRtl ? -2 : 2), 0));
-
- // home button
- mHomeButton = addButton(R.drawable.ic_sysbar_home, BUTTON_HOME, navContainer,
- navButtonController, R.id.home);
- mHomeButtonAlpha = new MultiValueAlpha(mHomeButton, NUM_ALPHA_CHANNELS);
- mHomeButtonAlpha.setUpdateVisibility(true);
- mPropertyHolders.add(
- new StatePropertyHolder(mHomeButtonAlpha.getProperty(
- ALPHA_INDEX_KEYGUARD_OR_DISABLE),
- flags -> (flags & FLAG_KEYGUARD_VISIBLE) == 0 &&
- (flags & FLAG_DISABLE_HOME) == 0));
-
- // Recents button
- View recentsButton = addButton(R.drawable.ic_sysbar_recent, BUTTON_RECENTS,
- navContainer, navButtonController, R.id.recent_apps);
- mHitboxExtender.init(recentsButton, mNavButtonsView, mContext.getDeviceProfile(),
- () -> {
- float[] recentsCoords = new float[2];
- getDescendantCoordRelativeToAncestor(recentsButton, mNavButtonsView,
- recentsCoords, false);
- return recentsCoords;
- }, new Handler());
- recentsButton.setOnClickListener(v -> {
- navButtonController.onButtonClick(BUTTON_RECENTS);
- mHitboxExtender.onRecentsButtonClicked();
- });
- mPropertyHolders.add(new StatePropertyHolder(recentsButton,
- flags -> (flags & FLAG_KEYGUARD_VISIBLE) == 0 && (flags & FLAG_DISABLE_RECENTS) == 0
- && !mContext.isNavBarKidsModeActive()));
-
- // A11y button
- mA11yButton = addButton(R.drawable.ic_sysbar_accessibility_button, BUTTON_A11Y,
- endContainer, navButtonController, R.id.accessibility_button,
- R.layout.taskbar_contextual_button);
- mPropertyHolders.add(new StatePropertyHolder(mA11yButton,
- flags -> (flags & FLAG_A11Y_VISIBLE) != 0
- && (flags & FLAG_ROTATION_BUTTON_VISIBLE) == 0));
- }
-
- private void parseSystemUiFlags(int sysUiStateFlags) {
- mSysuiStateFlags = sysUiStateFlags;
- boolean isImeVisible = (sysUiStateFlags & SYSUI_STATE_IME_SHOWING) != 0;
- boolean isImeSwitcherShowing = (sysUiStateFlags & SYSUI_STATE_IME_SWITCHER_SHOWING) != 0;
- boolean a11yVisible = (sysUiStateFlags & SYSUI_STATE_A11Y_BUTTON_CLICKABLE) != 0;
- boolean isHomeDisabled = (sysUiStateFlags & SYSUI_STATE_HOME_DISABLED) != 0;
- boolean isRecentsDisabled = (sysUiStateFlags & SYSUI_STATE_OVERVIEW_DISABLED) != 0;
- boolean isBackDisabled = (sysUiStateFlags & SYSUI_STATE_BACK_DISABLED) != 0;
- int shadeExpandedFlags = SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED
- | SYSUI_STATE_QUICK_SETTINGS_EXPANDED;
- boolean isNotificationShadeExpanded = (sysUiStateFlags & shadeExpandedFlags) != 0;
- boolean isScreenPinningActive = (sysUiStateFlags & SYSUI_STATE_SCREEN_PINNING) != 0;
-
- // TODO(b/202218289) we're getting IME as not visible on lockscreen from system
- updateStateForFlag(FLAG_IME_VISIBLE, isImeVisible);
- updateStateForFlag(FLAG_SWITCHER_SUPPORTED, isImeSwitcherShowing);
- updateStateForFlag(FLAG_A11Y_VISIBLE, a11yVisible);
- updateStateForFlag(FLAG_DISABLE_HOME, isHomeDisabled);
- updateStateForFlag(FLAG_DISABLE_RECENTS, isRecentsDisabled);
- updateStateForFlag(FLAG_DISABLE_BACK, isBackDisabled);
- updateStateForFlag(FLAG_NOTIFICATION_SHADE_EXPANDED, isNotificationShadeExpanded);
- updateStateForFlag(FLAG_SCREEN_PINNING_ACTIVE, isScreenPinningActive);
-
- if (mA11yButton != null) {
- // Only used in 3 button
- boolean a11yLongClickable =
- (sysUiStateFlags & SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE) != 0;
- mA11yButton.setLongClickable(a11yLongClickable);
- }
- }
-
- public void updateStateForSysuiFlags(int systemUiStateFlags, boolean skipAnim) {
- if (systemUiStateFlags == mSysuiStateFlags) {
- return;
- }
- parseSystemUiFlags(systemUiStateFlags);
- applyState();
- if (skipAnim) {
- mPropertyHolders.forEach(StatePropertyHolder::endAnimation);
- }
- }
-
- /**
- * Should be called when we need to show back button for bouncer
- */
- public void setBackForBouncer(boolean isBouncerVisible) {
- updateStateForFlag(FLAG_ONLY_BACK_FOR_BOUNCER_VISIBLE, isBouncerVisible);
- applyState();
- }
-
- /**
- * Slightly misnamed, but should be called when keyguard OR AOD is showing.
- * We consider keyguardVisible when it's showing bouncer OR is occlucded by another app
- */
- public void setKeyguardVisible(boolean isKeyguardVisible, boolean isKeyguardOccluded) {
- updateStateForFlag(FLAG_KEYGUARD_VISIBLE, isKeyguardVisible || isKeyguardOccluded);
- updateStateForFlag(FLAG_KEYGUARD_OCCLUDED, isKeyguardOccluded);
- applyState();
- }
-
- /**
- * Returns true if IME bar is visible
- */
- public boolean isImeVisible() {
- return (mState & FLAG_IME_VISIBLE) != 0;
- }
-
- /**
- * Returns true if the home button is disabled
- */
- public boolean isHomeDisabled() {
- return (mState & FLAG_DISABLE_HOME) != 0;
- }
-
- /**
- * Returns true if the recents (overview) button is disabled
- */
- public boolean isRecentsDisabled() {
- return (mState & FLAG_DISABLE_RECENTS) != 0;
- }
-
- /**
- * Adds the bounds corresponding to all visible buttons to provided region
- */
- public void addVisibleButtonsRegion(BaseDragLayer<?> parent, Region outRegion) {
- int count = mAllButtons.size();
- for (int i = 0; i < count; i++) {
- View button = mAllButtons.get(i);
- if (button.getVisibility() == View.VISIBLE) {
- parent.getDescendantRectRelativeToSelf(button, mTempRect);
- if (mHitboxExtender.extendedHitboxEnabled()) {
- mTempRect.bottom += mContext.getDeviceProfile().getTaskbarOffsetY();
- }
- outRegion.op(mTempRect, Op.UNION);
- }
- }
- }
-
- /**
- * Returns multi-value alpha controller for back button.
- */
- public MultiValueAlpha getBackButtonAlpha() {
- return mBackButtonAlpha;
- }
-
- /**
- * Returns multi-value alpha controller for home button.
- */
- public MultiValueAlpha getHomeButtonAlpha() {
- return mHomeButtonAlpha;
- }
-
- /** Use to set the translationY for the all nav+contextual buttons */
- public AnimatedFloat getTaskbarNavButtonTranslationY() {
- return mTaskbarNavButtonTranslationY;
- }
-
- /** Use to set the translationY for the all nav+contextual buttons when in Launcher */
- public AnimatedFloat getTaskbarNavButtonTranslationYForInAppDisplay() {
- return mTaskbarNavButtonTranslationYForInAppDisplay;
- }
-
- /** Use to set the dark intensity for the all nav+contextual buttons */
- public AnimatedFloat getTaskbarNavButtonDarkIntensity() {
- return mTaskbarNavButtonDarkIntensity;
- }
-
- /** Use to determine whether to use the dark intensity requested by the underlying app */
- public AnimatedFloat getNavButtonDarkIntensityMultiplier() {
- return mNavButtonDarkIntensityMultiplier;
- }
-
- /**
- * Does not call {@link #applyState()}. Don't forget to!
- */
- private void updateStateForFlag(int flag, boolean enabled) {
- if (enabled) {
- mState |= flag;
- } else {
- mState &= ~flag;
- }
- }
-
- private void applyState() {
- int count = mPropertyHolders.size();
- for (int i = 0; i < count; i++) {
- mPropertyHolders.get(i).setState(mState);
- }
- }
-
- private void updateNavButtonInAppDisplayProgressForSysui() {
- TaskbarUIController uiController = mControllers.uiController;
- if (uiController instanceof LauncherTaskbarUIController) {
- ((LauncherTaskbarUIController) uiController).onTaskbarInAppDisplayProgressUpdate(
- mNavButtonInAppDisplayProgressForSysui.value, SYSUI_SURFACE_PROGRESS_INDEX);
- }
- }
-
- private void updateNavButtonTranslationY() {
- final float normalTranslationY = mTaskbarNavButtonTranslationY.value;
- final float imeAdjustmentTranslationY = mTaskbarNavButtonTranslationYForIme.value;
- TaskbarUIController uiController = mControllers.uiController;
- final float inAppDisplayAdjustmentTranslationY =
- (uiController instanceof LauncherTaskbarUIController
- && ((LauncherTaskbarUIController) uiController).shouldUseInAppLayout())
- ? mTaskbarNavButtonTranslationYForInAppDisplay.value : 0;
-
- mNavButtonsView.setTranslationY(normalTranslationY
- + imeAdjustmentTranslationY
- + inAppDisplayAdjustmentTranslationY);
- }
-
- private void updateNavButtonDarkIntensity() {
- float darkIntensity = mTaskbarNavButtonDarkIntensity.value
- * mNavButtonDarkIntensityMultiplier.value;
- int iconColor = (int) ArgbEvaluator.getInstance().evaluate(darkIntensity, mLightIconColor,
- mDarkIconColor);
- for (ImageView button : mAllButtons) {
- button.setImageTintList(ColorStateList.valueOf(iconColor));
- }
- }
-
- protected ImageView addButton(@DrawableRes int drawableId, @TaskbarButton int buttonType,
- ViewGroup parent, TaskbarNavButtonController navButtonController, @IdRes int id) {
- return addButton(drawableId, buttonType, parent, navButtonController, id,
- R.layout.taskbar_nav_button);
- }
-
- private ImageView addButton(@DrawableRes int drawableId, @TaskbarButton int buttonType,
- ViewGroup parent, TaskbarNavButtonController navButtonController, @IdRes int id,
- @LayoutRes int layoutId) {
- ImageView buttonView = addButton(parent, id, layoutId);
- buttonView.setImageResource(drawableId);
- buttonView.setContentDescription(parent.getContext().getString(
- navButtonController.getButtonContentDescription(buttonType)));
- buttonView.setOnClickListener(view -> navButtonController.onButtonClick(buttonType));
- buttonView.setOnLongClickListener(view ->
- navButtonController.onButtonLongClick(buttonType));
- return buttonView;
- }
-
- private ImageView addButton(ViewGroup parent, @IdRes int id, @LayoutRes int layoutId) {
- ImageView buttonView = (ImageView) mContext.getLayoutInflater()
- .inflate(layoutId, parent, false);
- buttonView.setId(id);
- parent.addView(buttonView);
- mAllButtons.add(buttonView);
- return buttonView;
- }
-
- public boolean isEventOverAnyItem(MotionEvent ev) {
- return mFloatingRotationButtonBounds.contains((int) ev.getX(), (int) ev.getY());
- }
-
- public void onConfigurationChanged(@Config int configChanges) {
- if (mFloatingRotationButton != null) {
- mFloatingRotationButton.onConfigurationChanged(configChanges);
- }
- }
-
- public void onDestroy() {
- mPropertyHolders.clear();
- mControllers.rotationButtonController.unregisterListeners();
- if (mFloatingRotationButton != null) {
- mFloatingRotationButton.hide();
- }
-
- moveNavButtonsBackToTaskbarWindow();
- }
-
- /**
- * Moves mNavButtonsView from TaskbarDragLayer to a placeholder BaseDragLayer on a new window.
- */
- public void moveNavButtonsToNewWindow() {
- if (mAreNavButtonsInSeparateWindow) {
- return;
- }
-
- if (mIsImeRenderingNavButtons) {
- // IME is rendering the nav buttons, so we don't need to create a new layer for them.
- return;
- }
-
- mSeparateWindowParent.addOnAttachStateChangeListener(new OnAttachStateChangeListener() {
- @Override
- public void onViewAttachedToWindow(View view) {
- ViewTreeObserverWrapper.addOnComputeInsetsListener(
- mSeparateWindowParent.getViewTreeObserver(), mSeparateWindowInsetsComputer);
- }
-
- @Override
- public void onViewDetachedFromWindow(View view) {
- mSeparateWindowParent.removeOnAttachStateChangeListener(this);
- ViewTreeObserverWrapper.removeOnComputeInsetsListener(
- mSeparateWindowInsetsComputer);
- }
- });
-
- mAreNavButtonsInSeparateWindow = true;
- mContext.getDragLayer().removeView(mNavButtonsView);
- mSeparateWindowParent.addView(mNavButtonsView);
- WindowManager.LayoutParams windowLayoutParams = mContext.createDefaultWindowLayoutParams();
- windowLayoutParams.setTitle(NAV_BUTTONS_SEPARATE_WINDOW_TITLE);
- mContext.addWindowView(mSeparateWindowParent, windowLayoutParams);
-
- }
-
- /**
- * Moves mNavButtonsView from its temporary window and reattaches it to TaskbarDragLayer.
- */
- public void moveNavButtonsBackToTaskbarWindow() {
- if (!mAreNavButtonsInSeparateWindow) {
- return;
- }
-
- mAreNavButtonsInSeparateWindow = false;
- mContext.removeWindowView(mSeparateWindowParent);
- mSeparateWindowParent.removeView(mNavButtonsView);
- mContext.getDragLayer().addView(mNavButtonsView);
- }
-
- private void onComputeInsetsForSeparateWindow(ViewTreeObserverWrapper.InsetsInfo insetsInfo) {
- addVisibleButtonsRegion(mSeparateWindowParent, insetsInfo.touchableRegion);
- insetsInfo.setTouchableInsets(TOUCHABLE_INSETS_REGION);
- }
-
- @Override
- public void dumpLogs(String prefix, PrintWriter pw) {
- pw.println(prefix + "NavbarButtonsViewController:");
-
- pw.println(String.format("%s\tmState=%s", prefix, getStateString(mState)));
- pw.println(String.format(
- "%s\tmLightIconColor=0x%s", prefix, Integer.toHexString(mLightIconColor)));
- pw.println(String.format(
- "%s\tmDarkIconColor=0x%s", prefix, Integer.toHexString(mDarkIconColor)));
- pw.println(String.format(
- "%s\tmFloatingRotationButtonBounds=%s", prefix, mFloatingRotationButtonBounds));
- pw.println(String.format(
- "%s\tmSysuiStateFlags=%s",
- prefix,
- QuickStepContract.getSystemUiStateString(mSysuiStateFlags)));
- }
-
- private static String getStateString(int flags) {
- StringJoiner str = new StringJoiner("|");
- appendFlag(str, flags, FLAG_SWITCHER_SUPPORTED, "FLAG_SWITCHER_SUPPORTED");
- appendFlag(str, flags, FLAG_IME_VISIBLE, "FLAG_IME_VISIBLE");
- appendFlag(str, flags, FLAG_ROTATION_BUTTON_VISIBLE, "FLAG_ROTATION_BUTTON_VISIBLE");
- appendFlag(str, flags, FLAG_A11Y_VISIBLE, "FLAG_A11Y_VISIBLE");
- appendFlag(str, flags, FLAG_ONLY_BACK_FOR_BOUNCER_VISIBLE,
- "FLAG_ONLY_BACK_FOR_BOUNCER_VISIBLE");
- appendFlag(str, flags, FLAG_KEYGUARD_VISIBLE, "FLAG_KEYGUARD_VISIBLE");
- appendFlag(str, flags, FLAG_KEYGUARD_OCCLUDED, "FLAG_KEYGUARD_OCCLUDED");
- appendFlag(str, flags, FLAG_DISABLE_HOME, "FLAG_DISABLE_HOME");
- appendFlag(str, flags, FLAG_DISABLE_RECENTS, "FLAG_DISABLE_RECENTS");
- appendFlag(str, flags, FLAG_DISABLE_BACK, "FLAG_DISABLE_BACK");
- appendFlag(str, flags, FLAG_NOTIFICATION_SHADE_EXPANDED,
- "FLAG_NOTIFICATION_SHADE_EXPANDED");
- appendFlag(str, flags, FLAG_SCREEN_PINNING_ACTIVE, "FLAG_SCREEN_PINNING_ACTIVE");
- return str.toString();
- }
-
- public TouchController getTouchController() {
- return mHitboxExtender;
- }
-
- /**
- * @param alignment 0 -> Taskbar, 1 -> Workspace
- */
- public void updateTaskbarAlignment(float alignment) {
- mHitboxExtender.onAnimationProgressToOverview(alignment);
- }
-
- private class RotationButtonListener implements RotationButton.RotationButtonUpdatesCallback {
- @Override
- public void onVisibilityChanged(boolean isVisible) {
- if (isVisible) {
- mFloatingRotationButton.getCurrentView()
- .getBoundsOnScreen(mFloatingRotationButtonBounds);
- } else {
- mFloatingRotationButtonBounds.setEmpty();
- }
- }
- }
-
- private class RotationButtonImpl implements RotationButton {
-
- private final ImageView mButton;
- private AnimatedVectorDrawable mImageDrawable;
-
- RotationButtonImpl(ImageView button) {
- mButton = button;
- }
-
- @Override
- public void setRotationButtonController(RotationButtonController rotationButtonController) {
- // TODO(b/187754252) UI polish, different icons based on light/dark context, etc
- mImageDrawable = (AnimatedVectorDrawable) mButton.getContext()
- .getDrawable(rotationButtonController.getIconResId());
- mButton.setImageDrawable(mImageDrawable);
- mButton.setContentDescription(mButton.getResources()
- .getString(R.string.accessibility_rotate_button));
- mImageDrawable.setCallback(mButton);
- }
-
- @Override
- public View getCurrentView() {
- return mButton;
- }
-
- @Override
- public boolean show() {
- mButton.setVisibility(View.VISIBLE);
- mState |= FLAG_ROTATION_BUTTON_VISIBLE;
- applyState();
- return true;
- }
-
- @Override
- public boolean hide() {
- mButton.setVisibility(View.GONE);
- mState &= ~FLAG_ROTATION_BUTTON_VISIBLE;
- applyState();
- return true;
- }
-
- @Override
- public boolean isVisible() {
- return mButton.getVisibility() == View.VISIBLE;
- }
-
- @Override
- public void updateIcon(int lightIconColor, int darkIconColor) {
- // TODO(b/187754252): UI Polish
- }
-
- @Override
- public void setOnClickListener(OnClickListener onClickListener) {
- mButton.setOnClickListener(onClickListener);
- }
-
- @Override
- public void setOnHoverListener(OnHoverListener onHoverListener) {
- mButton.setOnHoverListener(onHoverListener);
- }
-
- @Override
- public AnimatedVectorDrawable getImageDrawable() {
- return mImageDrawable;
- }
-
- @Override
- public void setDarkIntensity(float darkIntensity) {
- // TODO(b/187754252) UI polish
- }
-
- @Override
- public boolean acceptRotationProposal() {
- return mButton.isAttachedToWindow();
- }
- }
-
- private static class StatePropertyHolder {
-
- private final float mEnabledValue, mDisabledValue;
- private final ObjectAnimator mAnimator;
- private final IntPredicate mEnableCondition;
-
- private boolean mIsEnabled = true;
-
- StatePropertyHolder(View view, IntPredicate enableCondition) {
- this(view, enableCondition, LauncherAnimUtils.VIEW_ALPHA, 1, 0);
- mAnimator.addListener(new AlphaUpdateListener(view));
- }
-
- StatePropertyHolder(MultiValueAlpha.AlphaProperty alphaProperty,
- IntPredicate enableCondition) {
- this(alphaProperty, enableCondition, MultiValueAlpha.VALUE, 1, 0);
- }
-
- StatePropertyHolder(AnimatedFloat animatedFloat, IntPredicate enableCondition) {
- this(animatedFloat, enableCondition, AnimatedFloat.VALUE, 1, 0);
- }
-
- <T> StatePropertyHolder(T target, IntPredicate enabledCondition,
- Property<T, Float> property, float enabledValue, float disabledValue) {
- mEnableCondition = enabledCondition;
- mEnabledValue = enabledValue;
- mDisabledValue = disabledValue;
- mAnimator = ObjectAnimator.ofFloat(target, property, enabledValue, disabledValue);
- }
-
- public void setState(int flags) {
- boolean isEnabled = mEnableCondition.test(flags);
- if (mIsEnabled != isEnabled) {
- mIsEnabled = isEnabled;
- mAnimator.cancel();
- mAnimator.setFloatValues(mIsEnabled ? mEnabledValue : mDisabledValue);
- mAnimator.start();
- }
- }
-
- public void endAnimation() {
- if (mAnimator.isRunning()) {
- mAnimator.end();
- }
- }
- }
-}
diff --git a/quickstep/src/com/android/launcher3/taskbar/RecentsHitboxExtender.java b/quickstep/src/com/android/launcher3/taskbar/RecentsHitboxExtender.java
deleted file mode 100644
index 4651570a60..0000000000
--- a/quickstep/src/com/android/launcher3/taskbar/RecentsHitboxExtender.java
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.launcher3.taskbar;
-
-import android.graphics.Rect;
-import android.os.Handler;
-import android.view.MotionEvent;
-import android.view.TouchDelegate;
-import android.view.View;
-
-import com.android.launcher3.DeviceProfile;
-import com.android.launcher3.util.TouchController;
-
-import java.util.function.Supplier;
-
-/**
- * Extends the Recents touch area during the taskbar to overview animation
- * to give user some error room when trying to quickly double tap recents button since it moves.
- *
- * Listens for icon alignment as our indication for the animation.
- */
-public class RecentsHitboxExtender implements TouchController {
-
- private static final int RECENTS_HITBOX_TIMEOUT_MS = 500;
-
- private View mRecentsButton;
- private View mRecentsParent;
- private DeviceProfile mDeviceProfile;
- private Supplier<float[]> mParentCoordSupplier;
- private TouchDelegate mRecentsTouchDelegate;
- /**
- * Will be true while the animation from taskbar to overview is occurring.
- * Lifecycle of this variable slightly extends past the animation by
- * {@link #RECENTS_HITBOX_TIMEOUT_MS}, so can use this variable as a proxy for if
- * the current hitbox is extended or not.
- */
- private boolean mAnimatingFromTaskbarToOverview;
- private float mLastIconAlignment;
- private final Rect mRecentsHitBox = new Rect();
- private boolean mRecentsButtonClicked;
- private Handler mHandler;
- private final Runnable mRecentsHitboxResetRunnable = this::reset;
-
- public void init(View recentsButton, View recentsParent, DeviceProfile deviceProfile,
- Supplier<float[]> parentCoordSupplier, Handler handler) {
- mRecentsButton = recentsButton;
- mRecentsParent = recentsParent;
- mDeviceProfile = deviceProfile;
- mParentCoordSupplier = parentCoordSupplier;
- mHandler = handler;
- }
-
- public void onRecentsButtonClicked() {
- mRecentsButtonClicked = true;
- }
-
- /**
- * @param progress 0 -> Taskbar, 1 -> Overview
- */
- public void onAnimationProgressToOverview(float progress) {
- if (progress == 1 || progress == 0) {
- // Done w/ animation
- mLastIconAlignment = progress;
- if (mAnimatingFromTaskbarToOverview) {
- if (progress == 1) {
- // Finished animation to workspace, remove the touch delegate shortly
- mHandler.postDelayed(mRecentsHitboxResetRunnable, RECENTS_HITBOX_TIMEOUT_MS);
- return;
- } else {
- // Went back to taskbar, reset immediately
- mHandler.removeCallbacks(mRecentsHitboxResetRunnable);
- reset();
- }
- }
- }
-
- if (mAnimatingFromTaskbarToOverview) {
- return;
- }
-
- if (progress > 0 && mLastIconAlignment == 0 && mRecentsButtonClicked) {
- // Starting animation, previously we were showing taskbar
- mAnimatingFromTaskbarToOverview = true;
- float[] recentsCoords = mParentCoordSupplier.get();
- int x = (int) recentsCoords[0];
- int y = (int) (recentsCoords[1]);
- // Extend hitbox vertically by the offset amount from mDeviceProfile.getTaskbarOffsetY()
- mRecentsHitBox.set(x, y,
- x + mRecentsButton.getWidth(),
- y + mRecentsButton.getHeight() + mDeviceProfile.getTaskbarOffsetY()
- );
- mRecentsTouchDelegate = new TouchDelegate(mRecentsHitBox, mRecentsButton);
- mRecentsParent.setTouchDelegate(mRecentsTouchDelegate);
- }
- }
-
- private void reset() {
- mAnimatingFromTaskbarToOverview = false;
- mRecentsButton.setTouchDelegate(null);
- mRecentsHitBox.setEmpty();
- mRecentsButtonClicked = false;
- }
-
- /**
- * @return {@code true} if the bounds for recents touches are currently extended
- */
- public boolean extendedHitboxEnabled() {
- return mAnimatingFromTaskbarToOverview;
- }
-
- @Override
- public boolean onControllerTouchEvent(MotionEvent ev) {
- return mRecentsTouchDelegate.onTouchEvent(ev);
- }
-
- @Override
- public boolean onControllerInterceptTouchEvent(MotionEvent ev) {
- return mRecentsHitBox.contains((int)ev.getX(), (int)ev.getY());
- }
-}
diff --git a/quickstep/src/com/android/launcher3/taskbar/StashedHandleView.java b/quickstep/src/com/android/launcher3/taskbar/StashedHandleView.java
deleted file mode 100644
index 6db58397c3..0000000000
--- a/quickstep/src/com/android/launcher3/taskbar/StashedHandleView.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright (C) 2021 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.launcher3.taskbar;
-
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.ObjectAnimator;
-import android.annotation.Nullable;
-import android.content.Context;
-import android.graphics.Rect;
-import android.util.AttributeSet;
-import android.view.View;
-
-import androidx.annotation.ColorInt;
-import androidx.core.content.ContextCompat;
-
-import com.android.launcher3.LauncherAnimUtils;
-import com.android.launcher3.R;
-
-public class StashedHandleView extends View {
-
- private static final long COLOR_CHANGE_DURATION = 120;
-
- private final @ColorInt int mStashedHandleLightColor;
- private final @ColorInt int mStashedHandleDarkColor;
- private final Rect mSampledRegion = new Rect();
- private final int[] mTmpArr = new int[2];
-
- private @Nullable ObjectAnimator mColorChangeAnim;
-
- public StashedHandleView(Context context) {
- this(context, null);
- }
-
- public StashedHandleView(Context context, AttributeSet attrs) {
- this(context, attrs, 0);
- }
-
- public StashedHandleView(Context context, AttributeSet attrs, int defStyleAttr) {
- this(context, attrs, defStyleAttr, 0);
- }
-
- public StashedHandleView(Context context, AttributeSet attrs, int defStyleAttr,
- int defStyleRes) {
- super(context, attrs, defStyleAttr, defStyleRes);
-
- mStashedHandleLightColor = ContextCompat.getColor(context,
- R.color.taskbar_stashed_handle_light_color);
- mStashedHandleDarkColor = ContextCompat.getColor(context,
- R.color.taskbar_stashed_handle_dark_color);
- }
-
- /**
- * Updates mSampledRegion to be the location of the stashedHandleBounds relative to the screen.
- * @see #getSampledRegion()
- */
- public void updateSampledRegion(Rect stashedHandleBounds) {
- getLocationOnScreen(mTmpArr);
- mSampledRegion.set(stashedHandleBounds);
- mSampledRegion.offset(mTmpArr[0], mTmpArr[1]);
- }
-
- public Rect getSampledRegion() {
- return mSampledRegion;
- }
-
- /**
- * Updates the handle color.
- * @param isRegionDark Whether the background behind the handle is dark, and thus the handle
- * should be light (and vice versa).
- * @param animate Whether to animate the change, or apply it immediately.
- */
- public void updateHandleColor(boolean isRegionDark, boolean animate) {
- int newColor = isRegionDark ? mStashedHandleLightColor : mStashedHandleDarkColor;
- if (mColorChangeAnim != null) {
- mColorChangeAnim.cancel();
- }
- if (animate) {
- mColorChangeAnim = ObjectAnimator.ofArgb(this,
- LauncherAnimUtils.VIEW_BACKGROUND_COLOR, newColor);
- mColorChangeAnim.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- mColorChangeAnim = null;
- }
- });
- mColorChangeAnim.setDuration(COLOR_CHANGE_DURATION);
- mColorChangeAnim.start();
- } else {
- setBackgroundColor(newColor);
- }
- }
-}
diff --git a/quickstep/src/com/android/launcher3/taskbar/StashedHandleViewController.java b/quickstep/src/com/android/launcher3/taskbar/StashedHandleViewController.java
deleted file mode 100644
index b7978076c1..0000000000
--- a/quickstep/src/com/android/launcher3/taskbar/StashedHandleViewController.java
+++ /dev/null
@@ -1,217 +0,0 @@
-/*
- * Copyright (C) 2021 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.launcher3.taskbar;
-
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.ValueAnimator;
-import android.content.SharedPreferences;
-import android.content.res.Resources;
-import android.graphics.Outline;
-import android.graphics.Rect;
-import android.view.View;
-import android.view.ViewOutlineProvider;
-
-import com.android.launcher3.R;
-import com.android.launcher3.Utilities;
-import com.android.launcher3.anim.RevealOutlineAnimation;
-import com.android.launcher3.anim.RoundedRectRevealOutlineProvider;
-import com.android.launcher3.util.Executors;
-import com.android.launcher3.util.MultiValueAlpha;
-import com.android.quickstep.AnimatedFloat;
-import com.android.systemui.shared.navigationbar.RegionSamplingHelper;
-
-import java.io.PrintWriter;
-
-/**
- * Handles properties/data collection, then passes the results to our stashed handle View to render.
- */
-public class StashedHandleViewController implements TaskbarControllers.LoggableTaskbarController {
-
- public static final int ALPHA_INDEX_STASHED = 0;
- public static final int ALPHA_INDEX_HOME_DISABLED = 1;
- private static final int NUM_ALPHA_CHANNELS = 2;
-
- /**
- * The SharedPreferences key for whether the stashed handle region is dark.
- */
- private static final String SHARED_PREFS_STASHED_HANDLE_REGION_DARK_KEY =
- "stashed_handle_region_is_dark";
-
- private final TaskbarActivityContext mActivity;
- private final SharedPreferences mPrefs;
- private final StashedHandleView mStashedHandleView;
- private final int mStashedHandleWidth;
- private final int mStashedHandleHeight;
- private final RegionSamplingHelper mRegionSamplingHelper;
- private final MultiValueAlpha mTaskbarStashedHandleAlpha;
- private final AnimatedFloat mTaskbarStashedHandleHintScale = new AnimatedFloat(
- this::updateStashedHandleHintScale);
-
- // Initialized in init.
- private TaskbarControllers mControllers;
-
- // The bounds we want to clip to in the settled state when showing the stashed handle.
- private final Rect mStashedHandleBounds = new Rect();
- private float mStashedHandleRadius;
-
- // When the reveal animation is cancelled, we can assume it's about to create a new animation,
- // which should start off at the same point the cancelled one left off.
- private float mStartProgressForNextRevealAnim;
- private boolean mWasLastRevealAnimReversed;
-
- public StashedHandleViewController(TaskbarActivityContext activity,
- StashedHandleView stashedHandleView) {
- mActivity = activity;
- mPrefs = Utilities.getPrefs(mActivity);
- mStashedHandleView = stashedHandleView;
- mTaskbarStashedHandleAlpha = new MultiValueAlpha(mStashedHandleView, NUM_ALPHA_CHANNELS);
- mTaskbarStashedHandleAlpha.setUpdateVisibility(true);
- mStashedHandleView.updateHandleColor(
- mPrefs.getBoolean(SHARED_PREFS_STASHED_HANDLE_REGION_DARK_KEY, false),
- false /* animate */);
- final Resources resources = mActivity.getResources();
- mStashedHandleWidth = resources.getDimensionPixelSize(R.dimen.taskbar_stashed_handle_width);
- mStashedHandleHeight = resources.getDimensionPixelSize(
- R.dimen.taskbar_stashed_handle_height);
- mRegionSamplingHelper = new RegionSamplingHelper(mStashedHandleView,
- new RegionSamplingHelper.SamplingCallback() {
- @Override
- public void onRegionDarknessChanged(boolean isRegionDark) {
- mStashedHandleView.updateHandleColor(isRegionDark, true /* animate */);
- mPrefs.edit().putBoolean(SHARED_PREFS_STASHED_HANDLE_REGION_DARK_KEY,
- isRegionDark).apply();
- }
-
- @Override
- public Rect getSampledRegion(View sampledView) {
- return mStashedHandleView.getSampledRegion();
- }
- }, Executors.UI_HELPER_EXECUTOR);
- }
-
- public void init(TaskbarControllers controllers) {
- mControllers = controllers;
- mStashedHandleView.getLayoutParams().height = mActivity.getDeviceProfile().taskbarSize;
-
- mTaskbarStashedHandleAlpha.getProperty(ALPHA_INDEX_STASHED).setValue(0);
- mTaskbarStashedHandleHintScale.updateValue(1f);
-
- final int stashedTaskbarHeight = mControllers.taskbarStashController.getStashedHeight();
- mStashedHandleView.setOutlineProvider(new ViewOutlineProvider() {
- @Override
- public void getOutline(View view, Outline outline) {
- final int stashedCenterX = view.getWidth() / 2;
- final int stashedCenterY = view.getHeight() - stashedTaskbarHeight / 2;
- mStashedHandleBounds.set(
- stashedCenterX - mStashedHandleWidth / 2,
- stashedCenterY - mStashedHandleHeight / 2,
- stashedCenterX + mStashedHandleWidth / 2,
- stashedCenterY + mStashedHandleHeight / 2);
- mStashedHandleView.updateSampledRegion(mStashedHandleBounds);
- mStashedHandleRadius = view.getHeight() / 2f;
- outline.setRoundRect(mStashedHandleBounds, mStashedHandleRadius);
- }
- });
-
- mStashedHandleView.addOnLayoutChangeListener((view, i, i1, i2, i3, i4, i5, i6, i7) -> {
- final int stashedCenterX = view.getWidth() / 2;
- final int stashedCenterY = view.getHeight() - stashedTaskbarHeight / 2;
-
- view.setPivotX(stashedCenterX);
- view.setPivotY(stashedCenterY);
- });
- }
-
- public void onDestroy() {
- mRegionSamplingHelper.stopAndDestroy();
- }
-
- public MultiValueAlpha getStashedHandleAlpha() {
- return mTaskbarStashedHandleAlpha;
- }
-
- public AnimatedFloat getStashedHandleHintScale() {
- return mTaskbarStashedHandleHintScale;
- }
-
- /**
- * Creates and returns a {@link RevealOutlineAnimation} Animator that updates the stashed handle
- * shape and size. When stashed, the shape is a thin rounded pill. When unstashed, the shape
- * morphs into the size of where the taskbar icons will be.
- */
- public Animator createRevealAnimToIsStashed(boolean isStashed) {
- final RevealOutlineAnimation handleRevealProvider = new RoundedRectRevealOutlineProvider(
- mStashedHandleRadius, mStashedHandleRadius,
- mControllers.taskbarViewController.getIconLayoutBounds(), mStashedHandleBounds);
-
- boolean isReversed = !isStashed;
- boolean changingDirection = mWasLastRevealAnimReversed != isReversed;
- mWasLastRevealAnimReversed = isReversed;
- if (changingDirection) {
- mStartProgressForNextRevealAnim = 1f - mStartProgressForNextRevealAnim;
- }
-
- ValueAnimator revealAnim = handleRevealProvider.createRevealAnimator(mStashedHandleView,
- isReversed, mStartProgressForNextRevealAnim);
- revealAnim.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- mStartProgressForNextRevealAnim = ((ValueAnimator) animation).getAnimatedFraction();
- }
- });
- return revealAnim;
- }
-
- /** Called when taskbar is stashed or unstashed. */
- public void onIsStashedChanged(boolean isStashed) {
- mRegionSamplingHelper.setWindowVisible(isStashed);
- if (isStashed) {
- mStashedHandleView.updateSampledRegion(mStashedHandleBounds);
- mRegionSamplingHelper.start(mStashedHandleView.getSampledRegion());
- } else {
- mRegionSamplingHelper.stop();
- }
- }
-
- protected void updateStashedHandleHintScale() {
- mStashedHandleView.setScaleX(mTaskbarStashedHandleHintScale.value);
- mStashedHandleView.setScaleY(mTaskbarStashedHandleHintScale.value);
- }
-
- /**
- * Should be called when the home button is disabled, so we can hide this handle as well.
- */
- public void setIsHomeButtonDisabled(boolean homeDisabled) {
- mTaskbarStashedHandleAlpha.getProperty(ALPHA_INDEX_HOME_DISABLED).setValue(
- homeDisabled ? 0 : 1);
- }
-
- public boolean isStashedHandleVisible() {
- return mStashedHandleView.getVisibility() == View.VISIBLE;
- }
-
- @Override
- public void dumpLogs(String prefix, PrintWriter pw) {
- pw.println(prefix + "StashedHandleViewController:");
-
- pw.println(String.format(
- "%s\tisStashedHandleVisible=%b", prefix, isStashedHandleVisible()));
- pw.println(String.format("%s\tmStashedHandleWidth=%dpx", prefix, mStashedHandleWidth));
- pw.println(String.format("%s\tmStashedHandleHeight=%dpx", prefix, mStashedHandleHeight));
- mRegionSamplingHelper.dump(prefix, pw);
- }
-}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
index 95da118948..4ba0ee0d41 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
@@ -15,90 +15,69 @@
*/
package com.android.launcher3.taskbar;
-import static android.content.pm.PackageManager.FEATURE_PC;
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
-import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
-import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
-import static com.android.launcher3.AbstractFloatingView.TYPE_ALL;
-import static com.android.launcher3.AbstractFloatingView.TYPE_REBIND_SAFE;
-import static com.android.launcher3.ResourceUtils.getBoolByName;
-import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_FOLDER_OPEN;
-import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED;
-import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_QUICK_SETTINGS_EXPANDED;
+import static com.android.systemui.shared.system.WindowManagerWrapper.ITYPE_BOTTOM_TAPPABLE_ELEMENT;
+import static com.android.systemui.shared.system.WindowManagerWrapper.ITYPE_EXTRA_NAVIGATION_BAR;
-import android.animation.AnimatorSet;
-import android.animation.ValueAnimator;
import android.app.ActivityOptions;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
-import android.content.pm.ActivityInfo.Config;
import android.content.pm.LauncherApps;
-import android.content.res.Resources;
import android.graphics.PixelFormat;
+import android.graphics.Point;
import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
import android.os.Process;
import android.os.SystemProperties;
-import android.provider.Settings;
import android.util.Log;
+import android.view.ContextThemeWrapper;
import android.view.Display;
import android.view.Gravity;
-import android.view.RoundedCorner;
+import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;
-import android.view.WindowManagerGlobal;
-import android.widget.FrameLayout;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
-import androidx.annotation.VisibleForTesting;
import com.android.launcher3.AbstractFloatingView;
-import com.android.launcher3.BubbleTextView;
import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.DragSource;
+import com.android.launcher3.DropTarget;
import com.android.launcher3.LauncherSettings.Favorites;
import com.android.launcher3.R;
-import com.android.launcher3.anim.AnimatorPlaybackController;
-import com.android.launcher3.config.FeatureFlags;
-import com.android.launcher3.dot.DotInfo;
+import com.android.launcher3.dragndrop.DragController;
+import com.android.launcher3.dragndrop.DragOptions;
+import com.android.launcher3.dragndrop.DragView;
+import com.android.launcher3.dragndrop.DraggableView;
import com.android.launcher3.folder.Folder;
import com.android.launcher3.folder.FolderIcon;
-import com.android.launcher3.logger.LauncherAtom;
-import com.android.launcher3.logging.StatsLogManager;
-import com.android.launcher3.model.data.AppInfo;
import com.android.launcher3.model.data.FolderInfo;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo;
-import com.android.launcher3.popup.PopupDataProvider;
-import com.android.launcher3.taskbar.allapps.TaskbarAllAppsController;
-import com.android.launcher3.testing.TestLogging;
-import com.android.launcher3.testing.TestProtocol;
+import com.android.launcher3.taskbar.TaskbarNavButtonController.TaskbarButton;
import com.android.launcher3.touch.ItemClickHandler;
-import com.android.launcher3.util.DisplayController;
-import com.android.launcher3.util.DisplayController.NavigationMode;
import com.android.launcher3.util.PackageManagerHelper;
-import com.android.launcher3.util.SettingsCache;
+import com.android.launcher3.util.Themes;
import com.android.launcher3.util.TraceHelper;
-import com.android.launcher3.util.ViewCache;
import com.android.launcher3.views.ActivityContext;
+import com.android.quickstep.SysUINavigationMode;
+import com.android.quickstep.SysUINavigationMode.Mode;
import com.android.systemui.shared.recents.model.Task;
-import com.android.systemui.shared.rotation.RotationButtonController;
import com.android.systemui.shared.system.ActivityManagerWrapper;
-import com.android.systemui.unfold.util.ScopedUnfoldTransitionProgressProvider;
-
-import java.io.PrintWriter;
+import com.android.systemui.shared.system.WindowManagerWrapper;
/**
* The {@link ActivityContext} with which we inflate Taskbar-related Views. This allows UI elements
* that are used by both Launcher and Taskbar (such as Folder) to reference a generic
* ActivityContext and BaseDragLayer instead of the Launcher activity and its DragLayer.
*/
-public class TaskbarActivityContext extends BaseTaskbarContext {
-
- private static final String IME_DRAWS_IME_NAV_BAR_RES_NAME = "config_imeDrawsImeNavBar";
+public class TaskbarActivityContext extends ContextThemeWrapper implements ActivityContext {
private static final boolean ENABLE_THREE_BUTTON_TASKBAR =
SystemProperties.getBoolean("persist.debug.taskbar_three_button", false);
@@ -106,513 +85,166 @@ public class TaskbarActivityContext extends BaseTaskbarContext {
private static final String WINDOW_TITLE = "Taskbar";
+ private final DeviceProfile mDeviceProfile;
+ private final LayoutInflater mLayoutInflater;
private final TaskbarDragLayer mDragLayer;
- private final TaskbarControllers mControllers;
+ private final TaskbarIconController mIconController;
+ private final MyDragController mDragController;
private final WindowManager mWindowManager;
- private final @Nullable RoundedCorner mLeftCorner, mRightCorner;
- private DeviceProfile mDeviceProfile;
private WindowManager.LayoutParams mWindowLayoutParams;
- private boolean mIsFullscreen;
- // The size we should return to when we call setTaskbarWindowFullscreen(false)
- private int mLastRequestedNonFullscreenHeight;
- private final NavigationMode mNavMode;
- private final boolean mImeDrawsImeNavBar;
- private final ViewCache mViewCache = new ViewCache();
+ private final SysUINavigationMode.Mode mNavMode;
+ private final TaskbarNavButtonController mNavButtonController;
private final boolean mIsSafeModeEnabled;
- private final boolean mIsUserSetupComplete;
- private final boolean mIsNavBarForceVisible;
- private final boolean mIsNavBarKidsMode;
- private boolean mIsDestroyed = false;
- // The flag to know if the window is excluded from magnification region computation.
- private boolean mIsExcludeFromMagnificationRegion = false;
- private boolean mBindingItems = false;
- private final TaskbarShortcutMenuAccessibilityDelegate mAccessibilityDelegate;
-
- public TaskbarActivityContext(Context windowContext, DeviceProfile dp,
- TaskbarNavButtonController buttonController, ScopedUnfoldTransitionProgressProvider
- unfoldTransitionProgressProvider) {
- super(windowContext);
- mDeviceProfile = dp.copy(this);
+ @NonNull
+ private TaskbarUIController mUIController = TaskbarUIController.DEFAULT;
- final Resources resources = getResources();
+ private final View.OnClickListener mOnTaskbarIconClickListener;
+ private final View.OnLongClickListener mOnTaskbarIconLongClickListener;
- mNavMode = DisplayController.getNavigationMode(windowContext);
- mImeDrawsImeNavBar = getBoolByName(IME_DRAWS_IME_NAV_BAR_RES_NAME, resources, false);
+ public TaskbarActivityContext(Context windowContext, DeviceProfile dp,
+ TaskbarNavButtonController buttonController) {
+ super(windowContext, Themes.getActivityThemeRes(windowContext));
+ mDeviceProfile = dp;
+ mNavButtonController = buttonController;
+ mNavMode = SysUINavigationMode.getMode(windowContext);
mIsSafeModeEnabled = TraceHelper.allowIpcs("isSafeMode",
() -> getPackageManager().isSafeMode());
- mIsUserSetupComplete = SettingsCache.INSTANCE.get(this).getValue(
- Settings.Secure.getUriFor(Settings.Secure.USER_SETUP_COMPLETE), 0);
- mIsNavBarForceVisible = SettingsCache.INSTANCE.get(this).getValue(
- Settings.Secure.getUriFor(Settings.Secure.NAV_BAR_FORCE_VISIBLE), 0);
- mIsNavBarKidsMode = SettingsCache.INSTANCE.get(this).getValue(
- Settings.Secure.getUriFor(Settings.Secure.NAV_BAR_KIDS_MODE), 0);
- updateIconSize(resources);
+ mOnTaskbarIconLongClickListener =
+ new TaskbarDragController(this)::startSystemDragOnLongClick;
+ mOnTaskbarIconClickListener = this::onTaskbarIconClicked;
+
+ float taskbarIconSize = getResources().getDimension(R.dimen.taskbar_icon_size);
+ float iconScale = taskbarIconSize / mDeviceProfile.iconSizePx;
+ mDeviceProfile.updateIconSize(iconScale, getResources());
+
+ mLayoutInflater = LayoutInflater.from(this).cloneInContext(this);
+ mDragLayer = (TaskbarDragLayer) mLayoutInflater
+ .inflate(R.layout.taskbar, null, false);
+ mIconController = new TaskbarIconController(this, mDragLayer);
+ mDragController = new MyDragController(this);
- // Get display and corners first, as views might use them in constructor.
Display display = windowContext.getDisplay();
Context c = display.getDisplayId() == Display.DEFAULT_DISPLAY
? windowContext.getApplicationContext()
: windowContext.getApplicationContext().createDisplayContext(display);
mWindowManager = c.getSystemService(WindowManager.class);
- mLeftCorner = display.getRoundedCorner(RoundedCorner.POSITION_BOTTOM_LEFT);
- mRightCorner = display.getRoundedCorner(RoundedCorner.POSITION_BOTTOM_RIGHT);
-
- // Inflate views.
- mDragLayer = (TaskbarDragLayer) mLayoutInflater.inflate(
- R.layout.taskbar, null, false);
- TaskbarView taskbarView = mDragLayer.findViewById(R.id.taskbar_view);
- TaskbarScrimView taskbarScrimView = mDragLayer.findViewById(R.id.taskbar_scrim);
- FrameLayout navButtonsView = mDragLayer.findViewById(R.id.navbuttons_view);
- StashedHandleView stashedHandleView = mDragLayer.findViewById(R.id.stashed_handle);
-
- mAccessibilityDelegate = new TaskbarShortcutMenuAccessibilityDelegate(this);
-
- // Construct controllers.
- mControllers = new TaskbarControllers(this,
- new TaskbarDragController(this),
- buttonController,
- getPackageManager().hasSystemFeature(FEATURE_PC)
- ? new DesktopNavbarButtonsViewController(this, navButtonsView) :
- new NavbarButtonsViewController(this, navButtonsView),
- new RotationButtonController(this,
- c.getColor(R.color.taskbar_nav_icon_light_color),
- c.getColor(R.color.taskbar_nav_icon_dark_color),
- R.drawable.ic_sysbar_rotate_button_ccw_start_0,
- R.drawable.ic_sysbar_rotate_button_ccw_start_90,
- R.drawable.ic_sysbar_rotate_button_cw_start_0,
- R.drawable.ic_sysbar_rotate_button_cw_start_90,
- () -> getDisplay().getRotation()),
- new TaskbarDragLayerController(this, mDragLayer),
- new TaskbarViewController(this, taskbarView),
- new TaskbarScrimViewController(this, taskbarScrimView),
- new TaskbarUnfoldAnimationController(this, unfoldTransitionProgressProvider,
- mWindowManager, WindowManagerGlobal.getWindowManagerService()),
- new TaskbarKeyguardController(this),
- new StashedHandleViewController(this, stashedHandleView),
- new TaskbarStashController(this),
- new TaskbarEduController(this),
- new TaskbarAutohideSuspendController(this),
- new TaskbarPopupController(this),
- new TaskbarForceVisibleImmersiveController(this),
- new TaskbarAllAppsController(this, dp),
- new TaskbarInsetsController(this));
}
- public void init(@NonNull TaskbarSharedState sharedState) {
- mLastRequestedNonFullscreenHeight = getDefaultTaskbarWindowHeight();
- mWindowLayoutParams = createDefaultWindowLayoutParams();
-
- // Initialize controllers after all are constructed.
- mControllers.init(sharedState);
- updateSysuiStateFlags(sharedState.sysuiStateFlags, true /* fromInit */);
-
- mWindowManager.addView(mDragLayer, mWindowLayoutParams);
- }
-
- @Override
- public DeviceProfile getDeviceProfile() {
- return mDeviceProfile;
- }
-
- /** Updates {@link DeviceProfile} instances for any Taskbar windows. */
- public void updateDeviceProfile(DeviceProfile dp) {
- mControllers.taskbarAllAppsController.updateDeviceProfile(dp);
- mDeviceProfile = dp.copy(this);
- updateIconSize(getResources());
-
- AbstractFloatingView.closeAllOpenViewsExcept(this, false, TYPE_REBIND_SAFE);
- // Reapply fullscreen to take potential new screen size into account.
- setTaskbarWindowFullscreen(mIsFullscreen);
-
- dispatchDeviceProfileChanged();
- }
-
- private void updateIconSize(Resources resources) {
- float taskbarIconSize = resources.getDimension(R.dimen.taskbar_icon_size);
- mDeviceProfile.updateIconSize(1, resources);
- float iconScale = taskbarIconSize / mDeviceProfile.iconSizePx;
- mDeviceProfile.updateIconSize(iconScale, resources);
- }
-
- @VisibleForTesting
- @Override
- public StatsLogManager getStatsLogManager() {
- // Used to mock, can't mock a default interface method directly
- return super.getStatsLogManager();
- }
-
- /** Creates LayoutParams for adding a view directly to WindowManager as a new window */
- public WindowManager.LayoutParams createDefaultWindowLayoutParams() {
- WindowManager.LayoutParams windowLayoutParams = new WindowManager.LayoutParams(
+ public void init() {
+ mWindowLayoutParams = new WindowManager.LayoutParams(
MATCH_PARENT,
- mLastRequestedNonFullscreenHeight,
- TYPE_NAVIGATION_BAR_PANEL,
- WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
- | WindowManager.LayoutParams.FLAG_SLIPPERY,
+ mDeviceProfile.taskbarSize,
+ TYPE_APPLICATION_OVERLAY,
+ WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT);
- windowLayoutParams.setTitle(WINDOW_TITLE);
- windowLayoutParams.packageName = getPackageName();
- windowLayoutParams.gravity = Gravity.BOTTOM;
- windowLayoutParams.setFitInsetsTypes(0);
- windowLayoutParams.receiveInsetsIgnoringZOrder = true;
- windowLayoutParams.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING;
- windowLayoutParams.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
- windowLayoutParams.privateFlags =
- WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION;
- return windowLayoutParams;
- }
-
- public void onConfigurationChanged(@Config int configChanges) {
- mControllers.onConfigurationChanged(configChanges);
- }
-
- public boolean isThreeButtonNav() {
- return mNavMode == NavigationMode.THREE_BUTTONS;
- }
-
- public boolean isGestureNav() {
- return mNavMode == NavigationMode.NO_BUTTON;
- }
-
- public boolean imeDrawsImeNavBar() {
- return mImeDrawsImeNavBar;
- }
-
- public int getLeftCornerRadius() {
- return mLeftCorner == null ? 0 : mLeftCorner.getRadius();
- }
-
- public int getRightCornerRadius() {
- return mRightCorner == null ? 0 : mRightCorner.getRadius();
- }
-
- public WindowManager.LayoutParams getWindowLayoutParams() {
- return mWindowLayoutParams;
- }
-
- @Override
- public TaskbarDragLayer getDragLayer() {
- return mDragLayer;
- }
-
- @Override
- public Rect getFolderBoundingBox() {
- return mControllers.taskbarDragLayerController.getFolderBoundingBox();
- }
-
- @Override
- public TaskbarDragController getDragController() {
- return mControllers.taskbarDragController;
- }
-
- @Override
- public ViewCache getViewCache() {
- return mViewCache;
- }
-
- @Override
- public View.OnClickListener getItemOnClickListener() {
- return this::onTaskbarIconClicked;
+ mWindowLayoutParams.setTitle(WINDOW_TITLE);
+ mWindowLayoutParams.packageName = getPackageName();
+ mWindowLayoutParams.gravity = Gravity.BOTTOM;
+ mWindowLayoutParams.setFitInsetsTypes(0);
+ mWindowLayoutParams.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING;
+ mWindowLayoutParams.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
+ mWindowLayoutParams.setSystemApplicationOverlay(true);
+
+ WindowManagerWrapper wmWrapper = WindowManagerWrapper.getInstance();
+ wmWrapper.setProvidesInsetsTypes(
+ mWindowLayoutParams,
+ new int[] { ITYPE_EXTRA_NAVIGATION_BAR, ITYPE_BOTTOM_TAPPABLE_ELEMENT }
+ );
+
+ mIconController.init(mOnTaskbarIconClickListener, mOnTaskbarIconLongClickListener);
+ mWindowManager.addView(mDragLayer, mWindowLayoutParams);
}
/**
- * Change from hotseat/predicted hotseat to taskbar container.
+ * Updates the TaskbarContainer height (pass deviceProfile.taskbarSize to reset).
*/
- @Override
- public void applyOverwritesToLogItem(LauncherAtom.ItemInfo.Builder itemInfoBuilder) {
- if (!itemInfoBuilder.hasContainerInfo()) {
+ public void setTaskbarWindowHeight(int height) {
+ if (mWindowLayoutParams.height == height) {
return;
}
- LauncherAtom.ContainerInfo oldContainer = itemInfoBuilder.getContainerInfo();
-
- if (oldContainer.hasPredictedHotseatContainer()) {
- LauncherAtom.PredictedHotseatContainer predictedHotseat =
- oldContainer.getPredictedHotseatContainer();
- LauncherAtom.TaskBarContainer.Builder taskbarBuilder =
- LauncherAtom.TaskBarContainer.newBuilder();
-
- if (predictedHotseat.hasIndex()) {
- taskbarBuilder.setIndex(predictedHotseat.getIndex());
- }
- if (predictedHotseat.hasCardinality()) {
- taskbarBuilder.setCardinality(predictedHotseat.getCardinality());
- }
-
- itemInfoBuilder.setContainerInfo(LauncherAtom.ContainerInfo.newBuilder()
- .setTaskBarContainer(taskbarBuilder));
- } else if (oldContainer.hasHotseat()) {
- LauncherAtom.HotseatContainer hotseat = oldContainer.getHotseat();
- LauncherAtom.TaskBarContainer.Builder taskbarBuilder =
- LauncherAtom.TaskBarContainer.newBuilder();
-
- if (hotseat.hasIndex()) {
- taskbarBuilder.setIndex(hotseat.getIndex());
- }
-
- itemInfoBuilder.setContainerInfo(LauncherAtom.ContainerInfo.newBuilder()
- .setTaskBarContainer(taskbarBuilder));
- } else if (oldContainer.hasFolder() && oldContainer.getFolder().hasHotseat()) {
- LauncherAtom.FolderContainer.Builder folderBuilder = oldContainer.getFolder()
- .toBuilder();
- LauncherAtom.HotseatContainer hotseat = folderBuilder.getHotseat();
- LauncherAtom.TaskBarContainer.Builder taskbarBuilder =
- LauncherAtom.TaskBarContainer.newBuilder();
-
- if (hotseat.hasIndex()) {
- taskbarBuilder.setIndex(hotseat.getIndex());
- }
-
- folderBuilder.setTaskbar(taskbarBuilder);
- folderBuilder.clearHotseat();
- itemInfoBuilder.setContainerInfo(LauncherAtom.ContainerInfo.newBuilder()
- .setFolder(folderBuilder));
- } else if (oldContainer.hasAllAppsContainer()) {
- itemInfoBuilder.setContainerInfo(LauncherAtom.ContainerInfo.newBuilder()
- .setAllAppsContainer(oldContainer.getAllAppsContainer().toBuilder()
- .setTaskbarContainer(LauncherAtom.TaskBarContainer.newBuilder())));
- } else if (oldContainer.hasPredictionContainer()) {
- itemInfoBuilder.setContainerInfo(LauncherAtom.ContainerInfo.newBuilder()
- .setPredictionContainer(oldContainer.getPredictionContainer().toBuilder()
- .setTaskbarContainer(LauncherAtom.TaskBarContainer.newBuilder())));
- }
- }
-
- @Override
- public DotInfo getDotInfoForItem(ItemInfo info) {
- return getPopupDataProvider().getDotInfoForItem(info);
+ mWindowLayoutParams.height = height;
+ mWindowManager.updateViewLayout(mDragLayer, mWindowLayoutParams);
}
- @NonNull
- @Override
- public PopupDataProvider getPopupDataProvider() {
- return mControllers.taskbarPopupController.getPopupDataProvider();
+ public boolean canShowNavButtons() {
+ return ENABLE_THREE_BUTTON_TASKBAR && mNavMode == Mode.THREE_BUTTONS;
}
@Override
- public View.AccessibilityDelegate getAccessibilityDelegate() {
- return mAccessibilityDelegate;
+ public LayoutInflater getLayoutInflater() {
+ return mLayoutInflater;
}
@Override
- public boolean isBindingItems() {
- return mBindingItems;
- }
-
- public void setBindingItems(boolean bindingItems) {
- mBindingItems = bindingItems;
+ public TaskbarDragLayer getDragLayer() {
+ return mDragLayer;
}
@Override
- public void onDragStart() {
- setTaskbarWindowFullscreen(true);
+ public DeviceProfile getDeviceProfile() {
+ return mDeviceProfile;
}
@Override
- public void onDragEnd() {
- maybeSetTaskbarWindowNotFullscreen();
+ public Rect getFolderBoundingBox() {
+ return mDragLayer.getFolderBoundingBox();
}
@Override
- public void onPopupVisibilityChanged(boolean isVisible) {
- setTaskbarWindowFocusable(isVisible);
+ public DragController getDragController() {
+ return mDragController;
}
/**
* Sets a new data-source for this taskbar instance
*/
public void setUIController(@NonNull TaskbarUIController uiController) {
- mControllers.uiController.onDestroy();
- mControllers.uiController = uiController;
- mControllers.uiController.init(mControllers);
- }
-
- /**
- * Sets the flag indicating setup UI is visible
- */
- public void setSetupUIVisible(boolean isVisible) {
- mControllers.taskbarStashController.setSetupUIVisible(isVisible);
+ mUIController.onDestroy();
+ mUIController = uiController;
+ mIconController.setUIController(mUIController);
+ mUIController.onCreate();
}
/**
* Called when this instance of taskbar is no longer needed
*/
public void onDestroy() {
- mIsDestroyed = true;
setUIController(TaskbarUIController.DEFAULT);
- mControllers.onDestroy();
+ mIconController.onDestroy();
mWindowManager.removeViewImmediate(mDragLayer);
}
- public void updateSysuiStateFlags(int systemUiStateFlags, boolean fromInit) {
- mControllers.navbarButtonsViewController.updateStateForSysuiFlags(systemUiStateFlags,
- fromInit);
- mControllers.taskbarViewController.setImeIsVisible(
- mControllers.navbarButtonsViewController.isImeVisible());
- int shadeExpandedFlags = SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED
- | SYSUI_STATE_QUICK_SETTINGS_EXPANDED;
- onNotificationShadeExpandChanged((systemUiStateFlags & shadeExpandedFlags) != 0, fromInit);
- mControllers.taskbarViewController.setRecentsButtonDisabled(
- mControllers.navbarButtonsViewController.isRecentsDisabled()
- || isNavBarKidsModeActive());
- mControllers.stashedHandleViewController.setIsHomeButtonDisabled(
- mControllers.navbarButtonsViewController.isHomeDisabled());
- mControllers.taskbarKeyguardController.updateStateForSysuiFlags(systemUiStateFlags);
- mControllers.taskbarStashController.updateStateForSysuiFlags(
- systemUiStateFlags, fromInit || !isUserSetupComplete());
- mControllers.taskbarScrimViewController.updateStateForSysuiFlags(systemUiStateFlags,
- fromInit);
- mControllers.navButtonController.updateSysuiFlags(systemUiStateFlags);
- mControllers.taskbarForceVisibleImmersiveController.updateSysuiFlags(systemUiStateFlags);
- }
-
- /**
- * Hides the taskbar icons and background when the notication shade is expanded.
- */
- private void onNotificationShadeExpandChanged(boolean isExpanded, boolean skipAnim) {
- float alpha = isExpanded ? 0 : 1;
- AnimatorSet anim = new AnimatorSet();
- anim.play(mControllers.taskbarViewController.getTaskbarIconAlpha().getProperty(
- TaskbarViewController.ALPHA_INDEX_NOTIFICATION_EXPANDED).animateToValue(alpha));
- if (!isThreeButtonNav()) {
- anim.play(mControllers.taskbarDragLayerController.getNotificationShadeBgTaskbar()
- .animateToValue(alpha));
- }
- anim.start();
- if (skipAnim) {
- anim.end();
- }
- }
-
- public void onRotationProposal(int rotation, boolean isValid) {
- mControllers.rotationButtonController.onRotationProposal(rotation, isValid);
- }
-
- public void disableNavBarElements(int displayId, int state1, int state2, boolean animate) {
- if (displayId != getDisplayId()) {
- return;
- }
- mControllers.rotationButtonController.onDisable2FlagChanged(state2);
- }
-
- public void onSystemBarAttributesChanged(int displayId, int behavior) {
- mControllers.rotationButtonController.onBehaviorChanged(displayId, behavior);
- }
-
- public void onNavButtonsDarkIntensityChanged(float darkIntensity) {
- if (!isUserSetupComplete()) {
- return;
- }
- mControllers.navbarButtonsViewController.getTaskbarNavButtonDarkIntensity()
- .updateValue(darkIntensity);
- }
-
- /**
- * Updates the TaskbarContainer to MATCH_PARENT vs original Taskbar size.
- */
- public void setTaskbarWindowFullscreen(boolean fullscreen) {
- mControllers.taskbarAutohideSuspendController.updateFlag(
- TaskbarAutohideSuspendController.FLAG_AUTOHIDE_SUSPEND_FULLSCREEN, fullscreen);
- mIsFullscreen = fullscreen;
- setTaskbarWindowHeight(fullscreen ? MATCH_PARENT : mLastRequestedNonFullscreenHeight);
+ void onNavigationButtonClick(@TaskbarButton int buttonType) {
+ mNavButtonController.onButtonClick(buttonType);
}
/**
- * Reverts Taskbar window to its original size, if all floating views are closed and there is
- * no system drag operation in progress.
+ * Should be called when the IME visibility changes, so we can hide/show Taskbar accordingly.
*/
- void maybeSetTaskbarWindowNotFullscreen() {
- if (AbstractFloatingView.getAnyView(this, TYPE_ALL) == null
- && !mControllers.taskbarDragController.isSystemDragInProgress()) {
- setTaskbarWindowFullscreen(false);
- }
- }
-
- public boolean isTaskbarWindowFullscreen() {
- return mIsFullscreen;
+ public void setImeIsVisible(boolean isImeVisible) {
+ mIconController.setImeIsVisible(isImeVisible);
}
/**
- * Notify system to inset the rounded corner frame based on the task bar insets.
- */
- public void updateInsetRoundedCornerFrame(boolean shouldInsetsRoundedCorner) {
- if (!mDragLayer.isAttachedToWindow()
- || mWindowLayoutParams.insetsRoundedCornerFrame == shouldInsetsRoundedCorner) {
- return;
- }
- mWindowLayoutParams.insetsRoundedCornerFrame = shouldInsetsRoundedCorner;
- mWindowManager.updateViewLayout(mDragLayer, mWindowLayoutParams);
- }
-
- /**
- * Updates the TaskbarContainer height (pass {@link #getDefaultTaskbarWindowHeight()} to reset).
- */
- public void setTaskbarWindowHeight(int height) {
- if (mWindowLayoutParams.height == height || mIsDestroyed) {
- return;
- }
- if (height == MATCH_PARENT) {
- height = mDeviceProfile.heightPx;
- } else {
- mLastRequestedNonFullscreenHeight = height;
- if (mIsFullscreen) {
- // We still need to be fullscreen, so defer any change to our height until we call
- // setTaskbarWindowFullscreen(false). For example, this could happen when dragging
- // from the gesture region, as the drag will cancel the gesture and reset launcher's
- // state, which in turn normally would reset the taskbar window height as well.
- return;
- }
- }
- mWindowLayoutParams.height = height;
- mControllers.taskbarInsetsController.onTaskbarWindowHeightOrInsetsChanged();
- mWindowManager.updateViewLayout(mDragLayer, mWindowLayoutParams);
- }
-
- /**
- * Returns the default height of the window, including the static corner radii above taskbar.
- */
- public int getDefaultTaskbarWindowHeight() {
- return mDeviceProfile.taskbarSize + Math.max(getLeftCornerRadius(), getRightCornerRadius());
- }
-
- /**
- * Either adds or removes {@link WindowManager.LayoutParams#FLAG_NOT_FOCUSABLE} on the taskbar
- * window.
+ * When in 3 button nav, the above doesn't get called since we prevent sysui nav bar from
+ * instantiating at all, which is what's responsible for sending sysui state flags over.
+ *
+ * @param vis IME visibility flag
*/
- public void setTaskbarWindowFocusable(boolean focusable) {
- if (focusable) {
- mWindowLayoutParams.flags &= ~FLAG_NOT_FOCUSABLE;
- } else {
- mWindowLayoutParams.flags |= FLAG_NOT_FOCUSABLE;
- }
- mWindowManager.updateViewLayout(mDragLayer, mWindowLayoutParams);
+ public void updateImeStatus(int displayId, int vis, boolean showImeSwitcher) {
+ mIconController.updateImeStatus(displayId, vis, showImeSwitcher);
}
/**
- * Either adds or removes {@link WindowManager.LayoutParams#FLAG_NOT_FOCUSABLE} on the taskbar
- * window. If we're now focusable, also move nav buttons to a separate window above IME.
+ * Updates the TaskbarContainer to MATCH_PARENT vs original Taskbar size.
*/
- public void setTaskbarWindowFocusableForIme(boolean focusable) {
- if (focusable) {
- mControllers.navbarButtonsViewController.moveNavButtonsToNewWindow();
- } else {
- mControllers.navbarButtonsViewController.moveNavButtonsBackToTaskbarWindow();
- }
- setTaskbarWindowFocusable(focusable);
- }
-
- /** Adds the given view to WindowManager with the provided LayoutParams (creates new window). */
- public void addWindowView(View view, WindowManager.LayoutParams windowLayoutParams) {
- mWindowManager.addView(view, windowLayoutParams);
- }
-
- /** Removes the given view from WindowManager. See {@link #addWindowView}. */
- public void removeWindowView(View view) {
- mWindowManager.removeViewImmediate(view);
+ protected void setTaskbarWindowFullscreen(boolean fullscreen) {
+ setTaskbarWindowHeight(fullscreen ? MATCH_PARENT : getDeviceProfile().taskbarSize);
}
protected void onTaskbarIconClicked(View view) {
@@ -624,26 +256,14 @@ public class TaskbarActivityContext extends BaseTaskbarContext {
} else if (tag instanceof FolderInfo) {
FolderIcon folderIcon = (FolderIcon) view;
Folder folder = folderIcon.getFolder();
-
- folder.setOnFolderStateChangedListener(newState -> {
- if (newState == Folder.STATE_OPEN) {
- setTaskbarWindowFocusableForIme(true);
- } else if (newState == Folder.STATE_CLOSED) {
- // Defer by a frame to ensure we're no longer fullscreen and thus won't jump.
- getDragLayer().post(() -> setTaskbarWindowFocusableForIme(false));
- folder.setOnFolderStateChangedListener(null);
- }
- });
-
setTaskbarWindowFullscreen(true);
getDragLayer().post(() -> {
folder.animateOpen();
- getStatsLogManager().logger().withItemInfo(folder.mInfo).log(LAUNCHER_FOLDER_OPEN);
folder.iterateOverItems((itemInfo, itemView) -> {
- mControllers.taskbarViewController
- .setClickAndLongClickListenersForIcon(itemView);
+ itemView.setOnClickListener(mOnTaskbarIconClickListener);
+ itemView.setOnLongClickListener(mOnTaskbarIconLongClickListener);
// To play haptic when dragging, like other Taskbar items do.
itemView.setHapticFeedbackEnabled(true);
return false;
@@ -651,9 +271,7 @@ public class TaskbarActivityContext extends BaseTaskbarContext {
});
} else if (tag instanceof WorkspaceItemInfo) {
WorkspaceItemInfo info = (WorkspaceItemInfo) tag;
- if (info.isDisabled()) {
- ItemClickHandler.handleDisabledItemClicked(info, this);
- } else {
+ if (!(info.isDisabled() && ItemClickHandler.handleDisabledItemClicked(info, this))) {
Intent intent = new Intent(info.getIntent())
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
try {
@@ -661,34 +279,28 @@ public class TaskbarActivityContext extends BaseTaskbarContext {
Toast.makeText(this, R.string.safemode_shortcut_error,
Toast.LENGTH_SHORT).show();
} else if (info.isPromise()) {
- TestLogging.recordEvent(
- TestProtocol.SEQUENCE_MAIN, "start: taskbarPromiseIcon");
intent = new PackageManagerHelper(this)
.getMarketIntent(info.getTargetPackage())
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
} else if (info.itemType == Favorites.ITEM_TYPE_DEEP_SHORTCUT) {
- TestLogging.recordEvent(
- TestProtocol.SEQUENCE_MAIN, "start: taskbarDeepShortcut");
String id = info.getDeepShortcutId();
String packageName = intent.getPackage();
getSystemService(LauncherApps.class)
.startShortcut(packageName, id, null, null, info.user);
+ } else if (info.user.equals(Process.myUserHandle())) {
+ startActivity(intent);
} else {
- startItemInfoActivity(info);
+ getSystemService(LauncherApps.class).startMainActivity(
+ intent.getComponent(), info.user, intent.getSourceBounds(), null);
}
-
- mControllers.uiController.onTaskbarIconLaunched(info);
} catch (NullPointerException | ActivityNotFoundException | SecurityException e) {
Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT)
.show();
Log.e(TAG, "Unable to launch. tag=" + info + " intent=" + intent, e);
}
}
- } else if (tag instanceof AppInfo) {
- startItemInfoActivity((AppInfo) tag);
- mControllers.uiController.onTaskbarIconLaunched((AppInfo) tag);
} else {
Log.e(TAG, "Unknown type clicked: " + tag);
}
@@ -696,132 +308,26 @@ public class TaskbarActivityContext extends BaseTaskbarContext {
AbstractFloatingView.closeAllOpenViews(this);
}
- private void startItemInfoActivity(ItemInfo info) {
- Intent intent = new Intent(info.getIntent())
- .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- try {
- TestLogging.recordEvent(TestProtocol.SEQUENCE_MAIN, "start: taskbarAppIcon");
- if (info.user.equals(Process.myUserHandle())) {
- // TODO(b/216683257): Use startActivityForResult for search results that require it.
- startActivity(intent);
- } else {
- getSystemService(LauncherApps.class).startMainActivity(
- intent.getComponent(), info.user, intent.getSourceBounds(), null);
- }
- } catch (NullPointerException | ActivityNotFoundException | SecurityException e) {
- Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT)
- .show();
- Log.e(TAG, "Unable to launch. tag=" + info + " intent=" + intent, e);
+ private static class MyDragController extends DragController<TaskbarActivityContext> {
+ MyDragController(TaskbarActivityContext activity) {
+ super(activity);
}
- }
-
- /**
- * Called when we detect a long press in the nav region before passing the gesture slop.
- * @return Whether taskbar handled the long press, and thus should cancel the gesture.
- */
- public boolean onLongPressToUnstashTaskbar() {
- return mControllers.taskbarStashController.onLongPressToUnstashTaskbar();
- }
-
- /**
- * Called when we detect a motion down or up/cancel in the nav region while stashed.
- * @param animateForward Whether to animate towards the unstashed hint state or back to stashed.
- */
- public void startTaskbarUnstashHint(boolean animateForward) {
- mControllers.taskbarStashController.startUnstashHint(animateForward);
- }
-
- protected boolean isUserSetupComplete() {
- return mIsUserSetupComplete;
- }
-
- protected boolean isNavBarKidsModeActive() {
- return mIsNavBarKidsMode && isThreeButtonNav();
- }
- protected boolean isNavBarForceVisible() {
- return mIsNavBarForceVisible;
- }
-
- /**
- * Displays a single frame of the Launcher start from SUW animation.
- *
- * This animation is a combination of the Launcher resume animation, which animates the hotseat
- * icons into position, the Taskbar unstash to hotseat animation, which animates the Taskbar
- * stash bar into the hotseat icons, and an override to prevent showing the Taskbar all apps
- * button.
- *
- * This should be used to run a Taskbar unstash to hotseat animation whose progress matches a
- * swipe progress.
- *
- * @param duration a placeholder duration to be used to ensure all full-length
- * sub-animations are properly coordinated. This duration should not actually
- * be used since this animation tracks a swipe progress.
- */
- protected AnimatorPlaybackController createLauncherStartFromSuwAnim(int duration) {
- AnimatorSet fullAnimation = new AnimatorSet();
- fullAnimation.setDuration(duration);
-
- TaskbarUIController uiController = mControllers.uiController;
- if (uiController instanceof LauncherTaskbarUIController) {
- ((LauncherTaskbarUIController) uiController).addLauncherResumeAnimation(
- fullAnimation, duration);
- }
- mControllers.taskbarStashController.addUnstashToHotseatAnimation(fullAnimation, duration);
-
- if (!FeatureFlags.ENABLE_ALL_APPS_BUTTON_IN_HOTSEAT.get()) {
- ValueAnimator alphaOverride = ValueAnimator.ofFloat(0, 1);
- alphaOverride.setDuration(duration);
- alphaOverride.addUpdateListener(a -> {
- // Override the alpha updates in the icon alignment animation.
- mControllers.taskbarViewController.getAllAppsButtonView().setAlpha(0);
- });
- fullAnimation.play(alphaOverride);
+ @Override
+ protected DragView startDrag(@Nullable Drawable drawable, @Nullable View view,
+ DraggableView originalView, int dragLayerX, int dragLayerY, DragSource source,
+ ItemInfo dragInfo, Point dragOffset, Rect dragRegion, float initialDragViewScale,
+ float dragViewScaleOnDrop, DragOptions options) {
+ return null;
}
- return AnimatorPlaybackController.wrap(fullAnimation, duration);
- }
-
- /**
- * Called when we determine the touchable region.
- *
- * @param exclude {@code true} then the magnification region computation will omit the window.
- */
- public void excludeFromMagnificationRegion(boolean exclude) {
- if (mIsExcludeFromMagnificationRegion == exclude) {
- return;
+ @Override
+ protected void exitDrag() {
}
- mIsExcludeFromMagnificationRegion = exclude;
- if (exclude) {
- mWindowLayoutParams.privateFlags |=
- WindowManager.LayoutParams.PRIVATE_FLAG_EXCLUDE_FROM_SCREEN_MAGNIFICATION;
- } else {
- mWindowLayoutParams.privateFlags &=
- ~WindowManager.LayoutParams.PRIVATE_FLAG_EXCLUDE_FROM_SCREEN_MAGNIFICATION;
+ @Override
+ protected DropTarget getDefaultDropTarget(int[] dropCoordinates) {
+ return null;
}
- mWindowManager.updateViewLayout(mDragLayer, mWindowLayoutParams);
- }
-
- public void showPopupMenuForIcon(BubbleTextView btv) {
- setTaskbarWindowFullscreen(true);
- btv.post(() -> mControllers.taskbarPopupController.showForIcon(btv));
- }
-
- protected void dumpLogs(String prefix, PrintWriter pw) {
- pw.println(prefix + "TaskbarActivityContext:");
-
- pw.println(String.format(
- "%s\tmNavMode=%s", prefix, mNavMode));
- pw.println(String.format(
- "%s\tmImeDrawsImeNavBar=%b", prefix, mImeDrawsImeNavBar));
- pw.println(String.format(
- "%s\tmIsUserSetupComplete=%b", prefix, mIsUserSetupComplete));
- pw.println(String.format(
- "%s\tmWindowLayoutParams.height=%dpx", prefix, mWindowLayoutParams.height));
- pw.println(String.format(
- "%s\tmBindInProgress=%b", prefix, mBindingItems));
- mControllers.dumpLogs(prefix + "\t", pw);
- mDeviceProfile.dump(prefix, pw);
}
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarAnimationController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarAnimationController.java
new file mode 100644
index 0000000000..e20ddf88ce
--- /dev/null
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarAnimationController.java
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2021 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.launcher3.taskbar;
+
+import static com.android.launcher3.LauncherState.TASKBAR;
+
+import android.animation.Animator;
+
+import com.android.launcher3.BaseQuickstepLauncher;
+import com.android.launcher3.Utilities;
+import com.android.launcher3.taskbar.LauncherTaskbarUIController.TaskbarAnimationControllerCallbacks;
+import com.android.quickstep.AnimatedFloat;
+import com.android.quickstep.SystemUiProxy;
+import com.android.systemui.shared.system.QuickStepContract;
+
+/**
+ * Works with TaskbarController to update the TaskbarView's visual properties based on factors such
+ * as LauncherState, whether Launcher is in the foreground, etc.
+ */
+public class TaskbarAnimationController {
+
+ private static final long IME_VISIBILITY_ALPHA_DURATION = 120;
+
+ private final BaseQuickstepLauncher mLauncher;
+ private final TaskbarAnimationControllerCallbacks mTaskbarCallbacks;
+
+ // Background alpha.
+ private final AnimatedFloat mTaskbarBackgroundAlpha = new AnimatedFloat(
+ this::onTaskbarBackgroundAlphaChanged);
+
+ // Overall visibility.
+ private final AnimatedFloat mTaskbarVisibilityAlphaForLauncherState = new AnimatedFloat(
+ this::updateVisibilityAlpha);
+ private final AnimatedFloat mTaskbarVisibilityAlphaForIme = new AnimatedFloat(
+ this::updateVisibilityAlphaForIme);
+
+ // Scale.
+ private final AnimatedFloat mTaskbarScaleForLauncherState = new AnimatedFloat(
+ this::updateScale);
+
+ // TranslationY.
+ private final AnimatedFloat mTaskbarTranslationYForLauncherState = new AnimatedFloat(
+ this::updateTranslationY);
+
+ public TaskbarAnimationController(BaseQuickstepLauncher launcher,
+ TaskbarAnimationControllerCallbacks taskbarCallbacks) {
+ mLauncher = launcher;
+ mTaskbarCallbacks = taskbarCallbacks;
+ }
+
+ protected void init() {
+ mTaskbarBackgroundAlpha.updateValue(mLauncher.hasBeenResumed() ? 0f : 1f);
+ boolean isVisibleForLauncherState = (mLauncher.getStateManager().getState()
+ .getVisibleElements(mLauncher) & TASKBAR) != 0;
+ mTaskbarVisibilityAlphaForLauncherState.updateValue(isVisibleForLauncherState ? 1f : 0f);
+ boolean isImeVisible = (SystemUiProxy.INSTANCE.get(mLauncher).getLastSystemUiStateFlags()
+ & QuickStepContract.SYSUI_STATE_IME_SHOWING) != 0;
+ mTaskbarVisibilityAlphaForIme.updateValue(isImeVisible ? 0f : 1f);
+
+ onTaskbarBackgroundAlphaChanged();
+ updateVisibilityAlpha();
+ }
+
+ protected void cleanup() {
+ setNavBarButtonAlpha(1f);
+ }
+
+ protected AnimatedFloat getTaskbarVisibilityForLauncherState() {
+ return mTaskbarVisibilityAlphaForLauncherState;
+ }
+
+ protected AnimatedFloat getTaskbarScaleForLauncherState() {
+ return mTaskbarScaleForLauncherState;
+ }
+
+ protected AnimatedFloat getTaskbarTranslationYForLauncherState() {
+ return mTaskbarTranslationYForLauncherState;
+ }
+
+ protected Animator createAnimToBackgroundAlpha(float toAlpha, long duration) {
+ return mTaskbarBackgroundAlpha.animateToValue(mTaskbarBackgroundAlpha.value, toAlpha)
+ .setDuration(duration);
+ }
+
+ protected void animateToVisibilityForIme(float toAlpha) {
+ mTaskbarVisibilityAlphaForIme.animateToValue(mTaskbarVisibilityAlphaForIme.value, toAlpha)
+ .setDuration(IME_VISIBILITY_ALPHA_DURATION).start();
+ }
+
+ private void onTaskbarBackgroundAlphaChanged() {
+ mTaskbarCallbacks.updateTaskbarBackgroundAlpha(mTaskbarBackgroundAlpha.value);
+ updateVisibilityAlpha();
+ updateScale();
+ updateTranslationY();
+ }
+
+ private void updateVisibilityAlpha() {
+ // We use mTaskbarBackgroundAlpha as a proxy for whether Launcher is resumed/paused, the
+ // assumption being that Taskbar should always be visible regardless of the current
+ // LauncherState if Launcher is paused.
+ float alphaDueToIme = mTaskbarVisibilityAlphaForIme.value;
+ float alphaDueToLauncher = Math.max(mTaskbarBackgroundAlpha.value,
+ mTaskbarVisibilityAlphaForLauncherState.value);
+ float taskbarAlpha = alphaDueToLauncher * alphaDueToIme;
+ mTaskbarCallbacks.updateTaskbarVisibilityAlpha(taskbarAlpha);
+
+ // Make the nav bar invisible if taskbar is visible.
+ setNavBarButtonAlpha(1f - taskbarAlpha);
+ }
+
+ private void updateVisibilityAlphaForIme() {
+ updateVisibilityAlpha();
+ float taskbarAlphaDueToIme = mTaskbarVisibilityAlphaForIme.value;
+ mTaskbarCallbacks.updateImeBarVisibilityAlpha(1f - taskbarAlphaDueToIme);
+ }
+
+ private void updateScale() {
+ // We use mTaskbarBackgroundAlpha as a proxy for whether Launcher is resumed/paused, the
+ // assumption being that Taskbar should always be at scale 1f regardless of the current
+ // LauncherState if Launcher is paused.
+ float scale = mTaskbarScaleForLauncherState.value;
+ scale = Utilities.mapRange(mTaskbarBackgroundAlpha.value, scale, 1f);
+ mTaskbarCallbacks.updateTaskbarScale(scale);
+ }
+
+ private void updateTranslationY() {
+ // We use mTaskbarBackgroundAlpha as a proxy for whether Launcher is resumed/paused, the
+ // assumption being that Taskbar should always be at translationY 0f regardless of the
+ // current LauncherState if Launcher is paused.
+ float translationY = mTaskbarTranslationYForLauncherState.value;
+ translationY = Utilities.mapRange(mTaskbarBackgroundAlpha.value, translationY, 0f);
+ mTaskbarCallbacks.updateTaskbarTranslationY(translationY);
+ }
+
+ private void setNavBarButtonAlpha(float navBarAlpha) {
+ SystemUiProxy.INSTANCE.get(mLauncher).setNavBarButtonAlpha(navBarAlpha, false);
+ }
+}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarAutohideSuspendController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarAutohideSuspendController.java
deleted file mode 100644
index c5615c7ba1..0000000000
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarAutohideSuspendController.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (C) 2021 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.launcher3.taskbar;
-
-import static com.android.launcher3.taskbar.Utilities.appendFlag;
-
-import androidx.annotation.IntDef;
-
-import com.android.quickstep.SystemUiProxy;
-
-import java.io.PrintWriter;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.StringJoiner;
-
-/**
- * Normally Taskbar will auto-hide when entering immersive (fullscreen) apps. This controller allows
- * us to suspend that behavior in certain cases (e.g. opening a Folder or dragging an icon).
- */
-public class TaskbarAutohideSuspendController implements
- TaskbarControllers.LoggableTaskbarController {
-
- public static final int FLAG_AUTOHIDE_SUSPEND_FULLSCREEN = 1 << 0;
- public static final int FLAG_AUTOHIDE_SUSPEND_DRAGGING = 1 << 1;
-
- @IntDef(flag = true, value = {
- FLAG_AUTOHIDE_SUSPEND_FULLSCREEN,
- FLAG_AUTOHIDE_SUSPEND_DRAGGING,
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface AutohideSuspendFlag {}
-
- private final SystemUiProxy mSystemUiProxy;
-
- private @AutohideSuspendFlag int mAutohideSuspendFlags = 0;
-
- public TaskbarAutohideSuspendController(TaskbarActivityContext activity) {
- mSystemUiProxy = SystemUiProxy.INSTANCE.get(activity);
- }
-
- public void onDestroy() {
- mSystemUiProxy.notifyTaskbarAutohideSuspend(false);
- }
-
- /**
- * Adds or removes the given flag, then notifies system UI proxy whether to suspend auto-hide.
- */
- public void updateFlag(@AutohideSuspendFlag int flag, boolean enabled) {
- if (enabled) {
- mAutohideSuspendFlags |= flag;
- } else {
- mAutohideSuspendFlags &= ~flag;
- }
- mSystemUiProxy.notifyTaskbarAutohideSuspend(mAutohideSuspendFlags != 0);
- }
-
- @Override
- public void dumpLogs(String prefix, PrintWriter pw) {
- pw.println(prefix + "TaskbarAutohideSuspendController:");
-
- pw.println(String.format(
- "%s\tmAutohideSuspendFlags=%s", prefix, getStateString(mAutohideSuspendFlags)));
- }
-
- private static String getStateString(int flags) {
- StringJoiner str = new StringJoiner("|");
- appendFlag(str, flags, FLAG_AUTOHIDE_SUSPEND_FULLSCREEN,
- "FLAG_AUTOHIDE_SUSPEND_FULLSCREEN");
- appendFlag(str, flags, FLAG_AUTOHIDE_SUSPEND_DRAGGING, "FLAG_AUTOHIDE_SUSPEND_DRAGGING");
- return str.toString();
- }
-}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarBackgroundRenderer.kt b/quickstep/src/com/android/launcher3/taskbar/TaskbarBackgroundRenderer.kt
deleted file mode 100644
index 1177bdb484..0000000000
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarBackgroundRenderer.kt
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.launcher3.taskbar
-
-import android.graphics.Canvas
-import android.graphics.Paint
-import android.graphics.Path
-import com.android.launcher3.R
-
-/**
- * Helps draw the taskbar background, made up of a rectangle plus two inverted rounded corners.
- */
-class TaskbarBackgroundRenderer(context: TaskbarActivityContext) {
-
- val paint: Paint = Paint()
- var backgroundHeight = context.deviceProfile.taskbarSize.toFloat()
-
- private val leftCornerRadius = context.leftCornerRadius.toFloat()
- private val rightCornerRadius = context.rightCornerRadius.toFloat()
- private val invertedLeftCornerPath: Path = Path()
- private val invertedRightCornerPath: Path = Path()
-
- init {
- paint.color = context.getColor(R.color.taskbar_background)
- paint.flags = Paint.ANTI_ALIAS_FLAG
- paint.style = Paint.Style.FILL
-
- // Create the paths for the inverted rounded corners above the taskbar. Start with a filled
- // square, and then subtract out a circle from the appropriate corner.
- val square = Path()
- square.addRect(0f, 0f, leftCornerRadius, leftCornerRadius, Path.Direction.CW)
- val circle = Path()
- circle.addCircle(leftCornerRadius, 0f, leftCornerRadius, Path.Direction.CW)
- invertedLeftCornerPath.op(square, circle, Path.Op.DIFFERENCE)
- square.reset()
- square.addRect(0f, 0f, rightCornerRadius, rightCornerRadius, Path.Direction.CW)
- circle.reset()
- circle.addCircle(0f, 0f, rightCornerRadius, Path.Direction.CW)
- invertedRightCornerPath.op(square, circle, Path.Op.DIFFERENCE)
- }
-
- /**
- * Draws the background with the given paint and height, on the provided canvas.
- */
- fun draw(canvas: Canvas) {
- canvas.save()
- canvas.translate(0f, canvas.height - backgroundHeight)
-
- // Draw the background behind taskbar content.
- canvas.drawRect(0f, 0f, canvas.width.toFloat(), backgroundHeight, paint)
-
- // Draw the inverted rounded corners above the taskbar.
- canvas.translate(0f, -leftCornerRadius)
- canvas.drawPath(invertedLeftCornerPath, paint)
- canvas.translate(0f, leftCornerRadius)
- canvas.translate(canvas.width - rightCornerRadius, -rightCornerRadius)
- canvas.drawPath(invertedRightCornerPath, paint)
-
- canvas.restore()
- }
-}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java
deleted file mode 100644
index 449e0a7311..0000000000
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java
+++ /dev/null
@@ -1,219 +0,0 @@
-/*
- * Copyright (C) 2021 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.launcher3.taskbar;
-
-import android.content.pm.ActivityInfo.Config;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.annotation.VisibleForTesting;
-
-import com.android.launcher3.taskbar.allapps.TaskbarAllAppsController;
-import com.android.systemui.shared.rotation.RotationButtonController;
-
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Hosts various taskbar controllers to facilitate passing between one another.
- */
-public class TaskbarControllers {
-
- public final TaskbarActivityContext taskbarActivityContext;
-
- public final TaskbarDragController taskbarDragController;
- public final TaskbarNavButtonController navButtonController;
- public final NavbarButtonsViewController navbarButtonsViewController;
- public final RotationButtonController rotationButtonController;
- public final TaskbarDragLayerController taskbarDragLayerController;
- public final TaskbarScrimViewController taskbarScrimViewController;
- public final TaskbarViewController taskbarViewController;
- public final TaskbarUnfoldAnimationController taskbarUnfoldAnimationController;
- public final TaskbarKeyguardController taskbarKeyguardController;
- public final StashedHandleViewController stashedHandleViewController;
- public final TaskbarStashController taskbarStashController;
- public final TaskbarEduController taskbarEduController;
- public final TaskbarAutohideSuspendController taskbarAutohideSuspendController;
- public final TaskbarPopupController taskbarPopupController;
- public final TaskbarForceVisibleImmersiveController taskbarForceVisibleImmersiveController;
- public final TaskbarAllAppsController taskbarAllAppsController;
- public final TaskbarInsetsController taskbarInsetsController;
-
- @Nullable private LoggableTaskbarController[] mControllersToLog = null;
-
- /** Do not store this controller, as it may change at runtime. */
- @NonNull public TaskbarUIController uiController = TaskbarUIController.DEFAULT;
-
- private boolean mAreAllControllersInitialized;
- private final List<Runnable> mPostInitCallbacks = new ArrayList<>();
-
- @Nullable private TaskbarSharedState mSharedState = null;
-
- public TaskbarControllers(TaskbarActivityContext taskbarActivityContext,
- TaskbarDragController taskbarDragController,
- TaskbarNavButtonController navButtonController,
- NavbarButtonsViewController navbarButtonsViewController,
- RotationButtonController rotationButtonController,
- TaskbarDragLayerController taskbarDragLayerController,
- TaskbarViewController taskbarViewController,
- TaskbarScrimViewController taskbarScrimViewController,
- TaskbarUnfoldAnimationController taskbarUnfoldAnimationController,
- TaskbarKeyguardController taskbarKeyguardController,
- StashedHandleViewController stashedHandleViewController,
- TaskbarStashController taskbarStashController,
- TaskbarEduController taskbarEduController,
- TaskbarAutohideSuspendController taskbarAutoHideSuspendController,
- TaskbarPopupController taskbarPopupController,
- TaskbarForceVisibleImmersiveController taskbarForceVisibleImmersiveController,
- TaskbarAllAppsController taskbarAllAppsController,
- TaskbarInsetsController taskbarInsetsController) {
- this.taskbarActivityContext = taskbarActivityContext;
- this.taskbarDragController = taskbarDragController;
- this.navButtonController = navButtonController;
- this.navbarButtonsViewController = navbarButtonsViewController;
- this.rotationButtonController = rotationButtonController;
- this.taskbarDragLayerController = taskbarDragLayerController;
- this.taskbarViewController = taskbarViewController;
- this.taskbarScrimViewController = taskbarScrimViewController;
- this.taskbarUnfoldAnimationController = taskbarUnfoldAnimationController;
- this.taskbarKeyguardController = taskbarKeyguardController;
- this.stashedHandleViewController = stashedHandleViewController;
- this.taskbarStashController = taskbarStashController;
- this.taskbarEduController = taskbarEduController;
- this.taskbarAutohideSuspendController = taskbarAutoHideSuspendController;
- this.taskbarPopupController = taskbarPopupController;
- this.taskbarForceVisibleImmersiveController = taskbarForceVisibleImmersiveController;
- this.taskbarAllAppsController = taskbarAllAppsController;
- this.taskbarInsetsController = taskbarInsetsController;
- }
-
- /**
- * Initializes all controllers. Note that controllers can now reference each other through this
- * TaskbarControllers instance, but should be careful to only access things that were created
- * in constructors for now, as some controllers may still be waiting for init().
- */
- public void init(@NonNull TaskbarSharedState sharedState) {
- mAreAllControllersInitialized = false;
- mSharedState = sharedState;
-
- taskbarDragController.init(this);
- navbarButtonsViewController.init(this);
- rotationButtonController.init();
- taskbarDragLayerController.init(this);
- taskbarViewController.init(this);
- taskbarScrimViewController.init(this);
- taskbarUnfoldAnimationController.init(this);
- taskbarKeyguardController.init(navbarButtonsViewController);
- stashedHandleViewController.init(this);
- taskbarStashController.init(this, sharedState.setupUIVisible);
- taskbarEduController.init(this);
- taskbarPopupController.init(this);
- taskbarForceVisibleImmersiveController.init(this);
- taskbarAllAppsController.init(this, sharedState.allAppsVisible);
- navButtonController.init(this);
- taskbarInsetsController.init(this);
-
- mControllersToLog = new LoggableTaskbarController[] {
- taskbarDragController, navButtonController, navbarButtonsViewController,
- taskbarDragLayerController, taskbarScrimViewController, taskbarViewController,
- taskbarUnfoldAnimationController, taskbarKeyguardController,
- stashedHandleViewController, taskbarStashController, taskbarEduController,
- taskbarAutohideSuspendController, taskbarPopupController, taskbarInsetsController
- };
-
- mAreAllControllersInitialized = true;
- for (Runnable postInitCallback : mPostInitCallbacks) {
- postInitCallback.run();
- }
- mPostInitCallbacks.clear();
- }
-
- @Nullable
- public TaskbarSharedState getSharedState() {
- // This should only be null if called before init() and after destroy().
- return mSharedState;
- }
-
- public void onConfigurationChanged(@Config int configChanges) {
- navbarButtonsViewController.onConfigurationChanged(configChanges);
- }
-
- /**
- * Cleans up all controllers.
- */
- public void onDestroy() {
- mSharedState = null;
-
- navbarButtonsViewController.onDestroy();
- uiController.onDestroy();
- rotationButtonController.onDestroy();
- taskbarDragLayerController.onDestroy();
- taskbarKeyguardController.onDestroy();
- taskbarUnfoldAnimationController.onDestroy();
- taskbarViewController.onDestroy();
- stashedHandleViewController.onDestroy();
- taskbarAutohideSuspendController.onDestroy();
- taskbarPopupController.onDestroy();
- taskbarForceVisibleImmersiveController.onDestroy();
- taskbarAllAppsController.onDestroy();
- navButtonController.onDestroy();
- taskbarInsetsController.onDestroy();
-
- mControllersToLog = null;
- }
-
- /**
- * If all controllers are already initialized, runs the given callback immediately. Otherwise,
- * queues it to run after calling init() on all controllers. This should likely be used in any
- * case where one controller is telling another controller to do something inside init().
- */
- public void runAfterInit(Runnable callback) {
- if (mAreAllControllersInitialized) {
- callback.run();
- } else {
- mPostInitCallbacks.add(callback);
- }
- }
-
- protected void dumpLogs(String prefix, PrintWriter pw) {
- pw.println(prefix + "TaskbarControllers:");
-
- if (mControllersToLog == null) {
- pw.println(String.format(
- "%s\t%s", prefix, "All taskbar controllers have already been destroyed."));
- return;
- }
-
- pw.println(String.format(
- "%s\tmAreAllControllersInitialized=%b", prefix, mAreAllControllersInitialized));
- for (LoggableTaskbarController controller : mControllersToLog) {
- controller.dumpLogs(prefix + "\t", pw);
- }
- uiController.dumpLogs(prefix + "\t", pw);
- rotationButtonController.dumpLogs(prefix + "\t", pw);
- }
-
- @VisibleForTesting
- TaskbarActivityContext getTaskbarActivityContext() {
- // Used to mock
- return taskbarActivityContext;
- }
-
- protected interface LoggableTaskbarController {
- void dumpLogs(String prefix, PrintWriter pw);
- }
-}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragController.java
index c522888fce..ee44927ce4 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragController.java
@@ -15,556 +15,129 @@
*/
package com.android.launcher3.taskbar;
-import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_ALL_APPS;
-import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT;
+import static android.view.View.INVISIBLE;
+import static android.view.View.VISIBLE;
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.ValueAnimator;
import android.content.ClipData;
import android.content.ClipDescription;
+import android.content.Context;
import android.content.Intent;
import android.content.pm.LauncherApps;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Point;
-import android.graphics.Rect;
-import android.graphics.drawable.Drawable;
import android.os.UserHandle;
import android.view.DragEvent;
-import android.view.MotionEvent;
-import android.view.SurfaceControl;
import android.view.View;
-import android.view.ViewRootImpl;
-import android.window.SurfaceSyncer;
-import androidx.annotation.Nullable;
-
-import com.android.internal.logging.InstanceId;
-import com.android.internal.logging.InstanceIdSequence;
-import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.BubbleTextView;
-import com.android.launcher3.DragSource;
-import com.android.launcher3.DropTarget;
import com.android.launcher3.LauncherSettings;
import com.android.launcher3.R;
-import com.android.launcher3.Utilities;
-import com.android.launcher3.accessibility.DragViewStateAnnouncer;
-import com.android.launcher3.anim.Interpolators;
-import com.android.launcher3.config.FeatureFlags;
-import com.android.launcher3.dragndrop.DragController;
-import com.android.launcher3.dragndrop.DragDriver;
-import com.android.launcher3.dragndrop.DragOptions;
-import com.android.launcher3.dragndrop.DragView;
-import com.android.launcher3.dragndrop.DraggableView;
-import com.android.launcher3.graphics.DragPreviewProvider;
-import com.android.launcher3.logging.StatsLogManager;
-import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo;
-import com.android.launcher3.popup.PopupContainerWithArrow;
-import com.android.launcher3.shortcuts.DeepShortcutView;
-import com.android.launcher3.shortcuts.ShortcutDragPreviewProvider;
-import com.android.launcher3.testing.TestLogging;
-import com.android.launcher3.testing.TestProtocol;
-import com.android.launcher3.util.IntSet;
-import com.android.launcher3.util.ItemInfoMatcher;
import com.android.systemui.shared.recents.model.Task;
-
-import java.io.PrintWriter;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.function.Predicate;
+import com.android.systemui.shared.system.ClipDescriptionCompat;
+import com.android.systemui.shared.system.LauncherAppsCompat;
/**
* Handles long click on Taskbar items to start a system drag and drop operation.
*/
-public class TaskbarDragController extends DragController<BaseTaskbarContext> implements
- TaskbarControllers.LoggableTaskbarController {
-
- private static boolean DEBUG_DRAG_SHADOW_SURFACE = false;
+public class TaskbarDragController {
+ private final Context mContext;
private final int mDragIconSize;
- private final int[] mTempXY = new int[2];
-
- // Initialized in init.
- TaskbarControllers mControllers;
-
- // Where the initial touch was relative to the dragged icon.
- private int mRegistrationX;
- private int mRegistrationY;
-
- private boolean mIsSystemDragInProgress;
-
- // Animation for the drag shadow back into position after an unsuccessful drag
- private ValueAnimator mReturnAnimator;
- public TaskbarDragController(BaseTaskbarContext activity) {
- super(activity);
- Resources resources = mActivity.getResources();
+ public TaskbarDragController(Context context) {
+ mContext = context;
+ Resources resources = mContext.getResources();
mDragIconSize = resources.getDimensionPixelSize(R.dimen.taskbar_icon_drag_icon_size);
}
- public void init(TaskbarControllers controllers) {
- mControllers = controllers;
- }
-
/**
* Attempts to start a system drag and drop operation for the given View, using its tag to
* generate the ClipDescription and Intent.
* @return Whether {@link View#startDragAndDrop} started successfully.
*/
- public boolean startDragOnLongClick(View view) {
- return startDragOnLongClick(view, null, null);
- }
-
- protected boolean startDragOnLongClick(
- DeepShortcutView shortcutView, Point iconShift) {
- return startDragOnLongClick(
- shortcutView.getBubbleText(),
- new ShortcutDragPreviewProvider(shortcutView.getIconView(), iconShift),
- iconShift);
- }
-
- private boolean startDragOnLongClick(
- View view,
- @Nullable DragPreviewProvider dragPreviewProvider,
- @Nullable Point iconShift) {
+ protected boolean startSystemDragOnLongClick(View view) {
if (!(view instanceof BubbleTextView)) {
return false;
}
- TestLogging.recordEvent(TestProtocol.SEQUENCE_MAIN, "onTaskbarItemLongClick");
- BubbleTextView btv = (BubbleTextView) view;
- mActivity.onDragStart();
- btv.post(() -> {
- DragView dragView = startInternalDrag(btv, dragPreviewProvider);
- if (iconShift != null) {
- dragView.animateShift(-iconShift.x, -iconShift.y);
- }
- btv.getIcon().setIsDisabled(true);
- mControllers.taskbarAutohideSuspendController.updateFlag(
- TaskbarAutohideSuspendController.FLAG_AUTOHIDE_SUSPEND_DRAGGING, true);
- });
- return true;
- }
-
- private DragView startInternalDrag(
- BubbleTextView btv, @Nullable DragPreviewProvider dragPreviewProvider) {
- float iconScale = btv.getIcon().getAnimatedScale();
-
- // Clear the pressed state if necessary
- btv.clearFocus();
- btv.setPressed(false);
- btv.clearPressedBackground();
-
- final DragPreviewProvider previewProvider = dragPreviewProvider == null
- ? new DragPreviewProvider(btv) : dragPreviewProvider;
- final Drawable drawable = previewProvider.createDrawable();
- final float scale = previewProvider.getScaleAndPosition(drawable, mTempXY);
- int dragLayerX = mTempXY[0];
- int dragLayerY = mTempXY[1];
-
- Rect dragRect = new Rect();
- btv.getSourceVisualDragBounds(dragRect);
- dragLayerY += dragRect.top;
-
- DragOptions dragOptions = new DragOptions();
- dragOptions.preDragCondition = null;
- if (FeatureFlags.ENABLE_TASKBAR_POPUP_MENU.get()) {
- PopupContainerWithArrow<BaseTaskbarContext> popupContainer =
- mControllers.taskbarPopupController.showForIcon(btv);
- if (popupContainer != null) {
- dragOptions.preDragCondition = popupContainer.createPreDragCondition(false);
- }
- }
- if (dragOptions.preDragCondition == null) {
- dragOptions.preDragCondition = new DragOptions.PreDragCondition() {
- private DragView mDragView;
-
- @Override
- public boolean shouldStartDrag(double distanceDragged) {
- return mDragView != null && mDragView.isAnimationFinished();
- }
-
- @Override
- public void onPreDragStart(DropTarget.DragObject dragObject) {
- mDragView = dragObject.dragView;
-
- if (FeatureFlags.ENABLE_TASKBAR_POPUP_MENU.get()
- && !shouldStartDrag(0)) {
- // Immediately close the popup menu.
- mDragView.setOnAnimationEndCallback(() -> callOnDragStart());
- }
- }
-
- @Override
- public void onPreDragEnd(DropTarget.DragObject dragObject, boolean dragStarted) {
- mDragView = null;
- }
- };
- }
-
- return startDrag(
- drawable,
- /* view = */ null,
- /* originalView = */ btv,
- dragLayerX,
- dragLayerY,
- (View target, DropTarget.DragObject d, boolean success) -> {} /* DragSource */,
- (ItemInfo) btv.getTag(),
- /* dragVisualizeOffset = */ null,
- dragRect,
- scale * iconScale,
- scale,
- dragOptions);
- }
-
- @Override
- protected DragView startDrag(@Nullable Drawable drawable, @Nullable View view,
- DraggableView originalView, int dragLayerX, int dragLayerY, DragSource source,
- ItemInfo dragInfo, Point dragOffset, Rect dragRegion, float initialDragViewScale,
- float dragViewScaleOnDrop, DragOptions options) {
- mOptions = options;
-
- mRegistrationX = mMotionDown.x - dragLayerX;
- mRegistrationY = mMotionDown.y - dragLayerY;
-
- final int dragRegionLeft = dragRegion == null ? 0 : dragRegion.left;
- final int dragRegionTop = dragRegion == null ? 0 : dragRegion.top;
-
- mLastDropTarget = null;
-
- mDragObject = new DropTarget.DragObject(mActivity.getApplicationContext());
- mDragObject.originalView = originalView;
- mDragObject.deferDragViewCleanupPostAnimation = false;
-
- mIsInPreDrag = mOptions.preDragCondition != null
- && !mOptions.preDragCondition.shouldStartDrag(0);
-
- float scalePx = mDragIconSize - dragRegion.width();
- final DragView dragView = mDragObject.dragView = new TaskbarDragView(
- mActivity,
- drawable,
- mRegistrationX,
- mRegistrationY,
- initialDragViewScale,
- dragViewScaleOnDrop,
- scalePx);
- dragView.setItemInfo(dragInfo);
- mDragObject.dragComplete = false;
-
- mDragObject.xOffset = mMotionDown.x - (dragLayerX + dragRegionLeft);
- mDragObject.yOffset = mMotionDown.y - (dragLayerY + dragRegionTop);
-
- mDragDriver = DragDriver.create(this, mOptions, /* secondaryEventConsumer = */ ev -> {});
- if (!mOptions.isAccessibleDrag) {
- mDragObject.stateAnnouncer = DragViewStateAnnouncer.createFor(dragView);
- }
-
- mDragObject.dragSource = source;
- mDragObject.dragInfo = dragInfo;
- mDragObject.originalDragInfo = mDragObject.dragInfo.makeShallowCopy();
-
- if (dragRegion != null) {
- dragView.setDragRegion(new Rect(dragRegion));
- }
-
- dragView.show(mLastTouch.x, mLastTouch.y);
- mDistanceSinceScroll = 0;
-
- if (!mIsInPreDrag) {
- callOnDragStart();
- } else if (mOptions.preDragCondition != null) {
- mOptions.preDragCondition.onPreDragStart(mDragObject);
- }
-
- handleMoveEvent(mLastTouch.x, mLastTouch.y);
-
- return dragView;
- }
-
- @Override
- protected void callOnDragStart() {
- super.callOnDragStart();
- // Pre-drag has ended, start the global system drag.
- AbstractFloatingView.closeAllOpenViews(mActivity);
- startSystemDrag((BubbleTextView) mDragObject.originalView);
- }
-
- private void startSystemDrag(BubbleTextView btv) {
- View.DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(btv) {
+ BubbleTextView btv = (BubbleTextView) view;
+ View.DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(view) {
@Override
public void onProvideShadowMetrics(Point shadowSize, Point shadowTouchPoint) {
- int iconSize = Math.max(mDragIconSize, btv.getWidth());
- shadowSize.set(iconSize, iconSize);
- // The registration point was taken before the icon scaled to mDragIconSize, so
- // offset the registration to where the touch is on the new size.
- int offsetX = (mDragIconSize - mDragObject.dragView.getDragRegionWidth()) / 2;
- int offsetY = (mDragIconSize - mDragObject.dragView.getDragRegionHeight()) / 2;
- shadowTouchPoint.set(mRegistrationX + offsetX, mRegistrationY + offsetY);
+ shadowSize.set(mDragIconSize, mDragIconSize);
+ // TODO: should be based on last touch point on the icon.
+ shadowTouchPoint.set(shadowSize.x / 2, shadowSize.y / 2);
}
@Override
public void onDrawShadow(Canvas canvas) {
canvas.save();
- if (DEBUG_DRAG_SHADOW_SURFACE) {
- canvas.drawColor(0xffff0000);
- }
- float scale = mDragObject.dragView.getScaleX();
+ float scale = (float) mDragIconSize / btv.getIconSize();
canvas.scale(scale, scale);
- mDragObject.dragView.draw(canvas);
+ btv.getIcon().draw(canvas);
canvas.restore();
}
};
- Object tag = btv.getTag();
+ Object tag = view.getTag();
ClipDescription clipDescription = null;
Intent intent = null;
- if (tag instanceof ItemInfo) {
- ItemInfo item = (ItemInfo) tag;
- LauncherApps launcherApps = mActivity.getSystemService(LauncherApps.class);
+ if (tag instanceof WorkspaceItemInfo) {
+ WorkspaceItemInfo item = (WorkspaceItemInfo) tag;
+ LauncherApps launcherApps = mContext.getSystemService(LauncherApps.class);
clipDescription = new ClipDescription(item.title,
new String[] {
item.itemType == LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT
- ? ClipDescription.MIMETYPE_APPLICATION_SHORTCUT
- : ClipDescription.MIMETYPE_APPLICATION_ACTIVITY
+ ? ClipDescriptionCompat.MIMETYPE_APPLICATION_SHORTCUT
+ : ClipDescriptionCompat.MIMETYPE_APPLICATION_ACTIVITY
});
intent = new Intent();
if (item.itemType == LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT) {
- String deepShortcutId = ((WorkspaceItemInfo) item).getDeepShortcutId();
- intent.putExtra(ClipDescription.EXTRA_PENDING_INTENT,
- launcherApps.getShortcutIntent(
- item.getIntent().getPackage(),
- deepShortcutId,
- null,
- item.user));
intent.putExtra(Intent.EXTRA_PACKAGE_NAME, item.getIntent().getPackage());
- intent.putExtra(Intent.EXTRA_SHORTCUT_ID, deepShortcutId);
+ intent.putExtra(Intent.EXTRA_SHORTCUT_ID, item.getDeepShortcutId());
} else {
- intent.putExtra(ClipDescription.EXTRA_PENDING_INTENT,
- launcherApps.getMainActivityLaunchIntent(item.getIntent().getComponent(),
- null, item.user));
+ intent.putExtra(ClipDescriptionCompat.EXTRA_PENDING_INTENT,
+ LauncherAppsCompat.getMainActivityLaunchIntent(launcherApps,
+ item.getIntent().getComponent(), null, item.user));
}
intent.putExtra(Intent.EXTRA_USER, item.user);
} else if (tag instanceof Task) {
Task task = (Task) tag;
clipDescription = new ClipDescription(task.titleDescription,
new String[] {
- ClipDescription.MIMETYPE_APPLICATION_TASK
+ ClipDescriptionCompat.MIMETYPE_APPLICATION_TASK
});
intent = new Intent();
- intent.putExtra(Intent.EXTRA_TASK_ID, task.key.id);
+ intent.putExtra(ClipDescriptionCompat.EXTRA_TASK_ID, task.key.id);
intent.putExtra(Intent.EXTRA_USER, UserHandle.of(task.key.userId));
}
if (clipDescription != null && intent != null) {
- // Need to share the same InstanceId between launcher3 and WM Shell (internal).
- InstanceId internalInstanceId = new InstanceIdSequence(
- com.android.launcher3.logging.InstanceId.INSTANCE_ID_MAX).newInstanceId();
- com.android.launcher3.logging.InstanceId launcherInstanceId =
- new com.android.launcher3.logging.InstanceId(internalInstanceId.getId());
-
- intent.putExtra(ClipDescription.EXTRA_LOGGING_INSTANCE_ID, internalInstanceId);
-
ClipData clipData = new ClipData(clipDescription, new ClipData.Item(intent));
- if (btv.startDragAndDrop(clipData, shadowBuilder, null /* localState */,
- View.DRAG_FLAG_GLOBAL | View.DRAG_FLAG_OPAQUE
- | View.DRAG_FLAG_REQUEST_SURFACE_FOR_RETURN_ANIMATION)) {
- onSystemDragStarted(btv);
-
- mActivity.getStatsLogManager().logger().withItemInfo(mDragObject.dragInfo)
- .withInstanceId(launcherInstanceId)
- .log(StatsLogManager.LauncherEvent.LAUNCHER_ITEM_DRAG_STARTED);
- }
+ view.setOnDragListener(getDraggedViewDragListener());
+ return view.startDragAndDrop(clipData, shadowBuilder, null /* localState */,
+ View.DRAG_FLAG_GLOBAL | View.DRAG_FLAG_OPAQUE);
}
+ return false;
}
- private void onSystemDragStarted(BubbleTextView btv) {
- mIsSystemDragInProgress = true;
- mActivity.getDragLayer().setOnDragListener((view, dragEvent) -> {
+ /**
+ * Hide the original Taskbar item while it is being dragged.
+ */
+ private View.OnDragListener getDraggedViewDragListener() {
+ return (view, dragEvent) -> {
switch (dragEvent.getAction()) {
case DragEvent.ACTION_DRAG_STARTED:
- // Return true to tell system we are interested in events, so we get DRAG_ENDED.
+ view.setVisibility(INVISIBLE);
return true;
case DragEvent.ACTION_DRAG_ENDED:
- mIsSystemDragInProgress = false;
- if (dragEvent.getResult()) {
- maybeOnDragEnd();
- } else {
- // This will take care of calling maybeOnDragEnd() after the animation
- animateGlobalDragViewToOriginalPosition(btv, dragEvent);
- }
+ view.setVisibility(VISIBLE);
+ view.setOnDragListener(null);
return true;
}
return false;
- });
- }
-
- @Override
- public boolean isDragging() {
- return super.isDragging() || mIsSystemDragInProgress;
- }
-
- /** {@code true} if the system is currently handling the drag. */
- public boolean isSystemDragInProgress() {
- return mIsSystemDragInProgress;
- }
-
- private void maybeOnDragEnd() {
- if (!isDragging()) {
- ((BubbleTextView) mDragObject.originalView).getIcon().setIsDisabled(false);
- mControllers.taskbarAutohideSuspendController.updateFlag(
- TaskbarAutohideSuspendController.FLAG_AUTOHIDE_SUSPEND_DRAGGING, false);
- mActivity.onDragEnd();
- }
- }
-
- @Override
- protected void callOnDragEnd() {
- super.callOnDragEnd();
- maybeOnDragEnd();
- }
-
- private void animateGlobalDragViewToOriginalPosition(BubbleTextView btv,
- DragEvent dragEvent) {
- SurfaceControl dragSurface = dragEvent.getDragSurface();
-
- // For top level icons, the target is the icon itself
- View target = btv;
- Object tag = btv.getTag();
- if (tag instanceof ItemInfo) {
- ItemInfo item = (ItemInfo) tag;
- TaskbarViewController taskbarViewController = mControllers.taskbarViewController;
- if (item.container == CONTAINER_ALL_APPS) {
- // Since all apps closes when the drag starts, target the all apps button instead.
- target = taskbarViewController.getAllAppsButtonView();
- } else if (item.container >= 0) {
- // Since folders close when the drag starts, target the folder icon instead.
- Predicate<ItemInfo> matcher = ItemInfoMatcher.forFolderMatch(
- ItemInfoMatcher.ofItemIds(IntSet.wrap(item.id)));
- target = taskbarViewController.getFirstIconMatch(matcher);
- } else if (item.itemType == ITEM_TYPE_DEEP_SHORTCUT) {
- // Find first icon with same package/user as the deep shortcut.
- Predicate<ItemInfo> packageUserMatcher = ItemInfoMatcher.ofPackages(
- Collections.singleton(item.getTargetPackage()), item.user);
- target = taskbarViewController.getFirstIconMatch(packageUserMatcher);
- }
- }
-
- // Finish any pending return animation before starting a new drag
- if (mReturnAnimator != null) {
- mReturnAnimator.end();
- }
-
- float fromX = dragEvent.getX() - dragEvent.getOffsetX();
- float fromY = dragEvent.getY() - dragEvent.getOffsetY();
- int[] toPosition = target.getLocationOnScreen();
- float toScale = (float) target.getWidth() / mDragIconSize;
- float toAlpha = (target == btv) ? 1f : 0f;
- final ViewRootImpl viewRoot = target.getViewRootImpl();
- SurfaceControl.Transaction tx = new SurfaceControl.Transaction();
- mReturnAnimator = ValueAnimator.ofFloat(0f, 1f);
- mReturnAnimator.setDuration(300);
- mReturnAnimator.setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
- mReturnAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
- @Override
- public void onAnimationUpdate(ValueAnimator animation) {
- float t = animation.getAnimatedFraction();
- float accelT = Interpolators.ACCEL_2.getInterpolation(t);
- float scale = 1f - t * (1f - toScale);
- float alpha = 1f - accelT * (1f - toAlpha);
- tx.setPosition(dragSurface, Utilities.mapRange(t, fromX, toPosition[0]),
- Utilities.mapRange(t, fromY, toPosition[1]));
- tx.setScale(dragSurface, scale, scale);
- tx.setAlpha(dragSurface, alpha);
- tx.apply();
- }
- });
- mReturnAnimator.addListener(new AnimatorListenerAdapter() {
- private boolean mCanceled = false;
-
- @Override
- public void onAnimationCancel(Animator animation) {
- cleanUpSurface();
- mCanceled = true;
- }
-
- @Override
- public void onAnimationEnd(Animator animation) {
- if (mCanceled) {
- return;
- }
- cleanUpSurface();
- }
-
- private void cleanUpSurface() {
- tx.close();
- maybeOnDragEnd();
- // Synchronize removing the drag surface with the next draw after calling
- // maybeOnDragEnd()
- SurfaceControl.Transaction transaction = new SurfaceControl.Transaction();
- transaction.remove(dragSurface);
- SurfaceSyncer syncer = new SurfaceSyncer();
- int syncId = syncer.setupSync(transaction::close);
- syncer.addToSync(syncId, viewRoot.getView());
- syncer.addTransactionToSync(syncId, transaction);
- syncer.markSyncReady(syncId);
- mReturnAnimator = null;
- }
- });
- mReturnAnimator.start();
- }
-
- @Override
- protected float getX(MotionEvent ev) {
- // We will resize to fill the screen while dragging, so use screen coordinates. This ensures
- // we start at the correct position even though touch down is on the smaller DragLayer size.
- return ev.getRawX();
- }
-
- @Override
- protected float getY(MotionEvent ev) {
- // We will resize to fill the screen while dragging, so use screen coordinates. This ensures
- // we start at the correct position even though touch down is on the smaller DragLayer size.
- return ev.getRawY();
- }
-
- @Override
- protected Point getClampedDragLayerPos(float x, float y) {
- // No need to clamp, as we will take up the entire screen.
- mTmpPoint.set(Math.round(x), Math.round(y));
- return mTmpPoint;
- }
-
- @Override
- protected void exitDrag() {
- if (mDragObject != null) {
- mActivity.getDragLayer().removeView(mDragObject.dragView);
- }
- }
-
- @Override
- public void addDropTarget(DropTarget target) {
- // No-op as Taskbar currently doesn't support any drop targets internally.
- // Note: if we do add internal DropTargets, we'll still need to ignore Folder.
- }
-
- @Override
- protected DropTarget getDefaultDropTarget(int[] dropCoordinates) {
- return null;
- }
-
- @Override
- public void dumpLogs(String prefix, PrintWriter pw) {
- pw.println(prefix + "TaskbarDragController:");
-
- pw.println(String.format("%s\tmDragIconSize=%dpx", prefix, mDragIconSize));
- pw.println(String.format("%s\tmTempXY=%s", prefix, Arrays.toString(mTempXY)));
- pw.println(String.format("%s\tmRegistrationX=%d", prefix, mRegistrationX));
- pw.println(String.format("%s\tmRegistrationY=%d", prefix, mRegistrationY));
- pw.println(String.format(
- "%s\tmIsSystemDragInProgress=%b", prefix, mIsSystemDragInProgress));
- pw.println(String.format(
- "%s\tisInternalDragInProgess=%b", prefix, super.isDragging()));
+ };
}
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayer.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayer.java
index c1a6185d23..45ec911527 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayer.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayer.java
@@ -15,22 +15,18 @@
*/
package com.android.launcher3.taskbar;
-import static android.view.KeyEvent.ACTION_UP;
-import static android.view.KeyEvent.KEYCODE_BACK;
-
import android.content.Context;
import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.Rect;
import android.util.AttributeSet;
-import android.view.KeyEvent;
-import android.view.MotionEvent;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
-import com.android.launcher3.AbstractFloatingView;
-import com.android.launcher3.testing.TestLogging;
-import com.android.launcher3.testing.TestProtocol;
+import com.android.launcher3.R;
+import com.android.launcher3.util.TouchController;
import com.android.launcher3.views.BaseDragLayer;
import com.android.systemui.shared.system.ViewTreeObserverWrapper;
import com.android.systemui.shared.system.ViewTreeObserverWrapper.InsetsInfo;
@@ -41,13 +37,13 @@ import com.android.systemui.shared.system.ViewTreeObserverWrapper.OnComputeInset
*/
public class TaskbarDragLayer extends BaseDragLayer<TaskbarActivityContext> {
- private final TaskbarBackgroundRenderer mBackgroundRenderer;
- private final OnComputeInsetsListener mTaskbarInsetsComputer = this::onComputeTaskbarInsets;
+ private final int mFolderMargin;
+ private final Paint mTaskbarBackgroundPaint;
- // Initialized in init.
- private TaskbarDragLayerController.TaskbarDragLayerCallbacks mControllerCallbacks;
+ private TaskbarIconController.Callbacks mControllerCallbacks;
+ private TaskbarView mTaskbarView;
- private float mTaskbarBackgroundOffset;
+ private final OnComputeInsetsListener mTaskbarInsetsComputer = this::onComputeTaskbarInsets;
public TaskbarDragLayer(@NonNull Context context) {
this(context, null);
@@ -65,19 +61,20 @@ public class TaskbarDragLayer extends BaseDragLayer<TaskbarActivityContext> {
public TaskbarDragLayer(@NonNull Context context, @Nullable AttributeSet attrs,
int defStyleAttr, int defStyleRes) {
super(context, attrs, 1 /* alphaChannelCount */);
- mBackgroundRenderer = new TaskbarBackgroundRenderer(mActivity);
- mBackgroundRenderer.getPaint().setAlpha(0);
- }
-
- public void init(TaskbarDragLayerController.TaskbarDragLayerCallbacks callbacks) {
- mControllerCallbacks = callbacks;
-
+ mFolderMargin = getResources().getDimensionPixelSize(R.dimen.taskbar_folder_margin);
+ mTaskbarBackgroundPaint = new Paint();
+ mTaskbarBackgroundPaint.setColor(getResources().getColor(R.color.taskbar_background));
recreateControllers();
}
@Override
public void recreateControllers() {
- mControllers = mControllerCallbacks.getTouchControllers();
+ mControllers = new TouchController[0];
+ }
+
+ public void init(TaskbarIconController.Callbacks callbacks, TaskbarView taskbarView) {
+ mControllerCallbacks = callbacks;
+ mTaskbarView = taskbarView;
}
private void onComputeTaskbarInsets(InsetsInfo insetsInfo) {
@@ -111,6 +108,12 @@ public class TaskbarDragLayer extends BaseDragLayer<TaskbarActivityContext> {
return true;
}
+ public void updateImeBarVisibilityAlpha(float alpha) {
+ if (mControllerCallbacks != null) {
+ mControllerCallbacks.updateImeBarVisibilityAlpha(alpha);
+ }
+ }
+
@Override
public void onViewRemoved(View child) {
super.onViewRemoved(child);
@@ -121,47 +124,27 @@ public class TaskbarDragLayer extends BaseDragLayer<TaskbarActivityContext> {
@Override
protected void dispatchDraw(Canvas canvas) {
- float backgroundHeight = mControllerCallbacks.getTaskbarBackgroundHeight()
- * (1f - mTaskbarBackgroundOffset);
- mBackgroundRenderer.setBackgroundHeight(backgroundHeight);
- mBackgroundRenderer.draw(canvas);
+ canvas.drawRect(0, canvas.getHeight() - mTaskbarView.getHeight(), canvas.getWidth(),
+ canvas.getHeight(), mTaskbarBackgroundPaint);
super.dispatchDraw(canvas);
}
/**
- * Sets the alpha of the background color behind all the Taskbar contents.
- * @param alpha 0 is fully transparent, 1 is fully opaque.
+ * @return Bounds (in our coordinates) where an opened Folder can display.
*/
- protected void setTaskbarBackgroundAlpha(float alpha) {
- mBackgroundRenderer.getPaint().setAlpha((int) (alpha * 255));
- invalidate();
+ protected Rect getFolderBoundingBox() {
+ Rect boundingBox = new Rect(0, 0, getWidth(), getHeight() - mTaskbarView.getHeight());
+ boundingBox.inset(mFolderMargin, mFolderMargin);
+ return boundingBox;
}
+
/**
- * Sets the translation of the background color behind all the Taskbar contents.
- * @param offset 0 is fully onscreen, 1 is fully offscreen.
+ * Sets the alpha of the background color behind all the Taskbar contents.
+ * @param alpha 0 is fully transparent, 1 is fully opaque.
*/
- protected void setTaskbarBackgroundOffset(float offset) {
- mTaskbarBackgroundOffset = offset;
+ protected void setTaskbarBackgroundAlpha(float alpha) {
+ mTaskbarBackgroundPaint.setAlpha((int) (alpha * 255));
invalidate();
}
-
- @Override
- public boolean dispatchTouchEvent(MotionEvent ev) {
- TestLogging.recordMotionEvent(TestProtocol.SEQUENCE_MAIN, "Touch event", ev);
- return super.dispatchTouchEvent(ev);
- }
-
- /** Called while Taskbar window is focusable, e.g. when pressing back while a folder is open */
- @Override
- public boolean dispatchKeyEvent(KeyEvent event) {
- if (event.getAction() == ACTION_UP && event.getKeyCode() == KEYCODE_BACK) {
- AbstractFloatingView topView = AbstractFloatingView.getTopOpenView(mActivity);
- if (topView != null && topView.onBackPressed()) {
- // Handled by the floating view.
- return true;
- }
- }
- return super.dispatchKeyEvent(event);
- }
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayerController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayerController.java
deleted file mode 100644
index 99c59a8a98..0000000000
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayerController.java
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * Copyright (C) 2021 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.launcher3.taskbar;
-
-import android.content.res.Resources;
-import android.graphics.Rect;
-
-import com.android.launcher3.R;
-import com.android.launcher3.util.TouchController;
-import com.android.quickstep.AnimatedFloat;
-import com.android.systemui.shared.system.ViewTreeObserverWrapper.InsetsInfo;
-
-import java.io.PrintWriter;
-
-/**
- * Handles properties/data collection, then passes the results to TaskbarDragLayer to render.
- */
-public class TaskbarDragLayerController implements TaskbarControllers.LoggableTaskbarController {
-
- private final TaskbarActivityContext mActivity;
- private final TaskbarDragLayer mTaskbarDragLayer;
- private final int mFolderMargin;
-
- // Alpha properties for taskbar background.
- private final AnimatedFloat mBgTaskbar = new AnimatedFloat(this::updateBackgroundAlpha);
- private final AnimatedFloat mBgNavbar = new AnimatedFloat(this::updateBackgroundAlpha);
- private final AnimatedFloat mKeyguardBgTaskbar = new AnimatedFloat(this::updateBackgroundAlpha);
- private final AnimatedFloat mNotificationShadeBgTaskbar = new AnimatedFloat(
- this::updateBackgroundAlpha);
- private final AnimatedFloat mImeBgTaskbar = new AnimatedFloat(this::updateBackgroundAlpha);
- // Used to hide our background color when someone else (e.g. ScrimView) is handling it.
- private final AnimatedFloat mBgOverride = new AnimatedFloat(this::updateBackgroundAlpha);
-
- // Translation property for taskbar background.
- private final AnimatedFloat mBgOffset = new AnimatedFloat(this::updateBackgroundOffset);
-
- // Initialized in init.
- private TaskbarControllers mControllers;
- private AnimatedFloat mNavButtonDarkIntensityMultiplier;
-
- private float mLastSetBackgroundAlpha;
-
- public TaskbarDragLayerController(TaskbarActivityContext activity,
- TaskbarDragLayer taskbarDragLayer) {
- mActivity = activity;
- mTaskbarDragLayer = taskbarDragLayer;
- final Resources resources = mTaskbarDragLayer.getResources();
- mFolderMargin = resources.getDimensionPixelSize(R.dimen.taskbar_folder_margin);
- }
-
- public void init(TaskbarControllers controllers) {
- mControllers = controllers;
- mTaskbarDragLayer.init(new TaskbarDragLayerCallbacks());
-
- mNavButtonDarkIntensityMultiplier = mControllers.navbarButtonsViewController
- .getNavButtonDarkIntensityMultiplier();
-
- mBgTaskbar.value = 1;
- mKeyguardBgTaskbar.value = 1;
- mNotificationShadeBgTaskbar.value = 1;
- mImeBgTaskbar.value = 1;
- mBgOverride.value = 1;
- updateBackgroundAlpha();
- }
-
- public void onDestroy() {
- mTaskbarDragLayer.onDestroy();
- }
-
- /**
- * @return Bounds (in TaskbarDragLayer coordinates) where an opened Folder can display.
- */
- public Rect getFolderBoundingBox() {
- Rect boundingBox = new Rect(0, 0, mTaskbarDragLayer.getWidth(),
- mTaskbarDragLayer.getHeight() - mActivity.getDeviceProfile().taskbarSize);
- boundingBox.inset(mFolderMargin, mFolderMargin);
- return boundingBox;
- }
-
- public AnimatedFloat getTaskbarBackgroundAlpha() {
- return mBgTaskbar;
- }
-
- public AnimatedFloat getNavbarBackgroundAlpha() {
- return mBgNavbar;
- }
-
- public AnimatedFloat getKeyguardBgTaskbar() {
- return mKeyguardBgTaskbar;
- }
-
- public AnimatedFloat getNotificationShadeBgTaskbar() {
- return mNotificationShadeBgTaskbar;
- }
-
- public AnimatedFloat getImeBgTaskbar() {
- return mImeBgTaskbar;
- }
-
- public AnimatedFloat getOverrideBackgroundAlpha() {
- return mBgOverride;
- }
-
- public AnimatedFloat getTaskbarBackgroundOffset() {
- return mBgOffset;
- }
-
- private void updateBackgroundAlpha() {
- final float bgNavbar = mBgNavbar.value;
- final float bgTaskbar = mBgTaskbar.value * mKeyguardBgTaskbar.value
- * mNotificationShadeBgTaskbar.value * mImeBgTaskbar.value;
- mLastSetBackgroundAlpha = mBgOverride.value * Math.max(bgNavbar, bgTaskbar);
- mTaskbarDragLayer.setTaskbarBackgroundAlpha(mLastSetBackgroundAlpha);
-
- updateNavBarDarkIntensityMultiplier();
- }
-
- private void updateBackgroundOffset() {
- mTaskbarDragLayer.setTaskbarBackgroundOffset(mBgOffset.value);
-
- updateNavBarDarkIntensityMultiplier();
- }
-
- private void updateNavBarDarkIntensityMultiplier() {
- // Zero out the app-requested dark intensity when we're drawing our own background.
- float effectiveBgAlpha = mLastSetBackgroundAlpha * (1 - mBgOffset.value);
- mNavButtonDarkIntensityMultiplier.updateValue(1 - effectiveBgAlpha);
- }
-
- @Override
- public void dumpLogs(String prefix, PrintWriter pw) {
- pw.println(prefix + "TaskbarDragLayerController:");
-
- pw.println(String.format("%s\tmBgOffset=%.2f", prefix, mBgOffset.value));
- pw.println(String.format("%s\tmFolderMargin=%dpx", prefix, mFolderMargin));
- pw.println(String.format(
- "%s\tmLastSetBackgroundAlpha=%.2f", prefix, mLastSetBackgroundAlpha));
- }
-
- /**
- * Callbacks for {@link TaskbarDragLayer} to interact with its controller.
- */
- public class TaskbarDragLayerCallbacks {
-
- /**
- * Called to update the touchable insets.
- * @see InsetsInfo#setTouchableInsets(int)
- */
- public void updateInsetsTouchability(InsetsInfo insetsInfo) {
- mControllers.taskbarInsetsController.updateInsetsTouchability(insetsInfo);
- }
-
- /**
- * Called when a child is removed from TaskbarDragLayer.
- */
- public void onDragLayerViewRemoved() {
- mActivity.maybeSetTaskbarWindowNotFullscreen();
- }
-
- /**
- * Returns how tall the background should be drawn at the bottom of the screen.
- */
- public int getTaskbarBackgroundHeight() {
- return mActivity.getDeviceProfile().taskbarSize;
- }
-
- /**
- * Returns touch controllers.
- */
- public TouchController[] getTouchControllers() {
- return new TouchController[]{mActivity.getDragController(),
- mControllers.taskbarForceVisibleImmersiveController,
- mControllers.navbarButtonsViewController.getTouchController()};
- }
- }
-}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragView.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragView.java
deleted file mode 100644
index 7a4243261c..0000000000
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragView.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2021 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.launcher3.taskbar;
-
-import android.graphics.drawable.Drawable;
-
-import com.android.launcher3.R;
-import com.android.launcher3.dragndrop.DragView;
-
-/**
- * A DragView drawn/used by the Taskbar. Note that this is only for the internal drag-and-drop,
- * while the pre-drag is still in progress (i.e. when the long press popup is still open). After
- * that ends, we switch to a system drag and drop view instead.
- */
-public class TaskbarDragView extends DragView<BaseTaskbarContext> {
- public TaskbarDragView(BaseTaskbarContext launcher, Drawable drawable, int registrationX,
- int registrationY, float initialScale, float scaleOnDrop, float finalScaleDps) {
- super(launcher, drawable, registrationX, registrationY, initialScale, scaleOnDrop,
- finalScaleDps);
- }
-
- @Override
- public void animateTo(int toTouchX, int toTouchY, Runnable onCompleteRunnable, int duration) {
- Runnable onAnimationEnd = () -> {
- if (onCompleteRunnable != null) {
- onCompleteRunnable.run();
- }
- mActivity.getDragLayer().removeView(this);
- };
-
- duration = Math.max(duration,
- getResources().getInteger(R.integer.config_dropAnimMinDuration));
-
- animate()
- .translationX(toTouchX - mRegistrationX)
- .translationY(toTouchY - mRegistrationY)
- .scaleX(mScaleOnDrop)
- .scaleY(mScaleOnDrop)
- .withEndAction(onAnimationEnd)
- .setDuration(duration)
- .start();
- }
-}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarEduController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarEduController.java
deleted file mode 100644
index e29b14b76f..0000000000
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarEduController.java
+++ /dev/null
@@ -1,223 +0,0 @@
-/*
- * Copyright (C) 2021 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.launcher3.taskbar;
-
-import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY;
-import static com.android.launcher3.anim.Interpolators.ACCEL_2;
-import static com.android.launcher3.anim.Interpolators.ACCEL_DEACCEL;
-import static com.android.launcher3.anim.Interpolators.DEACCEL;
-import static com.android.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN;
-
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.AnimatorSet;
-import android.animation.Keyframe;
-import android.animation.ObjectAnimator;
-import android.animation.PropertyValuesHolder;
-import android.animation.TimeInterpolator;
-import android.content.res.Resources;
-import android.text.TextUtils;
-import android.view.View;
-
-import com.android.launcher3.R;
-import com.android.launcher3.icons.BitmapInfo;
-import com.android.launcher3.model.data.ItemInfo;
-import com.android.launcher3.uioverrides.PredictedAppIcon;
-
-import java.io.PrintWriter;
-import java.util.Collections;
-import java.util.List;
-import java.util.stream.Collectors;
-
-/** Handles the Taskbar Education flow. */
-public class TaskbarEduController implements TaskbarControllers.LoggableTaskbarController {
-
- private static final long WAVE_ANIM_DELAY = 250;
- private static final long WAVE_ANIM_STAGGER = 50;
- private static final long WAVE_ANIM_EACH_ICON_DURATION = 633;
- private static final long WAVE_ANIM_SLOT_MACHINE_DURATION = 1085;
- // The fraction of each icon's animation at which we reach the top point of the wave.
- private static final float WAVE_ANIM_FRACTION_TOP = 0.4f;
- // The fraction of each icon's animation at which we reach the bottom, before overshooting.
- private static final float WAVE_ANIM_FRACTION_BOTTOM = 0.9f;
- private static final TimeInterpolator WAVE_ANIM_TO_TOP_INTERPOLATOR = FAST_OUT_SLOW_IN;
- private static final TimeInterpolator WAVE_ANIM_TO_BOTTOM_INTERPOLATOR = ACCEL_2;
- private static final TimeInterpolator WAVE_ANIM_OVERSHOOT_INTERPOLATOR = DEACCEL;
- private static final TimeInterpolator WAVE_ANIM_OVERSHOOT_RETURN_INTERPOLATOR = ACCEL_DEACCEL;
- private static final float WAVE_ANIM_ICON_SCALE = 1.2f;
- // How many icons to cycle through in the slot machine (+ the original icon at each end).
- private static final int WAVE_ANIM_SLOT_MACHINE_NUM_ICONS = 3;
-
- private final TaskbarActivityContext mActivity;
- private final float mWaveAnimTranslationY;
- private final float mWaveAnimTranslationYReturnOvershoot;
-
- // Initialized in init.
- TaskbarControllers mControllers;
-
- private TaskbarEduView mTaskbarEduView;
- private Animator mAnim;
-
- public TaskbarEduController(TaskbarActivityContext activity) {
- mActivity = activity;
-
- final Resources resources = activity.getResources();
- mWaveAnimTranslationY = resources.getDimension(R.dimen.taskbar_edu_wave_anim_trans_y);
- mWaveAnimTranslationYReturnOvershoot = resources.getDimension(
- R.dimen.taskbar_edu_wave_anim_trans_y_return_overshoot);
- }
-
- public void init(TaskbarControllers controllers) {
- mControllers = controllers;
- }
-
- void showEdu() {
- mActivity.setTaskbarWindowFullscreen(true);
- mActivity.getDragLayer().post(() -> {
- mTaskbarEduView = (TaskbarEduView) mActivity.getLayoutInflater().inflate(
- R.layout.taskbar_edu, mActivity.getDragLayer(), false);
- mTaskbarEduView.init(new TaskbarEduCallbacks());
- mTaskbarEduView.addOnCloseListener(() -> mTaskbarEduView = null);
- mTaskbarEduView.show();
- startAnim(createWaveAnim());
- });
- }
-
- void hideEdu() {
- if (mTaskbarEduView != null) {
- mTaskbarEduView.close(true /* animate */);
- }
- }
-
- /**
- * Starts the given animation, ending the previous animation first if it's still playing.
- */
- private void startAnim(Animator anim) {
- if (mAnim != null) {
- mAnim.end();
- }
- mAnim = anim;
- mAnim.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- mAnim = null;
- }
- });
- mAnim.start();
- }
-
- /**
- * Creates a staggered "wave" animation where each icon translates and scales up in succession.
- */
- private Animator createWaveAnim() {
- AnimatorSet waveAnim = new AnimatorSet();
- View[] icons = mControllers.taskbarViewController.getIconViews();
- for (int i = 0; i < icons.length; i++) {
- View icon = icons[i];
- AnimatorSet iconAnim = new AnimatorSet();
-
- Keyframe[] scaleKeyframes = new Keyframe[] {
- Keyframe.ofFloat(0, 1f),
- Keyframe.ofFloat(WAVE_ANIM_FRACTION_TOP, WAVE_ANIM_ICON_SCALE),
- Keyframe.ofFloat(WAVE_ANIM_FRACTION_BOTTOM, 1f),
- Keyframe.ofFloat(1f, 1f)
- };
- scaleKeyframes[1].setInterpolator(WAVE_ANIM_TO_TOP_INTERPOLATOR);
- scaleKeyframes[2].setInterpolator(WAVE_ANIM_TO_BOTTOM_INTERPOLATOR);
-
- Keyframe[] translationYKeyframes = new Keyframe[] {
- Keyframe.ofFloat(0, 0f),
- Keyframe.ofFloat(WAVE_ANIM_FRACTION_TOP, -mWaveAnimTranslationY),
- Keyframe.ofFloat(WAVE_ANIM_FRACTION_BOTTOM, 0f),
- // Half of the remaining fraction overshoots, then the other half returns to 0.
- Keyframe.ofFloat(
- WAVE_ANIM_FRACTION_BOTTOM + (1 - WAVE_ANIM_FRACTION_BOTTOM) / 2f,
- mWaveAnimTranslationYReturnOvershoot),
- Keyframe.ofFloat(1f, 0f)
- };
- translationYKeyframes[1].setInterpolator(WAVE_ANIM_TO_TOP_INTERPOLATOR);
- translationYKeyframes[2].setInterpolator(WAVE_ANIM_TO_BOTTOM_INTERPOLATOR);
- translationYKeyframes[3].setInterpolator(WAVE_ANIM_OVERSHOOT_INTERPOLATOR);
- translationYKeyframes[4].setInterpolator(WAVE_ANIM_OVERSHOOT_RETURN_INTERPOLATOR);
-
- iconAnim.play(ObjectAnimator.ofPropertyValuesHolder(icon,
- PropertyValuesHolder.ofKeyframe(SCALE_PROPERTY, scaleKeyframes))
- .setDuration(WAVE_ANIM_EACH_ICON_DURATION));
- iconAnim.play(ObjectAnimator.ofPropertyValuesHolder(icon,
- PropertyValuesHolder.ofKeyframe(View.TRANSLATION_Y, translationYKeyframes))
- .setDuration(WAVE_ANIM_EACH_ICON_DURATION));
-
- if (icon instanceof PredictedAppIcon) {
- // Play slot machine animation through random icons from AllAppsList.
- PredictedAppIcon predictedAppIcon = (PredictedAppIcon) icon;
- ItemInfo itemInfo = (ItemInfo) icon.getTag();
- List<BitmapInfo> iconsToAnimate = mControllers.uiController.getAppIconsForEdu()
- .filter(appInfo -> !TextUtils.equals(appInfo.title, itemInfo.title))
- .map(appInfo -> appInfo.bitmap)
- .filter(bitmap -> !bitmap.isNullOrLowRes())
- .collect(Collectors.toList());
- // Pick n icons at random.
- Collections.shuffle(iconsToAnimate);
- if (iconsToAnimate.size() > WAVE_ANIM_SLOT_MACHINE_NUM_ICONS) {
- iconsToAnimate = iconsToAnimate.subList(0, WAVE_ANIM_SLOT_MACHINE_NUM_ICONS);
- }
- Animator slotMachineAnim = predictedAppIcon.createSlotMachineAnim(iconsToAnimate);
- if (slotMachineAnim != null) {
- iconAnim.play(slotMachineAnim.setDuration(WAVE_ANIM_SLOT_MACHINE_DURATION));
- }
- }
-
- iconAnim.setStartDelay(WAVE_ANIM_STAGGER * i);
- waveAnim.play(iconAnim);
- }
- waveAnim.setStartDelay(WAVE_ANIM_DELAY);
- return waveAnim;
- }
-
- @Override
- public void dumpLogs(String prefix, PrintWriter pw) {
- pw.println(prefix + "TaskbarEduController:");
-
- pw.println(String.format("%s\tisShowingEdu=%b", prefix, mTaskbarEduView != null));
- pw.println(String.format("%s\tmWaveAnimTranslationY=%.2f", prefix, mWaveAnimTranslationY));
- pw.println(String.format(
- "%s\tmWaveAnimTranslationYReturnOvershoot=%.2f",
- prefix,
- mWaveAnimTranslationYReturnOvershoot));
- }
-
- /**
- * Callbacks for {@link TaskbarEduView} to interact with its controller.
- */
- class TaskbarEduCallbacks {
- void onPageChanged(int currentPage, int pageCount) {
- if (currentPage == 0) {
- mTaskbarEduView.updateStartButton(R.string.taskbar_edu_close,
- v -> mTaskbarEduView.close(true /* animate */));
- } else {
- mTaskbarEduView.updateStartButton(R.string.taskbar_edu_previous,
- v -> mTaskbarEduView.snapToPage(currentPage - 1));
- }
- if (currentPage == pageCount - 1) {
- mTaskbarEduView.updateEndButton(R.string.taskbar_edu_done,
- v -> mTaskbarEduView.close(true /* animate */));
- } else {
- mTaskbarEduView.updateEndButton(R.string.taskbar_edu_next,
- v -> mTaskbarEduView.snapToPage(currentPage + 1));
- }
- }
- }
-}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarEduPagedView.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarEduPagedView.java
deleted file mode 100644
index 8e57ea62fc..0000000000
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarEduPagedView.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (C) 2021 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.launcher3.taskbar;
-
-import static com.android.launcher3.AbstractFloatingView.TYPE_ALL;
-import static com.android.launcher3.AbstractFloatingView.TYPE_TASKBAR_EDUCATION_DIALOG;
-
-import android.content.Context;
-import android.util.AttributeSet;
-
-import com.android.launcher3.AbstractFloatingView;
-import com.android.launcher3.PagedView;
-import com.android.launcher3.R;
-import com.android.launcher3.pageindicators.PageIndicatorDots;
-import com.android.launcher3.taskbar.TaskbarEduController.TaskbarEduCallbacks;
-import com.android.launcher3.views.ActivityContext;
-
-/** Horizontal carousel of tutorial screens for Taskbar Edu. */
-public class TaskbarEduPagedView extends PagedView<PageIndicatorDots> {
-
- private TaskbarEduView mTaskbarEduView;
- private TaskbarEduCallbacks mControllerCallbacks;
-
- public TaskbarEduPagedView(Context context, AttributeSet attrs) {
- super(context, attrs);
- setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_YES);
- }
-
- void setTaskbarEduView(TaskbarEduView taskbarEduView) {
- mTaskbarEduView = taskbarEduView;
- mPageIndicator = taskbarEduView.findViewById(R.id.content_page_indicator);
- initParentViews(taskbarEduView);
- }
-
- void setControllerCallbacks(TaskbarEduCallbacks controllerCallbacks) {
- mControllerCallbacks = controllerCallbacks;
- mControllerCallbacks.onPageChanged(getCurrentPage(), getPageCount());
- }
-
- @Override
- protected int getChildGap(int fromIndex, int toIndex) {
- return mTaskbarEduView.getPaddingLeft() + mTaskbarEduView.getPaddingRight();
- }
-
- @Override
- protected void onScrollChanged(int l, int t, int oldl, int oldt) {
- super.onScrollChanged(l, t, oldl, oldt);
- if (mMaxScroll > 0) {
- mPageIndicator.setScroll(l, mMaxScroll);
- }
- }
-
- @Override
- protected void notifyPageSwitchListener(int prevPage) {
- super.notifyPageSwitchListener(prevPage);
- mControllerCallbacks.onPageChanged(getCurrentPage(), getPageCount());
- }
-
- @Override
- protected boolean canScroll(float absVScroll, float absHScroll) {
- return AbstractFloatingView.getTopOpenViewWithType(
- ActivityContext.lookupContext(getContext()),
- TYPE_ALL & ~TYPE_TASKBAR_EDUCATION_DIALOG) == null;
- }
-}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarEduView.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarEduView.java
deleted file mode 100644
index 89d67be685..0000000000
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarEduView.java
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * Copyright (C) 2021 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.launcher3.taskbar;
-
-import static com.android.launcher3.anim.Interpolators.AGGRESSIVE_EASE;
-
-import android.animation.PropertyValuesHolder;
-import android.content.Context;
-import android.graphics.Rect;
-import android.provider.Settings;
-import android.util.AttributeSet;
-import android.util.Pair;
-import android.view.View;
-import android.widget.Button;
-
-import com.android.launcher3.Insettable;
-import com.android.launcher3.R;
-import com.android.launcher3.views.AbstractSlideInView;
-
-/** Education view about the Taskbar. */
-public class TaskbarEduView extends AbstractSlideInView<TaskbarActivityContext>
- implements Insettable {
-
- private static final int DEFAULT_OPEN_DURATION = 500;
- private static final int DEFAULT_CLOSE_DURATION = 200;
-
- private final Rect mInsets = new Rect();
-
- private Button mStartButton;
- private Button mEndButton;
- private TaskbarEduPagedView mPagedView;
-
- public TaskbarEduView(Context context, AttributeSet attr) {
- this(context, attr, 0);
- }
-
- public TaskbarEduView(Context context, AttributeSet attrs,
- int defStyleAttr) {
- super(context, attrs, defStyleAttr);
- }
-
- protected void init(TaskbarEduController.TaskbarEduCallbacks callbacks) {
- if (mPagedView != null) {
- mPagedView.setControllerCallbacks(callbacks);
- }
- }
-
- @Override
- protected void handleClose(boolean animate) {
- handleClose(animate, DEFAULT_CLOSE_DURATION);
- }
-
- @Override
- protected boolean isOfType(int type) {
- return (type & TYPE_TASKBAR_EDUCATION_DIALOG) != 0;
- }
-
- @Override
- protected void onFinishInflate() {
- super.onFinishInflate();
- mContent = findViewById(R.id.edu_view);
- mStartButton = findViewById(R.id.edu_start_button);
- mEndButton = findViewById(R.id.edu_end_button);
- mPagedView = findViewById(R.id.content);
- mPagedView.setTaskbarEduView(this);
- }
-
- @Override
- public void setInsets(Rect insets) {
- mInsets.set(insets);
- mContent.setPadding(mContent.getPaddingStart(),
- mContent.getPaddingTop(), mContent.getPaddingEnd(), insets.bottom);
- }
-
- @Override
- protected void attachToContainer() {
- if (mColorScrim != null) {
- getPopupContainer().addView(mColorScrim, 0);
- }
- getPopupContainer().addView(this, 1);
- }
-
- @Override
- protected void onDetachedFromWindow() {
- super.onDetachedFromWindow();
-
- Settings.Secure.putInt(mContext.getContentResolver(),
- Settings.Secure.LAUNCHER_TASKBAR_EDUCATION_SHOWING, 0);
- }
-
- /** Show the Education flow. */
- public void show() {
- attachToContainer();
- animateOpen();
- }
-
- @Override
- protected Pair<View, String> getAccessibilityTarget() {
- return Pair.create(mContent, mIsOpen ? getContext().getString(R.string.taskbar_edu_opened)
- : getContext().getString(R.string.taskbar_edu_closed));
- }
-
- @Override
- protected int getScrimColor(Context context) {
- return context.getResources().getColor(R.color.widgets_picker_scrim);
- }
-
- @Override
- protected void onLayout(boolean changed, int l, int t, int r, int b) {
- int width = r - l;
- int height = b - t;
-
- // Lay out the content as center bottom aligned.
- int contentWidth = mContent.getMeasuredWidth();
- int contentLeft = (width - contentWidth - mInsets.left - mInsets.right) / 2 + mInsets.left;
- mContent.layout(contentLeft, height - mContent.getMeasuredHeight(),
- contentLeft + contentWidth, height);
-
- setTranslationShift(mTranslationShift);
- }
-
- private void animateOpen() {
- if (mIsOpen || mOpenCloseAnimator.isRunning()) {
- return;
- }
- mIsOpen = true;
- mOpenCloseAnimator.setValues(
- PropertyValuesHolder.ofFloat(TRANSLATION_SHIFT, TRANSLATION_SHIFT_OPENED));
- mOpenCloseAnimator.setInterpolator(AGGRESSIVE_EASE);
- mOpenCloseAnimator.setDuration(DEFAULT_OPEN_DURATION).start();
- }
-
- void snapToPage(int page) {
- mPagedView.snapToPage(page);
- }
-
- void updateStartButton(int textResId, OnClickListener onClickListener) {
- mStartButton.setText(textResId);
- mStartButton.setOnClickListener(onClickListener);
- }
-
- void updateEndButton(int textResId, OnClickListener onClickListener) {
- mEndButton.setText(textResId);
- mEndButton.setOnClickListener(onClickListener);
- }
-}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarForceVisibleImmersiveController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarForceVisibleImmersiveController.java
deleted file mode 100644
index c99cebb1a7..0000000000
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarForceVisibleImmersiveController.java
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.launcher3.taskbar;
-
-import static android.view.accessibility.AccessibilityManager.FLAG_CONTENT_CONTROLS;
-import static android.view.accessibility.AccessibilityManager.FLAG_CONTENT_ICONS;
-
-import static com.android.launcher3.taskbar.NavbarButtonsViewController.ALPHA_INDEX_IMMERSIVE_MODE;
-import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_IMMERSIVE_MODE;
-
-import android.os.Handler;
-import android.os.Looper;
-import android.view.MotionEvent;
-
-import com.android.launcher3.compat.AccessibilityManagerCompat;
-import com.android.launcher3.util.MultiValueAlpha;
-import com.android.launcher3.util.TouchController;
-import com.android.quickstep.AnimatedFloat;
-
-import java.util.Optional;
-import java.util.function.Consumer;
-
-/**
- * Controller for taskbar when force visible in immersive mode is set.
- */
-public class TaskbarForceVisibleImmersiveController implements TouchController {
- private static final int NAV_BAR_ICONS_DIM_ANIMATION_START_DELAY_MS = 4500;
- private static final int NAV_BAR_ICONS_DIM_ANIMATION_DURATION_MS = 500;
- private static final int NAV_BAR_ICONS_UNDIM_ANIMATION_DURATION_MS = 250;
- private static final float NAV_BAR_ICONS_DIM_PCT = 0.15f;
- private static final float NAV_BAR_ICONS_UNDIM_PCT = 1f;
-
- private final TaskbarActivityContext mContext;
- private final Handler mHandler = new Handler(Looper.getMainLooper());
- private final Runnable mDimmingRunnable = this::dimIcons;
- private final Runnable mUndimmingRunnable = this::undimIcons;
- private final AnimatedFloat mIconAlphaForDimming = new AnimatedFloat(
- this::updateIconDimmingAlpha);
- private final Consumer<MultiValueAlpha> mImmersiveModeAlphaUpdater = alpha -> alpha.getProperty(
- ALPHA_INDEX_IMMERSIVE_MODE).setValue(mIconAlphaForDimming.value);
-
- // Initialized in init.
- private TaskbarControllers mControllers;
- private boolean mIsImmersiveMode;
-
- public TaskbarForceVisibleImmersiveController(TaskbarActivityContext context) {
- mContext = context;
- }
-
- /**
- * Initialize controllers.
- */
- public void init(TaskbarControllers controllers) {
- mControllers = controllers;
- }
-
- /** Update values tracked via sysui flags. */
- public void updateSysuiFlags(int sysuiFlags) {
- mIsImmersiveMode = (sysuiFlags & SYSUI_STATE_IMMERSIVE_MODE) != 0;
- if (mContext.isNavBarForceVisible()) {
- if (mIsImmersiveMode) {
- startIconDimming();
- } else {
- startIconUndimming();
- }
- }
- }
-
- /** Clean up animations. */
- public void onDestroy() {
- startIconUndimming();
- }
-
- private void startIconUndimming() {
- mHandler.removeCallbacks(mDimmingRunnable);
- mHandler.removeCallbacks(mUndimmingRunnable);
- mHandler.post(mUndimmingRunnable);
- }
-
- private void undimIcons() {
- mIconAlphaForDimming.animateToValue(NAV_BAR_ICONS_UNDIM_PCT).setDuration(
- NAV_BAR_ICONS_UNDIM_ANIMATION_DURATION_MS).start();
- }
-
- private void startIconDimming() {
- mHandler.removeCallbacks(mDimmingRunnable);
- int accessibilityDimmingTimeout = AccessibilityManagerCompat.getRecommendedTimeoutMillis(
- mContext, NAV_BAR_ICONS_DIM_ANIMATION_START_DELAY_MS,
- (FLAG_CONTENT_ICONS | FLAG_CONTENT_CONTROLS));
- mHandler.postDelayed(mDimmingRunnable, accessibilityDimmingTimeout);
- }
-
- private void dimIcons() {
- mIconAlphaForDimming.animateToValue(NAV_BAR_ICONS_DIM_PCT).setDuration(
- NAV_BAR_ICONS_DIM_ANIMATION_DURATION_MS).start();
- }
-
- /**
- * Returns whether the taskbar is always visible in immersive mode.
- */
- private boolean isNavbarShownInImmersiveMode() {
- return mIsImmersiveMode && mContext.isNavBarForceVisible();
- }
-
- private void updateIconDimmingAlpha() {
- getBackButtonAlphaOptional().ifPresent(mImmersiveModeAlphaUpdater);
- getHomeButtonAlphaOptional().ifPresent(mImmersiveModeAlphaUpdater);
- }
-
- private Optional<MultiValueAlpha> getBackButtonAlphaOptional() {
- if (mControllers == null || mControllers.navbarButtonsViewController == null) {
- return Optional.empty();
- }
- return Optional.ofNullable(mControllers.navbarButtonsViewController.getBackButtonAlpha());
- }
-
- private Optional<MultiValueAlpha> getHomeButtonAlphaOptional() {
- if (mControllers == null || mControllers.navbarButtonsViewController == null) {
- return Optional.empty();
- }
- return Optional.ofNullable(mControllers.navbarButtonsViewController.getHomeButtonAlpha());
- }
-
- @Override
- public boolean onControllerInterceptTouchEvent(MotionEvent ev) {
- if (!isNavbarShownInImmersiveMode()
- || mControllers.taskbarStashController.supportsManualStashing()) {
- return false;
- }
- return onControllerTouchEvent(ev);
- }
-
- @Override
- public boolean onControllerTouchEvent(MotionEvent ev) {
- switch (ev.getAction()) {
- case MotionEvent.ACTION_DOWN:
- startIconUndimming();
- break;
- case MotionEvent.ACTION_UP:
- case MotionEvent.ACTION_CANCEL:
- startIconDimming();
- break;
- }
- return false;
- }
-}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarHotseatController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarHotseatController.java
new file mode 100644
index 0000000000..91cf7efab5
--- /dev/null
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarHotseatController.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2021 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.launcher3.taskbar;
+
+import android.view.View;
+
+import com.android.launcher3.BaseQuickstepLauncher;
+import com.android.launcher3.CellLayout;
+import com.android.launcher3.DropTarget;
+import com.android.launcher3.Hotseat;
+import com.android.launcher3.ShortcutAndWidgetContainer;
+import com.android.launcher3.dragndrop.DragController;
+import com.android.launcher3.dragndrop.DragOptions;
+import com.android.launcher3.model.data.ItemInfo;
+
+import java.util.function.Consumer;
+
+/**
+ * Works with TaskbarController to update the TaskbarView's Hotseat items.
+ */
+public class TaskbarHotseatController {
+
+ private final BaseQuickstepLauncher mLauncher;
+ private final Hotseat mHotseat;
+ private final Consumer<ItemInfo[]> mTaskbarCallbacks;
+ private final int mNumHotseatIcons;
+
+ private final DragController.DragListener mDragListener = new DragController.DragListener() {
+ @Override
+ public void onDragStart(DropTarget.DragObject dragObject, DragOptions options) { }
+
+ @Override
+ public void onDragEnd() {
+ onHotseatUpdated();
+ }
+ };
+
+ public TaskbarHotseatController(
+ BaseQuickstepLauncher launcher, Consumer<ItemInfo[]> taskbarCallbacks) {
+ mLauncher = launcher;
+ mHotseat = mLauncher.getHotseat();
+ mTaskbarCallbacks = taskbarCallbacks;
+ mNumHotseatIcons = mLauncher.getDeviceProfile().numShownHotseatIcons;
+ }
+
+ protected void init() {
+ mLauncher.getDragController().addDragListener(mDragListener);
+ onHotseatUpdated();
+ }
+
+ protected void cleanup() {
+ mLauncher.getDragController().removeDragListener(mDragListener);
+ }
+
+ /**
+ * Called when any Hotseat item changes, and reports the new list of items to TaskbarController.
+ */
+ protected void onHotseatUpdated() {
+ ShortcutAndWidgetContainer shortcutsAndWidgets = mHotseat.getShortcutsAndWidgets();
+ ItemInfo[] hotseatItemInfos = new ItemInfo[mNumHotseatIcons];
+ for (int i = 0; i < shortcutsAndWidgets.getChildCount(); i++) {
+ View child = shortcutsAndWidgets.getChildAt(i);
+ Object tag = shortcutsAndWidgets.getChildAt(i).getTag();
+ if (tag instanceof ItemInfo) {
+ ItemInfo itemInfo = (ItemInfo) tag;
+ CellLayout.LayoutParams lp = (CellLayout.LayoutParams) child.getLayoutParams();
+ // Since the hotseat might be laid out vertically or horizontally, use whichever
+ // index is higher.
+ int index = Math.max(lp.cellX, lp.cellY);
+ if (0 <= index && index < hotseatItemInfos.length) {
+ hotseatItemInfos[index] = itemInfo;
+ }
+ }
+ }
+
+ mTaskbarCallbacks.accept(hotseatItemInfos);
+ }
+}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarIconController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarIconController.java
new file mode 100644
index 0000000000..683a5b9fc4
--- /dev/null
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarIconController.java
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2021 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.launcher3.taskbar;
+
+import static android.view.View.GONE;
+import static android.view.View.VISIBLE;
+
+import static com.android.systemui.shared.system.ViewTreeObserverWrapper.InsetsInfo.TOUCHABLE_INSETS_FRAME;
+import static com.android.systemui.shared.system.ViewTreeObserverWrapper.InsetsInfo.TOUCHABLE_INSETS_REGION;
+
+import android.graphics.Rect;
+import android.inputmethodservice.InputMethodService;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.View.OnLongClickListener;
+
+import androidx.annotation.NonNull;
+
+import com.android.launcher3.R;
+import com.android.launcher3.anim.AlphaUpdateListener;
+import com.android.systemui.shared.system.ViewTreeObserverWrapper.InsetsInfo;
+
+/**
+ * Controller for taskbar icon UI
+ */
+public class TaskbarIconController {
+
+ private final Rect mTempRect = new Rect();
+
+ private final TaskbarActivityContext mActivity;
+ private final TaskbarDragLayer mDragLayer;
+
+ private final TaskbarView mTaskbarView;
+ private final ImeBarView mImeBarView;
+
+ @NonNull
+ private TaskbarUIController mUIController = TaskbarUIController.DEFAULT;
+
+ TaskbarIconController(TaskbarActivityContext activity, TaskbarDragLayer dragLayer) {
+ mActivity = activity;
+ mDragLayer = dragLayer;
+ mTaskbarView = mDragLayer.findViewById(R.id.taskbar_view);
+ mImeBarView = mDragLayer.findViewById(R.id.ime_bar_view);
+ }
+
+ public void init(OnClickListener clickListener, OnLongClickListener longClickListener) {
+ mDragLayer.addOnLayoutChangeListener((v, a, b, c, d, e, f, g, h) ->
+ mUIController.alignRealHotseatWithTaskbar());
+
+ ButtonProvider buttonProvider = new ButtonProvider(mActivity);
+ mImeBarView.init(buttonProvider);
+ mTaskbarView.construct(clickListener, longClickListener, buttonProvider);
+ mTaskbarView.getLayoutParams().height = mActivity.getDeviceProfile().taskbarSize;
+
+ mDragLayer.init(new Callbacks(), mTaskbarView);
+ }
+
+ public void onDestroy() {
+ mDragLayer.onDestroy();
+ }
+
+ public void setUIController(@NonNull TaskbarUIController uiController) {
+ mUIController = uiController;
+ }
+
+ /**
+ * When in 3 button nav, the above doesn't get called since we prevent sysui nav bar from
+ * instantiating at all, which is what's responsible for sending sysui state flags over.
+ *
+ * @param vis IME visibility flag
+ */
+ public void updateImeStatus(int displayId, int vis, boolean showImeSwitcher) {
+ if (displayId != mActivity.getDisplayId() || !mActivity.canShowNavButtons()) {
+ return;
+ }
+
+ mImeBarView.setImeSwitcherVisibility(showImeSwitcher);
+ setImeIsVisible((vis & InputMethodService.IME_VISIBLE) != 0);
+ }
+
+ /**
+ * Should be called when the IME visibility changes, so we can hide/show Taskbar accordingly.
+ */
+ public void setImeIsVisible(boolean isImeVisible) {
+ mTaskbarView.setTouchesEnabled(!isImeVisible);
+ mUIController.onImeVisible(mDragLayer, isImeVisible);
+ }
+
+ /**
+ * Callbacks for {@link TaskbarDragLayer} to interact with the icon controller
+ */
+ public class Callbacks {
+
+ /**
+ * Called to update the touchable insets
+ */
+ public void updateInsetsTouchability(InsetsInfo insetsInfo) {
+ insetsInfo.touchableRegion.setEmpty();
+ if (mDragLayer.getAlpha() < AlphaUpdateListener.ALPHA_CUTOFF_THRESHOLD) {
+ // Let touches pass through us.
+ insetsInfo.setTouchableInsets(TOUCHABLE_INSETS_REGION);
+ } else if (mImeBarView.getVisibility() == VISIBLE) {
+ insetsInfo.setTouchableInsets(TOUCHABLE_INSETS_FRAME);
+ } else if (!mUIController.isTaskbarTouchable()) {
+ // Let touches pass through us.
+ insetsInfo.setTouchableInsets(TOUCHABLE_INSETS_REGION);
+ } else if (mTaskbarView.areIconsVisible()) {
+ // Buttons are visible, take over the full taskbar area
+ insetsInfo.setTouchableInsets(TOUCHABLE_INSETS_FRAME);
+ } else {
+ if (mTaskbarView.mSystemButtonContainer.getVisibility() == VISIBLE) {
+ mDragLayer.getDescendantRectRelativeToSelf(
+ mTaskbarView.mSystemButtonContainer, mTempRect);
+ insetsInfo.touchableRegion.set(mTempRect);
+ }
+ insetsInfo.setTouchableInsets(TOUCHABLE_INSETS_REGION);
+ }
+
+ // TaskbarContainerView provides insets to other apps based on contentInsets. These
+ // insets should stay consistent even if we expand TaskbarContainerView's bounds, e.g.
+ // to show a floating view like Folder. Thus, we set the contentInsets to be where
+ // mTaskbarView is, since its position never changes and insets rather than overlays.
+ insetsInfo.contentInsets.left = mTaskbarView.getLeft();
+ insetsInfo.contentInsets.top = mTaskbarView.getTop();
+ insetsInfo.contentInsets.right = mDragLayer.getWidth() - mTaskbarView.getRight();
+ insetsInfo.contentInsets.bottom = mDragLayer.getHeight() - mTaskbarView.getBottom();
+ }
+
+ public void onDragLayerViewRemoved() {
+ int count = mDragLayer.getChildCount();
+ // Ensure no other children present (like Folders, etc)
+ for (int i = 0; i < count; i++) {
+ View v = mDragLayer.getChildAt(i);
+ if (!((v instanceof TaskbarView) || (v instanceof ImeBarView))) {
+ return;
+ }
+ }
+ mActivity.setTaskbarWindowFullscreen(false);
+ }
+
+ public void updateImeBarVisibilityAlpha(float alpha) {
+ if (!mActivity.canShowNavButtons()) {
+ // TODO Remove sysui IME bar for gesture nav as well
+ return;
+ }
+ mImeBarView.setAlpha(alpha);
+ mImeBarView.setVisibility(alpha == 0 ? GONE : VISIBLE);
+ }
+ }
+}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarInsetsController.kt b/quickstep/src/com/android/launcher3/taskbar/TaskbarInsetsController.kt
deleted file mode 100644
index 6a6a693dc3..0000000000
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarInsetsController.kt
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.launcher3.taskbar
-
-import android.graphics.Insets
-import android.graphics.Region
-import android.view.InsetsState.ITYPE_BOTTOM_MANDATORY_GESTURES
-import android.view.WindowManager
-import com.android.launcher3.AbstractFloatingView
-import com.android.launcher3.AbstractFloatingView.TYPE_TASKBAR_ALL_APPS
-import com.android.launcher3.DeviceProfile
-import com.android.launcher3.anim.AlphaUpdateListener
-import com.android.launcher3.taskbar.TaskbarControllers.LoggableTaskbarController
-import com.android.quickstep.KtR
-import com.android.systemui.shared.system.ViewTreeObserverWrapper.InsetsInfo
-import com.android.systemui.shared.system.WindowManagerWrapper
-import com.android.systemui.shared.system.WindowManagerWrapper.*
-import java.io.PrintWriter
-
-/**
- * Handles the insets that Taskbar provides to underlying apps and the IME.
- */
-class TaskbarInsetsController(val context: TaskbarActivityContext): LoggableTaskbarController {
-
- /** The bottom insets taskbar provides to the IME when IME is visible. */
- val taskbarHeightForIme: Int = context.resources.getDimensionPixelSize(
- KtR.dimen.taskbar_ime_size)
- private val contentRegion: Region = Region()
- private val deviceProfileChangeListener = { _: DeviceProfile ->
- onTaskbarWindowHeightOrInsetsChanged()
- }
-
- // Initialized in init.
- private lateinit var controllers: TaskbarControllers
- private lateinit var windowLayoutParams: WindowManager.LayoutParams
-
- fun init(controllers: TaskbarControllers) {
- this.controllers = controllers
- windowLayoutParams = context.windowLayoutParams
-
- val wmWrapper: WindowManagerWrapper = getInstance()
- wmWrapper.setProvidesInsetsTypes(
- windowLayoutParams,
- intArrayOf(
- ITYPE_EXTRA_NAVIGATION_BAR,
- ITYPE_BOTTOM_TAPPABLE_ELEMENT,
- ITYPE_BOTTOM_MANDATORY_GESTURES
- )
- )
-
- windowLayoutParams.providedInternalInsets = arrayOfNulls<Insets>(ITYPE_SIZE)
- windowLayoutParams.providedInternalImeInsets = arrayOfNulls<Insets>(ITYPE_SIZE)
-
- onTaskbarWindowHeightOrInsetsChanged()
-
- windowLayoutParams.insetsRoundedCornerFrame = true
- context.addOnDeviceProfileChangeListener(deviceProfileChangeListener)
- }
-
- fun onDestroy() {
- context.removeOnDeviceProfileChangeListener(deviceProfileChangeListener)
- }
-
- fun onTaskbarWindowHeightOrInsetsChanged() {
- var reducingSize = getReducingInsetsForTaskbarInsetsHeight(
- controllers.taskbarStashController.contentHeightToReportToApps)
-
- contentRegion.set(0, reducingSize.top,
- context.deviceProfile.widthPx, windowLayoutParams.height)
- windowLayoutParams.providedInternalInsets[ITYPE_EXTRA_NAVIGATION_BAR] = reducingSize
- windowLayoutParams.providedInternalInsets[ITYPE_BOTTOM_MANDATORY_GESTURES] = reducingSize
- reducingSize = getReducingInsetsForTaskbarInsetsHeight(
- controllers.taskbarStashController.tappableHeightToReportToApps)
- windowLayoutParams.providedInternalInsets[ITYPE_BOTTOM_TAPPABLE_ELEMENT] = reducingSize
- windowLayoutParams.providedInternalInsets[ITYPE_BOTTOM_MANDATORY_GESTURES] = reducingSize
-
- reducingSize = getReducingInsetsForTaskbarInsetsHeight(taskbarHeightForIme)
- windowLayoutParams.providedInternalImeInsets[ITYPE_EXTRA_NAVIGATION_BAR] = reducingSize
- windowLayoutParams.providedInternalImeInsets[ITYPE_BOTTOM_TAPPABLE_ELEMENT] = reducingSize
- windowLayoutParams.providedInternalImeInsets[ITYPE_BOTTOM_MANDATORY_GESTURES] = reducingSize
- }
-
- /**
- * WindowLayoutParams.providedInternal*Insets expects Insets that subtract from the window frame
- * height (i.e. WindowLayoutParams#height). So for Taskbar to report bottom insets to apps, it
- * actually provides insets from the top of its window frame.
- * @param height The number of pixels from the bottom of the screen that Taskbar insets.
- */
- private fun getReducingInsetsForTaskbarInsetsHeight(height: Int): Insets {
- return Insets.of(0, windowLayoutParams.height - height, 0, 0)
- }
-
- /**
- * Called to update the touchable insets.
- * @see InsetsInfo.setTouchableInsets
- */
- fun updateInsetsTouchability(insetsInfo: InsetsInfo) {
- insetsInfo.touchableRegion.setEmpty()
- // Always have nav buttons be touchable
- controllers.navbarButtonsViewController.addVisibleButtonsRegion(
- context.dragLayer, insetsInfo.touchableRegion
- )
- var insetsIsTouchableRegion = true
- if (context.dragLayer.alpha < AlphaUpdateListener.ALPHA_CUTOFF_THRESHOLD) {
- // Let touches pass through us.
- insetsInfo.setTouchableInsets(InsetsInfo.TOUCHABLE_INSETS_REGION)
- } else if (controllers.navbarButtonsViewController.isImeVisible) {
- insetsInfo.setTouchableInsets(InsetsInfo.TOUCHABLE_INSETS_REGION)
- } else if (!controllers.uiController.isTaskbarTouchable) {
- // Let touches pass through us.
- insetsInfo.setTouchableInsets(InsetsInfo.TOUCHABLE_INSETS_REGION)
- } else if (controllers.taskbarDragController.isSystemDragInProgress) {
- // Let touches pass through us.
- insetsInfo.setTouchableInsets(InsetsInfo.TOUCHABLE_INSETS_REGION)
- } else if (AbstractFloatingView.hasOpenView(context, TYPE_TASKBAR_ALL_APPS)) {
- // Let touches pass through us.
- insetsInfo.setTouchableInsets(InsetsInfo.TOUCHABLE_INSETS_REGION)
- } else if (controllers.taskbarViewController.areIconsVisible()
- || AbstractFloatingView.hasOpenView(context, AbstractFloatingView.TYPE_ALL)
- || context.isNavBarKidsModeActive
- ) {
- // Taskbar has some touchable elements, take over the full taskbar area
- insetsInfo.setTouchableInsets(
- if (context.isTaskbarWindowFullscreen) {
- InsetsInfo.TOUCHABLE_INSETS_FRAME
- } else {
- insetsInfo.touchableRegion.set(contentRegion)
- InsetsInfo.TOUCHABLE_INSETS_REGION
- }
- )
- insetsIsTouchableRegion = false
- } else {
- insetsInfo.setTouchableInsets(InsetsInfo.TOUCHABLE_INSETS_REGION)
- }
- context.excludeFromMagnificationRegion(insetsIsTouchableRegion)
- }
-
- override fun dumpLogs(prefix: String, pw: PrintWriter) {
- pw.println(prefix + "TaskbarInsetsController:")
- pw.println("$prefix\twindowHeight=${windowLayoutParams.height}")
- pw.println("$prefix\tprovidedInternalInsets[ITYPE_EXTRA_NAVIGATION_BAR]=" +
- "${windowLayoutParams.providedInternalInsets[ITYPE_EXTRA_NAVIGATION_BAR]}")
- pw.println("$prefix\tprovidedInternalInsets[ITYPE_BOTTOM_TAPPABLE_ELEMENT]=" +
- "${windowLayoutParams.providedInternalInsets[ITYPE_BOTTOM_TAPPABLE_ELEMENT]}")
- pw.println("$prefix\tprovidedInternalImeInsets[ITYPE_EXTRA_NAVIGATION_BAR]=" +
- "${windowLayoutParams.providedInternalImeInsets[ITYPE_EXTRA_NAVIGATION_BAR]}")
- pw.println("$prefix\tprovidedInternalImeInsets[ITYPE_BOTTOM_TAPPABLE_ELEMENT]=" +
- "${windowLayoutParams.providedInternalImeInsets[ITYPE_BOTTOM_TAPPABLE_ELEMENT]}")
- }
-} \ No newline at end of file
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarKeyguardController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarKeyguardController.java
deleted file mode 100644
index 56648eac38..0000000000
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarKeyguardController.java
+++ /dev/null
@@ -1,121 +0,0 @@
-package com.android.launcher3.taskbar;
-
-import static com.android.launcher3.AbstractFloatingView.TYPE_ALL;
-import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_BACK_DISABLED;
-import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_BOUNCER_SHOWING;
-import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_DEVICE_DOZING;
-import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_HOME_DISABLED;
-import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_OVERVIEW_DISABLED;
-import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING;
-import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED;
-
-import android.app.KeyguardManager;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-
-import com.android.launcher3.AbstractFloatingView;
-import com.android.systemui.shared.system.QuickStepContract;
-
-import java.io.PrintWriter;
-
-/**
- * Controller for managing keyguard state for taskbar
- */
-public class TaskbarKeyguardController implements TaskbarControllers.LoggableTaskbarController {
-
- private static final int KEYGUARD_SYSUI_FLAGS = SYSUI_STATE_BOUNCER_SHOWING |
- SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING | SYSUI_STATE_DEVICE_DOZING |
- SYSUI_STATE_OVERVIEW_DISABLED | SYSUI_STATE_HOME_DISABLED |
- SYSUI_STATE_BACK_DISABLED | SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED;
-
- private final TaskbarActivityContext mContext;
- private int mKeyguardSysuiFlags;
- private boolean mBouncerShowing;
- private NavbarButtonsViewController mNavbarButtonsViewController;
- private final KeyguardManager mKeyguardManager;
- private boolean mIsScreenOff;
-
- private final BroadcastReceiver mScreenOffReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- mIsScreenOff = true;
- AbstractFloatingView.closeOpenViews(mContext, false, TYPE_ALL);
- }
- };
-
- public TaskbarKeyguardController(TaskbarActivityContext context) {
- mContext = context;
- mKeyguardManager = mContext.getSystemService(KeyguardManager.class);
- }
-
- public void init(NavbarButtonsViewController navbarButtonUIController) {
- mNavbarButtonsViewController = navbarButtonUIController;
- mContext.registerReceiver(mScreenOffReceiver, new IntentFilter(Intent.ACTION_SCREEN_OFF));
- }
-
- public void updateStateForSysuiFlags(int systemUiStateFlags) {
- boolean bouncerShowing = (systemUiStateFlags & SYSUI_STATE_BOUNCER_SHOWING) != 0;
- boolean keyguardShowing = (systemUiStateFlags & SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING)
- != 0;
- boolean keyguardOccluded =
- (systemUiStateFlags & SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED) != 0;
- boolean dozing = (systemUiStateFlags & SYSUI_STATE_DEVICE_DOZING) != 0;
-
- int interestingKeyguardFlags = systemUiStateFlags & KEYGUARD_SYSUI_FLAGS;
- if (interestingKeyguardFlags == mKeyguardSysuiFlags) {
- return;
- }
- mKeyguardSysuiFlags = interestingKeyguardFlags;
-
- mBouncerShowing = bouncerShowing;
-
- mNavbarButtonsViewController.setKeyguardVisible(keyguardShowing || dozing,
- keyguardOccluded);
- updateIconsForBouncer();
-
- if (keyguardShowing) {
- AbstractFloatingView.closeOpenViews(mContext, true, TYPE_ALL);
- }
- }
-
- public boolean isScreenOff() {
- return mIsScreenOff;
- }
-
- public void setScreenOn() {
- mIsScreenOff = false;
- }
-
- /**
- * Hides/shows taskbar when keyguard is up
- */
- private void updateIconsForBouncer() {
- boolean disableBack = (mKeyguardSysuiFlags & SYSUI_STATE_BACK_DISABLED) != 0;
- boolean disableRecent = (mKeyguardSysuiFlags & SYSUI_STATE_OVERVIEW_DISABLED) != 0;
- boolean disableHome = (mKeyguardSysuiFlags & SYSUI_STATE_HOME_DISABLED) != 0;
- boolean onlyBackEnabled = !disableBack && disableRecent && disableHome;
-
- boolean showBackForBouncer = onlyBackEnabled &&
- mKeyguardManager.isDeviceSecure() &&
- mBouncerShowing;
- mNavbarButtonsViewController.setBackForBouncer(showBackForBouncer);
- }
-
- public void onDestroy() {
- mContext.unregisterReceiver(mScreenOffReceiver);
- }
-
- @Override
- public void dumpLogs(String prefix, PrintWriter pw) {
- pw.println(prefix + "TaskbarKeyguardController:");
-
- pw.println(String.format(
- "%s\tmKeyguardSysuiFlags=%s",
- prefix,
- QuickStepContract.getSystemUiStateString(mKeyguardSysuiFlags)));
- pw.println(String.format("%s\tmBouncerShowing=%b", prefix, mBouncerShowing));
- pw.println(String.format("%s\tmIsScreenOff=%b", prefix, mIsScreenOff));
- }
-}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java
deleted file mode 100644
index dc0ef27ba1..0000000000
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java
+++ /dev/null
@@ -1,521 +0,0 @@
-/*
- * Copyright (C) 2021 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.launcher3.taskbar;
-
-import static com.android.launcher3.taskbar.TaskbarStashController.FLAG_IN_APP;
-import static com.android.launcher3.taskbar.TaskbarStashController.FLAG_IN_STASHED_LAUNCHER_STATE;
-import static com.android.launcher3.taskbar.TaskbarStashController.TASKBAR_STASH_DURATION;
-import static com.android.launcher3.taskbar.TaskbarViewController.ALPHA_INDEX_HOME;
-
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.AnimatorSet;
-import android.animation.ObjectAnimator;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
-import com.android.launcher3.AbstractFloatingView;
-import com.android.launcher3.BaseQuickstepLauncher;
-import com.android.launcher3.LauncherState;
-import com.android.launcher3.Utilities;
-import com.android.launcher3.statemanager.StateManager;
-import com.android.launcher3.util.MultiValueAlpha;
-import com.android.quickstep.AnimatedFloat;
-import com.android.quickstep.RecentsAnimationCallbacks;
-import com.android.quickstep.RecentsAnimationController;
-import com.android.quickstep.views.RecentsView;
-import com.android.systemui.animation.ViewRootSync;
-import com.android.systemui.shared.recents.model.ThumbnailData;
-
-import java.io.PrintWriter;
-import java.util.HashMap;
-import java.util.StringJoiner;
-import java.util.function.Consumer;
-import java.util.function.Supplier;
-
-/**
- * Track LauncherState, RecentsAnimation, resumed state for task bar in one place here and animate
- * the task bar accordingly.
- */
- public class TaskbarLauncherStateController {
-
- public static final int FLAG_RESUMED = 1 << 0;
- public static final int FLAG_RECENTS_ANIMATION_RUNNING = 1 << 1;
- public static final int FLAG_TRANSITION_STATE_RUNNING = 1 << 2;
-
- /** Equivalent to an int with all 1s for binary operation purposes */
- private static final int FLAGS_ALL = ~0;
-
- private final AnimatedFloat mIconAlignmentForResumedState =
- new AnimatedFloat(this::onIconAlignmentRatioChangedForAppAndHomeTransition);
- private final AnimatedFloat mIconAlignmentForGestureState =
- new AnimatedFloat(this::onIconAlignmentRatioChangedForAppAndHomeTransition);
- private final AnimatedFloat mIconAlignmentForLauncherState =
- new AnimatedFloat(this::onIconAlignmentRatioChangedForStateTransition);
-
- private TaskbarControllers mControllers;
- private AnimatedFloat mTaskbarBackgroundAlpha;
- private MultiValueAlpha.AlphaProperty mIconAlphaForHome;
- private BaseQuickstepLauncher mLauncher;
-
- private Integer mPrevState;
- private int mState;
- private LauncherState mLauncherState = LauncherState.NORMAL;
-
- private @Nullable TaskBarRecentsAnimationListener mTaskBarRecentsAnimationListener;
-
- private boolean mIsAnimatingToLauncherViaGesture;
- private boolean mIsAnimatingToLauncherViaResume;
-
- private boolean mShouldDelayLauncherStateAnim;
-
- // We skip any view synchronizations during init/destroy.
- private boolean mCanSyncViews;
-
- private final StateManager.StateListener<LauncherState> mStateListener =
- new StateManager.StateListener<LauncherState>() {
-
- @Override
- public void onStateTransitionStart(LauncherState toState) {
- if (toState != mLauncherState) {
- // Treat FLAG_TRANSITION_STATE_RUNNING as a changed flag even if a previous
- // state transition was already running, so we update the new target.
- mPrevState &= ~FLAG_TRANSITION_STATE_RUNNING;
- mLauncherState = toState;
- }
- updateStateForFlag(FLAG_TRANSITION_STATE_RUNNING, true);
- if (!mShouldDelayLauncherStateAnim) {
- applyState();
- }
- }
-
- @Override
- public void onStateTransitionComplete(LauncherState finalState) {
- mLauncherState = finalState;
- updateStateForFlag(FLAG_TRANSITION_STATE_RUNNING, false);
- applyState();
- }
- };
-
- public void init(TaskbarControllers controllers, BaseQuickstepLauncher launcher) {
- mCanSyncViews = false;
-
- mControllers = controllers;
- mLauncher = launcher;
-
- mTaskbarBackgroundAlpha = mControllers.taskbarDragLayerController
- .getTaskbarBackgroundAlpha();
- MultiValueAlpha taskbarIconAlpha = mControllers.taskbarViewController.getTaskbarIconAlpha();
- mIconAlphaForHome = taskbarIconAlpha.getProperty(ALPHA_INDEX_HOME);
- mIconAlphaForHome.setConsumer(
- (Consumer<Float>) alpha -> mLauncher.getHotseat().setIconsAlpha(alpha > 0 ? 0 : 1));
-
- mIconAlignmentForResumedState.finishAnimation();
- onIconAlignmentRatioChangedForAppAndHomeTransition();
-
- mLauncher.getStateManager().addStateListener(mStateListener);
-
- // Initialize to the current launcher state
- updateStateForFlag(FLAG_RESUMED, launcher.hasBeenResumed());
- mLauncherState = launcher.getStateManager().getState();
- applyState(0);
-
- mCanSyncViews = true;
- }
-
- public void onDestroy() {
- mCanSyncViews = false;
-
- mIconAlignmentForResumedState.finishAnimation();
- mIconAlignmentForGestureState.finishAnimation();
- mIconAlignmentForLauncherState.finishAnimation();
-
- mIconAlphaForHome.setConsumer(null);
- mLauncher.getHotseat().setIconsAlpha(1f);
- mLauncher.getStateManager().removeStateListener(mStateListener);
-
- mCanSyncViews = true;
- }
-
- public Animator createAnimToLauncher(@NonNull LauncherState toState,
- @NonNull RecentsAnimationCallbacks callbacks, long duration) {
- // If going to overview, stash the task bar
- // If going home, align the icons to hotseat
- AnimatorSet animatorSet = new AnimatorSet();
-
- // Update stashed flags first to ensure goingToUnstashedLauncherState() returns correctly.
- TaskbarStashController stashController = mControllers.taskbarStashController;
- stashController.updateStateForFlag(FLAG_IN_STASHED_LAUNCHER_STATE,
- toState.isTaskbarStashed(mLauncher));
- stashController.updateStateForFlag(FLAG_IN_APP, false);
-
- updateStateForFlag(FLAG_RECENTS_ANIMATION_RUNNING, true);
- animatorSet.play(stashController.applyStateWithoutStart(duration));
- animatorSet.play(applyState(duration, false));
-
- mTaskBarRecentsAnimationListener = new TaskBarRecentsAnimationListener(callbacks);
- callbacks.addListener(mTaskBarRecentsAnimationListener);
- RecentsView recentsView = mLauncher.getOverviewPanel();
- recentsView.setTaskLaunchListener(() -> {
- mTaskBarRecentsAnimationListener.endGestureStateOverride(true);
- });
- return animatorSet;
- }
-
- public boolean isAnimatingToLauncher() {
- return mIsAnimatingToLauncherViaResume || mIsAnimatingToLauncherViaGesture;
- }
-
- public void setShouldDelayLauncherStateAnim(boolean shouldDelayLauncherStateAnim) {
- if (!shouldDelayLauncherStateAnim && mShouldDelayLauncherStateAnim) {
- // Animate the animation we have delayed immediately. This is usually triggered when
- // the user has released their finger.
- applyState();
- }
- mShouldDelayLauncherStateAnim = shouldDelayLauncherStateAnim;
- }
-
- /**
- * Updates the proper flag to change the state of the task bar.
- *
- * Note that this only updates the flag. {@link #applyState()} needs to be called separately.
- *
- * @param flag The flag to update.
- * @param enabled Whether to enable the flag
- */
- public void updateStateForFlag(int flag, boolean enabled) {
- if (enabled) {
- mState |= flag;
- } else {
- mState &= ~flag;
- }
- }
-
- private boolean hasAnyFlag(int flagMask) {
- return hasAnyFlag(mState, flagMask);
- }
-
- private boolean hasAnyFlag(int flags, int flagMask) {
- return (flags & flagMask) != 0;
- }
-
- public void applyState() {
- applyState(TASKBAR_STASH_DURATION);
- }
-
- public void applyState(long duration) {
- applyState(duration, true);
- }
-
- public Animator applyState(boolean start) {
- return applyState(TASKBAR_STASH_DURATION, start);
- }
-
- public Animator applyState(long duration, boolean start) {
- Animator animator = null;
- if (mPrevState == null || mPrevState != mState) {
- // If this is our initial state, treat all flags as changed.
- int changedFlags = mPrevState == null ? FLAGS_ALL : mPrevState ^ mState;
- mPrevState = mState;
- animator = onStateChangeApplied(changedFlags, duration, start);
- }
- return animator;
- }
-
- private Animator onStateChangeApplied(int changedFlags, long duration, boolean start) {
- AnimatorSet animatorSet = new AnimatorSet();
-
- // Add the state animation first to ensure FLAG_IN_STASHED_LAUNCHER_STATE is set and we can
- // determine whether goingToUnstashedLauncherStateChanged.
- boolean wasGoingToUnstashedLauncherState = goingToUnstashedLauncherState();
- if (hasAnyFlag(changedFlags, FLAG_TRANSITION_STATE_RUNNING)) {
- boolean committed = !hasAnyFlag(FLAG_TRANSITION_STATE_RUNNING);
- playStateTransitionAnim(animatorSet, duration, committed);
-
- if (committed && mLauncherState == LauncherState.QUICK_SWITCH) {
- // We're about to be paused, set immediately to ensure seamless handoff.
- updateStateForFlag(FLAG_RESUMED, false);
- applyState(0 /* duration */);
- }
- }
- boolean goingToUnstashedLauncherStateChanged = wasGoingToUnstashedLauncherState
- != goingToUnstashedLauncherState();
-
- boolean launcherStateChangedDuringAnimToResumeAlignment =
- mIconAlignmentForResumedState.isAnimating() && goingToUnstashedLauncherStateChanged;
- if (hasAnyFlag(changedFlags, FLAG_RESUMED)
- || launcherStateChangedDuringAnimToResumeAlignment) {
- boolean isResumed = isResumed();
- // If launcher is resumed, we show the icons when going to an unstashed launcher state
- // or launcher state is not changed (e.g. in overview, launcher is paused and resumed).
- float toAlignmentForResumedState = isResumed && (goingToUnstashedLauncherState()
- || !goingToUnstashedLauncherStateChanged) ? 1 : 0;
- // If we're already animating to the value, just leave it be instead of restarting it.
- if (!mIconAlignmentForResumedState.isAnimatingToValue(toAlignmentForResumedState)) {
- ObjectAnimator resumeAlignAnim = mIconAlignmentForResumedState
- .animateToValue(toAlignmentForResumedState)
- .setDuration(duration);
-
- resumeAlignAnim.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- mIsAnimatingToLauncherViaResume = false;
- }
-
- @Override
- public void onAnimationStart(Animator animation) {
- mIsAnimatingToLauncherViaResume = isResumed;
-
- TaskbarStashController stashController =
- mControllers.taskbarStashController;
- stashController.updateStateForFlag(FLAG_IN_APP, !isResumed);
- stashController.applyState(duration);
- }
- });
- animatorSet.play(resumeAlignAnim);
- }
- }
-
-
- boolean launcherStateChangedDuringAnimToGestureAlignment =
- mIconAlignmentForGestureState.isAnimating() && goingToUnstashedLauncherStateChanged;
- if (hasAnyFlag(changedFlags, FLAG_RECENTS_ANIMATION_RUNNING)
- || launcherStateChangedDuringAnimToGestureAlignment) {
- boolean isRecentsAnimationRunning = isRecentsAnimationRunning();
- float toAlignmentForGestureState = isRecentsAnimationRunning
- && goingToUnstashedLauncherState() ? 1 : 0;
- // If we're already animating to the value, just leave it be instead of restarting it.
- if (!mIconAlignmentForGestureState.isAnimatingToValue(toAlignmentForGestureState)) {
- Animator gestureAlignAnim = mIconAlignmentForGestureState
- .animateToValue(toAlignmentForGestureState);
- if (isRecentsAnimationRunning) {
- gestureAlignAnim.setDuration(duration);
- }
- gestureAlignAnim.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- mIsAnimatingToLauncherViaGesture = false;
- }
-
- @Override
- public void onAnimationStart(Animator animation) {
- mIsAnimatingToLauncherViaGesture = isRecentsAnimationRunning();
- }
- });
- animatorSet.play(gestureAlignAnim);
- }
- }
-
- if (hasAnyFlag(changedFlags, FLAG_RESUMED | FLAG_RECENTS_ANIMATION_RUNNING)) {
- boolean goingToLauncher = hasAnyFlag(FLAG_RESUMED | FLAG_RECENTS_ANIMATION_RUNNING);
- if (goingToLauncher) {
- // Handle closing open popups when going home/overview
- AbstractFloatingView.closeAllOpenViews(mControllers.taskbarActivityContext);
- }
- animatorSet.play(mTaskbarBackgroundAlpha.animateToValue(goingToLauncher ? 0 : 1)
- .setDuration(duration));
- }
-
- if (start) {
- animatorSet.start();
- }
- return animatorSet;
- }
-
- /** Returns whether we're going to a state where taskbar icons should align with launcher. */
- private boolean goingToUnstashedLauncherState() {
- return !mControllers.taskbarStashController.isInStashedLauncherState();
- }
-
- private void playStateTransitionAnim(AnimatorSet animatorSet, long duration,
- boolean committed) {
- boolean isInStashedState = mLauncherState.isTaskbarStashed(mLauncher);
- float toAlignment = mLauncherState.isTaskbarAlignedWithHotseat(mLauncher) ? 1 : 0;
-
- TaskbarStashController controller = mControllers.taskbarStashController;
- controller.updateStateForFlag(FLAG_IN_STASHED_LAUNCHER_STATE, isInStashedState);
- Animator stashAnimator = controller.applyStateWithoutStart(duration);
- if (stashAnimator != null) {
- stashAnimator.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- if (isInStashedState && committed) {
- // Reset hotseat alpha to default
- mLauncher.getHotseat().setIconsAlpha(1);
- }
- }
-
- @Override
- public void onAnimationStart(Animator animation) {
- if (mLauncher.getHotseat().getIconsAlpha() > 0) {
- mIconAlphaForHome.setValue(mLauncher.getHotseat().getIconsAlpha());
- }
- }
- });
- animatorSet.play(stashAnimator);
- }
-
- // If we're already animating to the value, just leave it be instead of restarting it.
- if (!mIconAlignmentForLauncherState.isAnimatingToValue(toAlignment)) {
- mIconAlignmentForLauncherState.finishAnimation();
- animatorSet.play(mIconAlignmentForLauncherState.animateToValue(toAlignment)
- .setDuration(duration));
- }
- }
-
- private boolean isResumed() {
- return (mState & FLAG_RESUMED) != 0;
- }
-
- private boolean isRecentsAnimationRunning() {
- return (mState & FLAG_RECENTS_ANIMATION_RUNNING) != 0;
- }
-
- private void onIconAlignmentRatioChangedForStateTransition() {
- if (!isResumed() && mTaskBarRecentsAnimationListener == null) {
- return;
- }
- onIconAlignmentRatioChanged(this::getCurrentIconAlignmentRatioForLauncherState);
- }
-
- private void onIconAlignmentRatioChangedForAppAndHomeTransition() {
- onIconAlignmentRatioChanged(this::getCurrentIconAlignmentRatioBetweenAppAndHome);
- }
-
- private void onIconAlignmentRatioChanged(Supplier<Float> alignmentSupplier) {
- if (mControllers == null) {
- return;
- }
- float alignment = alignmentSupplier.get();
- float currentValue = mIconAlphaForHome.getValue();
- boolean taskbarWillBeVisible = alignment < 1;
- boolean firstFrameVisChanged = (taskbarWillBeVisible && Float.compare(currentValue, 1) != 0)
- || (!taskbarWillBeVisible && Float.compare(currentValue, 0) != 0);
-
- updateIconAlignment(alignment);
-
- // Sync the first frame where we swap taskbar and hotseat.
- if (firstFrameVisChanged && mCanSyncViews && !Utilities.IS_RUNNING_IN_TEST_HARNESS) {
- ViewRootSync.synchronizeNextDraw(mLauncher.getHotseat(),
- mControllers.taskbarActivityContext.getDragLayer(),
- () -> {});
- }
- }
-
- private void updateIconAlignment(float alignment) {
- mControllers.taskbarViewController.setLauncherIconAlignment(
- alignment, mLauncher.getDeviceProfile());
-
- // Switch taskbar and hotseat in last frame
- setTaskbarViewVisible(alignment < 1);
- mControllers.navbarButtonsViewController.updateTaskbarAlignment(alignment);
- }
-
- private float getCurrentIconAlignmentRatioBetweenAppAndHome() {
- return Math.max(mIconAlignmentForResumedState.value, mIconAlignmentForGestureState.value);
- }
-
- private float getCurrentIconAlignmentRatioForLauncherState() {
- return mIconAlignmentForLauncherState.value;
- }
-
- private void setTaskbarViewVisible(boolean isVisible) {
- mIconAlphaForHome.setValue(isVisible ? 1 : 0);
- }
-
- private final class TaskBarRecentsAnimationListener implements
- RecentsAnimationCallbacks.RecentsAnimationListener {
- private final RecentsAnimationCallbacks mCallbacks;
-
- TaskBarRecentsAnimationListener(RecentsAnimationCallbacks callbacks) {
- mCallbacks = callbacks;
- }
-
- @Override
- public void onRecentsAnimationCanceled(HashMap<Integer, ThumbnailData> thumbnailDatas) {
- boolean isInOverview = mLauncher.isInState(LauncherState.OVERVIEW);
- endGestureStateOverride(!isInOverview);
- }
-
- @Override
- public void onRecentsAnimationFinished(RecentsAnimationController controller) {
- endGestureStateOverride(!controller.getFinishTargetIsLauncher());
- }
-
- private void endGestureStateOverride(boolean finishedToApp) {
- mCallbacks.removeListener(this);
- mTaskBarRecentsAnimationListener = null;
-
- // Update the resumed state immediately to ensure a seamless handoff
- boolean launcherResumed = !finishedToApp;
- updateStateForFlag(FLAG_RECENTS_ANIMATION_RUNNING, false);
- updateStateForFlag(FLAG_RESUMED, launcherResumed);
- applyState();
- // Set this last because applyState() might also animate it.
- mIconAlignmentForResumedState.cancelAnimation();
- mIconAlignmentForResumedState.updateValue(launcherResumed ? 1 : 0);
-
- TaskbarStashController controller = mControllers.taskbarStashController;
- controller.updateStateForFlag(FLAG_IN_APP, finishedToApp);
- controller.applyState();
- }
- }
-
- private static String getStateString(int flags) {
- StringJoiner str = new StringJoiner("|");
- str.add((flags & FLAG_RESUMED) != 0 ? "FLAG_RESUMED" : "");
- str.add((flags & FLAG_RECENTS_ANIMATION_RUNNING) != 0
- ? "FLAG_RECENTS_ANIMATION_RUNNING" : "");
- str.add((flags & FLAG_TRANSITION_STATE_RUNNING) != 0
- ? "FLAG_TRANSITION_STATE_RUNNING" : "");
- return str.toString();
- }
-
- protected void dumpLogs(String prefix, PrintWriter pw) {
- pw.println(prefix + "TaskbarLauncherStateController:");
-
- pw.println(String.format(
- "%s\tmIconAlignmentForResumedState=%.2f",
- prefix,
- mIconAlignmentForResumedState.value));
- pw.println(String.format(
- "%s\tmIconAlignmentForGestureState=%.2f",
- prefix,
- mIconAlignmentForGestureState.value));
- pw.println(String.format(
- "%s\tmIconAlignmentForLauncherState=%.2f",
- prefix,
- mIconAlignmentForLauncherState.value));
- pw.println(String.format(
- "%s\tmTaskbarBackgroundAlpha=%.2f", prefix, mTaskbarBackgroundAlpha.value));
- pw.println(String.format(
- "%s\tmIconAlphaForHome=%.2f", prefix, mIconAlphaForHome.getValue()));
- pw.println(String.format("%s\tmPrevState=%s", prefix, getStateString(mPrevState)));
- pw.println(String.format("%s\tmState=%s", prefix, getStateString(mState)));
- pw.println(String.format("%s\tmLauncherState=%s", prefix, mLauncherState));
- pw.println(String.format(
- "%s\tmIsAnimatingToLauncherViaGesture=%b",
- prefix,
- mIsAnimatingToLauncherViaGesture));
- pw.println(String.format(
- "%s\tmIsAnimatingToLauncherViaResume=%b",
- prefix,
- mIsAnimatingToLauncherViaResume));
- pw.println(String.format(
- "%s\tmShouldDelayLauncherStateAnim=%b", prefix, mShouldDelayLauncherStateAnim));
- }
-}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java
index 06262c0a25..d026bfbf37 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java
@@ -15,167 +15,75 @@
*/
package com.android.launcher3.taskbar;
-import static android.content.pm.PackageManager.FEATURE_PC;
import static android.view.Display.DEFAULT_DISPLAY;
-import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
+import static com.android.launcher3.util.DisplayController.CHANGE_ACTIVE_SCREEN;
import static com.android.launcher3.util.DisplayController.CHANGE_DENSITY;
-import static com.android.launcher3.util.DisplayController.CHANGE_NAVIGATION_MODE;
+import static com.android.launcher3.util.DisplayController.CHANGE_SUPPORTED_BOUNDS;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_IME_SHOWING;
-import android.content.ComponentCallbacks;
import android.content.Context;
-import android.content.Intent;
-import android.content.pm.ActivityInfo;
-import android.content.res.Configuration;
import android.hardware.display.DisplayManager;
-import android.net.Uri;
-import android.os.Handler;
-import android.provider.Settings;
+import android.inputmethodservice.InputMethodService;
import android.view.Display;
-import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.android.launcher3.BaseQuickstepLauncher;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.LauncherAppState;
-import com.android.launcher3.anim.AnimatorPlaybackController;
-import com.android.launcher3.statemanager.StatefulActivity;
-import com.android.launcher3.taskbar.unfold.NonDestroyableScopedUnfoldTransitionProgressProvider;
+import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.util.DisplayController;
-import com.android.launcher3.util.SettingsCache;
-import com.android.launcher3.util.SimpleBroadcastReceiver;
-import com.android.quickstep.RecentsActivity;
-import com.android.quickstep.SystemUiProxy;
+import com.android.launcher3.util.DisplayController.Info;
+import com.android.quickstep.SysUINavigationMode;
+import com.android.quickstep.SysUINavigationMode.Mode;
import com.android.quickstep.TouchInteractionService;
-import com.android.systemui.unfold.UnfoldTransitionProgressProvider;
-import com.android.systemui.unfold.util.ScopedUnfoldTransitionProgressProvider;
-
-import java.io.PrintWriter;
/**
- * Class to manage taskbar lifecycle
+ * Class to manager taskbar lifecycle
*/
-public class TaskbarManager {
-
- private static final Uri USER_SETUP_COMPLETE_URI = Settings.Secure.getUriFor(
- Settings.Secure.USER_SETUP_COMPLETE);
-
- private static final Uri NAV_BAR_KIDS_MODE = Settings.Secure.getUriFor(
- Settings.Secure.NAV_BAR_KIDS_MODE);
+public class TaskbarManager implements DisplayController.DisplayInfoChangeListener,
+ SysUINavigationMode.NavigationModeChangeListener {
private final Context mContext;
private final DisplayController mDisplayController;
+ private final SysUINavigationMode mSysUINavigationMode;
private final TaskbarNavButtonController mNavButtonController;
- private final SettingsCache.OnChangeListener mUserSetupCompleteListener;
- private final SettingsCache.OnChangeListener mNavBarKidsModeListener;
- private final ComponentCallbacks mComponentCallbacks;
- private final SimpleBroadcastReceiver mShutdownReceiver;
-
- // The source for this provider is set when Launcher is available
- // We use 'non-destroyable' version here so the original provider won't be destroyed
- // as it is tied to the activity lifecycle, not the taskbar lifecycle.
- // It's destruction/creation will be managed by the activity.
- private final ScopedUnfoldTransitionProgressProvider mUnfoldProgressProvider =
- new NonDestroyableScopedUnfoldTransitionProgressProvider();
private TaskbarActivityContext mTaskbarActivityContext;
- private StatefulActivity mActivity;
- /**
- * Cache a copy here so we can initialize state whenever taskbar is recreated, since
- * this class does not get re-initialized w/ new taskbars.
- */
- private final TaskbarSharedState mSharedState = new TaskbarSharedState();
+ private BaseQuickstepLauncher mLauncher;
- /**
- * We use WindowManager's ComponentCallbacks() for most of the config changes, however for
- * navigation mode, that callback gets called too soon, before it's internal navigation mode
- * reflects the current one.
- * DisplayController's callback is delayed enough to get the correct nav mode value
- *
- * We also use density change here because DeviceProfile has had a chance to update it's state
- * whereas density for component callbacks registered in this class don't update DeviceProfile.
- * Confused? Me too. Make it less confusing (TODO: b/227669780)
- *
- * Flags used with {@link #mDispInfoChangeListener}
- */
- private static final int CHANGE_FLAGS = CHANGE_NAVIGATION_MODE | CHANGE_DENSITY;
- private final DisplayController.DisplayInfoChangeListener mDispInfoChangeListener;
+ private static final int CHANGE_FLAGS =
+ CHANGE_ACTIVE_SCREEN | CHANGE_DENSITY | CHANGE_SUPPORTED_BOUNDS;
private boolean mUserUnlocked = false;
public TaskbarManager(TouchInteractionService service) {
mDisplayController = DisplayController.INSTANCE.get(service);
+ mSysUINavigationMode = SysUINavigationMode.INSTANCE.get(service);
Display display =
service.getSystemService(DisplayManager.class).getDisplay(DEFAULT_DISPLAY);
- mContext = service.createWindowContext(display, TYPE_NAVIGATION_BAR_PANEL, null);
- mNavButtonController = new TaskbarNavButtonController(service,
- SystemUiProxy.INSTANCE.get(mContext), new Handler());
- mUserSetupCompleteListener = isUserSetupComplete -> recreateTaskbar();
- mNavBarKidsModeListener = isNavBarKidsMode -> recreateTaskbar();
- // TODO(b/227669780): Consolidate this w/ DisplayController callbacks
- mComponentCallbacks = new ComponentCallbacks() {
- private Configuration mOldConfig = mContext.getResources().getConfiguration();
+ mContext = service.createWindowContext(display, TYPE_APPLICATION_OVERLAY, null);
+ mNavButtonController = new TaskbarNavButtonController(service);
- @Override
- public void onConfigurationChanged(Configuration newConfig) {
- DeviceProfile dp = mUserUnlocked
- ? LauncherAppState.getIDP(mContext).getDeviceProfile(mContext)
- : null;
- int configDiff = mOldConfig.diff(newConfig);
- int configsRequiringRecreate = ActivityInfo.CONFIG_ASSETS_PATHS
- | ActivityInfo.CONFIG_LAYOUT_DIRECTION | ActivityInfo.CONFIG_UI_MODE
- | ActivityInfo.CONFIG_SCREEN_SIZE;
- boolean requiresRecreate = (configDiff & configsRequiringRecreate) != 0;
- if ((configDiff & ActivityInfo.CONFIG_SCREEN_SIZE) != 0
- && mTaskbarActivityContext != null && dp != null) {
- // Additional check since this callback gets fired multiple times w/o
- // screen size changing, or when simply rotating the device.
- DeviceProfile oldDp = mTaskbarActivityContext.getDeviceProfile();
- boolean isOrientationChange =
- (configDiff & ActivityInfo.CONFIG_ORIENTATION) != 0;
- int oldWidth = isOrientationChange ? oldDp.heightPx : oldDp.widthPx;
- int oldHeight = isOrientationChange ? oldDp.widthPx : oldDp.heightPx;
- if (dp.widthPx == oldWidth && dp.heightPx == oldHeight) {
- configDiff &= ~ActivityInfo.CONFIG_SCREEN_SIZE;
- requiresRecreate = (configDiff & configsRequiringRecreate) != 0;
- }
- }
-
- if (requiresRecreate) {
- recreateTaskbar();
- } else {
- // Config change might be handled without re-creating the taskbar
- if (mTaskbarActivityContext != null) {
- if (dp != null && dp.isTaskbarPresent) {
- mTaskbarActivityContext.updateDeviceProfile(dp);
- }
- mTaskbarActivityContext.onConfigurationChanged(configDiff);
- }
- }
- mOldConfig = newConfig;
- }
-
- @Override
- public void onLowMemory() { }
- };
- mShutdownReceiver = new SimpleBroadcastReceiver(i -> destroyExistingTaskbar());
- mDispInfoChangeListener = (context, info, flags) -> {
- if ((flags & CHANGE_FLAGS) != 0) {
- recreateTaskbar();
- }
- };
- mDisplayController.addChangeListener(mDispInfoChangeListener);
- SettingsCache.INSTANCE.get(mContext).register(USER_SETUP_COMPLETE_URI,
- mUserSetupCompleteListener);
- SettingsCache.INSTANCE.get(mContext).register(NAV_BAR_KIDS_MODE,
- mNavBarKidsModeListener);
- mContext.registerComponentCallbacks(mComponentCallbacks);
- mShutdownReceiver.register(mContext, Intent.ACTION_SHUTDOWN);
+ mDisplayController.addChangeListener(this);
+ mSysUINavigationMode.addModeChangeListener(this);
+ recreateTaskbar();
+ }
+ @Override
+ public void onNavigationModeChanged(Mode newMode) {
recreateTaskbar();
}
+ @Override
+ public void onDisplayInfoChanged(Context context, Info info, int flags) {
+ if ((flags & CHANGE_FLAGS) != 0) {
+ recreateTaskbar();
+ }
+ }
+
private void destroyExistingTaskbar() {
if (mTaskbarActivityContext != null) {
mTaskbarActivityContext.onDestroy();
@@ -184,17 +92,6 @@ public class TaskbarManager {
}
/**
- * Displays a frame of the first Launcher reveal animation.
- *
- * This should be used to run a first Launcher reveal animation whose progress matches a swipe
- * progress.
- */
- public AnimatorPlaybackController createLauncherStartFromSuwAnim(int duration) {
- return mTaskbarActivityContext == null
- ? null : mTaskbarActivityContext.createLauncherStartFromSuwAnim(duration);
- }
-
- /**
* Called when the user is unlocked
*/
public void onUserUnlocked() {
@@ -203,125 +100,61 @@ public class TaskbarManager {
}
/**
- * Sets a {@link StatefulActivity} to act as taskbar callback
+ * Sets or clears a launcher to act as taskbar callback
*/
- public void setActivity(@NonNull StatefulActivity activity) {
- if (mActivity == activity) {
- return;
- }
- mActivity = activity;
- mUnfoldProgressProvider.setSourceProvider(getUnfoldTransitionProgressProviderForActivity(
- activity));
-
+ public void setLauncher(@Nullable BaseQuickstepLauncher launcher) {
+ mLauncher = launcher;
if (mTaskbarActivityContext != null) {
- mTaskbarActivityContext.setUIController(
- createTaskbarUIControllerForActivity(mActivity));
- }
- }
-
- /**
- * Returns an {@link UnfoldTransitionProgressProvider} to use while the given StatefulActivity
- * is active.
- */
- private UnfoldTransitionProgressProvider getUnfoldTransitionProgressProviderForActivity(
- StatefulActivity activity) {
- if (activity instanceof BaseQuickstepLauncher) {
- return ((BaseQuickstepLauncher) activity).getUnfoldTransitionProgressProvider();
- }
- return null;
- }
-
- /**
- * Creates a {@link TaskbarUIController} to use while the given StatefulActivity is active.
- */
- private TaskbarUIController createTaskbarUIControllerForActivity(StatefulActivity activity) {
- if (activity instanceof BaseQuickstepLauncher) {
- if (mTaskbarActivityContext.getPackageManager().hasSystemFeature(FEATURE_PC)) {
- return new DesktopTaskbarUIController((BaseQuickstepLauncher) activity);
- }
- return new LauncherTaskbarUIController((BaseQuickstepLauncher) activity);
- }
- if (activity instanceof RecentsActivity) {
- return new FallbackTaskbarUIController((RecentsActivity) activity);
- }
- return TaskbarUIController.DEFAULT;
- }
-
- /**
- * Clears a previously set {@link StatefulActivity}
- */
- public void clearActivity(@NonNull StatefulActivity activity) {
- if (mActivity == activity) {
- mActivity = null;
- if (mTaskbarActivityContext != null) {
- mTaskbarActivityContext.setUIController(TaskbarUIController.DEFAULT);
- }
- mUnfoldProgressProvider.setSourceProvider(null);
+ mTaskbarActivityContext.setUIController(mLauncher == null
+ ? TaskbarUIController.DEFAULT
+ : new LauncherTaskbarUIController(launcher, mTaskbarActivityContext));
}
}
private void recreateTaskbar() {
destroyExistingTaskbar();
-
- DeviceProfile dp =
- mUserUnlocked ? LauncherAppState.getIDP(mContext).getDeviceProfile(mContext) : null;
-
- boolean isTaskBarEnabled = dp != null && dp.isTaskbarPresent;
-
- if (!isTaskBarEnabled) {
- SystemUiProxy.INSTANCE.get(mContext)
- .notifyTaskbarStatus(/* visible */ false, /* stashed */ false);
+ if (!FeatureFlags.ENABLE_TASKBAR.get()) {
return;
}
-
- mTaskbarActivityContext = new TaskbarActivityContext(mContext, dp, mNavButtonController,
- mUnfoldProgressProvider);
-
- mTaskbarActivityContext.init(mSharedState);
- if (mActivity != null) {
+ if (!mUserUnlocked) {
+ return;
+ }
+ DeviceProfile dp = LauncherAppState.getIDP(mContext).getDeviceProfile(mContext);
+ if (!dp.isTaskbarPresent) {
+ return;
+ }
+ mTaskbarActivityContext = new TaskbarActivityContext(
+ mContext, dp.copy(mContext), mNavButtonController);
+ mTaskbarActivityContext.init();
+ if (mLauncher != null) {
mTaskbarActivityContext.setUIController(
- createTaskbarUIControllerForActivity(mActivity));
+ new LauncherTaskbarUIController(mLauncher, mTaskbarActivityContext));
}
}
+ /**
+ * See {@link com.android.systemui.shared.system.QuickStepContract.SystemUiStateFlags}
+ * @param systemUiStateFlags The latest SystemUiStateFlags
+ */
public void onSystemUiFlagsChanged(int systemUiStateFlags) {
- mSharedState.sysuiStateFlags = systemUiStateFlags;
+ boolean isImeVisible = (systemUiStateFlags & SYSUI_STATE_IME_SHOWING) != 0;
if (mTaskbarActivityContext != null) {
- mTaskbarActivityContext.updateSysuiStateFlags(systemUiStateFlags, false /* fromInit */);
+ mTaskbarActivityContext.setImeIsVisible(isImeVisible);
}
}
/**
- * Sets the flag indicating setup UI is visible
+ * When in 3 button nav, the above doesn't get called since we prevent sysui nav bar from
+ * instantiating at all, which is what's responsible for sending sysui state flags over.
+ *
+ * @param vis IME visibility flag
+ * @param backDisposition Used to determine back button behavior for software keyboard
+ * See BACK_DISPOSITION_* constants in {@link InputMethodService}
*/
- public void setSetupUIVisible(boolean isVisible) {
- mSharedState.setupUIVisible = isVisible;
+ public void updateImeStatus(int displayId, int vis, int backDisposition,
+ boolean showImeSwitcher) {
if (mTaskbarActivityContext != null) {
- mTaskbarActivityContext.setSetupUIVisible(isVisible);
- }
- }
-
- public void onRotationProposal(int rotation, boolean isValid) {
- if (mTaskbarActivityContext != null) {
- mTaskbarActivityContext.onRotationProposal(rotation, isValid);
- }
- }
-
- public void disableNavBarElements(int displayId, int state1, int state2, boolean animate) {
- if (mTaskbarActivityContext != null) {
- mTaskbarActivityContext.disableNavBarElements(displayId, state1, state2, animate);
- }
- }
-
- public void onSystemBarAttributesChanged(int displayId, int behavior) {
- if (mTaskbarActivityContext != null) {
- mTaskbarActivityContext.onSystemBarAttributesChanged(displayId, behavior);
- }
- }
-
- public void onNavButtonsDarkIntensityChanged(float darkIntensity) {
- if (mTaskbarActivityContext != null) {
- mTaskbarActivityContext.onNavButtonsDarkIntensityChanged(darkIntensity);
+ mTaskbarActivityContext.updateImeStatus(displayId, vis, showImeSwitcher);
}
}
@@ -330,25 +163,7 @@ public class TaskbarManager {
*/
public void destroy() {
destroyExistingTaskbar();
- mDisplayController.removeChangeListener(mDispInfoChangeListener);
- SettingsCache.INSTANCE.get(mContext).unregister(USER_SETUP_COMPLETE_URI,
- mUserSetupCompleteListener);
- SettingsCache.INSTANCE.get(mContext).unregister(NAV_BAR_KIDS_MODE,
- mNavBarKidsModeListener);
- mContext.unregisterComponentCallbacks(mComponentCallbacks);
- mContext.unregisterReceiver(mShutdownReceiver);
- }
-
- public @Nullable TaskbarActivityContext getCurrentActivityContext() {
- return mTaskbarActivityContext;
- }
-
- public void dumpLogs(String prefix, PrintWriter pw) {
- pw.println(prefix + "TaskbarManager:");
- if (mTaskbarActivityContext == null) {
- pw.println(prefix + "\tTaskbarActivityContext: null");
- } else {
- mTaskbarActivityContext.dumpLogs(prefix + "\t", pw);
- }
+ mDisplayController.removeChangeListener(this);
+ mSysUINavigationMode.removeModeChangeListener(this);
}
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarModelCallbacks.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarModelCallbacks.java
deleted file mode 100644
index 75881a31f2..0000000000
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarModelCallbacks.java
+++ /dev/null
@@ -1,217 +0,0 @@
-/*
- * Copyright (C) 2021 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.launcher3.taskbar;
-
-import android.util.SparseArray;
-import android.view.View;
-
-import com.android.launcher3.LauncherSettings.Favorites;
-import com.android.launcher3.model.BgDataModel;
-import com.android.launcher3.model.BgDataModel.FixedContainerItems;
-import com.android.launcher3.model.data.AppInfo;
-import com.android.launcher3.model.data.ItemInfo;
-import com.android.launcher3.model.data.WorkspaceItemInfo;
-import com.android.launcher3.util.ComponentKey;
-import com.android.launcher3.util.IntArray;
-import com.android.launcher3.util.IntSet;
-import com.android.launcher3.util.ItemInfoMatcher;
-import com.android.launcher3.util.LauncherBindableItemsContainer;
-
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.function.Predicate;
-
-/**
- * Launcher model Callbacks for rendering taskbar.
- */
-public class TaskbarModelCallbacks implements
- BgDataModel.Callbacks, LauncherBindableItemsContainer {
-
- private final SparseArray<ItemInfo> mHotseatItems = new SparseArray<>();
- private List<ItemInfo> mPredictedItems = Collections.emptyList();
-
- private final TaskbarActivityContext mContext;
- private final TaskbarView mContainer;
-
- // Initialized in init.
- private TaskbarControllers mControllers;
-
- public TaskbarModelCallbacks(
- TaskbarActivityContext context, TaskbarView container) {
- mContext = context;
- mContainer = container;
- }
-
- public void init(TaskbarControllers controllers) {
- mControllers = controllers;
- }
-
- @Override
- public void startBinding() {
- mContext.setBindingItems(true);
- mHotseatItems.clear();
- mPredictedItems = Collections.emptyList();
- }
-
- @Override
- public void finishBindingItems(IntSet pagesBoundFirst) {
- mContext.setBindingItems(false);
- commitItemsToUI();
- }
-
- @Override
- public void bindAppsAdded(IntArray newScreens, ArrayList<ItemInfo> addNotAnimated,
- ArrayList<ItemInfo> addAnimated) {
- boolean add1 = handleItemsAdded(addNotAnimated);
- boolean add2 = handleItemsAdded(addAnimated);
- if (add1 || add2) {
- commitItemsToUI();
- }
- }
-
- @Override
- public void bindItems(List<ItemInfo> shortcuts, boolean forceAnimateIcons) {
- if (handleItemsAdded(shortcuts)) {
- commitItemsToUI();
- }
- }
-
- private boolean handleItemsAdded(List<ItemInfo> items) {
- boolean modified = false;
- for (ItemInfo item : items) {
- if (item.container == Favorites.CONTAINER_HOTSEAT) {
- mHotseatItems.put(item.screenId, item);
- modified = true;
- }
- }
- return modified;
- }
-
-
- @Override
- public void bindWorkspaceItemsChanged(List<WorkspaceItemInfo> updated) {
- updateWorkspaceItems(updated, mContext);
- }
-
- @Override
- public void bindRestoreItemsChange(HashSet<ItemInfo> updates) {
- updateRestoreItems(updates, mContext);
- }
-
- @Override
- public void mapOverItems(ItemOperator op) {
- final int itemCount = mContainer.getChildCount();
- for (int itemIdx = 0; itemIdx < itemCount; itemIdx++) {
- View item = mContainer.getChildAt(itemIdx);
- if (op.evaluate((ItemInfo) item.getTag(), item)) {
- return;
- }
- }
- }
-
- @Override
- public void bindWorkspaceComponentsRemoved(Predicate<ItemInfo> matcher) {
- if (handleItemsRemoved(matcher)) {
- commitItemsToUI();
- }
- }
-
- private boolean handleItemsRemoved(Predicate<ItemInfo> matcher) {
- boolean modified = false;
- for (int i = mHotseatItems.size() - 1; i >= 0; i--) {
- if (matcher.test(mHotseatItems.valueAt(i))) {
- modified = true;
- mHotseatItems.removeAt(i);
- }
- }
- return modified;
- }
-
- @Override
- public void bindItemsModified(List<ItemInfo> items) {
- boolean removed = handleItemsRemoved(ItemInfoMatcher.ofItems(items));
- boolean added = handleItemsAdded(items);
- if (removed || added) {
- commitItemsToUI();
- }
- }
-
- @Override
- public void bindExtraContainerItems(FixedContainerItems item) {
- if (item.containerId == Favorites.CONTAINER_HOTSEAT_PREDICTION) {
- mPredictedItems = item.items;
- commitItemsToUI();
- } else if (item.containerId == Favorites.CONTAINER_PREDICTION) {
- mControllers.taskbarAllAppsController.setPredictedApps(item.items);
- }
- }
-
- private void commitItemsToUI() {
- if (mContext.isBindingItems()) {
- return;
- }
-
- ItemInfo[] hotseatItemInfos =
- new ItemInfo[mContext.getDeviceProfile().numShownHotseatIcons];
- int predictionSize = mPredictedItems.size();
- int predictionNextIndex = 0;
-
- boolean isHotseatEmpty = true;
- for (int i = 0; i < hotseatItemInfos.length; i++) {
- hotseatItemInfos[i] = mHotseatItems.get(i);
- if (hotseatItemInfos[i] == null && predictionNextIndex < predictionSize) {
- hotseatItemInfos[i] = mPredictedItems.get(predictionNextIndex);
- hotseatItemInfos[i].screenId = i;
- predictionNextIndex++;
- }
- if (hotseatItemInfos[i] != null) {
- isHotseatEmpty = false;
- }
- }
- mContainer.updateHotseatItems(hotseatItemInfos);
-
- final boolean finalIsHotseatEmpty = isHotseatEmpty;
- mControllers.runAfterInit(() -> {
- mControllers.taskbarStashController.updateStateForFlag(
- TaskbarStashController.FLAG_STASHED_IN_APP_EMPTY, finalIsHotseatEmpty);
- mControllers.taskbarStashController.applyState();
- });
- }
-
- @Override
- public void bindDeepShortcutMap(HashMap<ComponentKey, Integer> deepShortcutMapCopy) {
- mControllers.taskbarPopupController.setDeepShortcutMap(deepShortcutMapCopy);
- }
-
- @Override
- public void bindAllApplications(AppInfo[] apps, int flags) {
- mControllers.taskbarAllAppsController.setApps(apps, flags);
- }
-
- protected void dumpLogs(String prefix, PrintWriter pw) {
- pw.println(prefix + "TaskbarModelCallbacks:");
-
- pw.println(String.format("%s\thotseat items count=%s", prefix, mHotseatItems.size()));
- if (mPredictedItems != null) {
- pw.println(
- String.format("%s\tpredicted items count=%s", prefix, mPredictedItems.size()));
- }
- }
-}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarNavButtonController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarNavButtonController.java
index 4ff0649440..3b5afad691 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarNavButtonController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarNavButtonController.java
@@ -16,38 +16,17 @@
package com.android.launcher3.taskbar;
-import static com.android.internal.app.AssistUtils.INVOCATION_TYPE_HOME_BUTTON_LONG_PRESS;
-import static com.android.internal.app.AssistUtils.INVOCATION_TYPE_KEY;
-import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_RECENTS;
-import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASKBAR_A11Y_BUTTON_LONGPRESS;
-import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASKBAR_A11Y_BUTTON_TAP;
-import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASKBAR_BACK_BUTTON_LONGPRESS;
-import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASKBAR_BACK_BUTTON_TAP;
-import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASKBAR_HOME_BUTTON_LONGPRESS;
-import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASKBAR_HOME_BUTTON_TAP;
-import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASKBAR_IME_SWITCHER_BUTTON_TAP;
-import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASKBAR_OVERVIEW_BUTTON_LONGPRESS;
-import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASKBAR_OVERVIEW_BUTTON_TAP;
-import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_SCREEN_PINNING;
+import static android.view.Display.DEFAULT_DISPLAY;
-import android.os.Bundle;
-import android.os.Handler;
-import android.util.Log;
+import android.content.Intent;
+import android.view.inputmethod.InputMethodManager;
import androidx.annotation.IntDef;
-import androidx.annotation.Nullable;
-import androidx.annotation.StringRes;
-import com.android.launcher3.R;
-import com.android.launcher3.logging.StatsLogManager;
-import com.android.launcher3.testing.TestLogging;
-import com.android.launcher3.testing.TestProtocol;
import com.android.quickstep.OverviewCommandHelper;
import com.android.quickstep.SystemUiProxy;
-import com.android.quickstep.TaskUtils;
import com.android.quickstep.TouchInteractionService;
-import java.io.PrintWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -55,35 +34,17 @@ import java.lang.annotation.RetentionPolicy;
* Controller for 3 button mode in the taskbar.
* Handles all the functionality of the various buttons, making/routing the right calls into
* launcher or sysui/system.
+ *
+ * TODO: Create callbacks to hook into UI layer since state will change for more context buttons/
+ * assistant invocation.
*/
-public class TaskbarNavButtonController implements TaskbarControllers.LoggableTaskbarController {
-
- /** Allow some time in between the long press for back and recents. */
- static final int SCREEN_PIN_LONG_PRESS_THRESHOLD = 200;
- static final int SCREEN_PIN_LONG_PRESS_RESET = SCREEN_PIN_LONG_PRESS_THRESHOLD + 100;
- private static final String TAG = TaskbarNavButtonController.class.getSimpleName();
-
- private long mLastScreenPinLongPress;
- private boolean mScreenPinned;
-
- @Override
- public void dumpLogs(String prefix, PrintWriter pw) {
- pw.println(prefix + "TaskbarNavButtonController:");
-
- pw.println(String.format(
- "%s\tmLastScreenPinLongPress=%dms", prefix, mLastScreenPinLongPress));
- pw.println(String.format("%s\tmScreenPinned=%b", prefix, mScreenPinned));
- }
-
+public class TaskbarNavButtonController {
@Retention(RetentionPolicy.SOURCE)
@IntDef(value = {
BUTTON_BACK,
BUTTON_HOME,
BUTTON_RECENTS,
- BUTTON_IME_SWITCH,
- BUTTON_A11Y,
- BUTTON_QUICK_SETTINGS,
- BUTTON_NOTIFICATIONS,
+ BUTTON_IME_SWITCH
})
public @interface TaskbarButton {}
@@ -92,211 +53,48 @@ public class TaskbarNavButtonController implements TaskbarControllers.LoggableTa
static final int BUTTON_HOME = BUTTON_BACK << 1;
static final int BUTTON_RECENTS = BUTTON_HOME << 1;
static final int BUTTON_IME_SWITCH = BUTTON_RECENTS << 1;
- static final int BUTTON_A11Y = BUTTON_IME_SWITCH << 1;
- static final int BUTTON_QUICK_SETTINGS = BUTTON_A11Y << 1;
- static final int BUTTON_NOTIFICATIONS = BUTTON_QUICK_SETTINGS << 1;
-
- private static final int SCREEN_UNPIN_COMBO = BUTTON_BACK | BUTTON_RECENTS;
- private int mLongPressedButtons = 0;
private final TouchInteractionService mService;
- private final SystemUiProxy mSystemUiProxy;
- private final Handler mHandler;
- @Nullable private StatsLogManager mStatsLogManager;
- private final Runnable mResetLongPress = this::resetScreenUnpin;
-
- public TaskbarNavButtonController(TouchInteractionService service,
- SystemUiProxy systemUiProxy, Handler handler) {
+ public TaskbarNavButtonController(TouchInteractionService service) {
mService = service;
- mSystemUiProxy = systemUiProxy;
- mHandler = handler;
}
public void onButtonClick(@TaskbarButton int buttonType) {
switch (buttonType) {
case BUTTON_BACK:
- logEvent(LAUNCHER_TASKBAR_BACK_BUTTON_TAP);
executeBack();
break;
case BUTTON_HOME:
- logEvent(LAUNCHER_TASKBAR_HOME_BUTTON_TAP);
navigateHome();
break;
case BUTTON_RECENTS:
- logEvent(LAUNCHER_TASKBAR_OVERVIEW_BUTTON_TAP);
- navigateToOverview();
+ navigateToOverview();;
break;
case BUTTON_IME_SWITCH:
- logEvent(LAUNCHER_TASKBAR_IME_SWITCHER_BUTTON_TAP);
showIMESwitcher();
break;
- case BUTTON_A11Y:
- logEvent(LAUNCHER_TASKBAR_A11Y_BUTTON_TAP);
- notifyA11yClick(false /* longClick */);
- break;
- case BUTTON_QUICK_SETTINGS:
- showQuickSettings();
- break;
- case BUTTON_NOTIFICATIONS:
- showNotifications();
- break;
}
}
- public boolean onButtonLongClick(@TaskbarButton int buttonType) {
- switch (buttonType) {
- case BUTTON_HOME:
- logEvent(LAUNCHER_TASKBAR_HOME_BUTTON_LONGPRESS);
- startAssistant();
- return true;
- case BUTTON_A11Y:
- logEvent(LAUNCHER_TASKBAR_A11Y_BUTTON_LONGPRESS);
- notifyA11yClick(true /* longClick */);
- return true;
- case BUTTON_BACK:
- logEvent(LAUNCHER_TASKBAR_BACK_BUTTON_LONGPRESS);
- return backRecentsLongpress(buttonType);
- case BUTTON_RECENTS:
- logEvent(LAUNCHER_TASKBAR_OVERVIEW_BUTTON_LONGPRESS);
- return backRecentsLongpress(buttonType);
- case BUTTON_IME_SWITCH:
- default:
- return false;
- }
- }
-
- public @StringRes int getButtonContentDescription(@TaskbarButton int buttonType) {
- switch (buttonType) {
- case BUTTON_HOME:
- return R.string.taskbar_button_home;
- case BUTTON_A11Y:
- return R.string.taskbar_button_a11y;
- case BUTTON_BACK:
- return R.string.taskbar_button_back;
- case BUTTON_IME_SWITCH:
- return R.string.taskbar_button_ime_switcher;
- case BUTTON_RECENTS:
- return R.string.taskbar_button_recents;
- case BUTTON_NOTIFICATIONS:
- return R.string.taskbar_button_notifications;
- case BUTTON_QUICK_SETTINGS:
- return R.string.taskbar_button_quick_settings;
- default:
- return 0;
- }
- }
-
- private boolean backRecentsLongpress(@TaskbarButton int buttonType) {
- mLongPressedButtons |= buttonType;
- return determineScreenUnpin();
- }
-
- /**
- * Checks if the user has long pressed back and recents buttons
- * "together" (within {@link #SCREEN_PIN_LONG_PRESS_THRESHOLD})ms
- * If so, then requests the system to turn off screen pinning.
- *
- * @return true if the long press is a valid user action in attempting to unpin an app
- * Will always return {@code false} when screen pinning is not active.
- * NOTE: Returning true does not mean that screen pinning has stopped
- */
- private boolean determineScreenUnpin() {
- long timeNow = System.currentTimeMillis();
- if (!mScreenPinned) {
- return false;
- }
-
- if (mLastScreenPinLongPress == 0) {
- // First button long press registered, just mark time and wait for second button press
- mLastScreenPinLongPress = System.currentTimeMillis();
- mHandler.postDelayed(mResetLongPress, SCREEN_PIN_LONG_PRESS_RESET);
- return true;
- }
-
- if ((timeNow - mLastScreenPinLongPress) > SCREEN_PIN_LONG_PRESS_THRESHOLD) {
- // Too long in-between presses, reset the clock
- resetScreenUnpin();
- return false;
- }
-
- if ((mLongPressedButtons & SCREEN_UNPIN_COMBO) == SCREEN_UNPIN_COMBO) {
- // Hooray! They did it (finally...)
- mSystemUiProxy.stopScreenPinning();
- mHandler.removeCallbacks(mResetLongPress);
- resetScreenUnpin();
- }
- return true;
- }
-
- private void resetScreenUnpin() {
- mLongPressedButtons = 0;
- mLastScreenPinLongPress = 0;
- }
-
- public void updateSysuiFlags(int sysuiFlags) {
- mScreenPinned = (sysuiFlags & SYSUI_STATE_SCREEN_PINNING) != 0;
- }
-
- public void init(TaskbarControllers taskbarControllers) {
- mStatsLogManager = taskbarControllers.getTaskbarActivityContext().getStatsLogManager();
- }
-
- public void onDestroy() {
- mStatsLogManager = null;
- }
-
- private void logEvent(StatsLogManager.LauncherEvent event) {
- if (mStatsLogManager == null) {
- Log.w(TAG, "No stats log manager to log taskbar button event");
- return;
- }
- mStatsLogManager.logger().log(event);
- }
-
private void navigateHome() {
- mService.getOverviewCommandHelper().addCommand(OverviewCommandHelper.TYPE_HOME);
+ mService.startActivity(new Intent(Intent.ACTION_MAIN)
+ .addCategory(Intent.CATEGORY_HOME)
+ .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
}
private void navigateToOverview() {
- if (mScreenPinned) {
- return;
- }
- TestLogging.recordEvent(TestProtocol.SEQUENCE_MAIN, "onOverviewToggle");
- TaskUtils.closeSystemWindowsAsync(CLOSE_SYSTEM_WINDOWS_REASON_RECENTS);
- mService.getOverviewCommandHelper().addCommand(OverviewCommandHelper.TYPE_TOGGLE);
+ mService.getOverviewCommandHelper()
+ .addCommand(OverviewCommandHelper.TYPE_SHOW);
}
private void executeBack() {
- mSystemUiProxy.onBackPressed();
+ SystemUiProxy.INSTANCE.getNoCreate().onBackPressed();
}
private void showIMESwitcher() {
- mSystemUiProxy.onImeSwitcherPressed();
- }
-
- private void notifyA11yClick(boolean longClick) {
- if (longClick) {
- mSystemUiProxy.notifyAccessibilityButtonLongClicked();
- } else {
- mSystemUiProxy.notifyAccessibilityButtonClicked(mService.getDisplayId());
- }
- }
-
- private void startAssistant() {
- if (mScreenPinned) {
- return;
- }
- Bundle args = new Bundle();
- args.putInt(INVOCATION_TYPE_KEY, INVOCATION_TYPE_HOME_BUTTON_LONG_PRESS);
- mSystemUiProxy.startAssistant(args);
- }
-
- private void showQuickSettings() {
- mSystemUiProxy.toggleNotificationPanel();
- }
-
- private void showNotifications() {
- mSystemUiProxy.toggleNotificationPanel();
+ mService.getSystemService(InputMethodManager.class)
+ .showInputMethodPickerFromSystem(true /* showAuxiliarySubtypes */,
+ DEFAULT_DISPLAY);
}
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarPopupController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarPopupController.java
deleted file mode 100644
index 7b4501a003..0000000000
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarPopupController.java
+++ /dev/null
@@ -1,289 +0,0 @@
-/*
- * Copyright (C) 2021 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.launcher3.taskbar;
-
-import android.content.Intent;
-import android.content.pm.LauncherApps;
-import android.graphics.Point;
-import android.view.MotionEvent;
-import android.view.View;
-
-import androidx.annotation.NonNull;
-
-import com.android.launcher3.AbstractFloatingView;
-import com.android.launcher3.BubbleTextView;
-import com.android.launcher3.LauncherSettings;
-import com.android.launcher3.R;
-import com.android.launcher3.Utilities;
-import com.android.launcher3.dot.FolderDotInfo;
-import com.android.launcher3.folder.Folder;
-import com.android.launcher3.folder.FolderIcon;
-import com.android.launcher3.model.data.FolderInfo;
-import com.android.launcher3.model.data.ItemInfo;
-import com.android.launcher3.model.data.WorkspaceItemInfo;
-import com.android.launcher3.notification.NotificationListener;
-import com.android.launcher3.popup.PopupContainerWithArrow;
-import com.android.launcher3.popup.PopupDataProvider;
-import com.android.launcher3.popup.PopupLiveUpdateHandler;
-import com.android.launcher3.popup.SystemShortcut;
-import com.android.launcher3.shortcuts.DeepShortcutView;
-import com.android.launcher3.util.ComponentKey;
-import com.android.launcher3.util.LauncherBindableItemsContainer;
-import com.android.launcher3.util.PackageUserKey;
-import com.android.launcher3.util.ShortcutUtil;
-import com.android.launcher3.util.SplitConfigurationOptions.SplitPositionOption;
-import com.android.launcher3.views.ActivityContext;
-import com.android.quickstep.SystemUiProxy;
-
-import java.io.PrintWriter;
-import java.util.HashMap;
-import java.util.Objects;
-import java.util.function.Predicate;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-
-/**
- * Implements interfaces required to show and allow interacting with a PopupContainerWithArrow.
- */
-public class TaskbarPopupController implements TaskbarControllers.LoggableTaskbarController {
-
- private static final SystemShortcut.Factory<BaseTaskbarContext>
- APP_INFO = SystemShortcut.AppInfo::new;
-
- private final TaskbarActivityContext mContext;
- private final PopupDataProvider mPopupDataProvider;
-
- // Initialized in init.
- private TaskbarControllers mControllers;
-
- public TaskbarPopupController(TaskbarActivityContext context) {
- mContext = context;
- mPopupDataProvider = new PopupDataProvider(this::updateNotificationDots);
- }
-
- public void init(TaskbarControllers controllers) {
- mControllers = controllers;
-
- NotificationListener.addNotificationsChangedListener(mPopupDataProvider);
- }
-
- public void onDestroy() {
- NotificationListener.removeNotificationsChangedListener(mPopupDataProvider);
- }
-
- @NonNull
- public PopupDataProvider getPopupDataProvider() {
- return mPopupDataProvider;
- }
-
- public void setDeepShortcutMap(HashMap<ComponentKey, Integer> deepShortcutMapCopy) {
- mPopupDataProvider.setDeepShortcutMap(deepShortcutMapCopy);
- }
-
- private void updateNotificationDots(Predicate<PackageUserKey> updatedDots) {
- final PackageUserKey packageUserKey = new PackageUserKey(null, null);
- Predicate<ItemInfo> matcher = info -> !packageUserKey.updateFromItemInfo(info)
- || updatedDots.test(packageUserKey);
-
- LauncherBindableItemsContainer.ItemOperator op = (info, v) -> {
- if (info instanceof WorkspaceItemInfo && v instanceof BubbleTextView) {
- if (matcher.test(info)) {
- ((BubbleTextView) v).applyDotState(info, true /* animate */);
- }
- } else if (info instanceof FolderInfo && v instanceof FolderIcon) {
- FolderInfo fi = (FolderInfo) info;
- if (fi.contents.stream().anyMatch(matcher)) {
- FolderDotInfo folderDotInfo = new FolderDotInfo();
- for (WorkspaceItemInfo si : fi.contents) {
- folderDotInfo.addDotInfo(mPopupDataProvider.getDotInfoForItem(si));
- }
- ((FolderIcon) v).setDotInfo(folderDotInfo);
- }
- }
-
- // process all the shortcuts
- return false;
- };
-
- mControllers.taskbarViewController.mapOverItems(op);
- Folder folder = Folder.getOpen(mContext);
- if (folder != null) {
- folder.iterateOverItems(op);
- }
- }
-
- /**
- * Shows the notifications and deep shortcuts associated with a Taskbar {@param icon}.
- * @return the container if shown or null.
- */
- public PopupContainerWithArrow<BaseTaskbarContext> showForIcon(BubbleTextView icon) {
- BaseTaskbarContext context = ActivityContext.lookupContext(icon.getContext());
- if (PopupContainerWithArrow.getOpen(context) != null) {
- // There is already an items container open, so don't open this one.
- icon.clearFocus();
- return null;
- }
- ItemInfo item = (ItemInfo) icon.getTag();
- if (!ShortcutUtil.supportsShortcuts(item)) {
- return null;
- }
-
- final PopupContainerWithArrow<BaseTaskbarContext> container =
- (PopupContainerWithArrow<BaseTaskbarContext>) context.getLayoutInflater().inflate(
- R.layout.popup_container, context.getDragLayer(), false);
- container.addOnAttachStateChangeListener(
- new PopupLiveUpdateHandler<BaseTaskbarContext>(context, container) {
- @Override
- protected void showPopupContainerForIcon(BubbleTextView originalIcon) {
- showForIcon(originalIcon);
- }
- });
- // TODO (b/198438631): configure for taskbar/context
- container.setPopupItemDragHandler(new TaskbarPopupItemDragHandler());
- mControllers.taskbarDragController.addDragListener(container);
-
- container.populateAndShow(icon,
- mPopupDataProvider.getShortcutCountForItem(item),
- mPopupDataProvider.getNotificationKeysForItem(item),
- // TODO (b/198438631): add support for INSTALL shortcut factory
- getSystemShortcuts()
- .map(s -> s.getShortcut(context, item, icon))
- .filter(Objects::nonNull)
- .collect(Collectors.toList()));
- container.requestFocus();
-
- // Make focusable to receive back events
- context.onPopupVisibilityChanged(true);
- container.setOnCloseCallback(() -> {
- context.getDragLayer().post(() -> context.onPopupVisibilityChanged(false));
- container.setOnCloseCallback(null);
- });
-
- return container;
- }
-
- // Create a Stream of all applicable system shortcuts
- // TODO(b/227800345): Add "Split bottom" option when tablet is in portrait mode.
- private Stream<SystemShortcut.Factory> getSystemShortcuts() {
- // concat a Stream of split options with a Stream of APP_INFO
- return Stream.concat(
- Utilities.getSplitPositionOptions(mContext.getDeviceProfile())
- .stream()
- .map(this::createSplitShortcutFactory),
- Stream.of(APP_INFO)
- );
- }
-
- @Override
- public void dumpLogs(String prefix, PrintWriter pw) {
- pw.println(prefix + "TaskbarPopupController:");
-
- mPopupDataProvider.dump(prefix + "\t", pw);
- }
-
- private class TaskbarPopupItemDragHandler implements
- PopupContainerWithArrow.PopupItemDragHandler {
-
- protected final Point mIconLastTouchPos = new Point();
-
- TaskbarPopupItemDragHandler() {}
-
- @Override
- public boolean onTouch(View view, MotionEvent ev) {
- // Touched a shortcut, update where it was touched so we can drag from there on
- // long click.
- switch (ev.getAction()) {
- case MotionEvent.ACTION_DOWN:
- case MotionEvent.ACTION_MOVE:
- mIconLastTouchPos.set((int) ev.getX(), (int) ev.getY());
- break;
- }
- return false;
- }
-
- @Override
- public boolean onLongClick(View v) {
- // Return early if not the correct view
- if (!(v.getParent() instanceof DeepShortcutView)) return false;
-
- DeepShortcutView sv = (DeepShortcutView) v.getParent();
- sv.setWillDrawIcon(false);
-
- // Move the icon to align with the center-top of the touch point
- Point iconShift = new Point();
- iconShift.x = mIconLastTouchPos.x - sv.getIconCenter().x;
- iconShift.y = mIconLastTouchPos.y - mContext.getDeviceProfile().iconSizePx;
-
- ((TaskbarDragController) ActivityContext.lookupContext(
- v.getContext()).getDragController()).startDragOnLongClick(sv, iconShift);
-
- return false;
- }
- }
-
- /**
- * Creates a factory function representing a single "split position" menu item ("Split left,"
- * "Split right," or "Split top").
- * @param position A SplitPositionOption representing whether we are splitting top, left, or
- * right.
- * @return A factory function to be used in populating the long-press menu.
- */
- private SystemShortcut.Factory<BaseTaskbarContext> createSplitShortcutFactory(
- SplitPositionOption position) {
- return (context, itemInfo, originalView) -> new TaskbarSplitShortcut(context, itemInfo,
- originalView, position);
- }
-
- /**
- * A single menu item ("Split left," "Split right," or "Split top") that executes a split
- * from the taskbar, as if the user performed a drag and drop split.
- * Includes an onClick method that initiates the actual split.
- */
- private static class TaskbarSplitShortcut extends SystemShortcut<BaseTaskbarContext> {
- private final SplitPositionOption mPosition;
-
- TaskbarSplitShortcut(BaseTaskbarContext context, ItemInfo itemInfo, View originalView,
- SplitPositionOption position) {
- super(position.iconResId, position.textResId, context, itemInfo, originalView);
- mPosition = position;
- }
-
- @Override
- public void onClick(View view) {
- AbstractFloatingView.closeAllOpenViews(mTarget);
-
- if (mItemInfo.itemType == LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT) {
- WorkspaceItemInfo workspaceItemInfo = (WorkspaceItemInfo) mItemInfo;
- SystemUiProxy.INSTANCE.get(mTarget).startShortcut(
- workspaceItemInfo.getIntent().getPackage(),
- workspaceItemInfo.getDeepShortcutId(),
- mPosition.stagePosition,
- null,
- workspaceItemInfo.user);
- } else {
- SystemUiProxy.INSTANCE.get(mTarget).startIntent(
- mTarget.getSystemService(LauncherApps.class).getMainActivityLaunchIntent(
- mItemInfo.getIntent().getComponent(),
- null,
- mItemInfo.user),
- new Intent(),
- mPosition.stagePosition,
- null);
- }
- }
- }
-}
-
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarScrimView.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarScrimView.java
deleted file mode 100644
index 1d3757fca2..0000000000
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarScrimView.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2021 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.launcher3.taskbar;
-
-import android.content.Context;
-import android.graphics.Canvas;
-import android.util.AttributeSet;
-import android.view.View;
-
-import com.android.launcher3.views.ActivityContext;
-
-/**
- * View that handles scrimming the taskbar and the inverted corners it draws. The scrim is used
- * when bubbles is expanded.
- */
-public class TaskbarScrimView extends View {
- private final TaskbarBackgroundRenderer mRenderer;
-
- private boolean mShowScrim;
-
- public TaskbarScrimView(Context context) {
- this(context, null);
- }
-
- public TaskbarScrimView(Context context, AttributeSet attrs) {
- this(context, attrs, 0);
- }
-
- public TaskbarScrimView(Context context, AttributeSet attrs, int defStyleAttr) {
- this(context, attrs, defStyleAttr, 0);
- }
-
- public TaskbarScrimView(Context context, AttributeSet attrs, int defStyleAttr,
- int defStyleRes) {
- super(context, attrs, defStyleAttr, defStyleRes);
- mRenderer = new TaskbarBackgroundRenderer(ActivityContext.lookupContext(context));
- mRenderer.getPaint().setColor(getResources().getColor(
- android.R.color.system_neutral1_1000));
- }
-
- @Override
- protected void onDraw(Canvas canvas) {
- super.onDraw(canvas);
-
- if (mShowScrim) {
- mRenderer.draw(canvas);
- }
- }
-
- /**
- * Sets the alpha of the taskbar scrim.
- * @param alpha the alpha of the scrim.
- */
- protected void setScrimAlpha(float alpha) {
- mShowScrim = alpha > 0f;
- mRenderer.getPaint().setAlpha((int) (alpha * 255));
- invalidate();
- }
-}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarScrimViewController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarScrimViewController.java
deleted file mode 100644
index 58ace17787..0000000000
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarScrimViewController.java
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Copyright (C) 2021 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.launcher3.taskbar;
-
-import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_BUBBLES_EXPANDED;
-import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_BUBBLES_MANAGE_MENU_EXPANDED;
-
-import android.animation.ObjectAnimator;
-import android.view.animation.Interpolator;
-import android.view.animation.PathInterpolator;
-
-import com.android.quickstep.AnimatedFloat;
-import com.android.quickstep.SystemUiProxy;
-
-import java.io.PrintWriter;
-
-/**
- * Handles properties/data collection, and passes the results to {@link TaskbarScrimView} to render.
- */
-public class TaskbarScrimViewController implements TaskbarControllers.LoggableTaskbarController {
-
- private static final float SCRIM_ALPHA = 0.6f;
-
- private static final Interpolator SCRIM_ALPHA_IN = new PathInterpolator(0.4f, 0f, 1f, 1f);
- private static final Interpolator SCRIM_ALPHA_OUT = new PathInterpolator(0f, 0f, 0.8f, 1f);
-
- private final TaskbarActivityContext mActivity;
- private final TaskbarScrimView mScrimView;
-
- // Alpha property for the scrim.
- private final AnimatedFloat mScrimAlpha = new AnimatedFloat(this::updateScrimAlpha);
-
- // Initialized in init.
- private TaskbarControllers mControllers;
-
- public TaskbarScrimViewController(TaskbarActivityContext activity, TaskbarScrimView scrimView) {
- mActivity = activity;
- mScrimView = scrimView;
- }
-
- /**
- * Initializes the controller
- */
- public void init(TaskbarControllers controllers) {
- mControllers = controllers;
- }
-
- /**
- * Updates the scrim state based on the flags.
- */
- public void updateStateForSysuiFlags(int stateFlags, boolean skipAnim) {
- final boolean bubblesExpanded = (stateFlags & SYSUI_STATE_BUBBLES_EXPANDED) != 0;
- final boolean manageMenuExpanded =
- (stateFlags & SYSUI_STATE_BUBBLES_MANAGE_MENU_EXPANDED) != 0;
- final boolean showScrim = !mControllers.navbarButtonsViewController.isImeVisible()
- && bubblesExpanded && mControllers.taskbarStashController.isInAppAndNotStashed();
- final float scrimAlpha = manageMenuExpanded
- // When manage menu shows there's the first scrim and second scrim so figure out
- // what the total transparency would be.
- ? (SCRIM_ALPHA + (SCRIM_ALPHA * (1 - SCRIM_ALPHA)))
- : showScrim ? SCRIM_ALPHA : 0;
- showScrim(showScrim, scrimAlpha, skipAnim);
- }
-
- private void showScrim(boolean showScrim, float alpha, boolean skipAnim) {
- mScrimView.setOnClickListener(showScrim ? (view) -> onClick() : null);
- mScrimView.setClickable(showScrim);
- ObjectAnimator anim = mScrimAlpha.animateToValue(showScrim ? alpha : 0);
- anim.setInterpolator(showScrim ? SCRIM_ALPHA_IN : SCRIM_ALPHA_OUT);
- anim.start();
- if (skipAnim) {
- anim.end();
- }
- }
-
- private void updateScrimAlpha() {
- mScrimView.setScrimAlpha(mScrimAlpha.value);
- }
-
- private void onClick() {
- SystemUiProxy.INSTANCE.get(mActivity).onBackPressed();
- }
-
- @Override
- public void dumpLogs(String prefix, PrintWriter pw) {
- pw.println(prefix + "TaskbarScrimViewController:");
-
- pw.println(String.format("%s\tmScrimAlpha.value=%.2f", prefix, mScrimAlpha.value));
- }
-}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarShortcutMenuAccessibilityDelegate.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarShortcutMenuAccessibilityDelegate.java
deleted file mode 100644
index f131595126..0000000000
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarShortcutMenuAccessibilityDelegate.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright (C) 2021 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.launcher3.taskbar;
-
-import static com.android.launcher3.accessibility.LauncherAccessibilityDelegate.DEEP_SHORTCUTS;
-import static com.android.launcher3.accessibility.LauncherAccessibilityDelegate.SHORTCUTS_AND_NOTIFICATIONS;
-import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT;
-import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT;
-
-import android.content.Intent;
-import android.content.pm.LauncherApps;
-import android.view.KeyEvent;
-import android.view.View;
-
-import com.android.launcher3.BubbleTextView;
-import com.android.launcher3.LauncherSettings;
-import com.android.launcher3.R;
-import com.android.launcher3.accessibility.BaseAccessibilityDelegate;
-import com.android.launcher3.config.FeatureFlags;
-import com.android.launcher3.model.data.ItemInfo;
-import com.android.launcher3.model.data.WorkspaceItemInfo;
-import com.android.launcher3.notification.NotificationListener;
-import com.android.launcher3.util.ShortcutUtil;
-import com.android.quickstep.SystemUiProxy;
-
-import java.util.List;
-
-/**
- * Accessibility delegate for the Taskbar. This provides an accessible interface for taskbar
- * features.
- */
-public class TaskbarShortcutMenuAccessibilityDelegate
- extends BaseAccessibilityDelegate<TaskbarActivityContext> {
-
- public static final int MOVE_TO_TOP_OR_LEFT = R.id.action_move_to_top_or_left;
- public static final int MOVE_TO_BOTTOM_OR_RIGHT = R.id.action_move_to_bottom_or_right;
-
- private final LauncherApps mLauncherApps;
-
- public TaskbarShortcutMenuAccessibilityDelegate(TaskbarActivityContext context) {
- super(context);
- mLauncherApps = context.getSystemService(LauncherApps.class);
-
- mActions.put(DEEP_SHORTCUTS, new LauncherAction(DEEP_SHORTCUTS,
- R.string.action_deep_shortcut, KeyEvent.KEYCODE_S));
- mActions.put(SHORTCUTS_AND_NOTIFICATIONS, new LauncherAction(DEEP_SHORTCUTS,
- R.string.shortcuts_menu_with_notifications_description, KeyEvent.KEYCODE_S));
- mActions.put(MOVE_TO_TOP_OR_LEFT, new LauncherAction(
- MOVE_TO_TOP_OR_LEFT, R.string.move_drop_target_top_or_left, KeyEvent.KEYCODE_L));
- mActions.put(MOVE_TO_BOTTOM_OR_RIGHT, new LauncherAction(
- MOVE_TO_BOTTOM_OR_RIGHT,
- R.string.move_drop_target_bottom_or_right,
- KeyEvent.KEYCODE_R));
- }
-
- @Override
- protected void getSupportedActions(View host, ItemInfo item, List<LauncherAction> out) {
- if (ShortcutUtil.supportsShortcuts(item) && FeatureFlags.ENABLE_TASKBAR_POPUP_MENU.get()) {
- out.add(mActions.get(NotificationListener.getInstanceIfConnected() != null
- ? SHORTCUTS_AND_NOTIFICATIONS : DEEP_SHORTCUTS));
- }
- out.add(mActions.get(MOVE_TO_TOP_OR_LEFT));
- out.add(mActions.get(MOVE_TO_BOTTOM_OR_RIGHT));
- }
-
- @Override
- protected boolean performAction(View host, ItemInfo item, int action, boolean fromKeyboard) {
- if (item instanceof WorkspaceItemInfo
- && (action == MOVE_TO_TOP_OR_LEFT || action == MOVE_TO_BOTTOM_OR_RIGHT)) {
- WorkspaceItemInfo info = (WorkspaceItemInfo) item;
- int side = action == MOVE_TO_TOP_OR_LEFT
- ? SPLIT_POSITION_TOP_OR_LEFT : SPLIT_POSITION_BOTTOM_OR_RIGHT;
-
- if (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT) {
- SystemUiProxy.INSTANCE.get(mContext).startShortcut(
- info.getIntent().getPackage(),
- info.getDeepShortcutId(),
- side,
- /* bundleOpts= */ null,
- info.user);
- } else {
- SystemUiProxy.INSTANCE.get(mContext).startIntent(
- mLauncherApps.getMainActivityLaunchIntent(
- item.getIntent().getComponent(),
- /* startActivityOptions= */null,
- item.user),
- new Intent(), side, null);
- }
- return true;
- } else if (action == DEEP_SHORTCUTS || action == SHORTCUTS_AND_NOTIFICATIONS) {
- mContext.showPopupMenuForIcon((BubbleTextView) host);
-
- return true;
- }
- return false;
- }
-
- @Override
- protected boolean beginAccessibleDrag(View item, ItemInfo info, boolean fromKeyboard) {
- return false;
- }
-}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
deleted file mode 100644
index fc9f9d002b..0000000000
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
+++ /dev/null
@@ -1,772 +0,0 @@
-/*
- * Copyright (C) 2021 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.launcher3.taskbar;
-
-import static android.view.HapticFeedbackConstants.LONG_PRESS;
-
-import static com.android.launcher3.LauncherState.ALL_APPS;
-import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASKBAR_LONGPRESS_HIDE;
-import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASKBAR_LONGPRESS_SHOW;
-import static com.android.launcher3.taskbar.Utilities.appendFlag;
-import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_IME_SHOWING;
-import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_SCREEN_PINNING;
-
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.AnimatorSet;
-import android.annotation.Nullable;
-import android.content.SharedPreferences;
-import android.util.Log;
-import android.view.ViewConfiguration;
-import android.view.WindowInsets;
-
-import com.android.launcher3.DeviceProfile;
-import com.android.launcher3.Utilities;
-import com.android.launcher3.anim.AnimatorListeners;
-import com.android.launcher3.taskbar.allapps.TaskbarAllAppsSlideInView;
-import com.android.launcher3.testing.TestProtocol;
-import com.android.launcher3.util.MultiValueAlpha.AlphaProperty;
-import com.android.quickstep.AnimatedFloat;
-import com.android.quickstep.SystemUiProxy;
-import com.android.systemui.shared.system.WindowManagerWrapper;
-
-import java.io.PrintWriter;
-import java.util.StringJoiner;
-import java.util.function.IntPredicate;
-
-/**
- * Coordinates between controllers such as TaskbarViewController and StashedHandleViewController to
- * create a cohesive animation between stashed/unstashed states.
- */
-public class TaskbarStashController implements TaskbarControllers.LoggableTaskbarController {
-
- public static final int FLAG_IN_APP = 1 << 0;
- public static final int FLAG_STASHED_IN_APP_MANUAL = 1 << 1; // long press, persisted
- public static final int FLAG_STASHED_IN_APP_PINNED = 1 << 2; // app pinning
- public static final int FLAG_STASHED_IN_APP_EMPTY = 1 << 3; // no hotseat icons
- public static final int FLAG_STASHED_IN_APP_SETUP = 1 << 4; // setup wizard and AllSetActivity
- public static final int FLAG_STASHED_IN_APP_IME = 1 << 5; // IME is visible
- public static final int FLAG_IN_STASHED_LAUNCHER_STATE = 1 << 6;
- public static final int FLAG_STASHED_IN_APP_ALL_APPS = 1 << 7; // All apps is visible.
- public static final int FLAG_IN_SETUP = 1 << 8; // In the Setup Wizard
-
- // If any of these flags are enabled, isInApp should return true.
- private static final int FLAGS_IN_APP = FLAG_IN_APP | FLAG_IN_SETUP;
-
- // If we're in an app and any of these flags are enabled, taskbar should be stashed.
- private static final int FLAGS_STASHED_IN_APP = FLAG_STASHED_IN_APP_MANUAL
- | FLAG_STASHED_IN_APP_PINNED | FLAG_STASHED_IN_APP_EMPTY | FLAG_STASHED_IN_APP_SETUP
- | FLAG_STASHED_IN_APP_IME | FLAG_STASHED_IN_APP_ALL_APPS;
-
- private static final int FLAGS_STASHED_IN_APP_IGNORING_IME =
- FLAGS_STASHED_IN_APP & ~FLAG_STASHED_IN_APP_IME;
-
- // If any of these flags are enabled, inset apps by our stashed height instead of our unstashed
- // height. This way the reported insets are consistent even during transitions out of the app.
- // Currently any flag that causes us to stash in an app is included, except for IME or All Apps
- // since those cover the underlying app anyway and thus the app shouldn't change insets.
- private static final int FLAGS_REPORT_STASHED_INSETS_TO_APP = FLAGS_STASHED_IN_APP
- & ~FLAG_STASHED_IN_APP_IME & ~FLAG_STASHED_IN_APP_ALL_APPS;
-
- /**
- * How long to stash/unstash when manually invoked via long press.
- */
- public static final long TASKBAR_STASH_DURATION =
- WindowManagerWrapper.ANIMATION_DURATION_RESIZE;
-
- /**
- * How long to stash/unstash when keyboard is appearing/disappearing.
- */
- private static final long TASKBAR_STASH_DURATION_FOR_IME = 80;
-
- /**
- * The scale TaskbarView animates to when being stashed.
- */
- private static final float STASHED_TASKBAR_SCALE = 0.5f;
-
- /**
- * How long the hint animation plays, starting on motion down.
- */
- private static final long TASKBAR_HINT_STASH_DURATION =
- ViewConfiguration.DEFAULT_LONG_PRESS_TIMEOUT;
-
- /**
- * The scale that TaskbarView animates to when hinting towards the stashed state.
- */
- private static final float STASHED_TASKBAR_HINT_SCALE = 0.9f;
-
- /**
- * The scale that the stashed handle animates to when hinting towards the unstashed state.
- */
- private static final float UNSTASHED_TASKBAR_HANDLE_HINT_SCALE = 1.1f;
-
- /**
- * The SharedPreferences key for whether user has manually stashed the taskbar.
- */
- private static final String SHARED_PREFS_STASHED_KEY = "taskbar_is_stashed";
-
- /**
- * Whether taskbar should be stashed out of the box.
- */
- private static final boolean DEFAULT_STASHED_PREF = false;
-
- private final TaskbarActivityContext mActivity;
- private final SharedPreferences mPrefs;
- private final int mStashedHeight;
- private final int mUnstashedHeight;
- private final SystemUiProxy mSystemUiProxy;
-
- // Initialized in init.
- private TaskbarControllers mControllers;
- // Taskbar background properties.
- private AnimatedFloat mTaskbarBackgroundOffset;
- private AnimatedFloat mTaskbarImeBgAlpha;
- // TaskbarView icon properties.
- private AlphaProperty mIconAlphaForStash;
- private AnimatedFloat mIconScaleForStash;
- private AnimatedFloat mIconTranslationYForStash;
- // Stashed handle properties.
- private AlphaProperty mTaskbarStashedHandleAlpha;
- private AnimatedFloat mTaskbarStashedHandleHintScale;
-
- /** Whether we are currently visually stashed (might change based on launcher state). */
- private boolean mIsStashed = false;
- private int mState;
-
- private @Nullable AnimatorSet mAnimator;
- private boolean mIsSystemGestureInProgress;
- private boolean mIsImeShowing;
-
- private boolean mEnableManualStashingForTests = false;
-
- // Evaluate whether the handle should be stashed
- private final StatePropertyHolder mStatePropertyHolder = new StatePropertyHolder(
- flags -> {
- boolean inApp = hasAnyFlag(flags, FLAGS_IN_APP);
- boolean stashedInApp = hasAnyFlag(flags, FLAGS_STASHED_IN_APP);
- boolean stashedLauncherState = hasAnyFlag(flags, FLAG_IN_STASHED_LAUNCHER_STATE);
- return (inApp && stashedInApp) || (!inApp && stashedLauncherState);
- });
-
- public TaskbarStashController(TaskbarActivityContext activity) {
- mActivity = activity;
- mPrefs = Utilities.getPrefs(mActivity);
- mSystemUiProxy = SystemUiProxy.INSTANCE.get(activity);
- mUnstashedHeight = mActivity.getDeviceProfile().taskbarSize;
- mStashedHeight = mActivity.getDeviceProfile().stashedTaskbarSize;
- }
-
- public void init(TaskbarControllers controllers, boolean setupUIVisible) {
- mControllers = controllers;
-
- TaskbarDragLayerController dragLayerController = controllers.taskbarDragLayerController;
- mTaskbarBackgroundOffset = dragLayerController.getTaskbarBackgroundOffset();
- mTaskbarImeBgAlpha = dragLayerController.getImeBgTaskbar();
-
- TaskbarViewController taskbarViewController = controllers.taskbarViewController;
- mIconAlphaForStash = taskbarViewController.getTaskbarIconAlpha().getProperty(
- TaskbarViewController.ALPHA_INDEX_STASH);
- mIconScaleForStash = taskbarViewController.getTaskbarIconScaleForStash();
- mIconTranslationYForStash = taskbarViewController.getTaskbarIconTranslationYForStash();
-
- StashedHandleViewController stashedHandleController =
- controllers.stashedHandleViewController;
- mTaskbarStashedHandleAlpha = stashedHandleController.getStashedHandleAlpha().getProperty(
- StashedHandleViewController.ALPHA_INDEX_STASHED);
- mTaskbarStashedHandleHintScale = stashedHandleController.getStashedHandleHintScale();
-
- boolean isManuallyStashedInApp = supportsManualStashing()
- && mPrefs.getBoolean(SHARED_PREFS_STASHED_KEY, DEFAULT_STASHED_PREF);
- boolean isInSetup = !mActivity.isUserSetupComplete() || setupUIVisible;
- updateStateForFlag(FLAG_STASHED_IN_APP_MANUAL, isManuallyStashedInApp);
- updateStateForFlag(FLAG_STASHED_IN_APP_SETUP, isInSetup);
- updateStateForFlag(FLAG_IN_SETUP, isInSetup);
- applyState();
-
- notifyStashChange(/* visible */ false, /* stashed */ isStashedInApp());
- }
-
- /**
- * Returns whether the taskbar can visually stash into a handle based on the current device
- * state.
- */
- public boolean supportsVisualStashing() {
- return mControllers.uiController.supportsVisualStashing();
- }
-
- /**
- * Returns whether the user can manually stash the taskbar based on the current device state.
- */
- protected boolean supportsManualStashing() {
- return supportsVisualStashing()
- && (!Utilities.IS_RUNNING_IN_TEST_HARNESS || mEnableManualStashingForTests);
- }
-
- /**
- * Enables support for manual stashing. This should only be used to add this functionality
- * to Launcher specific tests.
- */
- public void enableManualStashingForTests(boolean enableManualStashing) {
- mEnableManualStashingForTests = enableManualStashing;
- }
-
- /**
- * Sets the flag indicating setup UI is visible
- */
- protected void setSetupUIVisible(boolean isVisible) {
- boolean hideTaskbar = isVisible || !mActivity.isUserSetupComplete();
- updateStateForFlag(FLAG_IN_SETUP, hideTaskbar);
- updateStateForFlag(FLAG_STASHED_IN_APP_SETUP, hideTaskbar);
- applyState(hideTaskbar ? 0 : TASKBAR_STASH_DURATION);
- }
-
- /**
- * Returns whether the taskbar is currently visually stashed.
- */
- public boolean isStashed() {
- return mIsStashed;
- }
-
- /**
- * Returns whether the taskbar should be stashed in apps (e.g. user long pressed to stash).
- */
- public boolean isStashedInApp() {
- return hasAnyFlag(FLAGS_STASHED_IN_APP);
- }
-
- /**
- * Returns whether the taskbar should be stashed in apps regardless of the IME visibility.
- */
- public boolean isStashedInAppIgnoringIme() {
- return hasAnyFlag(FLAGS_STASHED_IN_APP_IGNORING_IME);
- }
-
- /**
- * Returns whether the taskbar should be stashed in the current LauncherState.
- */
- public boolean isInStashedLauncherState() {
- return hasAnyFlag(FLAG_IN_STASHED_LAUNCHER_STATE) && supportsVisualStashing();
- }
-
- private boolean hasAnyFlag(int flagMask) {
- return hasAnyFlag(mState, flagMask);
- }
-
- private boolean hasAnyFlag(int flags, int flagMask) {
- return (flags & flagMask) != 0;
- }
-
-
- /**
- * Returns whether the taskbar is currently visible and in an app.
- */
- public boolean isInAppAndNotStashed() {
- return !mIsStashed && isInApp();
- }
-
- public boolean isInApp() {
- return hasAnyFlag(FLAGS_IN_APP);
- }
-
- /**
- * Returns the height that taskbar will inset when inside apps.
- * @see WindowInsets.Type#navigationBars()
- * @see WindowInsets.Type#systemBars()
- */
- public int getContentHeightToReportToApps() {
- if (supportsVisualStashing() && hasAnyFlag(FLAGS_REPORT_STASHED_INSETS_TO_APP)) {
- DeviceProfile dp = mActivity.getDeviceProfile();
- if (hasAnyFlag(FLAG_STASHED_IN_APP_SETUP) && dp.isTaskbarPresent && !dp.isLandscape) {
- // We always show the back button in SUW but in portrait the SUW layout may not
- // be wide enough to support overlapping the nav bar with its content. For now,
- // just inset by the bar height.
- return mUnstashedHeight;
- }
- boolean isAnimating = mAnimator != null && mAnimator.isStarted();
- if (!mControllers.stashedHandleViewController.isStashedHandleVisible()
- && isInApp()
- && !isAnimating) {
- // We are in a settled state where we're not showing the handle even though taskbar
- // is stashed. This can happen for example when home button is disabled (see
- // StashedHandleViewController#setIsHomeButtonDisabled()).
- return 0;
- }
- return mStashedHeight;
- }
- return mUnstashedHeight;
- }
-
- /**
- * Returns the height that taskbar will inset when inside apps.
- * @see WindowInsets.Type#tappableElement()
- */
- public int getTappableHeightToReportToApps() {
- int contentHeight = getContentHeightToReportToApps();
- return contentHeight <= mStashedHeight ? 0 : contentHeight;
- }
-
- public int getStashedHeight() {
- return mStashedHeight;
- }
-
- /**
- * Should be called when long pressing the nav region when taskbar is present.
- * @return Whether taskbar was stashed and now is unstashed.
- */
- public boolean onLongPressToUnstashTaskbar() {
- if (!isStashed()) {
- // We only listen for long press on the nav region to unstash the taskbar. To stash the
- // taskbar, we use an OnLongClickListener on TaskbarView instead.
- return false;
- }
- if (!canCurrentlyManuallyUnstash()) {
- return false;
- }
- if (updateAndAnimateIsManuallyStashedInApp(false)) {
- mControllers.taskbarActivityContext.getDragLayer().performHapticFeedback(LONG_PRESS);
- return true;
- }
- return false;
- }
-
- /**
- * Returns whether taskbar will unstash when long pressing it based on the current state. The
- * only time this is true is if the user is in an app and the taskbar is only stashed because
- * the user previously long pressed to manually stash (not due to other reasons like IME).
- */
- private boolean canCurrentlyManuallyUnstash() {
- return (mState & (FLAG_IN_APP | FLAGS_STASHED_IN_APP))
- == (FLAG_IN_APP | FLAG_STASHED_IN_APP_MANUAL);
- }
-
- /**
- * Updates whether we should stash the taskbar when in apps, and animates to the changed state.
- * @return Whether we started an animation to either be newly stashed or unstashed.
- */
- public boolean updateAndAnimateIsManuallyStashedInApp(boolean isManuallyStashedInApp) {
- if (!supportsManualStashing()) {
- return false;
- }
- if (hasAnyFlag(FLAG_STASHED_IN_APP_MANUAL) != isManuallyStashedInApp) {
- mPrefs.edit().putBoolean(SHARED_PREFS_STASHED_KEY, isManuallyStashedInApp).apply();
- updateStateForFlag(FLAG_STASHED_IN_APP_MANUAL, isManuallyStashedInApp);
- applyState();
- return true;
- }
- return false;
- }
-
- /**
- * Adds the Taskbar unstash to Hotseat animator to the animator set.
- *
- * This should be used to run a Taskbar unstash to Hotseat animation whose progress matches a
- * swipe progress.
- *
- * @param placeholderDuration a placeholder duration to be used to ensure all full-length
- * sub-animations are properly coordinated. This duration should not
- * actually be used since this animation tracks a swipe progress.
- */
- protected void addUnstashToHotseatAnimation(AnimatorSet animation, int placeholderDuration) {
- createAnimToIsStashed(
- /* isStashed= */ false,
- placeholderDuration,
- /* startDelay= */ 0,
- /* animateBg= */ false);
- animation.play(mAnimator);
- }
-
- /**
- * Create a stash animation and save to {@link #mAnimator}.
- * @param isStashed whether it's a stash animation or an unstash animation
- * @param duration duration of the animation
- * @param startDelay how many milliseconds to delay the animation after starting it.
- * @param animateBg whether the taskbar's background should be animated
- */
- private void createAnimToIsStashed(
- boolean isStashed, long duration, long startDelay, boolean animateBg) {
- if (mAnimator != null) {
- mAnimator.cancel();
- }
- mAnimator = new AnimatorSet();
-
- if (!supportsVisualStashing()) {
- // Just hide/show the icons and background instead of stashing into a handle.
- mAnimator.play(mIconAlphaForStash.animateToValue(isStashed ? 0 : 1)
- .setDuration(duration));
- mAnimator.play(mTaskbarImeBgAlpha.animateToValue(
- hasAnyFlag(FLAG_STASHED_IN_APP_IME) ? 0 : 1).setDuration(duration));
- mAnimator.setStartDelay(startDelay);
- mAnimator.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- mAnimator = null;
- }
- });
- return;
- }
-
- AnimatorSet fullLengthAnimatorSet = new AnimatorSet();
- // Not exactly half and may overlap. See [first|second]HalfDurationScale below.
- AnimatorSet firstHalfAnimatorSet = new AnimatorSet();
- AnimatorSet secondHalfAnimatorSet = new AnimatorSet();
-
- final float firstHalfDurationScale;
- final float secondHalfDurationScale;
-
- if (isStashed) {
- firstHalfDurationScale = 0.75f;
- secondHalfDurationScale = 0.5f;
- final float stashTranslation = (mUnstashedHeight - mStashedHeight) / 2f;
-
- fullLengthAnimatorSet.play(mIconTranslationYForStash.animateToValue(stashTranslation));
- if (animateBg) {
- fullLengthAnimatorSet.play(mTaskbarBackgroundOffset.animateToValue(1));
- } else {
- fullLengthAnimatorSet.addListener(AnimatorListeners.forEndCallback(
- () -> mTaskbarBackgroundOffset.updateValue(1)));
- }
-
- firstHalfAnimatorSet.playTogether(
- mIconAlphaForStash.animateToValue(0),
- mIconScaleForStash.animateToValue(STASHED_TASKBAR_SCALE)
- );
- secondHalfAnimatorSet.playTogether(
- mTaskbarStashedHandleAlpha.animateToValue(1)
- );
- } else {
- firstHalfDurationScale = 0.5f;
- secondHalfDurationScale = 0.75f;
-
- fullLengthAnimatorSet.playTogether(
- mIconScaleForStash.animateToValue(1),
- mIconTranslationYForStash.animateToValue(0));
- if (animateBg) {
- fullLengthAnimatorSet.play(mTaskbarBackgroundOffset.animateToValue(0));
- } else {
- fullLengthAnimatorSet.addListener(AnimatorListeners.forEndCallback(
- () -> mTaskbarBackgroundOffset.updateValue(0)));
- }
-
- firstHalfAnimatorSet.playTogether(
- mTaskbarStashedHandleAlpha.animateToValue(0)
- );
- secondHalfAnimatorSet.playTogether(
- mIconAlphaForStash.animateToValue(1)
- );
- }
-
- fullLengthAnimatorSet.play(mControllers.stashedHandleViewController
- .createRevealAnimToIsStashed(isStashed));
- // Return the stashed handle to its default scale in case it was changed as part of the
- // feedforward hint. Note that the reveal animation above also visually scales it.
- fullLengthAnimatorSet.play(mTaskbarStashedHandleHintScale.animateToValue(1f));
-
- fullLengthAnimatorSet.setDuration(duration);
- firstHalfAnimatorSet.setDuration((long) (duration * firstHalfDurationScale));
- secondHalfAnimatorSet.setDuration((long) (duration * secondHalfDurationScale));
- secondHalfAnimatorSet.setStartDelay((long) (duration * (1 - secondHalfDurationScale)));
-
- mAnimator.playTogether(fullLengthAnimatorSet, firstHalfAnimatorSet,
- secondHalfAnimatorSet);
- mAnimator.setStartDelay(startDelay);
- mAnimator.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationStart(Animator animation) {
- mIsStashed = isStashed;
- onIsStashedChanged(mIsStashed);
- }
-
- @Override
- public void onAnimationEnd(Animator animation) {
- mAnimator = null;
- }
- });
- }
-
- /**
- * Creates and starts a partial stash animation, hinting at the new state that will trigger when
- * long press is detected.
- * @param animateForward Whether we are going towards the new stashed state or returning to the
- * unstashed state.
- */
- public void startStashHint(boolean animateForward) {
- if (isStashed() || !supportsManualStashing()) {
- // Already stashed, no need to hint in that direction.
- return;
- }
- mIconScaleForStash.animateToValue(
- animateForward ? STASHED_TASKBAR_HINT_SCALE : 1)
- .setDuration(TASKBAR_HINT_STASH_DURATION).start();
- }
-
- /**
- * Creates and starts a partial unstash animation, hinting at the new state that will trigger
- * when long press is detected.
- * @param animateForward Whether we are going towards the new unstashed state or returning to
- * the stashed state.
- */
- public void startUnstashHint(boolean animateForward) {
- if (!isStashed()) {
- // Already unstashed, no need to hint in that direction.
- return;
- }
- if (!canCurrentlyManuallyUnstash()) {
- // If any other flags are causing us to be stashed, long press won't cause us to
- // unstash, so don't hint that it will.
- return;
- }
- mTaskbarStashedHandleHintScale.animateToValue(
- animateForward ? UNSTASHED_TASKBAR_HANDLE_HINT_SCALE : 1)
- .setDuration(TASKBAR_HINT_STASH_DURATION).start();
- }
-
- private void onIsStashedChanged(boolean isStashed) {
- mControllers.runAfterInit(() -> {
- mControllers.stashedHandleViewController.onIsStashedChanged(isStashed);
- mControllers.taskbarInsetsController.onTaskbarWindowHeightOrInsetsChanged();
- });
- }
-
- public void applyState() {
- applyState(hasAnyFlag(FLAG_IN_SETUP) ? 0 : TASKBAR_STASH_DURATION);
- }
-
- public void applyState(long duration) {
- mStatePropertyHolder.setState(mState, duration, true);
- }
-
- public void applyState(long duration, long startDelay) {
- mStatePropertyHolder.setState(mState, duration, startDelay, true);
- }
-
- public Animator applyStateWithoutStart() {
- return applyStateWithoutStart(TASKBAR_STASH_DURATION);
- }
-
- public Animator applyStateWithoutStart(long duration) {
- return mStatePropertyHolder.setState(mState, duration, false);
- }
-
- /**
- * Should be called when a system gesture starts and settles, so we can defer updating
- * FLAG_STASHED_IN_APP_IME until after the gesture transition completes.
- */
- public void setSystemGestureInProgress(boolean inProgress) {
- mIsSystemGestureInProgress = inProgress;
- if (mIsSystemGestureInProgress) {
- return;
- }
-
- // Only update the following flags when system gesture is not in progress.
- maybeResetStashedInAppAllApps(hasAnyFlag(FLAG_STASHED_IN_APP_IME) == mIsImeShowing);
- if (hasAnyFlag(FLAG_STASHED_IN_APP_IME) != mIsImeShowing) {
- updateStateForFlag(FLAG_STASHED_IN_APP_IME, mIsImeShowing);
- applyState(TASKBAR_STASH_DURATION_FOR_IME, getTaskbarStashStartDelayForIme());
- }
- }
-
- /**
- * Reset stashed in all apps only if no system gesture is in progress.
- * <p>
- * Otherwise, the reset should be deferred until after the gesture is finished.
- *
- * @see #setSystemGestureInProgress
- */
- public void maybeResetStashedInAppAllApps() {
- maybeResetStashedInAppAllApps(true);
- }
-
- private void maybeResetStashedInAppAllApps(boolean applyState) {
- if (mIsSystemGestureInProgress) {
- return;
- }
-
- updateStateForFlag(FLAG_STASHED_IN_APP_ALL_APPS, false);
- if (applyState) {
- applyState(ALL_APPS.getTransitionDuration(
- mControllers.taskbarActivityContext, false /* isToState */));
- }
- }
-
- /**
- * When hiding the IME, delay the unstash animation to align with the end of the transition.
- */
- private long getTaskbarStashStartDelayForIme() {
- if (mIsImeShowing) {
- // Only delay when IME is exiting, not entering.
- return 0;
- }
- // This duration is based on input_method_extract_exit.xml.
- long imeExitDuration = mControllers.taskbarActivityContext.getResources()
- .getInteger(android.R.integer.config_shortAnimTime);
- return imeExitDuration - TASKBAR_STASH_DURATION_FOR_IME;
- }
-
- /** Called when some system ui state has changed. (See SYSUI_STATE_... in QuickstepContract) */
- public void updateStateForSysuiFlags(int systemUiStateFlags, boolean skipAnim) {
- long animDuration = TASKBAR_STASH_DURATION;
- long startDelay = 0;
-
- updateStateForFlag(FLAG_STASHED_IN_APP_PINNED,
- hasAnyFlag(systemUiStateFlags, SYSUI_STATE_SCREEN_PINNING));
-
- // Only update FLAG_STASHED_IN_APP_IME when system gesture is not in progress.
- mIsImeShowing = hasAnyFlag(systemUiStateFlags, SYSUI_STATE_IME_SHOWING);
- if (!mIsSystemGestureInProgress) {
- updateStateForFlag(FLAG_STASHED_IN_APP_IME, mIsImeShowing);
- animDuration = TASKBAR_STASH_DURATION_FOR_IME;
- startDelay = getTaskbarStashStartDelayForIme();
- }
-
- applyState(skipAnim ? 0 : animDuration, skipAnim ? 0 : startDelay);
- }
-
- /**
- * Updates the proper flag to indicate whether the task bar should be stashed.
- *
- * Note that this only updates the flag. {@link #applyState()} needs to be called separately.
- *
- * @param flag The flag to update.
- * @param enabled Whether to enable the flag: True will cause the task bar to be stashed /
- * unstashed.
- */
- public void updateStateForFlag(int flag, boolean enabled) {
- if (flag == FLAG_IN_APP && TestProtocol.sDebugTracing) {
- Log.d(TestProtocol.TASKBAR_IN_APP_STATE, String.format(
- "setting flag FLAG_IN_APP to: %b", enabled), new Exception());
- }
- if (enabled) {
- mState |= flag;
- } else {
- mState &= ~flag;
- }
- }
-
- /**
- * Called after updateStateForFlag() and applyState() have been called.
- * @param changedFlags The flags that have changed.
- */
- private void onStateChangeApplied(int changedFlags) {
- if (hasAnyFlag(changedFlags, FLAGS_STASHED_IN_APP)) {
- mControllers.uiController.onStashedInAppChanged();
- }
- if (hasAnyFlag(changedFlags, FLAGS_STASHED_IN_APP | FLAGS_IN_APP)) {
- notifyStashChange(/* visible */ hasAnyFlag(FLAGS_IN_APP),
- /* stashed */ isStashedInApp());
- }
- if (hasAnyFlag(changedFlags, FLAG_STASHED_IN_APP_MANUAL)) {
- if (hasAnyFlag(FLAG_STASHED_IN_APP_MANUAL)) {
- mActivity.getStatsLogManager().logger().log(LAUNCHER_TASKBAR_LONGPRESS_HIDE);
- } else {
- mActivity.getStatsLogManager().logger().log(LAUNCHER_TASKBAR_LONGPRESS_SHOW);
- }
- }
- }
-
- private void notifyStashChange(boolean visible, boolean stashed) {
- mSystemUiProxy.notifyTaskbarStatus(visible, stashed);
- // If stashing taskbar is caused by IME visibility, we could just skip updating rounded
- // corner insets since the rounded corners will be covered by IME during IME is showing and
- // taskbar will be restored back to unstashed when IME is hidden.
- mControllers.taskbarActivityContext.updateInsetRoundedCornerFrame(
- visible && !isStashedInAppIgnoringIme());
- mControllers.rotationButtonController.onTaskbarStateChange(visible, stashed);
- }
-
- @Override
- public void dumpLogs(String prefix, PrintWriter pw) {
- pw.println(prefix + "TaskbarStashController:");
-
- pw.println(String.format("%s\tmStashedHeight=%dpx", prefix, mStashedHeight));
- pw.println(String.format("%s\tmUnstashedHeight=%dpx", prefix, mUnstashedHeight));
- pw.println(String.format("%s\tmIsStashed=%b", prefix, mIsStashed));
- pw.println(String.format(
- "%s\tappliedState=%s", prefix, getStateString(mStatePropertyHolder.mPrevFlags)));
- pw.println(String.format("%s\tmState=%s", prefix, getStateString(mState)));
- pw.println(String.format(
- "%s\tmIsSystemGestureInProgress=%b", prefix, mIsSystemGestureInProgress));
- pw.println(String.format("%s\tmIsImeShowing=%b", prefix, mIsImeShowing));
- }
-
- private static String getStateString(int flags) {
- StringJoiner str = new StringJoiner("|");
- appendFlag(str, flags, FLAGS_IN_APP, "FLAG_IN_APP");
- appendFlag(str, flags, FLAG_STASHED_IN_APP_MANUAL, "FLAG_STASHED_IN_APP_MANUAL");
- appendFlag(str, flags, FLAG_STASHED_IN_APP_PINNED, "FLAG_STASHED_IN_APP_PINNED");
- appendFlag(str, flags, FLAG_STASHED_IN_APP_EMPTY, "FLAG_STASHED_IN_APP_EMPTY");
- appendFlag(str, flags, FLAG_STASHED_IN_APP_SETUP, "FLAG_STASHED_IN_APP_SETUP");
- appendFlag(str, flags, FLAG_STASHED_IN_APP_IME, "FLAG_STASHED_IN_APP_IME");
- appendFlag(str, flags, FLAG_IN_STASHED_LAUNCHER_STATE, "FLAG_IN_STASHED_LAUNCHER_STATE");
- appendFlag(str, flags, FLAG_STASHED_IN_APP_ALL_APPS, "FLAG_STASHED_IN_APP_ALL_APPS");
- appendFlag(str, flags, FLAG_IN_SETUP, "FLAG_IN_SETUP");
- return str.toString();
- }
-
- private class StatePropertyHolder {
- private final IntPredicate mStashCondition;
-
- private boolean mIsStashed;
- private int mPrevFlags;
-
- StatePropertyHolder(IntPredicate stashCondition) {
- mStashCondition = stashCondition;
- }
-
- /**
- * @see #setState(int, long, long, boolean) with a default startDelay = 0.
- */
- public Animator setState(int flags, long duration, boolean start) {
- return setState(flags, duration, 0 /* startDelay */, start);
- }
-
- /**
- * Applies the latest state, potentially calling onStateChangeApplied() and creating a new
- * animation (stored in mAnimator) which is started if {@param start} is true.
- * @param flags The latest flags to apply (see the top of this file).
- * @param duration The length of the animation.
- * @param startDelay How long to delay the animation after calling start().
- * @param start Whether to start mAnimator immediately.
- * @return mAnimator if mIsStashed changed, else null.
- */
- public Animator setState(int flags, long duration, long startDelay, boolean start) {
- int changedFlags = mPrevFlags ^ flags;
- if (mPrevFlags != flags) {
- onStateChangeApplied(changedFlags);
- mPrevFlags = flags;
- }
- boolean isStashed = mStashCondition.test(flags);
- if (mIsStashed != isStashed) {
- if (TestProtocol.sDebugTracing) {
- Log.d(TestProtocol.TASKBAR_IN_APP_STATE, String.format(
- "setState: mIsStashed=%b, isStashed=%b, duration=%d, start=:%b",
- mIsStashed,
- isStashed,
- duration,
- start));
- }
- mIsStashed = isStashed;
-
- // This sets mAnimator.
- createAnimToIsStashed(mIsStashed, duration, startDelay, /* animateBg= */ true);
- if (start) {
- mAnimator.start();
- }
- return mAnimator;
- }
- return null;
- }
- }
-}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarStateHandler.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarStateHandler.java
new file mode 100644
index 0000000000..a701aae088
--- /dev/null
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarStateHandler.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2021 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.launcher3.taskbar;
+
+import static com.android.launcher3.LauncherState.TASKBAR;
+import static com.android.launcher3.anim.Interpolators.ACCEL_DEACCEL;
+import static com.android.launcher3.anim.Interpolators.LINEAR;
+
+import androidx.annotation.Nullable;
+
+import com.android.launcher3.BaseQuickstepLauncher;
+import com.android.launcher3.LauncherState;
+import com.android.launcher3.anim.PendingAnimation;
+import com.android.launcher3.anim.PropertySetter;
+import com.android.launcher3.statemanager.StateManager;
+import com.android.launcher3.states.StateAnimationConfig;
+import com.android.quickstep.AnimatedFloat;
+
+/**
+ * StateHandler to animate Taskbar according to Launcher's state machine. Does nothing if Taskbar
+ * isn't present (i.e. {@link #setAnimationController} is never called).
+ */
+public class TaskbarStateHandler implements StateManager.StateHandler<LauncherState> {
+
+ private final BaseQuickstepLauncher mLauncher;
+
+ // Contains Taskbar-related methods and fields we should aniamte. If null, don't do anything.
+ private @Nullable TaskbarAnimationController mAnimationController = null;
+
+ public TaskbarStateHandler(BaseQuickstepLauncher launcher) {
+ mLauncher = launcher;
+ }
+
+ public void setAnimationController(TaskbarAnimationController callbacks) {
+ mAnimationController = callbacks;
+ }
+
+ @Override
+ public void setState(LauncherState state) {
+ setState(state, PropertySetter.NO_ANIM_PROPERTY_SETTER);
+ }
+
+ @Override
+ public void setStateWithAnimation(LauncherState toState, StateAnimationConfig config,
+ PendingAnimation animation) {
+ setState(toState, animation);
+ }
+
+ private void setState(LauncherState toState, PropertySetter setter) {
+ if (mAnimationController == null) {
+ return;
+ }
+
+ boolean isTaskbarVisible = (toState.getVisibleElements(mLauncher) & TASKBAR) != 0;
+ setter.setFloat(mAnimationController.getTaskbarVisibilityForLauncherState(),
+ AnimatedFloat.VALUE, isTaskbarVisible ? 1f : 0f, LINEAR);
+ setter.setFloat(mAnimationController.getTaskbarScaleForLauncherState(),
+ AnimatedFloat.VALUE, toState.getTaskbarScale(mLauncher), LINEAR);
+ setter.setFloat(mAnimationController.getTaskbarTranslationYForLauncherState(),
+ AnimatedFloat.VALUE, toState.getTaskbarTranslationY(mLauncher), ACCEL_DEACCEL);
+ }
+}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java
index fcc34c6d99..50adeadbfc 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java
@@ -15,16 +15,6 @@
*/
package com.android.launcher3.taskbar;
-import android.view.View;
-
-import androidx.annotation.CallSuper;
-
-import com.android.launcher3.model.data.ItemInfo;
-import com.android.launcher3.model.data.ItemInfoWithIcon;
-
-import java.io.PrintWriter;
-import java.util.stream.Stream;
-
/**
* Base class for providing different taskbar UI
*/
@@ -32,72 +22,20 @@ public class TaskbarUIController {
public static final TaskbarUIController DEFAULT = new TaskbarUIController();
- // Initialized in init.
- protected TaskbarControllers mControllers;
+ /**
+ * Pads the Hotseat to line up exactly with Taskbar's copy of the Hotseat.
+ */
+ public void alignRealHotseatWithTaskbar() { }
- @CallSuper
- protected void init(TaskbarControllers taskbarControllers) {
- mControllers = taskbarControllers;
- }
+ protected void onCreate() { }
- @CallSuper
- protected void onDestroy() {
- mControllers = null;
- }
+ protected void onDestroy() { }
protected boolean isTaskbarTouchable() {
return true;
}
- public boolean supportsVisualStashing() {
- if (mControllers == null) return false;
- return !mControllers.taskbarActivityContext.isThreeButtonNav();
- }
-
- protected void onStashedInAppChanged() { }
-
- public Stream<ItemInfoWithIcon> getAppIconsForEdu() {
- return Stream.empty();
- }
-
- /** Called when an icon is launched. */
- public void onTaskbarIconLaunched(ItemInfo item) { }
-
- public View getRootView() {
- return mControllers.taskbarActivityContext.getDragLayer();
- }
-
- /**
- * Called when swiping from the bottom nav region in fully gestural mode.
- * @param inProgress True if the animation started, false if we just settled on an end target.
- */
- public void setSystemGestureInProgress(boolean inProgress) {
- mControllers.taskbarStashController.setSystemGestureInProgress(inProgress);
- }
-
- /**
- * Manually closes the all apps window.
- */
- public void hideAllApps() {
- mControllers.taskbarAllAppsController.hide();
- }
-
- /**
- * User expands PiP to full-screen (or split-screen) mode, try to hide the Taskbar.
- */
- public void onExpandPip() {
- if (mControllers != null) {
- final TaskbarStashController stashController = mControllers.taskbarStashController;
- stashController.updateStateForFlag(TaskbarStashController.FLAG_IN_APP, true);
- stashController.applyState();
- }
- }
-
- @CallSuper
- protected void dumpLogs(String prefix, PrintWriter pw) {
- pw.println(String.format(
- "%sTaskbarUIController: using an instance of %s",
- prefix,
- getClass().getSimpleName()));
+ protected void onImeVisible(TaskbarDragLayer container, boolean isVisible) {
+ container.updateImeBarVisibilityAlpha(isVisible ? 1 : 0);
}
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarUnfoldAnimationController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarUnfoldAnimationController.java
deleted file mode 100644
index 64a4fa79df..0000000000
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarUnfoldAnimationController.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright (C) 2021 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.launcher3.taskbar;
-
-import android.view.IWindowManager;
-import android.view.View;
-import android.view.WindowManager;
-
-import com.android.quickstep.util.LauncherViewsMoveFromCenterTranslationApplier;
-import com.android.systemui.shared.animation.UnfoldMoveFromCenterAnimator;
-import com.android.systemui.unfold.UnfoldTransitionProgressProvider.TransitionProgressListener;
-import com.android.systemui.unfold.util.NaturalRotationUnfoldProgressProvider;
-import com.android.systemui.unfold.util.ScopedUnfoldTransitionProgressProvider;
-
-import java.io.PrintWriter;
-
-/**
- * Controls animation of taskbar icons when unfolding foldable devices
- */
-public class TaskbarUnfoldAnimationController implements
- TaskbarControllers.LoggableTaskbarController {
-
- private final ScopedUnfoldTransitionProgressProvider mScopedUnfoldTransitionProgressProvider;
- private final NaturalRotationUnfoldProgressProvider mNaturalUnfoldTransitionProgressProvider;
- private final UnfoldMoveFromCenterAnimator mMoveFromCenterAnimator;
- private final TransitionListener mTransitionListener = new TransitionListener();
- private TaskbarViewController mTaskbarViewController;
-
- public TaskbarUnfoldAnimationController(BaseTaskbarContext context,
- ScopedUnfoldTransitionProgressProvider source,
- WindowManager windowManager, IWindowManager iWindowManager) {
- mScopedUnfoldTransitionProgressProvider = source;
- mNaturalUnfoldTransitionProgressProvider =
- new NaturalRotationUnfoldProgressProvider(context, iWindowManager, source);
- mMoveFromCenterAnimator = new UnfoldMoveFromCenterAnimator(windowManager,
- new LauncherViewsMoveFromCenterTranslationApplier());
- }
-
- /**
- * Initializes the controller
- * @param taskbarControllers references to all other taskbar controllers
- */
- public void init(TaskbarControllers taskbarControllers) {
- mNaturalUnfoldTransitionProgressProvider.init();
- mTaskbarViewController = taskbarControllers.taskbarViewController;
- mTaskbarViewController.addOneTimePreDrawListener(() ->
- mScopedUnfoldTransitionProgressProvider.setReadyToHandleTransition(true));
- mNaturalUnfoldTransitionProgressProvider.addCallback(mTransitionListener);
- }
-
- /**
- * Destroys the controller
- */
- public void onDestroy() {
- mScopedUnfoldTransitionProgressProvider.setReadyToHandleTransition(false);
- mNaturalUnfoldTransitionProgressProvider.removeCallback(mTransitionListener);
- mNaturalUnfoldTransitionProgressProvider.destroy();
- mTaskbarViewController = null;
- }
-
- @Override
- public void dumpLogs(String prefix, PrintWriter pw) {
- pw.println(prefix + "TaskbarUnfoldAnimationController:");
- }
-
- private class TransitionListener implements TransitionProgressListener {
-
- @Override
- public void onTransitionStarted() {
- mMoveFromCenterAnimator.updateDisplayProperties();
- View[] icons = mTaskbarViewController.getIconViews();
- for (View icon : icons) {
- // TODO(b/193794563) we should re-register views if they are re-bound/re-inflated
- // during the animation
- mMoveFromCenterAnimator.registerViewForAnimation(icon);
- }
-
- mMoveFromCenterAnimator.onTransitionStarted();
- }
-
- @Override
- public void onTransitionFinished() {
- mMoveFromCenterAnimator.onTransitionFinished();
- mMoveFromCenterAnimator.clearRegisteredViews();
- }
-
- @Override
- public void onTransitionProgress(float progress) {
- mMoveFromCenterAnimator.onTransitionProgress(progress);
- }
- }
-}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java
index 6f88d649fb..c6573a639c 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java
@@ -15,68 +15,75 @@
*/
package com.android.launcher3.taskbar;
+import static android.view.View.MeasureSpec.EXACTLY;
+import static android.view.View.MeasureSpec.makeMeasureSpec;
+
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Rect;
+import android.graphics.RectF;
import android.util.AttributeSet;
+import android.view.DragEvent;
+import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
-import android.view.ViewGroup;
-import android.widget.FrameLayout;
+import android.view.ViewConfiguration;
+import android.widget.LinearLayout;
import androidx.annotation.LayoutRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
-import androidx.core.graphics.ColorUtils;
+import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.BubbleTextView;
import com.android.launcher3.Insettable;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
-import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.folder.FolderIcon;
-import com.android.launcher3.icons.ThemedIconDrawable;
import com.android.launcher3.model.data.FolderInfo;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo;
-import com.android.launcher3.uioverrides.ApiWrapper;
-import com.android.launcher3.util.LauncherBindableItemsContainer;
import com.android.launcher3.views.ActivityContext;
-import com.android.launcher3.views.AllAppsButton;
-import com.android.launcher3.views.DoubleShadowBubbleTextView;
-
-import java.util.function.Predicate;
/**
* Hosts the Taskbar content such as Hotseat and Recent Apps. Drawn on top of other apps.
*/
-public class TaskbarView extends FrameLayout implements FolderIcon.FolderIconParent, Insettable {
+public class TaskbarView extends LinearLayout implements FolderIcon.FolderIconParent, Insettable {
- private static final float TASKBAR_BACKGROUND_LUMINANCE = 0.30f;
- public int mThemeIconsBackground;
-
- private final int[] mTempOutLocation = new int[2];
- private final Rect mIconLayoutBounds = new Rect();
private final int mIconTouchSize;
+ private final boolean mIsRtl;
+ private final int mTouchSlop;
+ private final RectF mTempDelegateBounds = new RectF();
+ private final RectF mDelegateSlopBounds = new RectF();
+ private final int[] mTempOutLocation = new int[2];
+
private final int mItemMarginLeftRight;
- private final int mItemPadding;
private final TaskbarActivityContext mActivityContext;
- // Initialized in init.
- private TaskbarViewController.TaskbarViewCallbacks mControllerCallbacks;
+ // Initialized in TaskbarController constructor.
private View.OnClickListener mIconClickListener;
private View.OnLongClickListener mIconLongClickListener;
+ LinearLayout mSystemButtonContainer;
+ LinearLayout mHotseatIconsContainer;
+
+ // Delegate touches to the closest view if within mIconTouchSize.
+ private boolean mDelegateTargeted;
+ private View mDelegateView;
// Prevents dispatching touches to children if true
private boolean mTouchEnabled = true;
+ private boolean mIsDraggingItem;
// Only non-null when the corresponding Folder is open.
private @Nullable FolderIcon mLeaveBehindFolderIcon;
- // Only non-null when device supports having an All Apps button.
- private @Nullable AllAppsButton mAllAppsButton;
+ /** Provider of buttons added to taskbar in 3 button nav */
+ private ButtonProvider mButtonProvider;
+
+ private boolean mDisableRelayout;
+ private boolean mAreHolesAllowed;
public TaskbarView(@NonNull Context context) {
this(context, null);
@@ -98,112 +105,85 @@ public class TaskbarView extends FrameLayout implements FolderIcon.FolderIconPar
Resources resources = getResources();
mIconTouchSize = resources.getDimensionPixelSize(R.dimen.taskbar_icon_touch_size);
+ mItemMarginLeftRight = resources.getDimensionPixelSize(R.dimen.taskbar_icon_spacing);
- int actualMargin = resources.getDimensionPixelSize(R.dimen.taskbar_icon_spacing);
- int actualIconSize = mActivityContext.getDeviceProfile().iconSizePx;
-
- // We layout the icons to be of mIconTouchSize in width and height
- mItemMarginLeftRight = actualMargin - (mIconTouchSize - actualIconSize) / 2;
- mItemPadding = (mIconTouchSize - actualIconSize) / 2;
-
- // Needed to draw folder leave-behind when opening one.
- setWillNotDraw(false);
-
- mThemeIconsBackground = calculateThemeIconsBackground();
-
- if (FeatureFlags.ENABLE_ALL_APPS_IN_TASKBAR.get()) {
- mAllAppsButton = new AllAppsButton(context);
- mAllAppsButton.setLayoutParams(
- new ViewGroup.LayoutParams(mIconTouchSize, mIconTouchSize));
- mAllAppsButton.setPadding(mItemPadding, mItemPadding, mItemPadding, mItemPadding);
- }
+ mIsRtl = Utilities.isRtl(resources);
+ mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
}
- private int getColorWithGivenLuminance(int color, float luminance) {
- float[] colorHSL = new float[3];
- ColorUtils.colorToHSL(color, colorHSL);
- colorHSL[2] = luminance;
- return ColorUtils.HSLToColor(colorHSL);
+ @Override
+ protected void onFinishInflate() {
+ super.onFinishInflate();
+ mSystemButtonContainer = findViewById(R.id.system_button_layout);
+ mHotseatIconsContainer = findViewById(R.id.hotseat_icons_layout);
}
- private int calculateThemeIconsBackground() {
- int color = ThemedIconDrawable.getColors(mContext)[0];
- if (Utilities.isDarkTheme(mContext)) {
- return getColorWithGivenLuminance(color, TASKBAR_BACKGROUND_LUMINANCE);
- }
- return color;
- }
+ protected void construct(OnClickListener clickListener, OnLongClickListener longClickListener,
+ ButtonProvider buttonProvider) {
+ mIconClickListener = clickListener;
+ mIconLongClickListener = longClickListener;
+ mButtonProvider = buttonProvider;
- protected void init(TaskbarViewController.TaskbarViewCallbacks callbacks) {
- mControllerCallbacks = callbacks;
- mIconClickListener = mControllerCallbacks.getIconOnClickListener();
- mIconLongClickListener = mControllerCallbacks.getIconOnLongClickListener();
+ if (mActivityContext.canShowNavButtons()) {
+ createNavButtons();
+ } else {
+ mSystemButtonContainer.setVisibility(GONE);
+ }
- setOnLongClickListener(mControllerCallbacks.getBackgroundOnLongClickListener());
+ int numHotseatIcons = mActivityContext.getDeviceProfile().numShownHotseatIcons;
+ updateHotseatItems(new ItemInfo[numHotseatIcons]);
+ }
- if (mAllAppsButton != null) {
- mAllAppsButton.setOnClickListener(mControllerCallbacks.getAllAppsButtonClickListener());
+ /**
+ * Enables/disables empty icons in taskbar so that the layout matches with Launcher
+ */
+ public void setHolesAllowedInLayout(boolean areHolesAllowed) {
+ if (mAreHolesAllowed != areHolesAllowed) {
+ mAreHolesAllowed = areHolesAllowed;
+ updateHotseatItemsVisibility();
+ // TODO: Add animation
}
}
- private void removeAndRecycle(View view) {
- removeView(view);
- view.setOnClickListener(null);
- view.setOnLongClickListener(null);
- if (!(view.getTag() instanceof FolderInfo)) {
- mActivityContext.getViewCache().recycleView(view.getSourceLayoutResId(), view);
+ private void setHolesAllowedInLayoutNoAnimation(boolean areHolesAllowed) {
+ if (mAreHolesAllowed != areHolesAllowed) {
+ mAreHolesAllowed = areHolesAllowed;
+ updateHotseatItemsVisibility();
+ onMeasure(makeMeasureSpec(getMeasuredWidth(), EXACTLY),
+ makeMeasureSpec(getMeasuredHeight(), EXACTLY));
+ onLayout(false, getLeft(), getTop(), getRight(), getBottom());
}
- view.setTag(null);
}
/**
* Inflates/binds the Hotseat views to show in the Taskbar given their ItemInfos.
*/
protected void updateHotseatItems(ItemInfo[] hotseatItemInfos) {
- int nextViewIndex = 0;
- int numViewsAnimated = 0;
-
- if (mAllAppsButton != null) {
- removeView(mAllAppsButton);
- }
-
for (int i = 0; i < hotseatItemInfos.length; i++) {
- ItemInfo hotseatItemInfo = hotseatItemInfos[i];
- if (hotseatItemInfo == null) {
- continue;
- }
+ ItemInfo hotseatItemInfo = hotseatItemInfos[
+ !mIsRtl ? i : hotseatItemInfos.length - i - 1];
+ View hotseatView = mHotseatIconsContainer.getChildAt(i);
// Replace any Hotseat views with the appropriate type if it's not already that type.
final int expectedLayoutResId;
boolean isFolder = false;
- if (hotseatItemInfo.isPredictedItem()) {
+ boolean needsReinflate = false;
+ if (hotseatItemInfo != null && hotseatItemInfo.isPredictedItem()) {
expectedLayoutResId = R.layout.taskbar_predicted_app_icon;
} else if (hotseatItemInfo instanceof FolderInfo) {
expectedLayoutResId = R.layout.folder_icon;
isFolder = true;
+ // Unlike for BubbleTextView, we can't reapply a new FolderInfo after inflation, so
+ // if the info changes we need to reinflate. This should only happen if a new folder
+ // is dragged to the position that another folder previously existed.
+ needsReinflate = hotseatView != null && hotseatView.getTag() != hotseatItemInfo;
} else {
expectedLayoutResId = R.layout.taskbar_app_icon;
}
-
- View hotseatView = null;
- while (nextViewIndex < getChildCount()) {
- hotseatView = getChildAt(nextViewIndex);
-
- // see if the view can be reused
- if ((hotseatView.getSourceLayoutResId() != expectedLayoutResId)
- || (isFolder && (hotseatView.getTag() != hotseatItemInfo))) {
- // Unlike for BubbleTextView, we can't reapply a new FolderInfo after inflation,
- // so if the info changes we need to reinflate. This should only happen if a new
- // folder is dragged to the position that another folder previously existed.
- removeAndRecycle(hotseatView);
- hotseatView = null;
- } else {
- // View found
- break;
- }
- }
-
- if (hotseatView == null) {
+ if (hotseatView == null
+ || hotseatView.getSourceLayoutResId() != expectedLayoutResId
+ || needsReinflate) {
+ mHotseatIconsContainer.removeView(hotseatView);
if (isFolder) {
FolderInfo folderInfo = (FolderInfo) hotseatItemInfo;
FolderIcon folderIcon = FolderIcon.inflateFolderAndIcon(expectedLayoutResId,
@@ -213,91 +193,40 @@ public class TaskbarView extends FrameLayout implements FolderIcon.FolderIconPar
} else {
hotseatView = inflate(expectedLayoutResId);
}
- LayoutParams lp = new LayoutParams(mIconTouchSize, mIconTouchSize);
- hotseatView.setPadding(mItemPadding, mItemPadding, mItemPadding, mItemPadding);
- addView(hotseatView, nextViewIndex, lp);
+ int iconSize = mActivityContext.getDeviceProfile().iconSizePx;
+ LayoutParams lp = new LayoutParams(iconSize, iconSize);
+ lp.setMargins(mItemMarginLeftRight, 0, mItemMarginLeftRight, 0);
+ mHotseatIconsContainer.addView(hotseatView, i, lp);
}
// Apply the Hotseat ItemInfos, or hide the view if there is none for a given index.
if (hotseatView instanceof BubbleTextView
&& hotseatItemInfo instanceof WorkspaceItemInfo) {
- BubbleTextView btv = (BubbleTextView) hotseatView;
- WorkspaceItemInfo workspaceInfo = (WorkspaceItemInfo) hotseatItemInfo;
-
- boolean animate = btv.shouldAnimateIconChange((WorkspaceItemInfo) hotseatItemInfo);
- btv.applyFromWorkspaceItem(workspaceInfo, animate, numViewsAnimated);
- if (animate) {
- numViewsAnimated++;
- }
+ ((BubbleTextView) hotseatView).applyFromWorkspaceItem(
+ (WorkspaceItemInfo) hotseatItemInfo);
+ hotseatView.setOnClickListener(mIconClickListener);
+ hotseatView.setOnLongClickListener(mIconLongClickListener);
+ } else if (isFolder) {
+ hotseatView.setOnClickListener(mIconClickListener);
+ hotseatView.setOnLongClickListener(mIconLongClickListener);
+ } else {
+ hotseatView.setOnClickListener(null);
+ hotseatView.setOnLongClickListener(null);
+ hotseatView.setTag(null);
}
- setClickAndLongClickListenersForIcon(hotseatView);
- nextViewIndex++;
- }
- // Remove remaining views
- while (nextViewIndex < getChildCount()) {
- removeAndRecycle(getChildAt(nextViewIndex));
+ updateHotseatItemVisibility(hotseatView);
}
-
- if (mAllAppsButton != null) {
- int index = Utilities.isRtl(getResources()) ? 0 : getChildCount();
- addView(mAllAppsButton, index);
- }
-
- mThemeIconsBackground = calculateThemeIconsBackground();
- setThemedIconsBackgroundColor(mThemeIconsBackground);
}
- /**
- * Traverse all the child views and change the background of themeIcons
- **/
- public void setThemedIconsBackgroundColor(int color) {
- for (View icon : getIconViews()) {
- if (icon instanceof DoubleShadowBubbleTextView) {
- DoubleShadowBubbleTextView textView = ((DoubleShadowBubbleTextView) icon);
- if (textView.getIcon() != null
- && textView.getIcon() instanceof ThemedIconDrawable) {
- ((ThemedIconDrawable) textView.getIcon()).changeBackgroundColor(color);
- }
- }
+ protected void updateHotseatItemsVisibility() {
+ for (int i = mHotseatIconsContainer.getChildCount() - 1; i >= 0; i--) {
+ updateHotseatItemVisibility(mHotseatIconsContainer.getChildAt(i));
}
}
- /**
- * Sets OnClickListener and OnLongClickListener for the given view.
- */
- public void setClickAndLongClickListenersForIcon(View icon) {
- icon.setOnClickListener(mIconClickListener);
- icon.setOnLongClickListener(mIconLongClickListener);
- }
-
- @Override
- protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
- int count = getChildCount();
- int spaceNeeded = count * (mItemMarginLeftRight * 2 + mIconTouchSize);
- int navSpaceNeeded = ApiWrapper.getHotseatEndOffset(getContext());
- boolean layoutRtl = isLayoutRtl();
- int iconEnd = right - (right - left - spaceNeeded) / 2;
- boolean needMoreSpaceForNav = layoutRtl ?
- navSpaceNeeded > (iconEnd - spaceNeeded) :
- iconEnd > (right - navSpaceNeeded);
- if (needMoreSpaceForNav) {
- int offset = layoutRtl ?
- navSpaceNeeded - (iconEnd - spaceNeeded) :
- (right - navSpaceNeeded) - iconEnd;
- iconEnd += offset;
- }
- // Layout the children
- mIconLayoutBounds.right = iconEnd;
- mIconLayoutBounds.top = (bottom - top - mIconTouchSize) / 2;
- mIconLayoutBounds.bottom = mIconLayoutBounds.top + mIconTouchSize;
- for (int i = count; i > 0; i--) {
- View child = getChildAt(i - 1);
- iconEnd -= mItemMarginLeftRight;
- int iconStart = iconEnd - mIconTouchSize;
- child.layout(iconStart, mIconLayoutBounds.top, iconEnd, mIconLayoutBounds.bottom);
- iconEnd = iconStart - mItemMarginLeftRight;
- }
- mIconLayoutBounds.left = iconEnd;
+ private void updateHotseatItemVisibility(View hotseatView) {
+ hotseatView.setVisibility(
+ hotseatView.getTag() != null ? VISIBLE : (mAreHolesAllowed ? INVISIBLE : GONE));
}
@Override
@@ -310,27 +239,87 @@ public class TaskbarView extends FrameLayout implements FolderIcon.FolderIconPar
@Override
public boolean onTouchEvent(MotionEvent event) {
- if (!mTouchEnabled) {
- return true;
+ boolean handled = delegateTouchIfNecessary(event);
+ return super.onTouchEvent(event) || handled;
+ }
+
+ public void setTouchesEnabled(boolean touchEnabled) {
+ this.mTouchEnabled = touchEnabled;
+ }
+
+ /**
+ * User touched the Taskbar background. Determine whether the touch is close enough to a view
+ * that we should forward the touches to it.
+ * @return Whether a delegate view was chosen and it handled the touch event.
+ */
+ private boolean delegateTouchIfNecessary(MotionEvent event) {
+ final float x = event.getX();
+ final float y = event.getY();
+ if (mDelegateView == null && event.getAction() == MotionEvent.ACTION_DOWN) {
+ View delegateView = findDelegateView(x, y);
+ if (delegateView != null) {
+ mDelegateTargeted = true;
+ mDelegateView = delegateView;
+ mDelegateSlopBounds.set(mTempDelegateBounds);
+ mDelegateSlopBounds.inset(-mTouchSlop, -mTouchSlop);
+ }
}
- if (mIconLayoutBounds.left <= event.getX() && event.getX() <= mIconLayoutBounds.right) {
- // Don't allow long pressing between icons, or above/below them.
- return true;
+
+ boolean sendToDelegate = mDelegateTargeted;
+ boolean inBounds = true;
+ switch (event.getAction()) {
+ case MotionEvent.ACTION_MOVE:
+ inBounds = mDelegateSlopBounds.contains(x, y);
+ break;
+ case MotionEvent.ACTION_UP:
+ case MotionEvent.ACTION_CANCEL:
+ mDelegateTargeted = false;
+ break;
}
- if (mControllerCallbacks.onTouchEvent(event)) {
- int oldAction = event.getAction();
- try {
- event.setAction(MotionEvent.ACTION_CANCEL);
- return super.onTouchEvent(event);
- } finally {
- event.setAction(oldAction);
+
+ boolean handled = false;
+ if (sendToDelegate) {
+ if (inBounds) {
+ // Offset event coordinates to be inside the target view
+ event.setLocation(mDelegateView.getWidth() / 2f, mDelegateView.getHeight() / 2f);
+ } else {
+ // Offset event coordinates to be outside the target view (in case it does
+ // something like tracking pressed state)
+ event.setLocation(-mTouchSlop * 2, -mTouchSlop * 2);
+ }
+ handled = mDelegateView.dispatchTouchEvent(event);
+ // Cleanup if this was the last event to send to the delegate.
+ if (!mDelegateTargeted) {
+ mDelegateView = null;
}
}
- return super.onTouchEvent(event);
+ return handled;
}
- public void setTouchesEnabled(boolean touchEnabled) {
- this.mTouchEnabled = touchEnabled;
+ /**
+ * Return an item whose touch bounds contain the given coordinates,
+ * or null if no such item exists.
+ *
+ * Also sets {@link #mTempDelegateBounds} to be the touch bounds of the chosen delegate view.
+ */
+ private @Nullable View findDelegateView(float x, float y) {
+ for (int i = 0; i < getChildCount(); i++) {
+ View child = getChildAt(i);
+ if (!child.isShown() || !child.isClickable()) {
+ continue;
+ }
+ int childCenterX = child.getLeft() + child.getWidth() / 2;
+ int childCenterY = child.getTop() + child.getHeight() / 2;
+ mTempDelegateBounds.set(
+ childCenterX - mIconTouchSize / 2f,
+ childCenterY - mIconTouchSize / 2f,
+ childCenterX + mIconTouchSize / 2f,
+ childCenterY + mIconTouchSize / 2f);
+ if (mTempDelegateBounds.contains(x, y)) {
+ return child;
+ }
+ }
+ return null;
}
/**
@@ -339,32 +328,69 @@ public class TaskbarView extends FrameLayout implements FolderIcon.FolderIconPar
*/
public boolean isEventOverAnyItem(MotionEvent ev) {
getLocationOnScreen(mTempOutLocation);
- int xInOurCoordinates = (int) ev.getX() - mTempOutLocation[0];
- int yInOurCoorindates = (int) ev.getY() - mTempOutLocation[1];
- return isShown() && mIconLayoutBounds.contains(xInOurCoordinates, yInOurCoorindates);
- }
-
- public Rect getIconLayoutBounds() {
- return mIconLayoutBounds;
+ float xInOurCoordinates = ev.getX() - mTempOutLocation[0];
+ float yInOurCoorindates = ev.getY() - mTempOutLocation[1];
+ return findDelegateView(xInOurCoordinates, yInOurCoorindates) != null;
}
/**
- * Returns the app icons currently shown in the taskbar.
+ * Add back/home/recents buttons into a single ViewGroup that will be inserted at
+ * {@param navButtonStartIndex}
*/
- public View[] getIconViews() {
- final int count = getChildCount();
- View[] icons = new View[count];
- for (int i = 0; i < count; i++) {
- icons[i] = getChildAt(i);
+ private void createNavButtons() {
+ LinearLayout.LayoutParams buttonParams = new LinearLayout.LayoutParams(
+ mActivityContext.getDeviceProfile().iconSizePx,
+ mActivityContext.getDeviceProfile().iconSizePx
+ );
+ buttonParams.gravity = Gravity.CENTER;
+
+ mSystemButtonContainer.addView(mButtonProvider.getBack(), buttonParams);
+ mSystemButtonContainer.addView(mButtonProvider.getHome(), buttonParams);
+ mSystemButtonContainer.addView(mButtonProvider.getRecents(), buttonParams);
+ }
+
+ @Override
+ public boolean onDragEvent(DragEvent event) {
+ switch (event.getAction()) {
+ case DragEvent.ACTION_DRAG_STARTED:
+ mIsDraggingItem = true;
+ AbstractFloatingView.closeAllOpenViews(mActivityContext);
+ return true;
+ case DragEvent.ACTION_DRAG_ENDED:
+ mIsDraggingItem = false;
+ break;
}
- return icons;
+ return super.onDragEvent(event);
+ }
+
+ public boolean isDraggingItem() {
+ return mIsDraggingItem;
}
/**
- * Returns the all apps button in the taskbar.
+ * @return The bounding box of where the hotseat elements are relative to this TaskbarView.
*/
- public View getAllAppsButtonView() {
- return mAllAppsButton;
+ protected RectF getHotseatBounds() {
+ RectF result;
+ mDisableRelayout = true;
+ boolean wereHolesAllowed = mAreHolesAllowed;
+ setHolesAllowedInLayoutNoAnimation(true);
+ result = new RectF(
+ mHotseatIconsContainer.getLeft(),
+ mHotseatIconsContainer.getTop(),
+ mHotseatIconsContainer.getRight(),
+ mHotseatIconsContainer.getBottom());
+ setHolesAllowedInLayoutNoAnimation(wereHolesAllowed);
+ mDisableRelayout = false;
+
+ return result;
+ }
+
+ @Override
+ public void requestLayout() {
+ if (!mDisableRelayout) {
+ super.requestLayout();
+ }
}
// FolderIconParent implemented methods.
@@ -395,7 +421,7 @@ public class TaskbarView extends FrameLayout implements FolderIcon.FolderIconPar
}
private View inflate(@LayoutRes int layoutResId) {
- return mActivityContext.getViewCache().getView(layoutResId, mActivityContext, this);
+ return mActivityContext.getLayoutInflater().inflate(layoutResId, this, false);
}
@Override
@@ -403,42 +429,11 @@ public class TaskbarView extends FrameLayout implements FolderIcon.FolderIconPar
// Ignore, we just implement Insettable to draw behind system insets.
}
- public boolean areIconsVisible() {
- // Consider the overall visibility
- return getVisibility() == VISIBLE;
- }
-
- /**
- * Maps {@code op} over all the child views.
- */
- public void mapOverItems(LauncherBindableItemsContainer.ItemOperator op) {
- // map over all the shortcuts on the taskbar
- for (int i = 0; i < getChildCount(); i++) {
- View item = getChildAt(i);
- if (op.evaluate((ItemInfo) item.getTag(), item)) {
- return;
- }
- }
+ public void setIconsVisibility(boolean isVisible) {
+ mHotseatIconsContainer.setVisibility(isVisible ? VISIBLE : INVISIBLE);
}
- /**
- * Finds the first icon to match one of the given matchers, from highest to lowest priority.
- * @return The first match, or All Apps button if no match was found.
- */
- public View getFirstMatch(Predicate<ItemInfo>... matchers) {
- for (Predicate<ItemInfo> matcher : matchers) {
- for (int i = 0; i < getChildCount(); i++) {
- View item = getChildAt(i);
- if (!(item.getTag() instanceof ItemInfo)) {
- // Should only happen for All Apps button.
- continue;
- }
- ItemInfo info = (ItemInfo) item.getTag();
- if (matcher.test(info)) {
- return item;
- }
- }
- }
- return mAllAppsButton;
+ public boolean areIconsVisible() {
+ return mHotseatIconsContainer.getVisibility() == VISIBLE;
}
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java
deleted file mode 100644
index 3562f5bc3c..0000000000
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java
+++ /dev/null
@@ -1,421 +0,0 @@
-/*
- * Copyright (C) 2021 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.launcher3.taskbar;
-
-import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY;
-import static com.android.launcher3.Utilities.squaredHypot;
-import static com.android.launcher3.anim.Interpolators.LINEAR;
-import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASKBAR_ALLAPPS_BUTTON_TAP;
-import static com.android.quickstep.AnimatedFloat.VALUE;
-
-import android.annotation.NonNull;
-import android.graphics.Rect;
-import android.util.FloatProperty;
-import android.util.Log;
-import android.view.MotionEvent;
-import android.view.View;
-
-import androidx.core.graphics.ColorUtils;
-import androidx.core.view.OneShotPreDrawListener;
-
-import com.android.launcher3.BubbleTextView;
-import com.android.launcher3.DeviceProfile;
-import com.android.launcher3.LauncherAppState;
-import com.android.launcher3.Utilities;
-import com.android.launcher3.anim.AnimatorPlaybackController;
-import com.android.launcher3.anim.PendingAnimation;
-import com.android.launcher3.config.FeatureFlags;
-import com.android.launcher3.folder.FolderIcon;
-import com.android.launcher3.icons.ThemedIconDrawable;
-import com.android.launcher3.model.data.ItemInfo;
-import com.android.launcher3.util.ItemInfoMatcher;
-import com.android.launcher3.util.LauncherBindableItemsContainer;
-import com.android.launcher3.util.MultiValueAlpha;
-import com.android.quickstep.AnimatedFloat;
-
-import java.io.PrintWriter;
-import java.util.function.Predicate;
-
-/**
- * Handles properties/data collection, then passes the results to TaskbarView to render.
- */
-public class TaskbarViewController implements TaskbarControllers.LoggableTaskbarController {
-
- private static final String TAG = TaskbarViewController.class.getSimpleName();
-
- private static final Runnable NO_OP = () -> { };
-
- public static final int ALPHA_INDEX_HOME = 0;
- public static final int ALPHA_INDEX_KEYGUARD = 1;
- public static final int ALPHA_INDEX_STASH = 2;
- public static final int ALPHA_INDEX_RECENTS_DISABLED = 3;
- public static final int ALPHA_INDEX_NOTIFICATION_EXPANDED = 4;
- private static final int NUM_ALPHA_CHANNELS = 5;
-
- private final TaskbarActivityContext mActivity;
- private final TaskbarView mTaskbarView;
- private final MultiValueAlpha mTaskbarIconAlpha;
- private final AnimatedFloat mTaskbarIconScaleForStash = new AnimatedFloat(this::updateScale);
- private final AnimatedFloat mTaskbarIconTranslationYForHome = new AnimatedFloat(
- this::updateTranslationY);
- private final AnimatedFloat mTaskbarIconTranslationYForStash = new AnimatedFloat(
- this::updateTranslationY);
- private AnimatedFloat mTaskbarNavButtonTranslationY;
- private AnimatedFloat mTaskbarNavButtonTranslationYForInAppDisplay;
-
- private final AnimatedFloat mThemeIconsBackground = new AnimatedFloat(
- this::updateIconsBackground);
-
- private final TaskbarModelCallbacks mModelCallbacks;
-
- // Initialized in init.
- private TaskbarControllers mControllers;
-
- // Animation to align icons with Launcher, created lazily. This allows the controller to be
- // active only during the animation and does not need to worry about layout changes.
- private AnimatorPlaybackController mIconAlignControllerLazy = null;
- private Runnable mOnControllerPreCreateCallback = NO_OP;
-
- private int mThemeIconsColor;
-
- public TaskbarViewController(TaskbarActivityContext activity, TaskbarView taskbarView) {
- mActivity = activity;
- mTaskbarView = taskbarView;
- mTaskbarIconAlpha = new MultiValueAlpha(mTaskbarView, NUM_ALPHA_CHANNELS);
- mTaskbarIconAlpha.setUpdateVisibility(true);
- mModelCallbacks = new TaskbarModelCallbacks(activity, mTaskbarView);
- }
-
- public void init(TaskbarControllers controllers) {
- mControllers = controllers;
- mTaskbarView.init(new TaskbarViewCallbacks());
- mTaskbarView.getLayoutParams().height = mActivity.getDeviceProfile().taskbarSize;
- mThemeIconsColor = ThemedIconDrawable.getColors(mTaskbarView.getContext())[0];
-
- mTaskbarIconScaleForStash.updateValue(1f);
-
- mModelCallbacks.init(controllers);
- if (mActivity.isUserSetupComplete()) {
- // Only load the callbacks if user setup is completed
- LauncherAppState.getInstance(mActivity).getModel().addCallbacksAndLoad(mModelCallbacks);
- }
- mTaskbarNavButtonTranslationY =
- controllers.navbarButtonsViewController.getTaskbarNavButtonTranslationY();
- mTaskbarNavButtonTranslationYForInAppDisplay = controllers.navbarButtonsViewController
- .getTaskbarNavButtonTranslationYForInAppDisplay();
- }
-
- public void onDestroy() {
- LauncherAppState.getInstance(mActivity).getModel().removeCallbacks(mModelCallbacks);
- }
-
- public boolean areIconsVisible() {
- return mTaskbarView.areIconsVisible();
- }
-
- public MultiValueAlpha getTaskbarIconAlpha() {
- return mTaskbarIconAlpha;
- }
-
- /**
- * Should be called when the IME visibility changes, so we can make Taskbar not steal touches.
- */
- public void setImeIsVisible(boolean isImeVisible) {
- mTaskbarView.setTouchesEnabled(!isImeVisible);
- }
-
- /**
- * Should be called when the recents button is disabled, so we can hide taskbar icons as well.
- */
- public void setRecentsButtonDisabled(boolean isDisabled) {
- // TODO: check TaskbarStashController#supportsStashing(), to stash instead of setting alpha.
- mTaskbarIconAlpha.getProperty(ALPHA_INDEX_RECENTS_DISABLED).setValue(isDisabled ? 0 : 1);
- }
-
- /**
- * Sets OnClickListener and OnLongClickListener for the given view.
- */
- public void setClickAndLongClickListenersForIcon(View icon) {
- mTaskbarView.setClickAndLongClickListenersForIcon(icon);
- }
-
- /**
- * Adds one time pre draw listener to the taskbar view, it is called before
- * drawing a frame and invoked only once
- * @param listener callback that will be invoked before drawing the next frame
- */
- public void addOneTimePreDrawListener(@NonNull Runnable listener) {
- OneShotPreDrawListener.add(mTaskbarView, listener);
- }
-
- public Rect getIconLayoutBounds() {
- return mTaskbarView.getIconLayoutBounds();
- }
-
- public View[] getIconViews() {
- return mTaskbarView.getIconViews();
- }
-
- public View getAllAppsButtonView() {
- return mTaskbarView.getAllAppsButtonView();
- }
-
- public AnimatedFloat getTaskbarIconScaleForStash() {
- return mTaskbarIconScaleForStash;
- }
-
- public AnimatedFloat getTaskbarIconTranslationYForStash() {
- return mTaskbarIconTranslationYForStash;
- }
-
- /**
- * Applies scale properties for the entire TaskbarView (rather than individual icons).
- */
- private void updateScale() {
- float scale = mTaskbarIconScaleForStash.value;
- mTaskbarView.setScaleX(scale);
- mTaskbarView.setScaleY(scale);
- }
-
- private void updateTranslationY() {
- mTaskbarView.setTranslationY(mTaskbarIconTranslationYForHome.value
- + mTaskbarIconTranslationYForStash.value);
- }
-
- private void updateIconsBackground() {
- mTaskbarView.setThemedIconsBackgroundColor(
- ColorUtils.blendARGB(
- mThemeIconsColor,
- mTaskbarView.mThemeIconsBackground,
- mThemeIconsBackground.value
- ));
- }
-
- /**
- * Sets the taskbar icon alignment relative to Launcher hotseat icons
- * @param alignmentRatio [0, 1]
- * 0 => not aligned
- * 1 => fully aligned
- */
- public void setLauncherIconAlignment(float alignmentRatio, DeviceProfile launcherDp) {
- if (mIconAlignControllerLazy == null) {
- mIconAlignControllerLazy = createIconAlignmentController(launcherDp);
- }
- mIconAlignControllerLazy.setPlayFraction(alignmentRatio);
- if (alignmentRatio <= 0 || alignmentRatio >= 1) {
- // Cleanup lazy controller so that it is created again in next animation
- mIconAlignControllerLazy = null;
- }
- }
-
- /**
- * Creates an animation for aligning the taskbar icons with the provided Launcher device profile
- */
- private AnimatorPlaybackController createIconAlignmentController(DeviceProfile launcherDp) {
- mOnControllerPreCreateCallback.run();
- PendingAnimation setter = new PendingAnimation(100);
- Rect hotseatPadding = launcherDp.getHotseatLayoutPadding(mActivity);
- float scaleUp = ((float) launcherDp.iconSizePx) / mActivity.getDeviceProfile().iconSizePx;
- int borderSpacing = launcherDp.hotseatBorderSpace;
- int hotseatCellSize = DeviceProfile.calculateCellWidth(
- launcherDp.availableWidthPx - hotseatPadding.left - hotseatPadding.right,
- borderSpacing,
- launcherDp.numShownHotseatIcons);
-
- int offsetY = launcherDp.getTaskbarOffsetY();
- setter.setFloat(mTaskbarIconTranslationYForHome, VALUE, -offsetY, LINEAR);
- setter.setFloat(mTaskbarNavButtonTranslationY, VALUE, -offsetY, LINEAR);
- setter.setFloat(mTaskbarNavButtonTranslationYForInAppDisplay, VALUE, offsetY, LINEAR);
-
- if (Utilities.isDarkTheme(mTaskbarView.getContext())) {
- setter.addFloat(mThemeIconsBackground, VALUE, 0f, 1f, LINEAR);
- }
-
- int collapsedHeight = mActivity.getDefaultTaskbarWindowHeight();
- int expandedHeight = Math.max(collapsedHeight,
- mActivity.getDeviceProfile().taskbarSize + offsetY);
- setter.addOnFrameListener(anim -> mActivity.setTaskbarWindowHeight(
- anim.getAnimatedFraction() > 0 ? expandedHeight : collapsedHeight));
-
- for (int i = 0; i < mTaskbarView.getChildCount(); i++) {
- View child = mTaskbarView.getChildAt(i);
-
- int positionInHotseat;
- if (FeatureFlags.ENABLE_ALL_APPS_IN_TASKBAR.get()
- && child == mTaskbarView.getAllAppsButtonView()) {
- // Note that there is no All Apps button in the hotseat, this position is only used
- // as its convenient for animation purposes.
- positionInHotseat = Utilities.isRtl(child.getResources())
- ? -1
- : mActivity.getDeviceProfile().numShownHotseatIcons;
-
- if (!FeatureFlags.ENABLE_ALL_APPS_BUTTON_IN_HOTSEAT.get()) {
- setter.setViewAlpha(child, 0, LINEAR);
- }
- } else if (child.getTag() instanceof ItemInfo) {
- positionInHotseat = ((ItemInfo) child.getTag()).screenId;
- } else {
- Log.w(TAG, "Unsupported view found in createIconAlignmentController, v=" + child);
- continue;
- }
-
- float hotseatIconCenter = hotseatPadding.left
- + (hotseatCellSize + borderSpacing) * positionInHotseat
- + hotseatCellSize / 2f;
-
- float childCenter = (child.getLeft() + child.getRight()) / 2f;
- setter.setFloat(child, ICON_TRANSLATE_X, hotseatIconCenter - childCenter, LINEAR);
-
- setter.setFloat(child, SCALE_PROPERTY, scaleUp, LINEAR);
- }
-
- AnimatorPlaybackController controller = setter.createPlaybackController();
- mOnControllerPreCreateCallback = () -> controller.setPlayFraction(0);
- return controller;
- }
-
- public void onRotationChanged(DeviceProfile deviceProfile) {
- if (mControllers.taskbarStashController.isInApp()) {
- // We only translate on rotation when on home
- return;
- }
- mActivity.setTaskbarWindowHeight(
- deviceProfile.taskbarSize + deviceProfile.getTaskbarOffsetY());
- mTaskbarNavButtonTranslationY.updateValue(-deviceProfile.getTaskbarOffsetY());
- }
-
- /**
- * Maps the given operator to all the top-level children of TaskbarView.
- */
- public void mapOverItems(LauncherBindableItemsContainer.ItemOperator op) {
- mTaskbarView.mapOverItems(op);
- }
-
- /**
- * Returns the first icon to match the given parameter, in priority from:
- * 1) Icons directly on Taskbar
- * 2) FolderIcon of the Folder containing the given icon
- * 3) All Apps button
- */
- public View getFirstIconMatch(Predicate<ItemInfo> matcher) {
- Predicate<ItemInfo> folderMatcher = ItemInfoMatcher.forFolderMatch(matcher);
- return mTaskbarView.getFirstMatch(matcher, folderMatcher);
- }
-
- /**
- * Returns whether the given MotionEvent, *in screen coorindates*, is within any Taskbar item's
- * touch bounds.
- */
- public boolean isEventOverAnyItem(MotionEvent ev) {
- return mTaskbarView.isEventOverAnyItem(ev);
- }
-
- @Override
- public void dumpLogs(String prefix, PrintWriter pw) {
- pw.println(prefix + "TaskbarViewController:");
- mModelCallbacks.dumpLogs(prefix + "\t", pw);
- }
-
- /**
- * Callbacks for {@link TaskbarView} to interact with its controller.
- */
- public class TaskbarViewCallbacks {
- private final float mSquaredTouchSlop = Utilities.squaredTouchSlop(mActivity);
-
- private float mDownX, mDownY;
- private boolean mCanceledStashHint;
-
- public View.OnClickListener getIconOnClickListener() {
- return mActivity.getItemOnClickListener();
- }
-
- public View.OnClickListener getAllAppsButtonClickListener() {
- return v -> {
- mActivity.getStatsLogManager().logger().log(LAUNCHER_TASKBAR_ALLAPPS_BUTTON_TAP);
- mControllers.taskbarAllAppsController.show();
- };
- }
-
- public View.OnLongClickListener getIconOnLongClickListener() {
- return mControllers.taskbarDragController::startDragOnLongClick;
- }
-
- public View.OnLongClickListener getBackgroundOnLongClickListener() {
- return view -> mControllers.taskbarStashController
- .updateAndAnimateIsManuallyStashedInApp(true);
- }
-
- /**
- * Get the first chance to handle TaskbarView#onTouchEvent, and return whether we want to
- * consume the touch so TaskbarView treats it as an ACTION_CANCEL.
- */
- public boolean onTouchEvent(MotionEvent motionEvent) {
- final float x = motionEvent.getRawX();
- final float y = motionEvent.getRawY();
- switch (motionEvent.getAction()) {
- case MotionEvent.ACTION_DOWN:
- mDownX = x;
- mDownY = y;
- mControllers.taskbarStashController.startStashHint(/* animateForward = */ true);
- mCanceledStashHint = false;
- break;
- case MotionEvent.ACTION_MOVE:
- if (!mCanceledStashHint
- && squaredHypot(mDownX - x, mDownY - y) > mSquaredTouchSlop) {
- mControllers.taskbarStashController.startStashHint(
- /* animateForward= */ false);
- mCanceledStashHint = true;
- return true;
- }
- break;
- case MotionEvent.ACTION_UP:
- case MotionEvent.ACTION_CANCEL:
- if (!mCanceledStashHint) {
- mControllers.taskbarStashController.startStashHint(
- /* animateForward= */ false);
- }
- break;
- }
- return false;
- }
- }
-
- public static final FloatProperty<View> ICON_TRANSLATE_X =
- new FloatProperty<View>("taskbarAligmentTranslateX") {
-
- @Override
- public void setValue(View view, float v) {
- if (view instanceof BubbleTextView) {
- ((BubbleTextView) view).setTranslationXForTaskbarAlignmentAnimation(v);
- } else if (view instanceof FolderIcon) {
- ((FolderIcon) view).setTranslationForTaskbarAlignmentAnimation(v);
- } else {
- view.setTranslationX(v);
- }
- }
-
- @Override
- public Float get(View view) {
- if (view instanceof BubbleTextView) {
- return ((BubbleTextView) view)
- .getTranslationXForTaskbarAlignmentAnimation();
- } else if (view instanceof FolderIcon) {
- return ((FolderIcon) view).getTranslationXForTaskbarAlignmentAnimation();
- }
- return view.getTranslationX();
- }
- };
-}
diff --git a/quickstep/src/com/android/launcher3/taskbar/Utilities.java b/quickstep/src/com/android/launcher3/taskbar/Utilities.java
deleted file mode 100644
index fda6453e7d..0000000000
--- a/quickstep/src/com/android/launcher3/taskbar/Utilities.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.launcher3.taskbar;
-
-import java.util.StringJoiner;
-
-/**
- * Various utilities shared amongst the Taskbar's classes.
- */
-public final class Utilities {
-
- private Utilities() {}
-
- static void appendFlag(StringJoiner str, int flags, int flag, String flagName) {
- if ((flags & flag) != 0) {
- str.add(flagName);
- }
- }
-}
diff --git a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsContainerView.java b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsContainerView.java
deleted file mode 100644
index 51fa4d9f3a..0000000000
--- a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsContainerView.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.launcher3.taskbar.allapps;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.view.WindowInsets;
-
-import com.android.launcher3.allapps.ActivityAllAppsContainerView;
-import com.android.launcher3.allapps.AllAppsGridAdapter;
-import com.android.launcher3.allapps.AlphabeticalAppsList;
-import com.android.launcher3.allapps.BaseAdapterProvider;
-import com.android.launcher3.allapps.BaseAllAppsAdapter;
-
-/** All apps container accessible from taskbar. */
-public class TaskbarAllAppsContainerView extends
- ActivityAllAppsContainerView<TaskbarAllAppsContext> {
-
- public TaskbarAllAppsContainerView(Context context, AttributeSet attrs) {
- this(context, attrs, 0);
- }
-
- public TaskbarAllAppsContainerView(Context context, AttributeSet attrs, int defStyleAttr) {
- super(context, attrs, defStyleAttr);
- }
-
- @Override
- public WindowInsets onApplyWindowInsets(WindowInsets insets) {
- setInsets(insets.getInsets(WindowInsets.Type.systemBars()).toRect());
- return super.onApplyWindowInsets(insets);
- }
-
- @Override
- protected BaseAllAppsAdapter<TaskbarAllAppsContext> createAdapter(
- AlphabeticalAppsList<TaskbarAllAppsContext> appsList,
- BaseAdapterProvider[] adapterProviders) {
- return new AllAppsGridAdapter<>(mActivityContext, getLayoutInflater(), appsList,
- adapterProviders);
- }
-}
diff --git a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsContext.java b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsContext.java
deleted file mode 100644
index e2f752212e..0000000000
--- a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsContext.java
+++ /dev/null
@@ -1,249 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.launcher3.taskbar.allapps;
-
-import static android.view.KeyEvent.ACTION_UP;
-import static android.view.KeyEvent.KEYCODE_BACK;
-import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
-
-import static com.android.systemui.shared.system.ViewTreeObserverWrapper.InsetsInfo.TOUCHABLE_INSETS_REGION;
-
-import android.content.Context;
-import android.graphics.Insets;
-import android.view.KeyEvent;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.WindowInsets;
-
-import com.android.launcher3.AbstractFloatingView;
-import com.android.launcher3.DeviceProfile;
-import com.android.launcher3.R;
-import com.android.launcher3.Utilities;
-import com.android.launcher3.allapps.ActivityAllAppsContainerView;
-import com.android.launcher3.allapps.search.DefaultSearchAdapterProvider;
-import com.android.launcher3.allapps.search.SearchAdapterProvider;
-import com.android.launcher3.dot.DotInfo;
-import com.android.launcher3.model.data.ItemInfo;
-import com.android.launcher3.popup.PopupDataProvider;
-import com.android.launcher3.taskbar.BaseTaskbarContext;
-import com.android.launcher3.taskbar.TaskbarActivityContext;
-import com.android.launcher3.taskbar.TaskbarDragController;
-import com.android.launcher3.taskbar.TaskbarStashController;
-import com.android.launcher3.testing.TestLogging;
-import com.android.launcher3.testing.TestProtocol;
-import com.android.launcher3.util.OnboardingPrefs;
-import com.android.launcher3.util.TouchController;
-import com.android.launcher3.views.BaseDragLayer;
-import com.android.systemui.shared.system.ViewTreeObserverWrapper;
-import com.android.systemui.shared.system.ViewTreeObserverWrapper.InsetsInfo;
-import com.android.systemui.shared.system.ViewTreeObserverWrapper.OnComputeInsetsListener;
-
-/**
- * Window context for the taskbar all apps overlay.
- * <p>
- * All apps has its own window and needs a window context. Some properties are delegated to the
- * {@link TaskbarActivityContext} such as {@link DeviceProfile} and {@link PopupDataProvider}.
- */
-class TaskbarAllAppsContext extends BaseTaskbarContext {
- private final TaskbarActivityContext mTaskbarContext;
- private final OnboardingPrefs<TaskbarAllAppsContext> mOnboardingPrefs;
-
- private final TaskbarAllAppsController mWindowController;
- private final TaskbarAllAppsViewController mAllAppsViewController;
- private final TaskbarDragController mDragController;
- private final TaskbarAllAppsDragLayer mDragLayer;
- private final TaskbarAllAppsContainerView mAppsView;
-
- // We automatically stash taskbar when all apps is opened in gesture navigation mode.
- private final boolean mWillTaskbarBeVisuallyStashed;
- private final int mStashedTaskbarHeight;
-
- TaskbarAllAppsContext(
- TaskbarActivityContext taskbarContext,
- TaskbarAllAppsController windowController,
- TaskbarStashController taskbarStashController) {
- super(taskbarContext.createWindowContext(TYPE_APPLICATION_OVERLAY, null));
- mTaskbarContext = taskbarContext;
- mWindowController = windowController;
- mDragController = new TaskbarDragController(this);
- mOnboardingPrefs = new OnboardingPrefs<>(this, Utilities.getPrefs(this));
-
- mDragLayer = new TaskbarAllAppsDragLayer(this);
- TaskbarAllAppsSlideInView slideInView = (TaskbarAllAppsSlideInView) mLayoutInflater.inflate(
- R.layout.taskbar_all_apps, mDragLayer, false);
- mAllAppsViewController = new TaskbarAllAppsViewController(
- this,
- slideInView,
- windowController,
- taskbarStashController);
- mAppsView = slideInView.getAppsView();
-
- mWillTaskbarBeVisuallyStashed = taskbarStashController.supportsVisualStashing();
- mStashedTaskbarHeight = taskbarStashController.getStashedHeight();
- }
-
- TaskbarAllAppsViewController getAllAppsViewController() {
- return mAllAppsViewController;
- }
-
- @Override
- public DeviceProfile getDeviceProfile() {
- return mWindowController.getDeviceProfile();
- }
-
- @Override
- public TaskbarDragController getDragController() {
- return mDragController;
- }
-
- @Override
- public TaskbarAllAppsDragLayer getDragLayer() {
- return mDragLayer;
- }
-
- @Override
- public TaskbarAllAppsContainerView getAppsView() {
- return mAppsView;
- }
-
- @Override
- public OnboardingPrefs<TaskbarAllAppsContext> getOnboardingPrefs() {
- return mOnboardingPrefs;
- }
-
- @Override
- public boolean isBindingItems() {
- return mTaskbarContext.isBindingItems();
- }
-
- @Override
- public View.OnClickListener getItemOnClickListener() {
- return mTaskbarContext.getItemOnClickListener();
- }
-
- @Override
- public PopupDataProvider getPopupDataProvider() {
- return mTaskbarContext.getPopupDataProvider();
- }
-
- @Override
- public DotInfo getDotInfoForItem(ItemInfo info) {
- return mTaskbarContext.getDotInfoForItem(info);
- }
-
- @Override
- public void onDragStart() {}
-
- @Override
- public void onDragEnd() {
- mWindowController.maybeCloseWindow();
- }
-
- @Override
- public void onPopupVisibilityChanged(boolean isVisible) {}
-
- @Override
- public SearchAdapterProvider<?> createSearchAdapterProvider(
- ActivityAllAppsContainerView<?> appsView) {
- return new DefaultSearchAdapterProvider(this);
- }
-
- /** Root drag layer for this context. */
- private static class TaskbarAllAppsDragLayer extends
- BaseDragLayer<TaskbarAllAppsContext> implements OnComputeInsetsListener {
-
- private TaskbarAllAppsDragLayer(Context context) {
- super(context, null, 1);
- setClipChildren(false);
- recreateControllers();
- }
-
- @Override
- protected void onAttachedToWindow() {
- super.onAttachedToWindow();
- ViewTreeObserverWrapper.addOnComputeInsetsListener(
- getViewTreeObserver(), this);
- }
-
- @Override
- protected void onDetachedFromWindow() {
- super.onDetachedFromWindow();
- ViewTreeObserverWrapper.removeOnComputeInsetsListener(this);
- }
-
- @Override
- public void recreateControllers() {
- mControllers = new TouchController[]{mActivity.mDragController};
- }
-
- @Override
- public boolean dispatchTouchEvent(MotionEvent ev) {
- TestLogging.recordMotionEvent(TestProtocol.SEQUENCE_MAIN, "Touch event", ev);
- return super.dispatchTouchEvent(ev);
- }
-
- @Override
- public boolean dispatchKeyEvent(KeyEvent event) {
- if (event.getAction() == ACTION_UP && event.getKeyCode() == KEYCODE_BACK) {
- AbstractFloatingView topView = AbstractFloatingView.getTopOpenView(mActivity);
- if (topView != null && topView.onBackPressed()) {
- return true;
- }
- }
- return super.dispatchKeyEvent(event);
- }
-
- @Override
- public void onComputeInsets(InsetsInfo inoutInfo) {
- if (mActivity.mDragController.isSystemDragInProgress()) {
- inoutInfo.touchableRegion.setEmpty();
- inoutInfo.setTouchableInsets(TOUCHABLE_INSETS_REGION);
- }
- }
-
- @Override
- public WindowInsets onApplyWindowInsets(WindowInsets insets) {
- return updateInsetsDueToStashing(insets);
- }
-
- /**
- * Taskbar automatically stashes when opening all apps, but we don't report the insets as
- * changing to avoid moving the underlying app. But internally, the apps view should still
- * layout according to the stashed insets rather than the unstashed insets. So this method
- * does two things:
- * 1) Sets navigationBars bottom inset to stashedHeight.
- * 2) Sets tappableInsets bottom inset to 0.
- */
- private WindowInsets updateInsetsDueToStashing(WindowInsets oldInsets) {
- if (!mActivity.mWillTaskbarBeVisuallyStashed) {
- return oldInsets;
- }
- WindowInsets.Builder updatedInsetsBuilder = new WindowInsets.Builder(oldInsets);
-
- Insets oldNavInsets = oldInsets.getInsets(WindowInsets.Type.navigationBars());
- Insets newNavInsets = Insets.of(oldNavInsets.left, oldNavInsets.top, oldNavInsets.right,
- mActivity.mStashedTaskbarHeight);
- updatedInsetsBuilder.setInsets(WindowInsets.Type.navigationBars(), newNavInsets);
-
- Insets oldTappableInsets = oldInsets.getInsets(WindowInsets.Type.tappableElement());
- Insets newTappableInsets = Insets.of(oldTappableInsets.left, oldTappableInsets.top,
- oldTappableInsets.right, 0);
- updatedInsetsBuilder.setInsets(WindowInsets.Type.tappableElement(), newTappableInsets);
-
- return updatedInsetsBuilder.build();
- }
- }
-}
diff --git a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsController.java b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsController.java
deleted file mode 100644
index 6fd98db19a..0000000000
--- a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsController.java
+++ /dev/null
@@ -1,257 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.launcher3.taskbar.allapps;
-
-import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
-import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
-
-import static com.android.launcher3.AbstractFloatingView.TYPE_ALL;
-import static com.android.launcher3.AbstractFloatingView.TYPE_REBIND_SAFE;
-
-import android.content.Context;
-import android.graphics.PixelFormat;
-import android.view.Gravity;
-import android.view.MotionEvent;
-import android.view.WindowManager;
-import android.view.WindowManager.LayoutParams;
-
-import androidx.annotation.Nullable;
-
-import com.android.launcher3.AbstractFloatingView;
-import com.android.launcher3.DeviceProfile;
-import com.android.launcher3.appprediction.PredictionRowView;
-import com.android.launcher3.config.FeatureFlags;
-import com.android.launcher3.model.data.AppInfo;
-import com.android.launcher3.model.data.ItemInfo;
-import com.android.launcher3.taskbar.TaskbarActivityContext;
-import com.android.launcher3.taskbar.TaskbarControllers;
-import com.android.systemui.shared.system.TaskStackChangeListener;
-import com.android.systemui.shared.system.TaskStackChangeListeners;
-
-import java.util.List;
-import java.util.Optional;
-
-/**
- * Handles the all apps overlay window initialization, updates, and its data.
- * <p>
- * All apps is in an application overlay window instead of taskbar's navigation bar panel window,
- * because a navigation bar panel is higher than UI components that all apps should be below such as
- * the notification tray.
- * <p>
- * The all apps window is created and destroyed upon opening and closing all apps, respectively.
- * Application data may be bound while the window does not exist, so this controller will store
- * the models for the next all apps session.
- */
-public final class TaskbarAllAppsController {
-
- private static final String WINDOW_TITLE = "Taskbar All Apps";
-
- private final TaskbarActivityContext mTaskbarContext;
- private final TaskbarAllAppsProxyView mProxyView;
- private final LayoutParams mLayoutParams;
-
- private final TaskStackChangeListener mTaskStackListener = new TaskStackChangeListener() {
- @Override
- public void onTaskStackChanged() {
- mProxyView.close(false);
- }
- };
-
- private DeviceProfile mDeviceProfile;
- private TaskbarControllers mControllers;
- /** Window context for all apps if it is open. */
- private @Nullable TaskbarAllAppsContext mAllAppsContext;
-
- // Application data models.
- private AppInfo[] mApps;
- private int mAppsModelFlags;
- private List<ItemInfo> mPredictedApps;
-
- public TaskbarAllAppsController(TaskbarActivityContext context, DeviceProfile dp) {
- mDeviceProfile = dp;
- mTaskbarContext = context;
- mProxyView = new TaskbarAllAppsProxyView(mTaskbarContext);
- mLayoutParams = createLayoutParams();
- }
-
- /** Initialize the controller. */
- public void init(TaskbarControllers controllers, boolean allAppsVisible) {
- if (!FeatureFlags.ENABLE_ALL_APPS_IN_TASKBAR.get()) {
- return;
- }
- mControllers = controllers;
-
- /*
- * Recreate All Apps if it was open in the previous Taskbar instance (e.g. the configuration
- * changed).
- */
- if (allAppsVisible) {
- show(false);
- }
- }
-
- /** Updates the current {@link AppInfo} instances. */
- public void setApps(AppInfo[] apps, int flags) {
- if (!FeatureFlags.ENABLE_ALL_APPS_IN_TASKBAR.get()) {
- return;
- }
-
- mApps = apps;
- mAppsModelFlags = flags;
- if (mAllAppsContext != null) {
- mAllAppsContext.getAppsView().getAppsStore().setApps(mApps, mAppsModelFlags);
- }
- }
-
- /** Updates the current predictions. */
- public void setPredictedApps(List<ItemInfo> predictedApps) {
- if (!FeatureFlags.ENABLE_ALL_APPS_IN_TASKBAR.get()) {
- return;
- }
-
- mPredictedApps = predictedApps;
- if (mAllAppsContext != null) {
- mAllAppsContext.getAppsView().getFloatingHeaderView()
- .findFixedRowByType(PredictionRowView.class)
- .setPredictedApps(mPredictedApps);
- }
- }
-
- /** Opens the {@link TaskbarAllAppsContainerView} in a new window. */
- public void show() {
- show(true);
- }
-
- private void show(boolean animate) {
- if (mProxyView.isOpen()) {
- return;
- }
- mProxyView.show();
- // mControllers and getSharedState should never be null here. Do not handle null-pointer
- // to catch invalid states.
- mControllers.getSharedState().allAppsVisible = true;
-
- mAllAppsContext = new TaskbarAllAppsContext(mTaskbarContext,
- this,
- mControllers.taskbarStashController);
- mAllAppsContext.getDragController().init(mControllers);
- TaskStackChangeListeners.getInstance().registerTaskStackListener(mTaskStackListener);
- Optional.ofNullable(mAllAppsContext.getSystemService(WindowManager.class))
- .ifPresent(m -> m.addView(mAllAppsContext.getDragLayer(), mLayoutParams));
-
- mAllAppsContext.getAppsView().getAppsStore().setApps(mApps, mAppsModelFlags);
- mAllAppsContext.getAppsView().getFloatingHeaderView()
- .findFixedRowByType(PredictionRowView.class)
- .setPredictedApps(mPredictedApps);
- mAllAppsContext.getAllAppsViewController().show(animate);
- }
-
- /** Closes the {@link TaskbarAllAppsContainerView}. */
- public void hide() {
- mProxyView.close(true);
- }
-
- /**
- * Removes the all apps window from the hierarchy, if all floating views are closed and there is
- * no system drag operation in progress.
- * <p>
- * This method should be called after an exit animation finishes, if applicable.
- */
- void maybeCloseWindow() {
- if (AbstractFloatingView.getOpenView(mAllAppsContext, TYPE_ALL) != null
- || mAllAppsContext.getDragController().isSystemDragInProgress()) {
- return;
- }
- mProxyView.close(false);
- // mControllers and getSharedState should never be null here. Do not handle null-pointer
- // to catch invalid states.
- mControllers.getSharedState().allAppsVisible = false;
- onDestroy();
- }
-
- /** Destroys the controller and any All Apps window if present. */
- public void onDestroy() {
- TaskStackChangeListeners.getInstance().unregisterTaskStackListener(mTaskStackListener);
- Optional.ofNullable(mAllAppsContext)
- .map(c -> c.getSystemService(WindowManager.class))
- .ifPresent(m -> m.removeView(mAllAppsContext.getDragLayer()));
- mAllAppsContext = null;
- }
-
- /** Updates {@link DeviceProfile} instance for Taskbar's All Apps window. */
- public void updateDeviceProfile(DeviceProfile dp) {
- mDeviceProfile = dp;
- Optional.ofNullable(mAllAppsContext).ifPresent(c -> {
- AbstractFloatingView.closeAllOpenViewsExcept(c, false, TYPE_REBIND_SAFE);
- c.dispatchDeviceProfileChanged();
- });
- }
-
- DeviceProfile getDeviceProfile() {
- return mDeviceProfile;
- }
-
- private LayoutParams createLayoutParams() {
- LayoutParams layoutParams = new LayoutParams(
- TYPE_APPLICATION_OVERLAY,
- 0,
- PixelFormat.TRANSLUCENT);
- layoutParams.setTitle(WINDOW_TITLE);
- layoutParams.gravity = Gravity.BOTTOM;
- layoutParams.packageName = mTaskbarContext.getPackageName();
- layoutParams.setFitInsetsTypes(0); // Handled by container view.
- layoutParams.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
- layoutParams.setSystemApplicationOverlay(true);
- return layoutParams;
- }
-
- /**
- * Proxy view connecting taskbar drag layer to the all apps window.
- * <p>
- * The all apps view is in a separate window and has its own drag layer, but this proxy lets it
- * behave as though its in the taskbar drag layer. For instance, when the taskbar closes all
- * {@link AbstractFloatingView} instances, the all apps window will also close.
- */
- private class TaskbarAllAppsProxyView extends AbstractFloatingView {
-
- private TaskbarAllAppsProxyView(Context context) {
- super(context, null);
- }
-
- private void show() {
- mIsOpen = true;
- mTaskbarContext.getDragLayer().addView(this);
- }
-
- @Override
- protected void handleClose(boolean animate) {
- mTaskbarContext.getDragLayer().removeView(this);
- Optional.ofNullable(mAllAppsContext)
- .map(TaskbarAllAppsContext::getAllAppsViewController)
- .ifPresent(v -> v.close(animate));
- }
-
- @Override
- protected boolean isOfType(int type) {
- return (type & TYPE_TASKBAR_ALL_APPS) != 0;
- }
-
- @Override
- public boolean onControllerInterceptTouchEvent(MotionEvent ev) {
- return false;
- }
- }
-}
diff --git a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsFallbackSearchContainer.java b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsFallbackSearchContainer.java
deleted file mode 100644
index 53fe06d32c..0000000000
--- a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsFallbackSearchContainer.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.launcher3.taskbar.allapps;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.view.View;
-
-import androidx.annotation.Nullable;
-
-import com.android.launcher3.ExtendedEditText;
-import com.android.launcher3.allapps.ActivityAllAppsContainerView;
-import com.android.launcher3.allapps.SearchUiManager;
-
-/** Empty search container for Taskbar All Apps used as a fallback if search is not supported. */
-public class TaskbarAllAppsFallbackSearchContainer extends View implements SearchUiManager {
- public TaskbarAllAppsFallbackSearchContainer(Context context, AttributeSet attrs) {
- this(context, attrs, 0);
- }
-
- public TaskbarAllAppsFallbackSearchContainer(
- Context context, AttributeSet attrs, int defStyleAttr) {
- super(context, attrs, defStyleAttr);
- }
-
- @Override
- public void initializeSearch(ActivityAllAppsContainerView<?> containerView) {
- // Do nothing.
- }
-
- @Override
- public void resetSearch() {
- // Do nothing.
- }
-
- @Nullable
- @Override
- public ExtendedEditText getEditText() {
- return null;
- }
-}
diff --git a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsSlideInView.java b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsSlideInView.java
deleted file mode 100644
index c4837a0c51..0000000000
--- a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsSlideInView.java
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.launcher3.taskbar.allapps;
-
-import static com.android.launcher3.LauncherState.ALL_APPS;
-import static com.android.launcher3.anim.Interpolators.AGGRESSIVE_EASE;
-import static com.android.systemui.animation.Interpolators.EMPHASIZED_ACCELERATE;
-
-import android.animation.PropertyValuesHolder;
-import android.content.Context;
-import android.graphics.Rect;
-import android.util.AttributeSet;
-import android.view.MotionEvent;
-import android.view.animation.Interpolator;
-
-import com.android.launcher3.DeviceProfile;
-import com.android.launcher3.Insettable;
-import com.android.launcher3.R;
-import com.android.launcher3.views.AbstractSlideInView;
-
-import java.util.Optional;
-
-/** Wrapper for taskbar all apps with slide-in behavior. */
-public class TaskbarAllAppsSlideInView extends AbstractSlideInView<TaskbarAllAppsContext>
- implements Insettable, DeviceProfile.OnDeviceProfileChangeListener {
- private TaskbarAllAppsContainerView mAppsView;
- private OnCloseListener mOnCloseBeginListener;
- private float mShiftRange;
-
- public TaskbarAllAppsSlideInView(Context context, AttributeSet attrs) {
- this(context, attrs, 0);
- }
-
- public TaskbarAllAppsSlideInView(Context context, AttributeSet attrs,
- int defStyleAttr) {
- super(context, attrs, defStyleAttr);
- }
-
- /** Opens the all apps view. */
- void show(boolean animate) {
- if (mIsOpen || mOpenCloseAnimator.isRunning()) {
- return;
- }
- mIsOpen = true;
- attachToContainer();
-
- if (animate) {
- mOpenCloseAnimator.setValues(
- PropertyValuesHolder.ofFloat(TRANSLATION_SHIFT, TRANSLATION_SHIFT_OPENED));
- mOpenCloseAnimator.setInterpolator(AGGRESSIVE_EASE);
- mOpenCloseAnimator.setDuration(
- ALL_APPS.getTransitionDuration(mActivityContext, true /* isToState */)).start();
- } else {
- mTranslationShift = TRANSLATION_SHIFT_OPENED;
- }
- }
-
- /** The apps container inside this view. */
- TaskbarAllAppsContainerView getAppsView() {
- return mAppsView;
- }
-
- /** Callback invoked when the view is beginning to close (e.g. close animation is started). */
- void setOnCloseBeginListener(OnCloseListener onCloseBeginListener) {
- mOnCloseBeginListener = onCloseBeginListener;
- }
-
- @Override
- protected void handleClose(boolean animate) {
- Optional.ofNullable(mOnCloseBeginListener).ifPresent(OnCloseListener::onSlideInViewClosed);
- handleClose(animate,
- ALL_APPS.getTransitionDuration(mActivityContext, false /* isToState */));
- }
-
- @Override
- protected Interpolator getIdleInterpolator() {
- return EMPHASIZED_ACCELERATE;
- }
-
- @Override
- protected boolean isOfType(int type) {
- return (type & TYPE_TASKBAR_ALL_APPS) != 0;
- }
-
- @Override
- protected void onFinishInflate() {
- super.onFinishInflate();
- mAppsView = findViewById(R.id.apps_view);
- mContent = mAppsView;
-
- DeviceProfile dp = mActivityContext.getDeviceProfile();
- setShiftRange(dp.allAppsShiftRange);
-
- mActivityContext.addOnDeviceProfileChangeListener(this);
- }
-
- @Override
- protected void onLayout(boolean changed, int l, int t, int r, int b) {
- super.onLayout(changed, l, t, r, b);
- setTranslationShift(mTranslationShift);
- }
-
- @Override
- protected int getScrimColor(Context context) {
- return context.getColor(R.color.widgets_picker_scrim);
- }
-
- @Override
- public boolean onControllerInterceptTouchEvent(MotionEvent ev) {
- if (ev.getAction() == MotionEvent.ACTION_DOWN) {
- mNoIntercept = !mAppsView.shouldContainerScroll(ev);
- }
- return super.onControllerInterceptTouchEvent(ev);
- }
-
- @Override
- public void setInsets(Rect insets) {
- mAppsView.setInsets(insets);
- }
-
- @Override
- public void onDeviceProfileChanged(DeviceProfile dp) {
- setShiftRange(dp.allAppsShiftRange);
- setTranslationShift(TRANSLATION_SHIFT_OPENED);
- }
-
- private void setShiftRange(float shiftRange) {
- mShiftRange = shiftRange;
- }
-
- @Override
- protected float getShiftRange() {
- return mShiftRange;
- }
-
- @Override
- protected boolean isEventOverContent(MotionEvent ev) {
- return getPopupContainer().isEventOverView(mAppsView.getVisibleContainerView(), ev);
- }
-}
diff --git a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsViewController.java b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsViewController.java
deleted file mode 100644
index a39e872a8d..0000000000
--- a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsViewController.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.launcher3.taskbar.allapps;
-
-import static com.android.launcher3.LauncherState.ALL_APPS;
-import static com.android.launcher3.taskbar.TaskbarStashController.FLAG_STASHED_IN_APP_ALL_APPS;
-import static com.android.launcher3.util.OnboardingPrefs.ALL_APPS_VISITED_COUNT;
-
-import com.android.launcher3.AbstractFloatingView;
-import com.android.launcher3.appprediction.AppsDividerView;
-import com.android.launcher3.appprediction.PredictionRowView;
-import com.android.launcher3.taskbar.TaskbarStashController;
-
-/**
- * Handles the {@link TaskbarAllAppsContainerView} behavior and synchronizes its transitions with
- * taskbar stashing.
- */
-final class TaskbarAllAppsViewController {
-
- private final TaskbarAllAppsContext mContext;
- private final TaskbarAllAppsSlideInView mSlideInView;
- private final TaskbarAllAppsContainerView mAppsView;
- private final TaskbarStashController mTaskbarStashController;
-
- TaskbarAllAppsViewController(
- TaskbarAllAppsContext context,
- TaskbarAllAppsSlideInView slideInView,
- TaskbarAllAppsController windowController,
- TaskbarStashController taskbarStashController) {
-
- mContext = context;
- mSlideInView = slideInView;
- mAppsView = mSlideInView.getAppsView();
- mTaskbarStashController = taskbarStashController;
-
- setUpIconLongClick();
- setUpAppDivider();
- setUpTaskbarStashing();
- mSlideInView.addOnCloseListener(windowController::maybeCloseWindow);
- }
-
- /** Starts the {@link TaskbarAllAppsSlideInView} enter transition. */
- void show(boolean animate) {
- mSlideInView.show(animate);
- }
-
- /** Closes the {@link TaskbarAllAppsSlideInView}. */
- void close(boolean animate) {
- mSlideInView.close(animate);
- }
-
- private void setUpIconLongClick() {
- mAppsView.setOnIconLongClickListener(
- mContext.getDragController()::startDragOnLongClick);
- mAppsView.getFloatingHeaderView()
- .findFixedRowByType(PredictionRowView.class)
- .setOnIconLongClickListener(
- mContext.getDragController()::startDragOnLongClick);
- }
-
- private void setUpAppDivider() {
- mAppsView.getFloatingHeaderView()
- .findFixedRowByType(AppsDividerView.class)
- .setShowAllAppsLabel(!mContext.getOnboardingPrefs().hasReachedMaxCount(
- ALL_APPS_VISITED_COUNT));
- mContext.getOnboardingPrefs().incrementEventCount(ALL_APPS_VISITED_COUNT);
- }
-
- private void setUpTaskbarStashing() {
- mTaskbarStashController.updateStateForFlag(FLAG_STASHED_IN_APP_ALL_APPS, true);
- mTaskbarStashController.applyState(
- ALL_APPS.getTransitionDuration(mContext, true /* isToState */));
- mSlideInView.setOnCloseBeginListener(() -> {
- AbstractFloatingView.closeOpenContainer(
- mContext, AbstractFloatingView.TYPE_ACTION_POPUP);
- // Post in case view is closing due to gesture navigation. If a gesture is in progress,
- // wait to unstash until after the gesture is finished.
- mSlideInView.post(mTaskbarStashController::maybeResetStashedInAppAllApps);
- });
- }
-}
diff --git a/quickstep/src/com/android/launcher3/taskbar/unfold/NonDestroyableScopedUnfoldTransitionProgressProvider.java b/quickstep/src/com/android/launcher3/taskbar/unfold/NonDestroyableScopedUnfoldTransitionProgressProvider.java
deleted file mode 100644
index f9da4e4e74..0000000000
--- a/quickstep/src/com/android/launcher3/taskbar/unfold/NonDestroyableScopedUnfoldTransitionProgressProvider.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.launcher3.taskbar.unfold;
-
-import com.android.systemui.unfold.util.ScopedUnfoldTransitionProgressProvider;
-
-/**
- * ScopedUnfoldTransitionProgressProvider that doesn't propagate destroy method
- */
-public class NonDestroyableScopedUnfoldTransitionProgressProvider extends
- ScopedUnfoldTransitionProgressProvider {
-
- @Override
- public void destroy() {
- // no-op
- }
-}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/ApiWrapper.java b/quickstep/src/com/android/launcher3/uioverrides/ApiWrapper.java
index 2f8e4d9dde..76a5782d11 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/ApiWrapper.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/ApiWrapper.java
@@ -17,14 +17,10 @@
package com.android.launcher3.uioverrides;
import android.app.Person;
-import android.content.Context;
import android.content.pm.ShortcutInfo;
-import android.content.res.Resources;
+import android.view.Display;
-import com.android.launcher3.R;
import com.android.launcher3.Utilities;
-import com.android.launcher3.util.DisplayController;
-import com.android.launcher3.util.DisplayController.NavigationMode;
public class ApiWrapper {
@@ -36,22 +32,9 @@ public class ApiWrapper {
}
/**
- * Returns the minimum space that should be left empty at the end of hotseat
+ * Returns true if the display is an internal displays
*/
- public static int getHotseatEndOffset(Context context) {
- if (DisplayController.getNavigationMode(context) == NavigationMode.THREE_BUTTONS) {
- Resources res = context.getResources();
- /*
- * 3 nav buttons +
- * Little space at the end for contextual buttons +
- * Little space between icons and nav buttons
- */
- return 3 * res.getDimensionPixelSize(R.dimen.taskbar_nav_buttons_size)
- + res.getDimensionPixelSize(R.dimen.taskbar_contextual_button_margin)
- + res.getDimensionPixelSize(R.dimen.taskbar_hotseat_nav_spacing);
- } else {
- return 0;
- }
-
+ public static boolean isInternalDisplay(Display display) {
+ return display.getType() == Display.TYPE_INTERNAL;
}
}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java b/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java
index 84b3839825..1d523151db 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java
@@ -17,8 +17,6 @@
package com.android.launcher3.uioverrides;
import static com.android.launcher3.anim.Interpolators.AGGRESSIVE_EASE_IN_OUT;
-import static com.android.launcher3.anim.Interpolators.FINAL_FRAME;
-import static com.android.launcher3.anim.Interpolators.INSTANT;
import static com.android.launcher3.anim.Interpolators.LINEAR;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_FADE;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_MODAL;
@@ -26,14 +24,14 @@ import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_SC
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_TRANSLATE_X;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_TRANSLATE_Y;
import static com.android.launcher3.states.StateAnimationConfig.SKIP_OVERVIEW;
-import static com.android.launcher3.testing.TestProtocol.BAD_STATE;
import static com.android.quickstep.views.RecentsView.ADJACENT_PAGE_HORIZONTAL_OFFSET;
import static com.android.quickstep.views.RecentsView.RECENTS_GRID_PROGRESS;
import static com.android.quickstep.views.RecentsView.RECENTS_SCALE_PROPERTY;
+import static com.android.quickstep.views.RecentsView.TASK_PRIMARY_SPLIT_TRANSLATION;
+import static com.android.quickstep.views.RecentsView.TASK_SECONDARY_SPLIT_TRANSLATION;
import static com.android.quickstep.views.RecentsView.TASK_SECONDARY_TRANSLATION;
import android.util.FloatProperty;
-import android.util.Log;
import androidx.annotation.NonNull;
@@ -42,6 +40,7 @@ import com.android.launcher3.LauncherState;
import com.android.launcher3.anim.PendingAnimation;
import com.android.launcher3.statemanager.StateManager.StateHandler;
import com.android.launcher3.states.StateAnimationConfig;
+import com.android.launcher3.touch.PagedOrientationHandler;
import com.android.quickstep.views.RecentsView;
/**
@@ -67,10 +66,7 @@ public abstract class BaseRecentsViewStateController<T extends RecentsView>
ADJACENT_PAGE_HORIZONTAL_OFFSET.set(mRecentsView, scaleAndOffset[1]);
TASK_SECONDARY_TRANSLATION.set(mRecentsView, 0f);
- float recentsAlpha = state.overviewUi ? 1f : 0;
- Log.d(BAD_STATE, "BaseRecentsViewStateController setState state=" + state
- + ", alpha=" + recentsAlpha);
- getContentAlphaProperty().set(mRecentsView, recentsAlpha);
+ getContentAlphaProperty().set(mRecentsView, state.overviewUi ? 1f : 0);
getTaskModalnessProperty().set(mRecentsView, state.getOverviewModalness());
RECENTS_GRID_PROGRESS.set(mRecentsView,
state.displayOverviewTasksAsGrid(mLauncher.getDeviceProfile()) ? 1f : 0f);
@@ -79,8 +75,6 @@ public abstract class BaseRecentsViewStateController<T extends RecentsView>
@Override
public void setStateWithAnimation(LauncherState toState, StateAnimationConfig config,
PendingAnimation builder) {
- Log.d(BAD_STATE, "BaseRecentsViewStateController setStateWithAnimation state=" + toState
- + ", config.skipOverview=" + config.hasAnimationFlag(SKIP_OVERVIEW));
if (config.hasAnimationFlag(SKIP_OVERVIEW)) {
return;
}
@@ -103,20 +97,23 @@ public abstract class BaseRecentsViewStateController<T extends RecentsView>
config.getInterpolator(ANIM_OVERVIEW_TRANSLATE_X, LINEAR));
setter.setFloat(mRecentsView, TASK_SECONDARY_TRANSLATION, 0f,
config.getInterpolator(ANIM_OVERVIEW_TRANSLATE_Y, LINEAR));
+ PagedOrientationHandler orientationHandler =
+ ((RecentsView) mLauncher.getOverviewPanel()).getPagedOrientationHandler();
+ FloatProperty taskViewsFloat = orientationHandler.getSplitSelectTaskOffset(
+ TASK_PRIMARY_SPLIT_TRANSLATION, TASK_SECONDARY_SPLIT_TRANSLATION,
+ mLauncher.getDeviceProfile());
+ setter.setFloat(mRecentsView, taskViewsFloat,
+ toState.getSplitSelectTranslation(mLauncher), LINEAR);
- float recentsAlpha = toState.overviewUi ? 1 : 0;
- Log.d(BAD_STATE, "BaseRecentsViewStateController setStateWithAnimationInternal toState="
- + toState + ", alpha=" + recentsAlpha);
- setter.setFloat(mRecentsView, getContentAlphaProperty(), recentsAlpha,
+ setter.setFloat(mRecentsView, getContentAlphaProperty(), toState.overviewUi ? 1 : 0,
config.getInterpolator(ANIM_OVERVIEW_FADE, AGGRESSIVE_EASE_IN_OUT));
setter.setFloat(
mRecentsView, getTaskModalnessProperty(),
toState.getOverviewModalness(),
config.getInterpolator(ANIM_OVERVIEW_MODAL, LINEAR));
- boolean showAsGrid = toState.displayOverviewTasksAsGrid(mLauncher.getDeviceProfile());
- setter.setFloat(mRecentsView, RECENTS_GRID_PROGRESS, showAsGrid ? 1f : 0f,
- showAsGrid ? INSTANT : FINAL_FRAME);
+ setter.setFloat(mRecentsView, RECENTS_GRID_PROGRESS,
+ toState.displayOverviewTasksAsGrid(mLauncher.getDeviceProfile()) ? 1f : 0f, LINEAR);
}
abstract FloatProperty getTaskModalnessProperty();
diff --git a/quickstep/src/com/android/launcher3/uioverrides/DeviceFlag.java b/quickstep/src/com/android/launcher3/uioverrides/DeviceFlag.java
index c46809afc6..c115bbb9fb 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/DeviceFlag.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/DeviceFlag.java
@@ -17,17 +17,21 @@
package com.android.launcher3.uioverrides;
import android.annotation.TargetApi;
+import android.content.Context;
import android.os.Build;
import android.provider.DeviceConfig;
import com.android.launcher3.config.FeatureFlags.DebugFlag;
+import java.util.ArrayList;
+
@TargetApi(Build.VERSION_CODES.P)
public class DeviceFlag extends DebugFlag {
public static final String NAMESPACE_LAUNCHER = "launcher";
private final boolean mDefaultValueInCode;
+ ArrayList<Runnable> mListeners;
public DeviceFlag(String key, boolean defaultValue, String description) {
super(key, getDeviceValue(key, defaultValue), description);
@@ -40,11 +44,53 @@ public class DeviceFlag extends DebugFlag {
}
@Override
+ public void initialize(Context context) {
+ super.initialize(context);
+ if (mListeners == null) {
+ mListeners = new ArrayList<>();
+ registerDeviceConfigChangedListener(context);
+ }
+ }
+
+ @Override
+ public void addChangeListener(Context context, Runnable r) {
+ if (mListeners == null) {
+ initialize(context);
+ }
+ mListeners.add(r);
+ }
+
+ @Override
+ public void removeChangeListener(Runnable r) {
+ if (mListeners == null) {
+ return;
+ }
+ mListeners.remove(r);
+ }
+
+ @Override
public boolean get() {
// Override this method in order to let Robolectric ShadowDeviceFlag to stub it.
return super.get();
}
+ private void registerDeviceConfigChangedListener(Context context) {
+ DeviceConfig.addOnPropertiesChangedListener(
+ NAMESPACE_LAUNCHER,
+ context.getMainExecutor(),
+ properties -> {
+ if (!NAMESPACE_LAUNCHER.equals(properties.getNamespace())
+ || !properties.getKeyset().contains(key)) {
+ return;
+ }
+ defaultValue = getDeviceValue(key, mDefaultValueInCode);
+ initialize(context);
+ for (Runnable r: mListeners) {
+ r.run();
+ }
+ });
+ }
+
protected static boolean getDeviceValue(String key, boolean defaultValue) {
return DeviceConfig.getBoolean(NAMESPACE_LAUNCHER, key, defaultValue);
}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/PredictedAppIcon.java b/quickstep/src/com/android/launcher3/uioverrides/PredictedAppIcon.java
index 5f3a990750..d839a36213 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/PredictedAppIcon.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/PredictedAppIcon.java
@@ -15,17 +15,6 @@
*/
package com.android.launcher3.uioverrides;
-import static com.android.launcher3.anim.Interpolators.ACCEL_DEACCEL;
-import static com.android.launcher3.icons.BitmapInfo.FLAG_THEMED;
-
-import android.animation.Animator;
-import android.animation.AnimatorSet;
-import android.animation.ArgbEvaluator;
-import android.animation.Keyframe;
-import android.animation.ObjectAnimator;
-import android.animation.PropertyValuesHolder;
-import android.animation.ValueAnimator;
-import android.annotation.Nullable;
import android.content.Context;
import android.graphics.BlurMaskFilter;
import android.graphics.Canvas;
@@ -34,10 +23,8 @@ import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
-import android.graphics.drawable.Drawable;
import android.os.Process;
import android.util.AttributeSet;
-import android.util.FloatProperty;
import android.view.LayoutInflater;
import android.view.ViewGroup;
@@ -48,8 +35,6 @@ import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherSettings;
import com.android.launcher3.R;
-import com.android.launcher3.anim.AnimatorListeners;
-import com.android.launcher3.icons.BitmapInfo;
import com.android.launcher3.icons.GraphicsUtils;
import com.android.launcher3.icons.IconNormalizer;
import com.android.launcher3.icons.LauncherIcons;
@@ -60,10 +45,6 @@ import com.android.launcher3.util.SafeCloseable;
import com.android.launcher3.views.ActivityContext;
import com.android.launcher3.views.DoubleShadowBubbleTextView;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
/**
* A BubbleTextView with a ring around it's drawable
*/
@@ -72,9 +53,6 @@ public class PredictedAppIcon extends DoubleShadowBubbleTextView {
private static final int RING_SHADOW_COLOR = 0x99000000;
private static final float RING_EFFECT_RATIO = 0.095f;
- private static final long ICON_CHANGE_ANIM_DURATION = 360;
- private static final long ICON_CHANGE_ANIM_STAGGER = 50;
-
boolean mIsDrawingDot = false;
private final DeviceProfile mDeviceProfile;
private final Paint mIconRingPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
@@ -89,25 +67,6 @@ public class PredictedAppIcon extends DoubleShadowBubbleTextView {
private int mPlateColor;
boolean mDrawForDrag = false;
- // Used for the "slot-machine" education animation.
- private List<Drawable> mSlotMachineIcons;
- private Animator mSlotMachineAnim;
- private float mSlotMachineIconTranslationY;
-
- private static final FloatProperty<PredictedAppIcon> SLOT_MACHINE_TRANSLATION_Y =
- new FloatProperty<PredictedAppIcon>("slotMachineTranslationY") {
- @Override
- public void setValue(PredictedAppIcon predictedAppIcon, float transY) {
- predictedAppIcon.mSlotMachineIconTranslationY = transY;
- predictedAppIcon.invalidate();
- }
-
- @Override
- public Float get(PredictedAppIcon predictedAppIcon) {
- return predictedAppIcon.mSlotMachineIconTranslationY;
- }
- };
-
public PredictedAppIcon(Context context) {
this(context, null, 0);
}
@@ -129,38 +88,15 @@ public class PredictedAppIcon extends DoubleShadowBubbleTextView {
@Override
public void onDraw(Canvas canvas) {
int count = canvas.save();
- boolean isSlotMachineAnimRunning = mSlotMachineAnim != null;
if (!mIsPinned) {
drawEffect(canvas);
- if (isSlotMachineAnimRunning) {
- // Clip to to outside of the ring during the slot machine animation.
- canvas.clipPath(mRingPath);
- }
canvas.translate(getWidth() * RING_EFFECT_RATIO, getHeight() * RING_EFFECT_RATIO);
canvas.scale(1 - 2 * RING_EFFECT_RATIO, 1 - 2 * RING_EFFECT_RATIO);
}
- if (isSlotMachineAnimRunning) {
- drawSlotMachineIcons(canvas);
- } else {
- super.onDraw(canvas);
- }
+ super.onDraw(canvas);
canvas.restoreToCount(count);
}
- private void drawSlotMachineIcons(Canvas canvas) {
- canvas.translate((getWidth() - getIconSize()) / 2f,
- (getHeight() - getIconSize()) / 2f + mSlotMachineIconTranslationY);
- for (Drawable icon : mSlotMachineIcons) {
- icon.setBounds(0, 0, getIconSize(), getIconSize());
- icon.draw(canvas);
- canvas.translate(0, getSlotMachineIconPlusSpacingSize());
- }
- }
-
- private float getSlotMachineIconPlusSpacingSize() {
- return getIconSize() + getOutlineOffsetY();
- }
-
@Override
protected void drawDotIfNecessary(Canvas canvas) {
mIsDrawingDot = true;
@@ -173,17 +109,9 @@ public class PredictedAppIcon extends DoubleShadowBubbleTextView {
}
@Override
- public void applyFromWorkspaceItem(WorkspaceItemInfo info, boolean animate, int staggerIndex) {
- // Create the slot machine animation first, since it uses the current icon to start.
- Animator slotMachineAnim = animate
- ? createSlotMachineAnim(Collections.singletonList(info.bitmap), false)
- : null;
- super.applyFromWorkspaceItem(info, animate, staggerIndex);
- int oldPlateColor = mPlateColor;
- int newPlateColor = ColorUtils.setAlphaComponent(mDotParams.appColor, 200);
- if (!animate) {
- mPlateColor = newPlateColor;
- }
+ public void applyFromWorkspaceItem(WorkspaceItemInfo info) {
+ super.applyFromWorkspaceItem(info);
+ mPlateColor = ColorUtils.setAlphaComponent(mDotParams.color, 200);
if (mIsPinned) {
setContentDescription(info.contentDescription);
} else {
@@ -191,76 +119,6 @@ public class PredictedAppIcon extends DoubleShadowBubbleTextView {
getContext().getString(R.string.hotseat_prediction_content_description,
info.contentDescription));
}
-
- if (animate) {
- ValueAnimator plateColorAnim = ValueAnimator.ofObject(new ArgbEvaluator(),
- oldPlateColor, newPlateColor);
- plateColorAnim.addUpdateListener(valueAnimator -> {
- mPlateColor = (int) valueAnimator.getAnimatedValue();
- invalidate();
- });
- AnimatorSet changeIconAnim = new AnimatorSet();
- if (slotMachineAnim != null) {
- changeIconAnim.play(slotMachineAnim);
- }
- changeIconAnim.play(plateColorAnim);
- changeIconAnim.setStartDelay(staggerIndex * ICON_CHANGE_ANIM_STAGGER);
- changeIconAnim.setDuration(ICON_CHANGE_ANIM_DURATION).start();
- }
- }
-
- /**
- * Returns an Animator that translates the given icons in a "slot-machine" fashion, beginning
- * and ending with the original icon.
- */
- public @Nullable Animator createSlotMachineAnim(List<BitmapInfo> iconsToAnimate) {
- return createSlotMachineAnim(iconsToAnimate, true);
- }
-
- /**
- * Returns an Animator that translates the given icons in a "slot-machine" fashion, beginning
- * with the original icon, then cycling through the given icons, optionally ending back with
- * the original icon.
- * @param endWithOriginalIcon Whether we should land back on the icon we started with, rather
- * than the last item in iconsToAnimate.
- */
- public @Nullable Animator createSlotMachineAnim(List<BitmapInfo> iconsToAnimate,
- boolean endWithOriginalIcon) {
- if (mIsPinned || iconsToAnimate == null || iconsToAnimate.isEmpty()) {
- return null;
- }
- if (mSlotMachineAnim != null) {
- mSlotMachineAnim.end();
- }
-
- // Bookend the other animating icons with the original icon on both ends.
- mSlotMachineIcons = new ArrayList<>(iconsToAnimate.size() + 2);
- mSlotMachineIcons.add(getIcon());
- iconsToAnimate.stream()
- .map(iconInfo -> iconInfo.newIcon(mContext, FLAG_THEMED))
- .forEach(mSlotMachineIcons::add);
- if (endWithOriginalIcon) {
- mSlotMachineIcons.add(getIcon());
- }
-
- float finalTrans = -getSlotMachineIconPlusSpacingSize() * (mSlotMachineIcons.size() - 1);
- Keyframe[] keyframes = new Keyframe[] {
- Keyframe.ofFloat(0f, 0f),
- Keyframe.ofFloat(0.82f, finalTrans - getOutlineOffsetY() / 2f), // Overshoot
- Keyframe.ofFloat(1f, finalTrans) // Ease back into the final position
- };
- keyframes[1].setInterpolator(ACCEL_DEACCEL);
- keyframes[2].setInterpolator(ACCEL_DEACCEL);
-
- mSlotMachineAnim = ObjectAnimator.ofPropertyValuesHolder(this,
- PropertyValuesHolder.ofKeyframe(SLOT_MACHINE_TRANSLATION_Y, keyframes));
- mSlotMachineAnim.addListener(AnimatorListeners.forEndCallback(() -> {
- mSlotMachineIcons = null;
- mSlotMachineAnim = null;
- mSlotMachineIconTranslationY = 0;
- invalidate();
- }));
- return mSlotMachineAnim;
}
/**
diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepInteractionHandler.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepInteractionHandler.java
index 08d147f7cf..1cf50f7f64 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepInteractionHandler.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepInteractionHandler.java
@@ -21,7 +21,6 @@ import android.app.ActivityOptions;
import android.app.ActivityTaskManager;
import android.app.PendingIntent;
import android.content.Intent;
-import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import android.util.Pair;
@@ -59,12 +58,6 @@ class QuickstepInteractionHandler implements RemoteViews.InteractionHandler {
Pair<Intent, ActivityOptions> options = remoteResponse.getLaunchOptions(view);
ActivityOptionsWrapper activityOptions = mLauncher.getAppTransitionManager()
.getActivityLaunchOptions(hostView);
- Object itemInfo = hostView.getTag();
- IBinder launchCookie = null;
- if (itemInfo instanceof ItemInfo) {
- launchCookie = mLauncher.getLaunchCookie((ItemInfo) itemInfo);
- activityOptions.options.setLaunchCookie(launchCookie);
- }
if (Utilities.ATLEAST_S && !pendingIntent.isActivity()) {
// In the event this pending intent eventually launches an activity, i.e. a trampoline,
// use the Quickstep transition animation.
@@ -72,14 +65,17 @@ class QuickstepInteractionHandler implements RemoteViews.InteractionHandler {
ActivityTaskManager.getService()
.registerRemoteAnimationForNextActivityStart(
pendingIntent.getCreatorPackage(),
- activityOptions.options.getRemoteAnimationAdapter(),
- launchCookie);
+ activityOptions.options.getRemoteAnimationAdapter());
} catch (RemoteException e) {
// Do nothing.
}
}
activityOptions.options.setPendingIntentLaunchFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- activityOptions.options.setSplashScreenStyle(SplashScreen.SPLASH_SCREEN_STYLE_SOLID_COLOR);
+ activityOptions.options.setSplashscreenStyle(SplashScreen.SPLASH_SCREEN_STYLE_EMPTY);
+ Object itemInfo = hostView.getTag();
+ if (itemInfo instanceof ItemInfo) {
+ mLauncher.addLaunchCookie((ItemInfo) itemInfo, activityOptions.options);
+ }
options = Pair.create(options.first, activityOptions.options);
if (pendingIntent.isActivity()) {
logAppLaunch(itemInfo);
diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
index 4bb43431bc..ec9893c84f 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
@@ -52,10 +52,10 @@ import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.appprediction.PredictionRowView;
import com.android.launcher3.hybridhotseat.HotseatPredictionController;
import com.android.launcher3.logging.InstanceId;
-import com.android.launcher3.logging.StatsLogManager;
import com.android.launcher3.logging.StatsLogManager.StatsLogger;
import com.android.launcher3.model.BgDataModel.FixedContainerItems;
import com.android.launcher3.model.data.ItemInfo;
+import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.launcher3.popup.SystemShortcut;
import com.android.launcher3.statemanager.StateManager.AtomicAnimationFactory;
import com.android.launcher3.uioverrides.states.QuickstepAtomicAnimationFactory;
@@ -68,13 +68,13 @@ import com.android.launcher3.uioverrides.touchcontrollers.StatusBarTouchControll
import com.android.launcher3.uioverrides.touchcontrollers.TaskViewTouchController;
import com.android.launcher3.uioverrides.touchcontrollers.TransposedQuickSwitchTouchController;
import com.android.launcher3.uioverrides.touchcontrollers.TwoButtonNavbarTouchController;
-import com.android.launcher3.util.DisplayController;
-import com.android.launcher3.util.DisplayController.NavigationMode;
-import com.android.launcher3.util.PendingRequestArgs;
+import com.android.launcher3.util.OnboardingPrefs;
import com.android.launcher3.util.TouchController;
import com.android.launcher3.util.UiThreadHelper;
import com.android.launcher3.util.UiThreadHelper.AsyncCommand;
import com.android.launcher3.widget.LauncherAppWidgetHost;
+import com.android.quickstep.SysUINavigationMode;
+import com.android.quickstep.SysUINavigationMode.Mode;
import com.android.quickstep.SystemUiProxy;
import com.android.quickstep.TaskUtils;
import com.android.quickstep.util.QuickstepOnboardingPrefs;
@@ -84,8 +84,8 @@ import com.android.quickstep.views.TaskView;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
+import java.util.List;
import java.util.Objects;
-import java.util.function.Predicate;
import java.util.stream.Stream;
public class QuickstepLauncher extends BaseQuickstepLauncher {
@@ -107,8 +107,7 @@ public class QuickstepLauncher extends BaseQuickstepLauncher {
}
@Override
- public void logAppLaunch(StatsLogManager statsLogManager, ItemInfo info,
- InstanceId instanceId) {
+ protected void logAppLaunch(ItemInfo info, InstanceId instanceId) {
// If the app launch is from any of the surfaces in AllApps then add the InstanceId from
// LiveSearchManager to recreate the AllApps session on the server side.
if (mAllAppsSessionLogId != null && ALL_APPS.equals(
@@ -116,7 +115,8 @@ public class QuickstepLauncher extends BaseQuickstepLauncher {
instanceId = mAllAppsSessionLogId;
}
- StatsLogger logger = statsLogManager.logger().withItemInfo(info).withInstanceId(instanceId);
+ StatsLogger logger = getStatsLogManager()
+ .logger().withItemInfo(info).withInstanceId(instanceId);
if (mAllAppsPredictions != null
&& (info.itemType == ITEM_TYPE_APPLICATION
@@ -140,15 +140,6 @@ public class QuickstepLauncher extends BaseQuickstepLauncher {
}
@Override
- protected void completeAddShortcut(Intent data, int container, int screenId, int cellX,
- int cellY, PendingRequestArgs args) {
- if (container == CONTAINER_HOTSEAT) {
- mHotseatPredictionController.onDeferredDrop(cellX, cellY);
- }
- super.completeAddShortcut(data, container, screenId, cellX, cellY, args);
- }
-
- @Override
protected LauncherAccessibilityDelegate createAccessibilityDelegate() {
return new QuickstepAccessibilityDelegate(this);
}
@@ -161,7 +152,7 @@ public class QuickstepLauncher extends BaseQuickstepLauncher {
}
@Override
- protected QuickstepOnboardingPrefs createOnboardingPrefs(SharedPreferences sharedPrefs) {
+ protected OnboardingPrefs createOnboardingPrefs(SharedPreferences sharedPrefs) {
return new QuickstepOnboardingPrefs(this, sharedPrefs);
}
@@ -175,11 +166,7 @@ public class QuickstepLauncher extends BaseQuickstepLauncher {
public boolean startActivitySafely(View v, Intent intent, ItemInfo item) {
// Only pause is taskbar controller is not present
mHotseatPredictionController.setPauseUIUpdate(getTaskbarUIController() == null);
- boolean started = super.startActivitySafely(v, intent, item);
- if (getTaskbarUIController() == null && !started) {
- mHotseatPredictionController.setPauseUIUpdate(false);
- }
- return started;
+ return super.startActivitySafely(v, intent, item);
}
@Override
@@ -220,7 +207,8 @@ public class QuickstepLauncher extends BaseQuickstepLauncher {
(getActivityFlags() & ACTIVITY_STATE_USER_WILL_BE_ACTIVE) != 0;
boolean visible = (state == NORMAL || state == OVERVIEW)
&& (willUserBeActive || isUserActive())
- && !profile.isVerticalBarLayout();
+ && !profile.isVerticalBarLayout()
+ && profile.isPhone && !profile.isLandscape;
UiThreadHelper.runAsyncCommand(this, SET_SHELF_HEIGHT, visible ? 1 : 0,
profile.hotseatBarSizePx);
}
@@ -233,10 +221,8 @@ public class QuickstepLauncher extends BaseQuickstepLauncher {
public void bindExtraContainerItems(FixedContainerItems item) {
if (item.containerId == Favorites.CONTAINER_PREDICTION) {
mAllAppsPredictions = item;
- PredictionRowView<?> predictionRowView =
- getAppsView().getFloatingHeaderView().findFixedRowByType(
- PredictionRowView.class);
- predictionRowView.setPredictedApps(item.items);
+ getAppsView().getFloatingHeaderView().findFixedRowByType(PredictionRowView.class)
+ .setPredictedApps(item.items);
} else if (item.containerId == Favorites.CONTAINER_HOTSEAT_PREDICTION) {
mHotseatPredictionController.setPredictedItems(item);
} else if (item.containerId == Favorites.CONTAINER_WIDGETS_PREDICTION) {
@@ -245,9 +231,12 @@ public class QuickstepLauncher extends BaseQuickstepLauncher {
}
@Override
- public void bindWorkspaceComponentsRemoved(Predicate<ItemInfo> matcher) {
- super.bindWorkspaceComponentsRemoved(matcher);
- mHotseatPredictionController.onModelItemsRemoved(matcher);
+ public void bindWorkspaceItemsChanged(List<WorkspaceItemInfo> updated) {
+ super.bindWorkspaceItemsChanged(updated);
+ if (getTaskbarUIController() != null && updated.stream()
+ .filter(w -> w.container == CONTAINER_HOTSEAT).findFirst().isPresent()) {
+ getTaskbarUIController().onHotseatUpdated();
+ }
}
@Override
@@ -262,7 +251,7 @@ public class QuickstepLauncher extends BaseQuickstepLauncher {
switch (state.ordinal) {
case HINT_STATE_ORDINAL: {
- Workspace<?> workspace = getWorkspace();
+ Workspace workspace = getWorkspace();
getStateManager().goToState(NORMAL);
if (workspace.getNextPage() != Workspace.DEFAULT_PAGE) {
workspace.post(workspace::moveToDefaultScreen);
@@ -302,7 +291,7 @@ public class QuickstepLauncher extends BaseQuickstepLauncher {
@Override
public TouchController[] createTouchControllers() {
- NavigationMode mode = DisplayController.getNavigationMode(this);
+ Mode mode = SysUINavigationMode.getMode(this);
ArrayList<TouchController> list = new ArrayList<>();
list.add(getDragController());
diff --git a/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java b/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java
index 00a98c0647..996d36aadc 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java
@@ -18,22 +18,20 @@ package com.android.launcher3.uioverrides;
import static com.android.launcher3.LauncherState.CLEAR_ALL_BUTTON;
import static com.android.launcher3.LauncherState.OVERVIEW_ACTIONS;
import static com.android.launcher3.LauncherState.OVERVIEW_SPLIT_SELECT;
+import static com.android.launcher3.LauncherState.SPLIT_PLACHOLDER_VIEW;
import static com.android.launcher3.anim.Interpolators.LINEAR;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_ACTIONS_FADE;
import static com.android.quickstep.views.RecentsView.CONTENT_ALPHA;
import static com.android.quickstep.views.RecentsView.FULLSCREEN_PROGRESS;
import static com.android.quickstep.views.RecentsView.TASK_MODALNESS;
-import static com.android.quickstep.views.RecentsView.TASK_PRIMARY_SPLIT_TRANSLATION;
-import static com.android.quickstep.views.RecentsView.TASK_SECONDARY_SPLIT_TRANSLATION;
+import static com.android.quickstep.views.SplitPlaceholderView.ALPHA_FLOAT;
import static com.android.quickstep.views.TaskView.FLAG_UPDATE_ALL;
import android.annotation.TargetApi;
import android.os.Build;
import android.util.FloatProperty;
-import android.util.Pair;
import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
import com.android.launcher3.BaseQuickstepLauncher;
import com.android.launcher3.LauncherState;
@@ -41,7 +39,6 @@ import com.android.launcher3.anim.AnimatorListeners;
import com.android.launcher3.anim.PendingAnimation;
import com.android.launcher3.anim.PropertySetter;
import com.android.launcher3.states.StateAnimationConfig;
-import com.android.launcher3.touch.PagedOrientationHandler;
import com.android.launcher3.util.MultiValueAlpha;
import com.android.quickstep.views.ClearAllButton;
import com.android.quickstep.views.LauncherRecentsView;
@@ -68,11 +65,6 @@ public final class RecentsViewStateController extends
}
setAlphas(PropertySetter.NO_ANIM_PROPERTY_SETTER, new StateAnimationConfig(), state);
mRecentsView.setFullscreenProgress(state.getOverviewFullscreenProgress());
- // In Overview, we may be layering app surfaces behind Launcher, so we need to notify
- // DepthController to prevent optimizations which might occlude the layers behind
- mLauncher.getDepthController().setHasContentBehindLauncher(state.overviewUi);
-
- handleSplitSelectionState(state, null);
}
@Override
@@ -88,12 +80,14 @@ public final class RecentsViewStateController extends
builder.addListener(
AnimatorListeners.forSuccessCallback(mRecentsView::resetTaskVisuals));
}
- // In Overview, we may be layering app surfaces behind Launcher, so we need to notify
- // DepthController to prevent optimizations which might occlude the layers behind
- builder.addListener(AnimatorListeners.forSuccessCallback(() ->
- mLauncher.getDepthController().setHasContentBehindLauncher(toState.overviewUi)));
- handleSplitSelectionState(toState, builder);
+ // Create or dismiss split screen select animations
+ LauncherState currentState = mLauncher.getStateManager().getState();
+ if (isSplitSelectionState(toState) && !isSplitSelectionState(currentState)) {
+ builder.add(mRecentsView.createSplitSelectInitAnimation().buildAnim());
+ } else if (!isSplitSelectionState(toState) && isSplitSelectionState(currentState)) {
+ builder.add(mRecentsView.cancelSplitSelect(true).buildAnim());
+ }
setAlphas(builder, config, toState);
builder.setFloat(mRecentsView, FULLSCREEN_PROGRESS,
@@ -101,39 +95,10 @@ public final class RecentsViewStateController extends
}
/**
- * Create or dismiss split screen select animations.
- * @param builder if null then this will run the split select animations right away, otherwise
- * will add animations to builder.
+ * @return true if {@param toState} is {@link LauncherState#OVERVIEW_SPLIT_SELECT}
*/
- private void handleSplitSelectionState(@NonNull LauncherState toState,
- @Nullable PendingAnimation builder) {
- boolean animate = builder != null;
- PagedOrientationHandler orientationHandler =
- ((RecentsView) mLauncher.getOverviewPanel()).getPagedOrientationHandler();
- Pair<FloatProperty, FloatProperty> taskViewsFloat =
- orientationHandler.getSplitSelectTaskOffset(
- TASK_PRIMARY_SPLIT_TRANSLATION, TASK_SECONDARY_SPLIT_TRANSLATION,
- mLauncher.getDeviceProfile());
-
- if (toState == OVERVIEW_SPLIT_SELECT) {
- // Animation to "dismiss" selected taskView
- PendingAnimation splitSelectInitAnimation = mRecentsView.createSplitSelectInitAnimation(
- toState.getTransitionDuration(mLauncher, true /* isToState */));
- // Add properties to shift remaining taskViews to get out of placeholder view
- splitSelectInitAnimation.setFloat(mRecentsView, taskViewsFloat.first,
- toState.getSplitSelectTranslation(mLauncher), LINEAR);
- splitSelectInitAnimation.setFloat(mRecentsView, taskViewsFloat.second, 0, LINEAR);
-
- if (!animate) {
- splitSelectInitAnimation.buildAnim().start();
- } else {
- builder.add(splitSelectInitAnimation.buildAnim());
- }
-
- mRecentsView.applySplitPrimaryScrollOffset();
- } else {
- mRecentsView.resetSplitPrimaryScrollOffset();
- }
+ private boolean isSplitSelectionState(@NonNull LauncherState toState) {
+ return toState == OVERVIEW_SPLIT_SELECT;
}
private void setAlphas(PropertySetter propertySetter, StateAnimationConfig config,
@@ -141,10 +106,16 @@ public final class RecentsViewStateController extends
float clearAllButtonAlpha = state.areElementsVisible(mLauncher, CLEAR_ALL_BUTTON) ? 1 : 0;
propertySetter.setFloat(mRecentsView.getClearAllButton(), ClearAllButton.VISIBILITY_ALPHA,
clearAllButtonAlpha, LINEAR);
- float overviewButtonAlpha = state.areElementsVisible(mLauncher, OVERVIEW_ACTIONS) ? 1 : 0;
+ float overviewButtonAlpha = state.areElementsVisible(mLauncher, OVERVIEW_ACTIONS)
+ && mRecentsView.shouldShowOverviewActionsForState(state) ? 1 : 0;
propertySetter.setFloat(mLauncher.getActionsView().getVisibilityAlpha(),
MultiValueAlpha.VALUE, overviewButtonAlpha, config.getInterpolator(
ANIM_OVERVIEW_ACTIONS_FADE, LINEAR));
+
+ float splitPlaceholderAlpha = state.areElementsVisible(mLauncher, SPLIT_PLACHOLDER_VIEW) ?
+ 0.85f : 0;
+ propertySetter.setFloat(mRecentsView.getSplitPlaceholder(), ALPHA_FLOAT,
+ splitPlaceholderAlpha, LINEAR);
}
@Override
diff --git a/quickstep/src/com/android/launcher3/uioverrides/plugins/PluginInitializerImpl.java b/quickstep/src/com/android/launcher3/uioverrides/plugins/PluginInitializerImpl.java
new file mode 100644
index 0000000000..d14e8efdd6
--- /dev/null
+++ b/quickstep/src/com/android/launcher3/uioverrides/plugins/PluginInitializerImpl.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2018 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.launcher3.uioverrides.plugins;
+
+import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
+
+import android.content.Context;
+import android.os.Looper;
+
+import com.android.launcher3.Utilities;
+import com.android.systemui.shared.plugins.PluginInitializer;
+
+public class PluginInitializerImpl implements PluginInitializer {
+ @Override
+ public Looper getBgLooper() {
+ return MODEL_EXECUTOR.getLooper();
+ }
+
+ @Override
+ public void onPluginManagerInit() {
+ }
+
+ @Override
+ public String[] getWhitelistedPlugins(Context context) {
+ return new String[0];
+ }
+
+ @Override
+ public PluginEnablerImpl getPluginEnabler(Context context) {
+ return new PluginEnablerImpl(context);
+ }
+
+ @Override
+ public void handleWtfs() {
+ }
+
+ public boolean isDebuggable() {
+ return Utilities.IS_DEBUG_DEVICE;
+ }
+}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/plugins/PluginManagerWrapper.java b/quickstep/src/com/android/launcher3/uioverrides/plugins/PluginManagerWrapper.java
index fe0bca6646..2e422b77f6 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/plugins/PluginManagerWrapper.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/plugins/PluginManagerWrapper.java
@@ -16,28 +16,20 @@ package com.android.launcher3.uioverrides.plugins;
import static android.content.pm.PackageManager.MATCH_DISABLED_COMPONENTS;
-import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
-
-import android.app.NotificationManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ResolveInfo;
-import com.android.launcher3.Utilities;
import com.android.launcher3.util.MainThreadInitializedObject;
import com.android.systemui.plugins.Plugin;
import com.android.systemui.plugins.PluginListener;
-import com.android.systemui.shared.plugins.PluginActionManager;
-import com.android.systemui.shared.plugins.PluginInstance;
import com.android.systemui.shared.plugins.PluginManager;
import com.android.systemui.shared.plugins.PluginManagerImpl;
import com.android.systemui.shared.plugins.PluginPrefs;
-import com.android.systemui.shared.system.UncaughtExceptionPreHandlerManager;
import java.io.PrintWriter;
import java.util.ArrayList;
-import java.util.Collections;
import java.util.List;
import java.util.Set;
@@ -48,45 +40,27 @@ public class PluginManagerWrapper {
public static final String PLUGIN_CHANGED = PluginManager.PLUGIN_CHANGED;
- private static final UncaughtExceptionPreHandlerManager UNCAUGHT_EXCEPTION_PRE_HANDLER_MANAGER =
- new UncaughtExceptionPreHandlerManager();
-
private final Context mContext;
private final PluginManager mPluginManager;
private final PluginEnablerImpl mPluginEnabler;
private PluginManagerWrapper(Context c) {
mContext = c;
- mPluginEnabler = new PluginEnablerImpl(c);
- List<String> privilegedPlugins = Collections.emptyList();
- PluginInstance.Factory instanceFactory = new PluginInstance.Factory(
- getClass().getClassLoader(), new PluginInstance.InstanceFactory<>(),
- new PluginInstance.VersionChecker(), privilegedPlugins,
- Utilities.IS_DEBUG_DEVICE);
- PluginActionManager.Factory instanceManagerFactory = new PluginActionManager.Factory(
- c, c.getPackageManager(), c.getMainExecutor(), MODEL_EXECUTOR,
- c.getSystemService(NotificationManager.class), mPluginEnabler,
- privilegedPlugins, instanceFactory);
-
- mPluginManager = new PluginManagerImpl(c, instanceManagerFactory,
- Utilities.IS_DEBUG_DEVICE,
- UNCAUGHT_EXCEPTION_PRE_HANDLER_MANAGER, mPluginEnabler,
- new PluginPrefs(c), privilegedPlugins);
+ PluginInitializerImpl pluginInitializer = new PluginInitializerImpl();
+ mPluginManager = new PluginManagerImpl(c, pluginInitializer);
+ mPluginEnabler = pluginInitializer.getPluginEnabler(c);
}
public PluginEnablerImpl getPluginEnabler() {
return mPluginEnabler;
}
- /** */
- public <T extends Plugin> void addPluginListener(
- PluginListener<T> listener, Class<T> pluginClass) {
+ public void addPluginListener(PluginListener<? extends Plugin> listener, Class<?> pluginClass) {
addPluginListener(listener, pluginClass, false);
}
- /** */
- public <T extends Plugin> void addPluginListener(
- PluginListener<T> listener, Class<T> pluginClass, boolean allowMultiple) {
+ public void addPluginListener(PluginListener<? extends Plugin> listener, Class<?> pluginClass,
+ boolean allowMultiple) {
mPluginManager.addPluginListener(listener, pluginClass, allowMultiple);
}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java b/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java
index a74774c62b..f8c9fd128f 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java
@@ -20,10 +20,10 @@ import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_ALLAP
import android.content.Context;
-import com.android.launcher3.DeviceProfile.DeviceProfileListenable;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherState;
import com.android.launcher3.R;
+import com.android.launcher3.allapps.AllAppsContainerView;
import com.android.launcher3.util.Themes;
/**
@@ -31,26 +31,28 @@ import com.android.launcher3.util.Themes;
*/
public class AllAppsState extends LauncherState {
- private static final float WORKSPACE_SCALE_FACTOR = 0.97f;
+ private static final int STATE_FLAGS = FLAG_WORKSPACE_INACCESSIBLE | FLAG_CLOSE_POPUPS;
- private static final int STATE_FLAGS =
- FLAG_WORKSPACE_INACCESSIBLE | FLAG_CLOSE_POPUPS | FLAG_HOTSEAT_INACCESSIBLE;
+ private static final PageAlphaProvider PAGE_ALPHA_PROVIDER = new PageAlphaProvider(DEACCEL_2) {
+ @Override
+ public float getPageAlpha(int pageIndex) {
+ return 0;
+ }
+ };
public AllAppsState(int id) {
super(id, LAUNCHER_STATE_ALLAPPS, STATE_FLAGS);
}
@Override
- public <DEVICE_PROFILE_CONTEXT extends Context & DeviceProfileListenable>
- int getTransitionDuration(DEVICE_PROFILE_CONTEXT context, boolean isToState) {
- return !context.getDeviceProfile().isTablet && isToState
- ? 600
- : isToState ? 500 : 300;
+ public int getTransitionDuration(Context context) {
+ return 320;
}
@Override
public String getDescription(Launcher launcher) {
- return launcher.getAppsView().getDescription();
+ AllAppsContainerView appsView = launcher.getAppsView();
+ return appsView.getDescription();
}
@Override
@@ -60,21 +62,10 @@ public class AllAppsState extends LauncherState {
@Override
public ScaleAndTranslation getWorkspaceScaleAndTranslation(Launcher launcher) {
- return new ScaleAndTranslation(WORKSPACE_SCALE_FACTOR, NO_OFFSET, NO_OFFSET);
- }
-
- @Override
- public ScaleAndTranslation getHotseatScaleAndTranslation(Launcher launcher) {
- if (launcher.getDeviceProfile().isTablet) {
- return getWorkspaceScaleAndTranslation(launcher);
- } else {
- ScaleAndTranslation overviewScaleAndTranslation = LauncherState.OVERVIEW
- .getWorkspaceScaleAndTranslation(launcher);
- return new ScaleAndTranslation(
- WORKSPACE_SCALE_FACTOR,
- overviewScaleAndTranslation.translationX,
- overviewScaleAndTranslation.translationY);
- }
+ ScaleAndTranslation scaleAndTranslation = LauncherState.OVERVIEW
+ .getWorkspaceScaleAndTranslation(launcher);
+ scaleAndTranslation.scale = 1;
+ return scaleAndTranslation;
}
@Override
@@ -86,22 +77,12 @@ public class AllAppsState extends LauncherState {
@Override
public PageAlphaProvider getWorkspacePageAlphaProvider(Launcher launcher) {
- PageAlphaProvider superPageAlphaProvider = super.getWorkspacePageAlphaProvider(launcher);
- return new PageAlphaProvider(DEACCEL_2) {
- @Override
- public float getPageAlpha(int pageIndex) {
- return launcher.getDeviceProfile().isTablet
- ? superPageAlphaProvider.getPageAlpha(pageIndex)
- : 0;
- }
- };
+ return PAGE_ALPHA_PROVIDER;
}
@Override
public int getVisibleElements(Launcher launcher) {
- // Don't add HOTSEAT_ICONS for non-tablets in ALL_APPS state.
- return launcher.getDeviceProfile().isTablet ? ALL_APPS_CONTENT | HOTSEAT_ICONS
- : ALL_APPS_CONTENT;
+ return ALL_APPS_CONTENT;
}
@Override
@@ -111,8 +92,6 @@ public class AllAppsState extends LauncherState {
@Override
public int getWorkspaceScrimColor(Launcher launcher) {
- return launcher.getDeviceProfile().isTablet
- ? launcher.getResources().getColor(R.color.widgets_picker_scrim)
- : Themes.getAttrColor(launcher, R.attr.allAppsScrimColor);
+ return Themes.getAttrColor(launcher, R.attr.allAppsScrimColor);
}
}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java b/quickstep/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java
index b7330072d4..fe5a3475ff 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java
@@ -23,7 +23,6 @@ import android.graphics.Color;
import com.android.launcher3.BaseDraggingActivity;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Launcher;
-import com.android.launcher3.R;
import com.android.launcher3.allapps.AllAppsTransitionController;
import com.android.quickstep.util.LayoutUtils;
import com.android.quickstep.views.RecentsView;
@@ -74,7 +73,8 @@ public class BackgroundAppState extends OverviewState {
return super.getVisibleElements(launcher)
& ~OVERVIEW_ACTIONS
& ~CLEAR_ALL_BUTTON
- & ~VERTICAL_SWIPE_INDICATOR;
+ & ~VERTICAL_SWIPE_INDICATOR
+ | TASKBAR;
}
@Override
@@ -89,10 +89,6 @@ public class BackgroundAppState extends OverviewState {
@Override
public int getWorkspaceScrimColor(Launcher launcher) {
- DeviceProfile dp = launcher.getDeviceProfile();
- if (dp.isTaskbarPresentInApps) {
- return launcher.getColor(R.color.taskbar_background);
- }
return Color.TRANSPARENT;
}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/OverviewModalTaskState.java b/quickstep/src/com/android/launcher3/uioverrides/states/OverviewModalTaskState.java
index 0c49e5fc69..6f084a1f97 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/states/OverviewModalTaskState.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/states/OverviewModalTaskState.java
@@ -40,7 +40,7 @@ public class OverviewModalTaskState extends OverviewState {
}
@Override
- public int getTransitionDuration(Context launcher, boolean isToState) {
+ public int getTransitionDuration(Context launcher) {
return 300;
}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java b/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java
index 6427e0981a..8c128c8e08 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java
@@ -21,15 +21,16 @@ import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_OVERV
import android.content.Context;
import android.graphics.Rect;
import android.os.SystemProperties;
+import android.view.View;
-import com.android.launcher3.BaseQuickstepLauncher;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherState;
import com.android.launcher3.R;
-import com.android.launcher3.taskbar.LauncherTaskbarUIController;
-import com.android.launcher3.util.DisplayController;
+import com.android.launcher3.Workspace;
+import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.util.Themes;
+import com.android.quickstep.SysUINavigationMode;
import com.android.quickstep.util.LayoutUtils;
import com.android.quickstep.views.RecentsView;
import com.android.quickstep.views.TaskView;
@@ -58,17 +59,20 @@ public class OverviewState extends LauncherState {
}
@Override
- public int getTransitionDuration(Context context, boolean isToState) {
+ public int getTransitionDuration(Context context) {
// In gesture modes, overview comes in all the way from the side, so give it more time.
- return DisplayController.getNavigationMode(context).hasGestures ? 380 : 250;
+ return SysUINavigationMode.INSTANCE.get(context).getMode().hasGestures ? 380 : 250;
}
@Override
public ScaleAndTranslation getWorkspaceScaleAndTranslation(Launcher launcher) {
RecentsView recentsView = launcher.getOverviewPanel();
- float workspacePageHeight = launcher.getDeviceProfile().getCellLayoutHeight();
+ Workspace workspace = launcher.getWorkspace();
+ View workspacePage = workspace.getPageAt(workspace.getCurrentPage());
+ float workspacePageWidth = workspacePage != null && workspacePage.getWidth() != 0
+ ? workspacePage.getWidth() : launcher.getDeviceProfile().availableWidthPx;
recentsView.getTaskSize(sTempRect);
- float scale = (float) sTempRect.height() / workspacePageHeight;
+ float scale = (float) sTempRect.width() / workspacePageWidth;
float parallaxFactor = 0.5f;
return new ScaleAndTranslation(scale, 0, -getDefaultSwipeHeight(launcher) * parallaxFactor);
}
@@ -79,6 +83,16 @@ public class OverviewState extends LauncherState {
}
@Override
+ public float getTaskbarScale(Launcher launcher) {
+ return 1f;
+ }
+
+ @Override
+ public float getTaskbarTranslationY(Launcher launcher) {
+ return 0f;
+ }
+
+ @Override
public PageAlphaProvider getWorkspacePageAlphaProvider(Launcher launcher) {
return new PageAlphaProvider(DEACCEL_2) {
@Override
@@ -94,24 +108,13 @@ public class OverviewState extends LauncherState {
}
@Override
- public boolean isTaskbarStashed(Launcher launcher) {
- if (launcher instanceof BaseQuickstepLauncher) {
- LauncherTaskbarUIController uiController =
- ((BaseQuickstepLauncher) launcher).getTaskbarUIController();
-
- return uiController != null && uiController.supportsVisualStashing();
- }
- return super.isTaskbarStashed(launcher);
- }
-
- @Override
public int getWorkspaceScrimColor(Launcher launcher) {
return Themes.getAttrColor(launcher, R.attr.overviewScrimColor);
}
@Override
public boolean displayOverviewTasksAsGrid(DeviceProfile deviceProfile) {
- return deviceProfile.isTablet;
+ return deviceProfile.isTablet && FeatureFlags.ENABLE_OVERVIEW_GRID.get();
}
@Override
@@ -131,14 +134,9 @@ public class OverviewState extends LauncherState {
@Override
public void onBackPressed(Launcher launcher) {
- RecentsView recentsView = launcher.getOverviewPanel();
- TaskView taskView = recentsView.getRunningTaskView();
+ TaskView taskView = launcher.<RecentsView>getOverviewPanel().getRunningTaskView();
if (taskView != null) {
- if (recentsView.isTaskViewFullyVisible(taskView)) {
- taskView.launchTasks();
- } else {
- recentsView.snapToPage(recentsView.indexOfChild(taskView));
- }
+ taskView.launchTaskAnimated();
} else {
super.onBackPressed(launcher);
}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/QuickSwitchState.java b/quickstep/src/com/android/launcher3/uioverrides/states/QuickSwitchState.java
index 969abc2804..d36e76b89b 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/states/QuickSwitchState.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/states/QuickSwitchState.java
@@ -17,7 +17,6 @@ package com.android.launcher3.uioverrides.states;
import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_BACKGROUND;
-import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Launcher;
import com.android.launcher3.R;
import com.android.launcher3.util.Themes;
@@ -43,10 +42,6 @@ public class QuickSwitchState extends BackgroundAppState {
@Override
public int getWorkspaceScrimColor(Launcher launcher) {
- DeviceProfile dp = launcher.getDeviceProfile();
- if (dp.isTaskbarPresentInApps) {
- return launcher.getColor(R.color.taskbar_background);
- }
return Themes.getAttrColor(launcher, R.attr.overviewScrimColor);
}
@@ -58,16 +53,6 @@ public class QuickSwitchState extends BackgroundAppState {
@Override
public int getVisibleElements(Launcher launcher) {
- return NONE;
- }
-
- @Override
- public boolean isTaskbarStashed(Launcher launcher) {
- return !launcher.getDeviceProfile().isTaskbarPresentInApps;
- }
-
- @Override
- public boolean isTaskbarAlignedWithHotseat(Launcher launcher) {
- return false;
+ return TASKBAR;
}
}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/QuickstepAtomicAnimationFactory.java b/quickstep/src/com/android/launcher3/uioverrides/states/QuickstepAtomicAnimationFactory.java
index 2d7fe69d3b..0e2fbbc2bf 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/states/QuickstepAtomicAnimationFactory.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/states/QuickstepAtomicAnimationFactory.java
@@ -17,12 +17,11 @@ package com.android.launcher3.uioverrides.states;
import static android.view.View.VISIBLE;
-import static com.android.launcher3.LauncherState.ALL_APPS;
import static com.android.launcher3.LauncherState.HINT_STATE;
import static com.android.launcher3.LauncherState.HINT_STATE_TWO_BUTTON;
import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.launcher3.LauncherState.OVERVIEW;
-import static com.android.launcher3.WorkspaceStateTransitionAnimation.getWorkspaceSpringScaleAnimator;
+import static com.android.launcher3.WorkspaceStateTransitionAnimation.getSpringScaleAnimator;
import static com.android.launcher3.anim.Interpolators.ACCEL;
import static com.android.launcher3.anim.Interpolators.ACCEL_DEACCEL;
import static com.android.launcher3.anim.Interpolators.DEACCEL;
@@ -42,17 +41,10 @@ import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_SC
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_TRANSLATE_X;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_TRANSLATE_Y;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_SCRIM_FADE;
-import static com.android.launcher3.states.StateAnimationConfig.ANIM_VERTICAL_PROGRESS;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_FADE;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_SCALE;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_TRANSLATE;
-import static com.android.launcher3.uioverrides.touchcontrollers.PortraitStatesTouchController.ALL_APPS_CONTENT_FADE_MAX_CLAMPING_THRESHOLD;
-import static com.android.launcher3.uioverrides.touchcontrollers.PortraitStatesTouchController.ALL_APPS_CONTENT_FADE_MIN_CLAMPING_THRESHOLD;
-import static com.android.launcher3.uioverrides.touchcontrollers.PortraitStatesTouchController.ALL_APPS_SCRIM_OPAQUE_THRESHOLD;
-import static com.android.launcher3.uioverrides.touchcontrollers.PortraitStatesTouchController.ALL_APPS_SCRIM_VISIBLE_THRESHOLD;
import static com.android.quickstep.views.RecentsView.RECENTS_SCALE_PROPERTY;
-import static com.android.systemui.animation.Interpolators.EMPHASIZED_ACCELERATE;
-import static com.android.systemui.animation.Interpolators.EMPHASIZED_DECELERATE;
import android.animation.ValueAnimator;
@@ -60,10 +52,9 @@ import com.android.launcher3.CellLayout;
import com.android.launcher3.Hotseat;
import com.android.launcher3.LauncherState;
import com.android.launcher3.Workspace;
-import com.android.launcher3.anim.Interpolators;
import com.android.launcher3.states.StateAnimationConfig;
import com.android.launcher3.uioverrides.QuickstepLauncher;
-import com.android.launcher3.util.DisplayController;
+import com.android.quickstep.SysUINavigationMode;
import com.android.quickstep.util.RecentsAtomicAnimationFactory;
import com.android.quickstep.views.RecentsView;
@@ -100,7 +91,7 @@ public class QuickstepAtomicAnimationFactory extends
config.setInterpolator(ANIM_WORKSPACE_SCALE, DEACCEL);
config.setInterpolator(ANIM_WORKSPACE_FADE, ACCEL);
- if (DisplayController.getNavigationMode(mActivity).hasGestures
+ if (SysUINavigationMode.getMode(mActivity).hasGestures
&& overview.getTaskViewCount() > 0) {
// Overview is going offscreen, so keep it at its current scale and opacity.
config.setInterpolator(ANIM_OVERVIEW_SCALE, FINAL_FRAME);
@@ -121,7 +112,7 @@ public class QuickstepAtomicAnimationFactory extends
config.duration = Math.max(config.duration, scrollDuration);
overview.snapToPage(DEFAULT_PAGE, Math.toIntExact(config.duration));
- Workspace<?> workspace = mActivity.getWorkspace();
+ Workspace workspace = mActivity.getWorkspace();
// Start from a higher workspace scale, but only if we're invisible so we don't jump.
boolean isWorkspaceVisible = workspace.getVisibility() == VISIBLE;
if (isWorkspaceVisible) {
@@ -142,7 +133,7 @@ public class QuickstepAtomicAnimationFactory extends
}
} else if ((fromState == NORMAL || fromState == HINT_STATE
|| fromState == HINT_STATE_TWO_BUTTON) && toState == OVERVIEW) {
- if (DisplayController.getNavigationMode(mActivity).hasGestures) {
+ if (SysUINavigationMode.getMode(mActivity).hasGestures) {
config.setInterpolator(ANIM_WORKSPACE_SCALE,
fromState == NORMAL ? ACCEL : OVERSHOOT_1_2);
config.setInterpolator(ANIM_WORKSPACE_TRANSLATE, ACCEL);
@@ -175,30 +166,11 @@ public class QuickstepAtomicAnimationFactory extends
} else if (fromState == HINT_STATE && toState == NORMAL) {
config.setInterpolator(ANIM_DEPTH, DEACCEL_3);
if (mHintToNormalDuration == -1) {
- ValueAnimator va = getWorkspaceSpringScaleAnimator(mActivity,
- mActivity.getWorkspace(),
+ ValueAnimator va = getSpringScaleAnimator(mActivity, mActivity.getWorkspace(),
toState.getWorkspaceScaleAndTranslation(mActivity).scale);
mHintToNormalDuration = (int) va.getDuration();
}
config.duration = Math.max(config.duration, mHintToNormalDuration);
- } else if (fromState == ALL_APPS && toState == NORMAL) {
- boolean isTablet = mActivity.getDeviceProfile().isTablet;
- config.setInterpolator(ANIM_ALL_APPS_FADE,
- isTablet ? FINAL_FRAME : Interpolators.clampToProgress(LINEAR,
- 1 - ALL_APPS_CONTENT_FADE_MAX_CLAMPING_THRESHOLD,
- 1 - ALL_APPS_CONTENT_FADE_MIN_CLAMPING_THRESHOLD));
- config.setInterpolator(ANIM_SCRIM_FADE, Interpolators.clampToProgress(LINEAR,
- 1 - ALL_APPS_SCRIM_OPAQUE_THRESHOLD,
- 1 - ALL_APPS_SCRIM_VISIBLE_THRESHOLD));
- config.setInterpolator(ANIM_VERTICAL_PROGRESS, EMPHASIZED_ACCELERATE);
- if (!isTablet) {
- config.setInterpolator(ANIM_WORKSPACE_FADE, INSTANT);
- }
- } else if (fromState == NORMAL && toState == ALL_APPS) {
- if (mActivity.getDeviceProfile().isTablet) {
- config.setInterpolator(ANIM_VERTICAL_PROGRESS, EMPHASIZED_DECELERATE);
- }
- // TODO(b/231682175): centralize this setup in AllAppsSwipeController
}
}
}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/SplitScreenSelectState.java b/quickstep/src/com/android/launcher3/uioverrides/states/SplitScreenSelectState.java
index e79d56b631..6968494b0f 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/states/SplitScreenSelectState.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/states/SplitScreenSelectState.java
@@ -17,6 +17,8 @@
package com.android.launcher3.uioverrides.states;
import com.android.launcher3.Launcher;
+import com.android.launcher3.R;
+import com.android.launcher3.touch.PagedOrientationHandler;
import com.android.quickstep.views.RecentsView;
/**
@@ -29,6 +31,11 @@ public class SplitScreenSelectState extends OverviewState {
}
@Override
+ public void onBackPressed(Launcher launcher) {
+ launcher.getStateManager().goToState(OVERVIEW);
+ }
+
+ @Override
public int getVisibleElements(Launcher launcher) {
return SPLIT_PLACHOLDER_VIEW;
}
@@ -36,6 +43,13 @@ public class SplitScreenSelectState extends OverviewState {
@Override
public float getSplitSelectTranslation(Launcher launcher) {
RecentsView recentsView = launcher.getOverviewPanel();
- return recentsView.getSplitSelectTranslation();
+ int splitPosition = recentsView.getSplitPlaceholder().getSplitController()
+ .getActiveSplitPositionOption().mStagePosition;
+ if (!recentsView.shouldShiftThumbnailsForSplitSelect(splitPosition)) {
+ return 0f;
+ }
+ PagedOrientationHandler orientationHandler = recentsView.getPagedOrientationHandler();
+ int direction = orientationHandler.getSplitTranslationDirectionFactor(splitPosition);
+ return launcher.getResources().getDimension(R.dimen.split_placeholder_size) * direction;
}
}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java
index 34a6821ac5..86c42caa7b 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java
@@ -21,8 +21,7 @@ import static com.android.launcher3.LauncherAnimUtils.SUCCESS_TRANSITION_PROGRES
import static com.android.launcher3.LauncherAnimUtils.newCancelListener;
import static com.android.launcher3.LauncherState.ALL_APPS;
import static com.android.launcher3.LauncherState.NORMAL;
-import static com.android.launcher3.allapps.AllAppsTransitionController.ALL_APPS_PULL_BACK_ALPHA;
-import static com.android.launcher3.allapps.AllAppsTransitionController.ALL_APPS_PULL_BACK_TRANSLATION;
+import static com.android.launcher3.allapps.AllAppsTransitionController.ALL_APPS_PROGRESS;
import static com.android.launcher3.anim.AnimatorListeners.forSuccessCallback;
import static com.android.launcher3.anim.Interpolators.DEACCEL_3;
import static com.android.launcher3.config.FeatureFlags.ENABLE_ALL_APPS_EDU;
@@ -41,14 +40,16 @@ import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.allapps.AllAppsTransitionController;
import com.android.launcher3.anim.AnimatorPlaybackController;
+import com.android.launcher3.anim.Interpolators;
import com.android.launcher3.anim.PendingAnimation;
import com.android.launcher3.compat.AccessibilityManagerCompat;
import com.android.launcher3.config.FeatureFlags;
+import com.android.launcher3.states.StateAnimationConfig;
import com.android.launcher3.touch.SingleAxisSwipeDetector;
import com.android.launcher3.util.TouchController;
import com.android.quickstep.TaskUtils;
-import com.android.quickstep.TopTaskTracker;
import com.android.quickstep.util.AnimatorControllerWithResistance;
+import com.android.quickstep.util.AssistantUtilities;
import com.android.quickstep.util.OverviewToHomeAnim;
import com.android.quickstep.views.RecentsView;
@@ -111,8 +112,7 @@ public class NavBarToHomeTouchController implements TouchController,
return true;
}
if (FeatureFlags.ASSISTANT_GIVES_LAUNCHER_FOCUS.get()
- && TopTaskTracker.INSTANCE.get(mLauncher).getCachedTopTask(false)
- .isExcludedAssistant()) {
+ && AssistantUtilities.isExcludedAssistantRunning()) {
return true;
}
return false;
@@ -147,10 +147,16 @@ public class NavBarToHomeTouchController implements TouchController,
AbstractFloatingView.closeOpenContainer(mLauncher, AbstractFloatingView.TYPE_TASK_MENU);
} else if (mStartState == ALL_APPS) {
AllAppsTransitionController allAppsController = mLauncher.getAllAppsController();
- builder.setFloat(allAppsController, ALL_APPS_PULL_BACK_TRANSLATION,
- -mPullbackDistance, PULLBACK_INTERPOLATOR);
- builder.setFloat(allAppsController, ALL_APPS_PULL_BACK_ALPHA,
- 0.5f, PULLBACK_INTERPOLATOR);
+ builder.setFloat(allAppsController, ALL_APPS_PROGRESS,
+ -mPullbackDistance / allAppsController.getShiftRange(), PULLBACK_INTERPOLATOR);
+
+ // Slightly fade out all apps content to further distinguish from scrolling.
+ StateAnimationConfig config = new StateAnimationConfig();
+ config.duration = accuracy;
+ config.setInterpolator(StateAnimationConfig.ANIM_ALL_APPS_FADE, Interpolators
+ .mapToProgress(PULLBACK_INTERPOLATOR, 0, 0.5f));
+
+ allAppsController.setAlphas(mEndState, config, builder);
}
AbstractFloatingView topView = AbstractFloatingView.getTopOpenView(mLauncher);
if (topView != null) {
diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonNavbarToOverviewTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonNavbarToOverviewTouchController.java
index 8faabc9561..283743dc64 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonNavbarToOverviewTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonNavbarToOverviewTouchController.java
@@ -18,14 +18,13 @@ package com.android.launcher3.uioverrides.touchcontrollers;
import static com.android.launcher3.LauncherAnimUtils.VIEW_BACKGROUND_COLOR;
import static com.android.launcher3.LauncherAnimUtils.newCancelListener;
-import static com.android.launcher3.LauncherState.ALL_APPS;
import static com.android.launcher3.LauncherState.HINT_STATE;
import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.launcher3.LauncherState.OVERVIEW;
import static com.android.launcher3.Utilities.EDGE_NAV_BAR;
import static com.android.launcher3.anim.AnimatorListeners.forSuccessCallback;
import static com.android.launcher3.anim.Interpolators.ACCEL_DEACCEL;
-import static com.android.quickstep.util.VibratorWrapper.OVERVIEW_HAPTIC;
+import static com.android.launcher3.util.VibratorWrapper.OVERVIEW_HAPTIC;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_OVERVIEW_DISABLED;
import android.animation.ObjectAnimator;
@@ -34,18 +33,16 @@ import android.graphics.PointF;
import android.view.MotionEvent;
import android.view.ViewConfiguration;
-import com.android.launcher3.BaseQuickstepLauncher;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherState;
import com.android.launcher3.Utilities;
import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.states.StateAnimationConfig;
-import com.android.launcher3.taskbar.LauncherTaskbarUIController;
+import com.android.launcher3.util.VibratorWrapper;
import com.android.quickstep.SystemUiProxy;
import com.android.quickstep.util.AnimatorControllerWithResistance;
import com.android.quickstep.util.MotionPauseDetector;
import com.android.quickstep.util.OverviewToHomeAnim;
-import com.android.quickstep.util.VibratorWrapper;
import com.android.quickstep.views.RecentsView;
/**
@@ -86,7 +83,7 @@ public class NoButtonNavbarToOverviewTouchController extends PortraitStatesTouch
@Override
protected boolean canInterceptTouch(MotionEvent ev) {
mDidTouchStartInNavBar = (ev.getEdgeFlags() & EDGE_NAV_BAR) != 0;
- return super.canInterceptTouch(ev) && !mLauncher.isInState(HINT_STATE);
+ return super.canInterceptTouch(ev);
}
@Override
@@ -112,14 +109,6 @@ public class NoButtonNavbarToOverviewTouchController extends PortraitStatesTouch
@Override
public void onDragStart(boolean start, float startDisplacement) {
- if (mLauncher.isInState(ALL_APPS)) {
- LauncherTaskbarUIController controller =
- ((BaseQuickstepLauncher) mLauncher).getTaskbarUIController();
- if (controller != null) {
- controller.setShouldDelayLauncherStateAnim(true);
- }
- }
-
super.onDragStart(start, startDisplacement);
mMotionPauseDetector.clear();
@@ -150,12 +139,6 @@ public class NoButtonNavbarToOverviewTouchController extends PortraitStatesTouch
@Override
public void onDragEnd(float velocity) {
- LauncherTaskbarUIController controller =
- ((BaseQuickstepLauncher) mLauncher).getTaskbarUIController();
- if (controller != null) {
- controller.setShouldDelayLauncherStateAnim(false);
- }
-
if (mStartedOverview) {
goToOverviewOrHomeOnDragEnd(velocity);
} else {
@@ -180,7 +163,7 @@ public class NoButtonNavbarToOverviewTouchController extends PortraitStatesTouch
// Normally we compute the duration based on the velocity and distance to the given
// state, but since the hint state tracks the entire screen without a clear endpoint, we
// need to manually set the duration to a reasonable value.
- animator.setDuration(HINT_STATE.getTransitionDuration(mLauncher, true /* isToState */));
+ animator.setDuration(HINT_STATE.getTransitionDuration(mLauncher));
}
}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java
index 53dc9dd873..40c3e02238 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java
@@ -27,7 +27,6 @@ import static com.android.launcher3.anim.Interpolators.DEACCEL_3;
import static com.android.launcher3.anim.Interpolators.LINEAR;
import static com.android.launcher3.anim.Interpolators.scrollInterpolatorForVelocity;
import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_HOME;
-import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_QUICKSWITCH_RIGHT;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_UNKNOWN_SWIPEDOWN;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_UNKNOWN_SWIPEUP;
import static com.android.launcher3.logging.StatsLogManager.getLauncherAtomEvent;
@@ -39,11 +38,10 @@ import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_S
import static com.android.launcher3.states.StateAnimationConfig.SKIP_ALL_ANIMATIONS;
import static com.android.launcher3.states.StateAnimationConfig.SKIP_OVERVIEW;
import static com.android.launcher3.states.StateAnimationConfig.SKIP_SCRIM;
-import static com.android.launcher3.testing.TestProtocol.BAD_STATE;
import static com.android.launcher3.touch.BothAxesSwipeDetector.DIRECTION_RIGHT;
import static com.android.launcher3.touch.BothAxesSwipeDetector.DIRECTION_UP;
-import static com.android.launcher3.util.window.RefreshRateTracker.getSingleFrameMs;
-import static com.android.quickstep.util.VibratorWrapper.OVERVIEW_HAPTIC;
+import static com.android.launcher3.util.DisplayController.getSingleFrameMs;
+import static com.android.launcher3.util.VibratorWrapper.OVERVIEW_HAPTIC;
import static com.android.quickstep.views.RecentsView.ADJACENT_PAGE_HORIZONTAL_OFFSET;
import static com.android.quickstep.views.RecentsView.CONTENT_ALPHA;
import static com.android.quickstep.views.RecentsView.FULLSCREEN_PROGRESS;
@@ -56,7 +54,6 @@ import android.animation.Animator.AnimatorListener;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.graphics.PointF;
-import android.util.Log;
import android.view.MotionEvent;
import android.view.animation.Interpolator;
@@ -70,15 +67,14 @@ import com.android.launcher3.states.StateAnimationConfig;
import com.android.launcher3.touch.BaseSwipeDetector;
import com.android.launcher3.touch.BothAxesSwipeDetector;
import com.android.launcher3.util.TouchController;
+import com.android.launcher3.util.VibratorWrapper;
import com.android.quickstep.AnimatedFloat;
import com.android.quickstep.SystemUiProxy;
import com.android.quickstep.util.AnimatorControllerWithResistance;
import com.android.quickstep.util.LayoutUtils;
import com.android.quickstep.util.MotionPauseDetector;
-import com.android.quickstep.util.VibratorWrapper;
import com.android.quickstep.util.WorkspaceRevealAnim;
import com.android.quickstep.views.LauncherRecentsView;
-import com.android.quickstep.views.RecentsView;
/**
* Handles quick switching to a recent task from the home screen. To give as much flexibility to
@@ -227,7 +223,6 @@ public class NoButtonQuickSwitchTouchController implements TouchController,
// Set RecentView's initial properties.
RECENTS_SCALE_PROPERTY.set(mRecentsView, fromState.getOverviewScaleAndOffset(mLauncher)[0]);
ADJACENT_PAGE_HORIZONTAL_OFFSET.set(mRecentsView, 1f);
- Log.d(BAD_STATE, "NBQSTC setupOverviewAnimators setContentAlpha=1");
mRecentsView.setContentAlpha(1);
mRecentsView.setFullscreenProgress(fromState.getOverviewFullscreenProgress());
mLauncher.getActionsView().getVisibilityAlpha().setValue(
@@ -240,30 +235,10 @@ public class NoButtonQuickSwitchTouchController implements TouchController,
// - RecentsView fade (if it's empty)
PendingAnimation xAnim = new PendingAnimation((long) (mXRange * 2));
xAnim.setFloat(mRecentsView, ADJACENT_PAGE_HORIZONTAL_OFFSET, scaleAndOffset[1], LINEAR);
- // Use QuickSwitchState instead of OverviewState to determine scrim color,
- // since we need to take potential taskbar into account.
xAnim.setViewBackgroundColor(mLauncher.getScrimView(),
- QUICK_SWITCH.getWorkspaceScrimColor(mLauncher), LINEAR);
+ toState.getWorkspaceScrimColor(mLauncher), LINEAR);
if (mRecentsView.getTaskViewCount() == 0) {
xAnim.addFloat(mRecentsView, CONTENT_ALPHA, 0f, 1f, LINEAR);
- Log.d(BAD_STATE, "NBQSTC setupOverviewAnimators from: 0 to: 1");
- xAnim.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationStart(Animator animation) {
- Log.d(BAD_STATE, "NBQSTC setupOverviewAnimators onStart");
- }
-
- @Override
- public void onAnimationCancel(Animator animation) {
- float alpha = mRecentsView == null ? -1 : CONTENT_ALPHA.get(mRecentsView);
- Log.d(BAD_STATE, "NBQSTC setupOverviewAnimators onCancel, alpha=" + alpha);
- }
-
- @Override
- public void onAnimationEnd(Animator animation) {
- Log.d(BAD_STATE, "NBQSTC setupOverviewAnimators onEnd");
- }
- });
}
mXOverviewAnim = xAnim.createPlaybackController();
mXOverviewAnim.dispatchOnStart();
@@ -334,11 +309,6 @@ public class NoButtonQuickSwitchTouchController implements TouchController,
}
});
overviewAnim.start();
-
- // Create an empty state transition so StateListeners get onStateTransitionStart().
- mLauncher.getStateManager().createAnimationToNewWorkspace(
- OVERVIEW, config.duration, StateAnimationConfig.SKIP_ALL_ANIMATIONS)
- .dispatchOnStart();
return;
}
@@ -413,7 +383,6 @@ public class NoButtonQuickSwitchTouchController implements TouchController,
config.animFlags = SKIP_ALL_ANIMATIONS;
updateNonOverviewAnim(targetState, config);
nonOverviewAnim = mNonOverviewAnim.getAnimationPlayer();
- mNonOverviewAnim.dispatchOnStart();
new WorkspaceRevealAnim(mLauncher, false /* animateOverviewScrim */).start();
} else {
@@ -429,14 +398,6 @@ public class NoButtonQuickSwitchTouchController implements TouchController,
nonOverviewAnim.setFloatValues(startProgress, endProgress);
mNonOverviewAnim.dispatchOnStart();
}
- if (targetState == QUICK_SWITCH) {
- // Navigating to quick switch, add scroll feedback since the first time is not
- // considered a scroll by the RecentsView.
- VibratorWrapper.INSTANCE.get(mLauncher).vibrate(
- RecentsView.SCROLL_VIBRATION_PRIMITIVE,
- RecentsView.SCROLL_VIBRATION_PRIMITIVE_SCALE,
- RecentsView.SCROLL_VIBRATION_FALLBACK);
- }
nonOverviewAnim.setDuration(Math.max(xDuration, yDuration));
mNonOverviewAnim.setEndAction(() -> onAnimationToStateCompleted(targetState));
@@ -452,11 +413,9 @@ public class NoButtonQuickSwitchTouchController implements TouchController,
.withSrcState(LAUNCHER_STATE_HOME)
.withDstState(targetState.statsLogOrdinal)
.log(getLauncherAtomEvent(mStartState.statsLogOrdinal, targetState.statsLogOrdinal,
- targetState == QUICK_SWITCH
- ? LAUNCHER_QUICKSWITCH_RIGHT
- : targetState.ordinal > mStartState.ordinal
- ? LAUNCHER_UNKNOWN_SWIPEUP
- : LAUNCHER_UNKNOWN_SWIPEDOWN));
+ targetState.ordinal > mStartState.ordinal
+ ? LAUNCHER_UNKNOWN_SWIPEUP
+ : LAUNCHER_UNKNOWN_SWIPEDOWN));
mLauncher.getStateManager().goToState(targetState, false, forEndCallback(this::clearState));
}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/PortraitStatesTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/PortraitStatesTouchController.java
index e56c90c20c..3c83d25b71 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/PortraitStatesTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/PortraitStatesTouchController.java
@@ -21,21 +21,12 @@ import static com.android.launcher3.AbstractFloatingView.getTopOpenViewWithType;
import static com.android.launcher3.LauncherState.ALL_APPS;
import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.launcher3.LauncherState.OVERVIEW;
-import static com.android.launcher3.anim.Interpolators.FINAL_FRAME;
-import static com.android.launcher3.anim.Interpolators.INSTANT;
-import static com.android.launcher3.anim.Interpolators.LINEAR;
+import static com.android.launcher3.anim.Interpolators.ACCEL;
+import static com.android.launcher3.anim.Interpolators.DEACCEL;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_ALL_APPS_FADE;
-import static com.android.launcher3.states.StateAnimationConfig.ANIM_DEPTH;
-import static com.android.launcher3.states.StateAnimationConfig.ANIM_HOTSEAT_FADE;
-import static com.android.launcher3.states.StateAnimationConfig.ANIM_HOTSEAT_SCALE;
-import static com.android.launcher3.states.StateAnimationConfig.ANIM_HOTSEAT_TRANSLATE;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_SCRIM_FADE;
-import static com.android.launcher3.states.StateAnimationConfig.ANIM_VERTICAL_PROGRESS;
-import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_FADE;
-import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_SCALE;
import android.view.MotionEvent;
-import android.view.animation.Interpolator;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Launcher;
@@ -61,49 +52,22 @@ public class PortraitStatesTouchController extends AbstractStateChangeTouchContr
/**
* The progress at which all apps content will be fully visible.
*/
- public static final float ALL_APPS_CONTENT_FADE_MAX_CLAMPING_THRESHOLD = 0.8f;
+ protected static final float ALL_APPS_CONTENT_FADE_MAX_CLAMPING_THRESHOLD = 0.8f;
/**
* Minimum clamping progress for fading in all apps content
*/
- public static final float ALL_APPS_CONTENT_FADE_MIN_CLAMPING_THRESHOLD = 0.5f;
+ protected static final float ALL_APPS_CONTENT_FADE_MIN_CLAMPING_THRESHOLD = 0.5f;
/**
* Minimum clamping progress for fading in all apps scrim
*/
- public static final float ALL_APPS_SCRIM_VISIBLE_THRESHOLD = .1f;
+ protected static final float ALL_APPS_SCRIM_VISIBLE_THRESHOLD = .1f;
/**
* Maximum clamping progress for opaque all apps scrim
*/
- public static final float ALL_APPS_SCRIM_OPAQUE_THRESHOLD = .5f;
-
- // Custom timing for NORMAL -> ALL_APPS on phones only.
- private static final float ALL_APPS_STATE_TRANSITION = 0.4f;
- private static final float ALL_APPS_FULL_DEPTH_PROGRESS = 0.5f;
-
- // Custom interpolators for NORMAL -> ALL_APPS on phones only.
- private static final Interpolator LINEAR_EARLY =
- Interpolators.clampToProgress(LINEAR, 0f, ALL_APPS_STATE_TRANSITION);
- private static final Interpolator STEP_TRANSITION =
- Interpolators.clampToProgress(FINAL_FRAME, 0f, ALL_APPS_STATE_TRANSITION);
- // The blur to and from All Apps is set to be complete when the interpolator is at 0.5.
- public static final Interpolator BLUR =
- Interpolators.clampToProgress(
- Interpolators.mapToProgress(LINEAR, 0f, ALL_APPS_FULL_DEPTH_PROGRESS),
- 0f, ALL_APPS_STATE_TRANSITION);
- public static final Interpolator WORKSPACE_FADE = STEP_TRANSITION;
- public static final Interpolator WORKSPACE_SCALE = LINEAR_EARLY;
- public static final Interpolator HOTSEAT_FADE = STEP_TRANSITION;
- public static final Interpolator HOTSEAT_SCALE = LINEAR_EARLY;
- public static final Interpolator HOTSEAT_TRANSLATE = STEP_TRANSITION;
- public static final Interpolator SCRIM_FADE = LINEAR_EARLY;
- public static final Interpolator ALL_APPS_FADE =
- Interpolators.clampToProgress(LINEAR, ALL_APPS_STATE_TRANSITION, 1f);
- public static final Interpolator ALL_APPS_VERTICAL_PROGRESS =
- Interpolators.clampToProgress(
- Interpolators.mapToProgress(LINEAR, ALL_APPS_STATE_TRANSITION, 1f),
- ALL_APPS_STATE_TRANSITION, 1f);
+ protected static final float ALL_APPS_SCRIM_OPAQUE_THRESHOLD = .5f;
private final PortraitOverviewStateTouchHelper mOverviewPortraitStateTouchHelper;
@@ -162,51 +126,23 @@ public class PortraitStatesTouchController extends AbstractStateChangeTouchContr
private StateAnimationConfig getNormalToAllAppsAnimation() {
StateAnimationConfig builder = new StateAnimationConfig();
- if (mLauncher.getDeviceProfile().isTablet) {
- builder.setInterpolator(ANIM_ALL_APPS_FADE, INSTANT);
- builder.setInterpolator(ANIM_SCRIM_FADE,
- Interpolators.clampToProgress(LINEAR,
- ALL_APPS_SCRIM_VISIBLE_THRESHOLD,
- ALL_APPS_SCRIM_OPAQUE_THRESHOLD));
- } else {
- // TODO(b/231682175): centralize this setup in AllAppsSwipeController.
- builder.setInterpolator(ANIM_DEPTH, BLUR);
- builder.setInterpolator(ANIM_WORKSPACE_FADE, WORKSPACE_FADE);
- builder.setInterpolator(ANIM_WORKSPACE_SCALE, WORKSPACE_SCALE);
- builder.setInterpolator(ANIM_HOTSEAT_FADE, HOTSEAT_FADE);
- builder.setInterpolator(ANIM_HOTSEAT_SCALE, HOTSEAT_SCALE);
- builder.setInterpolator(ANIM_HOTSEAT_TRANSLATE, HOTSEAT_TRANSLATE);
- builder.setInterpolator(ANIM_SCRIM_FADE, SCRIM_FADE);
- builder.setInterpolator(ANIM_ALL_APPS_FADE, ALL_APPS_FADE);
- builder.setInterpolator(ANIM_VERTICAL_PROGRESS, ALL_APPS_VERTICAL_PROGRESS);
- }
+ builder.setInterpolator(ANIM_ALL_APPS_FADE, Interpolators.clampToProgress(ACCEL,
+ ALL_APPS_CONTENT_FADE_MIN_CLAMPING_THRESHOLD,
+ ALL_APPS_CONTENT_FADE_MAX_CLAMPING_THRESHOLD));
+ builder.setInterpolator(ANIM_SCRIM_FADE, Interpolators.clampToProgress(ACCEL,
+ ALL_APPS_SCRIM_VISIBLE_THRESHOLD,
+ ALL_APPS_SCRIM_OPAQUE_THRESHOLD));
return builder;
}
private StateAnimationConfig getAllAppsToNormalAnimation() {
StateAnimationConfig builder = new StateAnimationConfig();
- if (mLauncher.getDeviceProfile().isTablet) {
- builder.setInterpolator(ANIM_ALL_APPS_FADE, FINAL_FRAME);
- builder.setInterpolator(ANIM_SCRIM_FADE,
- Interpolators.clampToProgress(LINEAR,
- 1 - ALL_APPS_SCRIM_OPAQUE_THRESHOLD,
- 1 - ALL_APPS_SCRIM_VISIBLE_THRESHOLD));
- } else {
- // These interpolators are the reverse of the ones used above, so swiping out of All
- // Apps feels the same as swiping into it.
- // TODO(b/231682175): centralize this setup in AllAppsSwipeController.
- builder.setInterpolator(ANIM_DEPTH, Interpolators.reverse(BLUR));
- builder.setInterpolator(ANIM_WORKSPACE_FADE, Interpolators.reverse(WORKSPACE_FADE));
- builder.setInterpolator(ANIM_WORKSPACE_SCALE, Interpolators.reverse(WORKSPACE_SCALE));
- builder.setInterpolator(ANIM_HOTSEAT_FADE, Interpolators.reverse(HOTSEAT_FADE));
- builder.setInterpolator(ANIM_HOTSEAT_SCALE, Interpolators.reverse(HOTSEAT_SCALE));
- builder.setInterpolator(ANIM_HOTSEAT_TRANSLATE,
- Interpolators.reverse(HOTSEAT_TRANSLATE));
- builder.setInterpolator(ANIM_SCRIM_FADE, Interpolators.reverse(SCRIM_FADE));
- builder.setInterpolator(ANIM_ALL_APPS_FADE, Interpolators.reverse(ALL_APPS_FADE));
- builder.setInterpolator(ANIM_VERTICAL_PROGRESS,
- Interpolators.reverse(ALL_APPS_VERTICAL_PROGRESS));
- }
+ builder.setInterpolator(ANIM_ALL_APPS_FADE, Interpolators.clampToProgress(DEACCEL,
+ 1 - ALL_APPS_CONTENT_FADE_MAX_CLAMPING_THRESHOLD,
+ 1 - ALL_APPS_CONTENT_FADE_MIN_CLAMPING_THRESHOLD));
+ builder.setInterpolator(ANIM_SCRIM_FADE, Interpolators.clampToProgress(DEACCEL,
+ 1 - ALL_APPS_SCRIM_OPAQUE_THRESHOLD,
+ 1 - ALL_APPS_SCRIM_VISIBLE_THRESHOLD));
return builder;
}
@@ -285,9 +221,13 @@ public class PortraitStatesTouchController extends AbstractStateChangeTouchContr
* @return true if the event is over the hotseat
*/
static boolean isTouchOverHotseat(Launcher launcher, MotionEvent ev) {
+ return (ev.getY() >= getHotseatTop(launcher));
+ }
+
+ public static int getHotseatTop(Launcher launcher) {
DeviceProfile dp = launcher.getDeviceProfile();
int hotseatHeight = dp.hotseatBarSizePx + dp.getInsets().bottom;
- return (ev.getY() >= (launcher.getDragLayer().getHeight() - hotseatHeight));
+ return launcher.getDragLayer().getHeight() - hotseatHeight;
}
@Override
@@ -318,7 +258,7 @@ public class PortraitStatesTouchController extends AbstractStateChangeTouchContr
@Override
protected void onReachedFinalState(LauncherState toState) {
- super.onReachedFinalState(toState);
+ super.onReinitToState(toState);
if (toState == ALL_APPS) {
InteractionJankMonitorWrapper.end(InteractionJankMonitorWrapper.CUJ_OPEN_ALL_APPS);
}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/QuickSwitchTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/QuickSwitchTouchController.java
index d1b0a9c4ba..f0ef9cc2d7 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/QuickSwitchTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/QuickSwitchTouchController.java
@@ -29,7 +29,6 @@ import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_TR
import static com.android.launcher3.states.StateAnimationConfig.ANIM_VERTICAL_PROGRESS;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_FADE;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_TRANSLATE;
-import static com.android.launcher3.testing.TestProtocol.BAD_STATE;
import static com.android.launcher3.util.SystemUiController.UI_STATE_FULLSCREEN_TASK;
import static com.android.quickstep.views.RecentsView.ADJACENT_PAGE_HORIZONTAL_OFFSET;
import static com.android.quickstep.views.RecentsView.RECENTS_SCALE_PROPERTY;
@@ -37,7 +36,6 @@ import static com.android.quickstep.views.RecentsView.UPDATE_SYSUI_FLAGS_THRESHO
import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_RECENTS;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_OVERVIEW_DISABLED;
-import android.util.Log;
import android.view.MotionEvent;
import com.android.launcher3.Launcher;
@@ -46,8 +44,8 @@ import com.android.launcher3.Utilities;
import com.android.launcher3.states.StateAnimationConfig;
import com.android.launcher3.touch.AbstractStateChangeTouchController;
import com.android.launcher3.touch.SingleAxisSwipeDetector;
-import com.android.launcher3.util.DisplayController;
-import com.android.launcher3.util.DisplayController.NavigationMode;
+import com.android.quickstep.SysUINavigationMode;
+import com.android.quickstep.SysUINavigationMode.Mode;
import com.android.quickstep.SystemUiProxy;
import com.android.quickstep.TaskUtils;
import com.android.quickstep.views.RecentsView;
@@ -114,7 +112,6 @@ public class QuickSwitchTouchController extends AbstractStateChangeTouchControll
RECENTS_SCALE_PROPERTY.set(mOverviewPanel,
QUICK_SWITCH.getOverviewScaleAndOffset(mLauncher)[0] * 0.85f);
ADJACENT_PAGE_HORIZONTAL_OFFSET.set(mOverviewPanel, 1f);
- Log.d(BAD_STATE, "QuickSwitchTouchController initCurrentAnimation setContentAlpha=1");
mOverviewPanel.setContentAlpha(1);
mCurrentAnimation = mLauncher.getStateManager()
@@ -128,7 +125,7 @@ public class QuickSwitchTouchController extends AbstractStateChangeTouchControll
private void setupInterpolators(StateAnimationConfig stateAnimationConfig) {
stateAnimationConfig.setInterpolator(ANIM_WORKSPACE_FADE, DEACCEL_2);
stateAnimationConfig.setInterpolator(ANIM_ALL_APPS_FADE, DEACCEL_2);
- if (DisplayController.getNavigationMode(mLauncher) == NavigationMode.NO_BUTTON) {
+ if (SysUINavigationMode.getMode(mLauncher) == Mode.NO_BUTTON) {
// Overview lives to the left of workspace, so translate down later than over
stateAnimationConfig.setInterpolator(ANIM_WORKSPACE_TRANSLATE, ACCEL_2);
stateAnimationConfig.setInterpolator(ANIM_VERTICAL_PROGRESS, ACCEL_2);
diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/TaskViewTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/TaskViewTouchController.java
index ca7f633bbc..180af0bd9f 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/TaskViewTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/TaskViewTouchController.java
@@ -22,7 +22,6 @@ import static com.android.launcher3.touch.SingleAxisSwipeDetector.DIRECTION_BOTH
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.os.SystemClock;
-import android.os.VibrationEffect;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.Interpolator;
@@ -35,14 +34,14 @@ import com.android.launcher3.Utilities;
import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.anim.Interpolators;
import com.android.launcher3.anim.PendingAnimation;
+import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.touch.BaseSwipeDetector;
import com.android.launcher3.touch.PagedOrientationHandler;
import com.android.launcher3.touch.SingleAxisSwipeDetector;
-import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.FlingBlockCheck;
import com.android.launcher3.util.TouchController;
import com.android.launcher3.views.BaseDragLayer;
-import com.android.quickstep.util.VibratorWrapper;
+import com.android.quickstep.SysUINavigationMode;
import com.android.quickstep.views.RecentsView;
import com.android.quickstep.views.TaskView;
@@ -57,12 +56,6 @@ public abstract class TaskViewTouchController<T extends BaseDraggingActivity>
private static final long MIN_TASK_DISMISS_ANIMATION_DURATION = 300;
private static final long MAX_TASK_DISMISS_ANIMATION_DURATION = 600;
- public static final int TASK_DISMISS_VIBRATION_PRIMITIVE =
- Utilities.ATLEAST_R ? VibrationEffect.Composition.PRIMITIVE_TICK : -1;
- public static final float TASK_DISMISS_VIBRATION_PRIMITIVE_SCALE = 1f;
- public static final VibrationEffect TASK_DISMISS_VIBRATION_FALLBACK =
- VibratorWrapper.EFFECT_TEXTURE_TICK;
-
protected final T mActivity;
private final SingleAxisSwipeDetector mDetector;
private final RecentsView mRecentsView;
@@ -84,8 +77,6 @@ public abstract class TaskViewTouchController<T extends BaseDraggingActivity>
private TaskView mTaskBeingDragged;
- private boolean mIsDismissHapticRunning = false;
-
public TaskViewTouchController(T activity) {
mActivity = activity;
mRecentsView = activity.getOverviewPanel();
@@ -167,21 +158,26 @@ public abstract class TaskViewTouchController<T extends BaseDraggingActivity>
mTaskBeingDragged = view;
int upDirection = mRecentsView.getPagedOrientationHandler()
.getUpDirection(mIsRtl);
-
- // The task can be dragged up to dismiss it
- mAllowGoingUp = true;
-
- // The task can be dragged down to open it if:
- // - It's the current page
- // - We support gestures to enter overview
- // - It's the focused task if in grid view
- // - The task is snapped
- mAllowGoingDown = i == mRecentsView.getCurrentPage()
- && DisplayController.getNavigationMode(mActivity).hasGestures
- && (!mRecentsView.showAsGrid() || mTaskBeingDragged.isFocusedTask())
- && mRecentsView.isTaskInExpectedScrollPosition(i);
-
- directionsToDetectScroll = mAllowGoingDown ? DIRECTION_BOTH : upDirection;
+ if (!SysUINavigationMode.getMode(mActivity).hasGestures || (
+ mActivity.getDeviceProfile().isTablet
+ && FeatureFlags.ENABLE_OVERVIEW_GRID.get())) {
+ // Don't allow swipe down to open if we don't support swipe up
+ // to enter overview, or when grid layout is enabled.
+ directionsToDetectScroll = upDirection;
+ mAllowGoingUp = true;
+ mAllowGoingDown = false;
+ } else {
+ // The task can be dragged up to dismiss it,
+ // and down to open if it's the current page.
+ mAllowGoingUp = true;
+ if (i == mRecentsView.getCurrentPage()) {
+ mAllowGoingDown = true;
+ directionsToDetectScroll = DIRECTION_BOTH;
+ } else {
+ mAllowGoingDown = false;
+ directionsToDetectScroll = upDirection;
+ }
+ }
break;
}
}
@@ -237,8 +233,7 @@ public abstract class TaskViewTouchController<T extends BaseDraggingActivity>
if (goingUp) {
currentInterpolator = Interpolators.LINEAR;
pa = mRecentsView.createTaskDismissAnimation(mTaskBeingDragged,
- true /* animateTaskView */, true /* removeTask */, maxDuration,
- false /* dismissingForSplitSelection*/);
+ true /* animateTaskView */, true /* removeTask */, maxDuration);
mEndDisplacement = -secondaryTaskDimension;
} else {
@@ -344,10 +339,10 @@ public abstract class TaskViewTouchController<T extends BaseDraggingActivity>
fling = false;
}
PagedOrientationHandler orientationHandler = mRecentsView.getPagedOrientationHandler();
- boolean goingUp = orientationHandler.isGoingUp(velocity, mIsRtl);
float progress = mCurrentAnimation.getProgressFraction();
float interpolatedProgress = mCurrentAnimation.getInterpolatedProgress();
if (fling) {
+ boolean goingUp = orientationHandler.isGoingUp(velocity, mIsRtl);
goingToEnd = goingUp == mCurrentAnimationIsGoingUp;
} else {
goingToEnd = interpolatedProgress > SUCCESS_TRANSITION_PROGRESS;
@@ -367,11 +362,6 @@ public abstract class TaskViewTouchController<T extends BaseDraggingActivity>
mCurrentAnimation.startWithVelocity(mActivity, goingToEnd,
velocity * orientationHandler.getSecondaryTranslationDirectionFactor(),
mEndDisplacement, animationDuration);
- if (goingUp && goingToEnd && !mIsDismissHapticRunning) {
- VibratorWrapper.INSTANCE.get(mActivity).vibrate(TASK_DISMISS_VIBRATION_PRIMITIVE,
- TASK_DISMISS_VIBRATION_PRIMITIVE_SCALE, TASK_DISMISS_VIBRATION_FALLBACK);
- mIsDismissHapticRunning = true;
- }
}
private void clearState() {
@@ -379,6 +369,5 @@ public abstract class TaskViewTouchController<T extends BaseDraggingActivity>
mDetector.setDetectableScrollConditions(0, false);
mTaskBeingDragged = null;
mCurrentAnimation = null;
- mIsDismissHapticRunning = false;
}
}
diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
index d676f7d195..97481233be 100644
--- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
+++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
@@ -22,7 +22,6 @@ import static android.widget.Toast.LENGTH_SHORT;
import static com.android.launcher3.BaseActivity.INVISIBLE_BY_STATE_HANDLER;
import static com.android.launcher3.BaseActivity.STATE_HANDLER_INVISIBILITY_FLAGS;
-import static com.android.launcher3.PagedView.INVALID_PAGE;
import static com.android.launcher3.anim.Interpolators.ACCEL_DEACCEL;
import static com.android.launcher3.anim.Interpolators.DEACCEL;
import static com.android.launcher3.anim.Interpolators.OVERSHOOT_1_2;
@@ -33,10 +32,11 @@ import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCH
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_OVERVIEW_GESTURE;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_QUICKSWITCH_LEFT;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_QUICKSWITCH_RIGHT;
+import static com.android.launcher3.util.DisplayController.getSingleFrameMs;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
import static com.android.launcher3.util.SystemUiController.UI_STATE_FULLSCREEN_TASK;
-import static com.android.launcher3.util.window.RefreshRateTracker.getSingleFrameMs;
+import static com.android.launcher3.util.VibratorWrapper.OVERVIEW_HAPTIC;
import static com.android.quickstep.GestureState.GestureEndTarget.HOME;
import static com.android.quickstep.GestureState.GestureEndTarget.LAST_TASK;
import static com.android.quickstep.GestureState.GestureEndTarget.NEW_TASK;
@@ -46,7 +46,6 @@ import static com.android.quickstep.GestureState.STATE_END_TARGET_SET;
import static com.android.quickstep.GestureState.STATE_RECENTS_ANIMATION_CANCELED;
import static com.android.quickstep.GestureState.STATE_RECENTS_SCROLLING_FINISHED;
import static com.android.quickstep.MultiStateCallback.DEBUG_STATES;
-import static com.android.quickstep.util.VibratorWrapper.OVERVIEW_HAPTIC;
import static com.android.quickstep.views.RecentsView.UPDATE_SYSUI_FLAGS_THRESHOLD;
import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_RECENTS;
import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.ACTIVITY_TYPE_HOME;
@@ -56,7 +55,6 @@ import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ValueAnimator;
import android.annotation.TargetApi;
-import android.app.Activity;
import android.app.ActivityManager;
import android.content.Context;
import android.content.Intent;
@@ -67,7 +65,6 @@ import android.graphics.RectF;
import android.os.Build;
import android.os.IBinder;
import android.os.SystemClock;
-import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnApplyWindowInsetsListener;
@@ -76,7 +73,6 @@ import android.view.ViewTreeObserver.OnScrollChangedListener;
import android.view.WindowInsets;
import android.view.animation.Interpolator;
import android.widget.Toast;
-import android.window.PictureInPictureSurfaceTransaction;
import androidx.annotation.Nullable;
import androidx.annotation.UiThread;
@@ -93,12 +89,11 @@ import com.android.launcher3.statemanager.BaseState;
import com.android.launcher3.statemanager.StatefulActivity;
import com.android.launcher3.tracing.InputConsumerProto;
import com.android.launcher3.tracing.SwipeHandlerProto;
-import com.android.launcher3.util.ActivityLifecycleCallbacksAdapter;
import com.android.launcher3.util.TraceHelper;
+import com.android.launcher3.util.VibratorWrapper;
import com.android.launcher3.util.WindowBounds;
import com.android.quickstep.BaseActivityInterface.AnimationFactory;
import com.android.quickstep.GestureState.GestureEndTarget;
-import com.android.quickstep.RemoteTargetGluer.RemoteTargetHandle;
import com.android.quickstep.util.ActiveGestureLog;
import com.android.quickstep.util.ActivityInitListener;
import com.android.quickstep.util.AnimatorControllerWithResistance;
@@ -111,11 +106,9 @@ import com.android.quickstep.util.RectFSpringAnim;
import com.android.quickstep.util.StaggeredWorkspaceAnim;
import com.android.quickstep.util.SurfaceTransactionApplier;
import com.android.quickstep.util.SwipePipToHomeAnimator;
-import com.android.quickstep.util.TaskViewSimulator;
-import com.android.quickstep.util.VibratorWrapper;
+import com.android.quickstep.util.TransformParams;
import com.android.quickstep.views.RecentsView;
import com.android.quickstep.views.TaskView;
-import com.android.systemui.shared.recents.model.Task;
import com.android.systemui.shared.recents.model.ThumbnailData;
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.InputConsumerController;
@@ -126,8 +119,6 @@ import com.android.systemui.shared.system.TaskStackChangeListener;
import com.android.systemui.shared.system.TaskStackChangeListeners;
import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
import java.util.function.Consumer;
/**
@@ -151,7 +142,6 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
// Null if the recents animation hasn't started yet or has been canceled or finished.
protected @Nullable RecentsAnimationController mRecentsAnimationController;
- protected @Nullable RecentsAnimationController mDeferredCleanupRecentsAnimationController;
protected RecentsAnimationTargets mRecentsAnimationTargets;
protected T mActivity;
protected Q mRecentsView;
@@ -159,21 +149,6 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
protected MultiStateCallback mStateCallback;
protected boolean mCanceled;
private boolean mRecentsViewScrollLinked = false;
- private final ActivityLifecycleCallbacksAdapter mLifecycleCallbacks =
- new ActivityLifecycleCallbacksAdapter() {
- @Override
- public void onActivityDestroyed(Activity activity) {
- if (mActivity != activity) {
- return;
- }
- if (mTaskAnimationManager != null) {
- mTaskAnimationManager.finishRunningRecentsAnimation(true);
- }
- mRecentsView = null;
- mActivity.unregisterActivityLifecycleCallbacks(mLifecycleCallbacks);
- mActivity = null;
- }
- };
private static int getFlagForIndex(int index, String name) {
if (DEBUG_STATES) {
@@ -187,51 +162,45 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
getFlagForIndex(0, "STATE_LAUNCHER_PRESENT");
protected static final int STATE_LAUNCHER_STARTED =
getFlagForIndex(1, "STATE_LAUNCHER_STARTED");
- protected static final int STATE_LAUNCHER_DRAWN =
- getFlagForIndex(2, "STATE_LAUNCHER_DRAWN");
- // Called when the Launcher has connected to the touch interaction service (and the taskbar
- // ui controller is initialized)
- protected static final int STATE_LAUNCHER_BIND_TO_SERVICE =
- getFlagForIndex(3, "STATE_LAUNCHER_BIND_TO_SERVICE");
+ protected static final int STATE_LAUNCHER_DRAWN = getFlagForIndex(2, "STATE_LAUNCHER_DRAWN");
// Internal initialization states
private static final int STATE_APP_CONTROLLER_RECEIVED =
- getFlagForIndex(4, "STATE_APP_CONTROLLER_RECEIVED");
+ getFlagForIndex(3, "STATE_APP_CONTROLLER_RECEIVED");
// Interaction finish states
private static final int STATE_SCALED_CONTROLLER_HOME =
- getFlagForIndex(5, "STATE_SCALED_CONTROLLER_HOME");
+ getFlagForIndex(4, "STATE_SCALED_CONTROLLER_HOME");
private static final int STATE_SCALED_CONTROLLER_RECENTS =
- getFlagForIndex(6, "STATE_SCALED_CONTROLLER_RECENTS");
+ getFlagForIndex(5, "STATE_SCALED_CONTROLLER_RECENTS");
protected static final int STATE_HANDLER_INVALIDATED =
- getFlagForIndex(7, "STATE_HANDLER_INVALIDATED");
+ getFlagForIndex(6, "STATE_HANDLER_INVALIDATED");
private static final int STATE_GESTURE_STARTED =
- getFlagForIndex(8, "STATE_GESTURE_STARTED");
+ getFlagForIndex(7, "STATE_GESTURE_STARTED");
private static final int STATE_GESTURE_CANCELLED =
- getFlagForIndex(9, "STATE_GESTURE_CANCELLED");
+ getFlagForIndex(8, "STATE_GESTURE_CANCELLED");
private static final int STATE_GESTURE_COMPLETED =
- getFlagForIndex(10, "STATE_GESTURE_COMPLETED");
+ getFlagForIndex(9, "STATE_GESTURE_COMPLETED");
private static final int STATE_CAPTURE_SCREENSHOT =
- getFlagForIndex(11, "STATE_CAPTURE_SCREENSHOT");
+ getFlagForIndex(10, "STATE_CAPTURE_SCREENSHOT");
protected static final int STATE_SCREENSHOT_CAPTURED =
- getFlagForIndex(12, "STATE_SCREENSHOT_CAPTURED");
+ getFlagForIndex(11, "STATE_SCREENSHOT_CAPTURED");
private static final int STATE_SCREENSHOT_VIEW_SHOWN =
- getFlagForIndex(13, "STATE_SCREENSHOT_VIEW_SHOWN");
+ getFlagForIndex(12, "STATE_SCREENSHOT_VIEW_SHOWN");
private static final int STATE_RESUME_LAST_TASK =
- getFlagForIndex(14, "STATE_RESUME_LAST_TASK");
+ getFlagForIndex(13, "STATE_RESUME_LAST_TASK");
private static final int STATE_START_NEW_TASK =
- getFlagForIndex(15, "STATE_START_NEW_TASK");
+ getFlagForIndex(14, "STATE_START_NEW_TASK");
private static final int STATE_CURRENT_TASK_FINISHED =
- getFlagForIndex(16, "STATE_CURRENT_TASK_FINISHED");
+ getFlagForIndex(15, "STATE_CURRENT_TASK_FINISHED");
private static final int STATE_FINISH_WITH_NO_END =
- getFlagForIndex(17, "STATE_FINISH_WITH_NO_END");
+ getFlagForIndex(16, "STATE_FINISH_WITH_NO_END");
private static final int LAUNCHER_UI_STATES =
- STATE_LAUNCHER_PRESENT | STATE_LAUNCHER_DRAWN | STATE_LAUNCHER_STARTED |
- STATE_LAUNCHER_BIND_TO_SERVICE;
+ STATE_LAUNCHER_PRESENT | STATE_LAUNCHER_DRAWN | STATE_LAUNCHER_STARTED;
public static final long MAX_SWIPE_DURATION = 350;
public static final long HOME_DURATION = StaggeredWorkspaceAnim.DURATION_MS;
@@ -243,8 +212,6 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
public static final long RECENTS_ATTACH_DURATION = 300;
- private static final float MAX_QUICK_SWITCH_RECENTS_SCALE_PROGRESS = 0.07f;
-
/**
* Used as the page index for logging when we return to the last task at the end of the gesture.
*/
@@ -253,11 +220,9 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
protected final TaskAnimationManager mTaskAnimationManager;
// Either RectFSpringAnim (if animating home) or ObjectAnimator (from mCurrentShift) otherwise
- private RunningWindowAnim[] mRunningWindowAnim;
+ private RunningWindowAnim mRunningWindowAnim;
// Possible second animation running at the same time as mRunningWindowAnim
private Animator mParallelRunningAnim;
- // Current running divider animation
- private ValueAnimator mDividerAnimator;
private boolean mIsMotionPaused;
private boolean mHasMotionEverBeenPaused;
@@ -286,33 +251,22 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
private SwipePipToHomeAnimator mSwipePipToHomeAnimator;
protected boolean mIsSwipingPipToHome;
- // TODO(b/195473090) no split PIP for now, remove once we have more clarity
- // can try to have RectFSpringAnim evaluate multiple rects at once
- private final SwipePipToHomeAnimator[] mSwipePipToHomeAnimators =
- new SwipePipToHomeAnimator[2];
-
- // Interpolate RecentsView scale from start of quick switch scroll until this scroll threshold
- private final float mQuickSwitchScaleScrollThreshold;
public AbsSwipeUpHandler(Context context, RecentsAnimationDeviceState deviceState,
TaskAnimationManager taskAnimationManager, GestureState gestureState,
long touchTimeMs, boolean continuingLastGesture,
InputConsumerController inputConsumer) {
- super(context, deviceState, gestureState);
+ super(context, deviceState, gestureState, new TransformParams());
mActivityInterface = gestureState.getActivityInterface();
mActivityInitListener = mActivityInterface.createActivityInitListener(this::onActivityInit);
mInputConsumerProxy =
- new InputConsumerProxy(context,
- () -> mRecentsView.getPagedViewOrientedState().getRecentsActivityRotation(),
- inputConsumer, () -> {
+ new InputConsumerProxy(inputConsumer, () -> {
endRunningWindowAnim(mGestureState.getEndTarget() == HOME /* cancel */);
endLauncherTransitionController();
}, new InputProxyHandlerFactory(mActivityInterface, mGestureState));
mTaskAnimationManager = taskAnimationManager;
mTouchTimeMs = touchTimeMs;
mContinuingLastGesture = continuingLastGesture;
- mQuickSwitchScaleScrollThreshold = context.getResources().getDimension(
- R.dimen.quick_switch_scaling_scroll_threshold);
initAfterSubclassConstructor();
initStateCallbacks();
@@ -430,15 +384,11 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
// Set up a entire animation lifecycle callback to notify the current recents view when
// the animation is canceled
mGestureState.runOnceAtState(STATE_RECENTS_ANIMATION_CANCELED, () -> {
- HashMap<Integer, ThumbnailData> snapshots =
- mGestureState.consumeRecentsAnimationCanceledSnapshot();
- if (snapshots != null) {
- mRecentsView.switchToScreenshot(snapshots, () -> {
+ ThumbnailData snapshot = mGestureState.consumeRecentsAnimationCanceledSnapshot();
+ if (snapshot != null) {
+ mRecentsView.switchToScreenshot(snapshot, () -> {
if (mRecentsAnimationController != null) {
mRecentsAnimationController.cleanupScreenshot();
- } else if (mDeferredCleanupRecentsAnimationController != null) {
- mDeferredCleanupRecentsAnimationController.cleanupScreenshot();
- mDeferredCleanupRecentsAnimationController = null;
}
});
mRecentsView.onRecentsAnimationComplete();
@@ -447,9 +397,7 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
setupRecentsViewUi();
linkRecentsViewScroll();
- activity.runOnBindToTouchInteractionService(this::onLauncherBindToService);
- mActivity.registerActivityLifecycleCallbacks(mLifecycleCallbacks);
return true;
}
@@ -471,8 +419,7 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
// RecentsView never updates the display rotation until swipe-up, force update
// RecentsOrientedState before passing to TaskViewSimulator.
mRecentsView.updateRecentsRotation();
- runActionOnRemoteHandles(remoteTargetHandle -> remoteTargetHandle.getTaskViewSimulator()
- .setOrientationState(mRecentsView.getPagedViewOrientedState()));
+ mTaskViewSimulator.setOrientationState(mRecentsView.getPagedViewOrientedState());
// If we've already ended the gesture and are going home, don't prepare recents UI,
// as that will set the state as BACKGROUND_APP, overriding the animation to NORMAL.
@@ -529,11 +476,6 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
mStateCallback.setState(STATE_LAUNCHER_STARTED);
}
- private void onLauncherBindToService() {
- mStateCallback.setState(STATE_LAUNCHER_BIND_TO_SERVICE);
- flushOnRecentsAnimationAndLauncherBound();
- }
-
private void onLauncherPresentAndGestureStarted() {
// Re-setup the recents UI when gesture starts, as the state could have been changed during
// that time by a previous window transition.
@@ -574,14 +516,7 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
}
protected void notifyGestureAnimationStartToRecents() {
- Task[] runningTasks;
- if (mIsSwipeForStagedSplit) {
- int[] splitTaskIds = TopTaskTracker.INSTANCE.get(mContext).getRunningSplitTaskIds();
- runningTasks = mGestureState.getRunningTask().getPlaceholderTasks(splitTaskIds);
- } else {
- runningTasks = mGestureState.getRunningTask().getPlaceholderTasks();
- }
- mRecentsView.onGestureAnimationStart(runningTasks, mDeviceState.getRotationTouchHelper());
+ mRecentsView.onGestureAnimationStart(mGestureState.getRunningTask());
}
private void launcherFrameDrawn() {
@@ -608,7 +543,7 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
@Override
public void onMotionPauseDetected() {
mHasMotionEverBeenPaused = true;
- maybeUpdateRecentsAttachedState(true/* animate */, true/* moveFocusedTask */);
+ maybeUpdateRecentsAttachedState();
performHapticFeedback();
}
@@ -619,24 +554,18 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
};
}
- private void maybeUpdateRecentsAttachedState() {
+ public void maybeUpdateRecentsAttachedState() {
maybeUpdateRecentsAttachedState(true /* animate */);
}
- private void maybeUpdateRecentsAttachedState(boolean animate) {
- maybeUpdateRecentsAttachedState(animate, false /* moveFocusedTask */);
- }
-
/**
* Determines whether to show or hide RecentsView. The window is always
* synchronized with its corresponding TaskView in RecentsView, so if
* RecentsView is shown, it will appear to be attached to the window.
*
* Note this method has no effect unless the navigation mode is NO_BUTTON.
- * @param animate whether to animate when attaching RecentsView
- * @param moveFocusedTask whether to move focused task to front when attaching
*/
- private void maybeUpdateRecentsAttachedState(boolean animate, boolean moveFocusedTask) {
+ private void maybeUpdateRecentsAttachedState(boolean animate) {
if (!mDeviceState.isFullyGesturalNavMode() || mRecentsView == null) {
return;
}
@@ -655,12 +584,6 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
} else {
recentsAttachedToAppWindow = mHasMotionEverBeenPaused || mIsLikelyToStartNewTask;
}
- if (moveFocusedTask && !mAnimationFactory.hasRecentsEverAttachedToAppWindow()
- && recentsAttachedToAppWindow) {
- // Only move focused task if RecentsView has never been attached before, to avoid
- // TaskView jumping to new position as we move the tasks.
- mRecentsView.moveFocusedTaskToFront();
- }
mAnimationFactory.setRecentsAttachedToAppWindow(recentsAttachedToAppWindow, animate);
// Reapply window transform throughout the attach animation, as the animation affects how
@@ -668,15 +591,15 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
if (animate) {
ValueAnimator reapplyWindowTransformAnim = ValueAnimator.ofFloat(0, 1);
reapplyWindowTransformAnim.addUpdateListener(anim -> {
- if (mRunningWindowAnim == null || mRunningWindowAnim.length == 0) {
- applyScrollAndTransform();
+ if (mRunningWindowAnim == null) {
+ applyWindowTransform();
}
});
reapplyWindowTransformAnim.setDuration(RECENTS_ATTACH_DURATION).start();
mStateCallback.runOnceAtState(STATE_HANDLER_INVALIDATED,
reapplyWindowTransformAnim::cancel);
} else {
- applyScrollAndTransform();
+ applyWindowTransform();
}
}
@@ -712,24 +635,13 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
public WindowInsets onApplyWindowInsets(View view, WindowInsets windowInsets) {
WindowInsets result = view.onApplyWindowInsets(windowInsets);
buildAnimationController();
- // Reapply the current shift to ensure it takes new insets into account, e.g. when long
- // pressing to stash taskbar without moving the finger.
- updateFinalShift();
return result;
}
private void onAnimatorPlaybackControllerCreated(AnimatorControllerWithResistance anim) {
- boolean isFirstCreation = mLauncherTransitionController == null;
mLauncherTransitionController = anim;
- if (isFirstCreation) {
- mStateCallback.runOnceAtState(STATE_GESTURE_STARTED, () -> {
- // Wait until the gesture is started (touch slop was passed) to start in sync with
- // mWindowTransitionController. This ensures we don't hide the taskbar background
- // when long pressing to stash it, for instance.
- mLauncherTransitionController.getNormalController().dispatchOnStart();
- updateLauncherTransitionProgress();
- });
- }
+ mLauncherTransitionController.getNormalController().dispatchOnStart();
+ updateLauncherTransitionProgress();
}
public Intent getLaunchIntent() {
@@ -751,7 +663,7 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
}
updateSysUiFlags(mCurrentShift.value);
- applyScrollAndTransform();
+ applyWindowTransform();
updateLauncherTransitionProgress();
}
@@ -761,8 +673,7 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|| !canCreateNewOrUpdateExistingLauncherTransitionController()) {
return;
}
- mLauncherTransitionController.setProgress(
- Math.max(mCurrentShift.value, getScaleProgressDueToScroll()), mDragLengthFactor);
+ mLauncherTransitionController.setProgress(mCurrentShift.value, mDragLengthFactor);
}
/**
@@ -780,7 +691,7 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
// We will handle the sysui flags based on the centermost task view.
mRecentsAnimationController.setUseLauncherSystemBarFlags(swipeUpThresholdPassed
|| (quickswitchThresholdPassed && centermostTaskFlags != 0));
- mRecentsAnimationController.setSplitScreenMinimized(mContext, swipeUpThresholdPassed);
+ mRecentsAnimationController.setSplitScreenMinimized(swipeUpThresholdPassed);
// Provide a hint to WM the direction that we will be settling in case the animation
// needs to be canceled
mRecentsAnimationController.setWillFinishToHome(swipeUpThresholdPassed);
@@ -797,25 +708,24 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
@Override
public void onRecentsAnimationStart(RecentsAnimationController controller,
RecentsAnimationTargets targets) {
- super.onRecentsAnimationStart(controller, targets);
ActiveGestureLog.INSTANCE.addLog("startRecentsAnimationCallback", targets.apps.length);
- mRemoteTargetHandles = mTargetGluer.assignTargetsForSplitScreen(mContext, targets);
mRecentsAnimationController = controller;
mRecentsAnimationTargets = targets;
+ mTransformParams.setTargetSet(mRecentsAnimationTargets);
+ RemoteAnimationTargetCompat runningTaskTarget = targets.findTask(
+ mGestureState.getRunningTaskId());
+
+ if (runningTaskTarget != null) {
+ mTaskViewSimulator.setPreview(runningTaskTarget);
+ }
// Only initialize the device profile, if it has not been initialized before, as in some
// configurations targets.homeContentInsets may not be correct.
if (mActivity == null) {
- RemoteAnimationTargetCompat primaryTaskTarget = targets.apps[0];
- // orientation state is independent of which remote target handle we use since both
- // should be pointing to the same one. Just choose index 0 for now since that works for
- // both split and non-split
- RecentsOrientedState orientationState = mRemoteTargetHandles[0].getTaskViewSimulator()
- .getOrientationState();
- DeviceProfile dp = orientationState.getLauncherDeviceProfile();
- if (targets.minimizedHomeBounds != null && primaryTaskTarget != null) {
+ DeviceProfile dp = mTaskViewSimulator.getOrientationState().getLauncherDeviceProfile();
+ if (targets.minimizedHomeBounds != null && runningTaskTarget != null) {
Rect overviewStackBounds = mActivityInterface
- .getOverviewWindowBounds(targets.minimizedHomeBounds, primaryTaskTarget);
+ .getOverviewWindowBounds(targets.minimizedHomeBounds, runningTaskTarget);
dp = dp.getMultiWindowProfile(mContext,
new WindowBounds(overviewStackBounds, targets.homeContentInsets));
} else {
@@ -825,33 +735,31 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
dp.updateInsets(targets.homeContentInsets);
dp.updateIsSeascape(mContext);
initTransitionEndpoints(dp);
- orientationState.setMultiWindowMode(dp.isMultiWindowMode);
+ mTaskViewSimulator.getOrientationState().setMultiWindowMode(dp.isMultiWindowMode);
}
// Notify when the animation starts
- flushOnRecentsAnimationAndLauncherBound();
+ if (!mRecentsAnimationStartCallbacks.isEmpty()) {
+ for (Runnable action : new ArrayList<>(mRecentsAnimationStartCallbacks)) {
+ action.run();
+ }
+ mRecentsAnimationStartCallbacks.clear();
+ }
// Only add the callback to enable the input consumer after we actually have the controller
mStateCallback.runOnceAtState(STATE_APP_CONTROLLER_RECEIVED | STATE_GESTURE_STARTED,
- this::startInterceptingTouchesForGesture);
+ mRecentsAnimationController::enableInputConsumer);
mStateCallback.setStateOnUiThread(STATE_APP_CONTROLLER_RECEIVED);
mPassedOverviewThreshold = false;
}
@Override
- public void onRecentsAnimationCanceled(HashMap<Integer, ThumbnailData> thumbnailDatas) {
+ public void onRecentsAnimationCanceled(ThumbnailData thumbnailData) {
ActiveGestureLog.INSTANCE.addLog("cancelRecentsAnimation");
mActivityInitListener.unregister();
- // Cache the recents animation controller so we can defer its cleanup to after having
- // properly cleaned up the screenshot without accidentally using it.
- mDeferredCleanupRecentsAnimationController = mRecentsAnimationController;
mStateCallback.setStateOnUiThread(STATE_GESTURE_CANCELLED | STATE_HANDLER_INVALIDATED);
- if (mRecentsAnimationTargets != null) {
- setDividerShown(true /* shown */, false /* immediate */);
- }
-
// Defer clearing the controller and the targets until after we've updated the state
mRecentsAnimationController = null;
mRecentsAnimationTargets = null;
@@ -935,29 +843,15 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
mLogDirectionUpOrLeft = velocity.x < 0;
}
mDownPos = downPos;
- Runnable handleNormalGestureEndCallback = () ->
- handleNormalGestureEnd(endVelocity, isFling, velocity, /* isCancel= */ false);
- if (mRecentsView != null) {
- mRecentsView.runOnPageScrollsInitialized(handleNormalGestureEndCallback);
- } else {
- handleNormalGestureEndCallback.run();
- }
+ handleNormalGestureEnd(endVelocity, isFling, velocity, false /* isCancel */);
}
private void endRunningWindowAnim(boolean cancel) {
if (mRunningWindowAnim != null) {
if (cancel) {
- for (RunningWindowAnim r : mRunningWindowAnim) {
- if (r != null) {
- r.cancel();
- }
- }
+ mRunningWindowAnim.cancel();
} else {
- for (RunningWindowAnim r : mRunningWindowAnim) {
- if (r != null) {
- r.end();
- }
- }
+ mRunningWindowAnim.end();
}
}
if (mParallelRunningAnim != null) {
@@ -971,9 +865,6 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
// Fast-finish the attaching animation if it's still running.
maybeUpdateRecentsAttachedState(false);
final GestureEndTarget endTarget = mGestureState.getEndTarget();
- // Wait until the given View (if supplied) draws before resuming the last task.
- View postResumeLastTask = mActivityInterface.onSettledOnEndTarget(endTarget);
-
if (endTarget != NEW_TASK) {
InteractionJankMonitorWrapper.cancel(
InteractionJankMonitorWrapper.CUJ_QUICK_SWITCH);
@@ -982,7 +873,6 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
InteractionJankMonitorWrapper.cancel(
InteractionJankMonitorWrapper.CUJ_APP_CLOSE_TO_HOME);
}
-
switch (endTarget) {
case HOME:
mStateCallback.setState(STATE_SCALED_CONTROLLER_HOME | STATE_CAPTURE_SCREENSHOT);
@@ -997,36 +887,27 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
mStateCallback.setState(STATE_START_NEW_TASK | STATE_CAPTURE_SCREENSHOT);
break;
case LAST_TASK:
- if (postResumeLastTask != null) {
- ViewUtils.postFrameDrawn(postResumeLastTask,
- () -> mStateCallback.setState(STATE_RESUME_LAST_TASK));
- } else {
- mStateCallback.setState(STATE_RESUME_LAST_TASK);
- }
- if (mRecentsAnimationTargets != null) {
- setDividerShown(true /* shown */, true /* immediate */);
- }
+ mStateCallback.setState(STATE_RESUME_LAST_TASK);
break;
}
ActiveGestureLog.INSTANCE.addLog("onSettledOnEndTarget " + endTarget);
}
/** @return Whether this was the task we were waiting to appear, and thus handled it. */
- protected boolean handleTaskAppeared(RemoteAnimationTargetCompat[] appearedTaskTarget) {
+ protected boolean handleTaskAppeared(RemoteAnimationTargetCompat appearedTaskTarget) {
if (mStateCallback.hasStates(STATE_HANDLER_INVALIDATED)) {
return false;
}
- boolean hasStartedTaskBefore = Arrays.stream(appearedTaskTarget).anyMatch(
- targetCompat -> targetCompat.taskId == mGestureState.getLastStartedTaskId());
- if (mStateCallback.hasStates(STATE_START_NEW_TASK) && hasStartedTaskBefore) {
+ if (mStateCallback.hasStates(STATE_START_NEW_TASK)
+ && appearedTaskTarget.taskId == mGestureState.getLastStartedTaskId()) {
reset();
return true;
}
return false;
}
- private GestureEndTarget calculateEndTarget(PointF velocity, float endVelocity,
- boolean isFlingY, boolean isCancel) {
+ private GestureEndTarget calculateEndTarget(PointF velocity, float endVelocity, boolean isFling,
+ boolean isCancel) {
if (mGestureState.isHandlingAtomicEvent()) {
// Button mode, this is only used to go to recents
return RECENTS;
@@ -1047,17 +928,11 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
goingToNewTask = false;
}
final boolean reachedOverviewThreshold = mCurrentShift.value >= MIN_PROGRESS_FOR_OVERVIEW;
- final boolean isFlingX = Math.abs(velocity.x) > mContext.getResources()
- .getDimension(R.dimen.quickstep_fling_threshold_speed);
- if (!isFlingY) {
+ if (!isFling) {
if (isCancel) {
endTarget = LAST_TASK;
} else if (mDeviceState.isFullyGesturalNavMode()) {
- if (goingToNewTask && isFlingX) {
- // Flinging towards new task takes precedence over mIsMotionPaused (which only
- // checks y-velocity).
- endTarget = NEW_TASK;
- } else if (mIsMotionPaused) {
+ if (mIsMotionPaused) {
endTarget = RECENTS;
} else if (goingToNewTask) {
endTarget = NEW_TASK;
@@ -1149,14 +1024,10 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
} else if (endTarget == RECENTS) {
if (mRecentsView != null) {
int nearestPage = mRecentsView.getDestinationPage();
- if (nearestPage == INVALID_PAGE) {
- // Allow the snap to invalid page to catch future error cases.
- Log.e(TAG,
- "RecentsView destination page is invalid",
- new IllegalStateException());
- }
-
boolean isScrolling = false;
+ // Update page scroll before snapping to page to make sure we snapped to the
+ // position calculated with target gesture in mind.
+ mRecentsView.updateScrollSynchronously();
if (mRecentsView.getNextPage() != nearestPage) {
// We shouldn't really scroll to the next page when swiping up to recents.
// Only allow settling on the next page if it's nearest to the center.
@@ -1186,11 +1057,6 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
}
private void doLogGesture(GestureEndTarget endTarget, @Nullable TaskView targetTask) {
- if (mDp == null || !mDp.isGestureMode || mDownPos == null) {
- // We probably never received an animation controller, skip logging.
- return;
- }
-
StatsLogManager.EventEnum event;
switch (endTarget) {
case HOME:
@@ -1214,10 +1080,15 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
logger.withItemInfo(targetTask.getItemInfo());
}
- int pageIndex = endTarget == LAST_TASK || mRecentsView == null
+ DeviceProfile dp = mDp;
+ if (dp == null || mDownPos == null) {
+ // We probably never received an animation controller, skip logging.
+ return;
+ }
+ int pageIndex = endTarget == LAST_TASK
? LOG_NO_OP_PAGE_INDEX
: mRecentsView.getNextPage();
- logger.withRank(pageIndex);
+ // TODO: set correct container using the pageIndex
logger.log(event);
}
@@ -1225,7 +1096,7 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
@UiThread
private void animateToProgress(float start, float end, long duration, Interpolator interpolator,
GestureEndTarget target, PointF velocityPxPerMs) {
- runOnRecentsAnimationAndLauncherBound(() -> animateToProgressInternal(start, end, duration,
+ runOnRecentsAnimationStart(() -> animateToProgressInternal(start, end, duration,
interpolator, target, velocityPxPerMs));
}
@@ -1262,15 +1133,8 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
mActivityRestartListener);
mParallelRunningAnim = mActivityInterface.getParallelAnimationToLauncher(
- mGestureState.getEndTarget(), duration,
- mTaskAnimationManager.getCurrentCallbacks());
+ mGestureState.getEndTarget(), duration);
if (mParallelRunningAnim != null) {
- mParallelRunningAnim.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- mParallelRunningAnim = null;
- }
- });
mParallelRunningAnim.start();
}
}
@@ -1286,24 +1150,21 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
boolean isTranslucent = runningTaskTarget != null && runningTaskTarget.isTranslucent;
boolean appCanEnterPip = !mDeviceState.isPipActive()
&& runningTaskTarget != null
- && runningTaskTarget.allowEnterPip
&& runningTaskTarget.taskInfo.pictureInPictureParams != null
&& runningTaskTarget.taskInfo.pictureInPictureParams.isAutoEnterEnabled();
HomeAnimationFactory homeAnimFactory =
createHomeAnimationFactory(cookies, duration, isTranslucent, appCanEnterPip,
runningTaskTarget);
- mIsSwipingPipToHome = !mIsSwipeForStagedSplit && appCanEnterPip;
- final RectFSpringAnim[] windowAnim;
+ mIsSwipingPipToHome = homeAnimFactory.supportSwipePipToHome() && appCanEnterPip;
+ final RectFSpringAnim windowAnim;
if (mIsSwipingPipToHome) {
mSwipePipToHomeAnimator = createWindowAnimationToPip(
homeAnimFactory, runningTaskTarget, start);
- mSwipePipToHomeAnimators[0] = mSwipePipToHomeAnimator;
- windowAnim = mSwipePipToHomeAnimators;
+ windowAnim = mSwipePipToHomeAnimator;
} else {
mSwipePipToHomeAnimator = null;
windowAnim = createWindowAnimationToHome(start, homeAnimFactory);
-
- windowAnim[0].addAnimatorListener(new AnimationSuccessListener() {
+ windowAnim.addAnimatorListener(new AnimationSuccessListener() {
@Override
public void onAnimationSuccess(Animator animator) {
if (mRecentsAnimationController == null) {
@@ -1317,22 +1178,14 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
}
});
}
- mRunningWindowAnim = new RunningWindowAnim[windowAnim.length];
- for (int i = 0, windowAnimLength = windowAnim.length; i < windowAnimLength; i++) {
- RectFSpringAnim windowAnimation = windowAnim[i];
- if (windowAnimation == null) {
- continue;
- }
- windowAnimation.start(mContext, velocityPxPerMs);
- mRunningWindowAnim[i] = RunningWindowAnim.wrap(windowAnimation);
- }
+ windowAnim.start(mContext, velocityPxPerMs);
+ mRunningWindowAnim = RunningWindowAnim.wrap(windowAnim);
homeAnimFactory.setSwipeVelocity(velocityPxPerMs.y);
homeAnimFactory.playAtomicAnimation(velocityPxPerMs.y);
mLauncherTransitionController = null;
if (mRecentsView != null) {
- mRecentsView.onPrepareGestureEndAnimation(null, mGestureState.getEndTarget(),
- getRemoteTaskViewSimulators());
+ mRecentsView.onPrepareGestureEndAnimation(null, mGestureState.getEndTarget());
}
} else {
AnimatorSet animatorSet = new AnimatorSet();
@@ -1374,42 +1227,24 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
animatorSet.play(windowAnim);
if (mRecentsView != null) {
mRecentsView.onPrepareGestureEndAnimation(
- animatorSet, mGestureState.getEndTarget(),
- getRemoteTaskViewSimulators());
+ animatorSet, mGestureState.getEndTarget());
}
animatorSet.setDuration(duration).setInterpolator(interpolator);
animatorSet.start();
- mRunningWindowAnim = new RunningWindowAnim[]{RunningWindowAnim.wrap(animatorSet)};
+ mRunningWindowAnim = RunningWindowAnim.wrap(animatorSet);
}
}
- private int calculateWindowRotation(RemoteAnimationTargetCompat runningTaskTarget,
- RecentsOrientedState orientationState) {
- if (runningTaskTarget.rotationChange != 0
- && TaskAnimationManager.ENABLE_SHELL_TRANSITIONS) {
- return Math.abs(runningTaskTarget.rotationChange) == ROTATION_90
- ? ROTATION_270 : ROTATION_90;
- } else {
- return orientationState.getDisplayRotation();
- }
- }
-
- /**
- * TODO(b/195473090) handle multiple task simulators (if needed) for PIP
- */
private SwipePipToHomeAnimator createWindowAnimationToPip(HomeAnimationFactory homeAnimFactory,
RemoteAnimationTargetCompat runningTaskTarget, float startProgress) {
// Directly animate the app to PiP (picture-in-picture) mode
- final ActivityManager.RunningTaskInfo taskInfo = runningTaskTarget.taskInfo;
- final RecentsOrientedState orientationState = mRemoteTargetHandles[0].getTaskViewSimulator()
- .getOrientationState();
- final int windowRotation = calculateWindowRotation(runningTaskTarget, orientationState);
+ final ActivityManager.RunningTaskInfo taskInfo = mGestureState.getRunningTask();
+ final RecentsOrientedState orientationState = mTaskViewSimulator.getOrientationState();
+ final int windowRotation = orientationState.getDisplayRotation();
final int homeRotation = orientationState.getRecentsActivityRotation();
- final Matrix[] homeToWindowPositionMaps = new Matrix[mRemoteTargetHandles.length];
- final RectF startRect = updateProgressForStartRect(homeToWindowPositionMaps,
- startProgress)[0];
- final Matrix homeToWindowPositionMap = homeToWindowPositionMaps[0];
+ final Matrix homeToWindowPositionMap = new Matrix();
+ final RectF startRect = updateProgressForStartRect(homeToWindowPositionMap, startProgress);
// Move the startRect to Launcher space as floatingIconView runs in Launcher
final Matrix windowToHomePositionMap = new Matrix();
homeToWindowPositionMap.invert(windowToHomePositionMap);
@@ -1425,7 +1260,7 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
.setContext(mContext)
.setTaskId(runningTaskTarget.taskId)
.setComponentName(taskInfo.topActivity)
- .setLeash(runningTaskTarget.leash)
+ .setLeash(runningTaskTarget.leash.getSurfaceControl())
.setSourceRectHint(
runningTaskTarget.taskInfo.pictureInPictureParams.getSourceRectHint())
.setAppBounds(taskInfo.configuration.windowConfiguration.getBounds())
@@ -1433,13 +1268,12 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
.setStartBounds(startRect)
.setDestinationBounds(destinationBounds)
.setCornerRadius(mRecentsView.getPipCornerRadius())
- .setShadowRadius(mRecentsView.getPipShadowRadius())
.setAttachedView(mRecentsView);
// We would assume home and app window always in the same rotation While homeRotation
// is not ROTATION_0 (which implies the rotation is turned on in launcher settings).
if (homeRotation == ROTATION_0
&& (windowRotation == ROTATION_90 || windowRotation == ROTATION_270)) {
- builder.setFromRotation(mRemoteTargetHandles[0].getTaskViewSimulator(), windowRotation,
+ builder.setFromRotation(mTaskViewSimulator, windowRotation,
taskInfo.displayCutoutInsets);
}
final SwipePipToHomeAnimator swipePipToHomeAnimator = builder.build();
@@ -1469,21 +1303,10 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
mGestureState.setState(STATE_END_TARGET_ANIMATION_FINISHED);
}
});
- setupWindowAnimation(new RectFSpringAnim[]{swipePipToHomeAnimator});
+ setupWindowAnimation(swipePipToHomeAnimator);
return swipePipToHomeAnimator;
}
- private void startInterceptingTouchesForGesture() {
- if (mRecentsAnimationController == null) {
- return;
- }
-
- mRecentsAnimationController.enableInputConsumer();
-
- // Start hiding the divider
- setDividerShown(false /* shown */, true /* immediate */);
- }
-
private void computeRecentsScrollIfInvisible() {
if (mRecentsView != null && mRecentsView.getVisibility() != View.VISIBLE) {
// Views typically don't compute scroll when invisible as an optimization,
@@ -1507,19 +1330,19 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
* @param homeAnimationFactory The home animation factory.
*/
@Override
- protected RectFSpringAnim[] createWindowAnimationToHome(float startProgress,
+ protected RectFSpringAnim createWindowAnimationToHome(float startProgress,
HomeAnimationFactory homeAnimationFactory) {
- RectFSpringAnim[] anim =
+ RectFSpringAnim anim =
super.createWindowAnimationToHome(startProgress, homeAnimationFactory);
setupWindowAnimation(anim);
return anim;
}
- private void setupWindowAnimation(RectFSpringAnim[] anims) {
- anims[0].addOnUpdateListener((r, p) -> {
+ private void setupWindowAnimation(RectFSpringAnim anim) {
+ anim.addOnUpdateListener((v, r, p) -> {
updateSysUiFlags(Math.max(p, mCurrentShift.value));
});
- anims[0].addAnimatorListener(new AnimationSuccessListener() {
+ anim.addAnimatorListener(new AnimationSuccessListener() {
@Override
public void onAnimationSuccess(Animator animator) {
if (mRecentsView != null) {
@@ -1531,7 +1354,7 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
}
});
if (mRecentsAnimationTargets != null) {
- mRecentsAnimationTargets.addReleaseCheck(anims[0]);
+ mRecentsAnimationTargets.addReleaseCheck(anim);
}
}
@@ -1676,10 +1499,6 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
boolean wasVisible = mWasLauncherAlreadyVisible || mGestureStarted;
mActivityInterface.onTransitionCancelled(wasVisible, mGestureState.getEndTarget());
- if (mRecentsAnimationTargets != null) {
- setDividerShown(true /* shown */, true /* immediate */);
- }
-
// Leave the pending invisible flag, as it may be used by wallpaper open animation.
if (mActivity != null) {
mActivity.clearForceInvisibleFlag(INVISIBLE_BY_STATE_HANDLER);
@@ -1768,7 +1587,7 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
// If there are no targets or the animation not started, then there is nothing to finish
mStateCallback.setStateOnUiThread(STATE_CURRENT_TASK_FINISHED);
} else {
- maybeFinishSwipeToHome();
+ maybeFinishSwipePipToHome();
finishRecentsControllerToHome(
() -> mStateCallback.setStateOnUiThread(STATE_CURRENT_TASK_FINISHED));
}
@@ -1777,14 +1596,12 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
}
/**
- * Notifies SysUI that transition is finished if applicable and also pass leash transactions
- * from Launcher to WM.
- * This should happen before {@link #finishRecentsControllerToHome(Runnable)}.
+ * Resets the {@link #mIsSwipingPipToHome} and notifies SysUI that transition is finished
+ * if applicable. This should happen before {@link #finishRecentsControllerToHome(Runnable)}.
*/
- private void maybeFinishSwipeToHome() {
- if (mIsSwipingPipToHome && mSwipePipToHomeAnimators[0] != null) {
+ private void maybeFinishSwipePipToHome() {
+ if (mIsSwipingPipToHome && mSwipePipToHomeAnimator != null) {
SystemUiProxy.INSTANCE.get(mContext).stopSwipePipToHome(
- mSwipePipToHomeAnimator.getTaskId(),
mSwipePipToHomeAnimator.getComponentName(),
mSwipePipToHomeAnimator.getDestinationBounds(),
mSwipePipToHomeAnimator.getContentOverlay());
@@ -1793,17 +1610,6 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
mSwipePipToHomeAnimator.getFinishTransaction(),
mSwipePipToHomeAnimator.getContentOverlay());
mIsSwipingPipToHome = false;
- } else if (mIsSwipeForStagedSplit) {
- // Transaction to hide the task to avoid flicker for entering PiP from split-screen.
- PictureInPictureSurfaceTransaction tx =
- new PictureInPictureSurfaceTransaction.Builder()
- .setAlpha(0f)
- .build();
- int[] taskIds = TopTaskTracker.INSTANCE.get(mContext).getRunningSplitTaskIds();
- for (int taskId : taskIds) {
- mRecentsAnimationController.setFinishTaskTransaction(taskId,
- tx, null /* overlay */);
- }
}
}
@@ -1816,10 +1622,7 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
endLauncherTransitionController();
mRecentsView.onSwipeUpAnimationSuccess();
if (ENABLE_QUICKSTEP_LIVE_TILE.get()) {
- mTaskAnimationManager.setLiveTileCleanUpHandler(() -> {
- mRecentsView.cleanupRemoteTargets();
- mInputConsumerProxy.destroy();
- });
+ mTaskAnimationManager.setLiveTileCleanUpHandler(mInputConsumerProxy::destroy);
mTaskAnimationManager.enableLiveTileRestartListener();
}
@@ -1838,8 +1641,8 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
* depend on proper class initialization.
*/
protected void initAfterSubclassConstructor() {
- initTransitionEndpoints(mRemoteTargetHandles[0].getTaskViewSimulator()
- .getOrientationState().getLauncherDeviceProfile());
+ initTransitionEndpoints(
+ mTaskViewSimulator.getOrientationState().getLauncherDeviceProfile());
}
protected void performHapticFeedback() {
@@ -1856,14 +1659,13 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
protected void linkRecentsViewScroll() {
SurfaceTransactionApplier.create(mRecentsView, applier -> {
- runActionOnRemoteHandles(remoteTargetHandle -> remoteTargetHandle.getTransformParams()
- .setSyncTransactionApplier(applier));
- runOnRecentsAnimationAndLauncherBound(() ->
+ mTransformParams.setSyncTransactionApplier(applier);
+ runOnRecentsAnimationStart(() ->
mRecentsAnimationTargets.addReleaseCheck(applier));
});
mRecentsView.addOnScrollChangedListener(mOnRecentsScrollListener);
- runOnRecentsAnimationAndLauncherBound(() ->
+ runOnRecentsAnimationStart(() ->
mRecentsView.setRecentsAnimationTargets(mRecentsAnimationController,
mRecentsAnimationTargets));
mRecentsViewScrollLinked = true;
@@ -1909,26 +1711,14 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
}
/**
- * Runs the given {@param action} if the recents animation has already started and Launcher has
- * been created and bound to the TouchInteractionService, or queues it to be run when it this
- * next happens.
+ * Runs the given {@param action} if the recents animation has already started, or queues it to
+ * be run when it is next started.
*/
- private void runOnRecentsAnimationAndLauncherBound(Runnable action) {
- mRecentsAnimationStartCallbacks.add(action);
- flushOnRecentsAnimationAndLauncherBound();
- }
-
- private void flushOnRecentsAnimationAndLauncherBound() {
- if (mRecentsAnimationTargets == null ||
- !mStateCallback.hasStates(STATE_LAUNCHER_BIND_TO_SERVICE)) {
- return;
- }
-
- if (!mRecentsAnimationStartCallbacks.isEmpty()) {
- for (Runnable action : new ArrayList<>(mRecentsAnimationStartCallbacks)) {
- action.run();
- }
- mRecentsAnimationStartCallbacks.clear();
+ protected void runOnRecentsAnimationStart(Runnable action) {
+ if (mRecentsAnimationTargets == null) {
+ mRecentsAnimationStartCallbacks.add(action);
+ } else {
+ action.run();
}
}
@@ -1942,9 +1732,6 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
@Override
public void onRecentsAnimationFinished(RecentsAnimationController controller) {
- if (!controller.getFinishTargetIsLauncher()) {
- setDividerShown(true /* shown */, false /* immediate */);
- }
mRecentsAnimationController = null;
mRecentsAnimationTargets = null;
if (mRecentsView != null) {
@@ -1953,9 +1740,9 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
}
@Override
- public void onTasksAppeared(RemoteAnimationTargetCompat[] appearedTaskTargets) {
+ public void onTaskAppeared(RemoteAnimationTargetCompat appearedTaskTarget) {
if (mRecentsAnimationController != null) {
- if (handleTaskAppeared(appearedTaskTargets)) {
+ if (handleTaskAppeared(appearedTaskTarget)) {
mRecentsAnimationController.finish(false /* toRecents */,
null /* onFinishComplete */);
mActivityInterface.onLaunchTaskSuccess();
@@ -1995,74 +1782,21 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
/**
* Applies the transform on the recents animation
*/
- protected void applyScrollAndTransform() {
- // No need to apply any transform if there is ongoing swipe-to-home animator
- // swipe-to-pip handles the leash solely
- // swipe-to-icon animation is handled by RectFSpringAnim anim
- boolean notSwipingToHome = mRecentsAnimationTargets != null
- && mGestureState.getEndTarget() != HOME;
- boolean setRecentsScroll = mRecentsViewScrollLinked && mRecentsView != null;
- for (RemoteTargetHandle remoteHandle : mRemoteTargetHandles) {
- AnimatorControllerWithResistance playbackController =
- remoteHandle.getPlaybackController();
- if (playbackController != null) {
- playbackController.setProgress(Math.max(mCurrentShift.value,
- getScaleProgressDueToScroll()), mDragLengthFactor);
- }
-
- if (notSwipingToHome) {
- TaskViewSimulator taskViewSimulator = remoteHandle.getTaskViewSimulator();
- if (setRecentsScroll) {
- taskViewSimulator.setScroll(mRecentsView.getScrollOffset());
- }
- taskViewSimulator.apply(remoteHandle.getTransformParams());
+ protected void applyWindowTransform() {
+ if (mWindowTransitionController != null) {
+ mWindowTransitionController.setProgress(mCurrentShift.value, mDragLengthFactor);
+ }
+ // No need to apply any transform if there is ongoing swipe-pip-to-home animator since
+ // that animator handles the leash solely.
+ if (mRecentsAnimationTargets != null && !mIsSwipingPipToHome) {
+ if (mRecentsViewScrollLinked && mRecentsView != null) {
+ mTaskViewSimulator.setScroll(mRecentsView.getScrollOffset());
}
+ mTaskViewSimulator.apply(mTransformParams);
}
ProtoTracer.INSTANCE.get(mContext).scheduleFrameUpdate();
}
- // Scaling of RecentsView during quick switch based on amount of recents scroll
- private float getScaleProgressDueToScroll() {
- if (mActivity == null || !mActivity.getDeviceProfile().isTablet || mRecentsView == null
- || !mRecentsViewScrollLinked) {
- return 0;
- }
-
- float scrollOffset = Math.abs(mRecentsView.getScrollOffset(mRecentsView.getCurrentPage()));
- int maxScrollOffset = mRecentsView.getPagedOrientationHandler().getPrimaryValue(
- mRecentsView.getLastComputedTaskSize().width(),
- mRecentsView.getLastComputedTaskSize().height());
- maxScrollOffset += mRecentsView.getPageSpacing();
-
- float maxScaleProgress =
- MAX_QUICK_SWITCH_RECENTS_SCALE_PROGRESS * mRecentsView.getMaxScaleForFullScreen();
- float scaleProgress = maxScaleProgress;
-
- if (scrollOffset < mQuickSwitchScaleScrollThreshold) {
- scaleProgress = Utilities.mapToRange(scrollOffset, 0, mQuickSwitchScaleScrollThreshold,
- 0, maxScaleProgress, ACCEL_DEACCEL);
- } else if (scrollOffset > (maxScrollOffset - mQuickSwitchScaleScrollThreshold)) {
- scaleProgress = Utilities.mapToRange(scrollOffset,
- (maxScrollOffset - mQuickSwitchScaleScrollThreshold), maxScrollOffset,
- maxScaleProgress, 0, ACCEL_DEACCEL);
- }
-
- return scaleProgress;
- }
-
- private void setDividerShown(boolean shown, boolean immediate) {
- if (mDividerAnimator != null) {
- mDividerAnimator.cancel();
- }
- mDividerAnimator = TaskViewUtils.createSplitAuxiliarySurfacesAnimator(
- mRecentsAnimationTargets.nonApps, shown, (dividerAnimator) -> {
- dividerAnimator.start();
- if (immediate) {
- dividerAnimator.end();
- }
- });
- }
-
/**
* Used for winscope tracing, see launcher_trace.proto
* @see com.android.systemui.shared.tracing.ProtoTraceable#writeToProto
@@ -2084,6 +1818,7 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
}
public interface Factory {
+
AbsSwipeUpHandler newHandler(GestureState gestureState, long touchTimeMs);
}
}
diff --git a/quickstep/src/com/android/quickstep/AnimatedFloat.java b/quickstep/src/com/android/quickstep/AnimatedFloat.java
index 6c7a885a1f..f7e8781573 100644
--- a/quickstep/src/com/android/quickstep/AnimatedFloat.java
+++ b/quickstep/src/com/android/quickstep/AnimatedFloat.java
@@ -42,8 +42,6 @@ public class AnimatedFloat {
private final Runnable mUpdateCallback;
private ObjectAnimator mValueAnimator;
- // Only non-null when an animation is playing to this value.
- private Float mEndValue;
public float value;
@@ -55,32 +53,14 @@ public class AnimatedFloat {
mUpdateCallback = updateCallback;
}
- /**
- * Returns an animation from the current value to the given value.
- */
- public ObjectAnimator animateToValue(float end) {
- return animateToValue(value, end);
- }
-
- /**
- * Returns an animation from the given start value to the given end value.
- */
public ObjectAnimator animateToValue(float start, float end) {
cancelAnimation();
mValueAnimator = ObjectAnimator.ofFloat(this, VALUE, start, end);
mValueAnimator.addListener(new AnimatorListenerAdapter() {
@Override
- public void onAnimationStart(Animator animator) {
- if (mValueAnimator == animator) {
- mEndValue = end;
- }
- }
-
- @Override
public void onAnimationEnd(Animator animator) {
if (mValueAnimator == animator) {
mValueAnimator = null;
- mEndValue = null;
}
}
});
@@ -98,15 +78,6 @@ public class AnimatedFloat {
}
}
- /**
- * Starts the animation.
- */
- public void startAnimation() {
- if (mValueAnimator != null) {
- mValueAnimator.start();
- }
- }
-
public void cancelAnimation() {
if (mValueAnimator != null) {
mValueAnimator.cancel();
@@ -122,15 +93,4 @@ public class AnimatedFloat {
public ObjectAnimator getCurrentAnimation() {
return mValueAnimator;
}
-
- public boolean isAnimating() {
- return mValueAnimator != null;
- }
-
- /**
- * Returns whether we are currently animating, and the animation's end value matches the given.
- */
- public boolean isAnimatingToValue(float endValue) {
- return isAnimating() && mEndValue != null && mEndValue == endValue;
- }
}
diff --git a/quickstep/src/com/android/quickstep/BaseActivityInterface.java b/quickstep/src/com/android/quickstep/BaseActivityInterface.java
index 2fcd286345..923a959986 100644
--- a/quickstep/src/com/android/quickstep/BaseActivityInterface.java
+++ b/quickstep/src/com/android/quickstep/BaseActivityInterface.java
@@ -21,6 +21,7 @@ import static com.android.launcher3.anim.Interpolators.INSTANT;
import static com.android.launcher3.anim.Interpolators.LINEAR;
import static com.android.quickstep.AbsSwipeUpHandler.RECENTS_ATTACH_DURATION;
import static com.android.quickstep.GestureState.GestureEndTarget.RECENTS;
+import static com.android.quickstep.SysUINavigationMode.getMode;
import static com.android.quickstep.util.RecentsAtomicAnimationFactory.INDEX_RECENTS_FADE_ANIM;
import static com.android.quickstep.util.RecentsAtomicAnimationFactory.INDEX_RECENTS_TRANSLATE_X_ANIM;
import static com.android.quickstep.views.RecentsView.ADJACENT_PAGE_HORIZONTAL_OFFSET;
@@ -29,7 +30,6 @@ import static com.android.quickstep.views.RecentsView.RECENTS_SCALE_PROPERTY;
import static com.android.quickstep.views.RecentsView.TASK_SECONDARY_TRANSLATION;
import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.annotation.TargetApi;
import android.content.Context;
@@ -40,7 +40,6 @@ import android.graphics.Rect;
import android.os.Build;
import android.view.Gravity;
import android.view.MotionEvent;
-import android.view.View;
import androidx.annotation.Nullable;
import androidx.annotation.UiThread;
@@ -49,25 +48,23 @@ import com.android.launcher3.DeviceProfile;
import com.android.launcher3.R;
import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.anim.PendingAnimation;
+import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.statehandlers.DepthController;
import com.android.launcher3.statemanager.BaseState;
import com.android.launcher3.statemanager.StatefulActivity;
-import com.android.launcher3.taskbar.TaskbarUIController;
import com.android.launcher3.touch.PagedOrientationHandler;
-import com.android.launcher3.util.DisplayController;
-import com.android.launcher3.util.DisplayController.NavigationMode;
import com.android.launcher3.util.WindowBounds;
import com.android.launcher3.views.ScrimView;
+import com.android.quickstep.SysUINavigationMode.Mode;
import com.android.quickstep.util.ActivityInitListener;
import com.android.quickstep.util.AnimatorControllerWithResistance;
import com.android.quickstep.util.SplitScreenBounds;
+import com.android.quickstep.views.OverviewActionsView;
import com.android.quickstep.views.RecentsView;
import com.android.quickstep.views.TaskView;
import com.android.systemui.shared.recents.model.ThumbnailData;
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
-import java.util.HashMap;
-import java.util.Optional;
import java.util.function.Consumer;
import java.util.function.Predicate;
@@ -84,8 +81,6 @@ public abstract class BaseActivityInterface<STATE_TYPE extends BaseState<STATE_T
private STATE_TYPE mTargetState;
- @Nullable private Runnable mOnInitBackgroundStateUICallback = null;
-
protected BaseActivityInterface(boolean rotationSupportedByActivity,
STATE_TYPE overviewState, STATE_TYPE backgroundState) {
this.rotationSupportedByActivity = rotationSupportedByActivity;
@@ -143,9 +138,6 @@ public abstract class BaseActivityInterface<STATE_TYPE extends BaseState<STATE_T
return null;
}
- @Nullable
- public abstract TaskbarUIController getTaskbarController();
-
public final boolean isResumed() {
ACTIVITY_TYPE activity = getCreatedActivity();
return activity != null && activity.hasBeenResumed();
@@ -169,7 +161,7 @@ public abstract class BaseActivityInterface<STATE_TYPE extends BaseState<STATE_T
public abstract boolean allowMinimizeSplitScreen();
public boolean deferStartingActivity(RecentsAnimationDeviceState deviceState, MotionEvent ev) {
- return deviceState.isInDeferredGestureRegion(ev) || deviceState.isImeRenderingNavButtons();
+ return deviceState.isInDeferredGestureRegion(ev);
}
/**
@@ -194,15 +186,9 @@ public abstract class BaseActivityInterface<STATE_TYPE extends BaseState<STATE_T
activity.getStateManager().moveToRestState();
}
- /**
- * Closes any overlays.
- */
- public void closeOverlay() {
- Optional.ofNullable(getTaskbarController()).ifPresent(TaskbarUIController::hideAllApps);
- }
+ public void closeOverlay() { }
- public void switchRunningTaskViewToScreenshot(HashMap<Integer, ThumbnailData> thumbnailDatas,
- Runnable runnable) {
+ public void switchRunningTaskViewToScreenshot(ThumbnailData thumbnailData, Runnable runnable) {
ACTIVITY_TYPE activity = getCreatedActivity();
if (activity == null) {
return;
@@ -214,35 +200,55 @@ public abstract class BaseActivityInterface<STATE_TYPE extends BaseState<STATE_T
}
return;
}
- recentsView.switchToScreenshot(thumbnailDatas, runnable);
+ recentsView.switchToScreenshot(thumbnailData, runnable);
}
/**
* Calculates the taskView size for the provided device configuration.
*/
- public final void calculateTaskSize(Context context, DeviceProfile dp, Rect outRect) {
+ public final void calculateTaskSize(Context context, DeviceProfile dp, Rect outRect,
+ PagedOrientationHandler orientedState) {
Resources res = context.getResources();
- float maxScale = res.getFloat(R.dimen.overview_max_scale);
- if (dp.isTablet) {
+ if (dp.isTablet && FeatureFlags.ENABLE_OVERVIEW_GRID.get()) {
Rect gridRect = new Rect();
- calculateGridSize(dp, gridRect);
+ calculateGridSize(context, dp, gridRect);
- calculateTaskSizeInternal(context, dp, gridRect, maxScale, Gravity.CENTER, outRect);
+ int verticalMargin = res.getDimensionPixelSize(
+ R.dimen.overview_grid_focus_vertical_margin);
+ float taskHeight = gridRect.height() - verticalMargin * 2;
+
+ PointF taskDimension = getTaskDimension(context, dp);
+ float scale = taskHeight / Math.max(taskDimension.x, taskDimension.y);
+ int outWidth = Math.round(scale * taskDimension.x);
+ int outHeight = Math.round(scale * taskDimension.y);
+
+ int gravity = Gravity.CENTER_VERTICAL;
+ gravity |= orientedState.getRecentsRtlSetting(res) ? Gravity.RIGHT : Gravity.LEFT;
+ Gravity.apply(gravity, outWidth, outHeight, gridRect, outRect);
} else {
int taskMargin = dp.overviewTaskMarginPx;
+ int proactiveRowAndMargin;
+ if (!TaskView.SHOW_PROACTIVE_ACTIONS || dp.isVerticalBarLayout()) {
+ // In Vertical Bar Layout the proactive row doesn't have its own space, it's inside
+ // the actions row.
+ proactiveRowAndMargin = 0;
+ } else {
+ proactiveRowAndMargin = res.getDimensionPixelSize(
+ R.dimen.overview_proactive_row_height)
+ + res.getDimensionPixelSize(R.dimen.overview_proactive_row_bottom_margin);
+ }
calculateTaskSizeInternal(context, dp,
dp.overviewTaskThumbnailTopMarginPx,
- dp.getOverviewActionsClaimedSpace(),
+ proactiveRowAndMargin + getOverviewActionsHeight(context, dp),
res.getDimensionPixelSize(R.dimen.overview_minimum_next_prev_size) + taskMargin,
- maxScale,
- Gravity.CENTER,
outRect);
}
}
- private void calculateTaskSizeInternal(Context context, DeviceProfile dp, int claimedSpaceAbove,
- int claimedSpaceBelow, int minimumHorizontalPadding, float maxScale, int gravity,
+ private void calculateTaskSizeInternal(Context context, DeviceProfile dp,
+ int claimedSpaceAbove, int claimedSpaceBelow, int minimumHorizontalPadding,
Rect outRect) {
+ PointF taskDimension = getTaskDimension(context, dp);
Rect insets = dp.getInsets();
Rect potentialTaskRect = new Rect(0, 0, dp.widthPx, dp.heightPx);
@@ -253,21 +259,13 @@ public abstract class BaseActivityInterface<STATE_TYPE extends BaseState<STATE_T
minimumHorizontalPadding,
claimedSpaceBelow);
- calculateTaskSizeInternal(context, dp, potentialTaskRect, maxScale, gravity, outRect);
- }
-
- private void calculateTaskSizeInternal(Context context, DeviceProfile dp,
- Rect potentialTaskRect, float maxScale, int gravity, Rect outRect) {
- PointF taskDimension = getTaskDimension(context, dp);
-
float scale = Math.min(
potentialTaskRect.width() / taskDimension.x,
potentialTaskRect.height() / taskDimension.y);
- scale = Math.min(scale, maxScale);
int outWidth = Math.round(scale * taskDimension.x);
int outHeight = Math.round(scale * taskDimension.y);
- Gravity.apply(gravity, outWidth, outHeight, potentialTaskRect, outRect);
+ Gravity.apply(Gravity.CENTER, outWidth, outHeight, potentialTaskRect, outRect);
}
private static PointF getTaskDimension(Context context, DeviceProfile dp) {
@@ -282,49 +280,34 @@ public abstract class BaseActivityInterface<STATE_TYPE extends BaseState<STATE_T
public static void getTaskDimension(Context context, DeviceProfile dp, PointF out) {
if (dp.isMultiWindowMode) {
WindowBounds bounds = SplitScreenBounds.INSTANCE.getSecondaryWindowBounds(context);
- out.x = bounds.availableSize.x;
- out.y = bounds.availableSize.y;
- if (!TaskView.clipLeft(dp)) {
- out.x += bounds.insets.left;
- }
- if (!TaskView.clipRight(dp)) {
- out.x += bounds.insets.right;
- }
- if (!TaskView.clipTop(dp)) {
- out.y += bounds.insets.top;
- }
- if (!TaskView.clipBottom(dp)) {
- out.y += bounds.insets.bottom;
+ if (TaskView.CLIP_STATUS_AND_NAV_BARS) {
+ out.x = bounds.availableSize.x;
+ out.y = bounds.availableSize.y;
+ } else {
+ out.x = bounds.availableSize.x + bounds.insets.left + bounds.insets.right;
+ out.y = bounds.availableSize.y + bounds.insets.top + bounds.insets.bottom;
}
+ } else if (TaskView.CLIP_STATUS_AND_NAV_BARS) {
+ out.x = dp.availableWidthPx;
+ out.y = dp.availableHeightPx;
} else {
out.x = dp.widthPx;
out.y = dp.heightPx;
- if (TaskView.clipLeft(dp)) {
- out.x -= dp.getInsets().left;
- }
- if (TaskView.clipRight(dp)) {
- out.x -= dp.getInsets().right;
- }
- if (TaskView.clipTop(dp)) {
- out.y -= dp.getInsets().top;
- }
- if (TaskView.clipBottom(dp)) {
- out.y -= Math.max(dp.getInsets().bottom, dp.taskbarSize);
- }
}
}
/**
* Calculates the overview grid size for the provided device configuration.
*/
- public final void calculateGridSize(DeviceProfile dp, Rect outRect) {
- Rect insets = dp.getInsets();
- int topMargin = dp.overviewTaskThumbnailTopMarginPx;
- int bottomMargin = dp.getOverviewActionsClaimedSpace();
- int sideMargin = dp.overviewGridSideMargin;
+ public final void calculateGridSize(Context context, DeviceProfile dp, Rect outRect) {
+ Resources res = context.getResources();
+ int topMargin = res.getDimensionPixelSize(R.dimen.overview_grid_top_margin);
+ int bottomMargin = res.getDimensionPixelSize(R.dimen.overview_grid_bottom_margin);
+ int sideMargin = res.getDimensionPixelSize(R.dimen.overview_grid_side_margin);
+ Rect insets = dp.getInsets();
outRect.set(0, 0, dp.widthPx, dp.heightPx);
- outRect.inset(Math.max(insets.left, sideMargin), insets.top + topMargin,
+ outRect.inset(Math.max(insets.left, sideMargin), Math.max(insets.top, topMargin),
Math.max(insets.right, sideMargin), Math.max(insets.bottom, bottomMargin));
}
@@ -334,46 +317,50 @@ public abstract class BaseActivityInterface<STATE_TYPE extends BaseState<STATE_T
public final void calculateGridTaskSize(Context context, DeviceProfile dp, Rect outRect,
PagedOrientationHandler orientedState) {
Resources res = context.getResources();
- Rect taskRect = new Rect();
- calculateTaskSize(context, dp, taskRect);
+ Rect gridRect = new Rect();
+ calculateGridSize(context, dp, gridRect);
- float rowHeight =
- (taskRect.height() + dp.overviewTaskThumbnailTopMarginPx - dp.overviewRowSpacing)
- / 2f;
+ int rowSpacing = res.getDimensionPixelSize(R.dimen.overview_grid_row_spacing);
+ float rowHeight = (gridRect.height() - rowSpacing) / 2f;
PointF taskDimension = getTaskDimension(context, dp);
- float scale = (rowHeight - dp.overviewTaskThumbnailTopMarginPx) / taskDimension.y;
+ float scale = (rowHeight - dp.overviewTaskThumbnailTopMarginPx) / Math.max(
+ taskDimension.x, taskDimension.y);
int outWidth = Math.round(scale * taskDimension.x);
int outHeight = Math.round(scale * taskDimension.y);
int gravity = Gravity.TOP;
gravity |= orientedState.getRecentsRtlSetting(res) ? Gravity.RIGHT : Gravity.LEFT;
- Gravity.apply(gravity, outWidth, outHeight, taskRect, outRect);
+ gridRect.inset(0, dp.overviewTaskThumbnailTopMarginPx, 0, 0);
+ Gravity.apply(gravity, outWidth, outHeight, gridRect, outRect);
}
/**
* Calculates the modal taskView size for the provided device configuration
*/
public final void calculateModalTaskSize(Context context, DeviceProfile dp, Rect outRect) {
- calculateTaskSize(context, dp, outRect);
- float maxScale = context.getResources().getFloat(R.dimen.overview_modal_max_scale);
calculateTaskSizeInternal(
context, dp,
dp.overviewTaskMarginPx,
- dp.heightPx - outRect.bottom - dp.getInsets().bottom,
- Math.round((dp.availableWidthPx - outRect.width() * maxScale) / 2),
- 1f /*maxScale*/,
- Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM,
+ getOverviewActionsHeight(context, dp),
+ dp.overviewTaskMarginPx,
outRect);
}
+ /** Gets the space that the overview actions will take, including bottom margin. */
+ private int getOverviewActionsHeight(Context context, DeviceProfile dp) {
+ Resources res = context.getResources();
+ return OverviewActionsView.getOverviewActionsBottomMarginPx(getMode(context), dp)
+ + OverviewActionsView.getOverviewActionsTopMarginPx(getMode(context), dp)
+ + res.getDimensionPixelSize(R.dimen.overview_actions_height);
+ }
+
/**
* Called when the gesture ends and the animation starts towards the given target. Used to add
* an optional additional animation with the same duration.
*/
public @Nullable Animator getParallelAnimationToLauncher(
- GestureState.GestureEndTarget endTarget, long duration,
- RecentsAnimationCallbacks callbacks) {
+ GestureState.GestureEndTarget endTarget, long duration) {
if (endTarget == RECENTS) {
ACTIVITY_TYPE activity = getCreatedActivity();
if (activity == null) {
@@ -400,35 +387,6 @@ public abstract class BaseActivityInterface<STATE_TYPE extends BaseState<STATE_T
*/
public abstract STATE_TYPE stateFromGestureEndTarget(GestureState.GestureEndTarget endTarget);
- /**
- * Called when the animation to the target has finished, but right before updating the state.
- * @return A View that needs to draw before ending the recents animation to LAST_TASK.
- * (This is a hack to ensure Taskbar draws its background first to avoid flickering.)
- */
- public @Nullable View onSettledOnEndTarget(GestureState.GestureEndTarget endTarget) {
- TaskbarUIController taskbarUIController = getTaskbarController();
- if (taskbarUIController != null) {
- taskbarUIController.setSystemGestureInProgress(false);
- return taskbarUIController.getRootView();
- }
- return null;
- }
-
- protected void runOnInitBackgroundStateUI(Runnable callback) {
- mOnInitBackgroundStateUICallback = callback;
- ACTIVITY_TYPE activity = getCreatedActivity();
- if (activity != null && activity.getStateManager().getState() == mBackgroundState) {
- onInitBackgroundStateUI();
- }
- }
-
- private void onInitBackgroundStateUI() {
- if (mOnInitBackgroundStateUICallback != null) {
- mOnInitBackgroundStateUICallback.run();
- mOnInitBackgroundStateUICallback = null;
- }
- }
-
public interface AnimationFactory {
void createActivityInterface(long transitionLength);
@@ -444,10 +402,6 @@ public abstract class BaseActivityInterface<STATE_TYPE extends BaseState<STATE_T
return false;
}
- default boolean hasRecentsEverAttachedToAppWindow() {
- return false;
- }
-
/** Called when the gesture ends and we know what state it is going towards */
default void setEndTarget(GestureState.GestureEndTarget endTarget) { }
}
@@ -459,7 +413,6 @@ public abstract class BaseActivityInterface<STATE_TYPE extends BaseState<STATE_T
private final Consumer<AnimatorControllerWithResistance> mCallback;
private boolean mIsAttachedToWindow;
- private boolean mHasEverAttachedToWindow;
DefaultAnimationFactory(Consumer<AnimatorControllerWithResistance> callback) {
mCallback = callback;
@@ -468,14 +421,13 @@ public abstract class BaseActivityInterface<STATE_TYPE extends BaseState<STATE_T
mStartState = mActivity.getStateManager().getState();
}
- protected ACTIVITY_TYPE initBackgroundStateUI() {
+ protected ACTIVITY_TYPE initUI() {
STATE_TYPE resetState = mStartState;
if (mStartState.shouldDisableRestore()) {
resetState = mActivity.getStateManager().getRestState();
}
mActivity.getStateManager().setRestState(resetState);
mActivity.getStateManager().goToState(mBackgroundState, false);
- onInitBackgroundStateUI();
return mActivity;
}
@@ -502,7 +454,7 @@ public abstract class BaseActivityInterface<STATE_TYPE extends BaseState<STATE_T
// Creating the activity controller animation sometimes reapplies the launcher state
// (because we set the animation as the current state animation), so we reapply the
// attached state here as well to ensure recents is shown/hidden appropriately.
- if (DisplayController.getNavigationMode(mActivity) == NavigationMode.NO_BUTTON) {
+ if (SysUINavigationMode.getMode(mActivity) == Mode.NO_BUTTON) {
setRecentsAttachedToAppWindow(mIsAttachedToWindow, false);
}
}
@@ -514,9 +466,6 @@ public abstract class BaseActivityInterface<STATE_TYPE extends BaseState<STATE_T
}
mIsAttachedToWindow = attached;
RecentsView recentsView = mActivity.getOverviewPanel();
- if (attached) {
- mHasEverAttachedToWindow = true;
- }
Animator fadeAnim = mActivity.getStateManager()
.createStateElementAnimation(INDEX_RECENTS_FADE_ANIM, attached ? 1 : 0);
@@ -547,11 +496,6 @@ public abstract class BaseActivityInterface<STATE_TYPE extends BaseState<STATE_T
}
@Override
- public boolean hasRecentsEverAttachedToAppWindow() {
- return mHasEverAttachedToWindow;
- }
-
- @Override
public void setEndTarget(GestureState.GestureEndTarget endTarget) {
mTargetState = stateFromGestureEndTarget(endTarget);
}
@@ -562,16 +506,11 @@ public abstract class BaseActivityInterface<STATE_TYPE extends BaseState<STATE_T
pa.addFloat(recentsView, RECENTS_SCALE_PROPERTY,
recentsView.getMaxScaleForFullScreen(), 1, LINEAR);
pa.addFloat(recentsView, FULLSCREEN_PROGRESS, 1, 0, LINEAR);
-
- pa.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationStart(Animator animation) {
- TaskbarUIController taskbarUIController = getTaskbarController();
- if (taskbarUIController != null) {
- taskbarUIController.setSystemGestureInProgress(true);
- }
- }
- });
}
}
+
+ /** Called when OverviewService is bound to this process */
+ void onOverviewServiceBound() {
+ // Do nothing
+ }
}
diff --git a/quickstep/src/com/android/quickstep/FallbackActivityInterface.java b/quickstep/src/com/android/quickstep/FallbackActivityInterface.java
index ba61574f03..7fb8e16063 100644
--- a/quickstep/src/com/android/quickstep/FallbackActivityInterface.java
+++ b/quickstep/src/com/android/quickstep/FallbackActivityInterface.java
@@ -16,13 +16,11 @@
package com.android.quickstep;
import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE;
-import static com.android.launcher3.util.DisplayController.NavigationMode.NO_BUTTON;
+import static com.android.quickstep.SysUINavigationMode.Mode.NO_BUTTON;
import static com.android.quickstep.fallback.RecentsState.BACKGROUND_APP;
import static com.android.quickstep.fallback.RecentsState.DEFAULT;
import static com.android.quickstep.fallback.RecentsState.HOME;
-import android.animation.Animator;
-import android.animation.AnimatorSet;
import android.content.Context;
import android.graphics.Rect;
import android.view.MotionEvent;
@@ -31,10 +29,7 @@ import androidx.annotation.Nullable;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.statemanager.StateManager;
-import com.android.launcher3.taskbar.FallbackTaskbarUIController;
import com.android.launcher3.touch.PagedOrientationHandler;
-import com.android.launcher3.util.DisplayController;
-import com.android.quickstep.GestureState.GestureEndTarget;
import com.android.quickstep.fallback.RecentsState;
import com.android.quickstep.util.ActivityInitListener;
import com.android.quickstep.util.AnimatorControllerWithResistance;
@@ -62,8 +57,9 @@ public final class FallbackActivityInterface extends
@Override
public int getSwipeUpDestinationAndLength(DeviceProfile dp, Context context, Rect outRect,
PagedOrientationHandler orientationHandler) {
- calculateTaskSize(context, dp, outRect);
- if (dp.isVerticalBarLayout() && DisplayController.getNavigationMode(context) != NO_BUTTON) {
+ calculateTaskSize(context, dp, outRect, orientationHandler);
+ if (dp.isVerticalBarLayout()
+ && SysUINavigationMode.INSTANCE.get(context).getMode() != NO_BUTTON) {
return dp.isSeascape() ? outRect.left : (dp.widthPx - outRect.right);
} else {
return dp.heightPx - outRect.bottom;
@@ -89,7 +85,7 @@ public final class FallbackActivityInterface extends
boolean activityVisible, Consumer<AnimatorControllerWithResistance> callback) {
notifyRecentsOfOrientation(deviceState.getRotationTouchHelper());
DefaultAnimationFactory factory = new DefaultAnimationFactory(callback);
- factory.initBackgroundStateUI();
+ factory.initUI();
return factory;
}
@@ -106,15 +102,6 @@ public final class FallbackActivityInterface extends
return RecentsActivity.ACTIVITY_TRACKER.getCreatedActivity();
}
- @Override
- public FallbackTaskbarUIController getTaskbarController() {
- RecentsActivity activity = getCreatedActivity();
- if (activity == null) {
- return null;
- }
- return activity.getTaskbarUIController();
- }
-
@Nullable
@Override
public RecentsView getVisibleRecentsView() {
@@ -195,7 +182,7 @@ public final class FallbackActivityInterface extends
}
@Override
- public RecentsState stateFromGestureEndTarget(GestureEndTarget endTarget) {
+ public RecentsState stateFromGestureEndTarget(GestureState.GestureEndTarget endTarget) {
switch (endTarget) {
case RECENTS:
return DEFAULT;
@@ -216,28 +203,6 @@ public final class FallbackActivityInterface extends
}
@Override
- public @Nullable Animator getParallelAnimationToLauncher(GestureEndTarget endTarget,
- long duration, RecentsAnimationCallbacks callbacks) {
- FallbackTaskbarUIController uiController = getTaskbarController();
- Animator superAnimator = super.getParallelAnimationToLauncher(
- endTarget, duration, callbacks);
- if (uiController == null) {
- return superAnimator;
- }
- RecentsState toState = stateFromGestureEndTarget(endTarget);
- Animator taskbarAnimator = uiController.createAnimToRecentsState(toState, duration);
- if (taskbarAnimator == null) {
- return superAnimator;
- }
- if (superAnimator == null) {
- return taskbarAnimator;
- }
- AnimatorSet animatorSet = new AnimatorSet();
- animatorSet.playTogether(superAnimator, taskbarAnimator);
- return animatorSet;
- }
-
- @Override
protected int getOverviewScrimColorForState(RecentsActivity activity, RecentsState state) {
return state.getScrimColor(activity);
}
diff --git a/quickstep/src/com/android/quickstep/FallbackSwipeHandler.java b/quickstep/src/com/android/quickstep/FallbackSwipeHandler.java
index ee5bb44040..fd44e023a7 100644
--- a/quickstep/src/com/android/quickstep/FallbackSwipeHandler.java
+++ b/quickstep/src/com/android/quickstep/FallbackSwipeHandler.java
@@ -21,16 +21,13 @@ import static android.content.Intent.EXTRA_USER;
import static com.android.launcher3.GestureNavContract.EXTRA_GESTURE_CONTRACT;
import static com.android.launcher3.GestureNavContract.EXTRA_ICON_POSITION;
import static com.android.launcher3.GestureNavContract.EXTRA_ICON_SURFACE;
-import static com.android.launcher3.GestureNavContract.EXTRA_ON_FINISH_CALLBACK;
import static com.android.launcher3.GestureNavContract.EXTRA_REMOTE_CALLBACK;
import static com.android.launcher3.Utilities.createHomeIntent;
-import static com.android.launcher3.anim.AnimatorListeners.forEndCallback;
import static com.android.launcher3.anim.Interpolators.ACCEL;
import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.ACTIVITY_TYPE_HOME;
import android.animation.ObjectAnimator;
import android.annotation.TargetApi;
-import android.app.ActivityManager.RunningTaskInfo;
import android.app.ActivityOptions;
import android.content.ActivityNotFoundException;
import android.content.Context;
@@ -46,9 +43,7 @@ import android.os.Looper;
import android.os.Message;
import android.os.Messenger;
import android.os.ParcelUuid;
-import android.os.RemoteException;
import android.os.UserHandle;
-import android.util.Log;
import android.view.Surface;
import android.view.SurfaceControl;
import android.view.SurfaceControl.Transaction;
@@ -61,14 +56,14 @@ import com.android.launcher3.Utilities;
import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.anim.PendingAnimation;
import com.android.launcher3.anim.SpringAnimationBuilder;
-import com.android.launcher3.states.StateAnimationConfig;
-import com.android.launcher3.util.DisplayController;
import com.android.quickstep.fallback.FallbackRecentsView;
import com.android.quickstep.fallback.RecentsState;
+import com.android.quickstep.util.AppCloseConfig;
import com.android.quickstep.util.RectFSpringAnim;
import com.android.quickstep.util.TransformParams;
import com.android.quickstep.util.TransformParams.BuilderProxy;
import com.android.systemui.shared.recents.model.Task.TaskKey;
+import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.InputConsumerController;
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat.SurfaceParams;
@@ -85,8 +80,6 @@ import java.util.function.Consumer;
public class FallbackSwipeHandler extends
AbsSwipeUpHandler<RecentsActivity, FallbackRecentsView, RecentsState> {
- private static final String TAG = "FallbackSwipeHandler";
-
/**
* Message used for receiving gesture nav contract information. We use a static messenger to
* avoid leaking too make binders in case the receiving launcher does not handle the contract
@@ -100,19 +93,15 @@ public class FallbackSwipeHandler extends
private final Matrix mTmpMatrix = new Matrix();
private float mMaxLauncherScale = 1;
- private boolean mAppCanEnterPip;
-
public FallbackSwipeHandler(Context context, RecentsAnimationDeviceState deviceState,
TaskAnimationManager taskAnimationManager, GestureState gestureState, long touchTimeMs,
boolean continuingLastGesture, InputConsumerController inputConsumer) {
super(context, deviceState, taskAnimationManager, gestureState, touchTimeMs,
continuingLastGesture, inputConsumer);
- mRunningOverHome = mGestureState.getRunningTask().isHomeTask();
+ mRunningOverHome = ActivityManagerWrapper.isHomeTask(mGestureState.getRunningTask());
if (mRunningOverHome) {
- runActionOnRemoteHandles(remoteTargetHandle ->
- remoteTargetHandle.getTransformParams().setHomeBuilderProxy(
- FallbackSwipeHandler.this::updateHomeActivityTransformDuringSwipeUp));
+ mTransformParams.setHomeBuilderProxy(this::updateHomeActivityTransformDuringSwipeUp);
}
}
@@ -120,9 +109,7 @@ public class FallbackSwipeHandler extends
protected void initTransitionEndpoints(DeviceProfile dp) {
super.initTransitionEndpoints(dp);
if (mRunningOverHome) {
- // Full screen scale should be independent of remote target handle
- mMaxLauncherScale = 1 / mRemoteTargetHandles[0].getTaskViewSimulator()
- .getFullScreenScale();
+ mMaxLauncherScale = 1 / mTaskViewSimulator.getFullScreenScale();
}
}
@@ -144,32 +131,20 @@ public class FallbackSwipeHandler extends
protected HomeAnimationFactory createHomeAnimationFactory(ArrayList<IBinder> launchCookies,
long duration, boolean isTargetTranslucent, boolean appCanEnterPip,
RemoteAnimationTargetCompat runningTaskTarget) {
- mAppCanEnterPip = appCanEnterPip;
- if (appCanEnterPip) {
- return new FallbackPipToHomeAnimationFactory();
- }
mActiveAnimationFactory = new FallbackHomeAnimationFactory(duration);
- startHomeIntent(mActiveAnimationFactory, runningTaskTarget);
- return mActiveAnimationFactory;
- }
-
- private void startHomeIntent(
- @Nullable FallbackHomeAnimationFactory gestureContractAnimationFactory,
- @Nullable RemoteAnimationTargetCompat runningTaskTarget) {
ActivityOptions options = ActivityOptions.makeCustomAnimation(mContext, 0, 0);
Intent intent = new Intent(mGestureState.getHomeIntent());
- if (gestureContractAnimationFactory != null && runningTaskTarget != null) {
- gestureContractAnimationFactory.addGestureContract(intent, runningTaskTarget.taskInfo);
- }
+ mActiveAnimationFactory.addGestureContract(intent);
try {
mContext.startActivity(intent, options.toBundle());
} catch (NullPointerException | ActivityNotFoundException | SecurityException e) {
mContext.startActivity(createHomeIntent());
}
+ return mActiveAnimationFactory;
}
@Override
- protected boolean handleTaskAppeared(RemoteAnimationTargetCompat[] appearedTaskTarget) {
+ protected boolean handleTaskAppeared(RemoteAnimationTargetCompat appearedTaskTarget) {
if (mActiveAnimationFactory != null
&& mActiveAnimationFactory.handleHomeTaskAppeared(appearedTaskTarget)) {
mActiveAnimationFactory = null;
@@ -181,21 +156,8 @@ public class FallbackSwipeHandler extends
@Override
protected void finishRecentsControllerToHome(Runnable callback) {
- final Runnable recentsCallback;
- if (mAppCanEnterPip) {
- // Make sure Launcher is resumed after auto-enter-pip transition to actually trigger
- // the PiP task appearing.
- recentsCallback = () -> {
- callback.run();
- startHomeIntent(
- null /* gestureContractAnimationFactory */, null /* runningTaskTarget */);
- };
- } else {
- recentsCallback = callback;
- }
- mRecentsView.cleanupRemoteTargets();
mRecentsAnimationController.finish(
- mAppCanEnterPip /* toRecents */, recentsCallback, true /* sendUserLeaveHint */);
+ false /* toRecents */, callback, true /* sendUserLeaveHint */);
}
@Override
@@ -211,29 +173,13 @@ public class FallbackSwipeHandler extends
@Override
protected void notifyGestureAnimationStartToRecents() {
if (mRunningOverHome) {
- if (DisplayController.getNavigationMode(mContext).hasGestures) {
- mRecentsView.onGestureAnimationStartOnHome(
- mGestureState.getRunningTask().getPlaceholderTasks(),
- mDeviceState.getRotationTouchHelper());
- }
+ mRecentsView.onGestureAnimationStartOnHome(mGestureState.getRunningTask());
} else {
super.notifyGestureAnimationStartToRecents();
}
}
- private class FallbackPipToHomeAnimationFactory extends HomeAnimationFactory {
- @NonNull
- @Override
- public AnimatorPlaybackController createActivityAnimationToHome() {
- // copied from {@link LauncherSwipeHandlerV2.LauncherHomeAnimationFactory}
- long accuracy = 2 * Math.max(mDp.widthPx, mDp.heightPx);
- return mActivity.getStateManager().createAnimationToNewWorkspace(
- RecentsState.HOME, accuracy, StateAnimationConfig.SKIP_ALL_ANIMATIONS);
- }
- }
-
- private class FallbackHomeAnimationFactory extends HomeAnimationFactory
- implements Consumer<Message> {
+ private class FallbackHomeAnimationFactory extends HomeAnimationFactory {
private final Rect mTempRect = new Rect();
private final TransformParams mHomeAlphaParams = new TransformParams();
private final AnimatedFloat mHomeAlpha;
@@ -244,9 +190,6 @@ public class FallbackSwipeHandler extends
private final RectF mTargetRect = new RectF();
private SurfaceControl mSurfaceControl;
- private boolean mAnimationFinished;
- private Message mOnFinishCallback;
-
private final long mDuration;
private RectFSpringAnim mSpringAnim;
@@ -257,22 +200,19 @@ public class FallbackSwipeHandler extends
mHomeAlpha = new AnimatedFloat();
mHomeAlpha.value = Utilities.boundToRange(1 - mCurrentShift.value, 0, 1);
mVerticalShiftForScale.value = mCurrentShift.value;
- runActionOnRemoteHandles(remoteTargetHandle ->
- remoteTargetHandle.getTransformParams().setHomeBuilderProxy(
- FallbackHomeAnimationFactory.this
- ::updateHomeActivityTransformDuringHomeAnim));
+ mTransformParams.setHomeBuilderProxy(
+ this::updateHomeActivityTransformDuringHomeAnim);
} else {
mHomeAlpha = new AnimatedFloat(this::updateHomeAlpha);
mHomeAlpha.value = 0;
+
mHomeAlphaParams.setHomeBuilderProxy(
this::updateHomeActivityTransformDuringHomeAnim);
}
mRecentsAlpha.value = 1;
- runActionOnRemoteHandles(remoteTargetHandle ->
- remoteTargetHandle.getTransformParams().setBaseBuilderProxy(
- FallbackHomeAnimationFactory.this
- ::updateRecentsActivityTransformDuringHomeAnim));
+ mTransformParams.setBaseBuilderProxy(
+ this::updateRecentsActivityTransformDuringHomeAnim);
}
@NonNull
@@ -309,8 +249,7 @@ public class FallbackSwipeHandler extends
}
}
- public boolean handleHomeTaskAppeared(RemoteAnimationTargetCompat[] appearedTaskTargets) {
- RemoteAnimationTargetCompat appearedTaskTarget = appearedTaskTargets[0];
+ public boolean handleHomeTaskAppeared(RemoteAnimationTargetCompat appearedTaskTarget) {
if (appearedTaskTarget.activityType == ACTIVITY_TYPE_HOME) {
RemoteAnimationTargets targets = new RemoteAnimationTargets(
new RemoteAnimationTargetCompat[] {appearedTaskTarget},
@@ -346,26 +285,9 @@ public class FallbackSwipeHandler extends
@Override
public void setAnimation(RectFSpringAnim anim) {
mSpringAnim = anim;
- mSpringAnim.addAnimatorListener(forEndCallback(this::onRectAnimationEnd));
- }
-
- private void onRectAnimationEnd() {
- mAnimationFinished = true;
- maybeSendEndMessage();
}
- private void maybeSendEndMessage() {
- if (mAnimationFinished && mOnFinishCallback != null) {
- try {
- mOnFinishCallback.replyTo.send(mOnFinishCallback);
- } catch (RemoteException e) {
- Log.e(TAG, "Error sending icon position", e);
- }
- }
- }
-
- @Override
- public void accept(Message msg) {
+ private void onMessageReceived(Message msg) {
try {
Bundle data = msg.getData();
RectF position = data.getParcelable(EXTRA_ICON_POSITION);
@@ -375,16 +297,15 @@ public class FallbackSwipeHandler extends
if (mSpringAnim != null) {
mSpringAnim.onTargetPositionChanged();
}
- mOnFinishCallback = data.getParcelable(EXTRA_ON_FINISH_CALLBACK);
}
- maybeSendEndMessage();
} catch (Exception e) {
// Ignore
}
}
@Override
- public void update(RectF currentRect, float progress, float radius) {
+ public void update(@Nullable AppCloseConfig config, RectF currentRect, float progress,
+ float radius) {
if (mSurfaceControl != null) {
currentRect.roundOut(mTempRect);
Transaction t = new Transaction();
@@ -397,12 +318,12 @@ public class FallbackSwipeHandler extends
}
}
- private void addGestureContract(Intent intent, RunningTaskInfo runningTaskInfo) {
- if (mRunningOverHome || runningTaskInfo == null) {
+ private void addGestureContract(Intent intent) {
+ if (mRunningOverHome || mGestureState.getRunningTask() == null) {
return;
}
- TaskKey key = new TaskKey(runningTaskInfo);
+ TaskKey key = new TaskKey(mGestureState.getRunningTask());
if (key.getComponent() != null) {
if (sMessageReceiver == null) {
sMessageReceiver = new StaticMessageReceiver();
@@ -411,8 +332,8 @@ public class FallbackSwipeHandler extends
Bundle gestureNavContract = new Bundle();
gestureNavContract.putParcelable(EXTRA_COMPONENT_NAME, key.getComponent());
gestureNavContract.putParcelable(EXTRA_USER, UserHandle.of(key.userId));
- gestureNavContract.putParcelable(
- EXTRA_REMOTE_CALLBACK, sMessageReceiver.newCallback(this));
+ gestureNavContract.putParcelable(EXTRA_REMOTE_CALLBACK,
+ sMessageReceiver.newCallback(this::onMessageReceived));
intent.putExtra(EXTRA_GESTURE_CONTRACT, gestureNavContract);
}
}
diff --git a/quickstep/src/com/android/quickstep/GestureState.java b/quickstep/src/com/android/quickstep/GestureState.java
index 3b52e9178e..aabba66386 100644
--- a/quickstep/src/com/android/quickstep/GestureState.java
+++ b/quickstep/src/com/android/quickstep/GestureState.java
@@ -20,8 +20,8 @@ import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_HOME;
import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_OVERVIEW;
import static com.android.quickstep.MultiStateCallback.DEBUG_STATES;
-import android.annotation.Nullable;
import android.annotation.TargetApi;
+import android.app.ActivityManager;
import android.content.Intent;
import android.os.Build;
@@ -29,14 +29,12 @@ import com.android.launcher3.statemanager.BaseState;
import com.android.launcher3.statemanager.StatefulActivity;
import com.android.launcher3.tracing.GestureStateProto;
import com.android.launcher3.tracing.SwipeHandlerProto;
-import com.android.quickstep.TopTaskTracker.CachedTaskInfo;
import com.android.quickstep.util.ActiveGestureLog;
import com.android.systemui.shared.recents.model.ThumbnailData;
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
import java.io.PrintWriter;
import java.util.ArrayList;
-import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;
@@ -124,6 +122,10 @@ public class GestureState implements RecentsAnimationCallbacks.RecentsAnimationL
public static final int STATE_RECENTS_ANIMATION_ENDED =
getFlagForIndex("STATE_RECENTS_ANIMATION_ENDED");
+ // Called when we create an overscroll window when swiping right to left on the most recent app
+ public static final int STATE_OVERSCROLL_WINDOW_CREATED =
+ getFlagForIndex("STATE_OVERSCROLL_WINDOW_CREATED");
+
// Called when RecentsView stops scrolling and settles on a TaskView.
public static final int STATE_RECENTS_SCROLLING_FINISHED =
getFlagForIndex("STATE_RECENTS_SCROLLING_FINISHED");
@@ -135,13 +137,13 @@ public class GestureState implements RecentsAnimationCallbacks.RecentsAnimationL
private final MultiStateCallback mStateCallback;
private final int mGestureId;
- private CachedTaskInfo mRunningTask;
+ private ActivityManager.RunningTaskInfo mRunningTask;
private GestureEndTarget mEndTarget;
private RemoteAnimationTargetCompat mLastAppearedTaskTarget;
private Set<Integer> mPreviouslyAppearedTaskIds = new HashSet<>();
private int mLastStartedTaskId = -1;
private RecentsAnimationController mRecentsAnimationController;
- private HashMap<Integer, ThumbnailData> mRecentsAnimationCanceledSnapshots;
+ private ThumbnailData mRecentsAnimationCanceledSnapshot;
/** The time when the swipe up gesture is triggered. */
private long mSwipeUpStartTimeMs;
@@ -231,7 +233,7 @@ public class GestureState implements RecentsAnimationCallbacks.RecentsAnimationL
/**
* @return the running task for this gesture.
*/
- public CachedTaskInfo getRunningTask() {
+ public ActivityManager.RunningTaskInfo getRunningTask() {
return mRunningTask;
}
@@ -239,13 +241,13 @@ public class GestureState implements RecentsAnimationCallbacks.RecentsAnimationL
* @return the running task id for this gesture.
*/
public int getRunningTaskId() {
- return mRunningTask != null ? mRunningTask.getTaskId() : -1;
+ return mRunningTask != null ? mRunningTask.taskId : -1;
}
/**
* Updates the running task for the gesture to be the given {@param runningTask}.
*/
- public void updateRunningTask(CachedTaskInfo runningTask) {
+ public void updateRunningTask(ActivityManager.RunningTaskInfo runningTask) {
mRunningTask = runningTask;
}
@@ -321,7 +323,7 @@ public class GestureState implements RecentsAnimationCallbacks.RecentsAnimationL
* user controlled gesture.
*/
public void setHandlingAtomicEvent(boolean handlingAtomicEvent) {
- mHandlingAtomicEvent = handlingAtomicEvent;
+ mHandlingAtomicEvent = true;
}
/**
@@ -356,16 +358,16 @@ public class GestureState implements RecentsAnimationCallbacks.RecentsAnimationL
}
@Override
- public void onRecentsAnimationCanceled(HashMap<Integer, ThumbnailData> thumbnailDatas) {
- mRecentsAnimationCanceledSnapshots = thumbnailDatas;
+ public void onRecentsAnimationCanceled(ThumbnailData thumbnailData) {
+ mRecentsAnimationCanceledSnapshot = thumbnailData;
mStateCallback.setState(STATE_RECENTS_ANIMATION_CANCELED);
mStateCallback.setState(STATE_RECENTS_ANIMATION_ENDED);
- if (mRecentsAnimationCanceledSnapshots != null) {
+ if (mRecentsAnimationCanceledSnapshot != null) {
// Clean up the screenshot to finalize the recents animation cancel
if (mRecentsAnimationController != null) {
mRecentsAnimationController.cleanupScreenshot();
}
- mRecentsAnimationCanceledSnapshots = null;
+ mRecentsAnimationCanceledSnapshot = null;
}
}
@@ -380,15 +382,10 @@ public class GestureState implements RecentsAnimationCallbacks.RecentsAnimationL
* while STATE_RECENTS_ANIMATION_CANCELED state is being set, and the caller is responsible for
* calling {@link RecentsAnimationController#cleanupScreenshot()}.
*/
- @Nullable
- HashMap<Integer, ThumbnailData> consumeRecentsAnimationCanceledSnapshot() {
- if (mRecentsAnimationCanceledSnapshots != null) {
- HashMap<Integer, ThumbnailData> data =
- new HashMap<Integer, ThumbnailData>(mRecentsAnimationCanceledSnapshots);
- mRecentsAnimationCanceledSnapshots = null;
- return data;
- }
- return null;
+ ThumbnailData consumeRecentsAnimationCanceledSnapshot() {
+ ThumbnailData data = mRecentsAnimationCanceledSnapshot;
+ mRecentsAnimationCanceledSnapshot = null;
+ return data;
}
void setSwipeUpStartTimeMs(long uptimeMs) {
diff --git a/quickstep/src/com/android/quickstep/ImageActionsApi.java b/quickstep/src/com/android/quickstep/ImageActionsApi.java
index 154848d224..8cb64c24b8 100644
--- a/quickstep/src/com/android/quickstep/ImageActionsApi.java
+++ b/quickstep/src/com/android/quickstep/ImageActionsApi.java
@@ -64,23 +64,20 @@ public class ImageActionsApi {
*/
@UiThread
public void shareWithExplicitIntent(@Nullable Rect crop, Intent intent) {
- addImageAndSendIntent(crop, intent, false, null /* exceptionCallback */);
+ addImageAndSendIntent(crop, intent, false);
}
/**
* Share the image this api was constructed with using the provided intent. The implementation
* should set the intent's data field to the URI pointing to the image.
- * @param exceptionCallback An optional callback to be called when the intent can't be resolved
*/
@UiThread
- public void shareAsDataWithExplicitIntent(@Nullable Rect crop, Intent intent,
- @Nullable Runnable exceptionCallback) {
- addImageAndSendIntent(crop, intent, true, exceptionCallback);
+ public void shareAsDataWithExplicitIntent(@Nullable Rect crop, Intent intent) {
+ addImageAndSendIntent(crop, intent, true);
}
@UiThread
- private void addImageAndSendIntent(@Nullable Rect crop, Intent intent, boolean setData,
- @Nullable Runnable exceptionCallback) {
+ private void addImageAndSendIntent(@Nullable Rect crop, Intent intent, boolean setData) {
if (mBitmapSupplier.get() == null) {
Log.e(TAG, "No snapshot available, not starting share.");
return;
@@ -95,7 +92,7 @@ public class ImageActionsApi {
intentForUri.putExtra(EXTRA_STREAM, uri);
}
return new Intent[]{intentForUri};
- }, TAG, exceptionCallback));
+ }, TAG));
}
/**
diff --git a/quickstep/src/com/android/quickstep/InputConsumer.java b/quickstep/src/com/android/quickstep/InputConsumer.java
index c455dc7462..0b2a057eb8 100644
--- a/quickstep/src/com/android/quickstep/InputConsumer.java
+++ b/quickstep/src/com/android/quickstep/InputConsumer.java
@@ -36,10 +36,9 @@ public interface InputConsumer {
int TYPE_SCREEN_PINNED = 1 << 6;
int TYPE_OVERVIEW_WITHOUT_FOCUS = 1 << 7;
int TYPE_RESET_GESTURE = 1 << 8;
- int TYPE_PROGRESS_DELEGATE = 1 << 9;
+ int TYPE_OVERSCROLL = 1 << 9;
int TYPE_SYSUI_OVERLAY = 1 << 10;
int TYPE_ONE_HANDED = 1 << 11;
- int TYPE_TASKBAR_STASH = 1 << 12;
String[] NAMES = new String[] {
"TYPE_NO_OP", // 0
@@ -51,10 +50,9 @@ public interface InputConsumer {
"TYPE_SCREEN_PINNED", // 6
"TYPE_OVERVIEW_WITHOUT_FOCUS", // 7
"TYPE_RESET_GESTURE", // 8
- "TYPE_PROGRESS_DELEGATE", // 9
+ "TYPE_OVERSCROLL", // 9
"TYPE_SYSUI_OVERLAY", // 10
"TYPE_ONE_HANDED", // 11
- "TYPE_TASKBAR_STASH", // 12
};
InputConsumer NO_OP = () -> TYPE_NO_OP;
@@ -99,8 +97,6 @@ public interface InputConsumer {
default void onMotionEvent(MotionEvent ev) { }
- default void onHoverEvent(MotionEvent ev) { }
-
default void onKeyEvent(KeyEvent ev) { }
default void onInputEvent(InputEvent ev) {
diff --git a/quickstep/src/com/android/quickstep/KtR.java b/quickstep/src/com/android/quickstep/KtR.java
deleted file mode 100644
index 758c6e08ef..0000000000
--- a/quickstep/src/com/android/quickstep/KtR.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2021 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.quickstep;
-
-import com.android.launcher3.R;
-
-/**
- * Bridge class to allow using resources in Kotlin.
- * <br/>
- * TODO(b/204069723) Can't use resources directly in Kotlin
- */
-public class KtR {
- public static final class id {
- public static int menu_option_layout = R.id.menu_option_layout;
- }
-
- public static final class dimen {
- public static int task_menu_spacing = R.dimen.task_menu_spacing;
- public static int task_menu_horizontal_padding = R.dimen.task_menu_horizontal_padding;
- public static int taskbar_ime_size = R.dimen.taskbar_ime_size;
- }
-
- public static final class layout {
- public static int task_menu_with_arrow = R.layout.task_menu_with_arrow;
- public static int task_view_menu_option = R.layout.task_view_menu_option;
- }
-}
diff --git a/quickstep/src/com/android/quickstep/LauncherActivityInterface.java b/quickstep/src/com/android/quickstep/LauncherActivityInterface.java
index c13b95f2ab..fb1391a309 100644
--- a/quickstep/src/com/android/quickstep/LauncherActivityInterface.java
+++ b/quickstep/src/com/android/quickstep/LauncherActivityInterface.java
@@ -44,9 +44,8 @@ import com.android.launcher3.statehandlers.DepthController.ClampedDepthProperty;
import com.android.launcher3.statemanager.StateManager;
import com.android.launcher3.taskbar.LauncherTaskbarUIController;
import com.android.launcher3.touch.PagedOrientationHandler;
-import com.android.launcher3.util.DisplayController;
-import com.android.launcher3.util.DisplayController.NavigationMode;
import com.android.quickstep.GestureState.GestureEndTarget;
+import com.android.quickstep.SysUINavigationMode.Mode;
import com.android.quickstep.util.ActivityInitListener;
import com.android.quickstep.util.AnimatorControllerWithResistance;
import com.android.quickstep.util.LayoutUtils;
@@ -72,9 +71,8 @@ public final class LauncherActivityInterface extends
@Override
public int getSwipeUpDestinationAndLength(DeviceProfile dp, Context context, Rect outRect,
PagedOrientationHandler orientationHandler) {
- calculateTaskSize(context, dp, outRect);
- if (dp.isVerticalBarLayout()
- && DisplayController.getNavigationMode(context) != NavigationMode.NO_BUTTON) {
+ calculateTaskSize(context, dp, outRect, orientationHandler);
+ if (dp.isVerticalBarLayout() && SysUINavigationMode.getMode(context) != Mode.NO_BUTTON) {
return dp.isSeascape() ? outRect.left : (dp.widthPx - outRect.right);
} else {
return LayoutUtils.getShelfTrackingDistance(context, dp, orientationHandler);
@@ -132,10 +130,11 @@ public final class LauncherActivityInterface extends
pa.addFloat(getDepthController(),
new ClampedDepthProperty(fromDepthRatio, toDepthRatio),
fromDepthRatio, toDepthRatio, LINEAR);
+
}
};
- BaseQuickstepLauncher launcher = factory.initBackgroundStateUI();
+ BaseQuickstepLauncher launcher = factory.initUI();
// Since all apps is not visible, we can safely reset the scroll position.
// This ensures then the next swipe up to all-apps starts from scroll 0.
launcher.getAppsView().reset(false /* animate */);
@@ -174,8 +173,7 @@ public final class LauncherActivityInterface extends
}
@Nullable
- @Override
- public LauncherTaskbarUIController getTaskbarController() {
+ private LauncherTaskbarUIController getTaskbarController() {
BaseQuickstepLauncher launcher = getCreatedActivity();
if (launcher == null) {
return null;
@@ -191,7 +189,7 @@ public final class LauncherActivityInterface extends
launcher != null && launcher.getStateManager().getState().overviewUi
? launcher.getOverviewPanel() : null;
if (recentsView == null || (!launcher.hasBeenResumed()
- && recentsView.getRunningTaskViewId() == -1)) {
+ && recentsView.getRunningTaskId() == -1)) {
// If live tile has ended, return null.
return null;
}
@@ -280,7 +278,6 @@ public final class LauncherActivityInterface extends
@Override
public void closeOverlay() {
- super.closeOverlay();
Launcher launcher = getCreatedActivity();
if (launcher == null) {
return;
@@ -291,23 +288,25 @@ public final class LauncherActivityInterface extends
} else {
om.hideOverlay(150);
}
- LauncherTaskbarUIController taskbarController = getTaskbarController();
- if (taskbarController != null) {
- taskbarController.hideEdu();
- }
+ }
+
+ @Override
+ void onOverviewServiceBound() {
+ final BaseQuickstepLauncher activity = getCreatedActivity();
+ if (activity == null) return;
+ activity.getAppTransitionManager().registerRemoteTransitions();
}
@Override
public @Nullable Animator getParallelAnimationToLauncher(GestureEndTarget endTarget,
- long duration, RecentsAnimationCallbacks callbacks) {
+ long duration) {
LauncherTaskbarUIController uiController = getTaskbarController();
- Animator superAnimator = super.getParallelAnimationToLauncher(
- endTarget, duration, callbacks);
- if (uiController == null || callbacks == null) {
+ Animator superAnimator = super.getParallelAnimationToLauncher(endTarget, duration);
+ if (uiController == null) {
return superAnimator;
}
LauncherState toState = stateFromGestureEndTarget(endTarget);
- Animator taskbarAnimator = uiController.createAnimToLauncher(toState, callbacks, duration);
+ Animator taskbarAnimator = uiController.createAnimToLauncher(toState, duration);
if (superAnimator == null) {
return taskbarAnimator;
} else {
@@ -329,8 +328,7 @@ public final class LauncherActivityInterface extends
if (uiController == null) {
return super.deferStartingActivity(deviceState, ev);
}
- return uiController.isEventOverAnyTaskbarItem(ev)
- || super.deferStartingActivity(deviceState, ev);
+ return uiController.isEventOverAnyTaskbarItem(ev);
}
@Override
diff --git a/quickstep/src/com/android/quickstep/LauncherBackAnimationController.java b/quickstep/src/com/android/quickstep/LauncherBackAnimationController.java
deleted file mode 100644
index fd9f922005..0000000000
--- a/quickstep/src/com/android/quickstep/LauncherBackAnimationController.java
+++ /dev/null
@@ -1,339 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.quickstep;
-
-import static com.android.launcher3.AbstractFloatingView.TYPE_REBIND_SAFE;
-import static com.android.launcher3.BaseActivity.INVISIBLE_ALL;
-import static com.android.launcher3.BaseActivity.INVISIBLE_BY_PENDING_FLAGS;
-import static com.android.launcher3.BaseActivity.PENDING_INVISIBLE_BY_WALLPAPER_ANIMATION;
-
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.AnimatorSet;
-import android.animation.ValueAnimator;
-import android.graphics.Matrix;
-import android.graphics.PointF;
-import android.graphics.Rect;
-import android.graphics.RectF;
-import android.os.Handler;
-import android.util.Pair;
-import android.view.RemoteAnimationTarget;
-import android.view.SurfaceControl;
-import android.view.animation.AnimationUtils;
-import android.view.animation.Interpolator;
-import android.window.BackEvent;
-import android.window.IOnBackInvokedCallback;
-
-import com.android.launcher3.AbstractFloatingView;
-import com.android.launcher3.BaseQuickstepLauncher;
-import com.android.launcher3.QuickstepTransitionManager;
-import com.android.launcher3.R;
-import com.android.launcher3.Utilities;
-import com.android.quickstep.util.RectFSpringAnim;
-import com.android.systemui.shared.system.QuickStepContract;
-import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
-import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat;
-
-/**
- * Controls the animation of swiping back and returning to launcher.
- *
- * This is a two part animation. The first part is an animation that tracks gesture location to
- * scale and move the leaving app window. Once the gesture is committed, the second part takes over
- * the app window and plays the rest of app close transitions in one go.
- *
- * This animation is used only for apps that enable back dispatching via
- * {@link android.window.OnBackInvokedDispatcher}. The controller registers
- * an {@link IOnBackInvokedCallback} with WM Shell and receives back dispatches when a back
- * navigation to launcher starts.
- *
- * Apps using the legacy back dispatching will keep triggering the WALLPAPER_OPEN remote
- * transition registered in {@link QuickstepTransitionManager}.
- *
- */
-public class LauncherBackAnimationController {
- private static final int CANCEL_TRANSITION_DURATION = 233;
- private static final float MIN_WINDOW_SCALE = 0.7f;
- private final QuickstepTransitionManager mQuickstepTransitionManager;
- private final Matrix mTransformMatrix = new Matrix();
- /** The window position at the beginning of the back animation. */
- private final Rect mStartRect = new Rect();
- /** The window position when the back gesture is cancelled. */
- private final RectF mCancelRect = new RectF();
- /** The current window position. */
- private final RectF mCurrentRect = new RectF();
- private final BaseQuickstepLauncher mLauncher;
- private final int mWindowScaleMarginX;
- /** Max window translation in the Y axis. */
- private final int mWindowMaxDeltaY;
- private final float mWindowScaleEndCornerRadius;
- private final float mWindowScaleStartCornerRadius;
- private final Interpolator mCancelInterpolator;
- private final PointF mInitialTouchPos = new PointF();
-
- private RemoteAnimationTargetCompat mBackTarget;
- private SurfaceControl.Transaction mTransaction = new SurfaceControl.Transaction();
- private boolean mSpringAnimationInProgress = false;
- private boolean mAnimatorSetInProgress = false;
- private float mBackProgress = 0;
- private boolean mBackInProgress = false;
- private IOnBackInvokedCallback mBackCallback;
-
- public LauncherBackAnimationController(
- BaseQuickstepLauncher launcher,
- QuickstepTransitionManager quickstepTransitionManager) {
- mLauncher = launcher;
- mQuickstepTransitionManager = quickstepTransitionManager;
- mWindowScaleEndCornerRadius = QuickStepContract.supportsRoundedCornersOnWindows(
- mLauncher.getResources())
- ? mLauncher.getResources().getDimensionPixelSize(
- R.dimen.swipe_back_window_corner_radius)
- : 0;
- mWindowScaleStartCornerRadius = QuickStepContract.getWindowCornerRadius(mLauncher);
- mWindowScaleMarginX = mLauncher.getResources().getDimensionPixelSize(
- R.dimen.swipe_back_window_scale_x_margin);
- mWindowMaxDeltaY = mLauncher.getResources().getDimensionPixelSize(
- R.dimen.swipe_back_window_max_delta_y);
- mCancelInterpolator =
- AnimationUtils.loadInterpolator(mLauncher, R.interpolator.back_cancel);
- }
-
- /**
- * Registers {@link IOnBackInvokedCallback} to receive back dispatches from shell.
- * @param handler Handler to the thread to run the animations on.
- */
- public void registerBackCallbacks(Handler handler) {
- mBackCallback = new IOnBackInvokedCallback.Stub() {
- @Override
- public void onBackCancelled() {
- handler.post(() -> resetPositionAnimated());
- }
-
- @Override
- public void onBackInvoked() {
- handler.post(() -> startTransition());
- }
-
- @Override
- public void onBackProgressed(BackEvent backEvent) {
- mBackProgress = backEvent.getProgress();
- // TODO: Update once the interpolation curve spec is finalized.
- mBackProgress =
- 1 - (1 - mBackProgress) * (1 - mBackProgress) * (1
- - mBackProgress);
- if (!mBackInProgress) {
- startBack(backEvent);
- } else {
- updateBackProgress(mBackProgress, backEvent);
- }
- }
-
- @Override
- public void onBackStarted() { }
- };
- SystemUiProxy.INSTANCE.get(mLauncher).setBackToLauncherCallback(mBackCallback);
- }
-
- private void resetPositionAnimated() {
- ValueAnimator cancelAnimator = ValueAnimator.ofFloat(0, 1);
- mCancelRect.set(mCurrentRect);
- cancelAnimator.setDuration(CANCEL_TRANSITION_DURATION);
- cancelAnimator.setInterpolator(mCancelInterpolator);
- cancelAnimator.addUpdateListener(
- animation -> {
- updateCancelProgress((float) animation.getAnimatedValue());
- });
- cancelAnimator.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- finishAnimation();
- }
- });
- cancelAnimator.start();
- }
-
- /** Unregisters the back to launcher callback in shell. */
- public void unregisterBackCallbacks() {
- if (mBackCallback != null) {
- SystemUiProxy.INSTANCE.get(mLauncher).clearBackToLauncherCallback(mBackCallback);
- }
- mBackCallback = null;
- }
-
- private void startBack(BackEvent backEvent) {
- mBackInProgress = true;
- RemoteAnimationTarget appTarget = backEvent.getDepartingAnimationTarget();
-
- if (appTarget == null) {
- return;
- }
-
- mTransaction.show(appTarget.leash).apply();
- mTransaction.setAnimationTransaction();
- mBackTarget = new RemoteAnimationTargetCompat(appTarget);
- mInitialTouchPos.set(backEvent.getTouchX(), backEvent.getTouchY());
-
- // TODO(b/218916755): Offset start rectangle in multiwindow mode.
- mStartRect.set(mBackTarget.windowConfiguration.getMaxBounds());
- }
-
- private void updateBackProgress(float progress, BackEvent event) {
- if (mBackTarget == null) {
- return;
- }
- float screenWidth = mStartRect.width();
- float screenHeight = mStartRect.height();
- float dX = Math.abs(event.getTouchX() - mInitialTouchPos.x);
- // The 'follow width' is the width of the window if it completely matches
- // the gesture displacement.
- float followWidth = screenWidth - dX;
- // The 'progress width' is the width of the window if it strictly linearly interpolates
- // to minimum scale base on progress.
- float progressWidth = Utilities.mapRange(progress, 1, MIN_WINDOW_SCALE) * screenWidth;
- // The final width is derived from interpolating between the follow with and progress width
- // using gesture progress.
- float width = Utilities.mapRange(progress, followWidth, progressWidth);
- float height = screenHeight / screenWidth * width;
- float deltaYRatio = (event.getTouchY() - mInitialTouchPos.y) / screenHeight;
- // Base the window movement in the Y axis on the touch movement in the Y axis.
- float deltaY = (float) Math.sin(deltaYRatio * Math.PI * 0.5f) * mWindowMaxDeltaY;
- // Move the window along the Y axis.
- float top = (screenHeight - height) * 0.5f + deltaY;
- // Move the window along the X axis.
- float left = event.getSwipeEdge() == BackEvent.EDGE_RIGHT
- ? progress * mWindowScaleMarginX
- : screenWidth - progress * mWindowScaleMarginX - width;
-
- mCurrentRect.set(left, top, left + width, top + height);
- float cornerRadius = Utilities.mapRange(
- progress, mWindowScaleStartCornerRadius, mWindowScaleEndCornerRadius);
- applyTransform(mCurrentRect, cornerRadius);
- }
-
- private void updateCancelProgress(float progress) {
- if (mBackTarget == null) {
- return;
- }
- mCurrentRect.set(
- Utilities.mapRange(progress, mCancelRect.left, mStartRect.left),
- Utilities.mapRange(progress, mCancelRect.top, mStartRect.top),
- Utilities.mapRange(progress, mCancelRect.right, mStartRect.right),
- Utilities.mapRange(progress, mCancelRect.bottom, mStartRect.bottom));
-
- float endCornerRadius = Utilities.mapRange(
- mBackProgress, mWindowScaleStartCornerRadius, mWindowScaleEndCornerRadius);
- float cornerRadius = Utilities.mapRange(
- progress, endCornerRadius, mWindowScaleStartCornerRadius);
- applyTransform(mCurrentRect, cornerRadius);
- }
-
- /** Transform the target window to match the target rect. */
- private void applyTransform(RectF targetRect, float cornerRadius) {
- SyncRtSurfaceTransactionApplierCompat.SurfaceParams.Builder builder =
- new SyncRtSurfaceTransactionApplierCompat.SurfaceParams.Builder(mBackTarget.leash);
- final float scale = targetRect.width() / mStartRect.width();
- mTransformMatrix.reset();
- mTransformMatrix.setScale(scale, scale);
- mTransformMatrix.postTranslate(targetRect.left, targetRect.top);
- builder.withMatrix(mTransformMatrix)
- .withWindowCrop(mStartRect)
- .withCornerRadius(cornerRadius);
- SyncRtSurfaceTransactionApplierCompat.SurfaceParams surfaceParams = builder.build();
-
- if (surfaceParams.surface.isValid()) {
- surfaceParams.applyTo(mTransaction);
- }
- mTransaction.apply();
- }
-
- private void startTransition() {
- if (mBackTarget == null) {
- // Trigger transition system instead of custom transition animation.
- finishAnimation();
- return;
- }
- if (mLauncher.isDestroyed()) {
- return;
- }
- // TODO: Catch the moment when launcher becomes visible after the top app un-occludes
- // launcher and start animating afterwards. Currently we occasionally get a flicker from
- // animating when launcher is still invisible.
- if (mLauncher.hasSomeInvisibleFlag(PENDING_INVISIBLE_BY_WALLPAPER_ANIMATION)) {
- mLauncher.addForceInvisibleFlag(INVISIBLE_BY_PENDING_FLAGS);
- mLauncher.getStateManager().moveToRestState();
- }
-
- // Explicitly close opened floating views (which is typically called from
- // Launcher#onResumed, but in the predictive back flow launcher is not resumed until
- // the transition is fully finished.)
- AbstractFloatingView.closeAllOpenViewsExcept(mLauncher, false, TYPE_REBIND_SAFE);
- float cornerRadius = Utilities.mapRange(
- mBackProgress, mWindowScaleStartCornerRadius, mWindowScaleEndCornerRadius);
- Pair<RectFSpringAnim, AnimatorSet> pair =
- mQuickstepTransitionManager.createWallpaperOpenAnimations(
- new RemoteAnimationTargetCompat[]{mBackTarget},
- new RemoteAnimationTargetCompat[]{},
- false /* fromUnlock */,
- mCurrentRect,
- cornerRadius);
- startTransitionAnimations(pair.first, pair.second);
- mLauncher.clearForceInvisibleFlag(INVISIBLE_ALL);
- }
-
- private void finishAnimation() {
- mBackTarget = null;
- mBackInProgress = false;
- mBackProgress = 0;
- mTransformMatrix.reset();
- mCancelRect.setEmpty();
- mCurrentRect.setEmpty();
- mStartRect.setEmpty();
- mInitialTouchPos.set(0, 0);
- mAnimatorSetInProgress = false;
- mSpringAnimationInProgress = false;
- SystemUiProxy.INSTANCE.get(mLauncher).onBackToLauncherAnimationFinished();
- }
-
- private void startTransitionAnimations(RectFSpringAnim springAnim, AnimatorSet anim) {
- mAnimatorSetInProgress = anim != null;
- mSpringAnimationInProgress = springAnim != null;
- if (springAnim != null) {
- springAnim.addAnimatorListener(
- new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- mSpringAnimationInProgress = false;
- tryFinishBackAnimation();
- }
- }
- );
- }
- anim.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- mAnimatorSetInProgress = false;
- tryFinishBackAnimation();
- }
- });
- anim.start();
- }
-
- private void tryFinishBackAnimation() {
- if (!mSpringAnimationInProgress && !mAnimatorSetInProgress) {
- finishAnimation();
- }
- }
-}
diff --git a/quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java b/quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java
index 50d1244c81..19cad53bb1 100644
--- a/quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java
+++ b/quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java
@@ -15,15 +15,25 @@
*/
package com.android.quickstep;
+import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY;
+import static com.android.launcher3.LauncherAnimUtils.VIEW_TRANSLATE_Y;
import static com.android.launcher3.LauncherState.NORMAL;
+import static com.android.launcher3.Utilities.boundToRange;
+import static com.android.launcher3.Utilities.dpToPx;
import static com.android.launcher3.Utilities.mapBoundToRange;
import static com.android.launcher3.anim.Interpolators.EXAGGERATED_EASE;
import static com.android.launcher3.anim.Interpolators.LINEAR;
+import static com.android.launcher3.config.FeatureFlags.PROTOTYPE_APP_CLOSE;
import static com.android.launcher3.model.data.ItemInfo.NO_MATCHING_ID;
import static com.android.launcher3.views.FloatingIconView.SHAPE_PROGRESS_DURATION;
import static com.android.launcher3.views.FloatingIconView.getFloatingIconView;
+import static java.lang.Math.round;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
+import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Rect;
import android.graphics.RectF;
@@ -36,18 +46,27 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.android.launcher3.BaseQuickstepLauncher;
+import com.android.launcher3.Hotseat;
import com.android.launcher3.LauncherState;
+import com.android.launcher3.R;
+import com.android.launcher3.Workspace;
import com.android.launcher3.anim.AnimatorPlaybackController;
+import com.android.launcher3.anim.SpringAnimationBuilder;
+import com.android.launcher3.dragndrop.DragLayer;
import com.android.launcher3.states.StateAnimationConfig;
+import com.android.launcher3.util.DynamicResource;
import com.android.launcher3.util.ObjectWrapper;
import com.android.launcher3.views.FloatingIconView;
import com.android.launcher3.views.FloatingView;
import com.android.launcher3.widget.LauncherAppWidgetHostView;
+import com.android.quickstep.util.AppCloseConfig;
import com.android.quickstep.util.RectFSpringAnim;
import com.android.quickstep.util.StaggeredWorkspaceAnim;
+import com.android.quickstep.util.WorkspaceRevealAnim;
import com.android.quickstep.views.FloatingWidgetView;
import com.android.quickstep.views.RecentsView;
import com.android.quickstep.views.TaskView;
+import com.android.systemui.plugins.ResourceProvider;
import com.android.systemui.shared.system.InputConsumerController;
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
@@ -87,11 +106,9 @@ public class LauncherSwipeHandlerV2 extends
boolean canUseWorkspaceView = workspaceView != null && workspaceView.isAttachedToWindow();
mActivity.getRootView().setForceHideBackArrow(true);
- if (!TaskAnimationManager.ENABLE_SHELL_TRANSITIONS) {
- mActivity.setHintUserWillBeActive();
- }
+ mActivity.setHintUserWillBeActive();
- if (!canUseWorkspaceView || appCanEnterPip || mIsSwipeForStagedSplit) {
+ if (!canUseWorkspaceView || appCanEnterPip) {
return new LauncherHomeAnimationFactory();
}
if (workspaceView instanceof LauncherAppWidgetHostView) {
@@ -102,6 +119,8 @@ public class LauncherSwipeHandlerV2 extends
}
private HomeAnimationFactory createIconHomeAnimationFactory(View workspaceView) {
+ final ResourceProvider rp = DynamicResource.provider(mActivity);
+ final float transY = dpToPx(rp.getFloat(R.dimen.swipe_up_trans_y_dp));
RectF iconLocation = new RectF();
FloatingIconView floatingIconView = getFloatingIconView(mActivity, workspaceView,
true /* hideOriginal */, iconLocation, false /* isOpening */);
@@ -112,15 +131,13 @@ public class LauncherSwipeHandlerV2 extends
return new FloatingViewHomeAnimationFactory(floatingIconView) {
- @Nullable
- @Override
- protected View getViewIgnoredInWorkspaceRevealAnimation() {
- return workspaceView;
- }
+ // There is a delay in loading the icon, so we need to keep the window
+ // opaque until it is ready.
+ private boolean mIsFloatingIconReady = false;
- @NonNull
@Override
public RectF getWindowTargetRect() {
+ super.getWindowTargetRect();
return iconLocation;
}
@@ -133,9 +150,24 @@ public class LauncherSwipeHandlerV2 extends
}
@Override
- public void update(RectF currentRect, float progress, float radius) {
- super.update(currentRect, progress, radius);
- floatingIconView.update(1f /* alpha */, 255 /* fgAlpha */, currentRect, progress,
+ public boolean keepWindowOpaque() {
+ if (mIsFloatingIconReady || floatingIconView.isVisibleToUser()) {
+ mIsFloatingIconReady = true;
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public void update(@Nullable AppCloseConfig config, RectF currentRect,
+ float progress, float radius) {
+ super.update(config, currentRect, progress, radius);
+ int fgAlpha = 255;
+ if (config != null && PROTOTYPE_APP_CLOSE.get()) {
+ progress = config.getInterpolatedProgress();
+ fgAlpha = config.getFgAlpha();
+ }
+ floatingIconView.update(1f, fgAlpha, currentRect, progress,
windowAlphaThreshold, radius, false);
}
};
@@ -147,16 +179,14 @@ public class LauncherSwipeHandlerV2 extends
final float floatingWidgetAlpha = isTargetTranslucent ? 0 : 1;
RectF backgroundLocation = new RectF();
Rect crop = new Rect();
- // We can assume there is only one remote target here because staged split never animates
- // into the app icon, only into the homescreen
- mRemoteTargetHandles[0].getTaskViewSimulator().getCurrentCropRect().roundOut(crop);
+ mTaskViewSimulator.getCurrentCropRect().roundOut(crop);
Size windowSize = new Size(crop.width(), crop.height());
int fallbackBackgroundColor =
FloatingWidgetView.getDefaultBackgroundColor(mContext, runningTaskTarget);
FloatingWidgetView floatingWidgetView = FloatingWidgetView.getFloatingWidgetView(mActivity,
hostView, backgroundLocation, windowSize,
- mRemoteTargetHandles[0].getTaskViewSimulator().getCurrentCornerRadius(),
- isTargetTranslucent, fallbackBackgroundColor);
+ mTaskViewSimulator.getCurrentCornerRadius(), isTargetTranslucent,
+ fallbackBackgroundColor);
return new FloatingViewHomeAnimationFactory(floatingWidgetView) {
@@ -187,8 +217,14 @@ public class LauncherSwipeHandlerV2 extends
}
@Override
- public void update(RectF currentRect, float progress, float radius) {
- super.update(currentRect, progress, radius);
+ public boolean keepWindowOpaque() {
+ return false;
+ }
+
+ @Override
+ public void update(@Nullable AppCloseConfig config, RectF currentRect, float progress,
+ float radius) {
+ super.update(config, currentRect, progress, radius);
final float fallbackBackgroundAlpha =
1 - mapBoundToRange(progress, 0.8f, 1, 0, 1, EXAGGERATED_EASE);
final float foregroundAlpha =
@@ -231,30 +267,128 @@ public class LauncherSwipeHandlerV2 extends
}
}
- return mActivity.getFirstMatchForAppClose(launchCookieItemId,
+ return mActivity.getWorkspace().getFirstMatchForAppClose(launchCookieItemId,
runningTaskView.getTask().key.getComponent().getPackageName(),
- UserHandle.of(runningTaskView.getTask().key.userId),
- false /* supportsAllAppsState */);
+ UserHandle.of(runningTaskView.getTask().key.userId));
}
@Override
protected void finishRecentsControllerToHome(Runnable callback) {
- mRecentsView.cleanupRemoteTargets();
mRecentsAnimationController.finish(
true /* toRecents */, callback, true /* sendUserLeaveHint */);
}
private class FloatingViewHomeAnimationFactory extends LauncherHomeAnimationFactory {
+ private final float mTransY;
private final FloatingView mFloatingView;
+ private ValueAnimator mBounceBackAnimator;
+ private final AnimatorSet mWorkspaceReveal;
FloatingViewHomeAnimationFactory(FloatingView floatingView) {
mFloatingView = floatingView;
+
+ ResourceProvider rp = DynamicResource.provider(mActivity);
+ mTransY = dpToPx(rp.getFloat(R.dimen.swipe_up_trans_y_dp));
+
+ mWorkspaceReveal = PROTOTYPE_APP_CLOSE.get()
+ ? new WorkspaceRevealAnim(mActivity, true /* animateScrim */).getAnimators()
+ : null;
+ }
+
+ @Override
+ public @NonNull RectF getWindowTargetRect() {
+ if (PROTOTYPE_APP_CLOSE.get()) {
+ // We want the target rect to be at this offset position, so that all
+ // launcher content can spring back upwards.
+ mFloatingView.setPositionOffsetY(mTransY);
+ }
+ return super.getWindowTargetRect();
+ }
+
+ @Override
+ public boolean shouldPlayAtomicWorkspaceReveal() {
+ return false;
+ }
+
+ @Override
+ public void update(@Nullable AppCloseConfig config, RectF currentRect, float progress,
+ float radius) {
+ if (config != null && PROTOTYPE_APP_CLOSE.get()) {
+ DragLayer dl = mActivity.getDragLayer();
+ float translationY = config.getWorkspaceTransY();
+ dl.setTranslationY(translationY);
+
+ long duration = mWorkspaceReveal.getDuration();
+ long playTime = boundToRange(round(duration * progress), 0, duration);
+ mWorkspaceReveal.setCurrentPlayTime(playTime);
+ }
+ }
+
+ protected void bounceBackToRestingPosition() {
+ final float startValue = mTransY;
+ final float endValue = 0;
+ // Ensures the velocity is always aligned with the direction.
+ float pixelPerSecond = Math.abs(mSwipeVelocity) * Math.signum(endValue - mTransY);
+
+ DragLayer dl = mActivity.getDragLayer();
+ Workspace workspace = mActivity.getWorkspace();
+ Hotseat hotseat = mActivity.getHotseat();
+
+ ResourceProvider rp = DynamicResource.provider(mActivity);
+ ValueAnimator springTransY = new SpringAnimationBuilder(dl.getContext())
+ .setStiffness(rp.getFloat(R.dimen.swipe_up_trans_y_stiffness))
+ .setDampingRatio(rp.getFloat(R.dimen.swipe_up_trans_y_damping))
+ .setMinimumVisibleChange(1f)
+ .setStartValue(startValue)
+ .setEndValue(endValue)
+ .setStartVelocity(pixelPerSecond)
+ .build(dl, VIEW_TRANSLATE_Y);
+ springTransY.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ dl.setTranslationY(0f);
+ dl.setAlpha(1f);
+ SCALE_PROPERTY.set(workspace, 1f);
+ SCALE_PROPERTY.set(hotseat, 1f);
+ }
+ });
+
+ mBounceBackAnimator = springTransY;
+ mBounceBackAnimator.start();
+ }
+
+ @Override
+ public void setAnimation(RectFSpringAnim anim) {
+ if (PROTOTYPE_APP_CLOSE.get()) {
+ // Use a spring to put drag layer translation back to 0.
+ anim.addAnimatorListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mFloatingView.setPositionOffsetY(0);
+ bounceBackToRestingPosition();
+ }
+ });
+
+ // Will be updated manually below so that the two animations are in sync.
+ mWorkspaceReveal.start();
+ mWorkspaceReveal.pause();
+
+ anim.addAnimatorListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mWorkspaceReveal.end();
+ }
+ });
+ }
}
@Override
public void onCancel() {
mFloatingView.fastFinish();
+ if (mBounceBackAnimator != null) {
+ mBounceBackAnimator.cancel();
+ }
}
}
@@ -281,9 +415,18 @@ public class LauncherSwipeHandlerV2 extends
@Override
public void playAtomicAnimation(float velocity) {
- new StaggeredWorkspaceAnim(mActivity, velocity, true /* animateOverviewScrim */,
- getViewIgnoredInWorkspaceRevealAnimation())
- .start();
+ if (!PROTOTYPE_APP_CLOSE.get()) {
+ new StaggeredWorkspaceAnim(mActivity, velocity, true /* animateOverviewScrim */,
+ getViewIgnoredInWorkspaceRevealAnimation())
+ .start();
+ } else if (shouldPlayAtomicWorkspaceReveal()) {
+ new WorkspaceRevealAnim(mActivity, true).start();
+ }
+ }
+
+ @Override
+ public boolean supportSwipePipToHome() {
+ return true;
}
}
}
diff --git a/quickstep/src/com/android/quickstep/OrientationRectF.java b/quickstep/src/com/android/quickstep/OrientationRectF.java
deleted file mode 100644
index aa01b05b47..0000000000
--- a/quickstep/src/com/android/quickstep/OrientationRectF.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Copyright (C) 2021 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.quickstep;
-
-import static com.android.launcher3.states.RotationHelper.deltaRotation;
-import static com.android.quickstep.util.RecentsOrientedState.postDisplayRotation;
-
-import android.graphics.Matrix;
-import android.graphics.RectF;
-import android.util.Log;
-import android.view.MotionEvent;
-
-public class OrientationRectF extends RectF {
-
- private static final String TAG = "OrientationRectF";
- private static final boolean DEBUG = false;
-
- private final int mRotation;
- private final float mHeight;
- private final float mWidth;
-
- private final Matrix mTmpMatrix = new Matrix();
- private final float[] mTmpPoint = new float[2];
-
- public OrientationRectF(float left, float top, float right, float bottom, int rotation) {
- super(left, top, right, bottom);
- mRotation = rotation;
- mHeight = bottom;
- mWidth = right;
- }
-
- @Override
- public String toString() {
- String s = super.toString();
- s += " rotation: " + mRotation;
- return s;
- }
-
- @Override
- public boolean contains(float x, float y) {
- // Mark bottom right as included in the Rect (copied from Rect src, added "=" in "<=")
- return left < right && top < bottom // check for empty first
- && x >= left && x <= right && y >= top && y <= bottom;
- }
-
- public boolean applyTransformFromRotation(MotionEvent event, int currentRotation,
- boolean forceTransform) {
- return applyTransform(event, deltaRotation(currentRotation, mRotation), forceTransform);
- }
-
- public boolean applyTransformToRotation(MotionEvent event, int currentRotation,
- boolean forceTransform) {
- return applyTransform(event, deltaRotation(mRotation, currentRotation), forceTransform);
- }
-
- public boolean applyTransform(MotionEvent event, int deltaRotation, boolean forceTransform) {
- mTmpMatrix.reset();
- postDisplayRotation(deltaRotation, mHeight, mWidth, mTmpMatrix);
- if (forceTransform) {
- if (DEBUG) {
- Log.d(TAG, "Transforming rotation due to forceTransform, "
- + "deltaRotation: " + deltaRotation
- + "mRotation: " + mRotation
- + " this: " + this);
- }
- event.applyTransform(mTmpMatrix);
- return true;
- }
- mTmpPoint[0] = event.getX();
- mTmpPoint[1] = event.getY();
- mTmpMatrix.mapPoints(mTmpPoint);
-
- if (DEBUG) {
- Log.d(TAG, "original: " + event.getX() + ", " + event.getY()
- + " new: " + mTmpPoint[0] + ", " + mTmpPoint[1]
- + " rect: " + this + " forceTransform: " + forceTransform
- + " contains: " + contains(mTmpPoint[0], mTmpPoint[1])
- + " this: " + this);
- }
-
- if (contains(mTmpPoint[0], mTmpPoint[1])) {
- event.applyTransform(mTmpMatrix);
- return true;
- }
- return false;
- }
-
- int getRotation() {
- return mRotation;
- }
-}
diff --git a/quickstep/src/com/android/quickstep/OrientationTouchTransformer.java b/quickstep/src/com/android/quickstep/OrientationTouchTransformer.java
index 895cf89382..35a851ab65 100644
--- a/quickstep/src/com/android/quickstep/OrientationTouchTransformer.java
+++ b/quickstep/src/com/android/quickstep/OrientationTouchTransformer.java
@@ -23,8 +23,10 @@ import static android.view.MotionEvent.ACTION_POINTER_DOWN;
import static android.view.MotionEvent.ACTION_UP;
import static com.android.launcher3.states.RotationHelper.deltaRotation;
+import static com.android.quickstep.util.RecentsOrientedState.postDisplayRotation;
import android.content.res.Resources;
+import android.graphics.Matrix;
import android.graphics.Point;
import android.graphics.RectF;
import android.util.Log;
@@ -34,34 +36,74 @@ import android.view.Surface;
import com.android.launcher3.R;
import com.android.launcher3.ResourceUtils;
import com.android.launcher3.util.DisplayController.Info;
-import com.android.launcher3.util.DisplayController.NavigationMode;
-import com.android.launcher3.util.window.CachedDisplayInfo;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;
+import java.util.Objects;
/**
* Maintains state for supporting nav bars and tracking their gestures in multiple orientations.
- * See {@link OrientationRectF#applyTransformToRotation(MotionEvent, int, boolean)} for
- * transformation of MotionEvents from one orientation's coordinate space to another's.
+ * See {@link OrientationRectF#applyTransform(MotionEvent, boolean)} for transformation of
+ * MotionEvents from one orientation's coordinate space to another's.
*
* This class only supports single touch/pointer gesture tracking for touches started in a supported
* nav bar region.
*/
class OrientationTouchTransformer {
+ private static class CurrentDisplay {
+ public Point size;
+ public int rotation;
+
+ CurrentDisplay() {
+ this.size = new Point(0, 0);
+ this.rotation = 0;
+ }
+
+ CurrentDisplay(Point size, int rotation) {
+ this.size = size;
+ this.rotation = rotation;
+ }
+
+ @Override
+ public String toString() {
+ return "CurrentDisplay:"
+ + " rotation: " + rotation
+ + " size: " + size;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ CurrentDisplay display = (CurrentDisplay) o;
+ if (rotation != display.rotation) return false;
+
+ return Objects.equals(size, display.size);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(size, rotation);
+ }
+ };
+
private static final String TAG = "OrientationTouchTransformer";
private static final boolean DEBUG = false;
private static final int QUICKSTEP_ROTATION_UNINITIALIZED = -1;
- private final Map<CachedDisplayInfo, OrientationRectF> mSwipeTouchRegions =
- new HashMap<CachedDisplayInfo, OrientationRectF>();
+ private final Matrix mTmpMatrix = new Matrix();
+ private final float[] mTmpPoint = new float[2];
+
+ private final Map<CurrentDisplay, OrientationRectF> mSwipeTouchRegions =
+ new HashMap<CurrentDisplay, OrientationRectF>();
private final RectF mAssistantLeftRegion = new RectF();
private final RectF mAssistantRightRegion = new RectF();
private final RectF mOneHandedModeRegion = new RectF();
- private CachedDisplayInfo mCachedDisplayInfo = new CachedDisplayInfo();
+ private CurrentDisplay mCurrentDisplay = new CurrentDisplay();
private int mNavBarGesturalHeight;
private final int mNavBarLargerGesturalHeight;
private boolean mEnableMultipleRegions;
@@ -75,7 +117,7 @@ class OrientationTouchTransformer {
* mQuickstepStartingRotation only updates when device rotation matches touch rotation.
*/
private int mActiveTouchRotation;
- private NavigationMode mMode;
+ private SysUINavigationMode.Mode mMode;
private QuickStepContractInfo mContractInfo;
/**
@@ -98,7 +140,7 @@ class OrientationTouchTransformer {
}
- OrientationTouchTransformer(Resources resources, NavigationMode mode,
+ OrientationTouchTransformer(Resources resources, SysUINavigationMode.Mode mode,
QuickStepContractInfo contractInfo) {
mResources = resources;
mMode = mode;
@@ -118,7 +160,7 @@ class OrientationTouchTransformer {
resetSwipeRegions(info);
}
- void setNavigationMode(NavigationMode newMode, Info info, Resources newRes) {
+ void setNavigationMode(SysUINavigationMode.Mode newMode, Info info, Resources newRes) {
if (DEBUG) {
Log.d(TAG, "setNavigationMode new: " + newMode + " oldMode: " + mMode + " " + this);
}
@@ -146,22 +188,22 @@ class OrientationTouchTransformer {
* @see #enableMultipleRegions(boolean, Info)
*/
void createOrAddTouchRegion(Info info) {
- mCachedDisplayInfo = new CachedDisplayInfo(info.currentSize, info.rotation);
+ mCurrentDisplay = new CurrentDisplay(info.currentSize, info.rotation);
if (mQuickStepStartingRotation > QUICKSTEP_ROTATION_UNINITIALIZED
- && mCachedDisplayInfo.rotation == mQuickStepStartingRotation) {
+ && mCurrentDisplay.rotation == mQuickStepStartingRotation) {
// User already was swiping and the current screen is same rotation as the starting one
// Remove active nav bars in other rotations except for the one we started out in
resetSwipeRegions(info);
return;
}
- OrientationRectF region = mSwipeTouchRegions.get(mCachedDisplayInfo);
+ OrientationRectF region = mSwipeTouchRegions.get(mCurrentDisplay);
if (region != null) {
return;
}
if (mEnableMultipleRegions) {
- mSwipeTouchRegions.put(mCachedDisplayInfo, createRegionForDisplay(info));
+ mSwipeTouchRegions.put(mCurrentDisplay, createRegionForDisplay(info));
} else {
resetSwipeRegions(info);
}
@@ -175,7 +217,8 @@ class OrientationTouchTransformer {
* @param info The current displayInfo which will be the start of the quickswitch gesture
*/
void enableMultipleRegions(boolean enableMultipleRegions, Info info) {
- mEnableMultipleRegions = enableMultipleRegions && mMode != NavigationMode.TWO_BUTTONS;
+ mEnableMultipleRegions = enableMultipleRegions &&
+ mMode != SysUINavigationMode.Mode.TWO_BUTTONS;
if (mEnableMultipleRegions) {
mQuickStepStartingRotation = info.rotation;
} else {
@@ -207,39 +250,40 @@ class OrientationTouchTransformer {
*/
private void resetSwipeRegions(Info region) {
if (DEBUG) {
- Log.d(TAG, "clearing all regions except rotation: " + mCachedDisplayInfo.rotation);
+ Log.d(TAG, "clearing all regions except rotation: " + mCurrentDisplay.rotation);
}
- mCachedDisplayInfo = new CachedDisplayInfo(region.currentSize, region.rotation);
- OrientationRectF regionToKeep = mSwipeTouchRegions.get(mCachedDisplayInfo);
+ mCurrentDisplay = new CurrentDisplay(region.currentSize, region.rotation);
+ OrientationRectF regionToKeep = mSwipeTouchRegions.get(mCurrentDisplay);
if (regionToKeep == null) {
regionToKeep = createRegionForDisplay(region);
}
mSwipeTouchRegions.clear();
- mSwipeTouchRegions.put(mCachedDisplayInfo, regionToKeep);
+ mSwipeTouchRegions.put(mCurrentDisplay, regionToKeep);
updateAssistantRegions(regionToKeep);
}
private void resetSwipeRegions() {
- OrientationRectF regionToKeep = mSwipeTouchRegions.get(mCachedDisplayInfo);
+ OrientationRectF regionToKeep = mSwipeTouchRegions.get(mCurrentDisplay);
mSwipeTouchRegions.clear();
if (regionToKeep != null) {
- mSwipeTouchRegions.put(mCachedDisplayInfo, regionToKeep);
+ mSwipeTouchRegions.put(mCurrentDisplay, regionToKeep);
updateAssistantRegions(regionToKeep);
}
}
private OrientationRectF createRegionForDisplay(Info display) {
if (DEBUG) {
- Log.d(TAG, "creating rotation region for: " + mCachedDisplayInfo.rotation
+ Log.d(TAG, "creating rotation region for: " + mCurrentDisplay.rotation
+ " with mode: " + mMode + " displayRotation: " + display.rotation);
}
Point size = display.currentSize;
int rotation = display.rotation;
int touchHeight = mNavBarGesturalHeight;
- OrientationRectF orientationRectF = new OrientationRectF(0, 0, size.x, size.y, rotation);
- if (mMode == NavigationMode.NO_BUTTON) {
+ OrientationRectF orientationRectF =
+ new OrientationRectF(0, 0, size.x, size.y, rotation);
+ if (mMode == SysUINavigationMode.Mode.NO_BUTTON) {
orientationRectF.top = orientationRectF.bottom - touchHeight;
updateAssistantRegions(orientationRectF);
} else {
@@ -321,18 +365,7 @@ class OrientationTouchTransformer {
if (mLastRectTouched == null) {
return;
}
- if (TaskAnimationManager.SHELL_TRANSITIONS_ROTATION) {
- if (event.getSurfaceRotation() != mActiveTouchRotation) {
- // With Shell transitions, we should rotated to the orientation at the start
- // of the gesture not the current display rotation which will happen early
- mLastRectTouched.applyTransform(event,
- deltaRotation(event.getSurfaceRotation(), mActiveTouchRotation),
- true);
- }
- } else {
- mLastRectTouched.applyTransformFromRotation(event, mCachedDisplayInfo.rotation,
- true);
- }
+ mLastRectTouched.applyTransform(event, true);
break;
}
case ACTION_CANCEL:
@@ -340,18 +373,7 @@ class OrientationTouchTransformer {
if (mLastRectTouched == null) {
return;
}
- if (TaskAnimationManager.SHELL_TRANSITIONS_ROTATION) {
- if (event.getSurfaceRotation() != mActiveTouchRotation) {
- // With Shell transitions, we should rotated to the orientation at the start
- // of the gesture not the current display rotation which will happen early
- mLastRectTouched.applyTransform(event,
- deltaRotation(event.getSurfaceRotation(), mActiveTouchRotation),
- true);
- }
- } else {
- mLastRectTouched.applyTransformFromRotation(event, mCachedDisplayInfo.rotation,
- true);
- }
+ mLastRectTouched.applyTransform(event, true);
mLastRectTouched = null;
break;
}
@@ -365,15 +387,14 @@ class OrientationTouchTransformer {
if (rect == null) {
continue;
}
- if (rect.applyTransformFromRotation(
- event, mCachedDisplayInfo.rotation, false)) {
+ if (rect.applyTransform(event, false)) {
mLastRectTouched = rect;
- mActiveTouchRotation = rect.getRotation();
+ mActiveTouchRotation = rect.mRotation;
if (mEnableMultipleRegions
- && mCachedDisplayInfo.rotation == mActiveTouchRotation) {
+ && mCurrentDisplay.rotation == mActiveTouchRotation) {
// TODO(b/154580671) might make this block unnecessary
// Start a touch session for the default nav region for the display
- mQuickStepStartingRotation = mLastRectTouched.getRotation();
+ mQuickStepStartingRotation = mLastRectTouched.mRotation;
resetSwipeRegions();
}
if (DEBUG) {
@@ -393,7 +414,7 @@ class OrientationTouchTransformer {
pw.println(" lastTouchedRegion=" + mLastRectTouched);
pw.println(" multipleRegionsEnabled=" + mEnableMultipleRegions);
StringBuilder regions = new StringBuilder(" currentTouchableRotations=");
- for (CachedDisplayInfo key: mSwipeTouchRegions.keySet()) {
+ for (CurrentDisplay key: mSwipeTouchRegions.keySet()) {
OrientationRectF rectF = mSwipeTouchRegions.get(key);
regions.append(rectF).append(" ");
}
@@ -402,4 +423,65 @@ class OrientationTouchTransformer {
pw.println(" mNavBarLargerGesturalHeight=" + mNavBarLargerGesturalHeight);
pw.println(" mOneHandedModeRegion=" + mOneHandedModeRegion);
}
+
+ private class OrientationRectF extends RectF {
+
+ private int mRotation;
+ private float mHeight;
+ private float mWidth;
+
+ OrientationRectF(float left, float top, float right, float bottom, int rotation) {
+ super(left, top, right, bottom);
+ this.mRotation = rotation;
+ mHeight = bottom;
+ mWidth = right;
+ }
+
+ @Override
+ public String toString() {
+ String s = super.toString();
+ s += " rotation: " + mRotation;
+ return s;
+ }
+
+ @Override
+ public boolean contains(float x, float y) {
+ // Mark bottom right as included in the Rect (copied from Rect src, added "=" in "<=")
+ return left < right && top < bottom // check for empty first
+ && x >= left && x <= right && y >= top && y <= bottom;
+ }
+
+ boolean applyTransform(MotionEvent event, boolean forceTransform) {
+ mTmpMatrix.reset();
+ postDisplayRotation(deltaRotation(mCurrentDisplay.rotation, mRotation),
+ mHeight, mWidth, mTmpMatrix);
+ if (forceTransform) {
+ if (DEBUG) {
+ Log.d(TAG, "Transforming rotation due to forceTransform, "
+ + "mCurrentRotation: " + mCurrentDisplay.rotation
+ + "mRotation: " + mRotation
+ + " this: " + this);
+ }
+ event.transform(mTmpMatrix);
+ return true;
+ }
+ mTmpPoint[0] = event.getX();
+ mTmpPoint[1] = event.getY();
+ mTmpMatrix.mapPoints(mTmpPoint);
+
+ if (DEBUG) {
+ Log.d(TAG, "original: " + event.getX() + ", " + event.getY()
+ + " new: " + mTmpPoint[0] + ", " + mTmpPoint[1]
+ + " rect: " + this + " forceTransform: " + forceTransform
+ + " contains: " + contains(mTmpPoint[0], mTmpPoint[1])
+ + " this: " + this);
+ }
+
+ if (contains(mTmpPoint[0], mTmpPoint[1])) {
+ event.transform(mTmpMatrix);
+ return true;
+ }
+ return false;
+ }
+ }
}
diff --git a/quickstep/src/com/android/quickstep/OverscrollPluginFactory.java b/quickstep/src/com/android/quickstep/OverscrollPluginFactory.java
new file mode 100644
index 0000000000..4c261abc7a
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/OverscrollPluginFactory.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2020 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.quickstep;
+
+import static com.android.launcher3.util.MainThreadInitializedObject.forOverride;
+
+import com.android.launcher3.R;
+import com.android.launcher3.util.MainThreadInitializedObject;
+import com.android.launcher3.util.ResourceBasedOverride;
+import com.android.systemui.plugins.OverscrollPlugin;
+
+/**
+ * Resource overrideable factory for forcing a local overscroll plugin.
+ * Override {@link R.string#overscroll_plugin_factory_class} to set a different class.
+ */
+public class OverscrollPluginFactory implements ResourceBasedOverride {
+ public static final MainThreadInitializedObject<OverscrollPluginFactory> INSTANCE = forOverride(
+ OverscrollPluginFactory.class,
+ R.string.overscroll_plugin_factory_class);
+
+ /**
+ * Get the plugin that is defined locally in launcher, as opposed to a dynamic side loaded one.
+ */
+ public OverscrollPlugin getLocalOverscrollPlugin() {
+ return null;
+ }
+}
diff --git a/quickstep/src/com/android/quickstep/OverviewCommandHelper.java b/quickstep/src/com/android/quickstep/OverviewCommandHelper.java
index dffdc5a641..5d1f90885a 100644
--- a/quickstep/src/com/android/quickstep/OverviewCommandHelper.java
+++ b/quickstep/src/com/android/quickstep/OverviewCommandHelper.java
@@ -37,9 +37,7 @@ import com.android.quickstep.views.TaskView;
import com.android.systemui.shared.recents.model.ThumbnailData;
import com.android.systemui.shared.system.InteractionJankMonitorWrapper;
-import java.io.PrintWriter;
import java.util.ArrayList;
-import java.util.HashMap;
/**
* Helper class to handle various atomic commands for switching between Overview.
@@ -51,13 +49,6 @@ public class OverviewCommandHelper {
public static final int TYPE_SHOW_NEXT_FOCUS = 2;
public static final int TYPE_HIDE = 3;
public static final int TYPE_TOGGLE = 4;
- public static final int TYPE_HOME = 5;
-
- /**
- * Use case for needing a queue is double tapping recents button in 3 button nav.
- * Size of 2 should be enough. We'll toss in one more because we're kind hearted.
- */
- private final static int MAX_QUEUE_SIZE = 3;
private static final String TRANSITION_NAME = "Transition:toOverview";
@@ -110,15 +101,10 @@ public class OverviewCommandHelper {
}
/**
- * Adds a command to be executed next, after all pending tasks are completed.
- * Max commands that can be queued is {@link #MAX_QUEUE_SIZE}.
- * Requests after reaching that limit will be silently dropped.
+ * Adds a command to be executed next, after all pending tasks are completed
*/
@BinderThread
public void addCommand(int type) {
- if (mPendingCommands.size() > MAX_QUEUE_SIZE) {
- return;
- }
CommandInfo cmd = new CommandInfo(type);
MAIN_EXECUTOR.execute(() -> addCommand(cmd));
}
@@ -128,12 +114,11 @@ public class OverviewCommandHelper {
mPendingCommands.clear();
}
- @Nullable
private TaskView getNextTask(RecentsView view) {
final TaskView runningTaskView = view.getRunningTaskView();
if (runningTaskView == null) {
- return view.getTaskViewAt(0);
+ return view.getTaskViewCount() > 0 ? view.getTaskViewAt(0) : null;
} else {
final TaskView nextTask = view.getNextTaskView();
return nextTask != null ? nextTask : runningTaskView;
@@ -169,10 +154,6 @@ public class OverviewCommandHelper {
// already hidden
return true;
}
- if (cmd.type == TYPE_HOME) {
- mService.startActivity(mOverviewComponentObserver.getHomeIntent());
- return true;
- }
} else {
switch (cmd.type) {
case TYPE_SHOW:
@@ -187,9 +168,6 @@ public class OverviewCommandHelper {
}
case TYPE_TOGGLE:
return launchTask(recents, getNextTask(recents), cmd);
- case TYPE_HOME:
- recents.startHome();
- return true;
}
}
@@ -217,13 +195,12 @@ public class OverviewCommandHelper {
@Override
public void onRecentsAnimationStart(RecentsAnimationController controller,
RecentsAnimationTargets targets) {
- activityInterface.runOnInitBackgroundStateUI(() ->
- interactionHandler.onGestureEnded(0, new PointF(), new PointF()));
+ interactionHandler.onGestureEnded(0, new PointF(), new PointF());
cmd.removeListener(this);
}
@Override
- public void onRecentsAnimationCanceled(HashMap<Integer, ThumbnailData> thumbnailDatas) {
+ public void onRecentsAnimationCanceled(ThumbnailData thumbnailData) {
interactionHandler.onGestureCancelled();
cmd.removeListener(this);
@@ -267,8 +244,8 @@ public class OverviewCommandHelper {
// Ensure that recents view has focus so that it receives the followup key inputs
TaskView taskView = rv.getNextTaskView();
if (taskView == null) {
- taskView = rv.getTaskViewAt(0);
- if (taskView != null) {
+ if (rv.getTaskViewCount() > 0) {
+ taskView = rv.getTaskViewAt(0);
taskView.requestFocus();
} else {
rv.requestFocus();
@@ -281,14 +258,6 @@ public class OverviewCommandHelper {
scheduleNextTask(cmd);
}
- public void dump(PrintWriter pw) {
- pw.println("OverviewCommandHelper:");
- pw.println(" mPendingCommands=" + mPendingCommands.size());
- if (!mPendingCommands.isEmpty()) {
- pw.println(" pendingCommandType=" + mPendingCommands.get(0).type);
- }
- }
-
private static class CommandInfo {
public final long createTime = SystemClock.elapsedRealtime();
public final int type;
diff --git a/quickstep/src/com/android/quickstep/QuickstepProcessInitializer.java b/quickstep/src/com/android/quickstep/QuickstepProcessInitializer.java
index 55210200e0..65847f11bb 100644
--- a/quickstep/src/com/android/quickstep/QuickstepProcessInitializer.java
+++ b/quickstep/src/com/android/quickstep/QuickstepProcessInitializer.java
@@ -16,18 +16,18 @@
package com.android.quickstep;
import android.annotation.TargetApi;
-import android.app.ActivityManager;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Build;
-import android.os.RemoteException;
import android.os.UserManager;
import android.util.Log;
-import android.view.ThreadedRenderer;
import com.android.launcher3.BuildConfig;
import com.android.launcher3.MainProcessInitializer;
+import com.android.launcher3.util.Executors;
+import com.android.quickstep.logging.SettingsChangeLogger;
import com.android.systemui.shared.system.InteractionJankMonitorWrapper;
+import com.android.systemui.shared.system.ThreadedRendererCompat;
@SuppressWarnings("unused")
@TargetApi(Build.VERSION_CODES.R)
@@ -60,14 +60,11 @@ public class QuickstepProcessInitializer extends MainProcessInitializer {
super.init(context);
// Elevate GPU priority for Quickstep and Remote animations.
- ThreadedRenderer.setContextPriority(
- ThreadedRenderer.EGL_CONTEXT_PRIORITY_HIGH_IMG);
+ ThreadedRendererCompat.setContextPriority(
+ ThreadedRendererCompat.EGL_CONTEXT_PRIORITY_HIGH_IMG);
- // Enable binder tracing on system server for calls originating from Launcher
- try {
- ActivityManager.getService().enableBinderTracing();
- } catch (RemoteException e) {
- Log.e(TAG, "Unable to enable binder tracing", e);
- }
+ // Initialize settings logger after a default timeout
+ Executors.MAIN_EXECUTOR.getHandler()
+ .postDelayed(() -> new SettingsChangeLogger(context), SETUP_DELAY_MILLIS);
}
}
diff --git a/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java b/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java
index 528fb97983..39af0db8ff 100644
--- a/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java
+++ b/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java
@@ -2,14 +2,14 @@ package com.android.quickstep;
import android.app.Activity;
import android.content.Context;
-import android.graphics.Rect;
import android.os.Bundle;
-import androidx.annotation.Nullable;
-
+import com.android.launcher3.LauncherState;
+import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.testing.TestInformationHandler;
import com.android.launcher3.testing.TestProtocol;
import com.android.launcher3.touch.PagedOrientationHandler;
+import com.android.launcher3.uioverrides.touchcontrollers.PortraitStatesTouchController;
import com.android.quickstep.util.LayoutUtils;
public class QuickstepTestInformationHandler extends TestInformationHandler {
@@ -21,9 +21,18 @@ public class QuickstepTestInformationHandler extends TestInformationHandler {
}
@Override
- public Bundle call(String method, String arg, @Nullable Bundle extras) {
+ public Bundle call(String method) {
final Bundle response = new Bundle();
switch (method) {
+ case TestProtocol.REQUEST_ALL_APPS_TO_OVERVIEW_SWIPE_HEIGHT: {
+ return getLauncherUIProperty(Bundle::putInt, l -> {
+ final float progress = LauncherState.OVERVIEW.getVerticalProgress(l)
+ - LauncherState.ALL_APPS.getVerticalProgress(l);
+ final float distance = l.getAllAppsController().getShiftRange() * progress;
+ return (int) distance;
+ });
+ }
+
case TestProtocol.REQUEST_HOME_TO_OVERVIEW_SWIPE_HEIGHT: {
final float swipeHeight =
LayoutUtils.getDefaultSwipeHeight(mContext, mDeviceProfile);
@@ -39,42 +48,25 @@ public class QuickstepTestInformationHandler extends TestInformationHandler {
return response;
}
- case TestProtocol.REQUEST_GET_FOCUSED_TASK_HEIGHT_FOR_TABLET: {
- if (!mDeviceProfile.isTablet) {
- return null;
- }
- Rect focusedTaskRect = new Rect();
- LauncherActivityInterface.INSTANCE.calculateTaskSize(mContext, mDeviceProfile,
- focusedTaskRect);
- response.putInt(TestProtocol.TEST_INFO_RESPONSE_FIELD, focusedTaskRect.height());
- return response;
- }
-
- case TestProtocol.REQUEST_GET_GRID_TASK_SIZE_RECT_FOR_TABLET: {
- if (!mDeviceProfile.isTablet) {
- return null;
- }
- Rect gridTaskRect = new Rect();
- LauncherActivityInterface.INSTANCE.calculateGridTaskSize(mContext, mDeviceProfile,
- gridTaskRect, PagedOrientationHandler.PORTRAIT);
- response.putParcelable(TestProtocol.TEST_INFO_RESPONSE_FIELD, gridTaskRect);
- return response;
+ case TestProtocol.REQUEST_HOTSEAT_TOP: {
+ return getLauncherUIProperty(
+ Bundle::putInt, PortraitStatesTouchController::getHotseatTop);
}
- case TestProtocol.REQUEST_GET_OVERVIEW_PAGE_SPACING: {
- response.putInt(TestProtocol.TEST_INFO_RESPONSE_FIELD,
- mDeviceProfile.overviewPageSpacing);
+ case TestProtocol.REQUEST_OVERVIEW_SHARE_ENABLED: {
+ response.putBoolean(TestProtocol.TEST_INFO_RESPONSE_FIELD,
+ FeatureFlags.ENABLE_OVERVIEW_SHARE.get());
return response;
}
- case TestProtocol.REQUEST_HAS_TIS: {
- response.putBoolean(
- TestProtocol.REQUEST_HAS_TIS, true);
+ case TestProtocol.REQUEST_OVERVIEW_CONTENT_PUSH_ENABLED: {
+ response.putBoolean(TestProtocol.TEST_INFO_RESPONSE_FIELD,
+ FeatureFlags.ENABLE_OVERVIEW_CONTENT_PUSH.get());
return response;
}
}
- return super.call(method, arg, extras);
+ return super.call(method);
}
@Override
diff --git a/quickstep/src/com/android/quickstep/RecentTasksList.java b/quickstep/src/com/android/quickstep/RecentTasksList.java
index 097850fd6f..3080f040ac 100644
--- a/quickstep/src/com/android/quickstep/RecentTasksList.java
+++ b/quickstep/src/com/android/quickstep/RecentTasksList.java
@@ -22,36 +22,35 @@ import android.annotation.TargetApi;
import android.app.ActivityManager;
import android.os.Build;
import android.os.Process;
-import android.os.RemoteException;
+import android.util.Log;
import android.util.SparseBooleanArray;
import androidx.annotation.VisibleForTesting;
-import com.android.quickstep.util.GroupTask;
+import com.android.launcher3.testing.TestProtocol;
import com.android.launcher3.util.LooperExecutor;
-import com.android.launcher3.util.SplitConfigurationOptions;
import com.android.systemui.shared.recents.model.Task;
+import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.KeyguardManagerCompat;
-import com.android.wm.shell.recents.IRecentTasksListener;
-import com.android.wm.shell.util.GroupedRecentTaskInfo;
-import com.android.wm.shell.util.StagedSplitBounds;
+import com.android.systemui.shared.system.TaskStackChangeListener;
+import com.android.systemui.shared.system.TaskStackChangeListeners;
-import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.List;
import java.util.function.Consumer;
/**
* Manages the recent task list from the system, caching it as necessary.
*/
@TargetApi(Build.VERSION_CODES.R)
-public class RecentTasksList {
+public class RecentTasksList extends TaskStackChangeListener {
private static final TaskLoadResult INVALID_RESULT = new TaskLoadResult(-1, false, 0);
private final KeyguardManagerCompat mKeyguardManager;
private final LooperExecutor mMainThreadExecutor;
- private final SystemUiProxy mSysUiProxy;
+ private final ActivityManagerWrapper mActivityManagerWrapper;
// The list change id, increments as the task list changes in the system
private int mChangeId;
@@ -63,17 +62,12 @@ public class RecentTasksList {
private TaskLoadResult mResultsUi = INVALID_RESULT;
public RecentTasksList(LooperExecutor mainThreadExecutor,
- KeyguardManagerCompat keyguardManager, SystemUiProxy sysUiProxy) {
+ KeyguardManagerCompat keyguardManager, ActivityManagerWrapper activityManagerWrapper) {
mMainThreadExecutor = mainThreadExecutor;
mKeyguardManager = keyguardManager;
mChangeId = 1;
- mSysUiProxy = sysUiProxy;
- sysUiProxy.registerRecentTasksListener(new IRecentTasksListener.Stub() {
- @Override
- public void onRecentTasksChanged() throws RemoteException {
- mMainThreadExecutor.execute(RecentTasksList.this::onRecentTasksChanged);
- }
- });
+ mActivityManagerWrapper = activityManagerWrapper;
+ TaskStackChangeListeners.getInstance().registerTaskStackListener(this);
}
@VisibleForTesting
@@ -84,11 +78,10 @@ public class RecentTasksList {
/**
* Fetches the task keys skipping any local cache.
*/
- public void getTaskKeys(int numTasks, Consumer<ArrayList<GroupTask>> callback) {
+ public void getTaskKeys(int numTasks, Consumer<ArrayList<Task>> callback) {
// Kick off task loading in the background
UI_HELPER_EXECUTOR.execute(() -> {
- ArrayList<GroupTask> tasks = loadTasksInBackground(numTasks, -1,
- true /* loadKeysOnly */);
+ ArrayList<Task> tasks = loadTasksInBackground(numTasks, -1, true /* loadKeysOnly */);
mMainThreadExecutor.execute(() -> callback.accept(tasks));
});
}
@@ -100,15 +93,14 @@ public class RecentTasksList {
* @param callback The callback to receive the list of recent tasks
* @return The change id of the current task list
*/
- public synchronized int getTasks(boolean loadKeysOnly,
- Consumer<ArrayList<GroupTask>> callback) {
+ public synchronized int getTasks(boolean loadKeysOnly, Consumer<ArrayList<Task>> callback) {
final int requestLoadId = mChangeId;
if (mResultsUi.isValidForRequest(requestLoadId, loadKeysOnly)) {
// The list is up to date, send the callback on the next frame,
// so that requestID can be returned first.
if (callback != null) {
// Copy synchronously as the changeId might change by next frame
- ArrayList<GroupTask> result = copyOf(mResultsUi);
+ ArrayList<Task> result = copyOf(mResultsUi);
mMainThreadExecutor.post(() -> {
callback.accept(result);
});
@@ -128,7 +120,7 @@ public class RecentTasksList {
mLoadingTasksInBackground = false;
mResultsUi = loadResult;
if (callback != null) {
- ArrayList<GroupTask> result = copyOf(mResultsUi);
+ ArrayList<Task> result = copyOf(mResultsUi);
callback.accept(result);
}
});
@@ -144,7 +136,35 @@ public class RecentTasksList {
return mChangeId == changeId;
}
- public void onRecentTasksChanged() {
+ @Override
+ public void onTaskStackChanged() {
+ invalidateLoadedTasks();
+ }
+
+ @Override
+ public void onRecentTaskListUpdated() {
+ // In some cases immediately after booting, the tasks in the system recent task list may be
+ // loaded, but not in the active task hierarchy in the system. These tasks are displayed in
+ // overview, but removing them don't result in a onTaskStackChanged() nor a onTaskRemoved()
+ // callback (those are for changes to the active tasks), but the task list is still updated,
+ // so we should also invalidate the change id to ensure we load a new list instead of
+ // reusing a stale list.
+ invalidateLoadedTasks();
+ }
+
+ @Override
+ public void onTaskRemoved(int taskId) {
+ invalidateLoadedTasks();
+ }
+
+
+ @Override
+ public void onActivityPinned(String packageName, int userId, int taskId, int stackId) {
+ invalidateLoadedTasks();
+ }
+
+ @Override
+ public synchronized void onActivityUnpinned() {
invalidateLoadedTasks();
}
@@ -160,8 +180,8 @@ public class RecentTasksList {
@VisibleForTesting
TaskLoadResult loadTasksInBackground(int numTasks, int requestId, boolean loadKeysOnly) {
int currentUserId = Process.myUserHandle().getIdentifier();
- ArrayList<GroupedRecentTaskInfo> rawTasks =
- mSysUiProxy.getRecentTasks(numTasks, currentUserId);
+ List<ActivityManager.RecentTaskInfo> rawTasks =
+ mActivityManagerWrapper.getRecentTasks(numTasks, currentUserId);
// The raw tasks are given in most-recent to least-recent order, we need to reverse it
Collections.reverse(rawTasks);
@@ -177,84 +197,45 @@ public class RecentTasksList {
};
TaskLoadResult allTasks = new TaskLoadResult(requestId, loadKeysOnly, rawTasks.size());
- for (GroupedRecentTaskInfo rawTask : rawTasks) {
- ActivityManager.RecentTaskInfo taskInfo1 = rawTask.mTaskInfo1;
- ActivityManager.RecentTaskInfo taskInfo2 = rawTask.mTaskInfo2;
- Task.TaskKey task1Key = new Task.TaskKey(taskInfo1);
- Task task1 = loadKeysOnly
- ? new Task(task1Key)
- : Task.from(task1Key, taskInfo1,
- tmpLockedUsers.get(task1Key.userId) /* isLocked */);
- task1.setLastSnapshotData(taskInfo1);
- Task task2 = null;
- if (taskInfo2 != null) {
- Task.TaskKey task2Key = new Task.TaskKey(taskInfo2);
- task2 = loadKeysOnly
- ? new Task(task2Key)
- : Task.from(task2Key, taskInfo2,
- tmpLockedUsers.get(task2Key.userId) /* isLocked */);
- task2.setLastSnapshotData(taskInfo2);
+ for (ActivityManager.RecentTaskInfo rawTask : rawTasks) {
+ Task.TaskKey taskKey = new Task.TaskKey(rawTask);
+ Task task;
+ if (!loadKeysOnly) {
+ boolean isLocked = tmpLockedUsers.get(taskKey.userId);
+ task = Task.from(taskKey, rawTask, isLocked);
+ } else {
+ task = new Task(taskKey);
}
- final SplitConfigurationOptions.StagedSplitBounds launcherSplitBounds =
- convertSplitBounds(rawTask.mStagedSplitBounds);
- allTasks.add(new GroupTask(task1, task2, launcherSplitBounds));
+ task.setLastSnapshotData(rawTask);
+ allTasks.add(task);
}
return allTasks;
}
- private SplitConfigurationOptions.StagedSplitBounds convertSplitBounds(
- StagedSplitBounds shellSplitBounds) {
- return shellSplitBounds == null ?
- null :
- new SplitConfigurationOptions.StagedSplitBounds(
- shellSplitBounds.leftTopBounds, shellSplitBounds.rightBottomBounds,
- shellSplitBounds.leftTopTaskId, shellSplitBounds.rightBottomTaskId);
- }
-
- private ArrayList<GroupTask> copyOf(ArrayList<GroupTask> tasks) {
- ArrayList<GroupTask> newTasks = new ArrayList<>();
+ private ArrayList<Task> copyOf(ArrayList<Task> tasks) {
+ ArrayList<Task> newTasks = new ArrayList<>();
for (int i = 0; i < tasks.size(); i++) {
- newTasks.add(new GroupTask(tasks.get(i)));
+ newTasks.add(new Task(tasks.get(i)));
}
return newTasks;
}
- public void dump(String prefix, PrintWriter writer) {
- writer.println(prefix + "RecentTasksList:");
- writer.println(prefix + " mChangeId=" + mChangeId);
- writer.println(prefix + " mResultsUi=[id=" + mResultsUi.mRequestId + ", tasks=");
- for (GroupTask task : mResultsUi) {
- writer.println(prefix + " t1=" + task.task1.key.id
- + " t2=" + (task.hasMultipleTasks() ? task.task2.key.id : "-1"));
- }
- writer.println(prefix + " ]");
- int currentUserId = Process.myUserHandle().getIdentifier();
- ArrayList<GroupedRecentTaskInfo> rawTasks =
- mSysUiProxy.getRecentTasks(Integer.MAX_VALUE, currentUserId);
- writer.println(prefix + " rawTasks=[");
- for (GroupedRecentTaskInfo task : rawTasks) {
- writer.println(prefix + " t1=" + task.mTaskInfo1.taskId
- + " t2=" + (task.mTaskInfo2 != null ? task.mTaskInfo2.taskId : "-1"));
- }
- writer.println(prefix + " ]");
- }
-
- private static class TaskLoadResult extends ArrayList<GroupTask> {
+ private static class TaskLoadResult extends ArrayList<Task> {
- final int mRequestId;
+ final int mId;
// If the result was loaded with keysOnly = true
final boolean mKeysOnly;
- TaskLoadResult(int requestId, boolean keysOnly, int size) {
+ TaskLoadResult(int id, boolean keysOnly, int size) {
super(size);
- mRequestId = requestId;
+ mId = id;
mKeysOnly = keysOnly;
}
boolean isValidForRequest(int requestId, boolean loadKeysOnly) {
- return mRequestId == requestId && (!mKeysOnly || loadKeysOnly);
+ return mId == requestId && (!mKeysOnly || loadKeysOnly);
}
}
} \ No newline at end of file
diff --git a/quickstep/src/com/android/quickstep/RecentsActivity.java b/quickstep/src/com/android/quickstep/RecentsActivity.java
index 4f0b9767f9..9dfcd12dde 100644
--- a/quickstep/src/com/android/quickstep/RecentsActivity.java
+++ b/quickstep/src/com/android/quickstep/RecentsActivity.java
@@ -22,9 +22,8 @@ import static com.android.launcher3.QuickstepTransitionManager.RECENTS_LAUNCH_DU
import static com.android.launcher3.QuickstepTransitionManager.STATUS_BAR_TRANSITION_DURATION;
import static com.android.launcher3.QuickstepTransitionManager.STATUS_BAR_TRANSITION_PRE_DELAY;
import static com.android.launcher3.Utilities.createHomeIntent;
-import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE;
import static com.android.launcher3.graphics.SysUiScrim.SYSUI_PROGRESS;
-import static com.android.launcher3.testing.TestProtocol.BAD_STATE;
+import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE;
import static com.android.launcher3.testing.TestProtocol.OVERVIEW_STATE_ORDINAL;
import static com.android.quickstep.TaskUtils.taskIsATargetWithMode;
import static com.android.quickstep.TaskViewUtils.createRecentsWindowAnimator;
@@ -39,8 +38,6 @@ import android.content.res.Configuration;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
-import android.util.Log;
-import android.view.Display;
import android.view.SurfaceControl.Transaction;
import android.view.View;
import android.window.SplashScreen;
@@ -63,8 +60,6 @@ import com.android.launcher3.statemanager.StateManager;
import com.android.launcher3.statemanager.StateManager.AtomicAnimationFactory;
import com.android.launcher3.statemanager.StateManager.StateHandler;
import com.android.launcher3.statemanager.StatefulActivity;
-import com.android.launcher3.taskbar.FallbackTaskbarUIController;
-import com.android.launcher3.taskbar.TaskbarManager;
import com.android.launcher3.util.ActivityOptionsWrapper;
import com.android.launcher3.util.ActivityTracker;
import com.android.launcher3.util.RunnableList;
@@ -78,9 +73,9 @@ import com.android.quickstep.fallback.RecentsDragLayer;
import com.android.quickstep.fallback.RecentsState;
import com.android.quickstep.util.RecentsAtomicAnimationFactory;
import com.android.quickstep.util.SplitSelectStateController;
-import com.android.quickstep.util.TISBindHelper;
import com.android.quickstep.views.OverviewActionsView;
import com.android.quickstep.views.RecentsView;
+import com.android.quickstep.views.SplitPlaceholderView;
import com.android.quickstep.views.TaskView;
import com.android.systemui.shared.system.ActivityOptionsCompat;
import com.android.systemui.shared.system.RemoteAnimationAdapterCompat;
@@ -102,15 +97,11 @@ public final class RecentsActivity extends StatefulActivity<RecentsState> {
private Handler mUiHandler = new Handler(Looper.getMainLooper());
private static final long HOME_APPEAR_DURATION = 250;
- private static final long RECENTS_ANIMATION_TIMEOUT = 1000;
private RecentsDragLayer mDragLayer;
private ScrimView mScrimView;
private FallbackRecentsView mFallbackRecentsView;
private OverviewActionsView mActionsView;
- private TISBindHelper mTISBindHelper;
- private @Nullable TaskbarManager mTaskbarManager;
- private @Nullable FallbackTaskbarUIController mTaskbarUIController;
private Configuration mOldConfig;
@@ -119,11 +110,6 @@ public final class RecentsActivity extends StatefulActivity<RecentsState> {
// Strong refs to runners which are cleared when the activity is destroyed
private RemoteAnimationFactory mActivityLaunchAnimationRunner;
- // For handling degenerate cases where starting an activity doesn't actually trigger the remote
- // animation callback
- private final Handler mHandler = new Handler();
- private final Runnable mAnimationStartTimeoutRunnable = this::onAnimationStartTimeout;
-
/**
* Init drag layer and overview panel views.
*/
@@ -136,31 +122,13 @@ public final class RecentsActivity extends StatefulActivity<RecentsState> {
mActionsView = findViewById(R.id.overview_actions_view);
SYSUI_PROGRESS.set(getRootView().getSysUiScrim(), 0f);
- SplitSelectStateController controller =
- new SplitSelectStateController(this, mHandler, getStateManager(),
- null /* depthController */);
- mDragLayer.recreateControllers();
- mFallbackRecentsView.init(mActionsView, controller);
-
- mTISBindHelper = new TISBindHelper(this, this::onTISConnected);
- }
-
- private void onTISConnected(TouchInteractionService.TISBinder binder) {
- mTaskbarManager = binder.getTaskbarManager();
- mTaskbarManager.setActivity(this);
- }
-
- @Override
- public void runOnBindToTouchInteractionService(Runnable r) {
- mTISBindHelper.runOnBindToTouchInteractionService(r);
- }
+ SplitPlaceholderView splitPlaceholderView = findViewById(R.id.split_placeholder);
+ splitPlaceholderView.init(
+ new SplitSelectStateController(mUiHandler, SystemUiProxy.INSTANCE.get(this))
+ );
- public void setTaskbarUIController(FallbackTaskbarUIController taskbarUIController) {
- mTaskbarUIController = taskbarUIController;
- }
-
- public FallbackTaskbarUIController getTaskbarUIController() {
- return mTaskbarUIController;
+ mDragLayer.recreateControllers();
+ mFallbackRecentsView.init(mActionsView, splitPlaceholderView);
}
@Override
@@ -228,16 +196,6 @@ public final class RecentsActivity extends StatefulActivity<RecentsState> {
// TODO(b/137318995) This should go home, but doing so removes freeform windows
}
- /**
- * Called if the remote animation callback from #getActivityLaunchOptions() hasn't called back
- * in a reasonable time due to a conflict with the recents animation.
- */
- private void onAnimationStartTimeout() {
- if (mActivityLaunchAnimationRunner != null) {
- mActivityLaunchAnimationRunner.onAnimationCancelled();
- }
- }
-
@Override
public ActivityOptionsWrapper getActivityLaunchOptions(final View v, @Nullable ItemInfo item) {
if (!(v instanceof TaskView)) {
@@ -252,7 +210,6 @@ public final class RecentsActivity extends StatefulActivity<RecentsState> {
public void onCreateAnimation(int transit, RemoteAnimationTargetCompat[] appTargets,
RemoteAnimationTargetCompat[] wallpaperTargets,
RemoteAnimationTargetCompat[] nonAppTargets, AnimationResult result) {
- mHandler.removeCallbacks(mAnimationStartTimeoutRunnable);
AnimatorSet anim = composeRecentsLaunchAnimator(taskView, appTargets,
wallpaperTargets, nonAppTargets);
anim.addListener(resetStateListener());
@@ -262,7 +219,6 @@ public final class RecentsActivity extends StatefulActivity<RecentsState> {
@Override
public void onAnimationCancelled() {
- mHandler.removeCallbacks(mAnimationStartTimeoutRunnable);
onEndCallback.executeAllAndDestroy();
}
};
@@ -272,15 +228,11 @@ public final class RecentsActivity extends StatefulActivity<RecentsState> {
RemoteAnimationAdapterCompat adapterCompat = new RemoteAnimationAdapterCompat(
wrapper, RECENTS_LAUNCH_DURATION,
RECENTS_LAUNCH_DURATION - STATUS_BAR_TRANSITION_DURATION
- - STATUS_BAR_TRANSITION_PRE_DELAY, getIApplicationThread());
+ - STATUS_BAR_TRANSITION_PRE_DELAY);
final ActivityOptionsWrapper activityOptions = new ActivityOptionsWrapper(
ActivityOptionsCompat.makeRemoteAnimation(adapterCompat),
onEndCallback);
- activityOptions.options.setSplashScreenStyle(SplashScreen.SPLASH_SCREEN_STYLE_ICON);
- activityOptions.options.setLaunchDisplayId(
- (v != null && v.getDisplay() != null) ? v.getDisplay().getDisplayId()
- : Display.DEFAULT_DISPLAY);
- mHandler.postDelayed(mAnimationStartTimeoutRunnable, RECENTS_ANIMATION_TIMEOUT);
+ activityOptions.options.setSplashscreenStyle(SplashScreen.SPLASH_SCREEN_STYLE_ICON);
return activityOptions;
}
@@ -314,7 +266,6 @@ public final class RecentsActivity extends StatefulActivity<RecentsState> {
protected void onStart() {
// Set the alpha to 1 before calling super, as it may get set back to 0 due to
// onActivityStart callback.
- Log.d(BAD_STATE, "RecentsActivity onStart mFallbackRecentsView.setContentAlpha(1)");
mFallbackRecentsView.setContentAlpha(1);
super.onStart();
mFallbackRecentsView.updateLocusId();
@@ -339,7 +290,7 @@ public final class RecentsActivity extends StatefulActivity<RecentsState> {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- mStateManager = new StateManager<>(this, RecentsState.BG_LAUNCHER);
+ mStateManager = new StateManager<>(this, RecentsState.DEFAULT);
mOldConfig = new Configuration(getResources().getConfiguration());
initDeviceProfile();
@@ -399,11 +350,6 @@ public final class RecentsActivity extends StatefulActivity<RecentsState> {
super.onDestroy();
ACTIVITY_TRACKER.onActivityDestroyed(this);
mActivityLaunchAnimationRunner = null;
-
- mTISBindHelper.onDestroy();
- if (mTaskbarManager != null) {
- mTaskbarManager.clearActivity(this);
- }
}
@Override
@@ -426,8 +372,7 @@ public final class RecentsActivity extends StatefulActivity<RecentsState> {
LauncherAnimationRunner runner = new LauncherAnimationRunner(
getMainThreadHandler(), mAnimationToHomeFactory, true);
RemoteAnimationAdapterCompat adapterCompat =
- new RemoteAnimationAdapterCompat(runner, HOME_APPEAR_DURATION, 0,
- getIApplicationThread());
+ new RemoteAnimationAdapterCompat(runner, HOME_APPEAR_DURATION, 0);
startActivity(createHomeIntent(),
ActivityOptionsCompat.makeRemoteAnimation(adapterCompat).toBundle());
}
@@ -445,7 +390,7 @@ public final class RecentsActivity extends StatefulActivity<RecentsState> {
RemoteAnimationTargets targets = new RemoteAnimationTargets(
appTargets, wallpaperTargets, nonAppTargets, MODE_OPENING);
for (RemoteAnimationTargetCompat app : targets.apps) {
- new Transaction().setAlpha(app.leash, 1).apply();
+ new Transaction().setAlpha(app.leash.getSurfaceControl(), 1).apply();
}
AnimatorSet anim = new AnimatorSet();
anim.play(controller.getAnimationPlayer());
diff --git a/quickstep/src/com/android/quickstep/RecentsAnimationCallbacks.java b/quickstep/src/com/android/quickstep/RecentsAnimationCallbacks.java
index 51ae56b96d..a21c7140de 100644
--- a/quickstep/src/com/android/quickstep/RecentsAnimationCallbacks.java
+++ b/quickstep/src/com/android/quickstep/RecentsAnimationCallbacks.java
@@ -16,14 +16,11 @@
package com.android.quickstep;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
-import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.ACTIVITY_TYPE_HOME;
import android.graphics.Rect;
import android.util.ArraySet;
-import android.view.RemoteAnimationTarget;
import androidx.annotation.BinderThread;
-import androidx.annotation.NonNull;
import androidx.annotation.UiThread;
import com.android.launcher3.Utilities;
@@ -32,8 +29,6 @@ import com.android.systemui.shared.recents.model.ThumbnailData;
import com.android.systemui.shared.system.RecentsAnimationControllerCompat;
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
-import java.util.Arrays;
-import java.util.HashMap;
import java.util.Set;
/**
@@ -44,7 +39,6 @@ public class RecentsAnimationCallbacks implements
com.android.systemui.shared.system.RecentsAnimationListener {
private final Set<RecentsAnimationListener> mListeners = new ArraySet<>();
- private final SystemUiProxy mSystemUiProxy;
private final boolean mAllowMinimizeSplitScreen;
// TODO(141886704): Remove these references when they are no longer needed
@@ -52,9 +46,7 @@ public class RecentsAnimationCallbacks implements
private boolean mCancelled;
- public RecentsAnimationCallbacks(SystemUiProxy systemUiProxy,
- boolean allowMinimizeSplitScreen) {
- mSystemUiProxy = systemUiProxy;
+ public RecentsAnimationCallbacks(boolean allowMinimizeSplitScreen) {
mAllowMinimizeSplitScreen = allowMinimizeSplitScreen;
}
@@ -78,7 +70,7 @@ public class RecentsAnimationCallbacks implements
public void notifyAnimationCanceled() {
mCancelled = true;
- onAnimationCanceled(new HashMap<>());
+ onAnimationCanceled(null);
}
// Called only in Q platform
@@ -97,18 +89,8 @@ public class RecentsAnimationCallbacks implements
RemoteAnimationTargetCompat[] appTargets,
RemoteAnimationTargetCompat[] wallpaperTargets,
Rect homeContentInsets, Rect minimizedHomeBounds) {
- // Convert appTargets to type RemoteAnimationTarget for all apps except Home app
- RemoteAnimationTarget[] nonHomeApps = Arrays.stream(appTargets)
- .filter(remoteAnimationTarget ->
- remoteAnimationTarget.activityType != ACTIVITY_TYPE_HOME)
- .map(RemoteAnimationTargetCompat::unwrap)
- .toArray(RemoteAnimationTarget[]::new);
-
- RemoteAnimationTarget[] nonAppTargets = mSystemUiProxy.onGoingToRecentsLegacy(nonHomeApps);
-
RecentsAnimationTargets targets = new RecentsAnimationTargets(appTargets,
- wallpaperTargets, RemoteAnimationTargetCompat.wrap(nonAppTargets),
- homeContentInsets, minimizedHomeBounds);
+ wallpaperTargets, homeContentInsets, minimizedHomeBounds);
mController = new RecentsAnimationController(animationController,
mAllowMinimizeSplitScreen, this::onAnimationFinished);
@@ -126,36 +108,24 @@ public class RecentsAnimationCallbacks implements
@BinderThread
@Override
- public final void onAnimationCanceled(HashMap<Integer, ThumbnailData> thumbnailDatas) {
+ public final void onAnimationCanceled(ThumbnailData thumbnailData) {
Utilities.postAsyncCallback(MAIN_EXECUTOR.getHandler(), () -> {
for (RecentsAnimationListener listener : getListeners()) {
- listener.onRecentsAnimationCanceled(thumbnailDatas);
+ listener.onRecentsAnimationCanceled(thumbnailData);
}
});
}
@BinderThread
@Override
- public void onTasksAppeared(RemoteAnimationTargetCompat[] apps) {
+ public void onTaskAppeared(RemoteAnimationTargetCompat app) {
Utilities.postAsyncCallback(MAIN_EXECUTOR.getHandler(), () -> {
for (RecentsAnimationListener listener : getListeners()) {
- listener.onTasksAppeared(apps);
+ listener.onTaskAppeared(app);
}
});
}
- @BinderThread
- @Override
- public boolean onSwitchToScreenshot(Runnable onFinished) {
- Utilities.postAsyncCallback(MAIN_EXECUTOR.getHandler(), () -> {
- for (RecentsAnimationListener listener : getListeners()) {
- if (listener.onSwitchToScreenshot(onFinished)) return;
- }
- onFinished.run();
- });
- return true;
- }
-
private final void onAnimationFinished(RecentsAnimationController controller) {
Utilities.postAsyncCallback(MAIN_EXECUTOR.getHandler(), () -> {
for (RecentsAnimationListener listener : getListeners()) {
@@ -179,24 +149,16 @@ public class RecentsAnimationCallbacks implements
* Callback from the system when the recents animation is canceled. {@param thumbnailData}
* is passed back for rendering screenshot to replace live tile.
*/
- default void onRecentsAnimationCanceled(
- @NonNull HashMap<Integer, ThumbnailData> thumbnailDatas) {}
+ default void onRecentsAnimationCanceled(ThumbnailData thumbnailData) {}
/**
* Callback made whenever the recents animation is finished.
*/
- default void onRecentsAnimationFinished(@NonNull RecentsAnimationController controller) {}
+ default void onRecentsAnimationFinished(RecentsAnimationController controller) {}
/**
* Callback made when a task started from the recents is ready for an app transition.
*/
- default void onTasksAppeared(@NonNull RemoteAnimationTargetCompat[] appearedTaskTarget) {}
-
- /**
- * @return whether this will call onFinished or not (onFinished should only be called once).
- */
- default boolean onSwitchToScreenshot(Runnable onFinished) {
- return false;
- }
+ default void onTaskAppeared(RemoteAnimationTargetCompat appearedTaskTarget) {}
}
}
diff --git a/quickstep/src/com/android/quickstep/RecentsAnimationController.java b/quickstep/src/com/android/quickstep/RecentsAnimationController.java
index 2007ee1ebd..53b66752e2 100644
--- a/quickstep/src/com/android/quickstep/RecentsAnimationController.java
+++ b/quickstep/src/com/android/quickstep/RecentsAnimationController.java
@@ -17,14 +17,9 @@ package com.android.quickstep;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
-import static com.android.quickstep.TaskAnimationManager.ENABLE_SHELL_TRANSITIONS;
-import android.content.Context;
-import android.os.RemoteException;
-import android.util.Log;
import android.view.IRecentsAnimationController;
import android.view.SurfaceControl;
-import android.view.WindowManagerGlobal;
import android.window.PictureInPictureSurfaceTransaction;
import androidx.annotation.NonNull;
@@ -44,7 +39,6 @@ import java.util.function.Consumer;
*/
public class RecentsAnimationController {
- private static final String TAG = "RecentsAnimationController";
private final RecentsAnimationControllerCompat mController;
private final Consumer<RecentsAnimationController> mOnFinishedListener;
private final boolean mAllowMinimizeSplitScreen;
@@ -52,8 +46,6 @@ public class RecentsAnimationController {
private boolean mUseLauncherSysBarFlags = false;
private boolean mSplitScreenMinimized = false;
private boolean mFinishRequested = false;
- // Only valid when mFinishRequested == true.
- private boolean mFinishTargetIsLauncher;
private RunnableList mPendingFinishCallbacks = new RunnableList();
public RecentsAnimationController(RecentsAnimationControllerCompat controller,
@@ -80,16 +72,7 @@ public class RecentsAnimationController {
if (mUseLauncherSysBarFlags != useLauncherSysBarFlags) {
mUseLauncherSysBarFlags = useLauncherSysBarFlags;
UI_HELPER_EXECUTOR.execute(() -> {
- if (!ENABLE_SHELL_TRANSITIONS) {
- mController.setAnimationTargetsBehindSystemBars(!useLauncherSysBarFlags);
- } else {
- try {
- WindowManagerGlobal.getWindowManagerService().setRecentsAppBehindSystemBars(
- useLauncherSysBarFlags);
- } catch (RemoteException e) {
- Log.e(TAG, "Unable to reach window manager", e);
- }
- }
+ mController.setAnimationTargetsBehindSystemBars(!useLauncherSysBarFlags);
});
}
}
@@ -98,20 +81,24 @@ public class RecentsAnimationController {
* Indicates that the gesture has crossed the window boundary threshold and we should minimize
* if we are in splitscreen.
*/
- public void setSplitScreenMinimized(Context context, boolean splitScreenMinimized) {
+ public void setSplitScreenMinimized(boolean splitScreenMinimized) {
if (!mAllowMinimizeSplitScreen) {
return;
}
if (mSplitScreenMinimized != splitScreenMinimized) {
mSplitScreenMinimized = splitScreenMinimized;
- UI_HELPER_EXECUTOR.execute(() -> SystemUiProxy.INSTANCE.get(context)
- .setSplitScreenMinimized(splitScreenMinimized));
+ UI_HELPER_EXECUTOR.execute(() -> {
+ SystemUiProxy p = SystemUiProxy.INSTANCE.getNoCreate();
+ if (p != null) {
+ p.setSplitScreenMinimized(splitScreenMinimized);
+ }
+ });
}
}
/**
* Remove task remote animation target from
- * {@link RecentsAnimationCallbacks#onTasksAppeared}}.
+ * {@link RecentsAnimationCallbacks#onTaskAppeared(RemoteAnimationTargetCompat)}}.
*/
@UiThread
public void removeTaskTarget(@NonNull RemoteAnimationTargetCompat target) {
@@ -158,7 +145,6 @@ public class RecentsAnimationController {
// Finish not yet requested
mFinishRequested = true;
- mFinishTargetIsLauncher = toRecents;
mOnFinishedListener.accept(this);
mPendingFinishCallbacks.add(callback);
UI_HELPER_EXECUTOR.execute(() -> {
@@ -231,12 +217,4 @@ public class RecentsAnimationController {
public RecentsAnimationControllerCompat getController() {
return mController;
}
-
- /**
- * RecentsAnimationListeners can check this in onRecentsAnimationFinished() to determine whether
- * the animation was finished to launcher vs an app.
- */
- public boolean getFinishTargetIsLauncher() {
- return mFinishTargetIsLauncher;
- }
}
diff --git a/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java b/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java
index 4fb7e6ba06..444d77a612 100644
--- a/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java
+++ b/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java
@@ -18,24 +18,21 @@ package com.android.quickstep;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.content.Intent.ACTION_USER_UNLOCKED;
-import static android.view.Display.DEFAULT_DISPLAY;
import static com.android.launcher3.util.DisplayController.CHANGE_ALL;
-import static com.android.launcher3.util.DisplayController.CHANGE_NAVIGATION_MODE;
import static com.android.launcher3.util.DisplayController.CHANGE_ROTATION;
-import static com.android.launcher3.util.DisplayController.NavigationMode.NO_BUTTON;
-import static com.android.launcher3.util.DisplayController.NavigationMode.THREE_BUTTONS;
-import static com.android.launcher3.util.DisplayController.NavigationMode.TWO_BUTTONS;
import static com.android.launcher3.util.SettingsCache.ONE_HANDED_ENABLED;
import static com.android.launcher3.util.SettingsCache.ONE_HANDED_SWIPE_BOTTOM_TO_NOTIFICATION_ENABLED;
+import static com.android.quickstep.SysUINavigationMode.Mode.NO_BUTTON;
+import static com.android.quickstep.SysUINavigationMode.Mode.THREE_BUTTONS;
+import static com.android.quickstep.SysUINavigationMode.Mode.TWO_BUTTONS;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_A11Y_BUTTON_CLICKABLE;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_ALLOW_GESTURE_IGNORING_BAR_VISIBILITY;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_ASSIST_GESTURE_CONSTRAINED;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_BUBBLES_EXPANDED;
-import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_DIALOG_SHOWING;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_GLOBAL_ACTIONS_SHOWING;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_HOME_DISABLED;
-import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_IME_SHOWING;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_MAGNIFICATION_OVERLAP;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_NAV_BAR_HIDDEN;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED;
@@ -45,30 +42,38 @@ import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_Q
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_SCREEN_PINNING;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED;
+import android.app.ActivityManager;
import android.app.ActivityTaskManager;
import android.content.BroadcastReceiver;
+import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.content.res.Resources;
import android.graphics.Region;
-import android.inputmethodservice.InputMethodService;
import android.net.Uri;
import android.os.Process;
import android.os.RemoteException;
import android.os.SystemProperties;
import android.os.UserManager;
import android.provider.Settings;
+import android.text.TextUtils;
+import android.util.DisplayMetrics;
+import android.util.Log;
import android.view.MotionEvent;
+import android.view.Surface;
import androidx.annotation.BinderThread;
+import com.android.launcher3.R;
import com.android.launcher3.Utilities;
+import com.android.launcher3.testing.TestProtocol;
import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.DisplayController.DisplayInfoChangeListener;
import com.android.launcher3.util.DisplayController.Info;
-import com.android.launcher3.util.DisplayController.NavigationMode;
import com.android.launcher3.util.SettingsCache;
-import com.android.quickstep.TopTaskTracker.CachedTaskInfo;
+import com.android.quickstep.SysUINavigationMode.NavigationModeChangeListener;
+import com.android.quickstep.SysUINavigationMode.OneHandedModeChangeListener;
import com.android.quickstep.util.NavBarPosition;
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.QuickStepContract;
@@ -79,27 +84,31 @@ import com.android.systemui.shared.system.TaskStackChangeListeners;
import java.io.PrintWriter;
import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
/**
* Manages the state of the system during a swipe up gesture.
*/
-public class RecentsAnimationDeviceState implements DisplayInfoChangeListener {
+public class RecentsAnimationDeviceState implements
+ NavigationModeChangeListener,
+ DisplayInfoChangeListener,
+ OneHandedModeChangeListener {
static final String SUPPORT_ONE_HANDED_MODE = "ro.support_one_handed_mode";
private final Context mContext;
+ private final SysUINavigationMode mSysUiNavMode;
private final DisplayController mDisplayController;
private final int mDisplayId;
private final RotationTouchHelper mRotationTouchHelper;
private final TaskStackChangeListener mPipListener;
- // Cache for better performance since it doesn't change at runtime.
- private final boolean mCanImeRenderGesturalNavButtons =
- InputMethodService.canImeRenderGesturalNavButtons();
+ private final List<ComponentName> mGestureBlockedActivities;
private final ArrayList<Runnable> mOnDestroyActions = new ArrayList<>();
private @SystemUiStateFlags int mSystemUiStateFlags;
- private NavigationMode mMode = THREE_BUTTONS;
+ private SysUINavigationMode.Mode mMode = THREE_BUTTONS;
private NavBarPosition mNavBarPosition;
private final Region mDeferredGestureRegion = new Region();
@@ -123,7 +132,6 @@ public class RecentsAnimationDeviceState implements DisplayInfoChangeListener {
}
};
- private int mGestureBlockingTaskId = -1;
private Region mExclusionRegion;
private SystemGestureExclusionListenerCompat mExclusionListener;
@@ -138,8 +146,10 @@ public class RecentsAnimationDeviceState implements DisplayInfoChangeListener {
public RecentsAnimationDeviceState(Context context, boolean isInstanceForTouches) {
mContext = context;
mDisplayController = DisplayController.INSTANCE.get(context);
- mDisplayId = DEFAULT_DISPLAY;
+ mSysUiNavMode = SysUINavigationMode.INSTANCE.get(context);
+ mDisplayId = mDisplayController.getInfo().id;
mIsOneHandedModeSupported = SystemProperties.getBoolean(SUPPORT_ONE_HANDED_MODE, false);
+ runOnDestroy(() -> mDisplayController.removeChangeListener(this));
mRotationTouchHelper = RotationTouchHelper.INSTANCE.get(context);
if (isInstanceForTouches) {
// rotationTouchHelper doesn't get initialized after being destroyed, so only destroy
@@ -168,10 +178,25 @@ public class RecentsAnimationDeviceState implements DisplayInfoChangeListener {
};
runOnDestroy(mExclusionListener::unregister);
- // Register for display changes changes
- mDisplayController.addChangeListener(this);
- onDisplayInfoChanged(context, mDisplayController.getInfo(), CHANGE_ALL);
- runOnDestroy(() -> mDisplayController.removeChangeListener(this));
+ // Register for navigation mode changes
+ onNavigationModeChanged(mSysUiNavMode.addModeChangeListener(this));
+ runOnDestroy(() -> mSysUiNavMode.removeModeChangeListener(this));
+
+ // Add any blocked activities
+ String[] blockingActivities;
+ try {
+ blockingActivities =
+ context.getResources().getStringArray(R.array.gesture_blocking_activities);
+ } catch (Resources.NotFoundException e) {
+ blockingActivities = new String[0];
+ }
+ mGestureBlockedActivities = new ArrayList<>(blockingActivities.length);
+ for (String blockingActivity : blockingActivities) {
+ if (!TextUtils.isEmpty(blockingActivity)) {
+ mGestureBlockedActivities.add(
+ ComponentName.unflattenFromString(blockingActivity));
+ }
+ }
SettingsCache settingsCache = SettingsCache.INSTANCE.get(mContext);
if (mIsOneHandedModeSupported) {
@@ -240,36 +265,56 @@ public class RecentsAnimationDeviceState implements DisplayInfoChangeListener {
* Adds a listener for the nav mode change, guaranteed to be called after the device state's
* mode has changed.
*/
- public void addNavigationModeChangedCallback(Runnable callback) {
- DisplayController.DisplayInfoChangeListener listener = (context, info, flags) -> {
- if ((flags & CHANGE_NAVIGATION_MODE) != 0) {
- callback.run();
- }
- };
- mDisplayController.addChangeListener(listener);
- callback.run();
- runOnDestroy(() -> mDisplayController.removeChangeListener(listener));
+ public void addNavigationModeChangedCallback(NavigationModeChangeListener listener) {
+ listener.onNavigationModeChanged(mSysUiNavMode.addModeChangeListener(listener));
+ runOnDestroy(() -> mSysUiNavMode.removeModeChangeListener(listener));
+ }
+
+ /**
+ * Adds a listener for the one handed mode change,
+ * guaranteed to be called after the device state's mode has changed.
+ */
+ public void addOneHandedModeChangedCallback(OneHandedModeChangeListener listener) {
+ listener.onOneHandedModeChanged(mSysUiNavMode.addOneHandedOverlayChangeListener(listener));
+ runOnDestroy(() -> mSysUiNavMode.removeOneHandedOverlayChangeListener(listener));
+ }
+
+ @Override
+ public void onNavigationModeChanged(SysUINavigationMode.Mode newMode) {
+ mDisplayController.removeChangeListener(this);
+ mDisplayController.addChangeListener(this);
+ onDisplayInfoChanged(mContext, mDisplayController.getInfo(), CHANGE_ALL);
+
+ if (newMode == NO_BUTTON) {
+ mExclusionListener.register();
+ } else {
+ mExclusionListener.unregister();
+ }
+
+ mNavBarPosition = new NavBarPosition(newMode, mDisplayController.getInfo());
+ mMode = newMode;
}
@Override
public void onDisplayInfoChanged(Context context, Info info, int flags) {
- if ((flags & (CHANGE_ROTATION | CHANGE_NAVIGATION_MODE)) != 0) {
- mMode = info.navigationMode;
+ if ((flags & CHANGE_ROTATION) != 0) {
mNavBarPosition = new NavBarPosition(mMode, info);
-
- if (mMode == NO_BUTTON) {
- mExclusionListener.register();
- } else {
- mExclusionListener.unregister();
- }
}
}
+ @Override
public void onOneHandedModeChanged(int newGesturalHeight) {
mRotationTouchHelper.setGesturalHeight(newGesturalHeight);
}
/**
+ * @return the current navigation mode for the device.
+ */
+ public SysUINavigationMode.Mode getNavMode() {
+ return mMode;
+ }
+
+ /**
* @return the nav bar position for the current nav bar mode and display rotation.
*/
public NavBarPosition getNavBarPosition() {
@@ -346,17 +391,19 @@ public class RecentsAnimationDeviceState implements DisplayInfoChangeListener {
}
/**
- * Sets the task id where gestures should be blocked
+ * @return whether the given running task info matches the gesture-blocked activity.
*/
- public void setGestureBlockingTaskId(int taskId) {
- mGestureBlockingTaskId = taskId;
+ public boolean isGestureBlockedActivity(ActivityManager.RunningTaskInfo runningTaskInfo) {
+ return runningTaskInfo != null
+ && mGestureBlockedActivities.contains(runningTaskInfo.topActivity);
}
/**
- * @return whether the given running task info matches the gesture-blocked task.
+ * @return the packages of gesture-blocked activities.
*/
- public boolean isGestureBlockedTask(CachedTaskInfo taskInfo) {
- return taskInfo != null && taskInfo.getTaskId() == mGestureBlockingTaskId;
+ public List<String> getGestureBlockedActivityPackages() {
+ return mGestureBlockedActivities.stream().map(ComponentName::getPackageName)
+ .collect(Collectors.toList());
}
/**
@@ -419,17 +466,10 @@ public class RecentsAnimationDeviceState implements DisplayInfoChangeListener {
}
/**
- * @return whether notification panel is expanded
- */
- public boolean isNotificationPanelExpanded() {
- return (mSystemUiStateFlags & SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED) != 0;
- }
-
- /**
* @return whether the global actions dialog is showing
*/
- public boolean isSystemUiDialogShowing() {
- return (mSystemUiStateFlags & SYSUI_STATE_DIALOG_SHOWING) != 0;
+ public boolean isGlobalActionsShowing() {
+ return (mSystemUiStateFlags & SYSUI_STATE_GLOBAL_ACTIONS_SHOWING) != 0;
}
/**
@@ -525,13 +565,15 @@ public class RecentsAnimationDeviceState implements DisplayInfoChangeListener {
/**
* @param ev An ACTION_DOWN motion event
+ * @param task Info for the currently running task
* @return whether the given motion event can trigger the assistant over the current task.
*/
- public boolean canTriggerAssistantAction(MotionEvent ev) {
+ public boolean canTriggerAssistantAction(MotionEvent ev, ActivityManager.RunningTaskInfo task) {
return mAssistantAvailable
&& !QuickStepContract.isAssistantGestureDisabled(mSystemUiStateFlags)
&& mRotationTouchHelper.touchInAssistantRegion(ev)
- && !isLockToAppActive();
+ && !isLockToAppActive()
+ && !isGestureBlockedActivity(task);
}
/**
@@ -548,7 +590,9 @@ public class RecentsAnimationDeviceState implements DisplayInfoChangeListener {
if (mIsOneHandedModeEnabled) {
final Info displayInfo = mDisplayController.getInfo();
return (mRotationTouchHelper.touchInOneHandedModeRegion(ev)
- && (displayInfo.currentSize.x < displayInfo.currentSize.y));
+ && displayInfo.rotation != Surface.ROTATION_90
+ && displayInfo.rotation != Surface.ROTATION_270
+ && displayInfo.densityDpi < DisplayMetrics.DENSITY_600);
}
return false;
}
@@ -569,12 +613,6 @@ public class RecentsAnimationDeviceState implements DisplayInfoChangeListener {
return mRotationTouchHelper;
}
- /** Returns whether IME is rendering nav buttons, and IME is currently showing. */
- public boolean isImeRenderingNavButtons() {
- return mCanImeRenderGesturalNavButtons && mMode == NO_BUTTON
- && ((mSystemUiStateFlags & SYSUI_STATE_IME_SHOWING) != 0);
- }
-
public void dump(PrintWriter pw) {
pw.println("DeviceState:");
pw.println(" canStartSystemGesture=" + canStartSystemGesture());
diff --git a/quickstep/src/com/android/quickstep/RecentsAnimationTargets.java b/quickstep/src/com/android/quickstep/RecentsAnimationTargets.java
index b6d9016727..3861bab04b 100644
--- a/quickstep/src/com/android/quickstep/RecentsAnimationTargets.java
+++ b/quickstep/src/com/android/quickstep/RecentsAnimationTargets.java
@@ -31,9 +31,9 @@ public class RecentsAnimationTargets extends RemoteAnimationTargets {
public final Rect minimizedHomeBounds;
public RecentsAnimationTargets(RemoteAnimationTargetCompat[] apps,
- RemoteAnimationTargetCompat[] wallpapers, RemoteAnimationTargetCompat[] nonApps,
- Rect homeContentInsets, Rect minimizedHomeBounds) {
- super(apps, wallpapers, nonApps, MODE_CLOSING);
+ RemoteAnimationTargetCompat[] wallpapers, Rect homeContentInsets,
+ Rect minimizedHomeBounds) {
+ super(apps, wallpapers, new RemoteAnimationTargetCompat[0], MODE_CLOSING);
this.homeContentInsets = homeContentInsets;
this.minimizedHomeBounds = minimizedHomeBounds;
}
diff --git a/quickstep/src/com/android/quickstep/RecentsModel.java b/quickstep/src/com/android/quickstep/RecentsModel.java
index 1634c0839f..1e82c8cbfa 100644
--- a/quickstep/src/com/android/quickstep/RecentsModel.java
+++ b/quickstep/src/com/android/quickstep/RecentsModel.java
@@ -24,7 +24,6 @@ import android.annotation.TargetApi;
import android.app.ActivityManager;
import android.content.ComponentCallbacks2;
import android.content.Context;
-import android.content.Intent;
import android.os.Build;
import android.os.Process;
import android.os.UserHandle;
@@ -35,7 +34,6 @@ import com.android.launcher3.icons.IconProvider;
import com.android.launcher3.icons.IconProvider.IconChangeListener;
import com.android.launcher3.util.Executors.SimpleThreadFactory;
import com.android.launcher3.util.MainThreadInitializedObject;
-import com.android.quickstep.util.GroupTask;
import com.android.systemui.shared.recents.model.Task;
import com.android.systemui.shared.recents.model.ThumbnailData;
import com.android.systemui.shared.system.ActivityManagerWrapper;
@@ -43,7 +41,6 @@ import com.android.systemui.shared.system.KeyguardManagerCompat;
import com.android.systemui.shared.system.TaskStackChangeListener;
import com.android.systemui.shared.system.TaskStackChangeListeners;
-import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executor;
@@ -54,7 +51,7 @@ import java.util.function.Consumer;
* Singleton class to load and manage recents model.
*/
@TargetApi(Build.VERSION_CODES.O)
-public class RecentsModel implements IconChangeListener, TaskStackChangeListener {
+public class RecentsModel extends TaskStackChangeListener implements IconChangeListener {
// We do not need any synchronization for this variable as its only written on UI thread.
public static final MainThreadInitializedObject<RecentsModel> INSTANCE =
@@ -73,7 +70,7 @@ public class RecentsModel implements IconChangeListener, TaskStackChangeListener
private RecentsModel(Context context) {
mContext = context;
mTaskList = new RecentTasksList(MAIN_EXECUTOR,
- new KeyguardManagerCompat(context), SystemUiProxy.INSTANCE.get(context));
+ new KeyguardManagerCompat(context), ActivityManagerWrapper.getInstance());
IconProvider iconProvider = new IconProvider(context);
mIconCache = new TaskIconCache(context, RECENTS_MODEL_EXECUTOR, iconProvider);
@@ -98,7 +95,7 @@ public class RecentsModel implements IconChangeListener, TaskStackChangeListener
* always called on the UI thread.
* @return the request id associated with this call.
*/
- public int getTasks(Consumer<ArrayList<GroupTask>> callback) {
+ public int getTasks(Consumer<ArrayList<Task>> callback) {
return mTaskList.getTasks(false /* loadKeysOnly */, callback);
}
@@ -123,9 +120,9 @@ public class RecentsModel implements IconChangeListener, TaskStackChangeListener
* @param callback Receives true if task is removed, false otherwise
*/
public void isTaskRemoved(int taskId, Consumer<Boolean> callback) {
- mTaskList.getTasks(true /* loadKeysOnly */, (taskGroups) -> {
- for (GroupTask group : taskGroups) {
- if (group.containsTask(taskId)) {
+ mTaskList.getTasks(true /* loadKeysOnly */, (tasks) -> {
+ for (Task task : tasks) {
+ if (task.key.id == taskId) {
callback.accept(false);
return;
}
@@ -151,21 +148,20 @@ public class RecentsModel implements IconChangeListener, TaskStackChangeListener
ActivityManager.RunningTaskInfo runningTask =
ActivityManagerWrapper.getInstance().getRunningTask();
int runningTaskId = runningTask != null ? runningTask.id : -1;
- mTaskList.getTaskKeys(mThumbnailCache.getCacheSize(), taskGroups -> {
- for (GroupTask group : taskGroups) {
- if (group.containsTask(runningTaskId)) {
+ mTaskList.getTaskKeys(mThumbnailCache.getCacheSize(), tasks -> {
+ for (Task task : tasks) {
+ if (task.key.id == runningTaskId) {
// Skip the running task, it's not going to have an up-to-date snapshot by the
// time the user next enters overview
continue;
}
- mThumbnailCache.updateThumbnailInCache(group.task1);
- mThumbnailCache.updateThumbnailInCache(group.task2);
+ mThumbnailCache.updateThumbnailInCache(task);
}
});
}
@Override
- public boolean onTaskSnapshotChanged(int taskId, ThumbnailData snapshot) {
+ public void onTaskSnapshotChanged(int taskId, ThumbnailData snapshot) {
mThumbnailCache.updateTaskSnapShot(taskId, snapshot);
for (int i = mThumbnailChangeListeners.size() - 1; i >= 0; i--) {
@@ -174,12 +170,11 @@ public class RecentsModel implements IconChangeListener, TaskStackChangeListener
task.thumbnail = snapshot;
}
}
- return true;
}
@Override
public void onTaskRemoved(int taskId) {
- Task.TaskKey stubKey = new Task.TaskKey(taskId, 0, new Intent(), null, 0, 0);
+ Task.TaskKey stubKey = new Task.TaskKey(taskId, 0, null, null, 0, 0);
mThumbnailCache.remove(stubKey);
mIconCache.onTaskRemoved(stubKey);
}
@@ -222,11 +217,6 @@ public class RecentsModel implements IconChangeListener, TaskStackChangeListener
mThumbnailChangeListeners.remove(listener);
}
- public void dump(String prefix, PrintWriter writer) {
- writer.println(prefix + "RecentsModel:");
- mTaskList.dump(" ", writer);
- }
-
/**
* Listener for receiving various task properties changes
*/
diff --git a/quickstep/src/com/android/quickstep/RemoteAnimationTargets.java b/quickstep/src/com/android/quickstep/RemoteAnimationTargets.java
index b20d48806a..c032889db5 100644
--- a/quickstep/src/com/android/quickstep/RemoteAnimationTargets.java
+++ b/quickstep/src/com/android/quickstep/RemoteAnimationTargets.java
@@ -77,12 +77,8 @@ public class RemoteAnimationTargets {
* Gets the navigation bar remote animation target if exists.
*/
public RemoteAnimationTargetCompat getNavBarRemoteAnimationTarget() {
- return getNonAppTargetOfType(TYPE_NAVIGATION_BAR);
- }
-
- public RemoteAnimationTargetCompat getNonAppTargetOfType(int type) {
for (RemoteAnimationTargetCompat target : nonApps) {
- if (target.windowType == type) {
+ if (target.windowType == TYPE_NAVIGATION_BAR) {
return target;
}
}
diff --git a/quickstep/src/com/android/quickstep/RemoteTargetGluer.java b/quickstep/src/com/android/quickstep/RemoteTargetGluer.java
deleted file mode 100644
index c3ea25683d..0000000000
--- a/quickstep/src/com/android/quickstep/RemoteTargetGluer.java
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
- * Copyright (C) 2021 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.quickstep;
-
-import android.content.Context;
-
-import androidx.annotation.Nullable;
-
-import com.android.launcher3.util.SplitConfigurationOptions.StagedSplitBounds;
-import com.android.quickstep.util.AnimatorControllerWithResistance;
-import com.android.quickstep.util.TaskViewSimulator;
-import com.android.quickstep.util.TransformParams;
-import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
-
-import java.util.ArrayList;
-
-/**
- * Glues together the necessary components to animate a remote target using a
- * {@link TaskViewSimulator}
- */
-public class RemoteTargetGluer {
- private RemoteTargetHandle[] mRemoteTargetHandles;
- private StagedSplitBounds mStagedSplitBounds;
-
- /**
- * Use this constructor if remote targets are split-screen independent
- */
- public RemoteTargetGluer(Context context, BaseActivityInterface sizingStrategy,
- RemoteAnimationTargets targets) {
- mRemoteTargetHandles = createHandles(context, sizingStrategy, targets.apps.length);
- }
-
- /**
- * Use this constructor if you want the number of handles created to match the number of active
- * running tasks
- */
- public RemoteTargetGluer(Context context, BaseActivityInterface sizingStrategy) {
- int[] splitIds = TopTaskTracker.INSTANCE.get(context).getRunningSplitTaskIds();
- mRemoteTargetHandles = createHandles(context, sizingStrategy, splitIds.length == 2 ? 2 : 1);
- }
-
- private RemoteTargetHandle[] createHandles(Context context,
- BaseActivityInterface sizingStrategy, int numHandles) {
- RemoteTargetHandle[] handles = new RemoteTargetHandle[numHandles];
- for (int i = 0; i < numHandles; i++) {
- TaskViewSimulator tvs = new TaskViewSimulator(context, sizingStrategy);
- TransformParams transformParams = new TransformParams();
- handles[i] = new RemoteTargetHandle(tvs, transformParams);
- }
- return handles;
- }
-
- /**
- * Pairs together {@link TaskViewSimulator}s and {@link TransformParams} into a
- * {@link RemoteTargetHandle}
- * Assigns only the apps associated with {@param targets} into their own TaskViewSimulators.
- * Length of targets.apps should match that of {@link #mRemoteTargetHandles}.
- *
- * If split screen may be active when this is called, you might want to use
- * {@link #assignTargetsForSplitScreen(Context, RemoteAnimationTargets)}
- */
- public RemoteTargetHandle[] assignTargets(RemoteAnimationTargets targets) {
- for (int i = 0; i < mRemoteTargetHandles.length; i++) {
- RemoteAnimationTargetCompat primaryTaskTarget = targets.apps[i];
- mRemoteTargetHandles[i].mTransformParams.setTargetSet(
- createRemoteAnimationTargetsForTarget(targets, null));
- mRemoteTargetHandles[i].mTaskViewSimulator.setPreview(primaryTaskTarget, null);
- }
- return mRemoteTargetHandles;
- }
-
- /**
- * Similar to {@link #assignTargets(RemoteAnimationTargets)}, except this matches the
- * apps in targets.apps to that of the _active_ split screened tasks.
- * See {@link #assignTargetsForSplitScreen(RemoteAnimationTargets, int[])}
- */
- public RemoteTargetHandle[] assignTargetsForSplitScreen(
- Context context, RemoteAnimationTargets targets) {
- int[] splitIds = TopTaskTracker.INSTANCE.get(context).getRunningSplitTaskIds();
- return assignTargetsForSplitScreen(targets, splitIds);
- }
-
- /**
- * Assigns the provided splitIDs to the {@link #mRemoteTargetHandles}, with index 0 will being
- * the left/top task, index 1 right/bottom
- */
- public RemoteTargetHandle[] assignTargetsForSplitScreen(RemoteAnimationTargets targets,
- int[] splitIds) {
- RemoteAnimationTargetCompat topLeftTarget; // only one set if single/fullscreen task
- RemoteAnimationTargetCompat bottomRightTarget;
- if (mRemoteTargetHandles.length == 1) {
- // If we're not in split screen, the splitIds count doesn't really matter since we
- // should always hit this case.
- mRemoteTargetHandles[0].mTransformParams.setTargetSet(targets);
- if (targets.apps.length > 0) {
- // Unclear why/when target.apps length == 0, but it sure does happen :(
- topLeftTarget = targets.apps[0];
- mRemoteTargetHandles[0].mTaskViewSimulator.setPreview(topLeftTarget, null);
- }
- } else {
- // split screen
- topLeftTarget = targets.findTask(splitIds[0]);
- bottomRightTarget = targets.findTask(splitIds[1]);
-
- // remoteTargetHandle[0] denotes topLeft task, so we pass in the bottomRight to exclude,
- // vice versa
- mStagedSplitBounds = new StagedSplitBounds(
- topLeftTarget.startScreenSpaceBounds,
- bottomRightTarget.startScreenSpaceBounds, splitIds[0], splitIds[1]);
- mRemoteTargetHandles[0].mTransformParams.setTargetSet(
- createRemoteAnimationTargetsForTarget(targets, bottomRightTarget));
- mRemoteTargetHandles[0].mTaskViewSimulator.setPreview(topLeftTarget,
- mStagedSplitBounds);
-
- mRemoteTargetHandles[1].mTransformParams.setTargetSet(
- createRemoteAnimationTargetsForTarget(targets, topLeftTarget));
- mRemoteTargetHandles[1].mTaskViewSimulator.setPreview(bottomRightTarget,
- mStagedSplitBounds);
- }
- return mRemoteTargetHandles;
- }
-
- /**
- * Ensures that we aren't excluding ancillary targets such as home/recents
- *
- * @param targetToExclude Will be excluded from the resulting return value.
- * Pass in {@code null} to not exclude anything
- * @return RemoteAnimationTargets where all the app targets from the passed in
- * {@param targets} are included except {@param targetToExclude}
- */
- private RemoteAnimationTargets createRemoteAnimationTargetsForTarget(
- RemoteAnimationTargets targets,
- RemoteAnimationTargetCompat targetToExclude) {
- ArrayList<RemoteAnimationTargetCompat> targetsWithoutExcluded =
- new ArrayList<RemoteAnimationTargetCompat>();
-
- for (RemoteAnimationTargetCompat targetCompat : targets.unfilteredApps) {
- if (targetCompat == targetToExclude) {
- continue;
- }
- if (targetToExclude != null
- && targetToExclude.taskInfo != null
- && targetCompat.taskInfo != null
- && targetToExclude.taskInfo.parentTaskId == targetCompat.taskInfo.taskId) {
- // Also exclude corresponding parent task
- continue;
- }
-
- targetsWithoutExcluded.add(targetCompat);
- }
- final RemoteAnimationTargetCompat[] filteredApps =
- targetsWithoutExcluded.toArray(
- new RemoteAnimationTargetCompat[targetsWithoutExcluded.size()]);
- return new RemoteAnimationTargets(
- filteredApps, targets.wallpapers, targets.nonApps, targets.targetMode);
- }
-
- public RemoteTargetHandle[] getRemoteTargetHandles() {
- return mRemoteTargetHandles;
- }
-
- public StagedSplitBounds getStagedSplitBounds() {
- return mStagedSplitBounds;
- }
-
- /**
- * Container to keep together all the associated objects whose properties need to be updated to
- * animate a single remote app target
- */
- public static class RemoteTargetHandle {
- private final TaskViewSimulator mTaskViewSimulator;
- private final TransformParams mTransformParams;
- @Nullable
- private AnimatorControllerWithResistance mPlaybackController;
-
- public RemoteTargetHandle(TaskViewSimulator taskViewSimulator,
- TransformParams transformParams) {
- mTransformParams = transformParams;
- mTaskViewSimulator = taskViewSimulator;
- }
-
- public TaskViewSimulator getTaskViewSimulator() {
- return mTaskViewSimulator;
- }
-
- public TransformParams getTransformParams() {
- return mTransformParams;
- }
-
- @Nullable
- public AnimatorControllerWithResistance getPlaybackController() {
- return mPlaybackController;
- }
-
- public void setPlaybackController(
- @Nullable AnimatorControllerWithResistance playbackController) {
- mPlaybackController = playbackController;
- }
- }
-}
diff --git a/quickstep/src/com/android/quickstep/RotationTouchHelper.java b/quickstep/src/com/android/quickstep/RotationTouchHelper.java
index f1e20dbb04..678b176151 100644
--- a/quickstep/src/com/android/quickstep/RotationTouchHelper.java
+++ b/quickstep/src/com/android/quickstep/RotationTouchHelper.java
@@ -15,19 +15,17 @@
*/
package com.android.quickstep;
-import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.Surface.ROTATION_0;
import static com.android.launcher3.util.DisplayController.CHANGE_ACTIVE_SCREEN;
import static com.android.launcher3.util.DisplayController.CHANGE_ALL;
-import static com.android.launcher3.util.DisplayController.CHANGE_NAVIGATION_MODE;
import static com.android.launcher3.util.DisplayController.CHANGE_ROTATION;
-import static com.android.launcher3.util.DisplayController.CHANGE_SUPPORTED_BOUNDS;
-import static com.android.launcher3.util.DisplayController.NavigationMode.THREE_BUTTONS;
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
+import static com.android.quickstep.SysUINavigationMode.Mode.THREE_BUTTONS;
import android.content.Context;
import android.content.res.Resources;
+import android.util.Log;
import android.view.MotionEvent;
import android.view.OrientationEventListener;
@@ -35,9 +33,9 @@ import com.android.launcher3.testing.TestProtocol;
import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.DisplayController.DisplayInfoChangeListener;
import com.android.launcher3.util.DisplayController.Info;
-import com.android.launcher3.util.DisplayController.NavigationMode;
import com.android.launcher3.util.MainThreadInitializedObject;
import com.android.quickstep.util.RecentsOrientedState;
+import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.QuickStepContract;
import com.android.systemui.shared.system.TaskStackChangeListener;
import com.android.systemui.shared.system.TaskStackChangeListeners;
@@ -45,22 +43,22 @@ import com.android.systemui.shared.system.TaskStackChangeListeners;
import java.io.PrintWriter;
import java.util.ArrayList;
-/**
- * Helper class for transforming touch events
- */
-public class RotationTouchHelper implements DisplayInfoChangeListener {
+public class RotationTouchHelper implements
+ SysUINavigationMode.NavigationModeChangeListener,
+ DisplayInfoChangeListener {
public static final MainThreadInitializedObject<RotationTouchHelper> INSTANCE =
new MainThreadInitializedObject<>(RotationTouchHelper::new);
private OrientationTouchTransformer mOrientationTouchTransformer;
private DisplayController mDisplayController;
+ private SysUINavigationMode mSysUiNavMode;
private int mDisplayId;
private int mDisplayRotation;
private final ArrayList<Runnable> mOnDestroyActions = new ArrayList<>();
- private NavigationMode mMode = THREE_BUTTONS;
+ private SysUINavigationMode.Mode mMode = THREE_BUTTONS;
private TaskStackChangeListener mFrozenTaskListener = new TaskStackChangeListener() {
@Override
@@ -74,6 +72,7 @@ public class RotationTouchHelper implements DisplayInfoChangeListener {
@Override
public void onActivityRotation(int displayId) {
+ super.onActivityRotation(displayId);
// This always gets called before onDisplayInfoChanged() so we know how to process
// the rotation in that method. This is done to avoid having a race condition between
// the sensor readings and onDisplayInfoChanged() call
@@ -146,16 +145,16 @@ public class RotationTouchHelper implements DisplayInfoChangeListener {
}
mDisplayController = DisplayController.INSTANCE.get(mContext);
Resources resources = mContext.getResources();
- mDisplayId = DEFAULT_DISPLAY;
+ mSysUiNavMode = SysUINavigationMode.INSTANCE.get(mContext);
+ mDisplayId = mDisplayController.getInfo().id;
mOrientationTouchTransformer = new OrientationTouchTransformer(resources, mMode,
- () -> QuickStepContract.getWindowCornerRadius(mContext));
+ () -> QuickStepContract.getWindowCornerRadius(resources));
// Register for navigation mode changes
- mDisplayController.addChangeListener(this);
- DisplayController.Info info = mDisplayController.getInfo();
- onDisplayInfoChangedInternal(info, CHANGE_ALL, info.navigationMode.hasGestures);
- runOnDestroy(() -> mDisplayController.removeChangeListener(this));
+ SysUINavigationMode.Mode newMode = mSysUiNavMode.addModeChangeListener(this);
+ onNavModeChangedInternal(newMode, newMode.hasGestures);
+ runOnDestroy(() -> mSysUiNavMode.removeModeChangeListener(this));
mOrientationListener = new OrientationEventListener(mContext) {
@Override
@@ -244,57 +243,66 @@ public class RotationTouchHelper implements DisplayInfoChangeListener {
event.getY(pointerIndex));
}
+
@Override
- public void onDisplayInfoChanged(Context context, Info info, int flags) {
- onDisplayInfoChangedInternal(info, flags, false);
+ public void onNavigationModeChanged(SysUINavigationMode.Mode newMode) {
+ onNavModeChangedInternal(newMode, false);
}
- private void onDisplayInfoChangedInternal(Info info, int flags, boolean forceRegister) {
- if ((flags & (CHANGE_ROTATION | CHANGE_ACTIVE_SCREEN | CHANGE_NAVIGATION_MODE
- | CHANGE_SUPPORTED_BOUNDS)) != 0) {
- mDisplayRotation = info.rotation;
-
- if (mMode.hasGestures) {
- updateGestureTouchRegions();
- mOrientationTouchTransformer.createOrAddTouchRegion(info);
- mCurrentAppRotation = mDisplayRotation;
-
- /* Update nav bars on the following:
- * a) if this is coming from an activity rotation OR
- * aa) we launch an app in the orientation that user is already in
- * b) We're not in overview, since overview will always be portrait (w/o home
- * rotation)
- * c) We're actively in quickswitch mode
- */
- if ((mPrioritizeDeviceRotation
- || mCurrentAppRotation == mSensorRotation)
- // switch to an app of orientation user is in
- && !mInOverview
- && mTaskListFrozen) {
- toggleSecondaryNavBarsForRotation();
- }
- }
- }
-
- if ((flags & CHANGE_NAVIGATION_MODE) != 0) {
- NavigationMode newMode = info.navigationMode;
- mOrientationTouchTransformer.setNavigationMode(newMode, mDisplayController.getInfo(),
- mContext.getResources());
+ /**
+ * @param forceRegister if {@code true}, this will register {@link #mFrozenTaskListener} via
+ * {@link #setupOrientationSwipeHandler()}
+ */
+ private void onNavModeChangedInternal(SysUINavigationMode.Mode newMode, boolean forceRegister) {
+ mDisplayController.removeChangeListener(this);
+ mDisplayController.addChangeListener(this);
+ onDisplayInfoChanged(mContext, mDisplayController.getInfo(), CHANGE_ALL);
- if (forceRegister || (!mMode.hasGestures && newMode.hasGestures)) {
- setupOrientationSwipeHandler();
- } else if (mMode.hasGestures && !newMode.hasGestures) {
- destroyOrientationSwipeHandlerCallback();
- }
+ mOrientationTouchTransformer.setNavigationMode(newMode, mDisplayController.getInfo(),
+ mContext.getResources());
- mMode = newMode;
+ if (forceRegister || (!mMode.hasGestures && newMode.hasGestures)) {
+ setupOrientationSwipeHandler();
+ } else if (mMode.hasGestures && !newMode.hasGestures){
+ destroyOrientationSwipeHandlerCallback();
}
+
+ mMode = newMode;
}
public int getDisplayRotation() {
return mDisplayRotation;
}
+ @Override
+ public void onDisplayInfoChanged(Context context, Info info, int flags) {
+ if ((flags & (CHANGE_ROTATION | CHANGE_ACTIVE_SCREEN)) == 0) {
+ return;
+ }
+
+ mDisplayRotation = info.rotation;
+
+ if (!mMode.hasGestures) {
+ return;
+ }
+ updateGestureTouchRegions();
+ mOrientationTouchTransformer.createOrAddTouchRegion(info);
+ mCurrentAppRotation = mDisplayRotation;
+
+ /* Update nav bars on the following:
+ * a) if this is coming from an activity rotation OR
+ * aa) we launch an app in the orientation that user is already in
+ * b) We're not in overview, since overview will always be portrait (w/o home rotation)
+ * c) We're actively in quickswitch mode
+ */
+ if ((mPrioritizeDeviceRotation
+ || mCurrentAppRotation == mSensorRotation) // switch to an app of orientation user is in
+ && !mInOverview
+ && mTaskListFrozen) {
+ toggleSecondaryNavBarsForRotation();
+ }
+ }
+
/**
* Sets the gestural height.
*/
diff --git a/quickstep/src/com/android/quickstep/SimpleOrientationTouchTransformer.java b/quickstep/src/com/android/quickstep/SimpleOrientationTouchTransformer.java
deleted file mode 100644
index f474796962..0000000000
--- a/quickstep/src/com/android/quickstep/SimpleOrientationTouchTransformer.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2021 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.quickstep;
-
-import static com.android.launcher3.util.DisplayController.CHANGE_ACTIVE_SCREEN;
-import static com.android.launcher3.util.DisplayController.CHANGE_ALL;
-import static com.android.launcher3.util.DisplayController.CHANGE_ROTATION;
-
-import android.content.Context;
-import android.view.MotionEvent;
-
-import com.android.launcher3.util.DisplayController;
-import com.android.launcher3.util.MainThreadInitializedObject;
-
-public class SimpleOrientationTouchTransformer implements
- DisplayController.DisplayInfoChangeListener {
-
- public static final MainThreadInitializedObject<SimpleOrientationTouchTransformer> INSTANCE =
- new MainThreadInitializedObject<>(SimpleOrientationTouchTransformer::new);
-
- private OrientationRectF mOrientationRectF;
-
- public SimpleOrientationTouchTransformer(Context context) {
- DisplayController.INSTANCE.get(context).addChangeListener(this);
- onDisplayInfoChanged(context, DisplayController.INSTANCE.get(context).getInfo(),
- CHANGE_ALL);
- }
-
- @Override
- public void onDisplayInfoChanged(Context context, DisplayController.Info info, int flags) {
- if ((flags & (CHANGE_ROTATION | CHANGE_ACTIVE_SCREEN)) == 0) {
- return;
- }
- mOrientationRectF = new OrientationRectF(0, 0, info.currentSize.y, info.currentSize.x,
- info.rotation);
- }
-
- public void transform(MotionEvent ev, int rotation) {
- mOrientationRectF.applyTransformToRotation(ev, rotation, true /* forceTransform */);
- }
-}
diff --git a/quickstep/src/com/android/quickstep/SwipeUpAnimationLogic.java b/quickstep/src/com/android/quickstep/SwipeUpAnimationLogic.java
index 966710854f..44954555b0 100644
--- a/quickstep/src/com/android/quickstep/SwipeUpAnimationLogic.java
+++ b/quickstep/src/com/android/quickstep/SwipeUpAnimationLogic.java
@@ -17,7 +17,7 @@ package com.android.quickstep;
import static com.android.launcher3.anim.Interpolators.ACCEL_1_5;
import static com.android.launcher3.anim.Interpolators.LINEAR;
-import static com.android.launcher3.config.FeatureFlags.ENABLE_SPLIT_SELECT;
+import static com.android.launcher3.config.FeatureFlags.PROTOTYPE_APP_CLOSE;
import android.animation.Animator;
import android.content.Context;
@@ -27,6 +27,7 @@ import android.graphics.Rect;
import android.graphics.RectF;
import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
import androidx.annotation.UiThread;
import com.android.launcher3.DeviceProfile;
@@ -35,31 +36,28 @@ import com.android.launcher3.anim.AnimationSuccessListener;
import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.anim.PendingAnimation;
import com.android.launcher3.touch.PagedOrientationHandler;
-import com.android.quickstep.RemoteTargetGluer.RemoteTargetHandle;
import com.android.quickstep.util.AnimatorControllerWithResistance;
+import com.android.quickstep.util.AppCloseConfig;
import com.android.quickstep.util.RectFSpringAnim;
+import com.android.quickstep.util.RectFSpringAnim2;
import com.android.quickstep.util.TaskViewSimulator;
import com.android.quickstep.util.TransformParams;
import com.android.quickstep.util.TransformParams.BuilderProxy;
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat.SurfaceParams.Builder;
-import java.util.Arrays;
-import java.util.function.Consumer;
-
-public abstract class SwipeUpAnimationLogic implements
- RecentsAnimationCallbacks.RecentsAnimationListener{
+public abstract class SwipeUpAnimationLogic {
protected static final Rect TEMP_RECT = new Rect();
- protected final RemoteTargetGluer mTargetGluer;
protected DeviceProfile mDp;
protected final Context mContext;
protected final RecentsAnimationDeviceState mDeviceState;
protected final GestureState mGestureState;
+ protected final TaskViewSimulator mTaskViewSimulator;
- protected RemoteTargetHandle[] mRemoteTargetHandles;
+ protected final TransformParams mTransformParams;
// Shift in the range of [0, 1].
// 0 => preview snapShot is completely visible, and hotseat is completely translated down
@@ -72,47 +70,37 @@ public abstract class SwipeUpAnimationLogic implements
// How much further we can drag past recents, as a factor of mTransitionDragLength.
protected float mDragLengthFactor = 1;
- protected boolean mIsSwipeForStagedSplit;
+ protected AnimatorControllerWithResistance mWindowTransitionController;
public SwipeUpAnimationLogic(Context context, RecentsAnimationDeviceState deviceState,
- GestureState gestureState) {
+ GestureState gestureState, TransformParams transformParams) {
mContext = context;
mDeviceState = deviceState;
mGestureState = gestureState;
+ mTaskViewSimulator = new TaskViewSimulator(context, gestureState.getActivityInterface());
+ mTransformParams = transformParams;
- mIsSwipeForStagedSplit = ENABLE_SPLIT_SELECT.get() &&
- TopTaskTracker.INSTANCE.get(context).getRunningSplitTaskIds().length > 1;
-
- mTargetGluer = new RemoteTargetGluer(mContext, mGestureState.getActivityInterface());
- mRemoteTargetHandles = mTargetGluer.getRemoteTargetHandles();
- runActionOnRemoteHandles(remoteTargetHandle ->
- remoteTargetHandle.getTaskViewSimulator().getOrientationState().update(
- mDeviceState.getRotationTouchHelper().getCurrentActiveRotation(),
- mDeviceState.getRotationTouchHelper().getDisplayRotation()
- ));
+ mTaskViewSimulator.getOrientationState().update(
+ mDeviceState.getRotationTouchHelper().getCurrentActiveRotation(),
+ mDeviceState.getRotationTouchHelper().getDisplayRotation());
}
protected void initTransitionEndpoints(DeviceProfile dp) {
mDp = dp;
+
+ mTaskViewSimulator.setDp(dp);
mTransitionDragLength = mGestureState.getActivityInterface().getSwipeUpDestinationAndLength(
- dp, mContext, TEMP_RECT, mRemoteTargetHandles[0].getTaskViewSimulator()
- .getOrientationState().getOrientationHandler());
+ dp, mContext, TEMP_RECT,
+ mTaskViewSimulator.getOrientationState().getOrientationHandler());
mDragLengthFactor = (float) dp.heightPx / mTransitionDragLength;
- for (RemoteTargetHandle remoteHandle : mRemoteTargetHandles) {
- PendingAnimation pendingAnimation = new PendingAnimation(mTransitionDragLength * 2);
- TaskViewSimulator taskViewSimulator = remoteHandle.getTaskViewSimulator();
- taskViewSimulator.setDp(dp);
- taskViewSimulator.addAppToOverviewAnim(pendingAnimation, LINEAR);
- AnimatorPlaybackController playbackController =
- pendingAnimation.createPlaybackController();
-
- remoteHandle.setPlaybackController(AnimatorControllerWithResistance.createForRecents(
- playbackController, mContext, taskViewSimulator.getOrientationState(),
- mDp, taskViewSimulator.recentsViewScale, AnimatedFloat.VALUE,
- taskViewSimulator.recentsViewSecondaryTranslation, AnimatedFloat.VALUE
- ));
- }
+ PendingAnimation pa = new PendingAnimation(mTransitionDragLength * 2);
+ mTaskViewSimulator.addAppToOverviewAnim(pa, LINEAR);
+ AnimatorPlaybackController normalController = pa.createPlaybackController();
+ mWindowTransitionController = AnimatorControllerWithResistance.createForRecents(
+ normalController, mContext, mTaskViewSimulator.getOrientationState(),
+ mDp, mTaskViewSimulator.recentsViewScale, AnimatedFloat.VALUE,
+ mTaskViewSimulator.recentsViewSecondaryTranslation, AnimatedFloat.VALUE);
}
@UiThread
@@ -137,9 +125,7 @@ public abstract class SwipeUpAnimationLogic implements
public abstract void updateFinalShift();
protected PagedOrientationHandler getOrientationHandler() {
- // OrientationHandler should be independent of remote target, can directly take one
- return mRemoteTargetHandles[0].getTaskViewSimulator()
- .getOrientationState().getOrientationHandler();
+ return mTaskViewSimulator.getOrientationState().getOrientationHandler();
}
protected abstract class HomeAnimationFactory {
@@ -175,13 +161,28 @@ public abstract class SwipeUpAnimationLogic implements
// No-op
}
+ public boolean shouldPlayAtomicWorkspaceReveal() {
+ return true;
+ }
+
public void setAnimation(RectFSpringAnim anim) { }
- public void update(RectF currentRect, float progress, float radius) { }
+ public boolean keepWindowOpaque() { return false; }
+
+ public void update(@Nullable AppCloseConfig config, RectF currentRect, float progress,
+ float radius) { }
public void onCancel() { }
/**
+ * @return {@code true} if this factory supports animating an Activity to PiP window on
+ * swiping up to home.
+ */
+ public boolean supportSwipePipToHome() {
+ return false;
+ }
+
+ /**
* @param progress The progress of the animation to the home screen.
* @return The current alpha to set on the animating app window.
*/
@@ -206,35 +207,16 @@ public abstract class SwipeUpAnimationLogic implements
* @param startProgress The progress of {@link #mCurrentShift} to start thw window from.
* @return {@link RectF} represents the bounds as starting point in window space.
*/
- protected RectF[] updateProgressForStartRect(Matrix[] outMatrix, float startProgress) {
+ protected RectF updateProgressForStartRect(Matrix outMatrix, float startProgress) {
mCurrentShift.updateValue(startProgress);
- RectF[] startRects = new RectF[mRemoteTargetHandles.length];
- for (int i = 0, mRemoteTargetHandlesLength = mRemoteTargetHandles.length;
- i < mRemoteTargetHandlesLength; i++) {
- RemoteTargetHandle remoteHandle = mRemoteTargetHandles[i];
- TaskViewSimulator tvs = remoteHandle.getTaskViewSimulator();
- tvs.apply(remoteHandle.getTransformParams().setProgress(startProgress));
-
- startRects[i] = new RectF(tvs.getCurrentCropRect());
- outMatrix[i] = new Matrix();
- tvs.applyWindowToHomeRotation(outMatrix[i]);
- tvs.getCurrentMatrix().mapRect(startRects[i]);
- }
- return startRects;
- }
+ mTaskViewSimulator.apply(mTransformParams.setProgress(startProgress));
+ RectF cropRectF = new RectF(mTaskViewSimulator.getCurrentCropRect());
- /** Helper to avoid writing some for-loops to iterate over {@link #mRemoteTargetHandles} */
- protected void runActionOnRemoteHandles(Consumer<RemoteTargetHandle> consumer) {
- for (RemoteTargetHandle handle : mRemoteTargetHandles) {
- consumer.accept(handle);
- }
- }
+ mTaskViewSimulator.applyWindowToHomeRotation(outMatrix);
- /** @return only the TaskViewSimulators from {@link #mRemoteTargetHandles} */
- protected TaskViewSimulator[] getRemoteTaskViewSimulators() {
- return Arrays.stream(mRemoteTargetHandles)
- .map(remoteTargetHandle -> remoteTargetHandle.getTaskViewSimulator())
- .toArray(TaskViewSimulator[]::new);
+ final RectF startRect = new RectF(cropRectF);
+ mTaskViewSimulator.getCurrentMatrix().mapRect(startRect);
+ return startRect;
}
/**
@@ -242,48 +224,33 @@ public abstract class SwipeUpAnimationLogic implements
* @param startProgress The progress of {@link #mCurrentShift} to start the window from.
* @param homeAnimationFactory The home animation factory.
*/
- protected RectFSpringAnim[] createWindowAnimationToHome(float startProgress,
+ protected RectFSpringAnim createWindowAnimationToHome(float startProgress,
HomeAnimationFactory homeAnimationFactory) {
- // TODO(b/195473584) compute separate end targets for different staged split
final RectF targetRect = homeAnimationFactory.getWindowTargetRect();
- RectFSpringAnim[] out = new RectFSpringAnim[mRemoteTargetHandles.length];
- Matrix[] homeToWindowPositionMap = new Matrix[mRemoteTargetHandles.length];
- RectF[] startRects = updateProgressForStartRect(homeToWindowPositionMap, startProgress);
- for (int i = 0, mRemoteTargetHandlesLength = mRemoteTargetHandles.length;
- i < mRemoteTargetHandlesLength; i++) {
- RemoteTargetHandle remoteHandle = mRemoteTargetHandles[i];
- out[i] = getWindowAnimationToHomeInternal(homeAnimationFactory,
- targetRect, remoteHandle.getTransformParams(),
- remoteHandle.getTaskViewSimulator(), startRects[i], homeToWindowPositionMap[i]);
- }
- return out;
- }
- private RectFSpringAnim getWindowAnimationToHomeInternal(
- HomeAnimationFactory homeAnimationFactory, RectF targetRect,
- TransformParams transformParams, TaskViewSimulator taskViewSimulator,
- RectF startRect, Matrix homeToWindowPositionMap) {
- RectF cropRectF = new RectF(taskViewSimulator.getCurrentCropRect());
+ Matrix homeToWindowPositionMap = new Matrix();
+ final RectF startRect = updateProgressForStartRect(homeToWindowPositionMap, startProgress);
+ RectF cropRectF = new RectF(mTaskViewSimulator.getCurrentCropRect());
+
// Move the startRect to Launcher space as floatingIconView runs in Launcher
Matrix windowToHomePositionMap = new Matrix();
-
- // If the start rect ends up overshooting too much to the left/right offscreen, bring it
- // back to fullscreen. This can happen when the recentsScroll value isn't aligned with
- // the pageScroll value for a given taskView, see b/228829958#comment12
- mRemoteTargetHandles[0].getTaskViewSimulator().getOrientationState().getOrientationHandler()
- .fixBoundsForHomeAnimStartRect(startRect, mDp);
-
homeToWindowPositionMap.invert(windowToHomePositionMap);
windowToHomePositionMap.mapRect(startRect);
- RectFSpringAnim anim = new RectFSpringAnim(startRect, targetRect, mContext, mDp);
+ RectFSpringAnim anim;
+ if (PROTOTYPE_APP_CLOSE.get()) {
+ anim = new RectFSpringAnim2(startRect, targetRect, mContext,
+ mTaskViewSimulator.getCurrentCornerRadius(),
+ homeAnimationFactory.getEndRadius(cropRectF));
+ } else {
+ anim = new RectFSpringAnim(startRect, targetRect, mContext);
+ }
homeAnimationFactory.setAnimation(anim);
SpringAnimationRunner runner = new SpringAnimationRunner(
- homeAnimationFactory, cropRectF, homeToWindowPositionMap,
- transformParams, taskViewSimulator);
- anim.addAnimatorListener(runner);
+ homeAnimationFactory, cropRectF, homeToWindowPositionMap);
anim.addOnUpdateListener(runner);
+ anim.addAnimatorListener(runner);
return anim;
}
@@ -295,7 +262,6 @@ public abstract class SwipeUpAnimationLogic implements
final RectF mWindowCurrentRect = new RectF();
final Matrix mHomeToWindowPositionMap;
- private final TransformParams mLocalTransformParams;
final HomeAnimationFactory mAnimationFactory;
final AnimatorPlaybackController mHomeAnim;
@@ -305,36 +271,41 @@ public abstract class SwipeUpAnimationLogic implements
final float mEndRadius;
SpringAnimationRunner(HomeAnimationFactory factory, RectF cropRectF,
- Matrix homeToWindowPositionMap, TransformParams transformParams,
- TaskViewSimulator taskViewSimulator) {
+ Matrix homeToWindowPositionMap) {
mAnimationFactory = factory;
mHomeAnim = factory.createActivityAnimationToHome();
mCropRectF = cropRectF;
mHomeToWindowPositionMap = homeToWindowPositionMap;
- mLocalTransformParams = transformParams;
cropRectF.roundOut(mCropRect);
// End on a "round-enough" radius so that the shape reveal doesn't have to do too much
// rounding at the end of the animation.
- mStartRadius = taskViewSimulator.getCurrentCornerRadius();
+ mStartRadius = mTaskViewSimulator.getCurrentCornerRadius();
mEndRadius = factory.getEndRadius(cropRectF);
}
@Override
- public void onUpdate(RectF currentRect, float progress) {
+ public void onUpdate(@Nullable AppCloseConfig config, RectF currentRect, float progress) {
mHomeAnim.setPlayFraction(progress);
mHomeToWindowPositionMap.mapRect(mWindowCurrentRect, currentRect);
mMatrix.setRectToRect(mCropRectF, mWindowCurrentRect, ScaleToFit.FILL);
float cornerRadius = Utilities.mapRange(progress, mStartRadius, mEndRadius);
float alpha = mAnimationFactory.getWindowAlpha(progress);
- mLocalTransformParams
+ if (config != null && PROTOTYPE_APP_CLOSE.get()) {
+ alpha = config.getWindowAlpha();
+ cornerRadius = config.getCornerRadius();
+ }
+ if (mAnimationFactory.keepWindowOpaque()) {
+ alpha = 1f;
+ }
+ mTransformParams
.setTargetAlpha(alpha)
.setCornerRadius(cornerRadius);
- mLocalTransformParams.applySurfaceParams(mLocalTransformParams
- .createSurfaceParams(this));
- mAnimationFactory.update(currentRect, progress, mMatrix.mapRadius(cornerRadius));
+ mTransformParams.applySurfaceParams(mTransformParams.createSurfaceParams(this));
+ mAnimationFactory.update(config, currentRect, progress,
+ mMatrix.mapRadius(cornerRadius));
}
@Override
diff --git a/quickstep/src/com/android/quickstep/SysUINavigationMode.java b/quickstep/src/com/android/quickstep/SysUINavigationMode.java
new file mode 100644
index 0000000000..74f4bea2a8
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/SysUINavigationMode.java
@@ -0,0 +1,202 @@
+/*
+ * 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.
+ */
+
+package com.android.quickstep;
+
+import static com.android.launcher3.ResourceUtils.INVALID_RESOURCE_HANDLE;
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_NAVIGATION_MODE_2_BUTTON;
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_NAVIGATION_MODE_3_BUTTON;
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_NAVIGATION_MODE_GESTURE_BUTTON;
+import static com.android.launcher3.util.PackageManagerHelper.getPackageFilter;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.util.Log;
+
+import com.android.launcher3.ResourceUtils;
+import com.android.launcher3.logging.StatsLogManager.LauncherEvent;
+import com.android.launcher3.util.MainThreadInitializedObject;
+
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+/**
+ * Observer for the resource config that specifies the navigation bar mode.
+ */
+public class SysUINavigationMode {
+
+ public enum Mode {
+ THREE_BUTTONS(false, 0, LAUNCHER_NAVIGATION_MODE_3_BUTTON),
+ TWO_BUTTONS(true, 1, LAUNCHER_NAVIGATION_MODE_2_BUTTON),
+ NO_BUTTON(true, 2, LAUNCHER_NAVIGATION_MODE_GESTURE_BUTTON);
+
+ public final boolean hasGestures;
+ public final int resValue;
+ public final LauncherEvent launcherEvent;
+
+ Mode(boolean hasGestures, int resValue, LauncherEvent launcherEvent) {
+ this.hasGestures = hasGestures;
+ this.resValue = resValue;
+ this.launcherEvent = launcherEvent;
+ }
+ }
+
+ public static Mode getMode(Context context) {
+ return INSTANCE.get(context).getMode();
+ }
+
+ public static final MainThreadInitializedObject<SysUINavigationMode> INSTANCE =
+ new MainThreadInitializedObject<>(SysUINavigationMode::new);
+
+ private static final String TAG = "SysUINavigationMode";
+ private static final String ACTION_OVERLAY_CHANGED = "android.intent.action.OVERLAY_CHANGED";
+ private static final String NAV_BAR_INTERACTION_MODE_RES_NAME =
+ "config_navBarInteractionMode";
+ private static final String TARGET_OVERLAY_PACKAGE = "android";
+
+ private final Context mContext;
+ private Mode mMode;
+
+ private int mNavBarGesturalHeight;
+ private int mNavBarLargerGesturalHeight;
+
+ private final List<NavigationModeChangeListener> mChangeListeners =
+ new CopyOnWriteArrayList<>();
+ private final List<OneHandedModeChangeListener> mOneHandedOverlayChangeListeners =
+ new ArrayList<>();
+
+ public SysUINavigationMode(Context context) {
+ mContext = context;
+ initializeMode();
+
+ mContext.registerReceiver(new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ updateMode();
+ updateGesturalHeight();
+ }
+ }, getPackageFilter(TARGET_OVERLAY_PACKAGE, ACTION_OVERLAY_CHANGED));
+ }
+
+ /** Updates navigation mode when needed. */
+ public void updateMode() {
+ Mode oldMode = mMode;
+ initializeMode();
+ if (mMode != oldMode) {
+ dispatchModeChange();
+ }
+ }
+
+ private void updateGesturalHeight() {
+ int newGesturalHeight = ResourceUtils.getDimenByName(
+ ResourceUtils.NAVBAR_BOTTOM_GESTURE_SIZE, mContext.getResources(),
+ INVALID_RESOURCE_HANDLE);
+
+ if (newGesturalHeight == INVALID_RESOURCE_HANDLE) {
+ Log.e(TAG, "Failed to get system resource ID. Incompatible framework version?");
+ return;
+ }
+
+ if (mNavBarGesturalHeight != newGesturalHeight) {
+ mNavBarGesturalHeight = newGesturalHeight;
+ }
+
+ int newLargerGesturalHeight = ResourceUtils.getDimenByName(
+ ResourceUtils.NAVBAR_BOTTOM_GESTURE_LARGER_SIZE, mContext.getResources(),
+ INVALID_RESOURCE_HANDLE);
+ if (newLargerGesturalHeight == INVALID_RESOURCE_HANDLE) {
+ Log.e(TAG, "Failed to get system resource ID. Incompatible framework version?");
+ return;
+ }
+ if (mNavBarLargerGesturalHeight != newLargerGesturalHeight) {
+ mNavBarLargerGesturalHeight = newLargerGesturalHeight;
+ dispatchOneHandedOverlayChange();
+ }
+ }
+
+ private void initializeMode() {
+ int modeInt = ResourceUtils.getIntegerByName(NAV_BAR_INTERACTION_MODE_RES_NAME,
+ mContext.getResources(), INVALID_RESOURCE_HANDLE);
+ mNavBarGesturalHeight = ResourceUtils.getDimenByName(
+ ResourceUtils.NAVBAR_BOTTOM_GESTURE_SIZE, mContext.getResources(),
+ INVALID_RESOURCE_HANDLE);
+ mNavBarLargerGesturalHeight = ResourceUtils.getDimenByName(
+ ResourceUtils.NAVBAR_BOTTOM_GESTURE_LARGER_SIZE, mContext.getResources(),
+ mNavBarGesturalHeight);
+
+ if (modeInt == INVALID_RESOURCE_HANDLE) {
+ Log.e(TAG, "Failed to get system resource ID. Incompatible framework version?");
+ return;
+ }
+
+ for (Mode m : Mode.values()) {
+ if (m.resValue == modeInt) {
+ mMode = m;
+ }
+ }
+ }
+
+ private void dispatchModeChange() {
+ for (NavigationModeChangeListener listener : mChangeListeners) {
+ listener.onNavigationModeChanged(mMode);
+ }
+ }
+
+ private void dispatchOneHandedOverlayChange() {
+ for (OneHandedModeChangeListener listener : mOneHandedOverlayChangeListeners) {
+ listener.onOneHandedModeChanged(mNavBarLargerGesturalHeight);
+ }
+ }
+
+ public Mode addModeChangeListener(NavigationModeChangeListener listener) {
+ mChangeListeners.add(listener);
+ return mMode;
+ }
+
+ public void removeModeChangeListener(NavigationModeChangeListener listener) {
+ mChangeListeners.remove(listener);
+ }
+
+ public int addOneHandedOverlayChangeListener(OneHandedModeChangeListener listener) {
+ mOneHandedOverlayChangeListeners.add(listener);
+ return mNavBarLargerGesturalHeight;
+ }
+
+ public void removeOneHandedOverlayChangeListener(OneHandedModeChangeListener listener) {
+ mOneHandedOverlayChangeListeners.remove(listener);
+ }
+
+ public Mode getMode() {
+ return mMode;
+ }
+
+ public void dump(PrintWriter pw) {
+ pw.println("SysUINavigationMode:");
+ pw.println(" mode=" + mMode.name());
+ pw.println(" mNavBarGesturalHeight=:" + mNavBarGesturalHeight);
+ }
+
+ public interface NavigationModeChangeListener {
+ void onNavigationModeChanged(Mode newMode);
+ }
+
+ public interface OneHandedModeChangeListener {
+ void onOneHandedModeChanged(int newGesturalHeight);
+ }
+}
diff --git a/quickstep/src/com/android/quickstep/SystemUiProxy.java b/quickstep/src/com/android/quickstep/SystemUiProxy.java
index 39d8b5447d..d040904f98 100644
--- a/quickstep/src/com/android/quickstep/SystemUiProxy.java
+++ b/quickstep/src/com/android/quickstep/SystemUiProxy.java
@@ -15,9 +15,6 @@
*/
package com.android.quickstep;
-import static android.app.ActivityManager.RECENT_IGNORE_UNAVAILABLE;
-
-import static com.android.launcher3.util.DisplayController.CHANGE_NAVIGATION_MODE;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import android.app.PendingIntent;
@@ -36,41 +33,29 @@ import android.os.RemoteException;
import android.os.UserHandle;
import android.util.Log;
import android.view.MotionEvent;
-import android.view.RemoteAnimationAdapter;
-import android.view.RemoteAnimationTarget;
import android.view.SurfaceControl;
-import android.window.IOnBackInvokedCallback;
-import com.android.launcher3.util.DisplayController;
-import com.android.launcher3.util.DisplayController.Info;
import com.android.launcher3.util.MainThreadInitializedObject;
import com.android.launcher3.util.SplitConfigurationOptions;
import com.android.systemui.shared.recents.ISystemUiProxy;
import com.android.systemui.shared.recents.model.Task;
import com.android.systemui.shared.system.RemoteTransitionCompat;
-import com.android.systemui.shared.system.smartspace.ILauncherUnlockAnimationController;
-import com.android.systemui.shared.system.smartspace.ISysuiUnlockAnimationController;
-import com.android.systemui.shared.system.smartspace.SmartspaceState;
-import com.android.wm.shell.back.IBackAnimation;
+import com.android.systemui.shared.system.smartspace.ISmartspaceCallback;
+import com.android.systemui.shared.system.smartspace.ISmartspaceTransitionController;
import com.android.wm.shell.onehanded.IOneHanded;
import com.android.wm.shell.pip.IPip;
import com.android.wm.shell.pip.IPipAnimationListener;
-import com.android.wm.shell.recents.IRecentTasks;
-import com.android.wm.shell.recents.IRecentTasksListener;
import com.android.wm.shell.splitscreen.ISplitScreen;
import com.android.wm.shell.splitscreen.ISplitScreenListener;
import com.android.wm.shell.startingsurface.IStartingWindow;
import com.android.wm.shell.startingsurface.IStartingWindowListener;
import com.android.wm.shell.transition.IShellTransitions;
-import com.android.wm.shell.util.GroupedRecentTaskInfo;
-
-import java.util.ArrayList;
-import java.util.Arrays;
/**
* Holds the reference to SystemUI.
*/
-public class SystemUiProxy implements ISystemUiProxy, DisplayController.DisplayInfoChangeListener {
+public class SystemUiProxy implements ISystemUiProxy,
+ SysUINavigationMode.NavigationModeChangeListener {
private static final String TAG = SystemUiProxy.class.getSimpleName();
public static final MainThreadInitializedObject<SystemUiProxy> INSTANCE =
@@ -78,28 +63,21 @@ public class SystemUiProxy implements ISystemUiProxy, DisplayController.DisplayI
private ISystemUiProxy mSystemUiProxy;
private IPip mPip;
- private ISysuiUnlockAnimationController mSysuiUnlockAnimationController;
+ private ISmartspaceTransitionController mSmartspaceTransitionController;
private ISplitScreen mSplitScreen;
private IOneHanded mOneHanded;
private IShellTransitions mShellTransitions;
private IStartingWindow mStartingWindow;
- private IRecentTasks mRecentTasks;
- private IBackAnimation mBackAnimation;
private final DeathRecipient mSystemUiProxyDeathRecipient = () -> {
MAIN_EXECUTOR.execute(() -> clearProxy());
};
- // Save the listeners passed into the proxy since OverviewProxyService may not have been bound
- // yet, and we'll need to set/register these listeners with SysUI when they do. Note that it is
- // up to the caller to clear the listeners to prevent leaks as these can be held indefinitely
- // in case SysUI needs to rebind.
- private IPipAnimationListener mPipAnimationListener;
- private ISplitScreenListener mSplitScreenListener;
- private IStartingWindowListener mStartingWindowListener;
- private ILauncherUnlockAnimationController mPendingLauncherUnlockAnimationController;
- private IRecentTasksListener mRecentTasksListener;
- private final ArrayList<RemoteTransitionCompat> mRemoteTransitions = new ArrayList<>();
- private IOnBackInvokedCallback mBackToLauncherCallback;
+ // Save the listeners passed into the proxy since when set/register these listeners,
+ // setProxy may not have been called, eg. OverviewProxyService is not connected yet.
+ private IPipAnimationListener mPendingPipAnimationListener;
+ private ISplitScreenListener mPendingSplitScreenListener;
+ private IStartingWindowListener mPendingStartingWindowListener;
+ private ISmartspaceCallback mPendingSmartspaceCallback;
// Used to dedupe calls to SystemUI
private int mLastShelfHeight;
@@ -107,21 +85,18 @@ public class SystemUiProxy implements ISystemUiProxy, DisplayController.DisplayI
private float mLastNavButtonAlpha;
private boolean mLastNavButtonAnimate;
private boolean mHasNavButtonAlphaBeenSet = false;
- private Runnable mPendingSetNavButtonAlpha = null;
// TODO(141886704): Find a way to remove this
private int mLastSystemUiStateFlags;
public SystemUiProxy(Context context) {
- DisplayController.INSTANCE.get(context).addChangeListener(this);
+ SysUINavigationMode.INSTANCE.get(context).addModeChangeListener(this);
}
@Override
- public void onDisplayInfoChanged(Context context, Info info, int flags) {
- if ((flags & CHANGE_NAVIGATION_MODE) != 0) {
- // Whenever the nav mode changes, force reset the nav button alpha
- setNavBarButtonAlpha(1f, false);
- }
+ public void onNavigationModeChanged(SysUINavigationMode.Mode newMode) {
+ // Whenever the nav mode changes, force reset the nav button alpha
+ setNavBarButtonAlpha(1f, false);
}
@Override
@@ -136,17 +111,6 @@ public class SystemUiProxy implements ISystemUiProxy, DisplayController.DisplayI
}
@Override
- public void onImeSwitcherPressed() {
- if (mSystemUiProxy != null) {
- try {
- mSystemUiProxy.onImeSwitcherPressed();
- } catch (RemoteException e) {
- Log.w(TAG, "Failed call onImeSwitcherPressed", e);
- }
- }
- }
-
- @Override
public void setHomeRotationEnabled(boolean enabled) {
if (mSystemUiProxy != null) {
try {
@@ -165,9 +129,8 @@ public class SystemUiProxy implements ISystemUiProxy, DisplayController.DisplayI
public void setProxy(ISystemUiProxy proxy, IPip pip, ISplitScreen splitScreen,
IOneHanded oneHanded, IShellTransitions shellTransitions,
- IStartingWindow startingWindow, IRecentTasks recentTasks,
- ISysuiUnlockAnimationController sysuiUnlockAnimationController,
- IBackAnimation backAnimation) {
+ IStartingWindow startingWindow,
+ ISmartspaceTransitionController smartSpaceTransitionController) {
unlinkToDeath();
mSystemUiProxy = proxy;
mPip = pip;
@@ -175,43 +138,29 @@ public class SystemUiProxy implements ISystemUiProxy, DisplayController.DisplayI
mOneHanded = oneHanded;
mShellTransitions = shellTransitions;
mStartingWindow = startingWindow;
- mSysuiUnlockAnimationController = sysuiUnlockAnimationController;
- mRecentTasks = recentTasks;
- mBackAnimation = backAnimation;
+ mSmartspaceTransitionController = smartSpaceTransitionController;
linkToDeath();
// re-attach the listeners once missing due to setProxy has not been initialized yet.
- if (mPipAnimationListener != null && mPip != null) {
- setPinnedStackAnimationListener(mPipAnimationListener);
- }
- if (mSplitScreenListener != null && mSplitScreen != null) {
- registerSplitScreenListener(mSplitScreenListener);
- }
- if (mStartingWindowListener != null && mStartingWindow != null) {
- setStartingWindowListener(mStartingWindowListener);
+ if (mPendingPipAnimationListener != null && mPip != null) {
+ setPinnedStackAnimationListener(mPendingPipAnimationListener);
+ mPendingPipAnimationListener = null;
}
- if (mPendingLauncherUnlockAnimationController != null
- && mSysuiUnlockAnimationController != null) {
- setLauncherUnlockAnimationController(mPendingLauncherUnlockAnimationController);
- mPendingLauncherUnlockAnimationController = null;
+ if (mPendingSplitScreenListener != null && mSplitScreen != null) {
+ registerSplitScreenListener(mPendingSplitScreenListener);
+ mPendingSplitScreenListener = null;
}
- for (int i = mRemoteTransitions.size() - 1; i >= 0; --i) {
- registerRemoteTransition(mRemoteTransitions.get(i));
+ if (mPendingStartingWindowListener != null && mStartingWindow != null) {
+ setStartingWindowListener(mPendingStartingWindowListener);
+ mPendingStartingWindowListener = null;
}
- if (mRecentTasksListener != null && mRecentTasks != null) {
- registerRecentTasksListener(mRecentTasksListener);
- }
- if (mBackAnimation != null && mBackToLauncherCallback != null) {
- setBackToLauncherCallback(mBackToLauncherCallback);
- }
-
- if (mPendingSetNavButtonAlpha != null) {
- mPendingSetNavButtonAlpha.run();
- mPendingSetNavButtonAlpha = null;
+ if (mPendingSmartspaceCallback != null && mSmartspaceTransitionController != null) {
+ setSmartspaceCallback(mPendingSmartspaceCallback);
+ mPendingSmartspaceCallback = null;
}
}
public void clearProxy() {
- setProxy(null, null, null, null, null, null, null, null, null);
+ setProxy(null, null, null, null, null, null, null);
}
// TODO(141886704): Find a way to remove this
@@ -291,18 +240,14 @@ public class SystemUiProxy implements ISystemUiProxy, DisplayController.DisplayI
boolean changed = Float.compare(alpha, mLastNavButtonAlpha) != 0
|| animate != mLastNavButtonAnimate
|| !mHasNavButtonAlphaBeenSet;
- if (changed) {
- if (mSystemUiProxy == null) {
- mPendingSetNavButtonAlpha = () -> setNavBarButtonAlpha(alpha, animate);
- } else {
- mLastNavButtonAlpha = alpha;
- mLastNavButtonAnimate = animate;
- mHasNavButtonAlphaBeenSet = true;
- try {
- mSystemUiProxy.setNavBarButtonAlpha(alpha, animate);
- } catch (RemoteException e) {
- Log.w(TAG, "Failed call setNavBarButtonAlpha", e);
- }
+ if (mSystemUiProxy != null && changed) {
+ mLastNavButtonAlpha = alpha;
+ mLastNavButtonAnimate = animate;
+ mHasNavButtonAlphaBeenSet = true;
+ try {
+ mSystemUiProxy.setNavBarButtonAlpha(alpha, animate);
+ } catch (RemoteException e) {
+ Log.w(TAG, "Failed call setNavBarButtonAlpha", e);
}
}
}
@@ -401,7 +346,7 @@ public class SystemUiProxy implements ISystemUiProxy, DisplayController.DisplayI
try {
mSystemUiProxy.setSplitScreenMinimized(minimized);
} catch (RemoteException e) {
- Log.w(TAG, "Failed call setSplitScreenMinimized", e);
+ Log.w(TAG, "Failed call stopScreenPinning", e);
}
}
}
@@ -443,34 +388,6 @@ public class SystemUiProxy implements ISystemUiProxy, DisplayController.DisplayI
}
@Override
- public void notifyTaskbarStatus(boolean visible, boolean stashed) {
- if (mSystemUiProxy != null) {
- try {
- mSystemUiProxy.notifyTaskbarStatus(visible, stashed);
- } catch (RemoteException e) {
- Log.w(TAG, "Failed call notifyTaskbarStatus with arg: " +
- visible + ", " + stashed, e);
- }
- }
- }
-
- /**
- * NOTE: If called to suspend, caller MUST call this method to also un-suspend
- * @param suspend should be true to stop auto-hide, false to resume normal behavior
- */
- @Override
- public void notifyTaskbarAutohideSuspend(boolean suspend) {
- if (mSystemUiProxy != null) {
- try {
- mSystemUiProxy.notifyTaskbarAutohideSuspend(suspend);
- } catch (RemoteException e) {
- Log.w(TAG, "Failed call notifyTaskbarAutohideSuspend with arg: " +
- suspend, e);
- }
- }
- }
-
- @Override
public void handleImageBundleAsScreenshot(Bundle screenImageBundle, Rect locationInScreen,
Insets visibleInsets, Task.TaskKey task) {
if (mSystemUiProxy != null) {
@@ -494,17 +411,6 @@ public class SystemUiProxy implements ISystemUiProxy, DisplayController.DisplayI
}
}
- @Override
- public void toggleNotificationPanel() {
- if (mSystemUiProxy != null) {
- try {
- mSystemUiProxy.toggleNotificationPanel();
- } catch (RemoteException e) {
- Log.w(TAG, "Failed call toggleNotificationPanel", e);
- }
- }
- }
-
//
// Pip
//
@@ -536,8 +442,9 @@ public class SystemUiProxy implements ISystemUiProxy, DisplayController.DisplayI
} catch (RemoteException e) {
Log.w(TAG, "Failed call setPinnedStackAnimationListener", e);
}
+ } else {
+ mPendingPipAnimationListener = listener;
}
- mPipAnimationListener = listener;
}
public Rect startSwipePipToHome(ComponentName componentName, ActivityInfo activityInfo,
@@ -553,16 +460,11 @@ public class SystemUiProxy implements ISystemUiProxy, DisplayController.DisplayI
return null;
}
- /**
- * Notifies WM Shell that launcher has finished all the animation for swipe to home. WM Shell
- * can choose to fade out the overlay when entering PIP is finished, and WM Shell should be
- * responsible for cleaning up the overlay.
- */
- public void stopSwipePipToHome(int taskId, ComponentName componentName, Rect destinationBounds,
+ public void stopSwipePipToHome(ComponentName componentName, Rect destinationBounds,
SurfaceControl overlay) {
if (mPip != null) {
try {
- mPip.stopSwipePipToHome(taskId, componentName, destinationBounds, overlay);
+ mPip.stopSwipePipToHome(componentName, destinationBounds, overlay);
} catch (RemoteException e) {
Log.w(TAG, "Failed call stopSwipePipToHome");
}
@@ -580,8 +482,9 @@ public class SystemUiProxy implements ISystemUiProxy, DisplayController.DisplayI
} catch (RemoteException e) {
Log.w(TAG, "Failed call registerSplitScreenListener");
}
+ } else {
+ mPendingSplitScreenListener = listener;
}
- mSplitScreenListener = listener;
}
public void unregisterSplitScreenListener(ISplitScreenListener listener) {
@@ -592,112 +495,94 @@ public class SystemUiProxy implements ISystemUiProxy, DisplayController.DisplayI
Log.w(TAG, "Failed call unregisterSplitScreenListener");
}
}
- mSplitScreenListener = null;
+ mPendingSplitScreenListener = null;
}
- /** Start multiple tasks in split-screen simultaneously. */
- public void startTasks(int mainTaskId, Bundle mainOptions, int sideTaskId, Bundle sideOptions,
- @SplitConfigurationOptions.StagePosition int sidePosition, float splitRatio,
- RemoteTransitionCompat remoteTransition) {
- if (mSystemUiProxy != null) {
+ public void setSideStageVisibility(boolean visible) {
+ if (mSplitScreen != null) {
try {
- mSplitScreen.startTasks(mainTaskId, mainOptions, sideTaskId, sideOptions,
- sidePosition, splitRatio, remoteTransition.getTransition());
+ mSplitScreen.setSideStageVisibility(visible);
} catch (RemoteException e) {
- Log.w(TAG, "Failed call startTask");
+ Log.w(TAG, "Failed call setSideStageVisibility");
}
}
}
- /**
- * Start multiple tasks in split-screen simultaneously.
- */
- public void startTasksWithLegacyTransition(int mainTaskId, Bundle mainOptions, int sideTaskId,
- Bundle sideOptions, @SplitConfigurationOptions.StagePosition int sidePosition,
- float splitRatio, RemoteAnimationAdapter adapter) {
- if (mSystemUiProxy != null) {
+ public void exitSplitScreen() {
+ if (mSplitScreen != null) {
try {
- mSplitScreen.startTasksWithLegacyTransition(mainTaskId, mainOptions, sideTaskId,
- sideOptions, sidePosition, splitRatio, adapter);
+ mSplitScreen.exitSplitScreen();
} catch (RemoteException e) {
- Log.w(TAG, "Failed call startTasksWithLegacyTransition");
+ Log.w(TAG, "Failed call exitSplitScreen");
}
}
}
- public void startIntentAndTaskWithLegacyTransition(PendingIntent pendingIntent,
- Intent fillInIntent, int taskId, Bundle mainOptions, Bundle sideOptions,
- @SplitConfigurationOptions.StagePosition int sidePosition, float splitRatio,
- RemoteAnimationAdapter adapter) {
- if (mSystemUiProxy != null) {
+ public void exitSplitScreenOnHide(boolean exitSplitScreenOnHide) {
+ if (mSplitScreen != null) {
try {
- mSplitScreen.startIntentAndTaskWithLegacyTransition(pendingIntent, fillInIntent,
- taskId, mainOptions, sideOptions, sidePosition, splitRatio, adapter);
+ mSplitScreen.exitSplitScreenOnHide(exitSplitScreenOnHide);
} catch (RemoteException e) {
- Log.w(TAG, "Failed call startTasksWithLegacyTransition");
+ Log.w(TAG, "Failed call exitSplitScreen");
}
}
}
- public void startShortcut(String packageName, String shortcutId, int position,
- Bundle options, UserHandle user) {
+ public void startTask(int taskId, int stage, int position, Bundle options) {
if (mSplitScreen != null) {
try {
- mSplitScreen.startShortcut(packageName, shortcutId, position, options,
- user);
+ mSplitScreen.startTask(taskId, stage, position, options);
} catch (RemoteException e) {
- Log.w(TAG, "Failed call startShortcut");
+ Log.w(TAG, "Failed call startTask");
}
}
}
- public void startIntent(PendingIntent intent, Intent fillInIntent, int position,
- Bundle options) {
- if (mSplitScreen != null) {
+ /** Start multiple tasks in split-screen simultaneously. */
+ public void startTasks(int mainTaskId, Bundle mainOptions, int sideTaskId, Bundle sideOptions,
+ @SplitConfigurationOptions.StagePosition int sidePosition,
+ RemoteTransitionCompat remoteTransition) {
+ if (mSystemUiProxy != null) {
try {
- mSplitScreen.startIntent(intent, fillInIntent, position, options);
+ mSplitScreen.startTasks(mainTaskId, mainOptions, sideTaskId, sideOptions,
+ sidePosition, remoteTransition.getTransition());
} catch (RemoteException e) {
- Log.w(TAG, "Failed call startIntent");
+ Log.w(TAG, "Failed call startTask");
}
}
}
- public void removeFromSideStage(int taskId) {
+ public void startShortcut(String packageName, String shortcutId, int stage, int position,
+ Bundle options, UserHandle user) {
if (mSplitScreen != null) {
try {
- mSplitScreen.removeFromSideStage(taskId);
+ mSplitScreen.startShortcut(packageName, shortcutId, stage, position, options,
+ user);
} catch (RemoteException e) {
- Log.w(TAG, "Failed call removeFromSideStage");
+ Log.w(TAG, "Failed call startShortcut");
}
}
}
- /**
- * Call this when going to recents so that shell can set-up and provide appropriate leashes
- * for animation (eg. DividerBar).
- *
- * @return RemoteAnimationTargets of windows that need to animate but only exist in shell.
- */
- public RemoteAnimationTarget[] onGoingToRecentsLegacy(RemoteAnimationTarget[] apps) {
+ public void startIntent(PendingIntent intent, Intent fillInIntent, int stage, int position,
+ Bundle options) {
if (mSplitScreen != null) {
try {
- return mSplitScreen.onGoingToRecentsLegacy(apps);
+ mSplitScreen.startIntent(intent, fillInIntent, stage, position, options);
} catch (RemoteException e) {
- Log.w(TAG, "Failed call onGoingToRecentsLegacy");
+ Log.w(TAG, "Failed call startIntent");
}
}
- return null;
}
- public RemoteAnimationTarget[] onStartingSplitLegacy(RemoteAnimationTarget[] apps) {
+ public void removeFromSideStage(int taskId) {
if (mSplitScreen != null) {
try {
- return mSplitScreen.onStartingSplitLegacy(apps);
+ mSplitScreen.removeFromSideStage(taskId);
} catch (RemoteException e) {
- Log.w(TAG, "Failed call onStartingSplitLegacy");
+ Log.w(TAG, "Failed call removeFromSideStage");
}
}
- return null;
}
//
@@ -737,9 +622,6 @@ public class SystemUiProxy implements ISystemUiProxy, DisplayController.DisplayI
Log.w(TAG, "Failed call registerRemoteTransition");
}
}
- if (!mRemoteTransitions.contains(remoteTransition)) {
- mRemoteTransitions.add(remoteTransition);
- }
}
public void unregisterRemoteTransition(RemoteTransitionCompat remoteTransition) {
@@ -750,7 +632,6 @@ public class SystemUiProxy implements ISystemUiProxy, DisplayController.DisplayI
Log.w(TAG, "Failed call registerRemoteTransition");
}
}
- mRemoteTransitions.remove(remoteTransition);
}
//
@@ -767,141 +648,25 @@ public class SystemUiProxy implements ISystemUiProxy, DisplayController.DisplayI
} catch (RemoteException e) {
Log.w(TAG, "Failed call setStartingWindowListener", e);
}
+ } else {
+ mPendingStartingWindowListener = listener;
}
- mStartingWindowListener = listener;
}
+
//
// SmartSpace transitions
//
- /**
- * Sets the instance of {@link ILauncherUnlockAnimationController} that System UI should use to
- * control the launcher side of the unlock animation. This will also cause us to dispatch the
- * current state of the smartspace to System UI (this will subsequently happen if the state
- * changes).
- */
- public void setLauncherUnlockAnimationController(
- ILauncherUnlockAnimationController controller) {
- if (mSysuiUnlockAnimationController != null) {
+ public void setSmartspaceCallback(ISmartspaceCallback callback) {
+ if (mSmartspaceTransitionController != null) {
try {
- mSysuiUnlockAnimationController.setLauncherUnlockController(controller);
-
- if (controller != null) {
- controller.dispatchSmartspaceStateToSysui();
- }
+ mSmartspaceTransitionController.setSmartspace(callback);
} catch (RemoteException e) {
Log.w(TAG, "Failed call setStartingWindowListener", e);
}
} else {
- mPendingLauncherUnlockAnimationController = controller;
- }
- }
-
- /**
- * Tells System UI that the Launcher's smartspace state has been updated, so that it can prepare
- * the unlock animation accordingly.
- */
- public void notifySysuiSmartspaceStateUpdated(SmartspaceState state) {
- if (mSysuiUnlockAnimationController != null) {
- try {
- mSysuiUnlockAnimationController.onLauncherSmartspaceStateUpdated(state);
- } catch (RemoteException e) {
- Log.w(TAG, "Failed call notifySysuiSmartspaceStateUpdated", e);
- e.printStackTrace();
- }
- }
- }
-
- //
- // Recents
- //
-
- public void registerRecentTasksListener(IRecentTasksListener listener) {
- if (mRecentTasks != null) {
- try {
- mRecentTasks.registerRecentTasksListener(listener);
- } catch (RemoteException e) {
- Log.w(TAG, "Failed call registerRecentTasksListener", e);
- }
- }
- mRecentTasksListener = listener;
- }
-
- public void unregisterRecentTasksListener(IRecentTasksListener listener) {
- if (mRecentTasks != null) {
- try {
- mRecentTasks.unregisterRecentTasksListener(listener);
- } catch (RemoteException e) {
- Log.w(TAG, "Failed call unregisterRecentTasksListener");
- }
- }
- mRecentTasksListener = null;
- }
-
- //
- // Back navigation transitions
- //
-
- /** Sets the launcher {@link android.window.IOnBackInvokedCallback} to shell */
- public void setBackToLauncherCallback(IOnBackInvokedCallback callback) {
- mBackToLauncherCallback = callback;
- if (mBackAnimation == null) {
- return;
- }
- try {
- mBackAnimation.setBackToLauncherCallback(callback);
- } catch (RemoteException e) {
- Log.e(TAG, "Failed call setBackToLauncherCallback", e);
- }
- }
-
- /** Clears the previously registered {@link IOnBackInvokedCallback}.
- *
- * @param callback The previously registered callback instance.
- */
- public void clearBackToLauncherCallback(IOnBackInvokedCallback callback) {
- if (mBackToLauncherCallback != callback) {
- return;
- }
- mBackToLauncherCallback = null;
- if (mBackAnimation == null) {
- return;
- }
- try {
- mBackAnimation.clearBackToLauncherCallback();
- } catch (RemoteException e) {
- Log.e(TAG, "Failed call clearBackToLauncherCallback", e);
- }
- }
-
- /**
- * Notifies shell that all back to launcher animations have finished (including the transition
- * that plays after the gesture is committed and before the app is closed.
- */
- public void onBackToLauncherAnimationFinished() {
- if (mBackAnimation != null) {
- try {
- mBackAnimation.onBackToLauncherAnimationFinished();
- } catch (RemoteException e) {
- Log.w(TAG, "Failed call onBackAnimationFinished", e);
- }
- }
- }
-
- public ArrayList<GroupedRecentTaskInfo> getRecentTasks(int numTasks, int userId) {
- if (mRecentTasks != null) {
- try {
- final GroupedRecentTaskInfo[] rawTasks = mRecentTasks.getRecentTasks(numTasks,
- RECENT_IGNORE_UNAVAILABLE, userId);
- if (rawTasks == null) {
- return new ArrayList<>();
- }
- return new ArrayList<>(Arrays.asList(rawTasks));
- } catch (RemoteException e) {
- Log.w(TAG, "Failed call getRecentTasks", e);
- }
+ mPendingSmartspaceCallback = callback;
}
- return new ArrayList<>();
}
}
diff --git a/quickstep/src/com/android/quickstep/TaskAnimationManager.java b/quickstep/src/com/android/quickstep/TaskAnimationManager.java
index 54f457d2d8..d7af074954 100644
--- a/quickstep/src/com/android/quickstep/TaskAnimationManager.java
+++ b/quickstep/src/com/android/quickstep/TaskAnimationManager.java
@@ -20,22 +20,18 @@ import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
import static com.android.quickstep.GestureState.STATE_RECENTS_ANIMATION_INITIALIZED;
import static com.android.quickstep.GestureState.STATE_RECENTS_ANIMATION_STARTED;
-import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.ACTIVITY_TYPE_HOME;
import android.app.ActivityManager;
-import android.app.ActivityOptions;
import android.content.Context;
import android.content.Intent;
+import android.os.Bundle;
import android.os.SystemProperties;
import android.util.Log;
-import android.view.RemoteAnimationTarget;
-import androidx.annotation.Nullable;
import androidx.annotation.UiThread;
import com.android.launcher3.Utilities;
import com.android.launcher3.config.FeatureFlags;
-import com.android.quickstep.TopTaskTracker.CachedTaskInfo;
import com.android.quickstep.views.RecentsView;
import com.android.systemui.shared.recents.model.ThumbnailData;
import com.android.systemui.shared.system.ActivityManagerWrapper;
@@ -45,14 +41,9 @@ import com.android.systemui.shared.system.RemoteTransitionCompat;
import com.android.systemui.shared.system.TaskStackChangeListener;
import com.android.systemui.shared.system.TaskStackChangeListeners;
-import java.util.ArrayList;
-import java.util.HashMap;
-
public class TaskAnimationManager implements RecentsAnimationCallbacks.RecentsAnimationListener {
public static final boolean ENABLE_SHELL_TRANSITIONS =
- SystemProperties.getBoolean("persist.wm.debug.shell_transit", false);
- public static final boolean SHELL_TRANSITIONS_ROTATION = ENABLE_SHELL_TRANSITIONS
- && SystemProperties.getBoolean("persist.wm.debug.shell_transit_rotate", false);
+ SystemProperties.getBoolean("persist.debug.shell_transit", false);
private RecentsAnimationController mController;
private RecentsAnimationCallbacks mCallbacks;
@@ -124,8 +115,7 @@ public class TaskAnimationManager implements RecentsAnimationCallbacks.RecentsAn
final BaseActivityInterface activityInterface = gestureState.getActivityInterface();
mLastGestureState = gestureState;
- mCallbacks = new RecentsAnimationCallbacks(SystemUiProxy.INSTANCE.get(mCtx),
- activityInterface.allowMinimizeSplitScreen());
+ mCallbacks = new RecentsAnimationCallbacks(activityInterface.allowMinimizeSplitScreen());
mCallbacks.addListener(new RecentsAnimationCallbacks.RecentsAnimationListener() {
@Override
public void onRecentsAnimationStart(RecentsAnimationController controller,
@@ -143,7 +133,7 @@ public class TaskAnimationManager implements RecentsAnimationCallbacks.RecentsAn
}
@Override
- public void onRecentsAnimationCanceled(HashMap<Integer, ThumbnailData> thumbnailDatas) {
+ public void onRecentsAnimationCanceled(ThumbnailData thumbnailData) {
cleanUpRecentsAnimation();
}
@@ -153,49 +143,20 @@ public class TaskAnimationManager implements RecentsAnimationCallbacks.RecentsAn
}
@Override
- public void onTasksAppeared(RemoteAnimationTargetCompat[] appearedTaskTargets) {
- RemoteAnimationTargetCompat appearedTaskTarget = appearedTaskTargets[0];
+ public void onTaskAppeared(RemoteAnimationTargetCompat appearedTaskTarget) {
BaseActivityInterface activityInterface = mLastGestureState.getActivityInterface();
- // Convert appTargets to type RemoteAnimationTarget for all apps except Home app
- final ArrayList<RemoteAnimationTargetCompat> tmpNonHomeApps = new ArrayList<>();
- final ArrayList<RemoteAnimationTargetCompat> tmpHomeApps = new ArrayList<>();
- for (RemoteAnimationTargetCompat compat : appearedTaskTargets) {
- if (compat.activityType != ACTIVITY_TYPE_HOME) {
- tmpNonHomeApps.add(compat);
- } else {
- tmpHomeApps.add(compat);
- }
- }
- RemoteAnimationTarget[] nonHomeApps = tmpNonHomeApps.stream()
- .map(RemoteAnimationTargetCompat::unwrap)
- .toArray(RemoteAnimationTarget[]::new);
- RemoteAnimationTarget[] homeApps = tmpHomeApps.stream()
- .map(RemoteAnimationTargetCompat::unwrap)
- .toArray(RemoteAnimationTarget[]::new);
- if (homeApps.length > 0
- && activityInterface.getCreatedActivity() instanceof RecentsActivity) {
- ((RecentsActivity) activityInterface.getCreatedActivity()).startHome();
- return;
- }
-
- RemoteAnimationTarget[] nonAppTargets =
- SystemUiProxy.INSTANCE.getNoCreate().onStartingSplitLegacy(nonHomeApps);
-
if (ENABLE_QUICKSTEP_LIVE_TILE.get() && activityInterface.isInLiveTileMode()
&& activityInterface.getCreatedActivity() != null) {
RecentsView recentsView =
activityInterface.getCreatedActivity().getOverviewPanel();
if (recentsView != null) {
- recentsView.launchSideTaskInLiveTileMode(appearedTaskTarget.taskId,
- appearedTaskTargets,
+ RemoteAnimationTargetCompat[] apps = new RemoteAnimationTargetCompat[1];
+ apps[0] = appearedTaskTarget;
+ recentsView.launchSideTaskInLiveTileMode(appearedTaskTarget.taskId, apps,
new RemoteAnimationTargetCompat[0] /* wallpaper */,
- RemoteAnimationTargetCompat.wrap(nonAppTargets) /* nonApps */);
+ new RemoteAnimationTargetCompat[0] /* nonApps */);
return;
}
- } else if (nonAppTargets != null && nonAppTargets.length > 0) {
- TaskViewUtils.createSplitAuxiliarySurfacesAnimator(
- RemoteAnimationTargetCompat.wrap(nonAppTargets) /* nonApps */,
- true /*shown*/, dividerAnimator -> dividerAnimator.start());
}
if (mController != null) {
if (mLastAppearedTaskTarget == null
@@ -208,24 +169,6 @@ public class TaskAnimationManager implements RecentsAnimationCallbacks.RecentsAn
}
}
}
-
- @Override
- public boolean onSwitchToScreenshot(Runnable onFinished) {
- if (!ENABLE_QUICKSTEP_LIVE_TILE.get() || !activityInterface.isInLiveTileMode()
- || activityInterface.getCreatedActivity() == null) {
- // No need to switch since tile is already a screenshot.
- onFinished.run();
- } else {
- final RecentsView recentsView =
- activityInterface.getCreatedActivity().getOverviewPanel();
- if (recentsView != null) {
- recentsView.switchToScreenshot(onFinished);
- } else {
- onFinished.run();
- }
- }
- return true;
- }
});
final long eventTime = gestureState.getSwipeUpStartTimeMs();
mCallbacks.addListener(gestureState);
@@ -233,19 +176,10 @@ public class TaskAnimationManager implements RecentsAnimationCallbacks.RecentsAn
if (ENABLE_SHELL_TRANSITIONS) {
RemoteTransitionCompat transition = new RemoteTransitionCompat(mCallbacks,
- mController != null ? mController.getController() : null,
- mCtx.getIApplicationThread());
- final ActivityOptions options = ActivityOptionsCompat.makeRemoteTransition(transition);
- // Allowing to pause Home if Home is top activity and Recents is not Home. So when user
- // start home when recents animation is playing, the home activity can be resumed again
- // to let the transition controller collect Home activity.
- CachedTaskInfo cti = gestureState.getRunningTask();
- boolean homeIsOnTop = cti != null && cti.isHomeTask();
- if (!homeIsOnTop) {
- options.setTransientLaunch();
- }
- options.setSourceInfo(ActivityOptions.SourceInfo.TYPE_RECENTS_ANIMATION, eventTime);
- UI_HELPER_EXECUTOR.execute(() -> mCtx.startActivity(intent, options.toBundle()));
+ mController != null ? mController.getController() : null);
+ Bundle options = ActivityOptionsCompat.makeRemoteTransition(transition)
+ .setTransientLaunch().toBundle();
+ mCtx.startActivity(intent, options);
} else {
UI_HELPER_EXECUTOR.execute(() -> ActivityManagerWrapper.getInstance()
.startRecentsActivity(intent, eventTime, mCallbacks, null, null));
@@ -267,22 +201,6 @@ public class TaskAnimationManager implements RecentsAnimationCallbacks.RecentsAn
return mCallbacks;
}
- public void endLiveTile() {
- if (mLastGestureState == null) {
- return;
- }
- BaseActivityInterface activityInterface = mLastGestureState.getActivityInterface();
- if (ENABLE_QUICKSTEP_LIVE_TILE.get() && activityInterface.isInLiveTileMode()
- && activityInterface.getCreatedActivity() != null) {
- RecentsView recentsView = activityInterface.getCreatedActivity().getOverviewPanel();
- if (recentsView != null) {
- recentsView.switchToScreenshot(null,
- () -> recentsView.finishRecentsAnimation(true /* toRecents */,
- false /* shouldPip */, null));
- }
- }
- }
-
public void setLiveTileCleanUpHandler(Runnable cleanUpHandler) {
mLiveTileCleanUpHandler = cleanUpHandler;
}
@@ -351,11 +269,6 @@ public class TaskAnimationManager implements RecentsAnimationCallbacks.RecentsAn
mLastAppearedTaskTarget = null;
}
- @Nullable
- public RecentsAnimationCallbacks getCurrentCallbacks() {
- return mCallbacks;
- }
-
public void dump() {
// TODO
}
diff --git a/quickstep/src/com/android/quickstep/TaskIconCache.java b/quickstep/src/com/android/quickstep/TaskIconCache.java
index 3803f0350b..fa61fffbc6 100644
--- a/quickstep/src/com/android/quickstep/TaskIconCache.java
+++ b/quickstep/src/com/android/quickstep/TaskIconCache.java
@@ -18,7 +18,6 @@ package com.android.quickstep;
import static com.android.launcher3.uioverrides.QuickstepLauncher.GO_LOW_RAM_RECENTS_ENABLED;
import static com.android.launcher3.util.DisplayController.CHANGE_DENSITY;
-import android.app.ActivityManager;
import android.app.ActivityManager.TaskDescription;
import android.content.Context;
import android.content.pm.ActivityInfo;
@@ -27,6 +26,7 @@ import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
+import android.os.Build;
import android.os.UserHandle;
import android.text.TextUtils;
import android.util.SparseArray;
@@ -37,7 +37,6 @@ import androidx.annotation.WorkerThread;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.icons.BaseIconFactory;
-import com.android.launcher3.icons.BaseIconFactory.IconOptions;
import com.android.launcher3.icons.BitmapInfo;
import com.android.launcher3.icons.IconProvider;
import com.android.launcher3.util.DisplayController;
@@ -49,6 +48,7 @@ import com.android.quickstep.util.TaskKeyLruCache;
import com.android.systemui.shared.recents.model.Task;
import com.android.systemui.shared.recents.model.Task.TaskKey;
import com.android.systemui.shared.system.PackageManagerWrapper;
+import com.android.systemui.shared.system.TaskDescriptionCompat;
import java.util.concurrent.Executor;
import java.util.function.Consumer;
@@ -64,8 +64,6 @@ public class TaskIconCache implements DisplayInfoChangeListener {
private final Context mContext;
private final TaskKeyLruCache<TaskCacheEntry> mIconCache;
private final SparseArray<BitmapInfo> mDefaultIcons = new SparseArray<>();
- private BitmapInfo mDefaultIconBase = null;
-
private final IconProvider mIconProvider;
private BaseIconFactory mIconFactory;
@@ -154,8 +152,9 @@ public class TaskIconCache implements DisplayInfoChangeListener {
// Load icon
// TODO: Load icon resource (b/143363444)
- Bitmap icon = getIcon(desc, key.userId);
+ Bitmap icon = TaskDescriptionCompat.getIcon(desc, key.userId);
if (icon != null) {
+ /* isInstantApp */
entry.icon = getBitmapInfo(
new BitmapDrawable(mContext.getResources(), icon),
key.userId,
@@ -193,14 +192,6 @@ public class TaskIconCache implements DisplayInfoChangeListener {
return entry;
}
- private Bitmap getIcon(ActivityManager.TaskDescription desc, int userId) {
- if (desc.getInMemoryIcon() != null) {
- return desc.getInMemoryIcon();
- }
- return ActivityManager.TaskDescription.loadTaskDescriptionIcon(
- desc.getIconFilename(), userId);
- }
-
private String getBadgedContentDescription(ActivityInfo info, int userId, TaskDescription td) {
PackageManager pm = mContext.getPackageManager();
String taskLabel = td == null ? null : Utilities.trim(td.getLabel());
@@ -219,23 +210,14 @@ public class TaskIconCache implements DisplayInfoChangeListener {
@WorkerThread
private Drawable getDefaultIcon(int userId) {
synchronized (mDefaultIcons) {
- if (mDefaultIconBase == null) {
+ BitmapInfo info = mDefaultIcons.get(userId);
+ if (info == null) {
try (BaseIconFactory bif = getIconFactory()) {
- mDefaultIconBase = bif.makeDefaultIcon();
- }
- }
-
- int index;
- if ((index = mDefaultIcons.indexOfKey(userId)) >= 0) {
- return mDefaultIcons.valueAt(index).newIcon(mContext);
- } else {
- try (BaseIconFactory li = getIconFactory()) {
- BitmapInfo info = mDefaultIconBase.withFlags(
- li.getBitmapFlagOp(new IconOptions().setUser(UserHandle.of(userId))));
- mDefaultIcons.put(userId, info);
- return info.newIcon(mContext);
+ info = bif.makeDefaultIcon(UserHandle.of(userId));
}
+ mDefaultIcons.put(userId, info);
}
+ return info.newIcon(mContext);
}
}
@@ -247,8 +229,8 @@ public class TaskIconCache implements DisplayInfoChangeListener {
bif.setWrapperBackgroundColor(primaryColor);
// User version code O, so that the icon is always wrapped in an adaptive icon container
- return bif.createBadgedIconBitmap(drawable,
- new IconOptions().setUser(UserHandle.of(userId)).setInstantApp(isInstantApp));
+ return bif.createBadgedIconBitmap(drawable, UserHandle.of(userId),
+ Build.VERSION_CODES.O, isInstantApp);
}
}
@@ -256,7 +238,7 @@ public class TaskIconCache implements DisplayInfoChangeListener {
private BaseIconFactory getIconFactory() {
if (mIconFactory == null) {
mIconFactory = new BaseIconFactory(mContext,
- DisplayController.INSTANCE.get(mContext).getInfo().getDensityDpi(),
+ DisplayController.INSTANCE.get(mContext).getInfo().densityDpi,
mContext.getResources().getDimensionPixelSize(R.dimen.taskbar_icon_size));
}
return mIconFactory;
diff --git a/quickstep/src/com/android/quickstep/TaskOverlayFactory.java b/quickstep/src/com/android/quickstep/TaskOverlayFactory.java
index 3ef1332a87..e75d751582 100644
--- a/quickstep/src/com/android/quickstep/TaskOverlayFactory.java
+++ b/quickstep/src/com/android/quickstep/TaskOverlayFactory.java
@@ -23,7 +23,6 @@ import static com.android.quickstep.views.OverviewActionsView.DISABLED_NO_THUMBN
import static com.android.quickstep.views.OverviewActionsView.DISABLED_ROTATED;
import android.annotation.SuppressLint;
-import android.app.ActivityManager;
import android.content.Context;
import android.graphics.Insets;
import android.graphics.Matrix;
@@ -46,14 +45,12 @@ import com.android.launcher3.popup.SystemShortcut;
import com.android.launcher3.touch.PagedOrientationHandler;
import com.android.launcher3.util.ResourceBasedOverride;
import com.android.launcher3.util.SplitConfigurationOptions.SplitPositionOption;
-import com.android.launcher3.views.ActivityContext;
import com.android.quickstep.TaskShortcutFactory.SplitSelectSystemShortcut;
import com.android.quickstep.util.RecentsOrientedState;
import com.android.quickstep.views.OverviewActionsView;
import com.android.quickstep.views.RecentsView;
import com.android.quickstep.views.TaskThumbnailView;
import com.android.quickstep.views.TaskView;
-import com.android.quickstep.views.TaskView.TaskIdAttributeContainer;
import com.android.systemui.shared.recents.model.Task;
import com.android.systemui.shared.recents.model.ThumbnailData;
@@ -66,45 +63,41 @@ import java.util.List;
public class TaskOverlayFactory implements ResourceBasedOverride {
public static List<SystemShortcut> getEnabledShortcuts(TaskView taskView,
- DeviceProfile deviceProfile, TaskIdAttributeContainer taskContainer) {
+ DeviceProfile deviceProfile) {
final ArrayList<SystemShortcut> shortcuts = new ArrayList<>();
final BaseDraggingActivity activity = BaseActivity.fromContext(taskView.getContext());
- boolean hasMultipleTasks = taskView.getTaskIds()[1] != -1;
for (TaskShortcutFactory menuOption : MENU_OPTIONS) {
- if (hasMultipleTasks && !menuOption.showForSplitscreen()) {
- continue;
- }
-
- SystemShortcut shortcut = menuOption.getShortcut(activity, taskContainer);
- if (shortcut == null) {
- continue;
- }
-
+ SystemShortcut shortcut = menuOption.getShortcut(activity, taskView);
if (menuOption == TaskShortcutFactory.SPLIT_SCREEN &&
FeatureFlags.ENABLE_SPLIT_SELECT.get()) {
addSplitOptions(shortcuts, activity, taskView, deviceProfile);
- } else {
+ continue;
+ }
+
+ if (shortcut != null) {
shortcuts.add(shortcut);
}
}
RecentsOrientedState orientedState = taskView.getRecentsView().getPagedViewOrientedState();
- boolean canLauncherRotate = orientedState.isRecentsActivityRotationAllowed();
+ boolean canLauncherRotate = orientedState.canRecentsActivityRotate();
boolean isInLandscape = orientedState.getTouchRotation() != ROTATION_0;
// Add overview actions to the menu when in in-place rotate landscape mode.
if (!canLauncherRotate && isInLandscape) {
// Add screenshot action to task menu.
SystemShortcut screenshotShortcut = TaskShortcutFactory.SCREENSHOT
- .getShortcut(activity, taskContainer);
+ .getShortcut(activity, taskView);
if (screenshotShortcut != null) {
+ screenshotShortcut.setHasFinishRecentsInAction(true);
shortcuts.add(screenshotShortcut);
}
// Add modal action only if display orientation is the same as the device orientation.
if (orientedState.getDisplayRotation() == ROTATION_0) {
SystemShortcut modalShortcut = TaskShortcutFactory.MODAL
- .getShortcut(activity, taskContainer);
+ .getShortcut(activity, taskView);
if (modalShortcut != null) {
+ modalShortcut.setHasFinishRecentsInAction(true);
shortcuts.add(modalShortcut);
}
}
@@ -113,35 +106,10 @@ public class TaskOverlayFactory implements ResourceBasedOverride {
}
- /**
- * Does NOT add split options in the following scenarios:
- * * The taskView to add split options is already showing split screen tasks
- * * There aren't at least 2 tasks in overview to show split options for
- * * Device is in "Lock task mode"
- * * The taskView to show split options for is the focused task AND we haven't started
- * scrolling in overview (if we haven't scrolled, there's a split overview action button so
- * we don't need this menu option)
- */
- private static void addSplitOptions(List<SystemShortcut> outShortcuts,
+ public static void addSplitOptions(List<SystemShortcut> outShortcuts,
BaseDraggingActivity activity, TaskView taskView, DeviceProfile deviceProfile) {
- RecentsView recentsView = taskView.getRecentsView();
- PagedOrientationHandler orientationHandler = recentsView.getPagedOrientationHandler();
- int[] taskViewTaskIds = taskView.getTaskIds();
- boolean taskViewHasMultipleTasks = taskViewTaskIds[0] != -1 &&
- taskViewTaskIds[1] != -1;
- boolean notEnoughTasksToSplit = recentsView.getTaskViewCount() < 2;
- boolean isFocusedTask = deviceProfile.isTablet && taskView.isFocusedTask();
- boolean isTaskInExpectedScrollPosition =
- recentsView.isTaskInExpectedScrollPosition(recentsView.indexOfChild(taskView));
- ActivityManager activityManager =
- (ActivityManager) taskView.getContext().getSystemService(Context.ACTIVITY_SERVICE);
- boolean isLockTaskMode = activityManager.isInLockTaskMode();
-
- if (taskViewHasMultipleTasks || notEnoughTasksToSplit || isLockTaskMode ||
- (isFocusedTask && isTaskInExpectedScrollPosition)) {
- return;
- }
-
+ PagedOrientationHandler orientationHandler =
+ taskView.getRecentsView().getPagedOrientationHandler();
List<SplitPositionOption> positions =
orientationHandler.getSplitPositionOptions(deviceProfile);
for (SplitPositionOption option : positions) {
@@ -157,15 +125,13 @@ public class TaskOverlayFactory implements ResourceBasedOverride {
* Subclasses can attach any system listeners in this method, must be paired with
* {@link #removeListeners()}
*/
- public void initListeners() {
- }
+ public void initListeners() { }
/**
* Subclasses should remove any system listeners in this method, must be paired with
* {@link #initListeners()}
*/
- public void removeListeners() {
- }
+ public void removeListeners() { }
/** Note that these will be shown in order from top to bottom, if available for the task. */
private static final TaskShortcutFactory[] MENU_OPTIONS = new TaskShortcutFactory[]{
@@ -192,7 +158,7 @@ public class TaskOverlayFactory implements ResourceBasedOverride {
mApplicationContext = taskThumbnailView.getContext().getApplicationContext();
mThumbnailView = taskThumbnailView;
mImageApi = new ImageActionsApi(
- mApplicationContext, mThumbnailView::getThumbnail);
+ mApplicationContext, mThumbnailView::getThumbnail);
}
protected T getActionsView() {
@@ -246,11 +212,6 @@ public class TaskOverlayFactory implements ResourceBasedOverride {
}
}
- private void enterSplitSelect() {
- RecentsView overviewPanel = mThumbnailView.getTaskView().getRecentsView();
- overviewPanel.initiateSplitSelect(mThumbnailView.getTaskView());
- }
-
/**
* Called when the overlay is no longer used.
*/
@@ -266,8 +227,7 @@ public class TaskOverlayFactory implements ResourceBasedOverride {
/**
* Gets the modal state system shortcut.
*/
- public SystemShortcut getModalStateSystemShortcut(WorkspaceItemInfo itemInfo,
- View original) {
+ public SystemShortcut getModalStateSystemShortcut(WorkspaceItemInfo itemInfo) {
return null;
}
@@ -281,10 +241,9 @@ public class TaskOverlayFactory implements ResourceBasedOverride {
* Gets the system shortcut for the screenshot that will be added to the task menu.
*/
public SystemShortcut getScreenshotShortcut(BaseDraggingActivity activity,
- ItemInfo iteminfo, View originalView) {
- return new ScreenshotSystemShortcut(activity, iteminfo, originalView);
+ ItemInfo iteminfo) {
+ return new ScreenshotSystemShortcut(activity, iteminfo);
}
-
/**
* Gets the task snapshot as it is displayed on the screen.
*
@@ -315,29 +274,18 @@ public class TaskOverlayFactory implements ResourceBasedOverride {
}
protected void showBlockedByPolicyMessage() {
- ActivityContext activityContext = ActivityContext.lookupContext(
- mThumbnailView.getContext());
- String message = activityContext.getStringCache() != null
- ? activityContext.getStringCache().disabledByAdminMessage
- : mThumbnailView.getContext().getString(R.string.blocked_by_policy);
Toast.makeText(
mThumbnailView.getContext(),
- message,
+ R.string.blocked_by_policy,
Toast.LENGTH_LONG).show();
}
- /** Called when the snapshot has updated its full screen drawing parameters. */
- public void setFullscreenParams(TaskView.FullscreenDrawParams fullscreenParams) {
- }
-
private class ScreenshotSystemShortcut extends SystemShortcut {
private final BaseDraggingActivity mActivity;
- ScreenshotSystemShortcut(BaseDraggingActivity activity, ItemInfo itemInfo,
- View originalView) {
- super(R.drawable.ic_screenshot, R.string.action_screenshot, activity, itemInfo,
- originalView);
+ ScreenshotSystemShortcut(BaseDraggingActivity activity, ItemInfo itemInfo) {
+ super(R.drawable.ic_screenshot, R.string.action_screenshot, activity, itemInfo);
mActivity = activity;
}
@@ -357,14 +305,18 @@ public class TaskOverlayFactory implements ResourceBasedOverride {
mTask = task;
}
+ public void onShare() {
+ if (mIsAllowedByPolicy) {
+ endLiveTileMode(() -> mImageApi.startShareActivity(null));
+ } else {
+ showBlockedByPolicyMessage();
+ }
+ }
+
@SuppressLint("NewApi")
public void onScreenshot() {
endLiveTileMode(() -> saveScreenshot(mTask));
}
-
- public void onSplit() {
- endLiveTileMode(TaskOverlay.this::enterSplitSelect);
- }
}
}
@@ -373,10 +325,10 @@ public class TaskOverlayFactory implements ResourceBasedOverride {
* controller.
*/
public interface OverlayUICallbacks {
+ /** User has indicated they want to share the current task. */
+ void onShare();
+
/** User has indicated they want to screenshot the current task. */
void onScreenshot();
-
- /** User wants to start split screen with current app. */
- void onSplit();
}
}
diff --git a/quickstep/src/com/android/quickstep/TaskShortcutFactory.java b/quickstep/src/com/android/quickstep/TaskShortcutFactory.java
index e807e26b08..a078bf331e 100644
--- a/quickstep/src/com/android/quickstep/TaskShortcutFactory.java
+++ b/quickstep/src/com/android/quickstep/TaskShortcutFactory.java
@@ -35,6 +35,7 @@ import android.window.SplashScreen;
import com.android.launcher3.BaseDraggingActivity;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.R;
+import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.logging.StatsLogManager.LauncherEvent;
import com.android.launcher3.model.WellbeingModel;
import com.android.launcher3.popup.SystemShortcut;
@@ -44,11 +45,11 @@ import com.android.launcher3.util.SplitConfigurationOptions.SplitPositionOption;
import com.android.quickstep.views.RecentsView;
import com.android.quickstep.views.TaskThumbnailView;
import com.android.quickstep.views.TaskView;
-import com.android.quickstep.views.TaskView.TaskIdAttributeContainer;
import com.android.systemui.shared.recents.model.Task;
import com.android.systemui.shared.recents.view.AppTransitionAnimationSpecCompat;
import com.android.systemui.shared.recents.view.AppTransitionAnimationSpecsFuture;
import com.android.systemui.shared.recents.view.RecentsTransition;
+import com.android.systemui.shared.system.ActivityCompat;
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.ActivityOptionsCompat;
import com.android.systemui.shared.system.WindowManagerWrapper;
@@ -60,31 +61,9 @@ import java.util.List;
* Represents a system shortcut that can be shown for a recent task.
*/
public interface TaskShortcutFactory {
- SystemShortcut getShortcut(BaseDraggingActivity activity,
- TaskIdAttributeContainer taskContainer);
+ SystemShortcut getShortcut(BaseDraggingActivity activity, TaskView view);
- default boolean showForSplitscreen() {
- return false;
- }
-
- TaskShortcutFactory APP_INFO = new TaskShortcutFactory() {
- @Override
- public SystemShortcut getShortcut(BaseDraggingActivity activity,
- TaskIdAttributeContainer taskContainer) {
- TaskView taskView = taskContainer.getTaskView();
- AppInfo.SplitAccessibilityInfo accessibilityInfo =
- new AppInfo.SplitAccessibilityInfo(taskView.containsMultipleTasks(),
- TaskUtils.getTitle(taskView.getContext(), taskContainer.getTask()),
- taskContainer.getA11yNodeId()
- );
- return new AppInfo(activity, taskContainer.getItemInfo(), taskView, accessibilityInfo);
- }
-
- @Override
- public boolean showForSplitscreen() {
- return true;
- }
- };
+ TaskShortcutFactory APP_INFO = (activity, view) -> new AppInfo(activity, view.getItemInfo());
abstract class MultiWindowFactory implements TaskShortcutFactory {
@@ -103,28 +82,28 @@ public interface TaskShortcutFactory {
protected abstract boolean onActivityStarted(BaseDraggingActivity activity);
@Override
- public SystemShortcut getShortcut(BaseDraggingActivity activity,
- TaskIdAttributeContainer taskContainer) {
- final Task task = taskContainer.getTask();
+ public SystemShortcut getShortcut(BaseDraggingActivity activity, TaskView taskView) {
+ final Task task = taskView.getTask();
if (!task.isDockable) {
return null;
}
if (!isAvailable(activity, task.key.displayId)) {
return null;
}
- return new MultiWindowSystemShortcut(mIconRes, mTextRes, activity, taskContainer, this,
+ return new MultiWindowSystemShortcut(mIconRes, mTextRes, activity, taskView, this,
mLauncherEvent);
}
}
class SplitSelectSystemShortcut extends SystemShortcut {
private final TaskView mTaskView;
- private final SplitPositionOption mSplitPositionOption;
+ private SplitPositionOption mSplitPositionOption;
public SplitSelectSystemShortcut(BaseDraggingActivity target, TaskView taskView,
SplitPositionOption option) {
- super(option.iconResId, option.textResId, target, taskView.getItemInfo(), taskView);
+ super(option.mIconResId, option.mTextResId, target, taskView.getItemInfo());
mTaskView = taskView;
mSplitPositionOption = option;
+ setEnabled(taskView.getRecentsView().getTaskViewCount() > 1);
}
@Override
@@ -133,7 +112,7 @@ public interface TaskShortcutFactory {
}
}
- class MultiWindowSystemShortcut extends SystemShortcut<BaseDraggingActivity> {
+ class MultiWindowSystemShortcut extends SystemShortcut {
private Handler mHandler;
@@ -144,15 +123,13 @@ public interface TaskShortcutFactory {
private final LauncherEvent mLauncherEvent;
public MultiWindowSystemShortcut(int iconRes, int textRes, BaseDraggingActivity activity,
- TaskIdAttributeContainer taskContainer, MultiWindowFactory factory,
- LauncherEvent launcherEvent) {
- super(iconRes, textRes, activity, taskContainer.getItemInfo(),
- taskContainer.getTaskView());
+ TaskView taskView, MultiWindowFactory factory, LauncherEvent launcherEvent) {
+ super(iconRes, textRes, activity, taskView.getItemInfo());
mLauncherEvent = launcherEvent;
mHandler = new Handler(Looper.getMainLooper());
- mTaskView = taskContainer.getTaskView();
+ mTaskView = taskView;
mRecentsView = activity.getOverviewPanel();
- mThumbnailView = taskContainer.getThumbnailView();
+ mThumbnailView = taskView.getThumbnail();
mFactory = factory;
}
@@ -190,7 +167,7 @@ public interface TaskShortcutFactory {
ActivityOptions options = mFactory.makeLaunchOptions(mTarget);
if (options != null) {
- options.setSplashScreenStyle(SplashScreen.SPLASH_SCREEN_STYLE_ICON);
+ options.setSplashscreenStyle(SplashScreen.SPLASH_SCREEN_STYLE_ICON);
}
if (options != null
&& ActivityManagerWrapper.getInstance().startActivityFromRecents(taskId,
@@ -242,7 +219,6 @@ public interface TaskShortcutFactory {
}
}
- /** @Deprecated */
TaskShortcutFactory SPLIT_SCREEN = new MultiWindowFactory(R.drawable.ic_split_screen,
R.string.recent_task_option_split_screen, LAUNCHER_SYSTEM_SHORTCUT_SPLIT_SCREEN_TAP) {
@@ -257,9 +233,20 @@ public interface TaskShortcutFactory {
}
@Override
+ public SystemShortcut getShortcut(BaseDraggingActivity activity, TaskView taskView) {
+ SystemShortcut shortcut = super.getShortcut(activity, taskView);
+ if (shortcut != null && FeatureFlags.ENABLE_SPLIT_SELECT.get()) {
+ // Disable if there's only one recent app for split screen
+ shortcut.setEnabled(taskView.getRecentsView().getTaskViewCount() > 1);
+ }
+ return shortcut;
+ }
+
+ @Override
protected ActivityOptions makeLaunchOptions(Activity activity) {
+ final ActivityCompat act = new ActivityCompat(activity);
final int navBarPosition = WindowManagerWrapper.getInstance().getNavBarPosition(
- activity.getDisplayId());
+ act.getDisplayId());
if (navBarPosition == WindowManagerWrapper.NAV_BAR_POS_INVALID) {
return null;
}
@@ -297,7 +284,7 @@ public interface TaskShortcutFactory {
}
};
- TaskShortcutFactory PIN = (activity, taskContainer) -> {
+ TaskShortcutFactory PIN = (activity, tv) -> {
if (!SystemUiProxy.INSTANCE.get(activity).isActive()) {
return null;
}
@@ -308,20 +295,18 @@ public interface TaskShortcutFactory {
// We shouldn't be able to pin while an app is locked.
return null;
}
- return new PinSystemShortcut(activity, taskContainer);
+ return new PinSystemShortcut(activity, tv);
};
- class PinSystemShortcut extends SystemShortcut<BaseDraggingActivity> {
+ class PinSystemShortcut extends SystemShortcut {
private static final String TAG = "PinSystemShortcut";
private final TaskView mTaskView;
- public PinSystemShortcut(BaseDraggingActivity target,
- TaskIdAttributeContainer taskContainer) {
- super(R.drawable.ic_pin, R.string.recent_task_option_pin, target,
- taskContainer.getItemInfo(), taskContainer.getTaskView());
- mTaskView = taskContainer.getTaskView();
+ public PinSystemShortcut(BaseDraggingActivity target, TaskView tv) {
+ super(R.drawable.ic_pin, R.string.recent_task_option_pin, target, tv.getItemInfo());
+ mTaskView = tv;
}
@Override
@@ -335,25 +320,20 @@ public interface TaskShortcutFactory {
}
}
- TaskShortcutFactory INSTALL = (activity, taskContainer) ->
+ TaskShortcutFactory INSTALL = (activity, view) ->
InstantAppResolver.newInstance(activity).isInstantApp(activity,
- taskContainer.getTask().getTopComponent().getPackageName())
- ? new SystemShortcut.Install(activity, taskContainer.getItemInfo(),
- taskContainer.getTaskView()) : null;
+ view.getTask().getTopComponent().getPackageName())
+ ? new SystemShortcut.Install(activity, view.getItemInfo()) : null;
- TaskShortcutFactory WELLBEING = (activity, taskContainer) ->
- WellbeingModel.SHORTCUT_FACTORY.getShortcut(activity, taskContainer.getItemInfo(),
- taskContainer.getTaskView());
+ TaskShortcutFactory WELLBEING = (activity, view) ->
+ WellbeingModel.SHORTCUT_FACTORY.getShortcut(activity, view.getItemInfo());
- TaskShortcutFactory SCREENSHOT = (activity, taskContainer) ->
- taskContainer.getThumbnailView().getTaskOverlay()
- .getScreenshotShortcut(activity, taskContainer.getItemInfo(),
- taskContainer.getTaskView());
+ TaskShortcutFactory SCREENSHOT = (activity, tv) -> tv.getThumbnail().getTaskOverlay()
+ .getScreenshotShortcut(activity, tv.getItemInfo());
- TaskShortcutFactory MODAL = (activity, taskContainer) -> {
+ TaskShortcutFactory MODAL = (activity, tv) -> {
if (ENABLE_OVERVIEW_SELECTIONS.get()) {
- return taskContainer.getThumbnailView().getTaskOverlay().getModalStateSystemShortcut(
- taskContainer.getItemInfo(), taskContainer.getTaskView());
+ return tv.getThumbnail().getTaskOverlay().getModalStateSystemShortcut(tv.getItemInfo());
}
return null;
};
diff --git a/quickstep/src/com/android/quickstep/TaskThumbnailCache.java b/quickstep/src/com/android/quickstep/TaskThumbnailCache.java
index 3175ba8463..a8a0219594 100644
--- a/quickstep/src/com/android/quickstep/TaskThumbnailCache.java
+++ b/quickstep/src/com/android/quickstep/TaskThumbnailCache.java
@@ -104,9 +104,6 @@ public class TaskThumbnailCache {
* Synchronously fetches the thumbnail for the given {@param task} and puts it in the cache.
*/
public void updateThumbnailInCache(Task task) {
- if (task == null) {
- return;
- }
Preconditions.assertUIThread();
// Fetch the thumbnail for this task and put it in the cache
if (task.thumbnail == null) {
@@ -134,8 +131,7 @@ public class TaskThumbnailCache {
Preconditions.assertUIThread();
boolean lowResolution = !mHighResLoadingState.isEnabled();
- if (task.thumbnail != null && task.thumbnail.thumbnail != null
- && (!task.thumbnail.reducedResolution || lowResolution)) {
+ if (task.thumbnail != null && (!task.thumbnail.reducedResolution || lowResolution)) {
// Nothing to load, the thumbnail is already high-resolution or matches what the
// request, so just callback
callback.accept(task.thumbnail);
@@ -153,8 +149,7 @@ public class TaskThumbnailCache {
Preconditions.assertUIThread();
ThumbnailData cachedThumbnail = mCache.getAndInvalidateIfModified(key);
- if (cachedThumbnail != null && cachedThumbnail.thumbnail != null
- && (!cachedThumbnail.reducedResolution || lowResolution)) {
+ if (cachedThumbnail != null && (!cachedThumbnail.reducedResolution || lowResolution)) {
// Already cached, lets use that thumbnail
callback.accept(cachedThumbnail);
return null;
diff --git a/quickstep/src/com/android/quickstep/TaskViewUtils.java b/quickstep/src/com/android/quickstep/TaskViewUtils.java
index db402aff85..37fda73d44 100644
--- a/quickstep/src/com/android/quickstep/TaskViewUtils.java
+++ b/quickstep/src/com/android/quickstep/TaskViewUtils.java
@@ -15,8 +15,6 @@
*/
package com.android.quickstep;
-import static android.app.ActivityTaskManager.INVALID_TASK_ID;
-import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
import static android.view.WindowManager.TRANSIT_OPEN;
import static android.view.WindowManager.TRANSIT_TO_FRONT;
@@ -29,15 +27,13 @@ import static com.android.launcher3.QuickstepTransitionManager.ANIMATION_NAV_FAD
import static com.android.launcher3.QuickstepTransitionManager.NAV_FADE_IN_INTERPOLATOR;
import static com.android.launcher3.QuickstepTransitionManager.NAV_FADE_OUT_INTERPOLATOR;
import static com.android.launcher3.QuickstepTransitionManager.RECENTS_LAUNCH_DURATION;
-import static com.android.launcher3.QuickstepTransitionManager.SPLIT_DIVIDER_ANIM_DURATION;
-import static com.android.launcher3.QuickstepTransitionManager.SPLIT_LAUNCH_DURATION;
import static com.android.launcher3.Utilities.getDescendantCoordRelativeToAncestor;
import static com.android.launcher3.anim.Interpolators.LINEAR;
import static com.android.launcher3.anim.Interpolators.TOUCH_RESPONSE_INTERPOLATOR;
+import static com.android.launcher3.anim.Interpolators.TOUCH_RESPONSE_INTERPOLATOR_ACCEL_DEACCEL;
import static com.android.launcher3.anim.Interpolators.clampToProgress;
import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE;
import static com.android.launcher3.statehandlers.DepthController.DEPTH;
-import static com.android.launcher3.testing.TestProtocol.BAD_STATE;
import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_CLOSING;
import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_OPENING;
@@ -45,9 +41,7 @@ import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
-import android.animation.ValueAnimator;
import android.annotation.TargetApi;
-import android.app.PendingIntent;
import android.content.ComponentName;
import android.content.Context;
import android.graphics.Matrix;
@@ -55,7 +49,6 @@ import android.graphics.Matrix.ScaleToFit;
import android.graphics.Rect;
import android.graphics.RectF;
import android.os.Build;
-import android.util.Log;
import android.view.SurfaceControl;
import android.view.View;
import android.window.TransitionInfo;
@@ -69,16 +62,15 @@ import com.android.launcher3.anim.AnimationSuccessListener;
import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.anim.Interpolators;
import com.android.launcher3.anim.PendingAnimation;
+import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.statehandlers.DepthController;
import com.android.launcher3.statemanager.StateManager;
import com.android.launcher3.util.DisplayController;
-import com.android.quickstep.RemoteTargetGluer.RemoteTargetHandle;
import com.android.quickstep.util.MultiValueUpdateListener;
import com.android.quickstep.util.SurfaceTransactionApplier;
import com.android.quickstep.util.TaskViewSimulator;
import com.android.quickstep.util.TransformParams;
-import com.android.quickstep.views.GroupedTaskView;
import com.android.quickstep.views.RecentsView;
import com.android.quickstep.views.TaskThumbnailView;
import com.android.quickstep.views.TaskView;
@@ -87,10 +79,6 @@ import com.android.systemui.shared.system.InteractionJankMonitorWrapper;
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat.SurfaceParams;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.function.Consumer;
-
/**
* Utility class for helpful methods related to {@link TaskView} objects and their tasks.
*/
@@ -151,100 +139,107 @@ public final class TaskViewUtils {
// If the opening task id is not currently visible in overview, then fall back to normal app
// icon launch animation
- TaskView taskView = recentsView.getTaskViewByTaskId(openingTaskId);
+ TaskView taskView = recentsView.getTaskView(openingTaskId);
if (taskView == null || !recentsView.isTaskViewVisible(taskView)) {
return null;
}
return taskView;
}
- public static void createRecentsWindowAnimator(
- @NonNull TaskView v, boolean skipViewChanges,
- @NonNull RemoteAnimationTargetCompat[] appTargets,
- @NonNull RemoteAnimationTargetCompat[] wallpaperTargets,
- @NonNull RemoteAnimationTargetCompat[] nonAppTargets,
- @Nullable DepthController depthController,
+ public static void createRecentsWindowAnimator(TaskView v, boolean skipViewChanges,
+ RemoteAnimationTargetCompat[] appTargets,
+ RemoteAnimationTargetCompat[] wallpaperTargets,
+ RemoteAnimationTargetCompat[] nonAppTargets, DepthController depthController,
PendingAnimation out) {
- RecentsView recentsView = v.getRecentsView();
+ boolean isRunningTask = v.isRunningTask();
+ TransformParams params = null;
+ TaskViewSimulator tsv = null;
+ if (ENABLE_QUICKSTEP_LIVE_TILE.get() && isRunningTask) {
+ params = v.getRecentsView().getLiveTileParams();
+ tsv = v.getRecentsView().getLiveTileTaskViewSimulator();
+ }
+ createRecentsWindowAnimator(v, skipViewChanges, appTargets, wallpaperTargets, nonAppTargets,
+ depthController, out, params, tsv);
+ }
+
+ /**
+ * Creates an animation that controls the window of the opening targets for the recents launch
+ * animation.
+ */
+ public static void createRecentsWindowAnimator(TaskView v, boolean skipViewChanges,
+ RemoteAnimationTargetCompat[] appTargets,
+ RemoteAnimationTargetCompat[] wallpaperTargets,
+ RemoteAnimationTargetCompat[] nonAppTargets, DepthController depthController,
+ PendingAnimation out, @Nullable TransformParams params,
+ @Nullable TaskViewSimulator tsv) {
boolean isQuickSwitch = v.isEndQuickswitchCuj();
v.setEndQuickswitchCuj(false);
+ boolean inLiveTileMode =
+ ENABLE_QUICKSTEP_LIVE_TILE.get() && v.getRecentsView().getRunningTaskIndex() != -1;
final RemoteAnimationTargets targets =
new RemoteAnimationTargets(appTargets, wallpaperTargets, nonAppTargets,
- MODE_OPENING);
+ inLiveTileMode ? MODE_CLOSING : MODE_OPENING);
final RemoteAnimationTargetCompat navBarTarget = targets.getNavBarRemoteAnimationTarget();
- SurfaceTransactionApplier applier = new SurfaceTransactionApplier(v);
- targets.addReleaseCheck(applier);
+ if (params == null) {
+ SurfaceTransactionApplier applier = new SurfaceTransactionApplier(v);
+ targets.addReleaseCheck(applier);
- RemoteTargetHandle[] remoteTargetHandles;
- RemoteTargetHandle[] recentsViewHandles = recentsView.getRemoteTargetHandles();
- if (v.isRunningTask() && recentsViewHandles != null) {
- // Re-use existing handles
- remoteTargetHandles = recentsViewHandles;
- } else {
- RemoteTargetGluer gluer = new RemoteTargetGluer(v.getContext(),
- recentsView.getSizeStrategy(), targets);
- if (v.containsMultipleTasks()) {
- remoteTargetHandles = gluer.assignTargetsForSplitScreen(targets, v.getTaskIds());
- } else {
- remoteTargetHandles = gluer.assignTargets(targets);
- }
- }
- for (RemoteTargetHandle remoteTargetGluer : remoteTargetHandles) {
- remoteTargetGluer.getTransformParams().setSyncTransactionApplier(applier);
+ params = new TransformParams()
+ .setSyncTransactionApplier(applier)
+ .setTargetSet(targets);
}
+ final RecentsView recentsView = v.getRecentsView();
int taskIndex = recentsView.indexOfChild(v);
Context context = v.getContext();
DeviceProfile dp = BaseActivity.fromContext(context).getDeviceProfile();
- boolean showAsGrid = dp.isTablet;
+ boolean showAsGrid = dp.isTablet && FeatureFlags.ENABLE_OVERVIEW_GRID.get();
boolean parallaxCenterAndAdjacentTask =
taskIndex != recentsView.getCurrentPage() && !showAsGrid;
- int taskRectTranslationPrimary = recentsView.getScrollOffset(taskIndex);
- int taskRectTranslationSecondary = showAsGrid ? (int) v.getGridTranslationY() : 0;
-
- RemoteTargetHandle[] topMostSimulators = null;
-
- if (!v.isRunningTask()) {
- // TVSs already initialized from the running task, no need to re-init
- for (RemoteTargetHandle targetHandle : remoteTargetHandles) {
- TaskViewSimulator tvsLocal = targetHandle.getTaskViewSimulator();
- tvsLocal.setDp(dp);
-
- // RecentsView never updates the display rotation until swipe-up so the value may
- // be stale. Use the display value instead.
- int displayRotation = DisplayController.INSTANCE.get(context).getInfo().rotation;
- tvsLocal.getOrientationState().update(displayRotation, displayRotation);
-
- tvsLocal.fullScreenProgress.value = 0;
- tvsLocal.recentsViewScale.value = 1;
- tvsLocal.setIsGridTask(v.isGridTask());
- tvsLocal.getOrientationState().getOrientationHandler().set(tvsLocal,
- TaskViewSimulator::setTaskRectTranslation, taskRectTranslationPrimary,
- taskRectTranslationSecondary);
-
- // Fade in the task during the initial 20% of the animation
- out.addFloat(targetHandle.getTransformParams(), TransformParams.TARGET_ALPHA, 0, 1,
- clampToProgress(LINEAR, 0, 0.2f));
+ float gridTranslationSecondary = recentsView.getGridTranslationSecondary(taskIndex);
+ int startScroll = recentsView.getScrollOffset(taskIndex);
+
+ TaskViewSimulator topMostSimulator = null;
+
+ if (tsv == null && targets.apps.length > 0) {
+ tsv = new TaskViewSimulator(context, recentsView.getSizeStrategy());
+ tsv.setDp(dp);
+
+ // RecentsView never updates the display rotation until swipe-up so the value may
+ // be stale. Use the display value instead.
+ int displayRotation = DisplayController.INSTANCE.get(context).getInfo().rotation;
+ tsv.getOrientationState().update(displayRotation, displayRotation);
+
+ tsv.setPreview(targets.apps[targets.apps.length - 1]);
+ tsv.fullScreenProgress.value = 0;
+ tsv.recentsViewScale.value = 1;
+ if (showAsGrid) {
+ tsv.taskSecondaryTranslation.value = gridTranslationSecondary;
}
+ tsv.setScroll(startScroll);
+
+ // Fade in the task during the initial 20% of the animation
+ out.addFloat(params, TransformParams.TARGET_ALPHA, 0, 1,
+ clampToProgress(LINEAR, 0, 0.2f));
}
- for (RemoteTargetHandle targetHandle : remoteTargetHandles) {
- TaskViewSimulator tvsLocal = targetHandle.getTaskViewSimulator();
- out.setFloat(tvsLocal.fullScreenProgress,
+ if (tsv != null) {
+ out.setFloat(tsv.fullScreenProgress,
AnimatedFloat.VALUE, 1, TOUCH_RESPONSE_INTERPOLATOR);
- out.setFloat(tvsLocal.recentsViewScale,
- AnimatedFloat.VALUE, tvsLocal.getFullScreenScale(),
- TOUCH_RESPONSE_INTERPOLATOR);
- out.setFloat(tvsLocal.recentsViewScroll, AnimatedFloat.VALUE, 0,
+ out.setFloat(tsv.recentsViewScale,
+ AnimatedFloat.VALUE, tsv.getFullScreenScale(), TOUCH_RESPONSE_INTERPOLATOR);
+ if (showAsGrid) {
+ out.setFloat(tsv.taskSecondaryTranslation, AnimatedFloat.VALUE, 0,
+ TOUCH_RESPONSE_INTERPOLATOR_ACCEL_DEACCEL);
+ }
+ out.setFloat(tsv.recentsViewScroll, AnimatedFloat.VALUE, 0,
TOUCH_RESPONSE_INTERPOLATOR);
- out.addOnFrameCallback(() -> {
- for (RemoteTargetHandle handle : remoteTargetHandles) {
- handle.getTaskViewSimulator().apply(handle.getTransformParams());
- }
- });
+ TaskViewSimulator finalTsv = tsv;
+ TransformParams finalParams = params;
+ out.addOnFrameCallback(() -> finalTsv.apply(finalParams));
if (navBarTarget != null) {
final Rect cropRect = new Rect();
out.addOnFrameListener(new MultiValueUpdateListener() {
@@ -257,23 +252,18 @@ public final class TaskViewUtils {
public void onUpdate(float percent, boolean initOnly) {
final SurfaceParams.Builder navBuilder =
new SurfaceParams.Builder(navBarTarget.leash);
-
- // TODO Do we need to operate over multiple TVSs for the navbar leash?
- for (RemoteTargetHandle handle : remoteTargetHandles) {
- if (mNavFadeIn.value > mNavFadeIn.getStartValue()) {
- TaskViewSimulator taskViewSimulator = handle.getTaskViewSimulator();
- taskViewSimulator.getCurrentCropRect().round(cropRect);
- navBuilder.withMatrix(taskViewSimulator.getCurrentMatrix())
- .withWindowCrop(cropRect)
- .withAlpha(mNavFadeIn.value);
- } else {
- navBuilder.withAlpha(mNavFadeOut.value);
- }
- handle.getTransformParams().applySurfaceParams(navBuilder.build());
+ if (mNavFadeIn.value > mNavFadeIn.getStartValue()) {
+ finalTsv.getCurrentCropRect().round(cropRect);
+ navBuilder.withMatrix(finalTsv.getCurrentMatrix())
+ .withWindowCrop(cropRect)
+ .withAlpha(mNavFadeIn.value);
+ } else {
+ navBuilder.withAlpha(mNavFadeOut.value);
}
+ finalParams.applySurfaceParams(navBuilder.build());
}
});
- } else {
+ } else if (inLiveTileMode) {
// There is no transition animation for app launch from recent in live tile mode so
// we have to trigger the navigation bar animation from system here.
final RecentsAnimationController controller =
@@ -282,17 +272,14 @@ public final class TaskViewUtils {
controller.animateNavigationBarToApp(RECENTS_LAUNCH_DURATION);
}
}
- topMostSimulators = remoteTargetHandles;
+ topMostSimulator = tsv;
}
- if (!skipViewChanges && parallaxCenterAndAdjacentTask && topMostSimulators != null
- && topMostSimulators.length > 0) {
+ if (!skipViewChanges && parallaxCenterAndAdjacentTask && topMostSimulator != null) {
out.addFloat(v, VIEW_ALPHA, 1, 0, clampToProgress(LINEAR, 0.2f, 0.4f));
- RemoteTargetHandle[] simulatorCopies = topMostSimulators;
- for (RemoteTargetHandle handle : simulatorCopies) {
- handle.getTaskViewSimulator().apply(handle.getTransformParams());
- }
+ TaskViewSimulator simulatorToCopy = topMostSimulator;
+ simulatorToCopy.apply(params);
// Mt represents the overall transformation on the thumbnailView relative to the
// Launcher's rootView
@@ -306,49 +293,36 @@ public final class TaskViewUtils {
// During animation we apply transformation on the thumbnailView (and not the rootView)
// to follow the TaskViewSimulator. So the final matrix applied on the thumbnailView is:
// Mt K(0)` K(t) Mt`
- TaskThumbnailView[] thumbnails = v.getThumbnails();
- Matrix[] mt = new Matrix[simulatorCopies.length];
- Matrix[] mti = new Matrix[simulatorCopies.length];
- for (int i = 0; i < thumbnails.length; i++) {
- TaskThumbnailView ttv = thumbnails[i];
- RectF localBounds = new RectF(0, 0, ttv.getWidth(), ttv.getHeight());
- float[] tvBoundsMapped = new float[]{0, 0, ttv.getWidth(), ttv.getHeight()};
- getDescendantCoordRelativeToAncestor(ttv, ttv.getRootView(), tvBoundsMapped, false);
- RectF localBoundsInRoot = new RectF(
- tvBoundsMapped[0], tvBoundsMapped[1],
- tvBoundsMapped[2], tvBoundsMapped[3]);
- Matrix localMt = new Matrix();
- localMt.setRectToRect(localBounds, localBoundsInRoot, ScaleToFit.FILL);
- mt[i] = localMt;
-
- Matrix localMti = new Matrix();
- localMt.invert(localMti);
- mti[i] = localMti;
- }
+ TaskThumbnailView ttv = v.getThumbnail();
+ RectF tvBounds = new RectF(0, 0, ttv.getWidth(), ttv.getHeight());
+ float[] tvBoundsMapped = new float[]{0, 0, ttv.getWidth(), ttv.getHeight()};
+ getDescendantCoordRelativeToAncestor(ttv, ttv.getRootView(), tvBoundsMapped, false);
+ RectF tvBoundsInRoot = new RectF(
+ tvBoundsMapped[0], tvBoundsMapped[1],
+ tvBoundsMapped[2], tvBoundsMapped[3]);
+
+ Matrix mt = new Matrix();
+ mt.setRectToRect(tvBounds, tvBoundsInRoot, ScaleToFit.FILL);
+
+ Matrix mti = new Matrix();
+ mt.invert(mti);
+
+ Matrix k0i = new Matrix();
+ simulatorToCopy.getCurrentMatrix().invert(k0i);
- Matrix[] k0i = new Matrix[simulatorCopies.length];
- for (int i = 0; i < simulatorCopies.length; i++) {
- k0i[i] = new Matrix();
- simulatorCopies[i].getTaskViewSimulator().getCurrentMatrix().invert(k0i[i]);
- }
Matrix animationMatrix = new Matrix();
out.addOnFrameCallback(() -> {
- for (int i = 0; i < simulatorCopies.length; i++) {
- animationMatrix.set(mt[i]);
- animationMatrix.postConcat(k0i[i]);
- animationMatrix.postConcat(simulatorCopies[i]
- .getTaskViewSimulator().getCurrentMatrix());
- animationMatrix.postConcat(mti[i]);
- thumbnails[i].setAnimationMatrix(animationMatrix);
- }
+ animationMatrix.set(mt);
+ animationMatrix.postConcat(k0i);
+ animationMatrix.postConcat(simulatorToCopy.getCurrentMatrix());
+ animationMatrix.postConcat(mti);
+ ttv.setAnimationMatrix(animationMatrix);
});
out.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
- for (TaskThumbnailView ttv : thumbnails) {
- ttv.setAnimationMatrix(null);
- }
+ ttv.setAnimationMatrix(null);
}
});
}
@@ -391,20 +365,18 @@ public final class TaskViewUtils {
* device is considered in multiWindowMode and things like insets and stuff change
* and calculations have to be adjusted in the animations for that
*/
- public static void composeRecentsSplitLaunchAnimator(int initialTaskId,
- @Nullable PendingIntent initialTaskPendingIntent, int secondTaskId,
- @NonNull TransitionInfo transitionInfo, SurfaceControl.Transaction t,
- @NonNull Runnable finishCallback) {
- // TODO: consider initialTaskPendingIntent
- TransitionInfo.Change splitRoot1 = null;
- TransitionInfo.Change splitRoot2 = null;
+ public static void composeRecentsSplitLaunchAnimator(@NonNull TaskView initialView,
+ @NonNull TaskView v, @NonNull TransitionInfo transitionInfo,
+ SurfaceControl.Transaction t, @NonNull Runnable finishCallback) {
+
+ final TransitionInfo.Change[] splitRoots = new TransitionInfo.Change[2];
for (int i = 0; i < transitionInfo.getChanges().size(); ++i) {
final TransitionInfo.Change change = transitionInfo.getChanges().get(i);
final int taskId = change.getTaskInfo() != null ? change.getTaskInfo().taskId : -1;
final int mode = change.getMode();
// Find the target tasks' root tasks since those are the split stages that need to
// be animated (the tasks themselves are children and thus inherit animation).
- if (taskId == initialTaskId || taskId == secondTaskId) {
+ if (taskId == initialView.getTask().key.id || taskId == v.getTask().key.id) {
if (!(mode == TRANSIT_OPEN || mode == TRANSIT_TO_FRONT)) {
throw new IllegalStateException(
"Expected task to be showing, but it is " + mode);
@@ -413,18 +385,16 @@ public final class TaskViewUtils {
throw new IllegalStateException("Initiating multi-split launch but the split"
+ "root of " + taskId + " is already visible or has broken hierarchy.");
}
- }
- if (taskId == initialTaskId && initialTaskId != INVALID_TASK_ID) {
- splitRoot1 = transitionInfo.getChange(change.getParent());
- }
- if (taskId == secondTaskId) {
- splitRoot2 = transitionInfo.getChange(change.getParent());
+ splitRoots[taskId == initialView.getTask().key.id ? 0 : 1] =
+ transitionInfo.getChange(change.getParent());
}
}
// This is where we should animate the split roots. For now, though, just make them visible.
- animateSplitRoot(t, splitRoot1);
- animateSplitRoot(t, splitRoot2);
+ for (int i = 0; i < 2; ++i) {
+ t.show(splitRoots[i].getLeash());
+ t.setAlpha(splitRoots[i].getLeash(), 1.f);
+ }
// This contains the initial state (before animation), so apply this at the beginning of
// the animation.
@@ -434,107 +404,78 @@ public final class TaskViewUtils {
finishCallback.run();
}
- private static void animateSplitRoot(SurfaceControl.Transaction t,
- TransitionInfo.Change splitRoot) {
- if (splitRoot != null) {
- t.show(splitRoot.getLeash());
- t.setAlpha(splitRoot.getLeash(), 1.f);
- }
- }
-
- /**
- * Legacy version (until shell transitions are enabled)
- *
- * If {@param launchingTaskView} is not null, then this will play the tasks launch animation
- * from the position of the GroupedTaskView (when user taps on the TaskView to start it).
- * Technically this case should be taken care of by
- * {@link #composeRecentsSplitLaunchAnimatorLegacy()} below, but the way we launch tasks whether
- * it's a single task or multiple tasks results in different entry-points.
- *
- * If it is null, then it will simply fade in the starting apps and fade out launcher (for the
- * case where launcher handles animating starting split tasks from app icon) */
- public static void composeRecentsSplitLaunchAnimatorLegacy(
- @Nullable GroupedTaskView launchingTaskView, int initialTaskId,
- @Nullable PendingIntent initialTaskPendingIntent, int secondTaskId,
- @NonNull RemoteAnimationTargetCompat[] appTargets,
+ /** Legacy version (until shell transitions are enabled) */
+ public static void composeRecentsSplitLaunchAnimatorLegacy(@NonNull AnimatorSet anim,
+ @NonNull TaskView v, @NonNull RemoteAnimationTargetCompat[] appTargets,
@NonNull RemoteAnimationTargetCompat[] wallpaperTargets,
- @NonNull RemoteAnimationTargetCompat[] nonAppTargets,
- @NonNull StateManager stateManager,
- @Nullable DepthController depthController,
- @NonNull Runnable finishCallback) {
- if (launchingTaskView != null) {
- AnimatorSet animatorSet = new AnimatorSet();
- RecentsView recentsView = launchingTaskView.getRecentsView();
- animatorSet.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- super.onAnimationEnd(animation);
- finishCallback.run();
- }
- });
- composeRecentsLaunchAnimator(animatorSet, launchingTaskView,
- appTargets, wallpaperTargets, nonAppTargets,
- true, stateManager,
- recentsView, depthController);
- animatorSet.start();
- return;
+ @NonNull RemoteAnimationTargetCompat[] nonAppTargets, boolean launcherClosing,
+ @NonNull StateManager stateManager, @NonNull DepthController depthController,
+ int targetStage) {
+ PendingAnimation out = new PendingAnimation(RECENTS_LAUNCH_DURATION);
+ boolean isRunningTask = v.isRunningTask();
+ TransformParams params = null;
+ TaskViewSimulator tvs = null;
+ RecentsView recentsView = v.getRecentsView();
+ if (ENABLE_QUICKSTEP_LIVE_TILE.get() && isRunningTask) {
+ params = recentsView.getLiveTileParams();
+ tvs = recentsView.getLiveTileTaskViewSimulator();
}
- final ArrayList<SurfaceControl> openingTargets = new ArrayList<>();
- final ArrayList<SurfaceControl> closingTargets = new ArrayList<>();
- for (RemoteAnimationTargetCompat appTarget : appTargets) {
- final int taskId = appTarget.taskInfo != null ? appTarget.taskInfo.taskId : -1;
- final int mode = appTarget.mode;
- final SurfaceControl leash = appTarget.leash;
- if (leash == null) {
- continue;
- }
+ boolean inLiveTileMode =
+ ENABLE_QUICKSTEP_LIVE_TILE.get() && recentsView.getRunningTaskIndex() != -1;
+ final RemoteAnimationTargets targets =
+ new RemoteAnimationTargets(appTargets, wallpaperTargets, nonAppTargets,
+ inLiveTileMode ? MODE_CLOSING : MODE_OPENING);
- if (mode == MODE_OPENING) {
- openingTargets.add(leash);
- } else if (taskId == initialTaskId || taskId == secondTaskId) {
- throw new IllegalStateException("Expected task to be opening, but it is " + mode);
- } else if (mode == MODE_CLOSING) {
- closingTargets.add(leash);
- }
+ if (params == null) {
+ SurfaceTransactionApplier applier = new SurfaceTransactionApplier(v);
+ targets.addReleaseCheck(applier);
+
+ params = new TransformParams()
+ .setSyncTransactionApplier(applier)
+ .setTargetSet(targets);
}
- for (int i = 0; i < nonAppTargets.length; ++i) {
- final SurfaceControl leash = nonAppTargets[i].leash;
- if (nonAppTargets[i].windowType == TYPE_DOCK_DIVIDER && leash != null) {
- openingTargets.add(leash);
- }
+ Rect crop = new Rect();
+ Context context = v.getContext();
+ DeviceProfile dp = BaseActivity.fromContext(context).getDeviceProfile();
+ if (tvs == null && targets.apps.length > 0) {
+ tvs = new TaskViewSimulator(recentsView.getContext(), recentsView.getSizeStrategy());
+ tvs.setDp(dp);
+
+ // RecentsView never updates the display rotation until swipe-up so the value may
+ // be stale. Use the display value instead.
+ int displayRotation = DisplayController.INSTANCE.get(recentsView.getContext())
+ .getInfo().rotation;
+ tvs.getOrientationState().update(displayRotation, displayRotation);
+
+ tvs.setPreview(targets.apps[targets.apps.length - 1]);
+ tvs.fullScreenProgress.value = 0;
+ tvs.recentsViewScale.value = 1;
+// tvs.setScroll(startScroll);
+
+ // Fade in the task during the initial 20% of the animation
+ out.addFloat(params, TransformParams.TARGET_ALPHA, 0, 1,
+ clampToProgress(LINEAR, 0, 0.2f));
}
- final SurfaceControl.Transaction t = new SurfaceControl.Transaction();
- ValueAnimator animator = ValueAnimator.ofFloat(0f, 1f);
- animator.setDuration(SPLIT_LAUNCH_DURATION);
- animator.addUpdateListener(valueAnimator -> {
- float progress = valueAnimator.getAnimatedFraction();
- for (SurfaceControl leash: openingTargets) {
- t.setAlpha(leash, progress);
- }
- t.apply();
- });
- animator.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationStart(Animator animation) {
- for (SurfaceControl leash: openingTargets) {
- t.show(leash).setAlpha(leash, 0.0f);
- }
- t.apply();
- }
+ TaskViewSimulator topMostSimulator = null;
- @Override
- public void onAnimationEnd(Animator animation) {
- for (SurfaceControl leash: closingTargets) {
- t.hide(leash);
- }
- super.onAnimationEnd(animation);
- finishCallback.run();
- }
- });
- animator.start();
+ if (tvs != null) {
+ out.setFloat(tvs.fullScreenProgress,
+ AnimatedFloat.VALUE, 1, TOUCH_RESPONSE_INTERPOLATOR);
+ out.setFloat(tvs.recentsViewScale,
+ AnimatedFloat.VALUE, tvs.getFullScreenScale(), TOUCH_RESPONSE_INTERPOLATOR);
+ out.setFloat(tvs.recentsViewScroll,
+ AnimatedFloat.VALUE, 0, TOUCH_RESPONSE_INTERPOLATOR);
+
+ TaskViewSimulator finalTsv = tvs;
+ TransformParams finalParams = params;
+ out.addOnFrameCallback(() -> finalTsv.apply(finalParams));
+ topMostSimulator = tvs;
+ }
+
+ anim.play(out.buildAnim());
}
public static void composeRecentsLaunchAnimator(@NonNull AnimatorSet anim, @NonNull View v,
@@ -542,26 +483,13 @@ public final class TaskViewUtils {
@NonNull RemoteAnimationTargetCompat[] wallpaperTargets,
@NonNull RemoteAnimationTargetCompat[] nonAppTargets, boolean launcherClosing,
@NonNull StateManager stateManager, @NonNull RecentsView recentsView,
- @Nullable DepthController depthController) {
+ @NonNull DepthController depthController) {
boolean skipLauncherChanges = !launcherClosing;
TaskView taskView = findTaskViewToLaunch(recentsView, v, appTargets);
PendingAnimation pa = new PendingAnimation(RECENTS_LAUNCH_DURATION);
createRecentsWindowAnimator(taskView, skipLauncherChanges, appTargets, wallpaperTargets,
nonAppTargets, depthController, pa);
- if (launcherClosing) {
- // TODO(b/182592057): differentiate between "restore split" vs "launch fullscreen app"
- TaskViewUtils.createSplitAuxiliarySurfacesAnimator(nonAppTargets, true /*shown*/,
- (dividerAnimator) -> {
- // If split apps are launching, we want to delay showing the divider bar
- // until the very end once the apps are mostly in place. This is because we
- // aren't moving the divider leash in the relative position with the
- // launching apps.
- dividerAnimator.setStartDelay(pa.getDuration()
- - SPLIT_DIVIDER_ANIM_DURATION);
- pa.add(dividerAnimator);
- });
- }
Animator childStateAnimation = null;
// Found a visible recents task that matches the opening app, lets launch the app from there
@@ -570,32 +498,9 @@ public final class TaskViewUtils {
if (launcherClosing) {
Context context = v.getContext();
DeviceProfile dp = BaseActivity.fromContext(context).getDeviceProfile();
- launcherAnim = dp.isTablet
+ launcherAnim = dp.isTablet && FeatureFlags.ENABLE_OVERVIEW_GRID.get()
? ObjectAnimator.ofFloat(recentsView, RecentsView.CONTENT_ALPHA, 0)
: recentsView.createAdjacentPageAnimForTaskLaunch(taskView);
- if (dp.isTablet) {
- Log.d(BAD_STATE, "TVU composeRecentsLaunchAnimator alpha=" + 0);
- launcherAnim.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationStart(Animator animation) {
- Log.d(BAD_STATE, "TVU composeRecentsLaunchAnimator onStart");
- }
-
- @Override
- public void onAnimationCancel(Animator animation) {
- float alpha = recentsView == null
- ? -1
- : RecentsView.CONTENT_ALPHA.get(recentsView);
- Log.d(BAD_STATE, "TVU composeRecentsLaunchAnimator onCancel, alpha="
- + alpha);
- }
-
- @Override
- public void onAnimationEnd(Animator animation) {
- Log.d(BAD_STATE, "TVU composeRecentsLaunchAnimator onEnd");
- }
- });
- }
launcherAnim.setInterpolator(Interpolators.TOUCH_RESPONSE_INTERPOLATOR);
launcherAnim.setDuration(RECENTS_LAUNCH_DURATION);
@@ -637,70 +542,4 @@ public final class TaskViewUtils {
stateManager.setCurrentAnimation(anim, childStateAnimation);
anim.addListener(windowAnimEndListener);
}
-
- /**
- * Creates an animation to show/hide the auxiliary surfaces (aka. divider bar), only calling
- * {@param animatorHandler} if there are valid surfaces to animate.
- *
- * @return the animator animating the surfaces
- */
- public static ValueAnimator createSplitAuxiliarySurfacesAnimator(
- RemoteAnimationTargetCompat[] nonApps, boolean shown,
- Consumer<ValueAnimator> animatorHandler) {
- if (nonApps == null || nonApps.length == 0) {
- return null;
- }
-
- SurfaceControl.Transaction t = new SurfaceControl.Transaction();
- List<SurfaceControl> auxiliarySurfaces = new ArrayList<>(nonApps.length);
- boolean hasSurfaceToAnimate = false;
- for (int i = 0; i < nonApps.length; ++i) {
- final RemoteAnimationTargetCompat targ = nonApps[i];
- final SurfaceControl leash = targ.leash;
- if (targ.windowType == TYPE_DOCK_DIVIDER && leash != null) {
- auxiliarySurfaces.add(leash);
- hasSurfaceToAnimate = true;
- }
- }
- if (!hasSurfaceToAnimate) {
- return null;
- }
-
- ValueAnimator dockFadeAnimator = ValueAnimator.ofFloat(0f, 1f);
- dockFadeAnimator.addUpdateListener(valueAnimator -> {
- float progress = valueAnimator.getAnimatedFraction();
- for (SurfaceControl leash : auxiliarySurfaces) {
- t.setAlpha(leash, shown ? progress : 1 - progress);
- }
- t.apply();
- });
- dockFadeAnimator.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationStart(Animator animation) {
- super.onAnimationStart(animation);
- if (shown) {
- for (SurfaceControl leash : auxiliarySurfaces) {
- t.setAlpha(leash, 0);
- t.show(leash);
- }
- t.apply();
- }
- }
-
- @Override
- public void onAnimationEnd(Animator animation) {
- super.onAnimationEnd(animation);
- if (!shown) {
- for (SurfaceControl leash : auxiliarySurfaces) {
- t.hide(leash);
- }
- t.apply();
- }
- t.close();
- }
- });
- dockFadeAnimator.setDuration(SPLIT_DIVIDER_ANIM_DURATION);
- animatorHandler.accept(dockFadeAnimator);
- return dockFadeAnimator;
- }
}
diff --git a/quickstep/src/com/android/quickstep/TopTaskTracker.java b/quickstep/src/com/android/quickstep/TopTaskTracker.java
deleted file mode 100644
index 723dc721a9..0000000000
--- a/quickstep/src/com/android/quickstep/TopTaskTracker.java
+++ /dev/null
@@ -1,271 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.quickstep;
-
-import static android.app.ActivityTaskManager.INVALID_TASK_ID;
-import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT;
-import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
-import static android.content.Intent.ACTION_CHOOSER;
-import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
-
-import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT;
-
-import android.app.ActivityManager.RunningTaskInfo;
-import android.content.Context;
-
-import androidx.annotation.Nullable;
-import androidx.annotation.UiThread;
-
-import com.android.launcher3.util.MainThreadInitializedObject;
-import com.android.launcher3.util.SplitConfigurationOptions;
-import com.android.launcher3.util.SplitConfigurationOptions.StagePosition;
-import com.android.launcher3.util.SplitConfigurationOptions.StageType;
-import com.android.launcher3.util.SplitConfigurationOptions.StagedSplitTaskPosition;
-import com.android.launcher3.util.TraceHelper;
-import com.android.systemui.shared.recents.model.Task;
-import com.android.systemui.shared.recents.model.Task.TaskKey;
-import com.android.systemui.shared.system.ActivityManagerWrapper;
-import com.android.systemui.shared.system.TaskStackChangeListener;
-import com.android.systemui.shared.system.TaskStackChangeListeners;
-import com.android.wm.shell.splitscreen.ISplitScreenListener;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-
-/**
- * This class tracked the top-most task and some 'approximate' task history to allow faster
- * system state estimation during touch interaction
- */
-public class TopTaskTracker extends ISplitScreenListener.Stub implements TaskStackChangeListener {
-
- public static MainThreadInitializedObject<TopTaskTracker> INSTANCE =
- new MainThreadInitializedObject<>(TopTaskTracker::new);
-
- private static final int HISTORY_SIZE = 5;
-
- // Ordered list with first item being the most recent task.
- private final LinkedList<RunningTaskInfo> mOrderedTaskList = new LinkedList<>();
-
- private final StagedSplitTaskPosition mMainStagePosition = new StagedSplitTaskPosition();
- private final StagedSplitTaskPosition mSideStagePosition = new StagedSplitTaskPosition();
- private int mPinnedTaskId = INVALID_TASK_ID;
-
- private TopTaskTracker(Context context) {
- mMainStagePosition.stageType = SplitConfigurationOptions.STAGE_TYPE_MAIN;
- mSideStagePosition.stageType = SplitConfigurationOptions.STAGE_TYPE_SIDE;
-
- TaskStackChangeListeners.getInstance().registerTaskStackListener(this);
- SystemUiProxy.INSTANCE.get(context).registerSplitScreenListener(this);
- }
-
- @Override
- public void onTaskRemoved(int taskId) {
- mOrderedTaskList.removeIf(rto -> rto.taskId == taskId);
- }
-
- @Override
- public void onTaskMovedToFront(RunningTaskInfo taskInfo) {
- mOrderedTaskList.removeIf(rto -> rto.taskId == taskInfo.taskId);
- mOrderedTaskList.addFirst(taskInfo);
- if (mOrderedTaskList.size() >= HISTORY_SIZE) {
- // If we grow in size, remove the last taskInfo which is not part of the split task.
- Iterator<RunningTaskInfo> itr = mOrderedTaskList.descendingIterator();
- while (itr.hasNext()) {
- RunningTaskInfo info = itr.next();
- if (info.taskId != taskInfo.taskId
- && info.taskId != mMainStagePosition.taskId
- && info.taskId != mSideStagePosition.taskId) {
- itr.remove();
- return;
- }
- }
- }
- }
-
- @Override
- public void onStagePositionChanged(@StageType int stage, @StagePosition int position) {
- if (stage == SplitConfigurationOptions.STAGE_TYPE_MAIN) {
- mMainStagePosition.stagePosition = position;
- } else {
- mSideStagePosition.stagePosition = position;
- }
- }
-
- @Override
- public void onTaskStageChanged(int taskId, @StageType int stage, boolean visible) {
- // If task is not visible but we are tracking it, stop tracking it
- if (!visible) {
- if (mMainStagePosition.taskId == taskId) {
- resetTaskId(mMainStagePosition);
- } else if (mSideStagePosition.taskId == taskId) {
- resetTaskId(mSideStagePosition);
- } // else it's an un-tracked child
- return;
- }
-
- // If stage has moved to undefined, stop tracking the task
- if (stage == SplitConfigurationOptions.STAGE_TYPE_UNDEFINED) {
- resetTaskId(taskId == mMainStagePosition.taskId
- ? mMainStagePosition : mSideStagePosition);
- return;
- }
-
- if (stage == SplitConfigurationOptions.STAGE_TYPE_MAIN) {
- mMainStagePosition.taskId = taskId;
- } else {
- mSideStagePosition.taskId = taskId;
- }
- }
-
- @Override
- public void onActivityPinned(String packageName, int userId, int taskId, int stackId) {
- mPinnedTaskId = taskId;
- }
-
- @Override
- public void onActivityUnpinned() {
- mPinnedTaskId = INVALID_TASK_ID;
- }
-
- private void resetTaskId(StagedSplitTaskPosition taskPosition) {
- taskPosition.taskId = INVALID_TASK_ID;
- }
-
- /**
- * @return index 0 will be task in left/top position, index 1 in right/bottom position.
- * Will return empty array if device is not in staged split
- */
- public int[] getRunningSplitTaskIds() {
- if (mMainStagePosition.taskId == INVALID_TASK_ID
- || mSideStagePosition.taskId == INVALID_TASK_ID) {
- return new int[]{};
- }
- int[] out = new int[2];
- if (mMainStagePosition.stagePosition == STAGE_POSITION_TOP_OR_LEFT) {
- out[0] = mMainStagePosition.taskId;
- out[1] = mSideStagePosition.taskId;
- } else {
- out[1] = mMainStagePosition.taskId;
- out[0] = mSideStagePosition.taskId;
- }
- return out;
- }
-
-
- /**
- * Returns the CachedTaskInfo for the top most task
- */
- @UiThread
- public CachedTaskInfo getCachedTopTask(boolean filterOnlyVisibleRecents) {
- if (filterOnlyVisibleRecents) {
- // Since we only know about the top most task, any filtering may not be applied on the
- // cache. The second to top task may change while the top task is still the same.
- RunningTaskInfo[] tasks = TraceHelper.allowIpcs("getCachedTopTask.true", () ->
- ActivityManagerWrapper.getInstance().getRunningTasks(true));
- return new CachedTaskInfo(Arrays.asList(tasks));
- }
-
- if (mOrderedTaskList.isEmpty()) {
- RunningTaskInfo[] tasks = TraceHelper.allowIpcs("getCachedTopTask.false", () ->
- ActivityManagerWrapper.getInstance().getRunningTasks(
- false /* filterOnlyVisibleRecents */));
- Collections.addAll(mOrderedTaskList, tasks);
- }
-
- // Strip the pinned task
- ArrayList<RunningTaskInfo> tasks = new ArrayList<>(mOrderedTaskList);
- tasks.removeIf(t -> t.taskId == mPinnedTaskId);
- return new CachedTaskInfo(tasks);
- }
-
- /**
- * Class to provide information about a task which can be safely cached and do not change
- * during the lifecycle of the task.
- */
- public static class CachedTaskInfo {
-
- @Nullable
- private final RunningTaskInfo mTopTask;
- private final List<RunningTaskInfo> mAllCachedTasks;
-
- CachedTaskInfo(List<RunningTaskInfo> allCachedTasks) {
- mAllCachedTasks = allCachedTasks;
- mTopTask = allCachedTasks.isEmpty() ? null : allCachedTasks.get(0);
- }
-
- public int getTaskId() {
- return mTopTask == null ? INVALID_TASK_ID : mTopTask.taskId;
- }
-
- /**
- * Returns true if the root of the task chooser activity
- */
- public boolean isRootChooseActivity() {
- return mTopTask != null && ACTION_CHOOSER.equals(mTopTask.baseIntent.getAction());
- }
-
- /**
- * Returns true if the given task holds an Assistant activity that is excluded from recents
- */
- public boolean isExcludedAssistant() {
- return mTopTask != null && mTopTask.configuration.windowConfiguration
- .getActivityType() == ACTIVITY_TYPE_ASSISTANT
- && (mTopTask.baseIntent.getFlags() & FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) != 0;
- }
-
- /**
- * Returns true if this represents the HOME task
- */
- public boolean isHomeTask() {
- return mTopTask != null && mTopTask.configuration.windowConfiguration
- .getActivityType() == ACTIVITY_TYPE_HOME;
- }
-
- /**
- * Returns {@link Task} array which can be used as a placeholder until the true object
- * is loaded by the model
- */
- public Task[] getPlaceholderTasks() {
- return mTopTask == null ? new Task[0]
- : new Task[] {Task.from(new TaskKey(mTopTask), mTopTask, false)};
- }
-
- /**
- * Returns {@link Task} array corresponding to the provided task ids which can be used as a
- * placeholder until the true object is loaded by the model
- */
- public Task[] getPlaceholderTasks(int[] taskIds) {
- if (mTopTask == null) {
- return new Task[0];
- }
- Task[] result = new Task[taskIds.length];
- for (int i = 0; i < taskIds.length; i++) {
- final int index = i;
- int taskId = taskIds[i];
- mAllCachedTasks.forEach(rti -> {
- if (rti.taskId == taskId) {
- result[index] = Task.from(new TaskKey(rti), rti, false);
- }
- });
- }
- return result;
- }
- }
-}
diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java
index 16f141b17b..db5c93c503 100644
--- a/quickstep/src/com/android/quickstep/TouchInteractionService.java
+++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java
@@ -15,6 +15,7 @@
*/
package com.android.quickstep;
+import static android.content.Intent.ACTION_CHOOSER;
import static android.view.MotionEvent.ACTION_CANCEL;
import static android.view.MotionEvent.ACTION_DOWN;
import static android.view.MotionEvent.ACTION_UP;
@@ -24,43 +25,49 @@ import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TI
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import static com.android.quickstep.GestureState.DEFAULT_STATE;
import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_RECENTS;
-import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_RECENT_TASKS;
-import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_SHELL_BACK_ANIMATION;
import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_SHELL_ONE_HANDED;
import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_SHELL_PIP;
import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_SHELL_SHELL_TRANSITIONS;
import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_SHELL_SPLIT_SCREEN;
import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_SHELL_STARTING_WINDOW;
+import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_SMARTSPACE_TRANSITION_CONTROLLER;
import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_SYSUI_PROXY;
-import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_UNLOCK_ANIMATION_CONTROLLER;
-import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_TRACING_ENABLED;
import android.annotation.TargetApi;
+import android.app.ActivityManager;
import android.app.PendingIntent;
import android.app.RemoteAction;
import android.app.Service;
+import android.content.ComponentName;
+import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Configuration;
+import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.Region;
import android.graphics.drawable.Icon;
+import android.hardware.display.DisplayManager;
import android.os.Build;
import android.os.Bundle;
import android.os.IBinder;
import android.os.Looper;
import android.os.SystemClock;
+import android.os.SystemProperties;
import android.util.Log;
import android.view.Choreographer;
+import android.view.Display;
import android.view.InputEvent;
import android.view.MotionEvent;
+import android.view.Surface;
import android.view.accessibility.AccessibilityManager;
import androidx.annotation.BinderThread;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.UiThread;
+import androidx.annotation.WorkerThread;
import com.android.launcher3.BaseDraggingActivity;
import com.android.launcher3.R;
@@ -69,14 +76,12 @@ import com.android.launcher3.Utilities;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.provider.RestoreDbTask;
import com.android.launcher3.statemanager.StatefulActivity;
-import com.android.launcher3.taskbar.TaskbarActivityContext;
import com.android.launcher3.taskbar.TaskbarManager;
import com.android.launcher3.testing.TestLogging;
import com.android.launcher3.testing.TestProtocol;
import com.android.launcher3.tracing.LauncherTraceProto;
import com.android.launcher3.tracing.TouchInteractionServiceProto;
import com.android.launcher3.uioverrides.plugins.PluginManagerWrapper;
-import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.OnboardingPrefs;
import com.android.launcher3.util.TraceHelper;
import com.android.launcher3.util.WindowBounds;
@@ -85,29 +90,29 @@ import com.android.quickstep.inputconsumers.AssistantInputConsumer;
import com.android.quickstep.inputconsumers.DeviceLockedInputConsumer;
import com.android.quickstep.inputconsumers.OneHandedModeInputConsumer;
import com.android.quickstep.inputconsumers.OtherActivityInputConsumer;
+import com.android.quickstep.inputconsumers.OverscrollInputConsumer;
import com.android.quickstep.inputconsumers.OverviewInputConsumer;
import com.android.quickstep.inputconsumers.OverviewWithoutFocusInputConsumer;
-import com.android.quickstep.inputconsumers.ProgressDelegateInputConsumer;
import com.android.quickstep.inputconsumers.ResetGestureInputConsumer;
import com.android.quickstep.inputconsumers.ScreenPinnedInputConsumer;
import com.android.quickstep.inputconsumers.SysUiOverlayInputConsumer;
-import com.android.quickstep.inputconsumers.TaskbarStashInputConsumer;
import com.android.quickstep.util.ActiveGestureLog;
+import com.android.quickstep.util.AssistantUtilities;
import com.android.quickstep.util.ProtoTracer;
-import com.android.quickstep.util.ProxyScreenStatusProvider;
import com.android.quickstep.util.SplitScreenBounds;
+import com.android.systemui.plugins.OverscrollPlugin;
+import com.android.systemui.plugins.PluginListener;
import com.android.systemui.shared.recents.IOverviewProxy;
import com.android.systemui.shared.recents.ISystemUiProxy;
import com.android.systemui.shared.system.ActivityManagerWrapper;
+import com.android.systemui.shared.system.InputChannelCompat;
import com.android.systemui.shared.system.InputChannelCompat.InputEventReceiver;
import com.android.systemui.shared.system.InputConsumerController;
import com.android.systemui.shared.system.InputMonitorCompat;
-import com.android.systemui.shared.system.smartspace.ISysuiUnlockAnimationController;
+import com.android.systemui.shared.system.smartspace.ISmartspaceTransitionController;
import com.android.systemui.shared.tracing.ProtoTraceable;
-import com.android.wm.shell.back.IBackAnimation;
import com.android.wm.shell.onehanded.IOneHanded;
import com.android.wm.shell.pip.IPip;
-import com.android.wm.shell.recents.IRecentTasks;
import com.android.wm.shell.splitscreen.ISplitScreen;
import com.android.wm.shell.startingsurface.IStartingWindow;
import com.android.wm.shell.transition.IShellTransitions;
@@ -116,14 +121,13 @@ import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.LinkedList;
-import java.util.function.Function;
/**
* Service connected by system-UI for handling touch interaction.
*/
@TargetApi(Build.VERSION_CODES.R)
-public class TouchInteractionService extends Service
- implements ProtoTraceable<LauncherTraceProto.Builder> {
+public class TouchInteractionService extends Service implements PluginListener<OverscrollPlugin>,
+ ProtoTraceable<LauncherTraceProto.Builder> {
private static final String TAG = "TouchInteractionService";
@@ -138,9 +142,12 @@ public class TouchInteractionService extends Service
*/
private static final int SYSTEM_ACTION_ID_ALL_APPS = 14;
- private int mBackGestureNotificationCounter = -1;
+ public static final boolean ENABLE_PER_WINDOW_INPUT_ROTATION =
+ SystemProperties.getBoolean("persist.debug.per_window_input_rotation", false);
- private final TISBinder mTISBinder = new TISBinder();
+ private int mBackGestureNotificationCounter = -1;
+ @Nullable
+ private OverscrollPlugin mOverscrollPlugin;
/**
* Local IOverviewProxy implementation with some methods for local components
@@ -160,19 +167,21 @@ public class TouchInteractionService extends Service
bundle.getBinder(KEY_EXTRA_SHELL_SHELL_TRANSITIONS));
IStartingWindow startingWindow = IStartingWindow.Stub.asInterface(
bundle.getBinder(KEY_EXTRA_SHELL_STARTING_WINDOW));
- ISysuiUnlockAnimationController launcherUnlockAnimationController =
- ISysuiUnlockAnimationController.Stub.asInterface(
- bundle.getBinder(KEY_EXTRA_UNLOCK_ANIMATION_CONTROLLER));
- IRecentTasks recentTasks = IRecentTasks.Stub.asInterface(
- bundle.getBinder(KEY_EXTRA_RECENT_TASKS));
- IBackAnimation backAnimation = IBackAnimation.Stub.asInterface(
- bundle.getBinder(KEY_EXTRA_SHELL_BACK_ANIMATION));
+ ISmartspaceTransitionController smartspaceTransitionController =
+ ISmartspaceTransitionController.Stub.asInterface(
+ bundle.getBinder(KEY_EXTRA_SMARTSPACE_TRANSITION_CONTROLLER));
MAIN_EXECUTOR.execute(() -> {
SystemUiProxy.INSTANCE.get(TouchInteractionService.this).setProxy(proxy, pip,
- splitscreen, onehanded, shellTransitions, startingWindow, recentTasks,
- launcherUnlockAnimationController, backAnimation);
- TouchInteractionService.this.initInputMonitor("TISBinder#onInitialize()");
+ splitscreen, onehanded, shellTransitions, startingWindow,
+ smartspaceTransitionController);
+ TouchInteractionService.this.initInputMonitor();
preloadOverview(true /* fromInit */);
+ mDeviceState.runOnUserUnlocked(() -> {
+ final BaseActivityInterface ai =
+ mOverviewComponentObserver.getActivityInterface();
+ if (ai == null) return;
+ ai.onOverviewServiceBound();
+ });
});
sIsInitialized = true;
}
@@ -253,57 +262,16 @@ public class TouchInteractionService extends Service
}
@Override
- public void onSplitScreenSecondaryBoundsChanged(Rect bounds, Rect insets) {
+ public void onSplitScreenSecondaryBoundsChanged(Rect bounds, Rect insets) {
WindowBounds wb = new WindowBounds(bounds, insets);
MAIN_EXECUTOR.execute(() -> SplitScreenBounds.INSTANCE.setSecondaryWindowBounds(wb));
}
- @BinderThread
- @Override
- public void onScreenTurnedOn() {
- MAIN_EXECUTOR.execute(ProxyScreenStatusProvider.INSTANCE::onScreenTurnedOn);
- }
-
- /**
- * Preloads the Overview activity.
- *
- * This method should only be used when the All Set page of the SUW is reached to safely
- * preload the Launcher for the SUW first reveal.
- */
- public void preloadOverviewForSUWAllSet() {
- preloadOverview(false, true);
- }
-
- @Override
- public void onRotationProposal(int rotation, boolean isValid) {
- executeForTaskbarManager(() -> mTaskbarManager.onRotationProposal(rotation, isValid));
- }
-
- @Override
- public void disable(int displayId, int state1, int state2, boolean animate) {
- executeForTaskbarManager(() -> mTaskbarManager
- .disableNavBarElements(displayId, state1, state2, animate));
- }
-
@Override
- public void onSystemBarAttributesChanged(int displayId, int behavior) {
- executeForTaskbarManager(() -> mTaskbarManager
- .onSystemBarAttributesChanged(displayId, behavior));
- }
-
- @Override
- public void onNavButtonsDarkIntensityChanged(float darkIntensity) {
- executeForTaskbarManager(() -> mTaskbarManager
- .onNavButtonsDarkIntensityChanged(darkIntensity));
- }
-
- private void executeForTaskbarManager(final Runnable r) {
- MAIN_EXECUTOR.execute(() -> {
- if (mTaskbarManager == null) {
- return;
- }
- r.run();
- });
+ public void onImeWindowStatusChanged(int displayId, IBinder token, int vis,
+ int backDisposition, boolean showImeSwitcher) {
+ MAIN_EXECUTOR.execute(() -> mTaskbarManager.updateImeStatus(
+ displayId, vis, backDisposition, showImeSwitcher));
}
public TaskbarManager getTaskbarManager() {
@@ -313,20 +281,6 @@ public class TouchInteractionService extends Service
public OverviewCommandHelper getOverviewCommandHelper() {
return mOverviewCommandHelper;
}
-
- /**
- * Sets a proxy to bypass swipe up behavior
- */
- public void setSwipeUpProxy(Function<GestureState, AnimatedFloat> proxy) {
- mSwipeUpProxyProvider = proxy != null ? proxy : (i -> null);
- }
-
- /**
- * Sets the task id where gestures should be blocked
- */
- public void setGestureBlockedTaskId(int taskId) {
- mDeviceState.setGestureBlockingTaskId(taskId);
- }
}
private static boolean sConnected = false;
@@ -337,6 +291,7 @@ public class TouchInteractionService extends Service
return sConnected;
}
+
public static boolean isInitialized() {
return sIsInitialized;
}
@@ -362,8 +317,9 @@ public class TouchInteractionService extends Service
private InputMonitorCompat mInputMonitorCompat;
private InputEventReceiver mInputEventReceiver;
+ private DisplayManager mDisplayManager;
+
private TaskbarManager mTaskbarManager;
- private Function<GestureState, AnimatedFloat> mSwipeUpProxyProvider = i -> null;
@Override
public void onCreate() {
@@ -373,20 +329,19 @@ public class TouchInteractionService extends Service
mMainChoreographer = Choreographer.getInstance();
mAM = ActivityManagerWrapper.getInstance();
mDeviceState = new RecentsAnimationDeviceState(this, true);
+ mDisplayManager = getSystemService(DisplayManager.class);
mTaskbarManager = new TaskbarManager(this);
- mRotationTouchHelper = mDeviceState.getRotationTouchHelper();
- // Call runOnUserUnlocked() before any other callbacks to ensure everything is initialized.
+ mRotationTouchHelper = mDeviceState.getRotationTouchHelper();
+ mDeviceState.addNavigationModeChangedCallback(this::onNavigationModeChanged);
+ mDeviceState.addOneHandedModeChangedCallback(this::onOneHandedModeOverlayChanged);
mDeviceState.runOnUserUnlocked(this::onUserUnlocked);
mDeviceState.runOnUserUnlocked(mTaskbarManager::onUserUnlocked);
- mDeviceState.addNavigationModeChangedCallback(this::onNavigationModeChanged);
-
ProtoTracer.INSTANCE.get(this).add(this);
sConnected = true;
}
- private void disposeEventHandlers(String reason) {
- Log.d(TAG, "disposeEventHandlers: Reason: " + reason);
+ private void disposeEventHandlers() {
if (mInputEventReceiver != null) {
mInputEventReceiver.dispose();
mInputEventReceiver = null;
@@ -397,8 +352,8 @@ public class TouchInteractionService extends Service
}
}
- private void initInputMonitor(String reason) {
- disposeEventHandlers("Initializing input monitor due to: " + reason);
+ private void initInputMonitor() {
+ disposeEventHandlers();
if (mDeviceState.isButtonNavMode()) {
return;
@@ -414,11 +369,18 @@ public class TouchInteractionService extends Service
/**
* Called when the navigation mode changes, guaranteed to be after the device state has updated.
*/
- private void onNavigationModeChanged() {
- initInputMonitor("onNavigationModeChanged()");
+ private void onNavigationModeChanged(SysUINavigationMode.Mode mode) {
+ initInputMonitor();
resetHomeBounceSeenOnQuickstepEnabledFirstTime();
}
+ /**
+ * Called when the one handed mode overlay package changes, to recreate touch region.
+ */
+ private void onOneHandedModeOverlayChanged(int newGesturalHeight) {
+ initInputMonitor();
+ }
+
@UiThread
public void onUserUnlocked() {
mTaskAnimationManager = new TaskAnimationManager(this);
@@ -431,15 +393,15 @@ public class TouchInteractionService extends Service
onSystemUiFlagsChanged(mDeviceState.getSystemUiStateFlags());
onAssistantVisibilityChanged();
- // Initialize the task tracker
- TopTaskTracker.INSTANCE.get(this);
-
// Temporarily disable model preload
// new ModelPreload().start(this);
mBackGestureNotificationCounter = Math.max(0, Utilities.getDevicePrefs(this)
.getInt(KEY_BACK_NOTIFICATION_COUNT, MAX_BACK_NOTIFICATION_COUNT));
resetHomeBounceSeenOnQuickstepEnabledFirstTime();
+ PluginManagerWrapper.INSTANCE.get(getBaseContext()).addPluginListener(this,
+ OverscrollPlugin.class, false /* allowMultiple */);
+
mOverviewComponentObserver.setOverviewChangeListener(this::onOverviewTargetChange);
onOverviewTargetChange(mOverviewComponentObserver.isHomeAndOverviewSame());
}
@@ -481,12 +443,6 @@ public class TouchInteractionService extends Service
} else {
am.unregisterSystemAction(SYSTEM_ACTION_ID_ALL_APPS);
}
-
- StatefulActivity newOverviewActivity = mOverviewComponentObserver.getActivityInterface()
- .getCreatedActivity();
- if (newOverviewActivity != null) {
- mTaskbarManager.setActivity(newOverviewActivity);
- }
}
@UiThread
@@ -497,15 +453,6 @@ public class TouchInteractionService extends Service
mOverviewComponentObserver.onSystemUiStateChanged();
mTaskbarManager.onSystemUiFlagsChanged(systemUiStateFlags);
- boolean wasExpanded = (lastSysUIFlags & SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED) != 0;
- boolean isExpanded =
- (systemUiStateFlags & SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED) != 0;
- if (wasExpanded != isExpanded && isExpanded) {
- // End live tile when expanding the notification panel for the first time from
- // overview.
- mTaskAnimationManager.endLiveTile();
- }
-
if ((lastSysUIFlags & SYSUI_STATE_TRACING_ENABLED) !=
(systemUiStateFlags & SYSUI_STATE_TRACING_ENABLED)) {
// Update the tracing state
@@ -536,8 +483,9 @@ public class TouchInteractionService extends Service
if (mDeviceState.isUserUnlocked()) {
mInputConsumer.unregisterInputConsumer();
mOverviewComponentObserver.onDestroy();
+ PluginManagerWrapper.INSTANCE.get(getBaseContext()).removePluginListener(this);
}
- disposeEventHandlers("TouchInteractionService onDestroy()");
+ disposeEventHandlers();
mDeviceState.destroy();
SystemUiProxy.INSTANCE.get(this).clearProxy();
ProtoTracer.INSTANCE.get(this).stop();
@@ -554,7 +502,7 @@ public class TouchInteractionService extends Service
@Override
public IBinder onBind(Intent intent) {
Log.d(TAG, "Touch service connected: user=" + getUserId());
- return mTISBinder;
+ return new TISBinder();
}
private void onInputEvent(InputEvent ev) {
@@ -563,6 +511,15 @@ public class TouchInteractionService extends Service
return;
}
MotionEvent event = (MotionEvent) ev;
+ if (ENABLE_PER_WINDOW_INPUT_ROTATION) {
+ final Display display = mDisplayManager.getDisplay(mDeviceState.getDisplayId());
+ int rotation = display.getRotation();
+ Point sz = new Point();
+ display.getRealSize(sz);
+ if (rotation != Surface.ROTATION_0) {
+ event.transform(InputChannelCompat.createRotationMatrix(rotation, sz.x, sz.y));
+ }
+ }
TestLogging.recordMotionEvent(
TestProtocol.SEQUENCE_TIS, "TouchInteractionService.onInputEvent", event);
@@ -591,14 +548,26 @@ public class TouchInteractionService extends Service
ActiveGestureLog.INSTANCE.addLog("setInputConsumer: " + mConsumer.getName());
mUncheckedConsumer = mConsumer;
- } else if (mDeviceState.isUserUnlocked() && mDeviceState.isFullyGesturalNavMode()
- && mDeviceState.canTriggerAssistantAction(event)) {
+ } else if (mDeviceState.isUserUnlocked() && mDeviceState.isFullyGesturalNavMode()) {
mGestureState = createGestureState(mGestureState);
- // Do not change mConsumer as if there is an ongoing QuickSwitch gesture, we
- // should not interrupt it. QuickSwitch assumes that interruption can only
- // happen if the next gesture is also quick switch.
- mUncheckedConsumer = tryCreateAssistantInputConsumer(
- InputConsumer.NO_OP, mGestureState, event);
+ ActivityManager.RunningTaskInfo runningTask = mGestureState.getRunningTask();
+ if (mDeviceState.canTriggerAssistantAction(event, runningTask)) {
+ // Do not change mConsumer as if there is an ongoing QuickSwitch gesture, we
+ // should not interrupt it. QuickSwitch assumes that interruption can only
+ // happen if the next gesture is also quick switch.
+ mUncheckedConsumer = new AssistantInputConsumer(
+ this,
+ mGestureState,
+ InputConsumer.NO_OP, mInputMonitorCompat,
+ mDeviceState,
+ event);
+ } else if (mDeviceState.canTriggerOneHandedAction(event)) {
+ // Consume gesture event for triggering one handed feature.
+ mUncheckedConsumer = new OneHandedModeInputConsumer(this, mDeviceState,
+ InputConsumer.NO_OP, mInputMonitorCompat);
+ } else {
+ mUncheckedConsumer = InputConsumer.NO_OP;
+ }
} else if (mDeviceState.canTriggerOneHandedAction(event)) {
// Consume gesture event for triggering one handed feature.
mUncheckedConsumer = new OneHandedModeInputConsumer(this, mDeviceState,
@@ -645,14 +614,6 @@ public class TouchInteractionService extends Service
ProtoTracer.INSTANCE.get(this).scheduleFrameUpdate();
}
- private InputConsumer tryCreateAssistantInputConsumer(InputConsumer base,
- GestureState gestureState, MotionEvent motionEvent) {
- return mDeviceState.isGestureBlockedTask(gestureState.getRunningTask())
- ? base
- : new AssistantInputConsumer(this, gestureState, base, mInputMonitorCompat,
- mDeviceState, motionEvent);
- }
-
public GestureState createGestureState(GestureState previousGestureState) {
GestureState gestureState = new GestureState(mOverviewComponentObserver,
ActiveGestureLog.INSTANCE.generateAndSetLogId());
@@ -662,20 +623,14 @@ public class TouchInteractionService extends Service
gestureState.updatePreviouslyAppearedTaskIds(
previousGestureState.getPreviouslyAppearedTaskIds());
} else {
- gestureState.updateRunningTask(
- TopTaskTracker.INSTANCE.get(this).getCachedTopTask(false));
+ gestureState.updateRunningTask(TraceHelper.allowIpcs("getRunningTask.0",
+ () -> mAM.getRunningTask(false /* filterOnlyVisibleRecents */)));
}
return gestureState;
}
private InputConsumer newConsumer(GestureState previousGestureState,
GestureState newGestureState, MotionEvent event) {
- AnimatedFloat progressProxy = mSwipeUpProxyProvider.apply(mGestureState);
- if (progressProxy != null) {
- return new ProgressDelegateInputConsumer(this, mTaskAnimationManager,
- mGestureState, mInputMonitorCompat, progressProxy);
- }
-
boolean canStartSystemGesture = mDeviceState.canStartSystemGesture();
if (!mDeviceState.isUserUnlocked()) {
@@ -698,22 +653,34 @@ public class TouchInteractionService extends Service
handleOrientationSetup(base);
}
if (mDeviceState.isFullyGesturalNavMode()) {
- if (mDeviceState.canTriggerAssistantAction(event)) {
- base = tryCreateAssistantInputConsumer(base, newGestureState, event);
+ if (mDeviceState.canTriggerAssistantAction(event, newGestureState.getRunningTask())) {
+ base = new AssistantInputConsumer(this, newGestureState, base, mInputMonitorCompat,
+ mDeviceState, event);
}
- // If Taskbar is present, we listen for long press to unstash it.
- TaskbarActivityContext tac = mTaskbarManager.getCurrentActivityContext();
- if (tac != null) {
- base = new TaskbarStashInputConsumer(this, base, mInputMonitorCompat, tac);
+ if (FeatureFlags.ENABLE_QUICK_CAPTURE_GESTURE.get()) {
+ OverscrollPlugin plugin = null;
+ if (FeatureFlags.FORCE_LOCAL_OVERSCROLL_PLUGIN.get()) {
+ plugin = OverscrollPluginFactory.INSTANCE.get(
+ getApplicationContext()).getLocalOverscrollPlugin();
+ }
+
+ // If not local plugin was forced, use the actual overscroll plugin if available.
+ if (plugin == null && mOverscrollPlugin != null && mOverscrollPlugin.isActive()) {
+ plugin = mOverscrollPlugin;
+ }
+
+ if (plugin != null) {
+ // Put the overscroll gesture as higher priority than the Assistant or base
+ // gestures
+ base = new OverscrollInputConsumer(this, newGestureState, base,
+ mInputMonitorCompat, plugin);
+ }
}
// If Bubbles is expanded, use the overlay input consumer, which will close Bubbles
// instead of going all the way home when a swipe up is detected.
- // Notification panel can be expanded on top of expanded bubbles. Bubbles remain
- // expanded in the back. Make sure swipe up is not passed to bubbles in this case.
- if ((mDeviceState.isBubblesExpanded() && !mDeviceState.isNotificationPanelExpanded())
- || mDeviceState.isSystemUiDialogShowing()) {
+ if (mDeviceState.isBubblesExpanded() || mDeviceState.isGlobalActionsShowing()) {
base = new SysUiOverlayInputConsumer(
getBaseContext(), mDeviceState, mInputMonitorCompat);
}
@@ -760,14 +727,17 @@ public class TouchInteractionService extends Service
// Use overview input consumer for sharesheets on top of home.
boolean forceOverviewInputConsumer = gestureState.getActivityInterface().isStarted()
&& gestureState.getRunningTask() != null
- && gestureState.getRunningTask().isRootChooseActivity();
- if (gestureState.getRunningTask() != null
- && gestureState.getRunningTask().isExcludedAssistant()) {
+ && ACTION_CHOOSER.equals(gestureState.getRunningTask().baseIntent.getAction());
+ if (AssistantUtilities.isExcludedAssistant(gestureState.getRunningTask())) {
// In the case where we are in the excluded assistant state, ignore it and treat the
// running activity as the task behind the assistant
- gestureState.updateRunningTask(TopTaskTracker.INSTANCE.get(this)
- .getCachedTopTask(true /* filterOnlyVisibleRecents */));
- forceOverviewInputConsumer = gestureState.getRunningTask().isHomeTask();
+ gestureState.updateRunningTask(TraceHelper.allowIpcs("getRunningTask.assistant",
+ () -> mAM.getRunningTask(true /* filterOnlyVisibleRecents */)));
+ ComponentName homeComponent = mOverviewComponentObserver.getHomeIntent().getComponent();
+ ComponentName runningComponent =
+ gestureState.getRunningTask().baseIntent.getComponent();
+ forceOverviewInputConsumer =
+ runningComponent != null && runningComponent.equals(homeComponent);
}
if (ENABLE_QUICKSTEP_LIVE_TILE.get()
@@ -777,14 +747,11 @@ public class TouchInteractionService extends Service
} else if (gestureState.getRunningTask() == null) {
return getDefaultInputConsumer();
} else if (previousGestureState.isRunningAnimationToLauncher()
- || (gestureState.getActivityInterface().isResumed()
- // with shell-transitions, home is resumed during recents animation, so
- // explicitly check against recents animation too.
- && !previousGestureState.isRecentsAnimationRunning())
+ || gestureState.getActivityInterface().isResumed()
|| forceOverviewInputConsumer) {
return createOverviewInputConsumer(
previousGestureState, gestureState, event, forceOverviewInputConsumer);
- } else if (mDeviceState.isGestureBlockedTask(gestureState.getRunningTask())) {
+ } else if (mDeviceState.isGestureBlockedActivity(gestureState.getRunningTask())) {
return getDefaultInputConsumer();
} else {
return createOtherActivityInputConsumer(gestureState, event);
@@ -875,10 +842,6 @@ public class TouchInteractionService extends Service
}
private void preloadOverview(boolean fromInit) {
- preloadOverview(fromInit, false);
- }
-
- private void preloadOverview(boolean fromInit, boolean forSUWAllSet) {
if (!mDeviceState.isUserUnlocked()) {
return;
}
@@ -888,8 +851,7 @@ public class TouchInteractionService extends Service
return;
}
- if ((RestoreDbTask.isPending(this) && !forSUWAllSet)
- || !mDeviceState.isUserSetupComplete()) {
+ if (RestoreDbTask.isPending(this) || !mDeviceState.isUserSetupComplete()) {
// Preloading while a restore is pending may cause launcher to start the restore
// too early.
return;
@@ -959,16 +921,13 @@ public class TouchInteractionService extends Service
if (mOverviewComponentObserver != null) {
mOverviewComponentObserver.dump(pw);
}
- if (mOverviewCommandHelper != null) {
- mOverviewCommandHelper.dump(pw);
- }
if (mGestureState != null) {
mGestureState.dump(pw);
}
pw.println("Input state:");
pw.println(" mInputMonitorCompat=" + mInputMonitorCompat);
pw.println(" mInputEventReceiver=" + mInputEventReceiver);
- DisplayController.INSTANCE.get(this).dump(pw);
+ SysUINavigationMode.INSTANCE.get(this).dump(pw);
pw.println("TouchState:");
BaseDraggingActivity createdOverviewActivity = mOverviewComponentObserver == null ? null
: mOverviewComponentObserver.getActivityInterface().getCreatedActivity();
@@ -978,13 +937,8 @@ public class TouchInteractionService extends Service
pw.println(" resumed=" + resumed);
pw.println(" mConsumer=" + mConsumer.getName());
ActiveGestureLog.INSTANCE.dump("", pw);
- RecentsModel.INSTANCE.get(this).dump("", pw);
pw.println("ProtoTrace:");
pw.println(" file=" + ProtoTracer.INSTANCE.get(this).getTraceFile());
- if (createdOverviewActivity != null) {
- createdOverviewActivity.getDeviceProfile().dump("", pw);
- }
- mTaskbarManager.dumpLogs("", pw);
}
}
@@ -1015,6 +969,32 @@ public class TouchInteractionService extends Service
mInputConsumer);
}
+ protected boolean shouldNotifyBackGesture() {
+ return mBackGestureNotificationCounter > 0 &&
+ !mDeviceState.getGestureBlockedActivityPackages().isEmpty();
+ }
+
+ @WorkerThread
+ protected void tryNotifyBackGesture() {
+ if (shouldNotifyBackGesture()) {
+ mBackGestureNotificationCounter--;
+ Utilities.getDevicePrefs(this).edit()
+ .putInt(KEY_BACK_NOTIFICATION_COUNT, mBackGestureNotificationCounter).apply();
+ mDeviceState.getGestureBlockedActivityPackages().forEach(blockedPackage ->
+ sendBroadcast(new Intent(NOTIFY_ACTION_BACK).setPackage(blockedPackage)));
+ }
+ }
+
+ @Override
+ public void onPluginConnected(OverscrollPlugin overscrollPlugin, Context context) {
+ mOverscrollPlugin = overscrollPlugin;
+ }
+
+ @Override
+ public void onPluginDisconnected(OverscrollPlugin overscrollPlugin) {
+ mOverscrollPlugin = null;
+ }
+
@Override
public void writeToProto(LauncherTraceProto.Builder proto) {
TouchInteractionServiceProto.Builder serviceProto =
diff --git a/quickstep/src/com/android/quickstep/ViewUtils.java b/quickstep/src/com/android/quickstep/ViewUtils.java
index 1fef544e3e..184ab17ae2 100644
--- a/quickstep/src/com/android/quickstep/ViewUtils.java
+++ b/quickstep/src/com/android/quickstep/ViewUtils.java
@@ -15,14 +15,14 @@
*/
package com.android.quickstep;
-import android.graphics.HardwareRenderer;
import android.os.Handler;
import android.view.View;
-import android.view.ViewRootImpl;
import com.android.launcher3.Utilities;
+import com.android.systemui.shared.system.ViewRootImplCompat;
import java.util.function.BooleanSupplier;
+import java.util.function.LongConsumer;
/**
* Utility class for helpful methods related to {@link View} objects.
@@ -45,9 +45,9 @@ public class ViewUtils {
return new FrameHandler(view, onFinishRunnable, canceled).schedule();
}
- private static class FrameHandler implements HardwareRenderer.FrameDrawingCallback {
+ private static class FrameHandler implements LongConsumer {
- final ViewRootImpl mViewRoot;
+ final ViewRootImplCompat mViewRoot;
final Runnable mFinishCallback;
final BooleanSupplier mCancelled;
final Handler mHandler;
@@ -55,14 +55,14 @@ public class ViewUtils {
int mDeferFrameCount = 1;
FrameHandler(View view, Runnable finishCallback, BooleanSupplier cancelled) {
- mViewRoot = view.getViewRootImpl();
+ mViewRoot = new ViewRootImplCompat(view);
mFinishCallback = finishCallback;
mCancelled = cancelled;
mHandler = new Handler();
}
@Override
- public void onFrameDraw(long frame) {
+ public void accept(long l) {
Utilities.postAsyncCallback(mHandler, this::onFrame);
}
@@ -83,7 +83,7 @@ public class ViewUtils {
}
private boolean schedule() {
- if (mViewRoot != null && mViewRoot.getView() != null) {
+ if (mViewRoot.isValid()) {
mViewRoot.registerRtFrameCallback(this);
mViewRoot.getView().invalidate();
return true;
diff --git a/quickstep/src/com/android/quickstep/fallback/FallbackNavBarTouchController.java b/quickstep/src/com/android/quickstep/fallback/FallbackNavBarTouchController.java
index 3e01ed0b77..9d9ef94169 100644
--- a/quickstep/src/com/android/quickstep/fallback/FallbackNavBarTouchController.java
+++ b/quickstep/src/com/android/quickstep/fallback/FallbackNavBarTouchController.java
@@ -22,9 +22,9 @@ import androidx.annotation.Nullable;
import com.android.launcher3.Utilities;
import com.android.launcher3.util.DisplayController;
-import com.android.launcher3.util.DisplayController.NavigationMode;
import com.android.launcher3.util.TouchController;
import com.android.quickstep.RecentsActivity;
+import com.android.quickstep.SysUINavigationMode;
import com.android.quickstep.util.NavBarPosition;
import com.android.quickstep.util.TriggerSwipeUpTouchTracker;
@@ -40,8 +40,8 @@ public class FallbackNavBarTouchController implements TouchController,
public FallbackNavBarTouchController(RecentsActivity activity) {
mActivity = activity;
- NavigationMode sysUINavigationMode = DisplayController.getNavigationMode(mActivity);
- if (sysUINavigationMode == NavigationMode.NO_BUTTON) {
+ SysUINavigationMode.Mode sysUINavigationMode = SysUINavigationMode.getMode(mActivity);
+ if (sysUINavigationMode == SysUINavigationMode.Mode.NO_BUTTON) {
NavBarPosition navBarPosition = new NavBarPosition(sysUINavigationMode,
DisplayController.INSTANCE.get(mActivity).getInfo());
mTriggerSwipeUpTracker = new TriggerSwipeUpTouchTracker(mActivity,
diff --git a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsStateController.java b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsStateController.java
index f68bbbce62..f0364eb410 100644
--- a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsStateController.java
+++ b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsStateController.java
@@ -15,8 +15,6 @@
*/
package com.android.quickstep.fallback;
-import static com.android.launcher3.anim.Interpolators.FINAL_FRAME;
-import static com.android.launcher3.anim.Interpolators.INSTANT;
import static com.android.launcher3.anim.Interpolators.LINEAR;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_MODAL;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_SCALE;
@@ -24,22 +22,14 @@ import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_TR
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_TRANSLATE_Y;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_SCRIM_FADE;
import static com.android.launcher3.states.StateAnimationConfig.SKIP_OVERVIEW;
-import static com.android.quickstep.fallback.RecentsState.OVERVIEW_SPLIT_SELECT;
import static com.android.quickstep.views.RecentsView.ADJACENT_PAGE_HORIZONTAL_OFFSET;
import static com.android.quickstep.views.RecentsView.FULLSCREEN_PROGRESS;
import static com.android.quickstep.views.RecentsView.RECENTS_GRID_PROGRESS;
import static com.android.quickstep.views.RecentsView.RECENTS_SCALE_PROPERTY;
import static com.android.quickstep.views.RecentsView.TASK_MODALNESS;
-import static com.android.quickstep.views.RecentsView.TASK_PRIMARY_SPLIT_TRANSLATION;
-import static com.android.quickstep.views.RecentsView.TASK_SECONDARY_SPLIT_TRANSLATION;
import static com.android.quickstep.views.RecentsView.TASK_SECONDARY_TRANSLATION;
import static com.android.quickstep.views.TaskView.FLAG_UPDATE_ALL;
-import android.util.FloatProperty;
-import android.util.Pair;
-
-import androidx.annotation.NonNull;
-
import com.android.launcher3.anim.PendingAnimation;
import com.android.launcher3.anim.PropertySetter;
import com.android.launcher3.statemanager.StateManager.StateHandler;
@@ -87,7 +77,9 @@ public class FallbackRecentsStateController implements StateHandler<RecentsState
float clearAllButtonAlpha = state.hasClearAllButton() ? 1 : 0;
setter.setFloat(mRecentsView.getClearAllButton(), ClearAllButton.VISIBILITY_ALPHA,
clearAllButtonAlpha, LINEAR);
- float overviewButtonAlpha = state.hasOverviewActions() ? 1 : 0;
+ float overviewButtonAlpha =
+ state.hasOverviewActions() && mRecentsView.shouldShowOverviewActionsForState(state)
+ ? 1 : 0;
setter.setFloat(mActivity.getActionsView().getVisibilityAlpha(),
MultiValueAlpha.VALUE, overviewButtonAlpha, LINEAR);
@@ -102,38 +94,10 @@ public class FallbackRecentsStateController implements StateHandler<RecentsState
setter.setFloat(mRecentsView, TASK_MODALNESS, state.getOverviewModalness(),
config.getInterpolator(ANIM_OVERVIEW_MODAL, LINEAR));
setter.setFloat(mRecentsView, FULLSCREEN_PROGRESS, state.isFullScreen() ? 1 : 0, LINEAR);
- boolean showAsGrid = state.displayOverviewTasksAsGrid(mActivity.getDeviceProfile());
- setter.setFloat(mRecentsView, RECENTS_GRID_PROGRESS, showAsGrid ? 1f : 0f,
- showAsGrid ? INSTANT : FINAL_FRAME);
+ setter.setFloat(mRecentsView, RECENTS_GRID_PROGRESS,
+ state.displayOverviewTasksAsGrid(mActivity.getDeviceProfile()) ? 1f : 0f, LINEAR);
setter.setViewBackgroundColor(mActivity.getScrimView(), state.getScrimColor(mActivity),
config.getInterpolator(ANIM_SCRIM_FADE, LINEAR));
-
- RecentsState currentState = mActivity.getStateManager().getState();
- if (isSplitSelectionState(state) && !isSplitSelectionState(currentState)) {
- setter.add(mRecentsView.createSplitSelectInitAnimation(
- state.getTransitionDuration(mActivity, true /* isToState */)).buildAnim());
- }
-
- Pair<FloatProperty, FloatProperty> taskViewsFloat =
- mRecentsView.getPagedOrientationHandler().getSplitSelectTaskOffset(
- TASK_PRIMARY_SPLIT_TRANSLATION, TASK_SECONDARY_SPLIT_TRANSLATION,
- mActivity.getDeviceProfile());
- setter.setFloat(mRecentsView, taskViewsFloat.second, 0, LINEAR);
- if (isSplitSelectionState(state)) {
- mRecentsView.applySplitPrimaryScrollOffset();
- setter.setFloat(mRecentsView, taskViewsFloat.first,
- mRecentsView.getSplitSelectTranslation(), LINEAR);
- } else {
- mRecentsView.resetSplitPrimaryScrollOffset();
- setter.setFloat(mRecentsView, taskViewsFloat.first, 0, LINEAR);
- }
- }
-
- /**
- * @return true if {@param toState} is {@link RecentsState#OVERVIEW_SPLIT_SELECT}
- */
- private boolean isSplitSelectionState(@NonNull RecentsState toState) {
- return toState == OVERVIEW_SPLIT_SELECT;
}
}
diff --git a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java
index ab3201a27e..ac3fb2731d 100644
--- a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java
+++ b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java
@@ -15,40 +15,34 @@
*/
package com.android.quickstep.fallback;
-import static com.android.launcher3.testing.TestProtocol.BAD_STATE;
import static com.android.quickstep.GestureState.GestureEndTarget.RECENTS;
import static com.android.quickstep.fallback.RecentsState.DEFAULT;
import static com.android.quickstep.fallback.RecentsState.HOME;
import static com.android.quickstep.fallback.RecentsState.MODAL_TASK;
-import static com.android.quickstep.fallback.RecentsState.OVERVIEW_SPLIT_SELECT;
import android.animation.AnimatorSet;
import android.annotation.TargetApi;
+import android.app.ActivityManager.RunningTaskInfo;
import android.content.Context;
import android.os.Build;
import android.util.AttributeSet;
import android.util.Log;
-import android.view.MotionEvent;
import androidx.annotation.Nullable;
-import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.anim.PendingAnimation;
-import com.android.launcher3.popup.QuickstepSystemShortcut;
import com.android.launcher3.statemanager.StateManager.StateListener;
-import com.android.launcher3.util.SplitConfigurationOptions;
+import com.android.launcher3.testing.TestProtocol;
import com.android.quickstep.FallbackActivityInterface;
import com.android.quickstep.GestureState;
import com.android.quickstep.RecentsActivity;
-import com.android.quickstep.RotationTouchHelper;
-import com.android.quickstep.util.GroupTask;
-import com.android.quickstep.util.SplitSelectStateController;
-import com.android.quickstep.util.TaskViewSimulator;
import com.android.quickstep.views.OverviewActionsView;
import com.android.quickstep.views.RecentsView;
+import com.android.quickstep.views.SplitPlaceholderView;
import com.android.quickstep.views.TaskView;
import com.android.systemui.shared.recents.model.Task;
+import com.android.systemui.shared.recents.model.Task.TaskKey;
import java.util.ArrayList;
@@ -56,8 +50,7 @@ import java.util.ArrayList;
public class FallbackRecentsView extends RecentsView<RecentsActivity, RecentsState>
implements StateListener<RecentsState> {
- @Nullable
- private Task mHomeTask;
+ private RunningTaskInfo mHomeTaskInfo;
public FallbackRecentsView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
@@ -69,8 +62,8 @@ public class FallbackRecentsView extends RecentsView<RecentsActivity, RecentsSta
}
@Override
- public void init(OverviewActionsView actionsView, SplitSelectStateController splitController) {
- super.init(actionsView, splitController);
+ public void init(OverviewActionsView actionsView, SplitPlaceholderView splitPlaceholderView) {
+ super.init(actionsView, splitPlaceholderView);
setOverviewStateEnabled(true);
setOverlayEnabled(true);
}
@@ -78,7 +71,6 @@ public class FallbackRecentsView extends RecentsView<RecentsActivity, RecentsSta
@Override
public void startHome() {
mActivity.startHome();
- AbstractFloatingView.closeAllOpenViews(mActivity, mActivity.isStarted());
}
/**
@@ -86,12 +78,9 @@ public class FallbackRecentsView extends RecentsView<RecentsActivity, RecentsSta
* to the home task. This allows us to handle quick-switch similarly to a quick-switching
* from a foreground task.
*/
- public void onGestureAnimationStartOnHome(Task[] homeTask,
- RotationTouchHelper rotationTouchHelper) {
- // TODO(b/195607777) General fallback love, but this might be correct
- // Home task should be defined as the front-most task info I think?
- mHomeTask = homeTask.length > 0 ? homeTask[0] : null;
- onGestureAnimationStart(homeTask, rotationTouchHelper);
+ public void onGestureAnimationStartOnHome(RunningTaskInfo homeTaskInfo) {
+ mHomeTaskInfo = homeTaskInfo;
+ onGestureAnimationStart(homeTaskInfo);
}
/**
@@ -101,14 +90,12 @@ public class FallbackRecentsView extends RecentsView<RecentsActivity, RecentsSta
*/
@Override
public void onPrepareGestureEndAnimation(
- @Nullable AnimatorSet animatorSet, GestureState.GestureEndTarget endTarget,
- TaskViewSimulator[] taskViewSimulators) {
- super.onPrepareGestureEndAnimation(animatorSet, endTarget, taskViewSimulators);
- if (mHomeTask != null && endTarget == RECENTS && animatorSet != null) {
- TaskView tv = getTaskViewByTaskId(mHomeTask.key.id);
+ @Nullable AnimatorSet animatorSet, GestureState.GestureEndTarget endTarget) {
+ super.onPrepareGestureEndAnimation(animatorSet, endTarget);
+ if (mHomeTaskInfo != null && endTarget == RECENTS && animatorSet != null) {
+ TaskView tv = getTaskView(mHomeTaskInfo.taskId);
if (tv != null) {
- PendingAnimation pa = createTaskDismissAnimation(tv, true, false, 150,
- false /* dismissingForSplitSelection*/);
+ PendingAnimation pa = createTaskDismissAnimation(tv, true, false, 150);
pa.addEndListener(e -> setCurrentTask(-1));
AnimatorPlaybackController controller = pa.createPlaybackController();
controller.dispatchOnStart();
@@ -127,70 +114,53 @@ public class FallbackRecentsView extends RecentsView<RecentsActivity, RecentsSta
}
@Override
- public void setCurrentTask(int runningTaskViewId) {
- super.setCurrentTask(runningTaskViewId);
- int runningTaskId = getTaskIdsForRunningTaskView()[0];
- if (mHomeTask != null && mHomeTask.key.id != runningTaskId) {
- mHomeTask = null;
+ public void setCurrentTask(int runningTaskId) {
+ super.setCurrentTask(runningTaskId);
+ if (mHomeTaskInfo != null && mHomeTaskInfo.taskId != runningTaskId) {
+ mHomeTaskInfo = null;
setRunningTaskHidden(false);
}
}
- @Nullable
@Override
- protected TaskView getHomeTaskView() {
- return mHomeTask != null ? getTaskViewByTaskId(mHomeTask.key.id) : null;
- }
-
- @Override
- protected boolean shouldAddStubTaskView(Task[] runningTasks) {
- if (runningTasks.length > 1) {
- // can't be in split screen w/ home task
- return super.shouldAddStubTaskView(runningTasks);
- }
-
- Task runningTask = runningTasks[0];
- if (mHomeTask != null && runningTask != null
- && mHomeTask.key.id == runningTask.key.id
- && getTaskViewCount() == 0 && mLoadPlanEverApplied) {
+ protected boolean shouldAddStubTaskView(RunningTaskInfo runningTaskInfo) {
+ if (mHomeTaskInfo != null && runningTaskInfo != null &&
+ mHomeTaskInfo.taskId == runningTaskInfo.taskId
+ && getTaskViewCount() == 0) {
// Do not add a stub task if we are running over home with empty recents, so that we
// show the empty recents message instead of showing a stub task and later removing it.
- // Ignore empty task signal if applyLoadPlan has never run.
return false;
}
- return super.shouldAddStubTaskView(runningTasks);
+ return super.shouldAddStubTaskView(runningTaskInfo);
}
@Override
- protected void applyLoadPlan(ArrayList<GroupTask> taskGroups) {
+ protected void applyLoadPlan(ArrayList<Task> tasks) {
// When quick-switching on 3p-launcher, we add a "stub" tile corresponding to Launcher
// as well. This tile is never shown as we have setCurrentTaskHidden, but allows use to
// track the index of the next task appropriately, as if we are switching on any other app.
- // TODO(b/195607777) Confirm home task info is front-most task and not mixed in with others
- int runningTaskId = getTaskIdsForRunningTaskView()[0];
- if (mHomeTask != null && mHomeTask.key.id == runningTaskId
- && !taskGroups.isEmpty()) {
+ if (mHomeTaskInfo != null && mHomeTaskInfo.taskId == mRunningTaskId && !tasks.isEmpty()) {
// Check if the task list has running task
boolean found = false;
- for (GroupTask group : taskGroups) {
- if (group.containsTask(runningTaskId)) {
+ for (Task t : tasks) {
+ if (t.key.id == mRunningTaskId) {
found = true;
break;
}
}
if (!found) {
- ArrayList<GroupTask> newList = new ArrayList<>(taskGroups.size() + 1);
- newList.addAll(taskGroups);
- newList.add(new GroupTask(mHomeTask, null, null));
- taskGroups = newList;
+ ArrayList<Task> newList = new ArrayList<>(tasks.size() + 1);
+ newList.addAll(tasks);
+ newList.add(Task.from(new TaskKey(mHomeTaskInfo), mHomeTaskInfo, false));
+ tasks = newList;
}
}
- super.applyLoadPlan(taskGroups);
+ super.applyLoadPlan(tasks);
}
@Override
public void setRunningTaskHidden(boolean isHidden) {
- if (mHomeTask != null) {
+ if (mHomeTaskInfo != null) {
// Always keep the home task hidden
isHidden = true;
}
@@ -205,27 +175,15 @@ public class FallbackRecentsView extends RecentsView<RecentsActivity, RecentsSta
} else {
if (mActivity.isInState(RecentsState.MODAL_TASK)) {
mActivity.getStateManager().goToState(DEFAULT);
- resetModalVisuals();
}
}
}
@Override
- public void initiateSplitSelect(TaskView taskView,
- @SplitConfigurationOptions.StagePosition int stagePosition) {
- super.initiateSplitSelect(taskView, stagePosition);
- mActivity.getStateManager().goToState(OVERVIEW_SPLIT_SELECT);
- }
-
- @Override
public void onStateTransitionStart(RecentsState toState) {
setOverviewStateEnabled(true);
setOverviewGridEnabled(toState.displayOverviewTasksAsGrid(mActivity.getDeviceProfile()));
setOverviewFullscreenEnabled(toState.isFullScreen());
- if (toState == MODAL_TASK) {
- setOverviewSelectEnabled(true);
- }
- Log.d(BAD_STATE, "FRV onStateTransitionStart setFreezeVisibility=true, toState=" + toState);
setFreezeViewVisibility(true);
}
@@ -235,19 +193,8 @@ public class FallbackRecentsView extends RecentsView<RecentsActivity, RecentsSta
// Clean-up logic that occurs when recents is no longer in use/visible.
reset();
}
- boolean isOverlayEnabled = finalState == DEFAULT || finalState == MODAL_TASK;
- setOverlayEnabled(isOverlayEnabled);
- Log.d(BAD_STATE, "FRV onStateTransitionComplete setFreezeVisibility=false, finalState="
- + finalState);
+ setOverlayEnabled(finalState == DEFAULT || finalState == MODAL_TASK);
setFreezeViewVisibility(false);
- if (finalState != MODAL_TASK) {
- setOverviewSelectEnabled(false);
- }
-
- if (isOverlayEnabled) {
- runActionOnRemoteHandles(remoteTargetHandle ->
- remoteTargetHandle.getTaskViewSimulator().setDrawsBelowRecents(true));
- }
}
@Override
@@ -258,22 +205,4 @@ public class FallbackRecentsView extends RecentsView<RecentsActivity, RecentsSta
setDisallowScrollToClearAll(!state.hasClearAllButton());
}
}
-
- @Override
- public boolean onTouchEvent(MotionEvent ev) {
- boolean result = super.onTouchEvent(ev);
- // Do not let touch escape to siblings below this view.
- return result || mActivity.getStateManager().getState().overviewUi();
- }
-
- @Override
- public void initiateSplitSelect(QuickstepSystemShortcut.SplitSelectSource splitSelectSource) {
- super.initiateSplitSelect(splitSelectSource);
- mActivity.getStateManager().goToState(OVERVIEW_SPLIT_SELECT);
- }
-
- @Override
- protected boolean canLaunchFullscreenTask() {
- return !mActivity.isInState(OVERVIEW_SPLIT_SELECT);
- }
}
diff --git a/quickstep/src/com/android/quickstep/fallback/RecentsState.java b/quickstep/src/com/android/quickstep/fallback/RecentsState.java
index 77db6b79f4..b6cfdce65a 100644
--- a/quickstep/src/com/android/quickstep/fallback/RecentsState.java
+++ b/quickstep/src/com/android/quickstep/fallback/RecentsState.java
@@ -23,6 +23,7 @@ import android.graphics.Color;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.R;
+import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.statemanager.BaseState;
import com.android.launcher3.util.Themes;
import com.android.quickstep.RecentsActivity;
@@ -39,20 +40,17 @@ public class RecentsState implements BaseState<RecentsState> {
private static final int FLAG_SHOW_AS_GRID = BaseState.getFlag(4);
private static final int FLAG_SCRIM = BaseState.getFlag(5);
private static final int FLAG_LIVE_TILE = BaseState.getFlag(6);
- private static final int FLAG_OVERVIEW_UI = BaseState.getFlag(7);
public static final RecentsState DEFAULT = new RecentsState(0,
- FLAG_DISABLE_RESTORE | FLAG_CLEAR_ALL_BUTTON | FLAG_OVERVIEW_ACTIONS | FLAG_SHOW_AS_GRID
- | FLAG_SCRIM | FLAG_LIVE_TILE | FLAG_OVERVIEW_UI);
+ FLAG_CLEAR_ALL_BUTTON | FLAG_OVERVIEW_ACTIONS | FLAG_SHOW_AS_GRID | FLAG_SCRIM
+ | FLAG_LIVE_TILE);
public static final RecentsState MODAL_TASK = new ModalState(1,
FLAG_DISABLE_RESTORE | FLAG_CLEAR_ALL_BUTTON | FLAG_OVERVIEW_ACTIONS | FLAG_MODAL
- | FLAG_SHOW_AS_GRID | FLAG_SCRIM | FLAG_LIVE_TILE | FLAG_OVERVIEW_UI);
+ | FLAG_SHOW_AS_GRID | FLAG_SCRIM | FLAG_LIVE_TILE);
public static final RecentsState BACKGROUND_APP = new BackgroundAppState(2,
- FLAG_DISABLE_RESTORE | FLAG_NON_INTERACTIVE | FLAG_FULL_SCREEN | FLAG_OVERVIEW_UI);
+ FLAG_DISABLE_RESTORE | FLAG_NON_INTERACTIVE | FLAG_FULL_SCREEN);
public static final RecentsState HOME = new RecentsState(3, 0);
public static final RecentsState BG_LAUNCHER = new LauncherState(4, 0);
- public static final RecentsState OVERVIEW_SPLIT_SELECT = new RecentsState(5,
- FLAG_SHOW_AS_GRID | FLAG_SCRIM | FLAG_OVERVIEW_UI);
public final int ordinal;
private final int mFlags;
@@ -77,7 +75,7 @@ public class RecentsState implements BaseState<RecentsState> {
}
@Override
- public int getTransitionDuration(Context context, boolean isToState) {
+ public int getTransitionDuration(Context context) {
return 250;
}
@@ -135,14 +133,11 @@ public class RecentsState implements BaseState<RecentsState> {
* For this state, whether tasks should layout as a grid rather than a list.
*/
public boolean displayOverviewTasksAsGrid(DeviceProfile deviceProfile) {
- return hasFlag(FLAG_SHOW_AS_GRID) && deviceProfile.isTablet;
+ return hasFlag(FLAG_SHOW_AS_GRID) && showAsGrid(deviceProfile);
}
- /**
- * True if the state has overview panel visible.
- */
- public boolean overviewUi() {
- return hasFlag(FLAG_OVERVIEW_UI);
+ private boolean showAsGrid(DeviceProfile deviceProfile) {
+ return deviceProfile.isTablet && FeatureFlags.ENABLE_OVERVIEW_GRID.get();
}
private static class ModalState extends RecentsState {
diff --git a/quickstep/src/com/android/quickstep/inputconsumers/AssistantInputConsumer.java b/quickstep/src/com/android/quickstep/inputconsumers/AssistantInputConsumer.java
index 162ace4965..510820a1e5 100644
--- a/quickstep/src/com/android/quickstep/inputconsumers/AssistantInputConsumer.java
+++ b/quickstep/src/com/android/quickstep/inputconsumers/AssistantInputConsumer.java
@@ -24,8 +24,6 @@ import static android.view.MotionEvent.ACTION_POINTER_DOWN;
import static android.view.MotionEvent.ACTION_POINTER_UP;
import static android.view.MotionEvent.ACTION_UP;
-import static com.android.internal.app.AssistUtils.INVOCATION_TYPE_GESTURE;
-import static com.android.internal.app.AssistUtils.INVOCATION_TYPE_KEY;
import static com.android.launcher3.Utilities.squaredHypot;
import android.animation.Animator;
@@ -66,6 +64,8 @@ public class AssistantInputConsumer extends DelegateInputConsumer {
private static final String OPA_BUNDLE_TRIGGER = "triggered_by";
// From //java/com/google/android/apps/gsa/assistant/shared/proto/opa_trigger.proto.
private static final int OPA_BUNDLE_TRIGGER_DIAG_SWIPE_GESTURE = 83;
+ private static final String INVOCATION_TYPE_KEY = "invocation_type";
+ private static final int INVOCATION_TYPE_GESTURE = 1;
private final PointF mDownPos = new PointF();
private final PointF mLastPos = new PointF();
diff --git a/quickstep/src/com/android/quickstep/inputconsumers/DeviceLockedInputConsumer.java b/quickstep/src/com/android/quickstep/inputconsumers/DeviceLockedInputConsumer.java
index 3d737ca0e4..fcc0217499 100644
--- a/quickstep/src/com/android/quickstep/inputconsumers/DeviceLockedInputConsumer.java
+++ b/quickstep/src/com/android/quickstep/inputconsumers/DeviceLockedInputConsumer.java
@@ -60,8 +60,6 @@ import com.android.systemui.shared.system.InputMonitorCompat;
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat.SurfaceParams.Builder;
-import java.util.HashMap;
-
/**
* A placeholder input consumer used when the device is still locked, e.g. from secure camera.
*/
@@ -241,7 +239,7 @@ public class DeviceLockedInputConsumer implements InputConsumer,
}
@Override
- public void onRecentsAnimationCanceled(HashMap<Integer, ThumbnailData> thumbnailDatas) {
+ public void onRecentsAnimationCanceled(ThumbnailData thumbnailData) {
mRecentsAnimationController = null;
mTransformParams.setTargetSet(null);
}
diff --git a/quickstep/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java b/quickstep/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java
index 11f0ff3259..725c7c45a5 100644
--- a/quickstep/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java
+++ b/quickstep/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java
@@ -29,6 +29,7 @@ import static com.android.launcher3.Utilities.EDGE_NAV_BAR;
import static com.android.launcher3.Utilities.squaredHypot;
import static com.android.launcher3.util.TraceHelper.FLAG_CHECK_FOR_RACE_CONDITIONS;
import static com.android.launcher3.util.VelocityUtils.PX_PER_MS;
+import static com.android.quickstep.GestureState.STATE_OVERSCROLL_WINDOW_CREATED;
import static com.android.quickstep.util.ActiveGestureLog.INTENT_EXTRA_LOG_TRACE_ID;
import android.annotation.TargetApi;
@@ -36,10 +37,12 @@ import android.content.Context;
import android.content.ContextWrapper;
import android.content.Intent;
import android.graphics.PointF;
+import android.hardware.display.DisplayManager;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
+import android.view.Display;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.ViewConfiguration;
@@ -61,6 +64,7 @@ import com.android.quickstep.RecentsAnimationCallbacks;
import com.android.quickstep.RecentsAnimationDeviceState;
import com.android.quickstep.RotationTouchHelper;
import com.android.quickstep.TaskAnimationManager;
+import com.android.quickstep.TouchInteractionService;
import com.android.quickstep.util.ActiveGestureLog;
import com.android.quickstep.util.CachedEventDispatcher;
import com.android.quickstep.util.MotionPauseDetector;
@@ -84,9 +88,6 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC
public static final float QUICKSTEP_TOUCH_SLOP_RATIO_TWO_BUTTON = 9;
public static final float QUICKSTEP_TOUCH_SLOP_RATIO_GESTURAL = 2;
- // Minimum angle of a gesture's coordinate where a release goes to overview.
- public static final int OVERVIEW_MIN_DEGREES = 15;
-
private final RecentsAnimationDeviceState mDeviceState;
private final NavBarPosition mNavBarPosition;
private final TaskAnimationManager mTaskAnimationManager;
@@ -113,6 +114,8 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC
private final PointF mLastPos = new PointF();
private int mActivePointerId = INVALID_POINTER_ID;
+ private int mLastRotation = -1;
+
// Distance after which we start dragging the window.
private final float mTouchSlop;
@@ -130,6 +133,8 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC
// Might be displacement in X or Y, depending on the direction we are swiping from the nav bar.
private float mStartDisplacement;
+ private final DisplayManager mDisplayManager;
+
private Handler mMainThreadHandler;
private Runnable mCancelRecentsAnimationRunnable = () -> {
ActivityManagerWrapper.getInstance().cancelRecentsAnimation(
@@ -172,6 +177,7 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC
mPassedPilferInputSlop = mPassedWindowMoveSlop = continuingPreviousGesture;
mDisableHorizontalSwipe = !mPassedPilferInputSlop && disableHorizontalSwipe;
mRotationTouchHelper = mDeviceState.getRotationTouchHelper();
+ mDisplayManager = getSystemService(DisplayManager.class);
}
@Override
@@ -197,6 +203,17 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC
return;
}
+ if (TouchInteractionService.ENABLE_PER_WINDOW_INPUT_ROTATION) {
+ final Display display = mDisplayManager.getDisplay(mDeviceState.getDisplayId());
+ final int rotation = display.getRotation();
+ if (rotation != mLastRotation) {
+ // If rotation changes, reset tracking to avoid degenerate velocities.
+ mLastPos.set(ev.getX(), ev.getY());
+ mVelocityTracker.clear();
+ mLastRotation = rotation;
+ }
+ }
+
// Proxy events to recents view
if (mPassedWindowMoveSlop && mInteractionHandler != null
&& !mRecentsViewDispatcher.hasConsumer()) {
@@ -294,9 +311,8 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC
// the gesture (in which case mPassedPilferInputSlop starts as true).
boolean haveNotPassedSlopOnContinuedGesture =
!mPassedSlopOnThisGesture && mPassedPilferInputSlop;
- double degrees = Math.toDegrees(Math.atan(upDist / horizontalDist));
boolean isLikelyToStartNewTask = haveNotPassedSlopOnContinuedGesture
- || degrees <= OVERVIEW_MIN_DEGREES;
+ || horizontalDist > upDist;
if (!mPassedPilferInputSlop) {
if (passedSlop) {
@@ -474,7 +490,7 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC
@Override
public boolean allowInterceptByParent() {
- return !mPassedPilferInputSlop;
+ return !mPassedPilferInputSlop || mGestureState.hasState(STATE_OVERSCROLL_WINDOW_CREATED);
}
@Override
diff --git a/quickstep/src/com/android/quickstep/inputconsumers/OverscrollInputConsumer.java b/quickstep/src/com/android/quickstep/inputconsumers/OverscrollInputConsumer.java
new file mode 100644
index 0000000000..fb420a272a
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/inputconsumers/OverscrollInputConsumer.java
@@ -0,0 +1,287 @@
+/*
+ * 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.
+ */
+package com.android.quickstep.inputconsumers;
+
+import static android.view.MotionEvent.ACTION_CANCEL;
+import static android.view.MotionEvent.ACTION_DOWN;
+import static android.view.MotionEvent.ACTION_MOVE;
+import static android.view.MotionEvent.ACTION_POINTER_DOWN;
+import static android.view.MotionEvent.ACTION_POINTER_UP;
+import static android.view.MotionEvent.ACTION_UP;
+
+import static com.android.launcher3.Utilities.squaredHypot;
+
+import static java.lang.Math.abs;
+
+import android.content.Context;
+import android.graphics.PointF;
+import android.util.Log;
+import android.view.MotionEvent;
+import android.view.ViewConfiguration;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import com.android.launcher3.BaseDraggingActivity;
+import com.android.launcher3.R;
+import com.android.quickstep.GestureState;
+import com.android.quickstep.InputConsumer;
+import com.android.quickstep.views.RecentsView;
+import com.android.systemui.plugins.OverscrollPlugin;
+import com.android.systemui.shared.system.InputMonitorCompat;
+
+/**
+ * Input consumer for handling events to pass to an {@code OverscrollPlugin}.
+ */
+public class OverscrollInputConsumer extends DelegateInputConsumer {
+ private static final String TAG = "OverscrollInputConsumer";
+ private static final boolean DEBUG_LOGS_ENABLED = false;
+ private static void debugPrint(String log) {
+ if (DEBUG_LOGS_ENABLED) {
+ Log.v(TAG, log);
+ }
+ }
+
+ private final PointF mDownPos = new PointF();
+ private final PointF mLastPos = new PointF();
+ private final PointF mStartDragPos = new PointF();
+ private final int mAngleThreshold;
+
+ private final int mFlingDistanceThresholdPx;
+ private final int mFlingVelocityThresholdPx;
+ private int mActivePointerId = -1;
+ private boolean mPassedSlop = false;
+ // True if we set ourselves as active, meaning we no longer pass events to the delegate.
+ private boolean mPassedActiveThreshold = false;
+ // When a gesture crosses this length, this recognizer will attempt to interpret touch events.
+ private final float mSquaredSlop;
+ // When a gesture crosses this length, this recognizer will become the sole active recognizer.
+ private final float mSquaredActiveThreshold;
+ // When a gesture crosses this length, the overscroll view should be shown.
+ private final float mSquaredFinishThreshold;
+ private boolean mThisDownIsIgnored = false;
+
+ private final GestureState mGestureState;
+ @Nullable
+ private final OverscrollPlugin mPlugin;
+
+ @Nullable
+ private RecentsView mRecentsView;
+
+ public OverscrollInputConsumer(Context context, GestureState gestureState,
+ InputConsumer delegate, InputMonitorCompat inputMonitor, OverscrollPlugin plugin) {
+ super(delegate, inputMonitor);
+
+ mAngleThreshold = context.getResources()
+ .getInteger(R.integer.assistant_gesture_corner_deg_threshold);
+ mFlingDistanceThresholdPx = (int) context.getResources()
+ .getDimension(R.dimen.gestures_overscroll_fling_threshold);
+ mFlingVelocityThresholdPx = ViewConfiguration.get(context).getScaledMinimumFlingVelocity();
+ mGestureState = gestureState;
+ mPlugin = plugin;
+
+ float slop = ViewConfiguration.get(context).getScaledTouchSlop();
+
+ mSquaredSlop = slop * slop;
+
+
+ float finishGestureThreshold = (int) context.getResources()
+ .getDimension(R.dimen.gestures_overscroll_finish_threshold);
+ mSquaredFinishThreshold = finishGestureThreshold * finishGestureThreshold;
+
+ float activeThreshold = (int) context.getResources()
+ .getDimension(R.dimen.gestures_overscroll_active_threshold);
+ mSquaredActiveThreshold = activeThreshold * activeThreshold;
+ }
+
+ @Override
+ public int getType() {
+ return TYPE_OVERSCROLL | mDelegate.getType();
+ }
+
+ @Override
+ public void onMotionEvent(MotionEvent ev) {
+ if (mPlugin == null) {
+ return;
+ }
+
+ debugPrint("got event, underlying activity is " + getUnderlyingActivity());
+ switch (ev.getActionMasked()) {
+ case ACTION_DOWN: {
+ debugPrint("ACTION_DOWN");
+ mActivePointerId = ev.getPointerId(0);
+ mDownPos.set(ev.getX(), ev.getY());
+ mLastPos.set(mDownPos);
+ if (mPlugin.blockOtherGestures()) {
+ debugPrint("mPlugin.blockOtherGestures(), becoming active on ACTION_DOWN");
+ // Otherwise, if an appear gesture is performed when the Activity is visible,
+ // the Activity will dismiss its keyboard.
+ mPassedActiveThreshold = true;
+ mPassedSlop = true;
+ mStartDragPos.set(mLastPos.x, mLastPos.y);
+ setActive(ev);
+ }
+ break;
+ }
+ case ACTION_POINTER_DOWN: {
+ if (mState != STATE_ACTIVE) {
+ mState = STATE_DELEGATE_ACTIVE;
+ }
+ break;
+ }
+ case ACTION_POINTER_UP: {
+ int ptrIdx = ev.getActionIndex();
+ int ptrId = ev.getPointerId(ptrIdx);
+ if (ptrId == mActivePointerId) {
+ final int newPointerIdx = ptrIdx == 0 ? 1 : 0;
+ mDownPos.set(
+ ev.getX(newPointerIdx) - (mLastPos.x - mDownPos.x),
+ ev.getY(newPointerIdx) - (mLastPos.y - mDownPos.y));
+ mLastPos.set(ev.getX(newPointerIdx), ev.getY(newPointerIdx));
+ mActivePointerId = ev.getPointerId(newPointerIdx);
+ }
+ break;
+ }
+ case ACTION_MOVE: {
+ if (mState == STATE_DELEGATE_ACTIVE) {
+ break;
+ }
+
+ if (!mDelegate.allowInterceptByParent()) {
+ mState = STATE_DELEGATE_ACTIVE;
+ break;
+ }
+
+ // Update last touch position.
+ int pointerIndex = ev.findPointerIndex(mActivePointerId);
+ if (pointerIndex == -1) {
+ break;
+ }
+ mLastPos.set(ev.getX(pointerIndex), ev.getY(pointerIndex));
+
+ float squaredDist = squaredHypot(mLastPos.x - mDownPos.x, mLastPos.y - mDownPos.y);
+ if ((!mPassedSlop) && (squaredDist > mSquaredSlop)) {
+ mPassedSlop = true;
+ mStartDragPos.set(mLastPos.x, mLastPos.y);
+ mGestureState.setState(GestureState.STATE_OVERSCROLL_WINDOW_CREATED);
+ }
+
+ boolean becomeActive = mPassedSlop && !mPassedActiveThreshold && isOverscrolled()
+ && (squaredDist > mSquaredActiveThreshold);
+ if (becomeActive) {
+ debugPrint("Past slop and past threshold, set active");
+ mPassedActiveThreshold = true;
+ setActive(ev);
+ }
+
+ if (mPassedActiveThreshold) {
+ debugPrint("ACTION_MOVE Relaying touch event");
+ mPlugin.onTouchEvent(ev, getHorizontalDistancePx(), getVerticalDistancePx(),
+ (int) Math.sqrt(mSquaredFinishThreshold), mFlingDistanceThresholdPx,
+ mFlingVelocityThresholdPx, getDeviceState(), getUnderlyingActivity());
+ }
+
+ break;
+ }
+ case ACTION_CANCEL:
+ case ACTION_UP:
+ debugPrint("ACTION_UP");
+ if (mPassedActiveThreshold) {
+ debugPrint("ACTION_UP Relaying touch event");
+
+ mPlugin.onTouchEvent(ev, getHorizontalDistancePx(), getVerticalDistancePx(),
+ (int) Math.sqrt(mSquaredFinishThreshold), mFlingDistanceThresholdPx,
+ mFlingVelocityThresholdPx, getDeviceState(), getUnderlyingActivity());
+ }
+
+
+ mPassedSlop = false;
+ mPassedActiveThreshold = false;
+ mState = STATE_INACTIVE;
+ break;
+ }
+
+ if (mState != STATE_ACTIVE) {
+ mDelegate.onMotionEvent(ev);
+ }
+ }
+
+ private boolean isOverscrolled() {
+ if (mRecentsView == null) {
+ BaseDraggingActivity activity = mGestureState.getActivityInterface()
+ .getCreatedActivity();
+ if (activity != null) {
+ mRecentsView = activity.getOverviewPanel();
+ }
+ }
+
+ // Make sure there isn't an app to quick switch to on our right
+ int maxIndex = 0;
+ if (mRecentsView != null && mRecentsView.hasRecentsExtraCard()) {
+ maxIndex = 1;
+ }
+
+ boolean atRightMostApp = mRecentsView == null
+ || (mRecentsView.getRunningTaskIndex() <= maxIndex);
+
+ // Check if the gesture is within our angle threshold of horizontal
+ float deltaY = abs(mLastPos.y - mDownPos.y);
+ float deltaX = mLastPos.x - mDownPos.x;
+
+ boolean angleInBounds = (Math.toDegrees(Math.atan2(deltaY, abs(deltaX))) < mAngleThreshold);
+
+ boolean overscrollVisible = mPlugin.blockOtherGestures();
+ boolean overscrollInvisibleAndLeftSwipe = !overscrollVisible && deltaX < 0;
+ boolean gestureDirectionMatchesVisibility = overscrollVisible
+ || overscrollInvisibleAndLeftSwipe;
+ return atRightMostApp && angleInBounds && gestureDirectionMatchesVisibility;
+ }
+
+ private String getDeviceState() {
+ String deviceState = OverscrollPlugin.DEVICE_STATE_UNKNOWN;
+ int consumerType = mDelegate.getType();
+ if (((consumerType & InputConsumer.TYPE_OVERVIEW) > 0)
+ || ((consumerType & InputConsumer.TYPE_OVERVIEW_WITHOUT_FOCUS)) > 0) {
+ deviceState = OverscrollPlugin.DEVICE_STATE_LAUNCHER;
+ } else if ((consumerType & InputConsumer.TYPE_OTHER_ACTIVITY) > 0) {
+ deviceState = OverscrollPlugin.DEVICE_STATE_APP;
+ } else if (((consumerType & InputConsumer.TYPE_RESET_GESTURE) > 0)
+ || ((consumerType & InputConsumer.TYPE_DEVICE_LOCKED) > 0)) {
+ deviceState = OverscrollPlugin.DEVICE_STATE_LOCKED;
+ }
+
+ return deviceState;
+ }
+
+ private int getHorizontalDistancePx() {
+ return (int) (mLastPos.x - mDownPos.x);
+ }
+
+ private int getVerticalDistancePx() {
+ return (int) (mLastPos.y - mDownPos.y);
+ }
+
+ private @NonNull String getUnderlyingActivity() {
+ // Overly defensive, got guidance on code review that something in the chain of
+ // `mGestureState.getRunningTask().topActivity` can be null and thus cause a null pointer
+ // exception to be thrown, but we aren't sure which part can be null.
+ if ((mGestureState == null) || (mGestureState.getRunningTask() == null)
+ || (mGestureState.getRunningTask().topActivity == null)) {
+ return "";
+ }
+ return mGestureState.getRunningTask().topActivity.flattenToString();
+ }
+}
diff --git a/quickstep/src/com/android/quickstep/inputconsumers/OverviewInputConsumer.java b/quickstep/src/com/android/quickstep/inputconsumers/OverviewInputConsumer.java
index 02ac48ebeb..b0df2869c7 100644
--- a/quickstep/src/com/android/quickstep/inputconsumers/OverviewInputConsumer.java
+++ b/quickstep/src/com/android/quickstep/inputconsumers/OverviewInputConsumer.java
@@ -101,13 +101,6 @@ public class OverviewInputConsumer<S extends BaseState<S>, T extends StatefulAct
}
@Override
- public void onHoverEvent(MotionEvent ev) {
- if (ENABLE_QUICKSTEP_LIVE_TILE.get()) {
- mActivity.dispatchGenericMotionEvent(ev);
- }
- }
-
- @Override
public void onKeyEvent(KeyEvent ev) {
if (ENABLE_QUICKSTEP_LIVE_TILE.get()) {
switch (ev.getKeyCode()) {
diff --git a/quickstep/src/com/android/quickstep/inputconsumers/ProgressDelegateInputConsumer.java b/quickstep/src/com/android/quickstep/inputconsumers/ProgressDelegateInputConsumer.java
deleted file mode 100644
index 71dca663f0..0000000000
--- a/quickstep/src/com/android/quickstep/inputconsumers/ProgressDelegateInputConsumer.java
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
- * Copyright (C) 2021 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.quickstep.inputconsumers;
-
-import static com.android.launcher3.anim.Interpolators.scrollInterpolatorForVelocity;
-import static com.android.launcher3.touch.BaseSwipeDetector.calculateDuration;
-import static com.android.launcher3.touch.SingleAxisSwipeDetector.DIRECTION_POSITIVE;
-import static com.android.launcher3.touch.SingleAxisSwipeDetector.VERTICAL;
-import static com.android.quickstep.MultiStateCallback.DEBUG_STATES;
-import static com.android.quickstep.util.ActiveGestureLog.INTENT_EXTRA_LOG_TRACE_ID;
-
-import android.animation.ObjectAnimator;
-import android.content.Context;
-import android.content.Intent;
-import android.graphics.Point;
-import android.view.MotionEvent;
-
-import com.android.launcher3.anim.AnimatorListeners;
-import com.android.launcher3.testing.TestLogging;
-import com.android.launcher3.testing.TestProtocol;
-import com.android.launcher3.touch.SingleAxisSwipeDetector;
-import com.android.launcher3.util.DisplayController;
-import com.android.quickstep.AnimatedFloat;
-import com.android.quickstep.GestureState;
-import com.android.quickstep.InputConsumer;
-import com.android.quickstep.MultiStateCallback;
-import com.android.quickstep.RecentsAnimationCallbacks;
-import com.android.quickstep.RecentsAnimationController;
-import com.android.quickstep.RecentsAnimationTargets;
-import com.android.quickstep.TaskAnimationManager;
-import com.android.systemui.shared.recents.model.ThumbnailData;
-import com.android.systemui.shared.system.InputMonitorCompat;
-
-import java.util.HashMap;
-
-/**
- * Input consumer which delegates the swipe-progress handling
- */
-public class ProgressDelegateInputConsumer implements InputConsumer,
- RecentsAnimationCallbacks.RecentsAnimationListener,
- SingleAxisSwipeDetector.Listener {
-
- private static final float SWIPE_DISTANCE_THRESHOLD = 0.2f;
-
- private static final String[] STATE_NAMES = DEBUG_STATES ? new String[3] : null;
- private static int getFlagForIndex(int index, String name) {
- if (DEBUG_STATES) {
- STATE_NAMES[index] = name;
- }
- return 1 << index;
- }
-
- private static final int STATE_TARGET_RECEIVED =
- getFlagForIndex(0, "STATE_TARGET_RECEIVED");
- private static final int STATE_HANDLER_INVALIDATED =
- getFlagForIndex(1, "STATE_HANDLER_INVALIDATED");
- private static final int STATE_FLING_FINISHED =
- getFlagForIndex(2, "STATE_FLING_FINISHED");
-
- private final Context mContext;
- private final TaskAnimationManager mTaskAnimationManager;
- private final GestureState mGestureState;
- private final InputMonitorCompat mInputMonitorCompat;
- private final MultiStateCallback mStateCallback;
-
- private final Point mDisplaySize;
- private final SingleAxisSwipeDetector mSwipeDetector;
-
- private final AnimatedFloat mProgress;
-
- private boolean mDragStarted = false;
-
- private RecentsAnimationController mRecentsAnimationController;
- private Boolean mFlingEndsOnHome;
-
- public ProgressDelegateInputConsumer(Context context,
- TaskAnimationManager taskAnimationManager, GestureState gestureState,
- InputMonitorCompat inputMonitorCompat, AnimatedFloat progress) {
- mContext = context;
- mTaskAnimationManager = taskAnimationManager;
- mGestureState = gestureState;
- mInputMonitorCompat = inputMonitorCompat;
- mProgress = progress;
-
- // Do not use DeviceProfile as the user data might be locked
- mDisplaySize = DisplayController.INSTANCE.get(context).getInfo().currentSize;
-
- // Init states
- mStateCallback = new MultiStateCallback(STATE_NAMES);
- mStateCallback.runOnceAtState(STATE_TARGET_RECEIVED | STATE_HANDLER_INVALIDATED,
- this::endRemoteAnimation);
- mStateCallback.runOnceAtState(STATE_TARGET_RECEIVED | STATE_FLING_FINISHED,
- this::onFlingFinished);
-
- mSwipeDetector = new SingleAxisSwipeDetector(mContext, this, VERTICAL);
- mSwipeDetector.setDetectableScrollConditions(DIRECTION_POSITIVE, false);
- }
-
- @Override
- public int getType() {
- return TYPE_PROGRESS_DELEGATE;
- }
-
- @Override
- public void onMotionEvent(MotionEvent ev) {
- if (mFlingEndsOnHome == null) {
- mSwipeDetector.onTouchEvent(ev);
- }
- }
-
- @Override
- public void onDragStart(boolean start, float startDisplacement) {
- mDragStarted = true;
- TestLogging.recordEvent(TestProtocol.SEQUENCE_PILFER, "pilferPointers");
- mInputMonitorCompat.pilferPointers();
- Intent intent = mGestureState.getHomeIntent()
- .putExtra(INTENT_EXTRA_LOG_TRACE_ID, mGestureState.getGestureId());
- mTaskAnimationManager.startRecentsAnimation(mGestureState, intent, this);
- }
-
- @Override
- public boolean onDrag(float displacement) {
- if (mDisplaySize.y > 0) {
- mProgress.updateValue(displacement / -mDisplaySize.y);
- }
- return true;
- }
-
- @Override
- public void onDragEnd(float velocity) {
- final boolean willExit;
- if (mSwipeDetector.isFling(velocity)) {
- willExit = velocity < 0;
- } else {
- willExit = mProgress.value > SWIPE_DISTANCE_THRESHOLD;
- }
- float endValue = willExit ? 1 : 0;
- long duration = calculateDuration(velocity, endValue - mProgress.value);
- mFlingEndsOnHome = willExit;
-
- ObjectAnimator anim = mProgress.animateToValue(endValue);
- anim.setDuration(duration).setInterpolator(scrollInterpolatorForVelocity(velocity));
- anim.addListener(AnimatorListeners.forSuccessCallback(
- () -> mStateCallback.setState(STATE_FLING_FINISHED)));
- anim.start();
- }
-
- private void onFlingFinished() {
- if (mRecentsAnimationController != null) {
- boolean endToRecents = mFlingEndsOnHome == null ? true : mFlingEndsOnHome;
- mRecentsAnimationController.finishController(endToRecents /* toRecents */,
- null /* callback */, false /* sendUserLeaveHint */);
- }
- }
-
- @Override
- public void onRecentsAnimationStart(RecentsAnimationController controller,
- RecentsAnimationTargets targets) {
- mRecentsAnimationController = controller;
- mStateCallback.setState(STATE_TARGET_RECEIVED);
- }
-
- @Override
- public void onRecentsAnimationCanceled(HashMap<Integer, ThumbnailData> thumbnailDatas) {
- mRecentsAnimationController = null;
- }
-
- private void endRemoteAnimation() {
- onDragEnd(Float.MIN_VALUE);
- }
-
- @Override
- public void onConsumerAboutToBeSwitched() {
- mStateCallback.setState(STATE_HANDLER_INVALIDATED);
- }
-
- @Override
- public boolean allowInterceptByParent() {
- return !mDragStarted;
- }
-}
diff --git a/quickstep/src/com/android/quickstep/inputconsumers/SysUiOverlayInputConsumer.java b/quickstep/src/com/android/quickstep/inputconsumers/SysUiOverlayInputConsumer.java
index 878f132531..3f833c0a6d 100644
--- a/quickstep/src/com/android/quickstep/inputconsumers/SysUiOverlayInputConsumer.java
+++ b/quickstep/src/com/android/quickstep/inputconsumers/SysUiOverlayInputConsumer.java
@@ -15,11 +15,9 @@
*/
package com.android.quickstep.inputconsumers;
-import android.app.ActivityManager;
import android.content.Context;
+import android.content.Intent;
import android.graphics.PointF;
-import android.os.RemoteException;
-import android.util.Log;
import android.view.MotionEvent;
import com.android.launcher3.testing.TestLogging;
@@ -38,10 +36,6 @@ import com.android.systemui.shared.system.InputMonitorCompat;
*/
public class SysUiOverlayInputConsumer implements InputConsumer,
TriggerSwipeUpTouchTracker.OnSwipeUpListener {
- private static final String TAG = "SysUiOverlayInputConsumer";
-
- // Should match the values in PhoneWindowManager
- private static final String SYSTEM_DIALOG_REASON_GESTURE_NAV = "gestureNav";
private final Context mContext;
private final InputMonitorCompat mInputMonitor;
@@ -82,11 +76,7 @@ public class SysUiOverlayInputConsumer implements InputConsumer,
@Override
public void onSwipeUp(boolean wasFling, PointF finalVelocity) {
// Close system dialogs when a swipe up is detected.
- try {
- ActivityManager.getService().closeSystemDialogs(SYSTEM_DIALOG_REASON_GESTURE_NAV);
- } catch (RemoteException e) {
- Log.e(TAG, "Exception calling closeSystemDialogs " + e.getMessage());
- }
+ mContext.sendBroadcast(new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS));
}
@Override
diff --git a/quickstep/src/com/android/quickstep/inputconsumers/TaskbarStashInputConsumer.java b/quickstep/src/com/android/quickstep/inputconsumers/TaskbarStashInputConsumer.java
deleted file mode 100644
index 3785de4ecd..0000000000
--- a/quickstep/src/com/android/quickstep/inputconsumers/TaskbarStashInputConsumer.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright (C) 2021 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.quickstep.inputconsumers;
-
-import static com.android.launcher3.Utilities.squaredHypot;
-
-import android.content.Context;
-import android.view.GestureDetector;
-import android.view.GestureDetector.SimpleOnGestureListener;
-import android.view.MotionEvent;
-
-import com.android.launcher3.R;
-import com.android.launcher3.Utilities;
-import com.android.launcher3.taskbar.TaskbarActivityContext;
-import com.android.quickstep.InputConsumer;
-import com.android.systemui.shared.system.InputMonitorCompat;
-
-/**
- * Listens for a long press, and cancels the current gesture if that causes Taskbar to be unstashed.
- */
-public class TaskbarStashInputConsumer extends DelegateInputConsumer {
-
- private final TaskbarActivityContext mTaskbarActivityContext;
- private final GestureDetector mLongPressDetector;
- private final float mSquaredTouchSlop;
-
-
- private float mDownX, mDownY;
- private boolean mCanceledUnstashHint;
- private final float mUnstashArea;
- private final float mScreenWidth;
-
- public TaskbarStashInputConsumer(Context context, InputConsumer delegate,
- InputMonitorCompat inputMonitor, TaskbarActivityContext taskbarActivityContext) {
- super(delegate, inputMonitor);
- mTaskbarActivityContext = taskbarActivityContext;
- mSquaredTouchSlop = Utilities.squaredTouchSlop(context);
- mScreenWidth = taskbarActivityContext.getDeviceProfile().widthPx;
- mUnstashArea = context.getResources()
- .getDimensionPixelSize(R.dimen.taskbar_unstash_input_area);
-
- mLongPressDetector = new GestureDetector(context, new SimpleOnGestureListener() {
- @Override
- public void onLongPress(MotionEvent motionEvent) {
- onLongPressDetected(motionEvent);
- }
- });
- }
-
- @Override
- public int getType() {
- return TYPE_TASKBAR_STASH | mDelegate.getType();
- }
-
- @Override
- public void onMotionEvent(MotionEvent ev) {
- mLongPressDetector.onTouchEvent(ev);
- if (mState != STATE_ACTIVE) {
- mDelegate.onMotionEvent(ev);
-
- if (mTaskbarActivityContext != null) {
- final float x = ev.getRawX();
- final float y = ev.getRawY();
- switch (ev.getAction()) {
- case MotionEvent.ACTION_DOWN:
- if (isInArea(x)) {
- mDownX = x;
- mDownY = y;
- mTaskbarActivityContext.startTaskbarUnstashHint(
- /* animateForward = */ true);
- mCanceledUnstashHint = false;
- }
- break;
- case MotionEvent.ACTION_MOVE:
- if (!mCanceledUnstashHint
- && squaredHypot(mDownX - x, mDownY - y) > mSquaredTouchSlop) {
- mTaskbarActivityContext.startTaskbarUnstashHint(
- /* animateForward = */ false);
- mCanceledUnstashHint = true;
- }
- break;
- case MotionEvent.ACTION_UP:
- case MotionEvent.ACTION_CANCEL:
- if (!mCanceledUnstashHint) {
- mTaskbarActivityContext.startTaskbarUnstashHint(
- /* animateForward = */ false);
- }
- break;
- }
- }
- }
- }
-
- private boolean isInArea(float x) {
- float areaFromMiddle = mUnstashArea / 2.0f;
- float distFromMiddle = Math.abs(mScreenWidth / 2.0f - x);
- return distFromMiddle < areaFromMiddle;
- }
-
- private void onLongPressDetected(MotionEvent motionEvent) {
- if (mTaskbarActivityContext != null && isInArea(motionEvent.getRawX())) {
- boolean taskBarPressed = mTaskbarActivityContext.onLongPressToUnstashTaskbar();
- if (taskBarPressed) {
- setActive(motionEvent);
- }
- }
- }
-}
diff --git a/quickstep/src/com/android/quickstep/interaction/AllSetActivity.java b/quickstep/src/com/android/quickstep/interaction/AllSetActivity.java
index caf61c790e..4472bdcf73 100644
--- a/quickstep/src/com/android/quickstep/interaction/AllSetActivity.java
+++ b/quickstep/src/com/android/quickstep/interaction/AllSetActivity.java
@@ -15,32 +15,11 @@
*/
package com.android.quickstep.interaction;
-import static com.android.launcher3.Utilities.mapBoundToRange;
-import static com.android.launcher3.Utilities.mapRange;
-import static com.android.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN;
-import static com.android.launcher3.anim.Interpolators.LINEAR;
-
-import android.animation.Animator;
import android.app.Activity;
-import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
-import android.graphics.Canvas;
import android.graphics.Color;
-import android.graphics.ColorFilter;
-import android.graphics.ColorMatrix;
-import android.graphics.ColorMatrixColorFilter;
-import android.graphics.Matrix;
-import android.graphics.Paint;
-import android.graphics.PixelFormat;
-import android.graphics.PointF;
-import android.graphics.RadialGradient;
-import android.graphics.Rect;
-import android.graphics.Shader.TileMode;
-import android.graphics.drawable.Drawable;
import android.os.Bundle;
-import android.os.VibrationEffect;
-import android.os.Vibrator;
import android.util.Log;
import android.view.View;
import android.view.View.AccessibilityDelegate;
@@ -50,19 +29,9 @@ import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.Nullable;
-import androidx.core.graphics.ColorUtils;
-import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
-import com.android.launcher3.anim.AnimatorPlaybackController;
-import com.android.launcher3.util.Executors;
-import com.android.quickstep.AnimatedFloat;
-import com.android.quickstep.GestureState;
-import com.android.quickstep.TouchInteractionService.TISBinder;
-import com.android.quickstep.util.TISBindHelper;
-
-import com.airbnb.lottie.LottieAnimationView;
import java.net.URISyntaxException;
@@ -78,31 +47,10 @@ public class AllSetActivity extends Activity {
private static final String EXTRA_ACCENT_COLOR_DARK_MODE = "suwColorAccentDark";
private static final String EXTRA_ACCENT_COLOR_LIGHT_MODE = "suwColorAccentLight";
- private static final float HINT_BOTTOM_FACTOR = 1 - .94f;
-
- private static final int MAX_SWIPE_DURATION = 350;
-
- private TISBindHelper mTISBindHelper;
- private TISBinder mBinder;
-
- private final AnimatedFloat mSwipeProgress = new AnimatedFloat(this::onSwipeProgressUpdate);
- private BgDrawable mBackground;
- private View mContentView;
- private float mSwipeUpShift;
-
- @Nullable private Vibrator mVibrator;
- private LottieAnimationView mAnimatedBackground;
- private Animator.AnimatorListener mBackgroundAnimatorListener;
-
- private AnimatorPlaybackController mLauncherStartAnim = null;
-
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_allset);
- findViewById(R.id.root_view).setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
- | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
- | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
int mode = getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK;
boolean isDarkTheme = mode == Configuration.UI_MODE_NIGHT_YES;
@@ -112,17 +60,6 @@ public class AllSetActivity extends Activity {
((ImageView) findViewById(R.id.icon)).getDrawable().mutate().setTint(accentColor);
- mBackground = new BgDrawable(this);
- findViewById(R.id.root_view).setBackground(mBackground);
- mContentView = findViewById(R.id.content_view);
- mSwipeUpShift = getResources().getDimension(R.dimen.allset_swipe_up_shift);
-
- boolean isTablet = InvariantDeviceProfile.INSTANCE.get(getApplicationContext())
- .getDeviceProfile(this).isTablet;
- TextView subtitle = findViewById(R.id.subtitle);
- subtitle.setText(isTablet
- ? R.string.allset_description_tablet : R.string.allset_description);
-
TextView tv = findViewById(R.id.navigation_settings);
tv.setTextColor(accentColor);
tv.setOnClickListener(v -> {
@@ -136,133 +73,6 @@ public class AllSetActivity extends Activity {
});
findViewById(R.id.hint).setAccessibilityDelegate(new SkipButtonAccessibilityDelegate());
- mTISBindHelper = new TISBindHelper(this, this::onTISConnected);
-
- mVibrator = getSystemService(Vibrator.class);
- mAnimatedBackground = findViewById(R.id.animated_background);
- startBackgroundAnimation();
- }
-
- private void runOnUiHelperThread(Runnable runnable) {
- Executors.UI_HELPER_EXECUTOR.execute(runnable);
- }
-
- private void startBackgroundAnimation() {
- if (Utilities.ATLEAST_S && mVibrator != null && mVibrator.areAllPrimitivesSupported(
- VibrationEffect.Composition.PRIMITIVE_THUD)) {
- if (mBackgroundAnimatorListener == null) {
- mBackgroundAnimatorListener =
- new Animator.AnimatorListener() {
- @Override
- public void onAnimationStart(Animator animation) {
- runOnUiHelperThread(() -> mVibrator.vibrate(getVibrationEffect()));
- }
-
- @Override
- public void onAnimationRepeat(Animator animation) {
- runOnUiHelperThread(() -> mVibrator.vibrate(getVibrationEffect()));
- }
-
- @Override
- public void onAnimationEnd(Animator animation) {
- runOnUiHelperThread(mVibrator::cancel);
- }
-
- @Override
- public void onAnimationCancel(Animator animation) {
- runOnUiHelperThread(mVibrator::cancel);
- }
- };
- }
- mAnimatedBackground.addAnimatorListener(mBackgroundAnimatorListener);
- }
- mAnimatedBackground.playAnimation();
- }
-
- /**
- * Sets up the vibration effect for the next round of animation. The parameters vary between
- * different illustrations.
- */
- private VibrationEffect getVibrationEffect() {
- return VibrationEffect.startComposition()
- .addPrimitive(VibrationEffect.Composition.PRIMITIVE_THUD, 1.0f, 50)
- .compose();
- }
-
- @Override
- protected void onResume() {
- super.onResume();
- if (mBinder != null) {
- mBinder.getTaskbarManager().setSetupUIVisible(true);
- mBinder.setSwipeUpProxy(this::createSwipeUpProxy);
- }
- }
-
- private void onTISConnected(TISBinder binder) {
- mBinder = binder;
- mBinder.getTaskbarManager().setSetupUIVisible(isResumed());
- mBinder.setSwipeUpProxy(isResumed() ? this::createSwipeUpProxy : null);
- mBinder.preloadOverviewForSUWAllSet();
- }
-
- @Override
- protected void onPause() {
- super.onPause();
- clearBinderOverride();
- if (mSwipeProgress.value >= 1) {
- finishAndRemoveTask();
- }
- }
-
- private void clearBinderOverride() {
- if (mBinder != null) {
- mBinder.getTaskbarManager().setSetupUIVisible(false);
- mBinder.setSwipeUpProxy(null);
- }
- }
-
- @Override
- protected void onDestroy() {
- super.onDestroy();
- mTISBindHelper.onDestroy();
- clearBinderOverride();
- if (mBackgroundAnimatorListener != null) {
- mAnimatedBackground.removeAnimatorListener(mBackgroundAnimatorListener);
- }
- }
-
- private AnimatedFloat createSwipeUpProxy(GestureState state) {
- if (!state.getHomeIntent().getComponent().getPackageName().equals(getPackageName())) {
- return null;
- }
- if (state.getRunningTaskId() != getTaskId()) {
- return null;
- }
- mSwipeProgress.updateValue(0);
- return mSwipeProgress;
- }
-
- private void onSwipeProgressUpdate() {
- mBackground.setProgress(mSwipeProgress.value);
- float alpha = Utilities.mapBoundToRange(
- mSwipeProgress.value, 0, HINT_BOTTOM_FACTOR, 1, 0, LINEAR);
- mContentView.setAlpha(alpha);
- mContentView.setTranslationY((alpha - 1) * mSwipeUpShift);
-
- if (mLauncherStartAnim == null) {
- mLauncherStartAnim = mBinder.getTaskbarManager().createLauncherStartFromSuwAnim(
- MAX_SWIPE_DURATION);
- }
- if (mLauncherStartAnim != null) {
- mLauncherStartAnim.setPlayFraction(Utilities.mapBoundToRange(
- mSwipeProgress.value, 0, 1, 0, 1, FAST_OUT_SLOW_IN));
- }
-
- if (alpha == 0f) {
- mAnimatedBackground.pauseAnimation();
- } else if (!mAnimatedBackground.isAnimating()) {
- mAnimatedBackground.resumeAnimation();
- }
}
/**
@@ -289,79 +99,4 @@ public class AllSetActivity extends Activity {
return super.performAccessibilityAction(host, action, args);
}
}
-
- private static class BgDrawable extends Drawable {
-
- private static final float START_SIZE_FACTOR = .5f;
- private static final float END_SIZE_FACTOR = 2;
- private static final float GRADIENT_END_PROGRESS = .5f;
-
- private final Paint mPaint = new Paint();
- private final RadialGradient mMaskGrad;
- private final Matrix mMatrix = new Matrix();
-
- private final ColorMatrix mColorMatrix = new ColorMatrix();
- private final ColorMatrixColorFilter mColorFilter =
- new ColorMatrixColorFilter(mColorMatrix);
-
- private final int mColor;
- private float mProgress = 0;
-
- BgDrawable(Context context) {
- mColor = context.getColor(R.color.all_set_page_background);
- mMaskGrad = new RadialGradient(0, 0, 1,
- new int[] {ColorUtils.setAlphaComponent(mColor, 0), mColor},
- new float[]{0, 1}, TileMode.CLAMP);
-
- mPaint.setShader(mMaskGrad);
- mPaint.setColorFilter(mColorFilter);
- }
-
- @Override
- public void draw(Canvas canvas) {
- if (mProgress <= 0) {
- canvas.drawColor(mColor);
- return;
- }
-
- // Update the progress to half the size only.
- float progress = mapBoundToRange(mProgress,
- 0, GRADIENT_END_PROGRESS, 0, 1, LINEAR);
- Rect bounds = getBounds();
- float x = bounds.exactCenterX();
- float height = bounds.height();
-
- float size = PointF.length(x, height);
- float radius = size * mapRange(progress, START_SIZE_FACTOR, END_SIZE_FACTOR);
- float y = mapRange(progress, height + radius , height / 2);
- mMatrix.setTranslate(x, y);
- mMatrix.postScale(radius, radius, x, y);
- mMaskGrad.setLocalMatrix(mMatrix);
-
- // Change the alpha-addition-component (index 19) so that every pixel is updated
- // accordingly
- mColorMatrix.getArray()[19] = mapBoundToRange(mProgress, 0, 1, 0, -255, LINEAR);
- mColorFilter.setColorMatrix(mColorMatrix);
-
- canvas.drawPaint(mPaint);
- }
-
- public void setProgress(float progress) {
- if (mProgress != progress) {
- mProgress = progress;
- invalidateSelf();
- }
- }
-
- @Override
- public int getOpacity() {
- return PixelFormat.TRANSLUCENT;
- }
-
- @Override
- public void setAlpha(int i) { }
-
- @Override
- public void setColorFilter(ColorFilter colorFilter) { }
- }
}
diff --git a/quickstep/src/com/android/quickstep/interaction/AnimatedTaskView.java b/quickstep/src/com/android/quickstep/interaction/AnimatedTaskView.java
deleted file mode 100644
index 53ad138b6a..0000000000
--- a/quickstep/src/com/android/quickstep/interaction/AnimatedTaskView.java
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * Copyright (C) 2021 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.quickstep.interaction;
-
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.AnimatorSet;
-import android.animation.ObjectAnimator;
-import android.animation.ValueAnimator;
-import android.annotation.ColorInt;
-import android.content.Context;
-import android.graphics.Outline;
-import android.graphics.Rect;
-import android.util.AttributeSet;
-import android.view.View;
-import android.view.ViewOutlineProvider;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.cardview.widget.CardView;
-import androidx.constraintlayout.widget.ConstraintLayout;
-
-import com.android.launcher3.R;
-
-import java.util.ArrayList;
-
-/**
- * Helper View for the gesture tutorial mock previous app task view.
- *
- * This helper class allows animating from a single-row layout to a two-row layout as seen in
- * large screen devices.
- */
-public class AnimatedTaskView extends ConstraintLayout {
-
- private View mFullTaskView;
- private CardView mTopTaskView;
- private CardView mBottomTaskView;
-
- private ViewOutlineProvider mTaskViewOutlineProvider = null;
- private final Rect mTaskViewAnimatedRect = new Rect();
- private float mTaskViewAnimatedRadius;
-
- public AnimatedTaskView(@NonNull Context context) {
- super(context);
- }
-
- public AnimatedTaskView(@NonNull Context context,
- @Nullable AttributeSet attrs) {
- super(context, attrs);
- }
-
- public AnimatedTaskView(
- @NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
- super(context, attrs, defStyleAttr);
- }
-
- public AnimatedTaskView(
- @NonNull Context context,
- @Nullable AttributeSet attrs,
- int defStyleAttr,
- int defStyleRes) {
- super(context, attrs, defStyleAttr, defStyleRes);
- }
-
- @Override
- protected void onFinishInflate() {
- super.onFinishInflate();
-
- mFullTaskView = findViewById(R.id.full_task_view);
- mTopTaskView = findViewById(R.id.top_task_view);
- mBottomTaskView = findViewById(R.id.bottom_task_view);
-
- setToSingleRowLayout(false);
- }
-
- AnimatorSet createAnimationToMultiRowLayout() {
- if (mTaskViewOutlineProvider == null) {
- // This is an illegal state.
- return null;
- }
- Outline startOutline = new Outline();
- mTaskViewOutlineProvider.getOutline(this, startOutline);
- Rect outlineStartRect = new Rect();
- startOutline.getRect(outlineStartRect);
- int endRectBottom = mTopTaskView.getHeight();
- float outlineStartRadius = startOutline.getRadius();
- float outlineEndRadius = getContext().getResources().getDimensionPixelSize(
- R.dimen.gesture_tutorial_small_task_view_corner_radius);
-
- ValueAnimator outlineAnimator = ValueAnimator.ofFloat(0f, 1f);
- outlineAnimator.addUpdateListener(valueAnimator -> {
- float progress = (float) valueAnimator.getAnimatedValue();
- mTaskViewAnimatedRect.bottom = (int) (outlineStartRect.bottom
- + progress * (endRectBottom - outlineStartRect.bottom));
- mTaskViewAnimatedRadius = outlineStartRadius
- + progress * (outlineEndRadius - outlineStartRadius);
- mFullTaskView.invalidateOutline();
- });
- outlineAnimator.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationStart(Animator animation) {
- super.onAnimationStart(animation);
-
- mTaskViewAnimatedRect.set(outlineStartRect);
- mTaskViewAnimatedRadius = outlineStartRadius;
-
- mFullTaskView.setClipToOutline(true);
- mFullTaskView.setOutlineProvider(new ViewOutlineProvider() {
- @Override
- public void getOutline(View view, Outline outline) {
- outline.setRoundRect(mTaskViewAnimatedRect, mTaskViewAnimatedRadius);
- }
- });
- }
-
- @Override
- public void onAnimationEnd(Animator animation) {
- super.onAnimationEnd(animation);
- mFullTaskView.setOutlineProvider(mTaskViewOutlineProvider);
- }
-
- @Override
- public void onAnimationCancel(Animator animation) {
- super.onAnimationCancel(animation);
- mFullTaskView.setOutlineProvider(mTaskViewOutlineProvider);
- }
- });
-
- ArrayList<Animator> animations = new ArrayList<>();
- animations.add(ObjectAnimator.ofFloat(
- mBottomTaskView, View.TRANSLATION_X, -mBottomTaskView.getWidth(), 0));
- animations.add(outlineAnimator);
-
- AnimatorSet animatorSet = new AnimatorSet();
- animatorSet.playTogether(animations);
- animatorSet.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationStart(Animator animation) {
- super.onAnimationStart(animation);
- setToSingleRowLayout(true);
-
- setPadding(0, outlineStartRect.top, 0, getHeight() - outlineStartRect.bottom);
- }
-
- @Override
- public void onAnimationEnd(Animator animation) {
- super.onAnimationEnd(animation);
- setToMultiRowLayout();
- }
-
- @Override
- public void onAnimationCancel(Animator animation) {
- super.onAnimationCancel(animation);
- setToMultiRowLayout();
- }
- });
-
- return animatorSet;
- }
-
- void setToSingleRowLayout(boolean forAnimation) {
- mFullTaskView.setVisibility(VISIBLE);
- mTopTaskView.setVisibility(INVISIBLE);
- mBottomTaskView.setVisibility(forAnimation ? VISIBLE : INVISIBLE);
- }
-
- void setToMultiRowLayout() {
- mFullTaskView.setVisibility(INVISIBLE);
- mTopTaskView.setVisibility(VISIBLE);
- mBottomTaskView.setVisibility(VISIBLE);
- }
-
- void setFakeTaskViewFillColor(@ColorInt int colorResId) {
- mFullTaskView.setBackgroundColor(colorResId);
- mTopTaskView.setCardBackgroundColor(colorResId);
- mBottomTaskView.setCardBackgroundColor(colorResId);
- }
-
- @Override
- public void setClipToOutline(boolean clipToOutline) {
- mFullTaskView.setClipToOutline(clipToOutline);
- }
-
- @Override
- public void setOutlineProvider(ViewOutlineProvider provider) {
- mTaskViewOutlineProvider = provider;
- mFullTaskView.setOutlineProvider(mTaskViewOutlineProvider);
- }
-}
diff --git a/quickstep/src/com/android/quickstep/interaction/AnimatedTaskbarView.java b/quickstep/src/com/android/quickstep/interaction/AnimatedTaskbarView.java
deleted file mode 100644
index e8cc45b97b..0000000000
--- a/quickstep/src/com/android/quickstep/interaction/AnimatedTaskbarView.java
+++ /dev/null
@@ -1,368 +0,0 @@
-/*
- * Copyright (C) 2021 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.quickstep.interaction;
-
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.AnimatorSet;
-import android.animation.ObjectAnimator;
-import android.content.Context;
-import android.util.AttributeSet;
-import android.view.View;
-import android.view.ViewGroup;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.constraintlayout.widget.ConstraintLayout;
-
-import com.android.launcher3.R;
-
-import java.util.ArrayList;
-
-
-/**
- * Helper View for the gesture tutorial mock taskbar view.
- *
- * This helper class allows animating this mock taskview to and from a mock hotseat and the bottom
- * of the screen.
- */
-public class AnimatedTaskbarView extends ConstraintLayout {
-
- private View mBackground;
- private View mIconContainer;
- private View mIcon1;
- private View mIcon2;
- private View mIcon3;
- private View mIcon4;
- private View mIcon5;
- private View mIcon6;
-
- @Nullable private Animator mRunningAnimator;
-
- public AnimatedTaskbarView(@NonNull Context context) {
- super(context);
- }
-
- public AnimatedTaskbarView(@NonNull Context context,
- @Nullable AttributeSet attrs) {
- super(context, attrs);
- }
-
- public AnimatedTaskbarView(@NonNull Context context, @Nullable AttributeSet attrs,
- int defStyleAttr) {
- super(context, attrs, defStyleAttr);
- }
-
- public AnimatedTaskbarView(@NonNull Context context, @Nullable AttributeSet attrs,
- int defStyleAttr,
- int defStyleRes) {
- super(context, attrs, defStyleAttr, defStyleRes);
- }
-
- @Override
- protected void onFinishInflate() {
- super.onFinishInflate();
-
- mBackground = findViewById(R.id.taskbar_background);
- mIconContainer = findViewById(R.id.icon_container);
- mIcon1 = findViewById(R.id.taskbar_icon_1);
- mIcon2 = findViewById(R.id.taskbar_icon_2);
- mIcon3 = findViewById(R.id.taskbar_icon_3);
- mIcon4 = findViewById(R.id.taskbar_icon_4);
- mIcon5 = findViewById(R.id.taskbar_icon_5);
- mIcon6 = findViewById(R.id.taskbar_icon_6);
- }
-
- /**
- * Animates this fake taskbar's disappearance into the given hotseat view.
- */
- public void animateDisappearanceToHotseat(ViewGroup hotseat) {
- ArrayList<Animator> animators = new ArrayList<>();
- int hotseatTop = hotseat.getTop();
-
- animators.add(ObjectAnimator.ofFloat(
- mBackground, View.TRANSLATION_Y, 0, mBackground.getHeight()));
- animators.add(ObjectAnimator.ofFloat(mBackground, View.ALPHA, 1f, 0f));
- animators.add(createIconDisappearanceToHotseatAnimator(
- mIcon1, hotseat.findViewById(R.id.hotseat_icon_1), hotseatTop));
- animators.add(createIconDisappearanceToHotseatAnimator(
- mIcon2, hotseat.findViewById(R.id.hotseat_icon_2), hotseatTop));
- animators.add(createIconDisappearanceToHotseatAnimator(
- mIcon3, hotseat.findViewById(R.id.hotseat_icon_3), hotseatTop));
- animators.add(createIconDisappearanceToHotseatAnimator(
- mIcon4, hotseat.findViewById(R.id.hotseat_icon_4), hotseatTop));
- animators.add(createIconDisappearanceToHotseatAnimator(
- mIcon5, hotseat.findViewById(R.id.hotseat_icon_5), hotseatTop));
- animators.add(createIconDisappearanceToHotseatAnimator(
- mIcon6, hotseat.findViewById(R.id.hotseat_icon_6), hotseatTop));
-
- AnimatorSet animatorSet = new AnimatorSet();
-
- animatorSet.playTogether(animators);
- animatorSet.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- super.onAnimationEnd(animation);
- setVisibility(INVISIBLE);
- }
-
- @Override
- public void onAnimationStart(Animator animation) {
- super.onAnimationStart(animation);
- setVisibility(VISIBLE);
- }
- });
-
- start(animatorSet);
- }
-
- /**
- * Animates this fake taskbar's appearance from the given hotseat view.
- */
- public void animateAppearanceFromHotseat(ViewGroup hotseat) {
- ArrayList<Animator> animators = new ArrayList<>();
- int hotseatTop = hotseat.getTop();
-
- animators.add(ObjectAnimator.ofFloat(
- mBackground, View.TRANSLATION_Y, mBackground.getHeight(), 0));
- animators.add(ObjectAnimator.ofFloat(mBackground, View.ALPHA, 0f, 1f));
- animators.add(createIconAppearanceFromHotseatAnimator(
- mIcon1, hotseat.findViewById(R.id.hotseat_icon_1), hotseatTop));
- animators.add(createIconAppearanceFromHotseatAnimator(
- mIcon2, hotseat.findViewById(R.id.hotseat_icon_2), hotseatTop));
- animators.add(createIconAppearanceFromHotseatAnimator(
- mIcon3, hotseat.findViewById(R.id.hotseat_icon_3), hotseatTop));
- animators.add(createIconAppearanceFromHotseatAnimator(
- mIcon4, hotseat.findViewById(R.id.hotseat_icon_4), hotseatTop));
- animators.add(createIconAppearanceFromHotseatAnimator(
- mIcon5, hotseat.findViewById(R.id.hotseat_icon_5), hotseatTop));
- animators.add(createIconAppearanceFromHotseatAnimator(
- mIcon6, hotseat.findViewById(R.id.hotseat_icon_6), hotseatTop));
-
- AnimatorSet animatorSet = new AnimatorSet();
-
- animatorSet.playTogether(animators);
- animatorSet.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationStart(Animator animation) {
- super.onAnimationStart(animation);
- setVisibility(VISIBLE);
- }
- });
-
- start(animatorSet);
- }
-
- /**
- * Animates this fake taskbar's disappearance to the bottom of the screen.
- */
- public void animateDisappearanceToBottom() {
- ArrayList<Animator> animators = new ArrayList<>();
-
- animators.add(ObjectAnimator.ofFloat(
- mBackground, View.TRANSLATION_Y, 0, mBackground.getHeight()));
- animators.add(ObjectAnimator.ofFloat(mBackground, View.ALPHA, 1f, 0f));
- animators.add(ObjectAnimator.ofFloat(mIconContainer, View.SCALE_X, 1f, 0f));
- animators.add(ObjectAnimator.ofFloat(mIconContainer, View.SCALE_Y, 1f, 0f));
-
- initializeIconContainerPivot();
-
- AnimatorSet animatorSet = new AnimatorSet();
-
- animatorSet.playTogether(animators);
- animatorSet.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- super.onAnimationEnd(animation);
- setVisibility(INVISIBLE);
- resetIconContainerPivot();
- }
-
- @Override
- public void onAnimationCancel(Animator animation) {
- super.onAnimationCancel(animation);
- resetIconContainerPivot();
- }
-
- @Override
- public void onAnimationStart(Animator animation) {
- super.onAnimationStart(animation);
- setVisibility(VISIBLE);
- }
- });
-
- start(animatorSet);
- }
-
- /**
- * Animates this fake taskbar's appearance from the bottom of the screen.
- */
- public void animateAppearanceFromBottom() {
- ArrayList<Animator> animators = new ArrayList<>();
-
- animators.add(ObjectAnimator.ofFloat(
- mBackground, View.TRANSLATION_Y, mBackground.getHeight(), 0));
- animators.add(ObjectAnimator.ofFloat(mBackground, View.ALPHA, 0f, 1f));
- animators.add(ObjectAnimator.ofFloat(mIconContainer, View.SCALE_X, 0f, 1f));
- animators.add(ObjectAnimator.ofFloat(mIconContainer, View.SCALE_Y, 0f, 1f));
-
- initializeIconContainerPivot();
-
- AnimatorSet animatorSet = new AnimatorSet();
-
- animatorSet.playTogether(animators);
- animatorSet.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationStart(Animator animation) {
- super.onAnimationStart(animation);
- setVisibility(VISIBLE);
- }
-
- @Override
- public void onAnimationEnd(Animator animation) {
- super.onAnimationEnd(animation);
- resetIconContainerPivot();
- }
-
- @Override
- public void onAnimationCancel(Animator animation) {
- super.onAnimationCancel(animation);
- resetIconContainerPivot();
- }
- });
-
- start(animatorSet);
- }
-
- private void initializeIconContainerPivot() {
- mIconContainer.setPivotX(getWidth() / 2f);
- mIconContainer.setPivotY(getHeight() * 0.8f);
- }
-
- private void resetIconContainerPivot() {
- mIconContainer.resetPivot();
- mIconContainer.setScaleX(1f);
- mIconContainer.setScaleY(1f);
- }
-
- private void start(Animator animator) {
- if (mRunningAnimator != null) {
- mRunningAnimator.cancel();
- }
-
- animator.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationCancel(Animator animation) {
- super.onAnimationCancel(animation);
- mRunningAnimator = null;
- }
-
- @Override
- public void onAnimationEnd(Animator animation) {
- super.onAnimationEnd(animation);
- mRunningAnimator = null;
- }
-
- @Override
- public void onAnimationStart(Animator animation) {
- super.onAnimationStart(animation);
- mRunningAnimator = animator;
- }
- });
-
- animator.start();
- }
-
- private Animator createIconDisappearanceToHotseatAnimator(
- View taskbarIcon, View hotseatIcon, int hotseatTop) {
- ArrayList<Animator> animators = new ArrayList<>();
-
- animators.add(ObjectAnimator.ofFloat(
- taskbarIcon,
- View.TRANSLATION_Y,
- 0,
- (hotseatTop + hotseatIcon.getTop()) - (getTop() + taskbarIcon.getTop())));
- animators.add(ObjectAnimator.ofFloat(
- taskbarIcon, View.TRANSLATION_X, 0, hotseatIcon.getLeft() - taskbarIcon.getLeft()));
- animators.add(ObjectAnimator.ofFloat(
- taskbarIcon,
- View.SCALE_X,
- 1f,
- (float) hotseatIcon.getWidth() / (float) taskbarIcon.getWidth()));
- animators.add(ObjectAnimator.ofFloat(
- taskbarIcon,
- View.SCALE_Y,
- 1f,
- (float) hotseatIcon.getHeight() / (float) taskbarIcon.getHeight()));
- animators.add(ObjectAnimator.ofFloat(taskbarIcon, View.ALPHA, 1f, 0f));
-
- AnimatorSet animatorSet = new AnimatorSet();
-
- animatorSet.playTogether(animators);
- animatorSet.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- super.onAnimationEnd(animation);
- taskbarIcon.setVisibility(INVISIBLE);
- }
-
- @Override
- public void onAnimationStart(Animator animation) {
- super.onAnimationStart(animation);
- taskbarIcon.setVisibility(VISIBLE);
- }
- });
-
- return animatorSet;
- }
-
- private Animator createIconAppearanceFromHotseatAnimator(
- View taskbarIcon, View hotseatIcon, int hotseatTop) {
- ArrayList<Animator> animators = new ArrayList<>();
-
- animators.add(ObjectAnimator.ofFloat(
- taskbarIcon,
- View.TRANSLATION_Y,
- (hotseatTop + hotseatIcon.getTop()) - (getTop() + taskbarIcon.getTop()),
- 0));
- animators.add(ObjectAnimator.ofFloat(
- taskbarIcon, View.TRANSLATION_X, hotseatIcon.getLeft() - taskbarIcon.getLeft(), 0));
- animators.add(ObjectAnimator.ofFloat(
- taskbarIcon,
- View.SCALE_X,
- (float) hotseatIcon.getWidth() / (float) taskbarIcon.getWidth(),
- 1f));
- animators.add(ObjectAnimator.ofFloat(
- taskbarIcon,
- View.SCALE_Y,
- (float) hotseatIcon.getHeight() / (float) taskbarIcon.getHeight(),
- 1f));
- animators.add(ObjectAnimator.ofFloat(taskbarIcon, View.ALPHA, 0f, 1f));
-
- AnimatorSet animatorSet = new AnimatorSet();
-
- animatorSet.playTogether(animators);
- animatorSet.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationStart(Animator animation) {
- super.onAnimationStart(animation);
- taskbarIcon.setVisibility(VISIBLE);
- }
- });
-
- return animatorSet;
- }
-}
diff --git a/quickstep/src/com/android/quickstep/interaction/AssistantGestureTutorialController.java b/quickstep/src/com/android/quickstep/interaction/AssistantGestureTutorialController.java
index 2f3a912fb4..957f776ae4 100644
--- a/quickstep/src/com/android/quickstep/interaction/AssistantGestureTutorialController.java
+++ b/quickstep/src/com/android/quickstep/interaction/AssistantGestureTutorialController.java
@@ -68,6 +68,7 @@ final class AssistantGestureTutorialController extends TutorialController {
showFeedback(R.string.assistant_gesture_feedback_swipe_too_far_from_corner);
break;
case ASSISTANT_COMPLETED:
+ hideFeedback(true);
showRippleEffect(null);
showFeedback(R.string.assistant_gesture_tutorial_playground_subtitle);
break;
diff --git a/quickstep/src/com/android/quickstep/interaction/AssistantGestureTutorialFragment.java b/quickstep/src/com/android/quickstep/interaction/AssistantGestureTutorialFragment.java
index f440638125..b797f0cba3 100644
--- a/quickstep/src/com/android/quickstep/interaction/AssistantGestureTutorialFragment.java
+++ b/quickstep/src/com/android/quickstep/interaction/AssistantGestureTutorialFragment.java
@@ -18,16 +18,10 @@ package com.android.quickstep.interaction;
import android.view.MotionEvent;
import android.view.View;
-import androidx.annotation.NonNull;
-
-import com.android.launcher3.logging.StatsLogManager;
import com.android.quickstep.interaction.TutorialController.TutorialType;
/** Shows the Home gesture interactive tutorial. */
public class AssistantGestureTutorialFragment extends TutorialFragment {
-
- public AssistantGestureTutorialFragment() {}
-
@Override
TutorialController createController(TutorialType type) {
return new AssistantGestureTutorialController(this, type);
@@ -45,14 +39,4 @@ public class AssistantGestureTutorialFragment extends TutorialFragment {
}
return super.onTouch(view, motionEvent);
}
-
- @Override
- void logTutorialStepShown(@NonNull StatsLogManager statsLogManager) {
- // No-Op: tutorial step not currently shown to users
- }
-
- @Override
- void logTutorialStepCompleted(@NonNull StatsLogManager statsLogManager) {
- // No-Op: tutorial step not currently shown to users
- }
}
diff --git a/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialController.java b/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialController.java
index 35d9f22d3a..3cb22f4ffe 100644
--- a/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialController.java
+++ b/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialController.java
@@ -18,9 +18,10 @@ package com.android.quickstep.interaction;
import static com.android.quickstep.interaction.TutorialController.TutorialType.BACK_NAVIGATION;
import static com.android.quickstep.interaction.TutorialController.TutorialType.BACK_NAVIGATION_COMPLETE;
-import android.annotation.LayoutRes;
import android.graphics.PointF;
+import androidx.appcompat.content.res.AppCompatResources;
+
import com.android.launcher3.R;
import com.android.quickstep.interaction.EdgeBackGestureHandler.BackGestureResult;
import com.android.quickstep.interaction.NavBarGestureHandler.NavBarGestureResult;
@@ -33,49 +34,23 @@ final class BackGestureTutorialController extends TutorialController {
}
@Override
- public int getIntroductionTitle() {
+ public Integer getIntroductionTitle() {
return R.string.back_gesture_intro_title;
}
@Override
- public int getIntroductionSubtitle() {
+ public Integer getIntroductionSubtitle() {
return R.string.back_gesture_intro_subtitle;
}
@Override
- public int getSpokenIntroductionSubtitle() {
- return R.string.back_gesture_spoken_intro_subtitle;
- }
-
- @Override
- public int getSuccessFeedbackSubtitle() {
- return mTutorialFragment.isAtFinalStep()
- ? R.string.back_gesture_feedback_complete_without_follow_up
- : R.string.back_gesture_feedback_complete_with_overview_follow_up;
- }
-
- @Override
- protected int getMockAppTaskLayoutResId() {
- return getMockAppTaskCurrentPageLayoutResId();
- }
-
- @LayoutRes
- int getMockAppTaskCurrentPageLayoutResId() {
- return mTutorialFragment.isLargeScreen()
- ? R.layout.gesture_tutorial_tablet_mock_conversation
- : R.layout.gesture_tutorial_mock_conversation;
- }
-
- @LayoutRes
- int getMockAppTaskPreviousPageLayoutResId() {
- return mTutorialFragment.isLargeScreen()
- ? R.layout.gesture_tutorial_tablet_mock_conversation_list
- : R.layout.gesture_tutorial_mock_conversation_list;
+ protected int getMockAppTaskThumbnailResId(boolean forDarkMode) {
+ return R.drawable.mock_conversation;
}
@Override
public void onBackGestureAttempted(BackGestureResult result) {
- if (isGestureCompleted()) {
+ if (mGestureCompleted) {
return;
}
switch (mTutorialType) {
@@ -95,9 +70,14 @@ final class BackGestureTutorialController extends TutorialController {
switch (result) {
case BACK_COMPLETED_FROM_LEFT:
case BACK_COMPLETED_FROM_RIGHT:
- mTutorialFragment.releaseFeedbackAnimation();
- updateFakeAppTaskViewLayout(getMockAppTaskPreviousPageLayoutResId());
- showSuccessFeedback();
+ mTutorialFragment.releaseGestureVideoView();
+ hideFeedback(true);
+ mFakeTaskView.setBackground(AppCompatResources.getDrawable(mContext,
+ R.drawable.mock_conversations_list));
+ int subtitleResId = mTutorialFragment.isAtFinalStep()
+ ? R.string.back_gesture_feedback_complete_without_follow_up
+ : R.string.back_gesture_feedback_complete_with_overview_follow_up;
+ showFeedback(subtitleResId, true);
break;
case BACK_CANCELLED_FROM_LEFT:
case BACK_CANCELLED_FROM_RIGHT:
@@ -114,7 +94,7 @@ final class BackGestureTutorialController extends TutorialController {
@Override
public void onNavBarGestureAttempted(NavBarGestureResult result, PointF finalVelocity) {
- if (isGestureCompleted()) {
+ if (mGestureCompleted) {
return;
}
if (mTutorialType == BACK_NAVIGATION_COMPLETE) {
@@ -122,22 +102,7 @@ final class BackGestureTutorialController extends TutorialController {
mTutorialFragment.closeTutorial();
}
} else if (mTutorialType == BACK_NAVIGATION) {
- switch (result) {
- case HOME_NOT_STARTED_TOO_FAR_FROM_EDGE:
- case OVERVIEW_NOT_STARTED_TOO_FAR_FROM_EDGE:
- case HOME_OR_OVERVIEW_CANCELLED:
- showFeedback(R.string.back_gesture_feedback_swipe_too_far_from_edge);
- break;
- case HOME_GESTURE_COMPLETED:
- case OVERVIEW_GESTURE_COMPLETED:
- case HOME_OR_OVERVIEW_NOT_STARTED_WRONG_SWIPE_DIRECTION:
- case ASSISTANT_COMPLETED:
- case ASSISTANT_NOT_STARTED_BAD_ANGLE:
- case ASSISTANT_NOT_STARTED_SWIPE_TOO_SHORT:
- default:
- showFeedback(R.string.back_gesture_feedback_swipe_in_nav_bar);
-
- }
+ showFeedback(R.string.back_gesture_feedback_swipe_in_nav_bar);
}
}
}
diff --git a/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialFragment.java b/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialFragment.java
index 37253e2b40..1740f68cc1 100644
--- a/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialFragment.java
+++ b/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialFragment.java
@@ -15,92 +15,26 @@
*/
package com.android.quickstep.interaction;
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.AnimatorSet;
-import android.animation.ObjectAnimator;
import android.view.MotionEvent;
import android.view.View;
-import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.android.launcher3.R;
-import com.android.launcher3.logging.StatsLogManager;
import com.android.quickstep.interaction.TutorialController.TutorialType;
-import java.util.ArrayList;
-
/** Shows the Back gesture interactive tutorial. */
public class BackGestureTutorialFragment extends TutorialFragment {
-
- public BackGestureTutorialFragment() {}
-
@Nullable
@Override
- Integer getEdgeAnimationResId() {
- return R.drawable.gesture_tutorial_loop_back;
+ Integer getFeedbackVideoResId(boolean forDarkMode) {
+ return R.drawable.gesture_tutorial_motion_back;
}
@Nullable
@Override
- protected Animator createGestureAnimation() {
- if (!(mTutorialController instanceof BackGestureTutorialController)) {
- return null;
- }
- BackGestureTutorialController controller =
- (BackGestureTutorialController) mTutorialController;
- float fingerDotStartTranslationX = (float) -(mRootView.getWidth() / 2);
-
- AnimatorSet fingerDotAppearanceAnimator = controller.createFingerDotAppearanceAnimatorSet();
- fingerDotAppearanceAnimator.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationStart(Animator animation) {
- super.onAnimationStart(animation);
- mFingerDotView.setTranslationX(fingerDotStartTranslationX);
- }
- });
-
- ObjectAnimator translationAnimator = ObjectAnimator.ofFloat(
- mFingerDotView, View.TRANSLATION_X, fingerDotStartTranslationX, 0);
- translationAnimator.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- super.onAnimationEnd(animation);
- controller.updateFakeAppTaskViewLayout(
- controller.getMockAppTaskPreviousPageLayoutResId());
- }
- });
- translationAnimator.setDuration(1000);
-
- Animator animationPause = controller.createAnimationPause();
- animationPause.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- super.onAnimationEnd(animation);
- controller.updateFakeAppTaskViewLayout(
- controller.getMockAppTaskCurrentPageLayoutResId());
- }
- });
- ArrayList<Animator> animators = new ArrayList<>();
-
- animators.add(fingerDotAppearanceAnimator);
- animators.add(translationAnimator);
- animators.add(controller.createFingerDotDisappearanceAnimatorSet());
- animators.add(animationPause);
-
- AnimatorSet finalAnimation = new AnimatorSet();
- finalAnimation.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationCancel(Animator animation) {
- super.onAnimationCancel(animation);
- controller.updateFakeAppTaskViewLayout(
- controller.getMockAppTaskCurrentPageLayoutResId());
- }
- });
- finalAnimation.playSequentially(animators);
-
- return finalAnimation;
+ Integer getGestureVideoResId() {
+ return R.drawable.gesture_tutorial_loop_back;
}
@Override
@@ -115,22 +49,9 @@ public class BackGestureTutorialFragment extends TutorialFragment {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
- releaseFeedbackAnimation();
if (motionEvent.getAction() == MotionEvent.ACTION_DOWN && mTutorialController != null) {
mTutorialController.setRippleHotspot(motionEvent.getX(), motionEvent.getY());
}
return super.onTouch(view, motionEvent);
}
-
- @Override
- void logTutorialStepShown(@NonNull StatsLogManager statsLogManager) {
- statsLogManager.logger().log(
- StatsLogManager.LauncherEvent.LAUNCHER_GESTURE_TUTORIAL_BACK_STEP_SHOWN);
- }
-
- @Override
- void logTutorialStepCompleted(@NonNull StatsLogManager statsLogManager) {
- statsLogManager.logger().log(
- StatsLogManager.LauncherEvent.LAUNCHER_GESTURE_TUTORIAL_BACK_STEP_COMPLETED);
- }
}
diff --git a/quickstep/src/com/android/quickstep/interaction/EdgeBackGestureHandler.java b/quickstep/src/com/android/quickstep/interaction/EdgeBackGestureHandler.java
index d059d828f8..c532f8e43d 100644
--- a/quickstep/src/com/android/quickstep/interaction/EdgeBackGestureHandler.java
+++ b/quickstep/src/com/android/quickstep/interaction/EdgeBackGestureHandler.java
@@ -31,7 +31,6 @@ import androidx.annotation.Nullable;
import com.android.launcher3.ResourceUtils;
import com.android.launcher3.Utilities;
-import com.android.launcher3.util.DisplayController;
/**
* Utility class to handle edge swipes for back gestures.
@@ -116,9 +115,10 @@ public class EdgeBackGestureHandler implements OnTouchListener {
// Add a nav bar panel window.
mEdgeBackPanel = new EdgeBackGesturePanel(mContext, parent, createLayoutParams());
mEdgeBackPanel.setBackCallback(mBackCallback);
- Point currentSize = DisplayController.INSTANCE.get(mContext).getInfo().currentSize;
- mDisplaySize.set(currentSize.x, currentSize.y);
- mEdgeBackPanel.setDisplaySize(mDisplaySize);
+ if (mContext.getDisplay() != null) {
+ mContext.getDisplay().getRealSize(mDisplaySize);
+ mEdgeBackPanel.setDisplaySize(mDisplaySize);
+ }
}
}
diff --git a/quickstep/src/com/android/quickstep/interaction/EdgeBackGesturePanel.java b/quickstep/src/com/android/quickstep/interaction/EdgeBackGesturePanel.java
index b2b2f59773..0521db4d1b 100644
--- a/quickstep/src/com/android/quickstep/interaction/EdgeBackGesturePanel.java
+++ b/quickstep/src/com/android/quickstep/interaction/EdgeBackGesturePanel.java
@@ -43,7 +43,7 @@ import androidx.dynamicanimation.animation.SpringForce;
import com.android.launcher3.R;
import com.android.launcher3.ResourceUtils;
import com.android.launcher3.anim.Interpolators;
-import com.android.quickstep.util.VibratorWrapper;
+import com.android.launcher3.util.VibratorWrapper;
/** Forked from platform/frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarEdgePanel.java. */
public class EdgeBackGesturePanel extends View {
@@ -282,7 +282,9 @@ public class EdgeBackGesturePanel extends View {
.setDampingRatio(SpringForce.DAMPING_RATIO_LOW_BOUNCY));
int currentNightMode =
context.getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK;
- mPaint.setColor(context.getColor(R.color.gesture_tutorial_back_arrow_color));
+ mPaint.setColor(context.getColor(currentNightMode == Configuration.UI_MODE_NIGHT_YES
+ ? R.color.back_arrow_color_light
+ : R.color.back_arrow_color_dark));
loadDimens();
updateArrowDirection();
diff --git a/quickstep/src/com/android/quickstep/interaction/GestureSandboxActivity.java b/quickstep/src/com/android/quickstep/interaction/GestureSandboxActivity.java
index bf7023c217..7fb7d2997e 100644
--- a/quickstep/src/com/android/quickstep/interaction/GestureSandboxActivity.java
+++ b/quickstep/src/com/android/quickstep/interaction/GestureSandboxActivity.java
@@ -15,7 +15,6 @@
*/
package com.android.quickstep.interaction;
-import android.content.SharedPreferences;
import android.graphics.Color;
import android.graphics.Rect;
import android.os.Bundle;
@@ -29,20 +28,17 @@ import androidx.annotation.NonNull;
import androidx.fragment.app.FragmentActivity;
import com.android.launcher3.R;
-import com.android.launcher3.Utilities;
-import com.android.launcher3.logging.StatsLogManager;
-import com.android.quickstep.TouchInteractionService.TISBinder;
import com.android.quickstep.interaction.TutorialController.TutorialType;
-import com.android.quickstep.util.TISBindHelper;
-import java.util.Arrays;
+import java.util.List;
/** Shows the gesture interactive sandbox in full screen mode. */
public class GestureSandboxActivity extends FragmentActivity {
+ private static final String LOG_TAG = "GestureSandboxActivity";
+
private static final String KEY_TUTORIAL_STEPS = "tutorial_steps";
private static final String KEY_CURRENT_STEP = "current_step";
- private static final String KEY_GESTURE_COMPLETE = "gesture_complete";
private TutorialType[] mTutorialSteps;
private TutorialType mCurrentTutorialStep;
@@ -51,31 +47,19 @@ public class GestureSandboxActivity extends FragmentActivity {
private int mCurrentStep;
private int mNumSteps;
- private SharedPreferences mSharedPrefs;
- private StatsLogManager mStatsLogManager;
-
- private TISBindHelper mTISBindHelper;
- private TISBinder mBinder;
-
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.gesture_tutorial_activity);
- mSharedPrefs = Utilities.getPrefs(this);
- mStatsLogManager = StatsLogManager.newInstance(getApplicationContext());
-
Bundle args = savedInstanceState == null ? getIntent().getExtras() : savedInstanceState;
mTutorialSteps = getTutorialSteps(args);
mCurrentTutorialStep = mTutorialSteps[mCurrentStep - 1];
- mFragment = TutorialFragment.newInstance(
- mCurrentTutorialStep, args.getBoolean(KEY_GESTURE_COMPLETE, false));
+ mFragment = TutorialFragment.newInstance(mCurrentTutorialStep);
getSupportFragmentManager().beginTransaction()
.add(R.id.gesture_tutorial_fragment_container, mFragment)
.commit();
-
- mTISBindHelper = new TISBindHelper(this, this::onTISConnected);
}
@Override
@@ -103,18 +87,9 @@ public class GestureSandboxActivity extends FragmentActivity {
protected void onSaveInstanceState(@NonNull Bundle savedInstanceState) {
savedInstanceState.putStringArray(KEY_TUTORIAL_STEPS, getTutorialStepNames());
savedInstanceState.putInt(KEY_CURRENT_STEP, mCurrentStep);
- savedInstanceState.putBoolean(KEY_GESTURE_COMPLETE, mFragment.isGestureComplete());
super.onSaveInstanceState(savedInstanceState);
}
- protected SharedPreferences getSharedPrefs() {
- return mSharedPrefs;
- }
-
- protected StatsLogManager getStatsLogManager() {
- return mStatsLogManager;
- }
-
/** Returns true iff there aren't anymore tutorial types to display to the user. */
public boolean isTutorialComplete() {
return mCurrentStep >= mNumSteps;
@@ -129,6 +104,13 @@ public class GestureSandboxActivity extends FragmentActivity {
}
/**
+ * Closes the tutorial and this activity.
+ */
+ public void closeTutorial() {
+ mFragment.closeTutorial();
+ }
+
+ /**
* Replaces the current TutorialFragment, continuing to the next tutorial step if there is one.
*
* If there is no following step, the tutorial is closed.
@@ -139,8 +121,7 @@ public class GestureSandboxActivity extends FragmentActivity {
return;
}
mCurrentTutorialStep = mTutorialSteps[mCurrentStep];
- mFragment = TutorialFragment.newInstance(
- mCurrentTutorialStep, /* gestureComplete= */ false);
+ mFragment = TutorialFragment.newInstance(mCurrentTutorialStep);
getSupportFragmentManager().beginTransaction()
.replace(R.id.gesture_tutorial_fragment_container, mFragment)
.runOnCommit(() -> mFragment.onAttachedToWindow())
@@ -213,37 +194,7 @@ public class GestureSandboxActivity extends FragmentActivity {
DisplayMetrics metrics = new DisplayMetrics();
display.getMetrics(metrics);
getWindow().setSystemGestureExclusionRects(
- Arrays.asList(new Rect(0, 0, metrics.widthPixels, metrics.heightPixels)));
+ List.of(new Rect(0, 0, metrics.widthPixels, metrics.heightPixels)));
}
}
-
- @Override
- protected void onResume() {
- super.onResume();
- updateServiceState(true);
- }
-
- private void onTISConnected(TISBinder binder) {
- mBinder = binder;
- updateServiceState(isResumed());
- }
-
- @Override
- protected void onPause() {
- super.onPause();
- updateServiceState(false);
- }
-
- private void updateServiceState(boolean isEnabled) {
- if (mBinder != null) {
- mBinder.setGestureBlockedTaskId(isEnabled ? getTaskId() : -1);
- }
- }
-
- @Override
- protected void onDestroy() {
- super.onDestroy();
- mTISBindHelper.onDestroy();
- updateServiceState(false);
- }
}
diff --git a/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialController.java b/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialController.java
index f519d50613..819c91c55b 100644
--- a/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialController.java
+++ b/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialController.java
@@ -32,37 +32,23 @@ final class HomeGestureTutorialController extends SwipeUpGestureTutorialControll
}
@Override
- public int getIntroductionTitle() {
+ public Integer getIntroductionTitle() {
return R.string.home_gesture_intro_title;
}
@Override
- public int getIntroductionSubtitle() {
+ public Integer getIntroductionSubtitle() {
return R.string.home_gesture_intro_subtitle;
}
@Override
- public int getSpokenIntroductionSubtitle() {
- return R.string.home_gesture_spoken_intro_subtitle;
- }
-
- @Override
- public int getSuccessFeedbackSubtitle() {
- return mTutorialFragment.isAtFinalStep()
- ? R.string.home_gesture_feedback_complete_without_follow_up
- : R.string.home_gesture_feedback_complete_with_follow_up;
- }
-
- @Override
- protected int getMockAppTaskLayoutResId() {
- return mTutorialFragment.isLargeScreen()
- ? R.layout.gesture_tutorial_tablet_mock_webpage
- : R.layout.gesture_tutorial_mock_webpage;
+ protected int getMockAppTaskThumbnailResId(boolean forDarkMode) {
+ return forDarkMode ? R.drawable.mock_webpage_dark_mode : R.drawable.mock_webpage_light_mode;
}
@Override
public void onBackGestureAttempted(BackGestureResult result) {
- if (isGestureCompleted()) {
+ if (mGestureCompleted) {
return;
}
switch (mTutorialType) {
@@ -87,16 +73,19 @@ final class HomeGestureTutorialController extends SwipeUpGestureTutorialControll
@Override
public void onNavBarGestureAttempted(NavBarGestureResult result, PointF finalVelocity) {
- if (isGestureCompleted()) {
+ if (mGestureCompleted) {
return;
}
switch (mTutorialType) {
case HOME_NAVIGATION:
switch (result) {
case HOME_GESTURE_COMPLETED: {
- mTutorialFragment.releaseFeedbackAnimation();
+ mTutorialFragment.releaseGestureVideoView();
animateFakeTaskViewHome(finalVelocity, null);
- showSuccessFeedback();
+ int subtitleResId = mTutorialFragment.isAtFinalStep()
+ ? R.string.home_gesture_feedback_complete_without_follow_up
+ : R.string.home_gesture_feedback_complete_with_follow_up;
+ showFeedback(subtitleResId, true);
break;
}
case HOME_NOT_STARTED_TOO_FAR_FROM_EDGE:
@@ -104,10 +93,8 @@ final class HomeGestureTutorialController extends SwipeUpGestureTutorialControll
showFeedback(R.string.home_gesture_feedback_swipe_too_far_from_edge);
break;
case OVERVIEW_GESTURE_COMPLETED:
- fadeOutFakeTaskView(true, true, () -> {
- showFeedback(R.string.home_gesture_feedback_overview_detected);
- showFakeTaskbar(/* animateFromHotseat= */ false);
- });
+ fadeOutFakeTaskView(true, true, () ->
+ showFeedback(R.string.home_gesture_feedback_overview_detected));
break;
case HOME_OR_OVERVIEW_NOT_STARTED_WRONG_SWIPE_DIRECTION:
case HOME_OR_OVERVIEW_CANCELLED:
diff --git a/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialFragment.java b/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialFragment.java
index 95eafdae33..9572637b0f 100644
--- a/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialFragment.java
+++ b/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialFragment.java
@@ -15,77 +15,25 @@
*/
package com.android.quickstep.interaction;
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.AnimatorSet;
-import android.view.MotionEvent;
-import android.view.View;
-
-import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.android.launcher3.R;
-import com.android.launcher3.logging.StatsLogManager;
import com.android.quickstep.interaction.TutorialController.TutorialType;
-import java.util.ArrayList;
-
/** Shows the Home gesture interactive tutorial. */
public class HomeGestureTutorialFragment extends TutorialFragment {
-
- public HomeGestureTutorialFragment() {}
-
@Nullable
@Override
- Integer getEdgeAnimationResId() {
- return R.drawable.gesture_tutorial_loop_home;
+ Integer getFeedbackVideoResId(boolean forDarkMode) {
+ return forDarkMode
+ ? R.drawable.gesture_tutorial_motion_home_dark_mode
+ : R.drawable.gesture_tutorial_motion_home_light_mode;
}
@Nullable
@Override
- protected Animator createGestureAnimation() {
- if (!(mTutorialController instanceof HomeGestureTutorialController)) {
- return null;
- }
- float fingerDotStartTranslationY = (float) mRootView.getFullscreenHeight() / 2;
- HomeGestureTutorialController controller =
- (HomeGestureTutorialController) mTutorialController;
-
- AnimatorSet fingerDotAppearanceAnimator = controller.createFingerDotAppearanceAnimatorSet();
- fingerDotAppearanceAnimator.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationStart(Animator animation) {
- super.onAnimationStart(animation);
- mFingerDotView.setTranslationY(fingerDotStartTranslationY);
- }
- });
-
- Animator animationPause = controller.createAnimationPause();
- animationPause.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- super.onAnimationEnd(animation);
- controller.resetFakeTaskView(true);
- }
- });
- ArrayList<Animator> animators = new ArrayList<>();
-
- animators.add(fingerDotAppearanceAnimator);
- animators.add(controller.createFingerDotHomeSwipeAnimator(fingerDotStartTranslationY));
- animators.add(controller.createFingerDotDisappearanceAnimatorSet());
- animators.add(animationPause);
-
- AnimatorSet finalAnimation = new AnimatorSet();
- finalAnimation.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationCancel(Animator animation) {
- super.onAnimationCancel(animation);
- controller.resetFakeTaskView(true);
- }
- });
- finalAnimation.playSequentially(animators);
-
- return finalAnimation;
+ Integer getGestureVideoResId() {
+ return R.drawable.gesture_tutorial_loop_home;
}
@Override
@@ -97,22 +45,4 @@ public class HomeGestureTutorialFragment extends TutorialFragment {
Class<? extends TutorialController> getControllerClass() {
return HomeGestureTutorialController.class;
}
-
- @Override
- public boolean onTouch(View view, MotionEvent motionEvent) {
- releaseFeedbackAnimation();
- return super.onTouch(view, motionEvent);
- }
-
- @Override
- void logTutorialStepShown(@NonNull StatsLogManager statsLogManager) {
- statsLogManager.logger().log(
- StatsLogManager.LauncherEvent.LAUNCHER_GESTURE_TUTORIAL_HOME_STEP_SHOWN);
- }
-
- @Override
- void logTutorialStepCompleted(@NonNull StatsLogManager statsLogManager) {
- statsLogManager.logger().log(
- StatsLogManager.LauncherEvent.LAUNCHER_GESTURE_TUTORIAL_HOME_STEP_COMPLETED);
- }
}
diff --git a/quickstep/src/com/android/quickstep/interaction/NavBarGestureHandler.java b/quickstep/src/com/android/quickstep/interaction/NavBarGestureHandler.java
index f9818600cf..a9a9e2a104 100644
--- a/quickstep/src/com/android/quickstep/interaction/NavBarGestureHandler.java
+++ b/quickstep/src/com/android/quickstep/interaction/NavBarGestureHandler.java
@@ -16,6 +16,7 @@
package com.android.quickstep.interaction;
import static com.android.launcher3.Utilities.squaredHypot;
+import static com.android.launcher3.util.VibratorWrapper.OVERVIEW_HAPTIC;
import static com.android.quickstep.interaction.NavBarGestureHandler.NavBarGestureResult.ASSISTANT_COMPLETED;
import static com.android.quickstep.interaction.NavBarGestureHandler.NavBarGestureResult.ASSISTANT_NOT_STARTED_BAD_ANGLE;
import static com.android.quickstep.interaction.NavBarGestureHandler.NavBarGestureResult.ASSISTANT_NOT_STARTED_SWIPE_TOO_SHORT;
@@ -25,7 +26,6 @@ import static com.android.quickstep.interaction.NavBarGestureHandler.NavBarGestu
import static com.android.quickstep.interaction.NavBarGestureHandler.NavBarGestureResult.HOME_OR_OVERVIEW_NOT_STARTED_WRONG_SWIPE_DIRECTION;
import static com.android.quickstep.interaction.NavBarGestureHandler.NavBarGestureResult.OVERVIEW_GESTURE_COMPLETED;
import static com.android.quickstep.interaction.NavBarGestureHandler.NavBarGestureResult.OVERVIEW_NOT_STARTED_TOO_FAR_FROM_EDGE;
-import static com.android.quickstep.util.VibratorWrapper.OVERVIEW_HAPTIC;
import android.animation.ValueAnimator;
import android.content.Context;
@@ -37,6 +37,7 @@ import android.os.SystemClock;
import android.view.Display;
import android.view.GestureDetector;
import android.view.MotionEvent;
+import android.view.Surface;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.ViewConfiguration;
@@ -46,12 +47,11 @@ import androidx.annotation.Nullable;
import com.android.launcher3.R;
import com.android.launcher3.ResourceUtils;
import com.android.launcher3.anim.Interpolators;
-import com.android.launcher3.util.DisplayController;
-import com.android.launcher3.util.DisplayController.NavigationMode;
+import com.android.launcher3.util.VibratorWrapper;
+import com.android.quickstep.SysUINavigationMode.Mode;
import com.android.quickstep.util.MotionPauseDetector;
import com.android.quickstep.util.NavBarPosition;
import com.android.quickstep.util.TriggerSwipeUpTouchTracker;
-import com.android.quickstep.util.VibratorWrapper;
import com.android.systemui.shared.system.QuickStepContract;
/** Utility class to handle Home and Assistant gestures. */
@@ -92,13 +92,16 @@ public class NavBarGestureHandler implements OnTouchListener,
NavBarGestureHandler(Context context) {
mContext = context;
final Display display = mContext.getDisplay();
- DisplayController.Info displayInfo = DisplayController.INSTANCE.get(mContext).getInfo();
- final int displayRotation = displayInfo.rotation;
- Point currentSize = displayInfo.currentSize;
- mDisplaySize.set(currentSize.x, currentSize.y);
+ final int displayRotation;
+ if (display == null) {
+ displayRotation = Surface.ROTATION_0;
+ } else {
+ displayRotation = display.getRotation();
+ display.getRealSize(mDisplaySize);
+ }
mSwipeUpTouchTracker =
new TriggerSwipeUpTouchTracker(context, true /*disableHorizontalSwipe*/,
- new NavBarPosition(NavigationMode.NO_BUTTON, displayRotation),
+ new NavBarPosition(Mode.NO_BUTTON, displayRotation),
null /*onInterceptTouch*/, this);
mMotionPauseDetector = new MotionPauseDetector(context);
@@ -117,7 +120,7 @@ public class NavBarGestureHandler implements OnTouchListener,
mAssistantGestureDetector = new GestureDetector(context, new AssistantGestureListener());
int assistantWidth = resources.getDimensionPixelSize(R.dimen.gestures_assistant_width);
final float assistantHeight = Math.max(mBottomGestureHeight,
- QuickStepContract.getWindowCornerRadius(context));
+ QuickStepContract.getWindowCornerRadius(resources));
mAssistantLeftRegion.bottom = mAssistantRightRegion.bottom = mDisplaySize.y;
mAssistantLeftRegion.top = mAssistantRightRegion.top = mDisplaySize.y - assistantHeight;
mAssistantLeftRegion.left = 0;
diff --git a/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialController.java b/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialController.java
index 6b016cee13..77ddb2b320 100644
--- a/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialController.java
+++ b/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialController.java
@@ -17,7 +17,6 @@ package com.android.quickstep.interaction;
import static com.android.launcher3.anim.Interpolators.ACCEL;
-import android.animation.Animator;
import android.animation.AnimatorSet;
import android.annotation.TargetApi;
import android.graphics.PointF;
@@ -30,8 +29,6 @@ import com.android.quickstep.SwipeUpAnimationLogic;
import com.android.quickstep.interaction.EdgeBackGestureHandler.BackGestureResult;
import com.android.quickstep.interaction.NavBarGestureHandler.NavBarGestureResult;
-import java.util.ArrayList;
-
/** A {@link TutorialController} for the Overview tutorial. */
@TargetApi(Build.VERSION_CODES.R)
final class OverviewGestureTutorialController extends SwipeUpGestureTutorialController {
@@ -42,37 +39,23 @@ final class OverviewGestureTutorialController extends SwipeUpGestureTutorialCont
}
@Override
- public int getIntroductionTitle() {
+ public Integer getIntroductionTitle() {
return R.string.overview_gesture_intro_title;
}
@Override
- public int getIntroductionSubtitle() {
+ public Integer getIntroductionSubtitle() {
return R.string.overview_gesture_intro_subtitle;
}
@Override
- public int getSpokenIntroductionSubtitle() {
- return R.string.overview_gesture_spoken_intro_subtitle;
- }
-
- @Override
- public int getSuccessFeedbackSubtitle() {
- return mTutorialFragment.getNumSteps() > 1 && mTutorialFragment.isAtFinalStep()
- ? R.string.overview_gesture_feedback_complete_with_follow_up
- : R.string.overview_gesture_feedback_complete_without_follow_up;
- }
-
- @Override
- protected int getMockAppTaskLayoutResId() {
- return mTutorialFragment.isLargeScreen()
- ? R.layout.gesture_tutorial_tablet_mock_conversation_list
- : R.layout.gesture_tutorial_mock_conversation_list;
+ protected int getMockAppTaskThumbnailResId(boolean forDarkMode) {
+ return R.drawable.mock_conversations_list;
}
@Override
public void onBackGestureAttempted(BackGestureResult result) {
- if (isGestureCompleted()) {
+ if (mGestureCompleted) {
return;
}
switch (mTutorialType) {
@@ -97,7 +80,7 @@ final class OverviewGestureTutorialController extends SwipeUpGestureTutorialCont
@Override
public void onNavBarGestureAttempted(NavBarGestureResult result, PointF finalVelocity) {
- if (isGestureCompleted()) {
+ if (mGestureCompleted) {
return;
}
switch (mTutorialType) {
@@ -105,8 +88,8 @@ final class OverviewGestureTutorialController extends SwipeUpGestureTutorialCont
switch (result) {
case HOME_GESTURE_COMPLETED: {
animateFakeTaskViewHome(finalVelocity, () -> {
+ resetFakeTaskView();
showFeedback(R.string.overview_gesture_feedback_home_detected);
- resetFakeTaskView(true);
});
break;
}
@@ -115,10 +98,19 @@ final class OverviewGestureTutorialController extends SwipeUpGestureTutorialCont
showFeedback(R.string.overview_gesture_feedback_swipe_too_far_from_edge);
break;
case OVERVIEW_GESTURE_COMPLETED:
- mTutorialFragment.releaseFeedbackAnimation();
- animateTaskViewToOverview();
+ mTutorialFragment.releaseGestureVideoView();
+ PendingAnimation anim = new PendingAnimation(300);
+ anim.setFloat(mTaskViewSwipeUpAnimation
+ .getCurrentShift(), AnimatedFloat.VALUE, 1, ACCEL);
+ AnimatorSet animset = anim.buildAnim();
+ animset.start();
+ mRunningWindowAnim = SwipeUpAnimationLogic.RunningWindowAnim.wrap(animset);
onMotionPaused(true /*arbitrary value*/);
- showSuccessFeedback();
+ int subtitleResId = mTutorialFragment.getNumSteps() > 1
+ && mTutorialFragment.isAtFinalStep()
+ ? R.string.overview_gesture_feedback_complete_with_follow_up
+ : R.string.overview_gesture_feedback_complete_without_follow_up;
+ showFeedback(subtitleResId, true);
break;
case HOME_OR_OVERVIEW_NOT_STARTED_WRONG_SWIPE_DIRECTION:
case HOME_OR_OVERVIEW_CANCELLED:
@@ -134,28 +126,4 @@ final class OverviewGestureTutorialController extends SwipeUpGestureTutorialCont
break;
}
}
-
- public void animateTaskViewToOverview() {
- PendingAnimation anim = new PendingAnimation(TASK_VIEW_END_ANIMATION_DURATION_MILLIS);
- anim.setFloat(mTaskViewSwipeUpAnimation
- .getCurrentShift(), AnimatedFloat.VALUE, 1, ACCEL);
-
- ArrayList<Animator> animators = new ArrayList<>();
-
- if (mTutorialFragment.isLargeScreen()) {
- Animator multiRowAnimation = mFakePreviousTaskView.createAnimationToMultiRowLayout();
-
- if (multiRowAnimation != null) {
- multiRowAnimation.setDuration(TASK_VIEW_END_ANIMATION_DURATION_MILLIS);
- animators.add(multiRowAnimation);
- }
- }
- animators.add(anim.buildAnim());
-
- AnimatorSet animset = new AnimatorSet();
- animset.playTogether(animators);
- hideFakeTaskbar(/* animateToHotseat= */ false);
- animset.start();
- mRunningWindowAnim = SwipeUpAnimationLogic.RunningWindowAnim.wrap(animset);
- }
}
diff --git a/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialFragment.java b/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialFragment.java
index 4e1521f161..d2ec327c81 100644
--- a/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialFragment.java
+++ b/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialFragment.java
@@ -15,89 +15,25 @@
*/
package com.android.quickstep.interaction;
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.AnimatorSet;
-import android.view.MotionEvent;
-import android.view.View;
-
-import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.android.launcher3.R;
-import com.android.launcher3.logging.StatsLogManager;
import com.android.quickstep.interaction.TutorialController.TutorialType;
-import java.util.ArrayList;
-
/** Shows the Overview gesture interactive tutorial. */
public class OverviewGestureTutorialFragment extends TutorialFragment {
-
- public OverviewGestureTutorialFragment() {}
-
@Nullable
@Override
- Integer getEdgeAnimationResId() {
- return R.drawable.gesture_tutorial_loop_overview;
+ Integer getFeedbackVideoResId(boolean forDarkMode) {
+ return forDarkMode
+ ? R.drawable.gesture_tutorial_motion_overview_dark_mode
+ : R.drawable.gesture_tutorial_motion_overview_light_mode;
}
@Nullable
@Override
- protected Animator createGestureAnimation() {
- if (!(mTutorialController instanceof OverviewGestureTutorialController)) {
- return null;
- }
- float fingerDotStartTranslationY = (float) mRootView.getFullscreenHeight() / 2;
- OverviewGestureTutorialController controller =
- (OverviewGestureTutorialController) mTutorialController;
-
- AnimatorSet fingerDotAppearanceAnimator = controller.createFingerDotAppearanceAnimatorSet();
- fingerDotAppearanceAnimator.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationStart(Animator animation) {
- super.onAnimationStart(animation);
-
- mFingerDotView.setTranslationY(fingerDotStartTranslationY);
- }
- });
-
- AnimatorSet fingerDotDisappearanceAnimator =
- controller.createFingerDotDisappearanceAnimatorSet();
- fingerDotDisappearanceAnimator.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationStart(Animator animation) {
- super.onAnimationStart(animation);
- controller.animateTaskViewToOverview();
- }
- });
-
- Animator animationPause = controller.createAnimationPause();
- animationPause.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- super.onAnimationEnd(animation);
- controller.resetFakeTaskView(false);
- }
- });
- ArrayList<Animator> animators = new ArrayList<>();
-
- animators.add(fingerDotAppearanceAnimator);
- animators.add(controller.createFingerDotOverviewSwipeAnimator(fingerDotStartTranslationY));
- animators.add(controller.createAnimationPause());
- animators.add(fingerDotDisappearanceAnimator);
- animators.add(animationPause);
-
- AnimatorSet finalAnimation = new AnimatorSet();
- finalAnimation.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationCancel(Animator animation) {
- super.onAnimationCancel(animation);
- controller.resetFakeTaskView(false);
- }
- });
- finalAnimation.playSequentially(animators);
-
- return finalAnimation;
+ Integer getGestureVideoResId() {
+ return R.drawable.gesture_tutorial_loop_overview;
}
@Override
@@ -109,22 +45,4 @@ public class OverviewGestureTutorialFragment extends TutorialFragment {
Class<? extends TutorialController> getControllerClass() {
return OverviewGestureTutorialController.class;
}
-
- @Override
- public boolean onTouch(View view, MotionEvent motionEvent) {
- releaseFeedbackAnimation();
- return super.onTouch(view, motionEvent);
- }
-
- @Override
- void logTutorialStepShown(@NonNull StatsLogManager statsLogManager) {
- statsLogManager.logger().log(
- StatsLogManager.LauncherEvent.LAUNCHER_GESTURE_TUTORIAL_OVERVIEW_STEP_SHOWN);
- }
-
- @Override
- void logTutorialStepCompleted(@NonNull StatsLogManager statsLogManager) {
- statsLogManager.logger().log(
- StatsLogManager.LauncherEvent.LAUNCHER_GESTURE_TUTORIAL_OVERVIEW_STEP_COMPLETED);
- }
}
diff --git a/quickstep/src/com/android/quickstep/interaction/RootSandboxLayout.java b/quickstep/src/com/android/quickstep/interaction/RootSandboxLayout.java
index ac0c17d72f..db1afc2012 100644
--- a/quickstep/src/com/android/quickstep/interaction/RootSandboxLayout.java
+++ b/quickstep/src/com/android/quickstep/interaction/RootSandboxLayout.java
@@ -16,10 +16,8 @@
package com.android.quickstep.interaction;
import android.content.Context;
-import android.graphics.Insets;
import android.util.AttributeSet;
import android.view.MotionEvent;
-import android.view.WindowInsets;
import android.widget.RelativeLayout;
import androidx.fragment.app.FragmentManager;
@@ -43,13 +41,4 @@ public class RootSandboxLayout extends RelativeLayout {
return ((TutorialFragment) FragmentManager.findFragment(this))
.onInterceptTouch(motionEvent);
}
-
- /**
- * Returns this view's fullscreen height. This method is agnostic of this view's actual height.
- */
- public int getFullscreenHeight() {
- Insets insets = getRootWindowInsets().getInsets(WindowInsets.Type.systemBars());
-
- return getHeight() + insets.top + insets.bottom;
- }
}
diff --git a/quickstep/src/com/android/quickstep/interaction/SandboxModeTutorialFragment.java b/quickstep/src/com/android/quickstep/interaction/SandboxModeTutorialFragment.java
index 5183e2c961..955a2f7d2e 100644
--- a/quickstep/src/com/android/quickstep/interaction/SandboxModeTutorialFragment.java
+++ b/quickstep/src/com/android/quickstep/interaction/SandboxModeTutorialFragment.java
@@ -18,16 +18,11 @@ package com.android.quickstep.interaction;
import android.view.MotionEvent;
import android.view.View;
-import androidx.annotation.NonNull;
-
-import com.android.launcher3.logging.StatsLogManager;
import com.android.quickstep.interaction.TutorialController.TutorialType;
/** Shows the general navigation gesture sandbox environment. */
public class SandboxModeTutorialFragment extends TutorialFragment {
- public SandboxModeTutorialFragment() {}
-
@Override
TutorialController createController(TutorialType type) {
return new SandboxModeTutorialController(this, type);
@@ -45,14 +40,4 @@ public class SandboxModeTutorialFragment extends TutorialFragment {
}
return super.onTouch(view, motionEvent);
}
-
- @Override
- void logTutorialStepShown(@NonNull StatsLogManager statsLogManager) {
- // No-Op: tutorial step not currently shown to users
- }
-
- @Override
- void logTutorialStepCompleted(@NonNull StatsLogManager statsLogManager) {
- // No-Op: tutorial step not currently shown to users
- }
}
diff --git a/quickstep/src/com/android/quickstep/interaction/SwipeUpGestureTutorialController.java b/quickstep/src/com/android/quickstep/interaction/SwipeUpGestureTutorialController.java
index b70c411196..b2183d62dc 100644
--- a/quickstep/src/com/android/quickstep/interaction/SwipeUpGestureTutorialController.java
+++ b/quickstep/src/com/android/quickstep/interaction/SwipeUpGestureTutorialController.java
@@ -16,7 +16,7 @@
package com.android.quickstep.interaction;
import static com.android.launcher3.anim.Interpolators.ACCEL;
-import static com.android.launcher3.util.window.RefreshRateTracker.getSingleFrameMs;
+import static com.android.launcher3.util.DisplayController.getSingleFrameMs;
import static com.android.launcher3.views.FloatingIconView.SHAPE_PROGRESS_DURATION;
import static com.android.quickstep.AbsSwipeUpHandler.MAX_SWIPE_DURATION;
import static com.android.quickstep.interaction.TutorialController.TutorialType.HOME_NAVIGATION_COMPLETE;
@@ -25,7 +25,6 @@ import static com.android.quickstep.interaction.TutorialController.TutorialType.
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
-import android.animation.ValueAnimator;
import android.annotation.TargetApi;
import android.content.Context;
import android.graphics.Outline;
@@ -33,6 +32,7 @@ import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.RectF;
import android.os.Build;
+import android.util.DisplayMetrics;
import android.view.SurfaceControl;
import android.view.View;
import android.view.ViewOutlineProvider;
@@ -50,9 +50,9 @@ import com.android.quickstep.AnimatedFloat;
import com.android.quickstep.GestureState;
import com.android.quickstep.OverviewComponentObserver;
import com.android.quickstep.RecentsAnimationDeviceState;
-import com.android.quickstep.RemoteTargetGluer;
import com.android.quickstep.SwipeUpAnimationLogic;
import com.android.quickstep.SwipeUpAnimationLogic.RunningWindowAnim;
+import com.android.quickstep.util.AppCloseConfig;
import com.android.quickstep.util.RectFSpringAnim;
import com.android.quickstep.util.TransformParams;
import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat.SurfaceParams;
@@ -62,25 +62,23 @@ abstract class SwipeUpGestureTutorialController extends TutorialController {
private static final int FAKE_PREVIOUS_TASK_MARGIN = Utilities.dpToPx(12);
- protected static final long TASK_VIEW_END_ANIMATION_DURATION_MILLIS = 300;
- private static final long HOME_SWIPE_ANIMATION_DURATION_MILLIS = 625;
- private static final long OVERVIEW_SWIPE_ANIMATION_DURATION_MILLIS = 1000;
-
final ViewSwipeUpAnimation mTaskViewSwipeUpAnimation;
private float mFakeTaskViewRadius;
- private final Rect mFakeTaskViewRect = new Rect();
+ private Rect mFakeTaskViewRect = new Rect();
RunningWindowAnim mRunningWindowAnim;
private boolean mShowTasks = false;
private boolean mShowPreviousTasks = false;
- private final AnimatorListenerAdapter mResetTaskView = new AnimatorListenerAdapter() {
+ private AnimatorListenerAdapter mResetTaskView = new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
mFakeHotseatView.setVisibility(View.INVISIBLE);
mFakeIconView.setVisibility(View.INVISIBLE);
if (mTutorialFragment.getActivity() != null) {
- int height = mTutorialFragment.getRootView().getFullscreenHeight();
- int width = mTutorialFragment.getRootView().getWidth();
+ DisplayMetrics displayMetrics =
+ mTutorialFragment.getResources().getDisplayMetrics();
+ int height = displayMetrics.heightPixels;
+ int width = displayMetrics.widthPixels;
mFakeTaskViewRect.set(0, 0, width, height);
}
mFakeTaskViewRadius = 0;
@@ -89,7 +87,6 @@ abstract class SwipeUpGestureTutorialController extends TutorialController {
mFakeTaskView.setAlpha(1);
mFakePreviousTaskView.setVisibility(View.INVISIBLE);
mFakePreviousTaskView.setAlpha(1);
- mFakePreviousTaskView.setToSingleRowLayout(false);
mShowTasks = false;
mShowPreviousTasks = false;
mRunningWindowAnim = null;
@@ -110,8 +107,9 @@ abstract class SwipeUpGestureTutorialController extends TutorialController {
.copy(mContext);
mTaskViewSwipeUpAnimation.initDp(dp);
- int height = mTutorialFragment.getRootView().getFullscreenHeight();
- int width = mTutorialFragment.getRootView().getWidth();
+ DisplayMetrics displayMetrics = mContext.getResources().getDisplayMetrics();
+ int height = displayMetrics.heightPixels;
+ int width = displayMetrics.widthPixels;
mFakeTaskViewRect.set(0, 0, width, height);
mFakeTaskViewRadius = 0;
@@ -139,6 +137,7 @@ abstract class SwipeUpGestureTutorialController extends TutorialController {
/** Fades the task view, optionally after animating to a fake Overview. */
void fadeOutFakeTaskView(boolean toOverviewFirst, boolean reset,
@Nullable Runnable onEndRunnable) {
+ hideFeedback(true);
cancelRunningAnimation();
PendingAnimation anim = new PendingAnimation(300);
if (toOverviewFirst) {
@@ -147,8 +146,7 @@ abstract class SwipeUpGestureTutorialController extends TutorialController {
anim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation, boolean isReverse) {
- PendingAnimation fadeAnim =
- new PendingAnimation(TASK_VIEW_END_ANIMATION_DURATION_MILLIS);
+ PendingAnimation fadeAnim = new PendingAnimation(300);
if (reset) {
fadeAnim.setFloat(mTaskViewSwipeUpAnimation
.getCurrentShift(), AnimatedFloat.VALUE, 0, ACCEL);
@@ -161,23 +159,6 @@ abstract class SwipeUpGestureTutorialController extends TutorialController {
fadeAnim.addListener(AnimatorListeners.forSuccessCallback(onEndRunnable));
}
AnimatorSet animset = fadeAnim.buildAnim();
-
- if (reset && mTutorialFragment.isLargeScreen()) {
- animset.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationStart(Animator animation) {
- super.onAnimationStart(animation);
- Animator multiRowAnimation =
- mFakePreviousTaskView.createAnimationToMultiRowLayout();
-
- if (multiRowAnimation != null) {
- multiRowAnimation.setDuration(
- TASK_VIEW_END_ANIMATION_DURATION_MILLIS).start();
- }
- }
- });
- }
-
animset.setStartDelay(100);
animset.start();
mRunningWindowAnim = RunningWindowAnim.wrap(animset);
@@ -197,27 +178,24 @@ abstract class SwipeUpGestureTutorialController extends TutorialController {
}
}
AnimatorSet animset = anim.buildAnim();
- hideFakeTaskbar(/* animateToHotseat= */ false);
animset.start();
mRunningWindowAnim = RunningWindowAnim.wrap(animset);
}
- void resetFakeTaskView(boolean animateFromHome) {
- mFakeTaskView.setVisibility(View.VISIBLE);
+ void resetFakeTaskView() {
PendingAnimation anim = new PendingAnimation(300);
anim.setFloat(mTaskViewSwipeUpAnimation
.getCurrentShift(), AnimatedFloat.VALUE, 0, ACCEL);
anim.setViewAlpha(mFakeTaskView, 1, ACCEL);
anim.addListener(mResetTaskView);
AnimatorSet animset = anim.buildAnim();
- showFakeTaskbar(animateFromHome);
animset.start();
mRunningWindowAnim = RunningWindowAnim.wrap(animset);
}
void animateFakeTaskViewHome(PointF finalVelocity, @Nullable Runnable onEndRunnable) {
+ hideFeedback(true);
cancelRunningAnimation();
- hideFakeTaskbar(/* animateToHotseat= */ true);
mFakePreviousTaskView.setVisibility(View.INVISIBLE);
mFakeHotseatView.setVisibility(View.VISIBLE);
mShowPreviousTasks = false;
@@ -236,9 +214,12 @@ abstract class SwipeUpGestureTutorialController extends TutorialController {
@Override
public void setNavBarGestureProgress(@Nullable Float displacement) {
- if (isGestureCompleted()) {
+ if (mGestureCompleted) {
return;
}
+ if (displacement != null) {
+ hideFeedback(true);
+ }
if (mTutorialType == HOME_NAVIGATION_COMPLETE
|| mTutorialType == OVERVIEW_NAVIGATION_COMPLETE) {
mFakeTaskView.setVisibility(View.INVISIBLE);
@@ -257,7 +238,7 @@ abstract class SwipeUpGestureTutorialController extends TutorialController {
@Override
public void onMotionPaused(boolean unused) {
- if (isGestureCompleted()) {
+ if (mGestureCompleted) {
return;
}
if (mShowTasks) {
@@ -277,32 +258,19 @@ abstract class SwipeUpGestureTutorialController extends TutorialController {
ViewSwipeUpAnimation(Context context, RecentsAnimationDeviceState deviceState,
GestureState gestureState) {
- super(context, deviceState, gestureState);
- mRemoteTargetHandles[0] = new RemoteTargetGluer.RemoteTargetHandle(
- mRemoteTargetHandles[0].getTaskViewSimulator(), new FakeTransformParams());
-
- for (RemoteTargetGluer.RemoteTargetHandle handle
- : mTargetGluer.getRemoteTargetHandles()) {
- // Override home screen rotation preference so that home and overview animations
- // work properly
- handle.getTaskViewSimulator()
- .getOrientationState()
- .ignoreAllowHomeRotationPreference();
- }
+ super(context, deviceState, gestureState, new FakeTransformParams());
}
void initDp(DeviceProfile dp) {
initTransitionEndpoints(dp);
- mRemoteTargetHandles[0].getTaskViewSimulator().setPreviewBounds(
+ mTaskViewSimulator.setPreviewBounds(
new Rect(0, 0, dp.widthPx, dp.heightPx), dp.getInsets());
}
@Override
public void updateFinalShift() {
- mRemoteTargetHandles[0].getPlaybackController()
- .setProgress(mCurrentShift.value, mDragLengthFactor);
- mRemoteTargetHandles[0].getTaskViewSimulator().apply(
- mRemoteTargetHandles[0].getTransformParams());
+ mWindowTransitionController.setProgress(mCurrentShift.value, mDragLengthFactor);
+ mTaskViewSimulator.apply(mTransformParams);
}
AnimatedFloat getCurrentShift() {
@@ -331,21 +299,23 @@ abstract class SwipeUpGestureTutorialController extends TutorialController {
@Override
public RectF getWindowTargetRect() {
int fakeHomeIconSizePx = Utilities.dpToPx(60);
- int fakeHomeIconLeft = getHotseatIconLeft();
- int fakeHomeIconTop = getHotseatIconTop();
+ int fakeHomeIconLeft = mFakeHotseatView.getLeft();
+ int fakeHomeIconTop = mDp.heightPx - Utilities.dpToPx(216);
return new RectF(fakeHomeIconLeft, fakeHomeIconTop,
fakeHomeIconLeft + fakeHomeIconSizePx,
fakeHomeIconTop + fakeHomeIconSizePx);
}
@Override
- public void update(RectF rect, float progress, float radius) {
+ public void update(@Nullable AppCloseConfig config, RectF rect, float progress,
+ float radius) {
mFakeIconView.setVisibility(View.VISIBLE);
mFakeIconView.update(rect, progress,
1f - SHAPE_PROGRESS_DURATION /* shapeProgressStart */,
radius, 255,
false, /* isOpening */
- mFakeIconView, mDp);
+ mFakeIconView, mDp,
+ false /* isVerticalBarLayout */);
mFakeIconView.setAlpha(1);
mFakeTaskView.setAlpha(getWindowAlpha(progress));
mFakePreviousTaskView.setAlpha(getWindowAlpha(progress));
@@ -356,62 +326,12 @@ abstract class SwipeUpGestureTutorialController extends TutorialController {
mFakeIconView.setVisibility(View.INVISIBLE);
}
};
- RectFSpringAnim windowAnim = createWindowAnimationToHome(startShift,
- homeAnimFactory)[0];
+ RectFSpringAnim windowAnim = createWindowAnimationToHome(startShift, homeAnimFactory);
windowAnim.start(mContext, velocityPxPerMs);
return windowAnim;
}
}
- protected Animator createFingerDotHomeSwipeAnimator(float fingerDotStartTranslationY) {
- Animator homeSwipeAnimator = createFingerDotSwipeUpAnimator(fingerDotStartTranslationY)
- .setDuration(HOME_SWIPE_ANIMATION_DURATION_MILLIS);
-
- homeSwipeAnimator.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- super.onAnimationEnd(animation);
- animateFakeTaskViewHome(
- new PointF(
- 0f,
- fingerDotStartTranslationY / HOME_SWIPE_ANIMATION_DURATION_MILLIS),
- null);
- }
- });
-
- return homeSwipeAnimator;
- }
-
- protected Animator createFingerDotOverviewSwipeAnimator(float fingerDotStartTranslationY) {
- Animator overviewSwipeAnimator = createFingerDotSwipeUpAnimator(fingerDotStartTranslationY)
- .setDuration(OVERVIEW_SWIPE_ANIMATION_DURATION_MILLIS);
-
- overviewSwipeAnimator.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- super.onAnimationEnd(animation);
- mFakePreviousTaskView.setVisibility(View.VISIBLE);
- onMotionPaused(true /*arbitrary value*/);
- }
- });
-
- return overviewSwipeAnimator;
- }
-
-
- private Animator createFingerDotSwipeUpAnimator(float fingerDotStartTranslationY) {
- ValueAnimator swipeAnimator = ValueAnimator.ofFloat(0f, 1f);
-
- swipeAnimator.addUpdateListener(valueAnimator -> {
- float gestureProgress =
- -fingerDotStartTranslationY * valueAnimator.getAnimatedFraction();
- setNavBarGestureProgress(gestureProgress);
- mFingerDotView.setTranslationY(fingerDotStartTranslationY + gestureProgress);
- });
-
- return swipeAnimator;
- }
-
private class FakeTransformParams extends TransformParams {
@Override
diff --git a/quickstep/src/com/android/quickstep/interaction/TutorialController.java b/quickstep/src/com/android/quickstep/interaction/TutorialController.java
index fa7d848a7c..4b4e7e6753 100644
--- a/quickstep/src/com/android/quickstep/interaction/TutorialController.java
+++ b/quickstep/src/com/android/quickstep/interaction/TutorialController.java
@@ -16,40 +16,31 @@
package com.android.quickstep.interaction;
import static android.view.View.GONE;
-import static android.view.View.NO_ID;
-import static android.view.View.inflate;
-
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.AnimatorSet;
-import android.animation.ObjectAnimator;
-import android.animation.ValueAnimator;
-import android.annotation.ColorRes;
+
import android.content.Context;
import android.content.pm.PackageManager;
+import android.graphics.drawable.Animatable2;
import android.graphics.drawable.AnimatedVectorDrawable;
import android.graphics.drawable.ColorDrawable;
+import android.graphics.drawable.Drawable;
import android.graphics.drawable.RippleDrawable;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.view.accessibility.AccessibilityEvent;
import android.widget.Button;
-import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import androidx.annotation.CallSuper;
import androidx.annotation.DrawableRes;
-import androidx.annotation.LayoutRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.content.res.AppCompatResources;
-import com.android.launcher3.DeviceProfile;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.anim.AnimatorListeners;
@@ -57,57 +48,46 @@ import com.android.launcher3.views.ClipIconView;
import com.android.quickstep.interaction.EdgeBackGestureHandler.BackGestureAttemptCallback;
import com.android.quickstep.interaction.NavBarGestureHandler.NavBarGestureAttemptCallback;
-import java.util.ArrayList;
-
abstract class TutorialController implements BackGestureAttemptCallback,
NavBarGestureAttemptCallback {
- private static final String LOG_TAG = "TutorialController";
-
- private static final float FINGER_DOT_VISIBLE_ALPHA = 0.7f;
- private static final float FINGER_DOT_SMALL_SCALE = 0.7f;
- private static final int FINGER_DOT_ANIMATION_DURATION_MILLIS = 500;
+ private static final String TAG = "TutorialController";
private static final String PIXEL_TIPS_APP_PACKAGE_NAME = "com.google.android.apps.tips";
private static final CharSequence DEFAULT_PIXEL_TIPS_APP_NAME = "Pixel Tips";
- private static final int FEEDBACK_ANIMATION_MS = 133;
+ private static final int FEEDBACK_ANIMATION_MS = 250;
private static final int RIPPLE_VISIBLE_MS = 300;
private static final int GESTURE_ANIMATION_DELAY_MS = 1500;
- private static final int ADVANCE_TUTORIAL_TIMEOUT_MS = 2000;
- private static final long GESTURE_ANIMATION_PAUSE_DURATION_MILLIS = 1000;
+ private static final int ADVANCE_TUTORIAL_TIMEOUT_MS = 4000;
final TutorialFragment mTutorialFragment;
TutorialType mTutorialType;
final Context mContext;
- final TextView mSkipButton;
- final Button mDoneButton;
+ final TextView mCloseButton;
final ViewGroup mFeedbackView;
final TextView mFeedbackTitleView;
- final ImageView mEdgeGestureVideoView;
+ final ImageView mFeedbackVideoView;
+ final ImageView mGestureVideoView;
final RelativeLayout mFakeLauncherView;
- final FrameLayout mFakeHotseatView;
- @Nullable View mHotseatIconView;
+ final ImageView mFakeHotseatView;
final ClipIconView mFakeIconView;
- final FrameLayout mFakeTaskView;
- final AnimatedTaskbarView mFakeTaskbarView;
- final AnimatedTaskView mFakePreviousTaskView;
+ final View mFakeTaskView;
+ final View mFakePreviousTaskView;
final View mRippleView;
final RippleDrawable mRippleDrawable;
+ final Button mActionButton;
final TutorialStepIndicator mTutorialStepView;
- final ImageView mFingerDotView;
private final AlertDialog mSkipTutorialDialog;
- private boolean mGestureCompleted = false;
+ protected boolean mGestureCompleted = false;
// These runnables should be used when posting callbacks to their views and cleared from their
// views before posting new callbacks.
private final Runnable mTitleViewCallback;
@Nullable private Runnable mFeedbackViewCallback;
- @Nullable private Runnable mFakeTaskViewCallback;
- @Nullable private Runnable mFakeTaskbarViewCallback;
- private final Runnable mShowFeedbackRunnable;
+ @Nullable private Runnable mFeedbackVideoViewCallback;
TutorialController(TutorialFragment tutorialFragment, TutorialType tutorialType) {
mTutorialFragment = tutorialFragment;
@@ -115,52 +95,28 @@ abstract class TutorialController implements BackGestureAttemptCallback,
mContext = mTutorialFragment.getContext();
RootSandboxLayout rootView = tutorialFragment.getRootView();
- mSkipButton = rootView.findViewById(R.id.gesture_tutorial_fragment_close_button);
- mSkipButton.setOnClickListener(button -> showSkipTutorialDialog());
+ mCloseButton = rootView.findViewById(R.id.gesture_tutorial_fragment_close_button);
+ mCloseButton.setOnClickListener(button -> showSkipTutorialDialog());
mFeedbackView = rootView.findViewById(R.id.gesture_tutorial_fragment_feedback_view);
mFeedbackTitleView = mFeedbackView.findViewById(
R.id.gesture_tutorial_fragment_feedback_title);
- mEdgeGestureVideoView = rootView.findViewById(R.id.gesture_tutorial_edge_gesture_video);
+ mFeedbackVideoView = rootView.findViewById(R.id.gesture_tutorial_feedback_video);
+ mGestureVideoView = rootView.findViewById(R.id.gesture_tutorial_gesture_video);
mFakeLauncherView = rootView.findViewById(R.id.gesture_tutorial_fake_launcher_view);
mFakeHotseatView = rootView.findViewById(R.id.gesture_tutorial_fake_hotseat_view);
mFakeIconView = rootView.findViewById(R.id.gesture_tutorial_fake_icon_view);
mFakeTaskView = rootView.findViewById(R.id.gesture_tutorial_fake_task_view);
- mFakeTaskbarView = rootView.findViewById(R.id.gesture_tutorial_fake_taskbar_view);
mFakePreviousTaskView =
rootView.findViewById(R.id.gesture_tutorial_fake_previous_task_view);
mRippleView = rootView.findViewById(R.id.gesture_tutorial_ripple_view);
mRippleDrawable = (RippleDrawable) mRippleView.getBackground();
- mDoneButton = rootView.findViewById(R.id.gesture_tutorial_fragment_action_button);
+ mActionButton = rootView.findViewById(R.id.gesture_tutorial_fragment_action_button);
mTutorialStepView =
rootView.findViewById(R.id.gesture_tutorial_fragment_feedback_tutorial_step);
- mFingerDotView = rootView.findViewById(R.id.gesture_tutorial_finger_dot);
mSkipTutorialDialog = createSkipTutorialDialog();
mTitleViewCallback = () -> mFeedbackTitleView.sendAccessibilityEvent(
AccessibilityEvent.TYPE_VIEW_FOCUSED);
- mShowFeedbackRunnable = () -> {
- mFeedbackView.setAlpha(0f);
- mFeedbackView.setScaleX(0.95f);
- mFeedbackView.setScaleY(0.95f);
- mFeedbackView.setVisibility(View.VISIBLE);
- mFeedbackView.animate()
- .setDuration(FEEDBACK_ANIMATION_MS)
- .alpha(1f)
- .scaleX(1f)
- .scaleY(1f)
- .withEndAction(() -> {
- if (mGestureCompleted && !mTutorialFragment.isAtFinalStep()) {
- if (mFeedbackViewCallback != null) {
- mFeedbackView.removeCallbacks(mFeedbackViewCallback);
- }
- mFeedbackViewCallback = mTutorialFragment::continueTutorial;
- mFeedbackView.postDelayed(mFeedbackViewCallback,
- ADVANCE_TUTORIAL_TIMEOUT_MS);
- }
- })
- .start();
- mFeedbackTitleView.postDelayed(mTitleViewCallback, FEEDBACK_ANIMATION_MS);
- };
}
private void showSkipTutorialDialog() {
@@ -169,37 +125,23 @@ abstract class TutorialController implements BackGestureAttemptCallback,
}
}
- public int getHotseatIconTop() {
- return mHotseatIconView == null
- ? 0 : mFakeHotseatView.getTop() + mHotseatIconView.getTop();
- }
-
- public int getHotseatIconLeft() {
- return mHotseatIconView == null
- ? 0 : mFakeHotseatView.getLeft() + mHotseatIconView.getLeft();
- }
-
void setTutorialType(TutorialType tutorialType) {
mTutorialType = tutorialType;
}
- @LayoutRes
+ @DrawableRes
protected int getMockHotseatResId() {
- return mTutorialFragment.isLargeScreen()
- ? (mTutorialFragment.isFoldable()
- ? R.layout.gesture_tutorial_foldable_mock_hotseat
- : R.layout.gesture_tutorial_tablet_mock_hotseat)
- : R.layout.gesture_tutorial_mock_hotseat;
+ return R.drawable.default_sandbox_mock_launcher;
}
- @LayoutRes
- protected int getMockAppTaskLayoutResId() {
- return View.NO_ID;
+ @DrawableRes
+ protected int getMockAppTaskThumbnailResId(boolean forDarkMode) {
+ return R.drawable.default_sandbox_app_task_thumbnail;
}
- @ColorRes
- protected int getMockPreviousAppTaskThumbnailColorResId() {
- return R.color.gesture_tutorial_fake_previous_task_view_color;
+ @DrawableRes
+ protected int getMockPreviousAppTaskThumbnailResId() {
+ return R.drawable.default_sandbox_app_previous_task_thumbnail;
}
@DrawableRes
@@ -217,23 +159,13 @@ abstract class TutorialController implements BackGestureAttemptCallback,
}
@StringRes
- public int getIntroductionTitle() {
- return NO_ID;
- }
-
- @StringRes
- public int getIntroductionSubtitle() {
- return NO_ID;
- }
-
- @StringRes
- public int getSpokenIntroductionSubtitle() {
- return NO_ID;
+ public Integer getIntroductionTitle() {
+ return null;
}
@StringRes
- public int getSuccessFeedbackSubtitle() {
- return NO_ID;
+ public Integer getIntroductionSubtitle() {
+ return null;
}
void showFeedback() {
@@ -241,27 +173,18 @@ abstract class TutorialController implements BackGestureAttemptCallback,
mFeedbackView.setTranslationY(0);
return;
}
- Animator gestureAnimation = mTutorialFragment.getGestureAnimation();
- AnimatedVectorDrawable edgeAnimation = mTutorialFragment.getEdgeAnimation();
- if (gestureAnimation != null && edgeAnimation != null) {
- playFeedbackAnimation(gestureAnimation, edgeAnimation, mShowFeedbackRunnable, true);
- }
- }
+ AnimatedVectorDrawable tutorialAnimation = mTutorialFragment.getTutorialAnimation();
+ AnimatedVectorDrawable gestureAnimation = mTutorialFragment.getGestureAnimation();
- /**
- * Show feedback reflecting a successful gesture attempt.
- **/
- void showSuccessFeedback() {
- int successSubtitleResId = getSuccessFeedbackSubtitle();
- if (successSubtitleResId == NO_ID) {
- // Allow crash since this should never be reached with a tutorial controller used in
- // production.
- Log.e(LOG_TAG,
- "Cannot show success feedback for tutorial step: " + mTutorialType
- + ", no success feedback subtitle",
- new IllegalStateException());
+ if (tutorialAnimation != null && gestureAnimation != null) {
+ TextView title = mFeedbackView.findViewById(
+ R.id.gesture_tutorial_fragment_feedback_title);
+
+ playFeedbackVideo(tutorialAnimation, gestureAnimation, () -> {
+ mFeedbackView.setTranslationY(0);
+ title.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED);
+ }, true);
}
- showFeedback(successSubtitleResId, true);
}
/**
@@ -283,7 +206,6 @@ abstract class TutorialController implements BackGestureAttemptCallback,
isGestureSuccessful
? R.string.gesture_tutorial_nice : R.string.gesture_tutorial_try_again,
subtitleResId,
- NO_ID,
isGestureSuccessful,
false);
}
@@ -291,100 +213,90 @@ abstract class TutorialController implements BackGestureAttemptCallback,
void showFeedback(
int titleResId,
int subtitleResId,
- int spokenSubtitleResId,
boolean isGestureSuccessful,
boolean useGestureAnimationDelay) {
- mFeedbackTitleView.removeCallbacks(mTitleViewCallback);
- if (mFeedbackViewCallback != null) {
- mFeedbackView.removeCallbacks(mFeedbackViewCallback);
- mFeedbackViewCallback = null;
- }
-
mFeedbackTitleView.setText(titleResId);
+ mFeedbackTitleView.removeCallbacks(mTitleViewCallback);
TextView subtitle =
mFeedbackView.findViewById(R.id.gesture_tutorial_fragment_feedback_subtitle);
- subtitle.setText(spokenSubtitleResId == NO_ID
- ? mContext.getText(subtitleResId)
- : Utilities.wrapForTts(
- mContext.getText(subtitleResId), mContext.getString(spokenSubtitleResId)));
+ subtitle.setText(subtitleResId);
if (isGestureSuccessful) {
+ hideCloseButton();
if (mTutorialFragment.isAtFinalStep()) {
showActionButton();
}
- if (mFakeTaskViewCallback != null) {
- mFakeTaskView.removeCallbacks(mFakeTaskViewCallback);
- mFakeTaskViewCallback = null;
+ if (mFeedbackVideoViewCallback != null) {
+ mFeedbackVideoView.removeCallbacks(mFeedbackVideoViewCallback);
+ mFeedbackVideoViewCallback = null;
}
}
mGestureCompleted = isGestureSuccessful;
- Animator gestureAnimation = mTutorialFragment.getGestureAnimation();
- AnimatedVectorDrawable edgeAnimation = mTutorialFragment.getEdgeAnimation();
- if (!isGestureSuccessful && gestureAnimation != null && edgeAnimation != null) {
- playFeedbackAnimation(
- gestureAnimation,
- edgeAnimation,
- mShowFeedbackRunnable,
- useGestureAnimationDelay);
- return;
- } else {
- mTutorialFragment.releaseFeedbackAnimation();
+ AnimatedVectorDrawable tutorialAnimation = mTutorialFragment.getTutorialAnimation();
+ AnimatedVectorDrawable gestureAnimation = mTutorialFragment.getGestureAnimation();
+ if (tutorialAnimation != null && gestureAnimation != null) {
+ if (!isGestureSuccessful) {
+ playFeedbackVideo(tutorialAnimation, gestureAnimation, () -> {
+ mFeedbackView.setTranslationY(
+ -mFeedbackView.getHeight() - mFeedbackView.getTop());
+ mFeedbackView.setVisibility(View.VISIBLE);
+ mFeedbackView.animate()
+ .setDuration(FEEDBACK_ANIMATION_MS)
+ .translationY(0)
+ .start();
+ mFeedbackTitleView.postDelayed(mTitleViewCallback, FEEDBACK_ANIMATION_MS);
+ }, useGestureAnimationDelay);
+ return;
+ } else {
+ mTutorialFragment.releaseFeedbackVideoView();
+ }
}
- mFeedbackViewCallback = mShowFeedbackRunnable;
-
- mFeedbackView.post(mFeedbackViewCallback);
- }
-
- public boolean isGestureCompleted() {
- return mGestureCompleted;
+ mFeedbackView.setTranslationY(-mFeedbackView.getHeight() - mFeedbackView.getTop());
+ mFeedbackView.setVisibility(View.VISIBLE);
+ mFeedbackView.animate()
+ .setDuration(FEEDBACK_ANIMATION_MS)
+ .translationY(0)
+ .withEndAction(() -> {
+ if (isGestureSuccessful && !mTutorialFragment.isAtFinalStep()) {
+ if (mFeedbackViewCallback != null) {
+ mFeedbackView.removeCallbacks(mFeedbackViewCallback);
+ }
+ mFeedbackViewCallback = mTutorialFragment::continueTutorial;
+ mFeedbackView.postDelayed(mFeedbackViewCallback,
+ ADVANCE_TUTORIAL_TIMEOUT_MS);
+ }
+ })
+ .start();
+ mFeedbackTitleView.postDelayed(mTitleViewCallback, FEEDBACK_ANIMATION_MS);
}
- void hideFeedback() {
- if (mFeedbackView.getVisibility() != View.VISIBLE) {
- return;
- }
- cancelQueuedGestureAnimation();
+ void hideFeedback(boolean releaseFeedbackVideo) {
mFeedbackView.clearAnimation();
mFeedbackView.setVisibility(View.INVISIBLE);
- }
-
- void cancelQueuedGestureAnimation() {
- if (mFeedbackViewCallback != null) {
- mFeedbackView.removeCallbacks(mFeedbackViewCallback);
- mFeedbackViewCallback = null;
- }
- if (mFakeTaskViewCallback != null) {
- mFakeTaskView.removeCallbacks(mFakeTaskViewCallback);
- mFakeTaskViewCallback = null;
+ if (releaseFeedbackVideo) {
+ mTutorialFragment.releaseFeedbackVideoView();
}
- if (mFakeTaskbarViewCallback != null) {
- mFakeTaskbarView.removeCallbacks(mFakeTaskbarViewCallback);
- mFakeTaskbarViewCallback = null;
- }
- mFeedbackTitleView.removeCallbacks(mTitleViewCallback);
}
- private void playFeedbackAnimation(
- @NonNull Animator gestureAnimation,
- @NonNull AnimatedVectorDrawable edgeAnimation,
+ private void playFeedbackVideo(
+ @NonNull AnimatedVectorDrawable tutorialAnimation,
+ @NonNull AnimatedVectorDrawable gestureAnimation,
@NonNull Runnable onStartRunnable,
boolean useGestureAnimationDelay) {
- if (gestureAnimation.isRunning()) {
- gestureAnimation.cancel();
+ if (tutorialAnimation.isRunning()) {
+ tutorialAnimation.reset();
}
- if (edgeAnimation.isRunning()) {
- edgeAnimation.reset();
- }
- gestureAnimation.addListener(new AnimatorListenerAdapter() {
+ tutorialAnimation.registerAnimationCallback(new Animatable2.AnimationCallback() {
+
@Override
- public void onAnimationStart(Animator animation) {
- super.onAnimationStart(animation);
+ public void onAnimationStart(Drawable drawable) {
+ super.onAnimationStart(drawable);
- mEdgeGestureVideoView.setVisibility(GONE);
- if (edgeAnimation.isRunning()) {
- edgeAnimation.stop();
+ mGestureVideoView.setVisibility(GONE);
+ if (gestureAnimation.isRunning()) {
+ gestureAnimation.stop();
}
if (!useGestureAnimationDelay) {
@@ -393,25 +305,37 @@ abstract class TutorialController implements BackGestureAttemptCallback,
}
@Override
- public void onAnimationEnd(Animator animation) {
- super.onAnimationEnd(animation);
+ public void onAnimationEnd(Drawable drawable) {
+ super.onAnimationEnd(drawable);
- mEdgeGestureVideoView.setVisibility(View.VISIBLE);
- edgeAnimation.start();
+ mGestureVideoView.setVisibility(View.VISIBLE);
+ gestureAnimation.start();
- gestureAnimation.removeListener(this);
+ tutorialAnimation.unregisterAnimationCallback(this);
}
});
- cancelQueuedGestureAnimation();
+ if (mFeedbackViewCallback != null) {
+ mFeedbackVideoView.removeCallbacks(mFeedbackViewCallback);
+ mFeedbackViewCallback = null;
+ }
+ if (mFeedbackVideoViewCallback != null) {
+ mFeedbackVideoView.removeCallbacks(mFeedbackVideoViewCallback);
+ mFeedbackVideoViewCallback = null;
+ }
if (useGestureAnimationDelay) {
mFeedbackViewCallback = onStartRunnable;
- mFakeTaskViewCallback = gestureAnimation::start;
+ mFeedbackVideoViewCallback = () -> {
+ mFeedbackVideoView.setVisibility(View.VISIBLE);
+ tutorialAnimation.start();
+ };
+ mFeedbackVideoView.setVisibility(View.GONE);
mFeedbackView.post(mFeedbackViewCallback);
- mFakeTaskView.postDelayed(mFakeTaskViewCallback, GESTURE_ANIMATION_DELAY_MS);
+ mFeedbackVideoView.postDelayed(mFeedbackVideoViewCallback, GESTURE_ANIMATION_DELAY_MS);
} else {
- gestureAnimation.start();
+ mFeedbackVideoView.setVisibility(View.VISIBLE);
+ tutorialAnimation.start();
}
}
@@ -436,12 +360,10 @@ abstract class TutorialController implements BackGestureAttemptCallback,
@CallSuper
void transitToController() {
- hideFeedback();
+ hideFeedback(false);
hideActionButton();
- updateCloseButton();
updateSubtext();
updateDrawables();
- updateLayout();
mGestureCompleted = false;
if (mFakeHotseatView != null) {
@@ -449,70 +371,28 @@ abstract class TutorialController implements BackGestureAttemptCallback,
}
}
- void updateCloseButton() {
- mSkipButton.setTextAppearance(Utilities.isDarkTheme(mContext)
+ void hideCloseButton() {
+ mCloseButton.setVisibility(GONE);
+ }
+
+ void showCloseButton() {
+ mCloseButton.setVisibility(View.VISIBLE);
+ mCloseButton.setTextAppearance(Utilities.isDarkTheme(mContext)
? R.style.TextAppearance_GestureTutorial_Feedback_Subtext
: R.style.TextAppearance_GestureTutorial_Feedback_Subtext_Dark);
}
void hideActionButton() {
- mSkipButton.setVisibility(View.VISIBLE);
+ showCloseButton();
// Invisible to maintain the layout.
- mDoneButton.setVisibility(View.INVISIBLE);
- mDoneButton.setOnClickListener(null);
+ mActionButton.setVisibility(View.INVISIBLE);
+ mActionButton.setOnClickListener(null);
}
void showActionButton() {
- mSkipButton.setVisibility(GONE);
- mDoneButton.setVisibility(View.VISIBLE);
- mDoneButton.setOnClickListener(this::onActionButtonClicked);
- }
-
- void hideFakeTaskbar(boolean animateToHotseat) {
- if (!mTutorialFragment.isLargeScreen()) {
- return;
- }
- if (mFakeTaskbarViewCallback != null) {
- mFakeTaskbarView.removeCallbacks(mFakeTaskbarViewCallback);
- }
- if (animateToHotseat) {
- mFakeTaskbarViewCallback = () ->
- mFakeTaskbarView.animateDisappearanceToHotseat(mFakeHotseatView);
- } else {
- mFakeTaskbarViewCallback = mFakeTaskbarView::animateDisappearanceToBottom;
- }
- mFakeTaskbarView.post(mFakeTaskbarViewCallback);
- }
-
- void showFakeTaskbar(boolean animateFromHotseat) {
- if (!mTutorialFragment.isLargeScreen()) {
- return;
- }
- if (mFakeTaskbarViewCallback != null) {
- mFakeTaskbarView.removeCallbacks(mFakeTaskbarViewCallback);
- }
- if (animateFromHotseat) {
- mFakeTaskbarViewCallback = () ->
- mFakeTaskbarView.animateAppearanceFromHotseat(mFakeHotseatView);
- } else {
- mFakeTaskbarViewCallback = mFakeTaskbarView::animateAppearanceFromBottom;
- }
- mFakeTaskbarView.post(mFakeTaskbarViewCallback);
- }
-
- void updateFakeAppTaskViewLayout(@LayoutRes int mockAppTaskLayoutResId) {
- updateFakeViewLayout(mFakeTaskView, mockAppTaskLayoutResId);
- }
-
- void updateFakeViewLayout(ViewGroup view, @LayoutRes int mockLayoutResId) {
- view.removeAllViews();
- if (mockLayoutResId != NO_ID) {
- view.addView(
- inflate(mContext, mockLayoutResId, null),
- new FrameLayout.LayoutParams(
- ViewGroup.LayoutParams.MATCH_PARENT,
- ViewGroup.LayoutParams.MATCH_PARENT));
- }
+ hideCloseButton();
+ mActionButton.setVisibility(View.VISIBLE);
+ mActionButton.setOnClickListener(this::onActionButtonClicked);
}
private void updateSubtext() {
@@ -524,63 +404,24 @@ abstract class TutorialController implements BackGestureAttemptCallback,
if (mContext != null) {
mTutorialFragment.getRootView().setBackground(AppCompatResources.getDrawable(
mContext, getMockWallpaperResId()));
- mTutorialFragment.updateFeedbackAnimation();
+ mTutorialFragment.updateFeedbackVideo();
mFakeLauncherView.setBackgroundColor(
- mContext.getColor(R.color.gesture_tutorial_fake_wallpaper_color));
- updateFakeViewLayout(mFakeHotseatView, getMockHotseatResId());
- mHotseatIconView = mFakeHotseatView.findViewById(R.id.hotseat_icon_1);
- updateFakeViewLayout(mFakeTaskView, getMockAppTaskLayoutResId());
+ mContext.getColor(Utilities.isDarkTheme(mContext)
+ ? R.color.fake_wallpaper_color_dark_mode
+ : R.color.fake_wallpaper_color_light_mode));
+ mFakeHotseatView.setImageDrawable(AppCompatResources.getDrawable(
+ mContext, getMockHotseatResId()));
+ mFakeTaskView.setBackground(AppCompatResources.getDrawable(
+ mContext, getMockAppTaskThumbnailResId(Utilities.isDarkTheme(mContext))));
mFakeTaskView.animate().alpha(1).setListener(
AnimatorListeners.forSuccessCallback(() -> mFakeTaskView.animate().cancel()));
- mFakePreviousTaskView.setFakeTaskViewFillColor(mContext.getResources().getColor(
- getMockPreviousAppTaskThumbnailColorResId()));
+ mFakePreviousTaskView.setBackground(AppCompatResources.getDrawable(
+ mContext, getMockPreviousAppTaskThumbnailResId()));
mFakeIconView.setBackground(AppCompatResources.getDrawable(
mContext, getMockAppIconResId()));
}
}
- private void updateLayout() {
- if (mContext == null) {
- return;
- }
- RelativeLayout.LayoutParams feedbackLayoutParams =
- (RelativeLayout.LayoutParams) mFeedbackView.getLayoutParams();
- feedbackLayoutParams.setMarginStart(mContext.getResources().getDimensionPixelSize(
- mTutorialFragment.isLargeScreen()
- ? R.dimen.gesture_tutorial_tablet_feedback_margin_start_end
- : R.dimen.gesture_tutorial_feedback_margin_start_end));
- feedbackLayoutParams.setMarginEnd(mContext.getResources().getDimensionPixelSize(
- mTutorialFragment.isLargeScreen()
- ? R.dimen.gesture_tutorial_tablet_feedback_margin_start_end
- : R.dimen.gesture_tutorial_feedback_margin_start_end));
- feedbackLayoutParams.topMargin = mContext.getResources().getDimensionPixelSize(
- mTutorialFragment.isLargeScreen()
- ? R.dimen.gesture_tutorial_tablet_feedback_margin_top
- : R.dimen.gesture_tutorial_feedback_margin_top);
-
- mFakeTaskbarView.setVisibility(mTutorialFragment.isLargeScreen() ? View.VISIBLE : GONE);
-
- RelativeLayout.LayoutParams hotseatLayoutParams =
- (RelativeLayout.LayoutParams) mFakeHotseatView.getLayoutParams();
- if (!mTutorialFragment.isLargeScreen()) {
- DeviceProfile dp = mTutorialFragment.getDeviceProfile();
- dp.updateIsSeascape(mContext);
-
- hotseatLayoutParams.addRule(dp.isLandscape
- ? (dp.isSeascape()
- ? RelativeLayout.ALIGN_PARENT_START
- : RelativeLayout.ALIGN_PARENT_END)
- : RelativeLayout.ALIGN_PARENT_BOTTOM);
- } else {
- hotseatLayoutParams.width = RelativeLayout.LayoutParams.MATCH_PARENT;
- hotseatLayoutParams.height = RelativeLayout.LayoutParams.WRAP_CONTENT;
- hotseatLayoutParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
- hotseatLayoutParams.removeRule(RelativeLayout.ALIGN_PARENT_START);
- hotseatLayoutParams.removeRule(RelativeLayout.ALIGN_PARENT_END);
- }
- mFakeHotseatView.setLayoutParams(hotseatLayoutParams);
- }
-
private AlertDialog createSkipTutorialDialog() {
if (mContext instanceof GestureSandboxActivity) {
GestureSandboxActivity sandboxActivity = (GestureSandboxActivity) mContext;
@@ -599,7 +440,7 @@ abstract class TutorialController implements BackGestureAttemptCallback,
packageManager.getApplicationInfo(
PIXEL_TIPS_APP_PACKAGE_NAME, PackageManager.GET_META_DATA));
} catch (PackageManager.NameNotFoundException e) {
- Log.e(LOG_TAG,
+ Log.e(TAG,
"Could not find app label for package name: "
+ PIXEL_TIPS_APP_PACKAGE_NAME
+ ". Defaulting to 'Pixel Tips.'",
@@ -612,7 +453,7 @@ abstract class TutorialController implements BackGestureAttemptCallback,
subtitleTextView.setText(
mContext.getString(R.string.skip_tutorial_dialog_subtitle, tipsAppName));
} else {
- Log.w(LOG_TAG, "No subtitle view in the skip tutorial dialog to update.");
+ Log.w(TAG, "No subtitle view in the skip tutorial dialog to update.");
}
Button cancelButton = (Button) contentView.findViewById(
@@ -621,18 +462,18 @@ abstract class TutorialController implements BackGestureAttemptCallback,
cancelButton.setOnClickListener(
v -> tutorialDialog.dismiss());
} else {
- Log.w(LOG_TAG, "No cancel button in the skip tutorial dialog to update.");
+ Log.w(TAG, "No cancel button in the skip tutorial dialog to update.");
}
Button confirmButton = contentView.findViewById(
R.id.gesture_tutorial_dialog_confirm_button);
if (confirmButton != null) {
confirmButton.setOnClickListener(v -> {
- mTutorialFragment.closeTutorial(true);
+ sandboxActivity.closeTutorial();
tutorialDialog.dismiss();
});
} else {
- Log.w(LOG_TAG, "No confirm button in the skip tutorial dialog to update.");
+ Log.w(TAG, "No confirm button in the skip tutorial dialog to update.");
}
tutorialDialog.getWindow().setBackgroundDrawable(
@@ -644,52 +485,6 @@ abstract class TutorialController implements BackGestureAttemptCallback,
return null;
}
- protected AnimatorSet createFingerDotAppearanceAnimatorSet() {
- ObjectAnimator alphaAnimator = ObjectAnimator.ofFloat(
- mFingerDotView, View.ALPHA, 0f, FINGER_DOT_VISIBLE_ALPHA);
- ObjectAnimator yScaleAnimator = ObjectAnimator.ofFloat(
- mFingerDotView, View.SCALE_Y, FINGER_DOT_SMALL_SCALE, 1f);
- ObjectAnimator xScaleAnimator = ObjectAnimator.ofFloat(
- mFingerDotView, View.SCALE_X, FINGER_DOT_SMALL_SCALE, 1f);
- ArrayList<Animator> animators = new ArrayList<>();
-
- animators.add(alphaAnimator);
- animators.add(xScaleAnimator);
- animators.add(yScaleAnimator);
-
- AnimatorSet appearanceAnimatorSet = new AnimatorSet();
-
- appearanceAnimatorSet.playTogether(animators);
- appearanceAnimatorSet.setDuration(FINGER_DOT_ANIMATION_DURATION_MILLIS);
-
- return appearanceAnimatorSet;
- }
-
- protected AnimatorSet createFingerDotDisappearanceAnimatorSet() {
- ObjectAnimator alphaAnimator = ObjectAnimator.ofFloat(
- mFingerDotView, View.ALPHA, FINGER_DOT_VISIBLE_ALPHA, 0f);
- ObjectAnimator yScaleAnimator = ObjectAnimator.ofFloat(
- mFingerDotView, View.SCALE_Y, 1f, FINGER_DOT_SMALL_SCALE);
- ObjectAnimator xScaleAnimator = ObjectAnimator.ofFloat(
- mFingerDotView, View.SCALE_X, 1f, FINGER_DOT_SMALL_SCALE);
- ArrayList<Animator> animators = new ArrayList<>();
-
- animators.add(alphaAnimator);
- animators.add(xScaleAnimator);
- animators.add(yScaleAnimator);
-
- AnimatorSet appearanceAnimatorSet = new AnimatorSet();
-
- appearanceAnimatorSet.playTogether(animators);
- appearanceAnimatorSet.setDuration(FINGER_DOT_ANIMATION_DURATION_MILLIS);
-
- return appearanceAnimatorSet;
- }
-
- protected Animator createAnimationPause() {
- return ValueAnimator.ofFloat(0f, 1f).setDuration(GESTURE_ANIMATION_PAUSE_DURATION_MILLIS);
- }
-
/** Denotes the type of the tutorial. */
enum TutorialType {
BACK_NAVIGATION,
diff --git a/quickstep/src/com/android/quickstep/interaction/TutorialFragment.java b/quickstep/src/com/android/quickstep/interaction/TutorialFragment.java
index 1599c8c32d..7637450a1a 100644
--- a/quickstep/src/com/android/quickstep/interaction/TutorialFragment.java
+++ b/quickstep/src/com/android/quickstep/interaction/TutorialFragment.java
@@ -15,27 +15,20 @@
*/
package com.android.quickstep.interaction;
-import static android.view.View.NO_ID;
-
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
-import android.content.SharedPreferences;
import android.graphics.Insets;
import android.graphics.drawable.Animatable2;
import android.graphics.drawable.AnimatedVectorDrawable;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
-import android.util.ArraySet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.ViewGroup;
-import android.view.ViewTreeObserver;
import android.view.WindowInsets;
import android.widget.ImageView;
@@ -44,46 +37,30 @@ import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
-import com.android.launcher3.DeviceProfile;
-import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.R;
-import com.android.launcher3.logging.StatsLogManager;
+import com.android.launcher3.Utilities;
import com.android.quickstep.interaction.TutorialController.TutorialType;
-import java.util.Set;
-
abstract class TutorialFragment extends Fragment implements OnTouchListener {
private static final String LOG_TAG = "TutorialFragment";
static final String KEY_TUTORIAL_TYPE = "tutorial_type";
- static final String KEY_GESTURE_COMPLETE = "gesture_complete";
-
- private static final String TUTORIAL_SKIPPED_PREFERENCE_KEY = "pref_gestureTutorialSkipped";
- private static final String COMPLETED_TUTORIAL_STEPS_PREFERENCE_KEY =
- "pref_completedTutorialSteps";
TutorialType mTutorialType;
- boolean mGestureComplete = false;
@Nullable TutorialController mTutorialController = null;
RootSandboxLayout mRootView;
- View mFingerDotView;
- View mFakePreviousTaskView;
EdgeBackGestureHandler mEdgeBackGestureHandler;
NavBarGestureHandler mNavBarGestureHandler;
- private ImageView mEdgeGestureVideoView;
+ private ImageView mFeedbackVideoView;
+ private ImageView mGestureVideoView;
- @Nullable private Animator mGestureAnimation = null;
- @Nullable private AnimatedVectorDrawable mEdgeAnimation = null;
+ @Nullable private AnimatedVectorDrawable mTutorialAnimation = null;
+ @Nullable private AnimatedVectorDrawable mGestureAnimation = null;
private boolean mIntroductionShown = false;
private boolean mFragmentStopped = false;
- private DeviceProfile mDeviceProfile;
- private boolean mIsLargeScreen;
- private boolean mIsFoldable;
-
- public static TutorialFragment newInstance(
- TutorialType tutorialType, boolean gestureComplete) {
+ public static TutorialFragment newInstance(TutorialType tutorialType) {
TutorialFragment fragment = getFragmentForTutorialType(tutorialType);
if (fragment == null) {
fragment = new BackGestureTutorialFragment();
@@ -92,7 +69,6 @@ abstract class TutorialFragment extends Fragment implements OnTouchListener {
Bundle args = new Bundle();
args.putSerializable(KEY_TUTORIAL_TYPE, tutorialType);
- args.putBoolean(KEY_GESTURE_COMPLETE, gestureComplete);
fragment.setArguments(args);
return fragment;
}
@@ -120,24 +96,22 @@ abstract class TutorialFragment extends Fragment implements OnTouchListener {
return null;
}
- @Nullable Integer getEdgeAnimationResId() {
+ @Nullable Integer getFeedbackVideoResId(boolean forDarkMode) {
return null;
}
- @Nullable
- Animator getGestureAnimation() {
- return mGestureAnimation;
+ @Nullable Integer getGestureVideoResId() {
+ return null;
}
@Nullable
- AnimatedVectorDrawable getEdgeAnimation() {
- return mEdgeAnimation;
+ AnimatedVectorDrawable getTutorialAnimation() {
+ return mTutorialAnimation;
}
-
@Nullable
- protected Animator createGestureAnimation() {
- return null;
+ AnimatedVectorDrawable getGestureAnimation() {
+ return mGestureAnimation;
}
abstract TutorialController createController(TutorialType type);
@@ -149,26 +123,8 @@ abstract class TutorialFragment extends Fragment implements OnTouchListener {
super.onCreate(savedInstanceState);
Bundle args = savedInstanceState != null ? savedInstanceState : getArguments();
mTutorialType = (TutorialType) args.getSerializable(KEY_TUTORIAL_TYPE);
- mGestureComplete = args.getBoolean(KEY_GESTURE_COMPLETE, false);
mEdgeBackGestureHandler = new EdgeBackGestureHandler(getContext());
mNavBarGestureHandler = new NavBarGestureHandler(getContext());
-
- mDeviceProfile = InvariantDeviceProfile.INSTANCE.get(getContext())
- .getDeviceProfile(getContext());
- mIsLargeScreen = mDeviceProfile.isTablet;
- mIsFoldable = mDeviceProfile.isTwoPanels;
- }
-
- public boolean isLargeScreen() {
- return mIsLargeScreen;
- }
-
- public boolean isFoldable() {
- return mIsFoldable;
- }
-
- DeviceProfile getDeviceProfile() {
- return mDeviceProfile;
}
@Override
@@ -191,148 +147,121 @@ abstract class TutorialFragment extends Fragment implements OnTouchListener {
return insets;
});
mRootView.setOnTouchListener(this);
- mEdgeGestureVideoView = mRootView.findViewById(R.id.gesture_tutorial_edge_gesture_video);
- mFingerDotView = mRootView.findViewById(R.id.gesture_tutorial_finger_dot);
- mFakePreviousTaskView = mRootView.findViewById(
- R.id.gesture_tutorial_fake_previous_task_view);
+ mFeedbackVideoView = mRootView.findViewById(R.id.gesture_tutorial_feedback_video);
+ mGestureVideoView = mRootView.findViewById(R.id.gesture_tutorial_gesture_video);
return mRootView;
}
@Override
public void onStop() {
super.onStop();
- releaseFeedbackAnimation();
+ releaseFeedbackVideoView();
+ releaseGestureVideoView();
mFragmentStopped = true;
}
void initializeFeedbackVideoView() {
- if (!updateFeedbackAnimation() || mTutorialController == null) {
+ if (!updateFeedbackVideo()) {
return;
}
- if (isGestureComplete()) {
- mTutorialController.showSuccessFeedback();
- } else if (!mIntroductionShown) {
- int introTitleResId = mTutorialController.getIntroductionTitle();
- int introSubtitleResId = mTutorialController.getIntroductionSubtitle();
- if (introTitleResId == NO_ID) {
- // Allow crash since this should never be reached with a tutorial controller used in
- // production.
- Log.e(LOG_TAG,
- "Cannot show introduction feedback for tutorial step: " + mTutorialType
- + ", no introduction feedback title",
- new IllegalStateException());
+ if (!mIntroductionShown && mTutorialController != null) {
+ Integer introTileStringResId = mTutorialController.getIntroductionTitle();
+ Integer introSubtitleResId = mTutorialController.getIntroductionSubtitle();
+ if (introTileStringResId != null && introSubtitleResId != null) {
+ mTutorialController.showFeedback(
+ introTileStringResId, introSubtitleResId, false, true);
+ mIntroductionShown = true;
}
- if (introTitleResId == NO_ID) {
- // Allow crash since this should never be reached with a tutorial controller used in
- // production.
- Log.e(LOG_TAG,
- "Cannot show introduction feedback for tutorial step: " + mTutorialType
- + ", no introduction feedback subtitle",
- new IllegalStateException());
- }
- mTutorialController.showFeedback(
- introTitleResId,
- introSubtitleResId,
- mTutorialController.getSpokenIntroductionSubtitle(),
- false,
- true);
- mIntroductionShown = true;
}
}
- boolean updateFeedbackAnimation() {
- if (!updateEdgeAnimation()) {
+ boolean updateFeedbackVideo() {
+ if (getContext() == null) {
return false;
}
- mGestureAnimation = createGestureAnimation();
+ Integer feedbackVideoResId = getFeedbackVideoResId(Utilities.isDarkTheme(getContext()));
- if (mGestureAnimation != null) {
- mGestureAnimation.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationStart(Animator animation) {
- super.onAnimationStart(animation);
- mFingerDotView.setVisibility(View.VISIBLE);
- }
+ if (feedbackVideoResId == null || !updateGestureVideo()) {
+ return false;
+ }
+ mTutorialAnimation = (AnimatedVectorDrawable) getContext().getDrawable(feedbackVideoResId);
+
+ if (mTutorialAnimation != null) {
+ mTutorialAnimation.registerAnimationCallback(new Animatable2.AnimationCallback() {
@Override
- public void onAnimationCancel(Animator animation) {
- super.onAnimationCancel(animation);
- mFingerDotView.setVisibility(View.GONE);
+ public void onAnimationStart(Drawable drawable) {
+ super.onAnimationStart(drawable);
+
+ mFeedbackVideoView.setVisibility(View.VISIBLE);
}
@Override
- public void onAnimationEnd(Animator animation) {
- super.onAnimationEnd(animation);
- mFingerDotView.setVisibility(View.GONE);
+ public void onAnimationEnd(Drawable drawable) {
+ super.onAnimationEnd(drawable);
+
+ releaseFeedbackVideoView();
}
});
}
+ mFeedbackVideoView.setImageDrawable(mTutorialAnimation);
- return mGestureAnimation != null;
+ return true;
}
- boolean updateEdgeAnimation() {
- Integer edgeAnimationResId = getEdgeAnimationResId();
- if (edgeAnimationResId == null || getContext() == null) {
+ boolean updateGestureVideo() {
+ Integer gestureVideoResId = getGestureVideoResId();
+ if (gestureVideoResId == null || getContext() == null) {
return false;
}
- mEdgeAnimation = (AnimatedVectorDrawable) getContext().getDrawable(edgeAnimationResId);
+ mGestureAnimation = (AnimatedVectorDrawable) getContext().getDrawable(gestureVideoResId);
- if (mEdgeAnimation != null) {
- mEdgeAnimation.registerAnimationCallback(new Animatable2.AnimationCallback() {
+ if (mGestureAnimation != null) {
+ mGestureAnimation.registerAnimationCallback(new Animatable2.AnimationCallback() {
@Override
public void onAnimationEnd(Drawable drawable) {
super.onAnimationEnd(drawable);
- mEdgeAnimation.start();
+ mGestureAnimation.start();
}
});
}
- mEdgeGestureVideoView.setImageDrawable(mEdgeAnimation);
+ mGestureVideoView.setImageDrawable(mGestureAnimation);
- return mEdgeAnimation != null;
+ return true;
}
- void releaseFeedbackAnimation() {
- if (mTutorialController != null && !mTutorialController.isGestureCompleted()) {
- mTutorialController.cancelQueuedGestureAnimation();
+ void releaseFeedbackVideoView() {
+ if (mTutorialAnimation != null && mTutorialAnimation.isRunning()) {
+ mTutorialAnimation.stop();
}
+
+ mFeedbackVideoView.setVisibility(View.GONE);
+ }
+
+ void releaseGestureVideoView() {
if (mGestureAnimation != null && mGestureAnimation.isRunning()) {
- mGestureAnimation.cancel();
- }
- if (mEdgeAnimation != null && mEdgeAnimation.isRunning()) {
- mEdgeAnimation.stop();
+ mGestureAnimation.stop();
}
- mEdgeGestureVideoView.setVisibility(View.GONE);
+ mGestureVideoView.setVisibility(View.GONE);
}
@Override
public void onResume() {
super.onResume();
- releaseFeedbackAnimation();
if (mFragmentStopped && mTutorialController != null) {
mTutorialController.showFeedback();
mFragmentStopped = false;
} else {
- mRootView.getViewTreeObserver().addOnGlobalLayoutListener(
- new ViewTreeObserver.OnGlobalLayoutListener() {
- @Override
- public void onGlobalLayout() {
- changeController(mTutorialType);
- mRootView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
- }
- });
+ changeController(mTutorialType);
}
}
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
- if (mTutorialController != null && !isGestureComplete()) {
- mTutorialController.hideFeedback();
- }
// Note: Using logical-or to ensure both functions get called.
return mEdgeBackGestureHandler.onTouch(view, motionEvent)
| mNavBarGestureHandler.onTouch(view, motionEvent);
@@ -345,10 +274,6 @@ abstract class TutorialFragment extends Fragment implements OnTouchListener {
}
void onAttachedToWindow() {
- StatsLogManager statsLogManager = getStatsLogManager();
- if (statsLogManager != null) {
- logTutorialStepShown(statsLogManager);
- }
mEdgeBackGestureHandler.setViewGroupParent(getRootView());
}
@@ -367,7 +292,6 @@ abstract class TutorialFragment extends Fragment implements OnTouchListener {
mEdgeBackGestureHandler.registerBackGestureAttemptCallback(mTutorialController);
mNavBarGestureHandler.registerNavBarGestureAttemptCallback(mTutorialController);
mTutorialType = tutorialType;
-
initializeFeedbackVideoView();
}
@@ -382,22 +306,8 @@ abstract class TutorialFragment extends Fragment implements OnTouchListener {
}
void continueTutorial() {
- SharedPreferences sharedPrefs = getSharedPreferences();
- if (sharedPrefs != null) {
- Set<String> updatedCompletedSteps = new ArraySet<>(sharedPrefs.getStringSet(
- COMPLETED_TUTORIAL_STEPS_PREFERENCE_KEY, new ArraySet<>()));
-
- updatedCompletedSteps.add(mTutorialType.toString());
-
- sharedPrefs.edit().putStringSet(
- COMPLETED_TUTORIAL_STEPS_PREFERENCE_KEY, updatedCompletedSteps).apply();
- }
- StatsLogManager statsLogManager = getStatsLogManager();
- if (statsLogManager != null) {
- logTutorialStepCompleted(statsLogManager);
- }
-
GestureSandboxActivity gestureSandboxActivity = getGestureSandboxActivity();
+
if (gestureSandboxActivity == null) {
closeTutorial();
return;
@@ -406,21 +316,6 @@ abstract class TutorialFragment extends Fragment implements OnTouchListener {
}
void closeTutorial() {
- closeTutorial(false);
- }
-
- void closeTutorial(boolean tutorialSkipped) {
- if (tutorialSkipped) {
- SharedPreferences sharedPrefs = getSharedPreferences();
- if (sharedPrefs != null) {
- sharedPrefs.edit().putBoolean(TUTORIAL_SKIPPED_PREFERENCE_KEY, true).apply();
- }
- StatsLogManager statsLogManager = getStatsLogManager();
- if (statsLogManager != null) {
- statsLogManager.logger().log(
- StatsLogManager.LauncherEvent.LAUNCHER_GESTURE_TUTORIAL_SKIPPED);
- }
- }
FragmentActivity activity = getActivity();
if (activity != null) {
activity.setResult(Activity.RESULT_OK);
@@ -448,33 +343,10 @@ abstract class TutorialFragment extends Fragment implements OnTouchListener {
return getCurrentStep() == getNumSteps();
}
- boolean isGestureComplete() {
- return mGestureComplete
- || (mTutorialController != null && mTutorialController.isGestureCompleted());
- }
-
- abstract void logTutorialStepShown(@NonNull StatsLogManager statsLogManager);
-
- abstract void logTutorialStepCompleted(@NonNull StatsLogManager statsLogManager);
-
@Nullable
private GestureSandboxActivity getGestureSandboxActivity() {
Context context = getContext();
return context instanceof GestureSandboxActivity ? (GestureSandboxActivity) context : null;
}
-
- @Nullable
- private StatsLogManager getStatsLogManager() {
- GestureSandboxActivity activity = getGestureSandboxActivity();
-
- return activity != null ? activity.getStatsLogManager() : null;
- }
-
- @Nullable
- private SharedPreferences getSharedPreferences() {
- GestureSandboxActivity activity = getGestureSandboxActivity();
-
- return activity != null ? activity.getSharedPrefs() : null;
- }
}
diff --git a/quickstep/src/com/android/quickstep/interaction/TutorialStepIndicator.java b/quickstep/src/com/android/quickstep/interaction/TutorialStepIndicator.java
index ae0e725aad..d880d74e5d 100644
--- a/quickstep/src/com/android/quickstep/interaction/TutorialStepIndicator.java
+++ b/quickstep/src/com/android/quickstep/interaction/TutorialStepIndicator.java
@@ -23,6 +23,7 @@ import android.widget.ImageView;
import android.widget.LinearLayout;
import androidx.appcompat.content.res.AppCompatResources;
+import androidx.core.graphics.ColorUtils;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
@@ -86,10 +87,8 @@ public class TutorialStepIndicator extends LinearLayout {
for (int i = mTotalSteps; i < getChildCount(); i++) {
removeViewAt(i);
}
- int activeStepIndicatorColor = GraphicsUtils.getAttrColor(
+ int stepIndicatorColor = GraphicsUtils.getAttrColor(
getContext(), android.R.attr.textColorPrimary);
- int inactiveStepIndicatorColor = GraphicsUtils.getAttrColor(
- getContext(), android.R.attr.textColorSecondaryInverse);
for (int i = 0; i < mTotalSteps; i++) {
Drawable pageIndicatorPillDrawable = AppCompatResources.getDrawable(
getContext(), R.drawable.tutorial_step_indicator_pill);
@@ -108,9 +107,10 @@ public class TutorialStepIndicator extends LinearLayout {
}
if (pageIndicatorPillDrawable != null) {
if (i < mCurrentStep) {
- pageIndicatorPillDrawable.setTint(activeStepIndicatorColor);
+ pageIndicatorPillDrawable.setTint(stepIndicatorColor);
} else {
- pageIndicatorPillDrawable.setTint(inactiveStepIndicatorColor);
+ pageIndicatorPillDrawable.setTint(
+ ColorUtils.setAlphaComponent(stepIndicatorColor, 0x22));
}
}
}
diff --git a/quickstep/src/com/android/quickstep/logging/SettingsChangeLogger.java b/quickstep/src/com/android/quickstep/logging/SettingsChangeLogger.java
index bd0250d27d..7eca360224 100644
--- a/quickstep/src/com/android/quickstep/logging/SettingsChangeLogger.java
+++ b/quickstep/src/com/android/quickstep/logging/SettingsChangeLogger.java
@@ -16,17 +16,20 @@
package com.android.quickstep.logging;
+import static com.android.launcher3.InvariantDeviceProfile.KEY_MIGRATION_SRC_HOTSEAT_COUNT;
import static com.android.launcher3.Utilities.getDevicePrefs;
import static com.android.launcher3.Utilities.getPrefs;
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_GRID_SIZE_2;
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_GRID_SIZE_3;
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_GRID_SIZE_4;
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_GRID_SIZE_5;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_HOME_SCREEN_SUGGESTIONS_DISABLED;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_HOME_SCREEN_SUGGESTIONS_ENABLED;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_NOTIFICATION_DOT_DISABLED;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_NOTIFICATION_DOT_ENABLED;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_THEMED_ICON_DISABLED;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_THEMED_ICON_ENABLED;
-import static com.android.launcher3.model.DeviceGridState.KEY_WORKSPACE_SIZE;
import static com.android.launcher3.model.QuickstepModelDelegate.LAST_PREDICTION_ENABLED_STATE;
-import static com.android.launcher3.util.DisplayController.CHANGE_NAVIGATION_MODE;
import static com.android.launcher3.util.SettingsCache.NOTIFICATION_BADGING_URI;
import static com.android.launcher3.util.Themes.KEY_THEMED_ICONS;
@@ -41,33 +44,24 @@ import android.util.Xml;
import com.android.launcher3.AutoInstallsLayout;
import com.android.launcher3.R;
import com.android.launcher3.config.FeatureFlags;
-import com.android.launcher3.logging.InstanceId;
+import com.android.launcher3.logging.InstanceIdSequence;
import com.android.launcher3.logging.StatsLogManager;
import com.android.launcher3.logging.StatsLogManager.StatsLogger;
-import com.android.launcher3.model.DeviceGridState;
-import com.android.launcher3.util.DisplayController;
-import com.android.launcher3.util.DisplayController.Info;
-import com.android.launcher3.util.DisplayController.NavigationMode;
-import com.android.launcher3.util.MainThreadInitializedObject;
import com.android.launcher3.util.SettingsCache;
+import com.android.quickstep.SysUINavigationMode;
+import com.android.quickstep.SysUINavigationMode.Mode;
+import com.android.quickstep.SysUINavigationMode.NavigationModeChangeListener;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import java.io.IOException;
-import java.util.Optional;
/**
* Utility class to log launcher settings changes
*/
public class SettingsChangeLogger implements
- DisplayController.DisplayInfoChangeListener, OnSharedPreferenceChangeListener {
-
- /**
- * Singleton instance
- */
- public static MainThreadInitializedObject<SettingsChangeLogger> INSTANCE =
- new MainThreadInitializedObject<>(SettingsChangeLogger::new);
+ NavigationModeChangeListener, OnSharedPreferenceChangeListener {
private static final String TAG = "SettingsChangeLogger";
private static final String ROOT_TAG = "androidx.preference.PreferenceScreen";
@@ -75,18 +69,14 @@ public class SettingsChangeLogger implements
private final Context mContext;
private final ArrayMap<String, LoggablePref> mLoggablePrefs;
- private final StatsLogManager mStatsLogManager;
- private NavigationMode mNavMode;
- private StatsLogManager.LauncherEvent mNotificationDotsEvent;
- private StatsLogManager.LauncherEvent mHomeScreenSuggestionEvent;
+ private Mode mNavMode;
+ private boolean mNotificationDotsEnabled;
- private SettingsChangeLogger(Context context) {
+ public SettingsChangeLogger(Context context) {
mContext = context;
- mStatsLogManager = StatsLogManager.newInstance(mContext);
mLoggablePrefs = loadPrefKeys(context);
- DisplayController.INSTANCE.get(context).addChangeListener(this);
- mNavMode = DisplayController.getNavigationMode(context);
+ mNavMode = SysUINavigationMode.INSTANCE.get(context).addModeChangeListener(this);
getPrefs(context).registerOnSharedPreferenceChangeListener(this);
getDevicePrefs(context).registerOnSharedPreferenceChangeListener(this);
@@ -131,54 +121,60 @@ public class SettingsChangeLogger implements
}
private void onNotificationDotsChanged(boolean isDotsEnabled) {
- StatsLogManager.LauncherEvent mEvent =
- isDotsEnabled ? LAUNCHER_NOTIFICATION_DOT_ENABLED
- : LAUNCHER_NOTIFICATION_DOT_DISABLED;
-
- // Log only when the setting is actually changed and not during initialization.
- if (mNotificationDotsEvent != null && mNotificationDotsEvent != mEvent) {
- mStatsLogManager.logger().log(mNotificationDotsEvent);
- }
- mNotificationDotsEvent = mEvent;
+ mNotificationDotsEnabled = isDotsEnabled;
+ dispatchUserEvent();
}
@Override
- public void onDisplayInfoChanged(Context context, Info info, int flags) {
- if ((flags & CHANGE_NAVIGATION_MODE) != 0) {
- mNavMode = info.navigationMode;
- mStatsLogManager.logger().log(mNavMode.launcherEvent);
- }
+ public void onNavigationModeChanged(Mode newMode) {
+ mNavMode = newMode;
+ dispatchUserEvent();
}
@Override
public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
- if (LAST_PREDICTION_ENABLED_STATE.equals(key)
- || KEY_WORKSPACE_SIZE.equals(key)
- || KEY_THEMED_ICONS.equals(key)
+ if (LAST_PREDICTION_ENABLED_STATE.equals(key) || KEY_MIGRATION_SRC_HOTSEAT_COUNT.equals(key)
|| mLoggablePrefs.containsKey(key)) {
-
- mHomeScreenSuggestionEvent = getDevicePrefs(mContext)
- .getBoolean(LAST_PREDICTION_ENABLED_STATE, true)
- ? LAUNCHER_HOME_SCREEN_SUGGESTIONS_ENABLED
- : LAUNCHER_HOME_SCREEN_SUGGESTIONS_DISABLED;
-
- mStatsLogManager.logger().log(mHomeScreenSuggestionEvent);
+ dispatchUserEvent();
}
}
- /**
- * Takes snapshot of all eligible launcher settings and log them with the provided instance ID.
- */
- public void logSnapshot(InstanceId snapshotInstanceId) {
- StatsLogger logger = mStatsLogManager.logger().withInstanceId(snapshotInstanceId);
+ private void dispatchUserEvent() {
+ StatsLogger logger = StatsLogManager.newInstance(mContext).logger()
+ .withInstanceId(new InstanceIdSequence().newInstanceId());
- Optional.ofNullable(mNotificationDotsEvent).ifPresent(logger::log);
- Optional.ofNullable(mNavMode).map(mode -> mode.launcherEvent).ifPresent(logger::log);
- Optional.ofNullable(mHomeScreenSuggestionEvent).ifPresent(logger::log);
- Optional.ofNullable(new DeviceGridState(mContext).getWorkspaceSizeEvent()).ifPresent(
- logger::log);
+ logger.log(mNotificationDotsEnabled
+ ? LAUNCHER_NOTIFICATION_DOT_ENABLED
+ : LAUNCHER_NOTIFICATION_DOT_DISABLED);
+ logger.log(mNavMode.launcherEvent);
+ logger.log(getDevicePrefs(mContext).getBoolean(LAST_PREDICTION_ENABLED_STATE, true)
+ ? LAUNCHER_HOME_SCREEN_SUGGESTIONS_ENABLED
+ : LAUNCHER_HOME_SCREEN_SUGGESTIONS_DISABLED);
SharedPreferences prefs = getPrefs(mContext);
+ StatsLogManager.LauncherEvent gridSizeChangedEvent = null;
+ // TODO(b/184981523): This doesn't work for 2-panel grid, which has 6 hotseat icons
+ switch (prefs.getInt(KEY_MIGRATION_SRC_HOTSEAT_COUNT, -1)) {
+ case 5:
+ gridSizeChangedEvent = LAUNCHER_GRID_SIZE_5;
+ break;
+ case 4:
+ gridSizeChangedEvent = LAUNCHER_GRID_SIZE_4;
+ break;
+ case 3:
+ gridSizeChangedEvent = LAUNCHER_GRID_SIZE_3;
+ break;
+ case 2:
+ gridSizeChangedEvent = LAUNCHER_GRID_SIZE_2;
+ break;
+ default:
+ // Ignore illegal input.
+ break;
+ }
+ if (gridSizeChangedEvent != null) {
+ logger.log(gridSizeChangedEvent);
+ }
+
if (FeatureFlags.ENABLE_THEMED_ICONS.get()) {
logger.log(prefs.getBoolean(KEY_THEMED_ICONS, false)
? LAUNCHER_THEMED_ICON_ENABLED
diff --git a/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java b/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java
index 45c80366f4..6575996d69 100644
--- a/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java
+++ b/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java
@@ -19,8 +19,6 @@ package com.android.quickstep.logging;
import static androidx.core.util.Preconditions.checkNotNull;
import static androidx.core.util.Preconditions.checkState;
-import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_NON_ACTIONABLE;
-import static com.android.launcher3.logger.LauncherAtom.ContainerInfo.ContainerCase.ALL_APPS_CONTAINER;
import static com.android.launcher3.logger.LauncherAtom.ContainerInfo.ContainerCase.EXTENDED_CONTAINERS;
import static com.android.launcher3.logger.LauncherAtom.ContainerInfo.ContainerCase.FOLDER;
import static com.android.launcher3.logger.LauncherAtom.ContainerInfo.ContainerCase.SEARCH_RESULT_CONTAINER;
@@ -33,26 +31,21 @@ import static com.android.systemui.shared.system.SysUiStatsLog.LAUNCHER_UICHANGE
import android.content.Context;
import android.util.Log;
-import android.util.StatsEvent;
import android.view.View;
import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
import androidx.annotation.WorkerThread;
import androidx.slice.SliceItem;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.Utilities;
import com.android.launcher3.logger.LauncherAtom;
-import com.android.launcher3.logger.LauncherAtom.Attribute;
import com.android.launcher3.logger.LauncherAtom.ContainerInfo;
import com.android.launcher3.logger.LauncherAtom.FolderContainer.ParentContainerCase;
import com.android.launcher3.logger.LauncherAtom.FolderIcon;
import com.android.launcher3.logger.LauncherAtom.FromState;
-import com.android.launcher3.logger.LauncherAtom.LauncherAttributes;
import com.android.launcher3.logger.LauncherAtom.ToState;
import com.android.launcher3.logger.LauncherAtomExtensions.DeviceSearchResultContainer;
-import com.android.launcher3.logger.LauncherAtomExtensions.DeviceSearchResultContainer.SearchAttributes;
import com.android.launcher3.logger.LauncherAtomExtensions.ExtendedContainers;
import com.android.launcher3.logging.InstanceId;
import com.android.launcher3.logging.StatsLogManager;
@@ -63,7 +56,6 @@ import com.android.launcher3.model.data.FolderInfo;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.util.Executors;
import com.android.launcher3.util.LogConfig;
-import com.android.launcher3.views.ActivityContext;
import com.android.systemui.shared.system.InteractionJankMonitorWrapper;
import com.android.systemui.shared.system.SysUiStatsLog;
@@ -84,7 +76,6 @@ import java.util.concurrent.CopyOnWriteArrayList;
public class StatsLogCompatManager extends StatsLogManager {
private static final String TAG = "StatsLog";
- private static final String LATENCY_TAG = "StatsLatencyLog";
private static final boolean IS_VERBOSE = Utilities.isPropertyEnabled(LogConfig.STATSLOG);
private static final InstanceId DEFAULT_INSTANCE_ID = InstanceId.fakeInstanceId(0);
// LauncherAtom.ItemInfo.getDefaultInstance() should be used but until launcher proto migrates
@@ -93,15 +84,7 @@ public class StatsLogCompatManager extends StatsLogManager {
private static final int FOLDER_HIERARCHY_OFFSET = 100;
private static final int SEARCH_RESULT_HIERARCHY_OFFSET = 200;
private static final int EXTENDED_CONTAINERS_HIERARCHY_OFFSET = 300;
- private static final int ALL_APPS_HIERARCHY_OFFSET = 400;
-
- /**
- * Flags for converting SearchAttribute to integer value.
- */
- private static final int SEARCH_ATTRIBUTES_CORRECTED_QUERY = 1 << 0;
- private static final int SEARCH_ATTRIBUTES_DIRECT_MATCH = 1 << 1;
- private static final int SEARCH_ATTRIBUTES_ENTRY_STATE_ALL_APPS = 1 << 2;
- private static final int SEARCH_ATTRIBUTES_ENTRY_STATE_QSB = 1 << 3;
+ private static final int ATTRIBUTE_MULTIPLIER = 100;
public static final CopyOnWriteArrayList<StatsLogConsumer> LOGS_CONSUMER =
new CopyOnWriteArrayList<>();
@@ -114,12 +97,7 @@ public class StatsLogCompatManager extends StatsLogManager {
@Override
protected StatsLogger createLogger() {
- return new StatsCompatLogger(mContext, mActivityContext);
- }
-
- @Override
- protected StatsLatencyLogger createLatencyLogger() {
- return new StatsCompatLatencyLogger(mContext, mActivityContext);
+ return new StatsCompatLogger(mContext);
}
/**
@@ -130,12 +108,13 @@ public class StatsLogCompatManager extends StatsLogManager {
if (IS_VERBOSE) {
Log.d(TAG, String.format("\nwriteSnapshot(%d):\n%s", instanceId.getId(), info));
}
- if (!Utilities.ATLEAST_R || Utilities.IS_RUNNING_IN_TEST_HARNESS) {
+ if (!Utilities.ATLEAST_R) {
return;
}
SysUiStatsLog.write(SysUiStatsLog.LAUNCHER_SNAPSHOT,
LAUNCHER_WORKSPACE_SNAPSHOT.getId() /* event_id */,
- info.getItemCase().getNumber() /* target_id */,
+ info.getAttribute().getNumber() * ATTRIBUTE_MULTIPLIER
+ + info.getItemCase().getNumber() /* target_id */,
instanceId.getId() /* instance_id */,
0 /* uid */,
getPackageName(info) /* package_name */,
@@ -148,50 +127,11 @@ public class StatsLogCompatManager extends StatsLogManager {
getParentPageId(info) /* page_id_parent */,
getHierarchy(info) /* hierarchy */,
info.getIsWork() /* is_work_profile */,
- 0 /* origin */,
+ info.getAttribute().getNumber() /* origin */,
getCardinality(info) /* cardinality */,
info.getWidget().getSpanX(),
info.getWidget().getSpanY(),
- getFeatures(info),
- getAttributes(info) /* attributes */
- );
- }
-
- private static byte[] getAttributes(LauncherAtom.ItemInfo itemInfo) {
- LauncherAttributes.Builder responseBuilder = LauncherAttributes.newBuilder();
- itemInfo.getItemAttributesList().stream().map(Attribute::getNumber).forEach(
- responseBuilder::addItemAttributes);
- return responseBuilder.build().toByteArray();
- }
-
- /**
- * Builds {@link StatsEvent} from {@link LauncherAtom.ItemInfo}. Used for pulled atom callback
- * implementation.
- */
- public static StatsEvent buildStatsEvent(LauncherAtom.ItemInfo info,
- @Nullable InstanceId instanceId) {
- return SysUiStatsLog.buildStatsEvent(
- SysUiStatsLog.LAUNCHER_LAYOUT_SNAPSHOT, // atom ID,
- LAUNCHER_WORKSPACE_SNAPSHOT.getId(), // event_id = 1;
- info.getItemCase().getNumber(), // item_id = 2;
- instanceId == null ? 0 : instanceId.getId(), //instance_id = 3;
- 0, //uid = 4 [(is_uid) = true];
- getPackageName(info), // package_name = 5;
- getComponentName(info), // component_name = 6;
- getGridX(info, false), //grid_x = 7 [default = -1];
- getGridY(info, false), //grid_y = 8 [default = -1];
- getPageId(info), // page_id = 9 [default = -2];
- getGridX(info, true), //grid_x_parent = 10 [default = -1];
- getGridY(info, true), //grid_y_parent = 11 [default = -1];
- getParentPageId(info), //page_id_parent = 12 [default = -2];
- getHierarchy(info), // container_id = 13;
- info.getIsWork(), // is_work_profile = 14;
- 0, // attribute_id = 15;
- getCardinality(info), // cardinality = 16;
- info.getWidget().getSpanX(), // span_x = 17 [default = 1];
- info.getWidget().getSpanY(), // span_y = 18 [default = 1];
- getAttributes(info) /* attributes */
- );
+ getFeatures(info));
}
/**
@@ -200,11 +140,8 @@ public class StatsLogCompatManager extends StatsLogManager {
private static class StatsCompatLogger implements StatsLogger {
private static final ItemInfo DEFAULT_ITEM_INFO = new ItemInfo();
- static {
- DEFAULT_ITEM_INFO.itemType = ITEM_TYPE_NON_ACTIONABLE;
- }
- private final Context mContext;
- private final Optional<ActivityContext> mActivityContext;
+
+ private Context mContext;
private ItemInfo mItemInfo = DEFAULT_ITEM_INFO;
private InstanceId mInstanceId = DEFAULT_INSTANCE_ID;
private OptionalInt mRank = OptionalInt.empty();
@@ -217,9 +154,8 @@ public class StatsLogCompatManager extends StatsLogManager {
private SliceItem mSliceItem;
private LauncherAtom.Slice mSlice;
- StatsCompatLogger(Context context, ActivityContext activityContext) {
+ StatsCompatLogger(Context context) {
mContext = context;
- mActivityContext = Optional.ofNullable(activityContext);
}
@Override
@@ -371,9 +307,6 @@ public class StatsLogCompatManager extends StatsLogManager {
mRank.ifPresent(itemInfoBuilder::setRank);
mContainerInfo.ifPresent(itemInfoBuilder::setContainerInfo);
- mActivityContext.ifPresent(activityContext ->
- activityContext.applyOverwritesToLogItem(itemInfoBuilder));
-
if (mFromState.isPresent() || mToState.isPresent() || mEditText.isPresent()) {
FolderIcon.Builder folderIconBuilder = itemInfoBuilder
.getFolderIcon()
@@ -394,31 +327,19 @@ public class StatsLogCompatManager extends StatsLogManager {
if (IS_VERBOSE) {
String name = (event instanceof Enum) ? ((Enum) event).name() :
event.getId() + "";
- StringBuilder logStringBuilder = new StringBuilder("\n");
- if (instanceId != DEFAULT_INSTANCE_ID) {
- logStringBuilder.append(String.format("InstanceId:%s ", instanceId));
- }
- logStringBuilder.append(name);
- if (srcState != LAUNCHER_STATE_UNSPECIFIED
- || dstState != LAUNCHER_STATE_UNSPECIFIED) {
- logStringBuilder.append(
- String.format("(State:%s->%s)", getStateString(srcState),
- getStateString(dstState)));
- }
- if (atomInfo.hasContainerInfo()) {
- logStringBuilder.append("\n").append(atomInfo);
- }
- Log.d(TAG, logStringBuilder.toString());
+
+ Log.d(TAG, instanceId == DEFAULT_INSTANCE_ID
+ ? String.format("\n%s (State:%s->%s)\n%s", name, getStateString(srcState),
+ getStateString(dstState), atomInfo)
+ : String.format("\n%s (State:%s->%s) (InstanceId:%s)\n%s", name,
+ getStateString(srcState), getStateString(dstState), instanceId,
+ atomInfo));
}
for (StatsLogConsumer consumer : LOGS_CONSUMER) {
consumer.consume(event, atomInfo);
}
- // TODO: remove this when b/231648228 is fixed.
- if (Utilities.IS_RUNNING_IN_TEST_HARNESS) {
- return;
- }
SysUiStatsLog.write(
SysUiStatsLog.LAUNCHER_EVENT,
SysUiStatsLog.LAUNCHER_UICHANGED__ACTION__DEFAULT_ACTION /* deprecated */,
@@ -427,7 +348,8 @@ public class StatsLogCompatManager extends StatsLogManager {
null /* launcher extensions, deprecated */,
false /* quickstep_enabled, deprecated */,
event.getId() /* event_id */,
- atomInfo.getItemCase().getNumber() /* target_id */,
+ atomInfo.getAttribute().getNumber() * ATTRIBUTE_MULTIPLIER
+ + atomInfo.getItemCase().getNumber() /* target_id */,
instanceId.getId() /* instance_id TODO */,
0 /* uid TODO */,
getPackageName(atomInfo) /* package_name */,
@@ -445,91 +367,14 @@ public class StatsLogCompatManager extends StatsLogManager {
atomInfo.getFolderIcon().getToLabelState().getNumber() /* toState */,
atomInfo.getFolderIcon().getLabelInfo() /* edittext */,
getCardinality(atomInfo) /* cardinality */,
- getFeatures(atomInfo) /* features */,
- getSearchAttributes(atomInfo) /* searchAttributes */,
- getAttributes(atomInfo) /* attributes */
- );
- }
- }
-
- /**
- * Helps to construct and log statsd compatible latency events.
- */
- private static class StatsCompatLatencyLogger implements StatsLatencyLogger {
- private final Context mContext;
- private final Optional<ActivityContext> mActivityContext;
- private InstanceId mInstanceId = DEFAULT_INSTANCE_ID;
- private LatencyType mType = LatencyType.UNKNOWN;
- private int mPackageId = 0;
- private long mLatencyInMillis;
- private int mQueryLength = -1;
-
- StatsCompatLatencyLogger(Context context, ActivityContext activityContext) {
- mContext = context;
- mActivityContext = Optional.ofNullable(activityContext);
- }
-
- @Override
- public StatsLatencyLogger withInstanceId(InstanceId instanceId) {
- this.mInstanceId = instanceId;
- return this;
- }
-
- @Override
- public StatsLatencyLogger withType(LatencyType type) {
- this.mType = type;
- return this;
- }
-
- @Override
- public StatsLatencyLogger withPackageId(int packageId) {
- this.mPackageId = packageId;
- return this;
- }
-
- @Override
- public StatsLatencyLogger withLatency(long latencyInMillis) {
- this.mLatencyInMillis = latencyInMillis;
- return this;
- }
-
- @Override
- public StatsLatencyLogger withQueryLength(int queryLength) {
- this.mQueryLength = queryLength;
- return this;
- }
-
- @Override
- public void log(EventEnum event) {
- if (IS_VERBOSE) {
- String name = (event instanceof Enum) ? ((Enum) event).name() :
- event.getId() + "";
- StringBuilder logStringBuilder = new StringBuilder("\n");
- logStringBuilder.append(String.format("InstanceId:%s ", mInstanceId));
- logStringBuilder.append(String.format("%s=%sms", name, mLatencyInMillis));
- Log.d(LATENCY_TAG, logStringBuilder.toString());
- }
-
- SysUiStatsLog.write(SysUiStatsLog.LAUNCHER_LATENCY,
- event.getId(), // event_id
- mInstanceId.getId(), // instance_id
- mPackageId, // package_id
- mLatencyInMillis, // latency_in_millis
- mType.getId(), //type
- mQueryLength // query_length
- );
+ getFeatures(atomInfo) /* features */);
}
}
private static int getCardinality(LauncherAtom.ItemInfo info) {
- if (Utilities.IS_RUNNING_IN_TEST_HARNESS) {
- return 0;
- }
switch (info.getContainerInfo().getContainerCase()) {
case PREDICTED_HOTSEAT_CONTAINER:
return info.getContainerInfo().getPredictedHotseatContainer().getCardinality();
- case TASK_BAR_CONTAINER:
- return info.getContainerInfo().getTaskBarContainer().getCardinality();
case SEARCH_RESULT_CONTAINER:
return info.getContainerInfo().getSearchResultContainer().getQueryLength();
case EXTENDED_CONTAINERS:
@@ -582,18 +427,14 @@ public class StatsLogCompatManager extends StatsLogManager {
}
private static int getGridX(LauncherAtom.ItemInfo info, boolean parent) {
- LauncherAtom.ContainerInfo containerInfo = info.getContainerInfo();
- if (containerInfo.getContainerCase() == FOLDER) {
+ if (info.getContainerInfo().getContainerCase() == FOLDER) {
if (parent) {
- return containerInfo.getFolder().getWorkspace().getGridX();
+ return info.getContainerInfo().getFolder().getWorkspace().getGridX();
} else {
- return containerInfo.getFolder().getGridX();
+ return info.getContainerInfo().getFolder().getGridX();
}
- } else if (containerInfo.getContainerCase() == EXTENDED_CONTAINERS) {
- return containerInfo.getExtendedContainers()
- .getDeviceSearchResultContainer().getGridX();
} else {
- return containerInfo.getWorkspace().getGridX();
+ return info.getContainerInfo().getWorkspace().getGridX();
}
}
@@ -620,8 +461,6 @@ public class StatsLogCompatManager extends StatsLogManager {
return info.getContainerInfo().getHotseat().getIndex();
case PREDICTED_HOTSEAT_CONTAINER:
return info.getContainerInfo().getPredictedHotseatContainer().getIndex();
- case TASK_BAR_CONTAINER:
- return info.getContainerInfo().getTaskBarContainer().getIndex();
default:
return info.getContainerInfo().getWorkspace().getPageIndex();
}
@@ -644,9 +483,6 @@ public class StatsLogCompatManager extends StatsLogManager {
}
private static int getHierarchy(LauncherAtom.ItemInfo info) {
- if (Utilities.IS_RUNNING_IN_TEST_HARNESS) {
- return 0;
- }
if (info.getContainerInfo().getContainerCase() == FOLDER) {
return info.getContainerInfo().getFolder().getParentContainerCase().getNumber()
+ FOLDER_HIERARCHY_OFFSET;
@@ -656,9 +492,6 @@ public class StatsLogCompatManager extends StatsLogManager {
} else if (info.getContainerInfo().getContainerCase() == EXTENDED_CONTAINERS) {
return info.getContainerInfo().getExtendedContainers().getContainerCase().getNumber()
+ EXTENDED_CONTAINERS_HIERARCHY_OFFSET;
- } else if (info.getContainerInfo().getContainerCase() == ALL_APPS_CONTAINER) {
- return info.getContainerInfo().getAllAppsContainer().getParentContainerCase()
- .getNumber() + ALL_APPS_HIERARCHY_OFFSET;
} else {
return info.getContainerInfo().getContainerCase().getNumber();
}
@@ -686,39 +519,6 @@ public class StatsLogCompatManager extends StatsLogManager {
return 0;
}
- private static int getSearchAttributes(LauncherAtom.ItemInfo info) {
- if (Utilities.IS_RUNNING_IN_TEST_HARNESS) {
- return 0;
- }
- ContainerInfo containerInfo = info.getContainerInfo();
- if (containerInfo.getContainerCase() == EXTENDED_CONTAINERS
- && containerInfo.getExtendedContainers().getContainerCase()
- == DEVICE_SEARCH_RESULT_CONTAINER
- && containerInfo.getExtendedContainers()
- .getDeviceSearchResultContainer().hasSearchAttributes()
- ) {
- return searchAttributesToInt(containerInfo.getExtendedContainers()
- .getDeviceSearchResultContainer().getSearchAttributes());
- }
- return 0;
- }
-
- private static int searchAttributesToInt(SearchAttributes searchAttributes) {
- int response = 0;
- if (searchAttributes.getCorrectedQuery()) {
- response = response | SEARCH_ATTRIBUTES_CORRECTED_QUERY;
- }
- if (searchAttributes.getDirectMatch()) {
- response = response | SEARCH_ATTRIBUTES_DIRECT_MATCH;
- }
- if (searchAttributes.getEntryState() == SearchAttributes.EntryState.ALL_APPS) {
- response = response | SEARCH_ATTRIBUTES_ENTRY_STATE_ALL_APPS;
- } else if (searchAttributes.getEntryState() == SearchAttributes.EntryState.QSB) {
- response = response | SEARCH_ATTRIBUTES_ENTRY_STATE_QSB;
- }
-
- return response;
- }
/**
* Interface to get stats log while it is dispatched to the system
diff --git a/quickstep/src/com/android/quickstep/util/ActivityInitListener.java b/quickstep/src/com/android/quickstep/util/ActivityInitListener.java
index aeec36f63c..b9879ab82b 100644
--- a/quickstep/src/com/android/quickstep/util/ActivityInitListener.java
+++ b/quickstep/src/com/android/quickstep/util/ActivityInitListener.java
@@ -15,6 +15,11 @@
*/
package com.android.quickstep.util;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.Handler;
+
import com.android.launcher3.BaseActivity;
import com.android.launcher3.util.ActivityTracker;
import com.android.launcher3.util.ActivityTracker.SchedulerCallback;
@@ -70,4 +75,17 @@ public class ActivityInitListener<T extends BaseActivity> implements
mIsRegistered = false;
mOnInitListener = null;
}
+
+ /**
+ * Starts the given intent with the provided animation. Unlike {@link #register(Intent)}, this
+ * method will not call {@link #init} if the activity already exists, it will only call it when
+ * we get handleIntent() for the provided intent that we're starting.
+ */
+ public void registerAndStartActivity(Intent intent, RemoteAnimationProvider animProvider,
+ Context context, Handler handler, long duration) {
+ register();
+
+ Bundle options = animProvider.toActivityOptions(handler, duration, context).toBundle();
+ context.startActivity(new Intent(intent), options);
+ }
}
diff --git a/quickstep/src/com/android/quickstep/util/AnimatorControllerWithResistance.java b/quickstep/src/com/android/quickstep/util/AnimatorControllerWithResistance.java
index 7c838332a6..7f94839971 100644
--- a/quickstep/src/com/android/quickstep/util/AnimatorControllerWithResistance.java
+++ b/quickstep/src/com/android/quickstep/util/AnimatorControllerWithResistance.java
@@ -48,16 +48,14 @@ import com.android.quickstep.views.RecentsView;
public class AnimatorControllerWithResistance {
private enum RecentsResistanceParams {
- FROM_APP(0.75f, 0.5f, 1f, false),
- FROM_APP_TABLET(1f, 0.7f, 1f, true),
- FROM_OVERVIEW(1f, 0.75f, 0.5f, false);
+ FROM_APP(0.75f, 0.5f, 1f),
+ FROM_OVERVIEW(1f, 0.75f, 0.5f);
RecentsResistanceParams(float scaleStartResist, float scaleMaxResist,
- float translationFactor, boolean stopScalingAtTop) {
+ float translationFactor) {
this.scaleStartResist = scaleStartResist;
this.scaleMaxResist = scaleMaxResist;
this.translationFactor = translationFactor;
- this.stopScalingAtTop = stopScalingAtTop;
}
/**
@@ -75,12 +73,6 @@ public class AnimatorControllerWithResistance {
* where 0 will keep it centered and 1 will have it barely touch the top of the screen.
*/
public final float translationFactor;
-
- /**
- * Whether to end scaling effect when the scaled down version of TaskView's top reaches the
- * non-scaled version of TaskView's top.
- */
- public final boolean stopScalingAtTop;
}
private static final TimeInterpolator RECENTS_SCALE_RESIST_INTERPOLATOR = DEACCEL;
@@ -158,7 +150,8 @@ public class AnimatorControllerWithResistance {
Rect startRect = new Rect();
PagedOrientationHandler orientationHandler = params.recentsOrientedState
.getOrientationHandler();
- LauncherActivityInterface.INSTANCE.calculateTaskSize(params.context, params.dp, startRect);
+ LauncherActivityInterface.INSTANCE.calculateTaskSize(params.context, params.dp, startRect,
+ orientationHandler);
long distanceToCover = startRect.bottom;
PendingAnimation resistAnim = params.resistAnim != null
? params.resistAnim
@@ -167,20 +160,6 @@ public class AnimatorControllerWithResistance {
PointF pivot = new PointF();
float fullscreenScale = params.recentsOrientedState.getFullScreenScaleAndPivot(
startRect, params.dp, pivot);
-
- // Compute where the task view would be based on the end scale.
- RectF endRectF = new RectF(startRect);
- Matrix temp = new Matrix();
- temp.setScale(params.resistanceParams.scaleMaxResist,
- params.resistanceParams.scaleMaxResist, pivot.x, pivot.y);
- temp.mapRect(endRectF);
- // Translate such that the task view touches the top of the screen when drag does.
- float endTranslation = endRectF.top
- * orientationHandler.getSecondaryTranslationDirectionFactor()
- * params.resistanceParams.translationFactor;
- resistAnim.addFloat(params.translationTarget, params.translationProperty,
- params.startTranslation, endTranslation, RECENTS_TRANSLATE_RESIST_INTERPOLATOR);
-
float prevScaleRate = (fullscreenScale - params.startScale)
/ (params.dp.heightPx - startRect.bottom);
// This is what the scale would be at the end of the drag if we didn't apply resistance.
@@ -191,22 +170,30 @@ public class AnimatorControllerWithResistance {
params.startScale, endScale);
float maxResist = Utilities.getProgress(params.resistanceParams.scaleMaxResist,
params.startScale, endScale);
- float stopResist =
- params.resistanceParams.stopScalingAtTop ? 1f - startRect.top / endRectF.top : 1f;
final TimeInterpolator scaleInterpolator = t -> {
if (t < startResist) {
return t;
}
- if (t > stopResist) {
- return maxResist;
- }
- float resistProgress = Utilities.getProgress(t, startResist, stopResist);
+ float resistProgress = Utilities.getProgress(t, startResist, 1);
resistProgress = RECENTS_SCALE_RESIST_INTERPOLATOR.getInterpolation(resistProgress);
return startResist + resistProgress * (maxResist - startResist);
};
resistAnim.addFloat(params.scaleTarget, params.scaleProperty, params.startScale, endScale,
scaleInterpolator);
+ // Compute where the task view would be based on the end scale.
+ RectF endRectF = new RectF(startRect);
+ Matrix temp = new Matrix();
+ temp.setScale(params.resistanceParams.scaleMaxResist,
+ params.resistanceParams.scaleMaxResist, pivot.x, pivot.y);
+ temp.mapRect(endRectF);
+ // Translate such that the task view touches the top of the screen when drag does.
+ float endTranslation = endRectF.top
+ * orientationHandler.getSecondaryTranslationDirectionFactor()
+ * params.resistanceParams.translationFactor;
+ resistAnim.addFloat(params.translationTarget, params.translationProperty,
+ params.startTranslation, endTranslation, RECENTS_TRANSLATE_RESIST_INTERPOLATOR);
+
return resistAnim;
}
@@ -241,7 +228,7 @@ public class AnimatorControllerWithResistance {
// These are not required, or can have a default value that is generally correct.
@Nullable public PendingAnimation resistAnim = null;
- public RecentsResistanceParams resistanceParams;
+ public RecentsResistanceParams resistanceParams = RecentsResistanceParams.FROM_APP;
public float startScale = 1f;
public float startTranslation = 0f;
@@ -255,11 +242,6 @@ public class AnimatorControllerWithResistance {
this.scaleProperty = scaleProperty;
this.translationTarget = translationTarget;
this.translationProperty = translationProperty;
- if (dp.isTablet) {
- resistanceParams = RecentsResistanceParams.FROM_APP_TABLET;
- } else {
- resistanceParams = RecentsResistanceParams.FROM_APP;
- }
}
private RecentsParams setResistAnim(PendingAnimation resistAnim) {
diff --git a/quickstep/src/com/android/quickstep/util/AssistantUtilities.java b/quickstep/src/com/android/quickstep/util/AssistantUtilities.java
new file mode 100644
index 0000000000..336f7d1362
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/util/AssistantUtilities.java
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+package com.android.quickstep.util;
+
+import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.ACTIVITY_TYPE_ASSISTANT;
+
+import android.annotation.TargetApi;
+import android.app.TaskInfo;
+import android.content.Intent;
+import android.os.Build;
+
+import com.android.systemui.shared.system.ActivityManagerWrapper;
+
+/**
+ * Utility class for interacting with the Assistant.
+ */
+@TargetApi(Build.VERSION_CODES.Q)
+public final class AssistantUtilities {
+
+ /** Returns true if an Assistant activity that is excluded from recents is running. */
+ public static boolean isExcludedAssistantRunning() {
+ return isExcludedAssistant(ActivityManagerWrapper.getInstance().getRunningTask());
+ }
+
+ /** Returns true if the given task holds an Assistant activity that is excluded from recents. */
+ public static boolean isExcludedAssistant(TaskInfo info) {
+ return info != null
+ && info.configuration.windowConfiguration.getActivityType() == ACTIVITY_TYPE_ASSISTANT
+ && (info.baseIntent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) != 0;
+ }
+
+ private AssistantUtilities() {}
+}
diff --git a/quickstep/src/com/android/quickstep/util/BaseUnfoldMoveFromCenterAnimator.java b/quickstep/src/com/android/quickstep/util/BaseUnfoldMoveFromCenterAnimator.java
deleted file mode 100644
index 143042fb31..0000000000
--- a/quickstep/src/com/android/quickstep/util/BaseUnfoldMoveFromCenterAnimator.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Copyright (C) 2021 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.quickstep.util;
-
-import android.annotation.CallSuper;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.WindowManager;
-
-import com.android.systemui.shared.animation.UnfoldMoveFromCenterAnimator;
-import com.android.systemui.unfold.UnfoldTransitionProgressProvider.TransitionProgressListener;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Animation that moves launcher icons and widgets from center to the sides (final position)
- */
-public abstract class BaseUnfoldMoveFromCenterAnimator implements TransitionProgressListener {
-
- private final UnfoldMoveFromCenterAnimator mMoveFromCenterAnimation;
-
- private final Map<ViewGroup, Boolean> mOriginalClipToPadding = new HashMap<>();
- private final Map<ViewGroup, Boolean> mOriginalClipChildren = new HashMap<>();
-
- private boolean mAnimationInProgress = false;
-
- public BaseUnfoldMoveFromCenterAnimator(WindowManager windowManager) {
- mMoveFromCenterAnimation = new UnfoldMoveFromCenterAnimator(windowManager,
- new LauncherViewsMoveFromCenterTranslationApplier());
- }
-
- @CallSuper
- @Override
- public void onTransitionStarted() {
- mAnimationInProgress = true;
- mMoveFromCenterAnimation.updateDisplayProperties();
- onPrepareViewsForAnimation();
- onTransitionProgress(0f);
- }
-
- @CallSuper
- @Override
- public void onTransitionProgress(float progress) {
- mMoveFromCenterAnimation.onTransitionProgress(progress);
- }
-
- @CallSuper
- @Override
- public void onTransitionFinished() {
- mAnimationInProgress = false;
- mMoveFromCenterAnimation.onTransitionFinished();
- clearRegisteredViews();
- }
-
- /**
- * Re-prepares views for animation. This is useful in case views are re-bound while the
- * animation is in progress.
- */
- public void updateRegisteredViewsIfNeeded() {
- if (mAnimationInProgress) {
- clearRegisteredViews();
- onPrepareViewsForAnimation();
- }
- }
-
- private void clearRegisteredViews() {
- mMoveFromCenterAnimation.clearRegisteredViews();
-
- mOriginalClipChildren.clear();
- mOriginalClipToPadding.clear();
- }
-
- protected void onPrepareViewsForAnimation() {
-
- }
-
- protected void registerViewForAnimation(View view) {
- mMoveFromCenterAnimation.registerViewForAnimation(view);
- }
-
- protected void disableClipping(ViewGroup view) {
- mOriginalClipToPadding.put(view, view.getClipToPadding());
- mOriginalClipChildren.put(view, view.getClipChildren());
- view.setClipToPadding(false);
- view.setClipChildren(false);
- }
-
- protected void restoreClipping(ViewGroup view) {
- final Boolean originalClipToPadding = mOriginalClipToPadding.get(view);
- if (originalClipToPadding != null) {
- view.setClipToPadding(originalClipToPadding);
- }
- final Boolean originalClipChildren = mOriginalClipChildren.get(view);
- if (originalClipChildren != null) {
- view.setClipChildren(originalClipChildren);
- }
- }
-}
diff --git a/quickstep/src/com/android/quickstep/util/GroupTask.java b/quickstep/src/com/android/quickstep/util/GroupTask.java
deleted file mode 100644
index e2563e398d..0000000000
--- a/quickstep/src/com/android/quickstep/util/GroupTask.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2021 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.quickstep.util;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
-import com.android.launcher3.util.SplitConfigurationOptions.StagedSplitBounds;
-import com.android.systemui.shared.recents.model.Task;
-
-/**
- * A {@link Task} container that can contain one or two tasks, depending on if the two tasks
- * are represented as an app-pair in the recents task list.
- */
-public class GroupTask {
- public @NonNull Task task1;
- public @Nullable Task task2;
- public @Nullable StagedSplitBounds mStagedSplitBounds;
-
- public GroupTask(@NonNull Task t1, @Nullable Task t2,
- @Nullable StagedSplitBounds stagedSplitBounds) {
- task1 = t1;
- task2 = t2;
- mStagedSplitBounds = stagedSplitBounds;
- }
-
- public GroupTask(@NonNull GroupTask group) {
- task1 = new Task(group.task1);
- task2 = group.task2 != null
- ? new Task(group.task2)
- : null;
- mStagedSplitBounds = group.mStagedSplitBounds;
- }
-
- public boolean containsTask(int taskId) {
- return task1.key.id == taskId || (task2 != null && task2.key.id == taskId);
- }
-
- public boolean hasMultipleTasks() {
- return task2 != null;
- }
-}
diff --git a/quickstep/src/com/android/quickstep/util/ImageActionUtils.java b/quickstep/src/com/android/quickstep/util/ImageActionUtils.java
index 63d5b0dd50..de7dbd64f5 100644
--- a/quickstep/src/com/android/quickstep/util/ImageActionUtils.java
+++ b/quickstep/src/com/android/quickstep/util/ImageActionUtils.java
@@ -48,10 +48,10 @@ import androidx.annotation.WorkerThread;
import androidx.core.content.FileProvider;
import com.android.internal.app.ChooserActivity;
-import com.android.internal.util.ScreenshotHelper;
import com.android.launcher3.BuildConfig;
import com.android.quickstep.SystemUiProxy;
import com.android.systemui.shared.recents.model.Task;
+import com.android.systemui.shared.recents.utilities.BitmapUtil;
import java.io.File;
import java.io.FileOutputStream;
@@ -77,8 +77,7 @@ public class ImageActionUtils {
public static void saveScreenshot(SystemUiProxy systemUiProxy, Bitmap screenshot,
Rect screenshotBounds,
Insets visibleInsets, Task.TaskKey task) {
- systemUiProxy.handleImageBundleAsScreenshot(
- ScreenshotHelper.HardwareBitmapBundler.hardwareBitmapToBundle(screenshot),
+ systemUiProxy.handleImageBundleAsScreenshot(BitmapUtil.hardwareBitmapToBundle(screenshot),
screenshotBounds, visibleInsets, task);
}
@@ -155,18 +154,6 @@ public class ImageActionUtils {
@WorkerThread
public static void persistBitmapAndStartActivity(Context context, Bitmap bitmap, Rect crop,
Intent intent, BiFunction<Uri, Intent, Intent[]> uriToIntentMap, String tag) {
- persistBitmapAndStartActivity(context, bitmap, crop, intent, uriToIntentMap, tag,
- (Runnable) null);
- }
-
- /**
- * Starts activity based on given intent created from image uri.
- * @param exceptionCallback An optional callback to be called when the intent can't be resolved
- */
- @WorkerThread
- public static void persistBitmapAndStartActivity(Context context, Bitmap bitmap, Rect crop,
- Intent intent, BiFunction<Uri, Intent, Intent[]> uriToIntentMap, String tag,
- Runnable exceptionCallback) {
Intent[] intents = uriToIntentMap.apply(getImageUri(bitmap, crop, context, tag), intent);
try {
@@ -178,9 +165,6 @@ public class ImageActionUtils {
}
} catch (ActivityNotFoundException e) {
Log.e(TAG, "No activity found to receive image intent");
- if (exceptionCallback != null) {
- exceptionCallback.run();
- }
}
}
diff --git a/quickstep/src/com/android/quickstep/util/InputConsumerProxy.java b/quickstep/src/com/android/quickstep/util/InputConsumerProxy.java
index 91b53c7ff2..2e5b33ae24 100644
--- a/quickstep/src/com/android/quickstep/util/InputConsumerProxy.java
+++ b/quickstep/src/com/android/quickstep/util/InputConsumerProxy.java
@@ -19,14 +19,12 @@ import static android.view.MotionEvent.ACTION_CANCEL;
import static android.view.MotionEvent.ACTION_DOWN;
import static android.view.MotionEvent.ACTION_UP;
-import android.content.Context;
import android.util.Log;
import android.view.InputEvent;
import android.view.KeyEvent;
import android.view.MotionEvent;
import com.android.quickstep.InputConsumer;
-import com.android.quickstep.SimpleOrientationTouchTransformer;
import com.android.systemui.shared.system.InputConsumerController;
import java.util.function.Supplier;
@@ -39,8 +37,6 @@ public class InputConsumerProxy {
private static final String TAG = "InputConsumerProxy";
- private final Context mContext;
- private final Supplier<Integer> mRotationSupplier;
private final InputConsumerController mInputConsumerController;
private Runnable mCallback;
private Supplier<InputConsumer> mConsumerSupplier;
@@ -52,11 +48,8 @@ public class InputConsumerProxy {
private boolean mTouchInProgress = false;
private boolean mDestroyPending = false;
- public InputConsumerProxy(Context context, Supplier<Integer> rotationSupplier,
- InputConsumerController inputConsumerController,
+ public InputConsumerProxy(InputConsumerController inputConsumerController,
Runnable callback, Supplier<InputConsumer> consumerSupplier) {
- mContext = context;
- mRotationSupplier = rotationSupplier;
mInputConsumerController = inputConsumerController;
mCallback = callback;
mConsumerSupplier = consumerSupplier;
@@ -71,16 +64,7 @@ public class InputConsumerProxy {
private boolean onInputConsumerEvent(InputEvent ev) {
if (ev instanceof MotionEvent) {
- MotionEvent event = (MotionEvent) ev;
- int action = event.getActionMasked();
- boolean isHoverEvent = action == MotionEvent.ACTION_HOVER_ENTER
- || action == MotionEvent.ACTION_HOVER_MOVE
- || action == MotionEvent.ACTION_HOVER_EXIT;
- if (isHoverEvent) {
- onInputConsumerHoverEvent(event);
- } else {
- onInputConsumerMotionEvent(event);
- }
+ onInputConsumerMotionEvent((MotionEvent) ev);
} else if (ev instanceof KeyEvent) {
initInputConsumerIfNeeded();
mInputConsumer.onKeyEvent((KeyEvent) ev);
@@ -114,23 +98,12 @@ public class InputConsumerProxy {
}
}
if (mInputConsumer != null) {
- SimpleOrientationTouchTransformer.INSTANCE.get(mContext).transform(ev,
- mRotationSupplier.get());
mInputConsumer.onMotionEvent(ev);
}
return true;
}
- private void onInputConsumerHoverEvent(MotionEvent ev) {
- initInputConsumerIfNeeded();
- if (mInputConsumer != null) {
- SimpleOrientationTouchTransformer.INSTANCE.get(mContext).transform(ev,
- mRotationSupplier.get());
- mInputConsumer.onHoverEvent(ev);
- }
- }
-
public void destroy() {
if (mTouchInProgress) {
mDestroyPending = true;
diff --git a/quickstep/src/com/android/quickstep/util/LauncherUnfoldAnimationController.java b/quickstep/src/com/android/quickstep/util/LauncherUnfoldAnimationController.java
deleted file mode 100644
index 97be4370b9..0000000000
--- a/quickstep/src/com/android/quickstep/util/LauncherUnfoldAnimationController.java
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * Copyright (C) 2021 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.quickstep.util;
-
-import static com.android.launcher3.LauncherAnimUtils.HOTSEAT_SCALE_PROPERTY_FACTORY;
-import static com.android.launcher3.LauncherAnimUtils.SCALE_INDEX_UNFOLD_ANIMATION;
-import static com.android.launcher3.LauncherAnimUtils.WORKSPACE_SCALE_PROPERTY_FACTORY;
-import static com.android.launcher3.Utilities.comp;
-
-import android.annotation.Nullable;
-import android.util.FloatProperty;
-import android.util.MathUtils;
-import android.view.WindowManager;
-import android.view.WindowManagerGlobal;
-
-import androidx.core.view.OneShotPreDrawListener;
-
-import com.android.launcher3.Hotseat;
-import com.android.launcher3.Launcher;
-import com.android.launcher3.Workspace;
-import com.android.launcher3.util.HorizontalInsettableView;
-import com.android.systemui.unfold.UnfoldTransitionProgressProvider;
-import com.android.systemui.unfold.UnfoldTransitionProgressProvider.TransitionProgressListener;
-import com.android.systemui.unfold.util.NaturalRotationUnfoldProgressProvider;
-import com.android.systemui.unfold.util.ScopedUnfoldTransitionProgressProvider;
-
-/**
- * Controls animations that are happening during unfolding foldable devices
- */
-public class LauncherUnfoldAnimationController {
-
- // Percentage of the width of the quick search bar that will be reduced
- // from the both sides of the bar when progress is 0
- private static final float MAX_WIDTH_INSET_FRACTION = 0.15f;
- private static final FloatProperty<Workspace<?>> WORKSPACE_SCALE_PROPERTY =
- WORKSPACE_SCALE_PROPERTY_FACTORY.get(SCALE_INDEX_UNFOLD_ANIMATION);
- private static final FloatProperty<Hotseat> HOTSEAT_SCALE_PROPERTY =
- HOTSEAT_SCALE_PROPERTY_FACTORY.get(SCALE_INDEX_UNFOLD_ANIMATION);
-
- private final Launcher mLauncher;
- private final ScopedUnfoldTransitionProgressProvider mProgressProvider;
- private final NaturalRotationUnfoldProgressProvider mNaturalOrientationProgressProvider;
- private final UnfoldMoveFromCenterHotseatAnimator mUnfoldMoveFromCenterHotseatAnimator;
- private final UnfoldMoveFromCenterWorkspaceAnimator mUnfoldMoveFromCenterWorkspaceAnimator;
-
- @Nullable
- private HorizontalInsettableView mQsbInsettable;
-
- public LauncherUnfoldAnimationController(
- Launcher launcher,
- WindowManager windowManager,
- UnfoldTransitionProgressProvider unfoldTransitionProgressProvider) {
- mLauncher = launcher;
- mProgressProvider = new ScopedUnfoldTransitionProgressProvider(
- unfoldTransitionProgressProvider);
- mUnfoldMoveFromCenterHotseatAnimator = new UnfoldMoveFromCenterHotseatAnimator(launcher,
- windowManager);
- mUnfoldMoveFromCenterWorkspaceAnimator = new UnfoldMoveFromCenterWorkspaceAnimator(launcher,
- windowManager);
- mNaturalOrientationProgressProvider = new NaturalRotationUnfoldProgressProvider(launcher,
- WindowManagerGlobal.getWindowManagerService(), mProgressProvider);
- mNaturalOrientationProgressProvider.init();
-
- // Animated in all orientations
- mProgressProvider.addCallback(mUnfoldMoveFromCenterWorkspaceAnimator);
- mProgressProvider.addCallback(new LauncherScaleAnimationListener());
-
- // Animated only in natural orientation
- mNaturalOrientationProgressProvider.addCallback(new QsbAnimationListener());
- mNaturalOrientationProgressProvider.addCallback(mUnfoldMoveFromCenterHotseatAnimator);
- }
-
- /**
- * Called when launcher is resumed
- */
- public void onResume() {
- Hotseat hotseat = mLauncher.getHotseat();
- if (hotseat != null && hotseat.getQsb() instanceof HorizontalInsettableView) {
- mQsbInsettable = (HorizontalInsettableView) hotseat.getQsb();
- }
-
- OneShotPreDrawListener.add(mLauncher.getWorkspace(),
- () -> mProgressProvider.setReadyToHandleTransition(true));
- }
-
- /**
- * Called when launcher activity is paused
- */
- public void onPause() {
- mProgressProvider.setReadyToHandleTransition(false);
- mQsbInsettable = null;
- }
-
- /**
- * Called when launcher activity is destroyed
- */
- public void onDestroy() {
- mProgressProvider.destroy();
- mNaturalOrientationProgressProvider.destroy();
- }
-
- /** Called when launcher finished binding its items. */
- public void updateRegisteredViewsIfNeeded() {
- mUnfoldMoveFromCenterHotseatAnimator.updateRegisteredViewsIfNeeded();
- mUnfoldMoveFromCenterWorkspaceAnimator.updateRegisteredViewsIfNeeded();
- }
-
- private class QsbAnimationListener implements TransitionProgressListener {
-
- @Override
- public void onTransitionStarted() {
- }
-
- @Override
- public void onTransitionFinished() {
- if (mQsbInsettable != null) {
- mQsbInsettable.setHorizontalInsets(0);
- }
- }
-
- @Override
- public void onTransitionProgress(float progress) {
- if (mQsbInsettable != null) {
- float insetPercentage = comp(progress) * MAX_WIDTH_INSET_FRACTION;
- mQsbInsettable.setHorizontalInsets(insetPercentage);
- }
- }
- }
-
- private class LauncherScaleAnimationListener implements TransitionProgressListener {
-
- @Override
- public void onTransitionStarted() {
- mLauncher.getWorkspace().setPivotToScaleWithSelf(mLauncher.getHotseat());
- }
-
- @Override
- public void onTransitionFinished() {
- setScale(1);
- }
-
- @Override
- public void onTransitionProgress(float progress) {
- setScale(MathUtils.constrainedMap(0.85f, 1, 0, 1, progress));
- }
-
- private void setScale(float value) {
- WORKSPACE_SCALE_PROPERTY.setValue(mLauncher.getWorkspace(), value);
- HOTSEAT_SCALE_PROPERTY.setValue(mLauncher.getHotseat(), value);
- }
- }
-}
diff --git a/quickstep/src/com/android/quickstep/util/LauncherViewsMoveFromCenterTranslationApplier.java b/quickstep/src/com/android/quickstep/util/LauncherViewsMoveFromCenterTranslationApplier.java
deleted file mode 100644
index effdfdd97b..0000000000
--- a/quickstep/src/com/android/quickstep/util/LauncherViewsMoveFromCenterTranslationApplier.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2021 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.quickstep.util;
-
-import android.annotation.NonNull;
-import android.view.View;
-
-import com.android.launcher3.BubbleTextView;
-import com.android.launcher3.folder.FolderIcon;
-import com.android.launcher3.widget.NavigableAppWidgetHostView;
-import com.android.systemui.shared.animation.UnfoldMoveFromCenterAnimator.TranslationApplier;
-
-/**
- * Class that allows to set translations for move from center animation independently
- * from other translations for certain launcher views
- */
-public class LauncherViewsMoveFromCenterTranslationApplier implements TranslationApplier {
-
- @Override
- public void apply(@NonNull View view, float x, float y) {
- if (view instanceof NavigableAppWidgetHostView) {
- ((NavigableAppWidgetHostView) view).setTranslationForMoveFromCenterAnimation(x, y);
- } else if (view instanceof BubbleTextView) {
- ((BubbleTextView) view).setTranslationForMoveFromCenterAnimation(x, y);
- } else if (view instanceof FolderIcon) {
- ((FolderIcon) view).setTranslationForMoveFromCenterAnimation(x, y);
- } else {
- view.setTranslationX(x);
- view.setTranslationY(y);
- }
- }
-}
diff --git a/quickstep/src/com/android/quickstep/util/LayoutUtils.java b/quickstep/src/com/android/quickstep/util/LayoutUtils.java
index d0856bed20..8834dc2c6c 100644
--- a/quickstep/src/com/android/quickstep/util/LayoutUtils.java
+++ b/quickstep/src/com/android/quickstep/util/LayoutUtils.java
@@ -22,9 +22,8 @@ import android.view.ViewGroup;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.touch.PagedOrientationHandler;
-import com.android.launcher3.util.DisplayController;
-import com.android.launcher3.util.DisplayController.NavigationMode;
import com.android.quickstep.LauncherActivityInterface;
+import com.android.quickstep.SysUINavigationMode;
public class LayoutUtils {
@@ -33,7 +32,7 @@ public class LayoutUtils {
*/
public static float getDefaultSwipeHeight(Context context, DeviceProfile dp) {
float swipeHeight = dp.allAppsCellHeightPx - dp.allAppsIconTextSizePx;
- if (DisplayController.getNavigationMode(context) == NavigationMode.NO_BUTTON) {
+ if (SysUINavigationMode.getMode(context) == SysUINavigationMode.Mode.NO_BUTTON) {
swipeHeight -= dp.getInsets().bottom;
}
return swipeHeight;
@@ -43,7 +42,8 @@ public class LayoutUtils {
PagedOrientationHandler orientationHandler) {
// Track the bottom of the window.
Rect taskSize = new Rect();
- LauncherActivityInterface.INSTANCE.calculateTaskSize(context, dp, taskSize);
+ LauncherActivityInterface.INSTANCE.calculateTaskSize(
+ context, dp, taskSize, orientationHandler);
return orientationHandler.getDistanceToBottomOfRect(dp, taskSize);
}
diff --git a/quickstep/src/com/android/quickstep/util/MotionPauseDetector.java b/quickstep/src/com/android/quickstep/util/MotionPauseDetector.java
index b83e26e5de..1ed2da3051 100644
--- a/quickstep/src/com/android/quickstep/util/MotionPauseDetector.java
+++ b/quickstep/src/com/android/quickstep/util/MotionPauseDetector.java
@@ -23,7 +23,6 @@ import android.view.VelocityTracker;
import com.android.launcher3.Alarm;
import com.android.launcher3.R;
import com.android.launcher3.compat.AccessibilityManagerCompat;
-import com.android.launcher3.testing.TestProtocol;
/**
* Given positions along x- or y-axis, tracks velocity and acceleration and determines when there is
@@ -119,10 +118,9 @@ public class MotionPauseDetector {
* @param pointerIndex Index for the pointer being tracked in the motion event
*/
public void addPosition(MotionEvent ev, int pointerIndex) {
- long timeoutMs = TestProtocol.sForcePauseTimeout != null
- ? TestProtocol.sForcePauseTimeout
- : mMakePauseHarderToTrigger ? HARDER_TRIGGER_TIMEOUT : FORCE_PAUSE_TIMEOUT;
- mForcePauseTimeout.setAlarm(timeoutMs);
+ mForcePauseTimeout.setAlarm(mMakePauseHarderToTrigger
+ ? HARDER_TRIGGER_TIMEOUT
+ : FORCE_PAUSE_TIMEOUT);
float newVelocity = mVelocityProvider.addMotionEvent(ev, ev.getPointerId(pointerIndex));
if (mPreviousVelocity != null) {
checkMotionPaused(newVelocity, mPreviousVelocity, ev.getEventTime());
diff --git a/quickstep/src/com/android/quickstep/util/NavBarPosition.java b/quickstep/src/com/android/quickstep/util/NavBarPosition.java
index 527a6d2d9a..449dba8f26 100644
--- a/quickstep/src/com/android/quickstep/util/NavBarPosition.java
+++ b/quickstep/src/com/android/quickstep/util/NavBarPosition.java
@@ -15,27 +15,27 @@
*/
package com.android.quickstep.util;
-import static com.android.launcher3.util.DisplayController.NavigationMode.NO_BUTTON;
+import static com.android.quickstep.SysUINavigationMode.Mode.NO_BUTTON;
import android.view.Surface;
import com.android.launcher3.util.DisplayController.Info;
-import com.android.launcher3.util.DisplayController.NavigationMode;
+import com.android.quickstep.SysUINavigationMode;
/**
* Utility class to check nav bar position.
*/
public class NavBarPosition {
- private final NavigationMode mMode;
+ private final SysUINavigationMode.Mode mMode;
private final int mDisplayRotation;
- public NavBarPosition(NavigationMode mode, Info info) {
+ public NavBarPosition(SysUINavigationMode.Mode mode, Info info) {
mMode = mode;
mDisplayRotation = info.rotation;
}
- public NavBarPosition(NavigationMode mode, int displayRotation) {
+ public NavBarPosition(SysUINavigationMode.Mode mode, int displayRotation) {
mMode = mode;
mDisplayRotation = displayRotation;
}
diff --git a/quickstep/src/com/android/quickstep/util/OverviewToHomeAnim.java b/quickstep/src/com/android/quickstep/util/OverviewToHomeAnim.java
index 3cec1a4f1a..5cf4f0b97f 100644
--- a/quickstep/src/com/android/quickstep/util/OverviewToHomeAnim.java
+++ b/quickstep/src/com/android/quickstep/util/OverviewToHomeAnim.java
@@ -82,7 +82,7 @@ public class OverviewToHomeAnim {
// WorkspaceRevealAnim handles the depth, so don't interfere.
config.animFlags |= StateAnimationConfig.SKIP_DEPTH_CONTROLLER;
}
- config.duration = startState.getTransitionDuration(mLauncher, false /* isToState */);
+ config.duration = startState.getTransitionDuration(mLauncher);
AnimatorSet stateAnim = stateManager.createAtomicAnimation(
startState, NORMAL, config);
stateAnim.addListener(new AnimationSuccessListener() {
diff --git a/quickstep/src/com/android/quickstep/util/ProxyScreenStatusProvider.java b/quickstep/src/com/android/quickstep/util/ProxyScreenStatusProvider.java
deleted file mode 100644
index 3777c659e3..0000000000
--- a/quickstep/src/com/android/quickstep/util/ProxyScreenStatusProvider.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2021 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.quickstep.util;
-
-import androidx.annotation.NonNull;
-
-import com.android.systemui.unfold.updates.screen.ScreenStatusProvider;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Screen status provider implementation that exposes methods to provide screen
- * status updates to listeners. It is used to receive screen turned on event from
- * SystemUI to Launcher.
- */
-public class ProxyScreenStatusProvider implements ScreenStatusProvider {
-
- public static final ProxyScreenStatusProvider INSTANCE = new ProxyScreenStatusProvider();
- private final List<ScreenListener> mListeners = new ArrayList<>();
-
- /**
- * Called when the screen is on and ready (windows are drawn and screen blocker is removed)
- */
- public void onScreenTurnedOn() {
- mListeners.forEach(ScreenListener::onScreenTurnedOn);
- }
-
- @Override
- public void addCallback(@NonNull ScreenListener listener) {
- mListeners.add(listener);
- }
-
- @Override
- public void removeCallback(@NonNull ScreenListener listener) {
- mListeners.remove(listener);
- }
-}
diff --git a/quickstep/src/com/android/quickstep/util/QuickstepOnboardingPrefs.java b/quickstep/src/com/android/quickstep/util/QuickstepOnboardingPrefs.java
index fb32581508..6d6e802231 100644
--- a/quickstep/src/com/android/quickstep/util/QuickstepOnboardingPrefs.java
+++ b/quickstep/src/com/android/quickstep/util/QuickstepOnboardingPrefs.java
@@ -21,21 +21,20 @@ import static com.android.launcher3.LauncherState.ALL_APPS;
import static com.android.launcher3.LauncherState.HINT_STATE;
import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.launcher3.LauncherState.OVERVIEW;
-import static com.android.launcher3.util.DisplayController.NavigationMode.NO_BUTTON;
+import static com.android.quickstep.SysUINavigationMode.Mode.NO_BUTTON;
import android.content.SharedPreferences;
import com.android.launcher3.LauncherState;
import com.android.launcher3.Utilities;
import com.android.launcher3.Workspace;
-import com.android.launcher3.appprediction.AppsDividerView;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.hybridhotseat.HotseatPredictionController;
import com.android.launcher3.statemanager.StateManager;
import com.android.launcher3.statemanager.StateManager.StateListener;
import com.android.launcher3.uioverrides.QuickstepLauncher;
-import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.OnboardingPrefs;
+import com.android.quickstep.SysUINavigationMode;
import com.android.quickstep.views.AllAppsEduView;
/**
@@ -51,8 +50,8 @@ public class QuickstepOnboardingPrefs extends OnboardingPrefs<QuickstepLauncher>
stateManager.addStateListener(new StateListener<LauncherState>() {
@Override
public void onStateTransitionComplete(LauncherState finalState) {
- boolean swipeUpEnabled =
- DisplayController.getNavigationMode(mLauncher).hasGestures;
+ boolean swipeUpEnabled = SysUINavigationMode.INSTANCE
+ .get(mLauncher).getMode().hasGestures;
LauncherState prevState = stateManager.getLastState();
if (((swipeUpEnabled && finalState == OVERVIEW) || (!swipeUpEnabled
@@ -88,7 +87,7 @@ public class QuickstepOnboardingPrefs extends OnboardingPrefs<QuickstepLauncher>
});
}
- if (DisplayController.getNavigationMode(launcher) == NO_BUTTON
+ if (SysUINavigationMode.getMode(launcher) == NO_BUTTON
&& FeatureFlags.ENABLE_ALL_APPS_EDU.get()) {
stateManager.addStateListener(new StateListener<LauncherState>() {
private static final int MAX_NUM_SWIPES_TO_TRIGGER_EDU = 3;
@@ -133,24 +132,5 @@ public class QuickstepOnboardingPrefs extends OnboardingPrefs<QuickstepLauncher>
}
});
}
-
- if (!hasReachedMaxCount(ALL_APPS_VISITED_COUNT)) {
- mLauncher.getStateManager().addStateListener(new StateListener<LauncherState>() {
- @Override
- public void onStateTransitionComplete(LauncherState finalState) {
- if (finalState == ALL_APPS) {
- incrementEventCount(ALL_APPS_VISITED_COUNT);
- return;
- }
-
- boolean hasReachedMaxCount = hasReachedMaxCount(ALL_APPS_VISITED_COUNT);
- mLauncher.getAppsView().getFloatingHeaderView().findFixedRowByType(
- AppsDividerView.class).setShowAllAppsLabel(!hasReachedMaxCount);
- if (hasReachedMaxCount) {
- mLauncher.getStateManager().removeStateListener(this);
- }
- }
- });
- }
}
}
diff --git a/quickstep/src/com/android/quickstep/util/RecentsAtomicAnimationFactory.java b/quickstep/src/com/android/quickstep/util/RecentsAtomicAnimationFactory.java
index edaa32637a..5c72c8fe26 100644
--- a/quickstep/src/com/android/quickstep/util/RecentsAtomicAnimationFactory.java
+++ b/quickstep/src/com/android/quickstep/util/RecentsAtomicAnimationFactory.java
@@ -15,13 +15,10 @@
*/
package com.android.quickstep.util;
-import static com.android.launcher3.testing.TestProtocol.BAD_STATE;
import static com.android.quickstep.views.RecentsView.ADJACENT_PAGE_HORIZONTAL_OFFSET;
import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
-import android.util.Log;
import androidx.dynamicanimation.animation.DynamicAnimation;
@@ -30,8 +27,6 @@ import com.android.launcher3.statemanager.StateManager.AtomicAnimationFactory;
import com.android.launcher3.statemanager.StatefulActivity;
import com.android.quickstep.views.RecentsView;
-import java.util.Arrays;
-
public class RecentsAtomicAnimationFactory<ACTIVITY_TYPE extends StatefulActivity, STATE_TYPE>
extends AtomicAnimationFactory<STATE_TYPE> {
@@ -51,30 +46,8 @@ public class RecentsAtomicAnimationFactory<ACTIVITY_TYPE extends StatefulActivit
public Animator createStateElementAnimation(int index, float... values) {
switch (index) {
case INDEX_RECENTS_FADE_ANIM:
- ObjectAnimator alpha = ObjectAnimator.ofFloat(mActivity.getOverviewPanel(),
+ return ObjectAnimator.ofFloat(mActivity.getOverviewPanel(),
RecentsView.CONTENT_ALPHA, values);
- Log.d(BAD_STATE, "RAAF createStateElementAnimation alpha="
- + Arrays.toString(values));
- alpha.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationStart(Animator animation) {
- Log.d(BAD_STATE, "RAAF createStateElementAnimation onStart");
- }
-
- @Override
- public void onAnimationCancel(Animator animation) {
- RecentsView recent = mActivity.getOverviewPanel();
- float alpha = recent == null ? -1 : RecentsView.CONTENT_ALPHA.get(recent);
- Log.d(BAD_STATE, "RAAF createStateElementAnimation onCancel, alpha="
- + alpha);
- }
-
- @Override
- public void onAnimationEnd(Animator animation) {
- Log.d(BAD_STATE, "RAAF createStateElementAnimation onEnd");
- }
- });
- return alpha;
case INDEX_RECENTS_TRANSLATE_X_ANIM: {
RecentsView rv = mActivity.getOverviewPanel();
return new SpringAnimationBuilder(mActivity)
diff --git a/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java b/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java
index 6038a22de8..7cfd151cda 100644
--- a/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java
+++ b/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java
@@ -52,7 +52,6 @@ import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.SettingsCache;
import com.android.quickstep.BaseActivityInterface;
import com.android.quickstep.SystemUiProxy;
-import com.android.quickstep.TaskAnimationManager;
import com.android.quickstep.views.TaskView;
import java.lang.annotation.Retention;
@@ -102,8 +101,6 @@ public class RecentsOrientedState implements
// Whether the swipe gesture is running, so the recents would stay locked in the
// current orientation
private static final int FLAG_SWIPE_UP_NOT_RUNNING = 1 << 8;
- // Ignore shared prefs for home rotation rotation, allowing it in if the activity supports it
- private static final int FLAG_IGNORE_ALLOW_HOME_ROTATION_PREF = 1 << 9;
private static final int MASK_MULTIPLE_ORIENTATION_SUPPORTED_BY_DEVICE =
FLAG_MULTIPLE_ORIENTATION_SUPPORTED_BY_ACTIVITY
@@ -165,7 +162,7 @@ public class RecentsOrientedState implements
*/
public void setDeviceProfile(DeviceProfile deviceProfile) {
boolean oldMultipleOrientationsSupported = isMultipleOrientationSupportedByDevice();
- setFlag(FLAG_MULTIPLE_ORIENTATION_SUPPORTED_BY_DENSITY, !deviceProfile.isTablet);
+ setFlag(FLAG_MULTIPLE_ORIENTATION_SUPPORTED_BY_DENSITY, !deviceProfile.allowRotation);
if (mListenersInitialized) {
boolean newMultipleOrientationsSupported = isMultipleOrientationSupportedByDevice();
// If isMultipleOrientationSupportedByDevice is changed, init or destroy listeners
@@ -221,8 +218,8 @@ public class RecentsOrientedState implements
private boolean updateHandler() {
mRecentsActivityRotation = inferRecentsActivityRotation(mDisplayRotation);
- if (mRecentsActivityRotation == mTouchRotation || (isRecentsActivityRotationAllowed()
- && (mFlags & FLAG_SWIPE_UP_NOT_RUNNING) != 0)) {
+ if (mRecentsActivityRotation == mTouchRotation
+ || (canRecentsActivityRotate() && (mFlags & FLAG_SWIPE_UP_NOT_RUNNING) != 0)) {
mOrientationHandler = PagedOrientationHandler.PORTRAIT;
} else if (mTouchRotation == ROTATION_90) {
mOrientationHandler = PagedOrientationHandler.LANDSCAPE;
@@ -256,7 +253,7 @@ public class RecentsOrientedState implements
private boolean setFlag(int mask, boolean enabled) {
boolean wasRotationEnabled = !TestProtocol.sDisableSensorRotation
&& (mFlags & VALUE_ROTATION_WATCHER_ENABLED) == VALUE_ROTATION_WATCHER_ENABLED
- && !isRecentsActivityRotationAllowed();
+ && !canRecentsActivityRotate();
if (enabled) {
mFlags |= mask;
} else {
@@ -265,7 +262,7 @@ public class RecentsOrientedState implements
boolean isRotationEnabled = !TestProtocol.sDisableSensorRotation
&& (mFlags & VALUE_ROTATION_WATCHER_ENABLED) == VALUE_ROTATION_WATCHER_ENABLED
- && !isRecentsActivityRotationAllowed();
+ && !canRecentsActivityRotate();
if (wasRotationEnabled != isRotationEnabled) {
UI_HELPER_EXECUTOR.execute(() -> {
if (isRotationEnabled) {
@@ -307,7 +304,6 @@ public class RecentsOrientedState implements
private void initMultipleOrientationListeners() {
mSharedPrefs.registerOnSharedPreferenceChangeListener(this);
mSettingsCache.register(ROTATION_SETTING_URI, mRotationChangeListener);
- updateAutoRotateSetting();
}
private void destroyMultipleOrientationListeners() {
@@ -344,11 +340,6 @@ public class RecentsOrientedState implements
@SurfaceRotation
public int getDisplayRotation() {
- if (TaskAnimationManager.SHELL_TRANSITIONS_ROTATION) {
- // When shell transitions are enabled, both the display and activity rotations should
- // be the same once the gesture starts
- return mRecentsActivityRotation;
- }
return mDisplayRotation;
}
@@ -374,22 +365,24 @@ public class RecentsOrientedState implements
== MASK_MULTIPLE_ORIENTATION_SUPPORTED_BY_DEVICE;
}
- public void ignoreAllowHomeRotationPreference() {
- setFlag(FLAG_IGNORE_ALLOW_HOME_ROTATION_PREF, true);
- }
-
public boolean isRecentsActivityRotationAllowed() {
// Activity rotation is allowed if the multi-simulated-rotation is not supported
// (fallback recents or tablets) or activity rotation is enabled by various settings.
return ((mFlags & MASK_MULTIPLE_ORIENTATION_SUPPORTED_BY_DEVICE)
!= MASK_MULTIPLE_ORIENTATION_SUPPORTED_BY_DEVICE)
- || (mFlags & (FLAG_IGNORE_ALLOW_HOME_ROTATION_PREF
- | FLAG_HOME_ROTATION_ALLOWED_IN_PREFS
+ || (mFlags & (FLAG_HOME_ROTATION_ALLOWED_IN_PREFS
| FLAG_MULTIWINDOW_ROTATION_ALLOWED
| FLAG_HOME_ROTATION_FORCE_ENABLED_FOR_TESTING)) != 0;
}
/**
+ * Returns true if the activity can rotate, if allowed by system rotation settings
+ */
+ public boolean canRecentsActivityRotate() {
+ return (mFlags & FLAG_SYSTEM_ROTATION_ALLOWED) != 0 && isRecentsActivityRotationAllowed();
+ }
+
+ /**
* Enables or disables the rotation watcher for listening to rotation callbacks
*/
public void setRotationWatcherEnabled(boolean isEnabled) {
@@ -403,17 +396,9 @@ public class RecentsOrientedState implements
Rect insets = dp.getInsets();
float fullWidth = dp.widthPx;
float fullHeight = dp.heightPx;
- if (TaskView.clipLeft(dp)) {
- fullWidth -= insets.left;
- }
- if (TaskView.clipRight(dp)) {
- fullWidth -= insets.right;
- }
- if (TaskView.clipTop(dp)) {
- fullHeight -= insets.top;
- }
- if (TaskView.clipBottom(dp)) {
- fullHeight -= insets.bottom;
+ if (TaskView.CLIP_STATUS_AND_NAV_BARS) {
+ fullWidth -= insets.left + insets.right;
+ fullHeight -= insets.top + insets.bottom;
}
getTaskDimension(mContext, dp, outPivot);
@@ -607,7 +592,17 @@ public class RecentsOrientedState implements
width = Math.min(currentSize.x, currentSize.y);
height = Math.max(currentSize.x, currentSize.y);
}
- return idp.getBestMatch(width, height, mRecentsActivityRotation);
+
+ DeviceProfile bestMatch = idp.supportedProfiles.get(0);
+ float minDiff = Float.MAX_VALUE;
+ for (DeviceProfile profile : idp.supportedProfiles) {
+ float diff = Math.abs(profile.widthPx - width) + Math.abs(profile.heightPx - height);
+ if (diff < minDiff) {
+ minDiff = diff;
+ bestMatch = profile;
+ }
+ }
+ return bestMatch;
}
private static String nameAndAddress(Object obj) {
diff --git a/quickstep/src/com/android/quickstep/util/RectFSpringAnim.java b/quickstep/src/com/android/quickstep/util/RectFSpringAnim.java
index c4909de510..02ec68a8d9 100644
--- a/quickstep/src/com/android/quickstep/util/RectFSpringAnim.java
+++ b/quickstep/src/com/android/quickstep/util/RectFSpringAnim.java
@@ -15,31 +15,24 @@
*/
package com.android.quickstep.util;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
import android.animation.Animator;
import android.content.Context;
import android.graphics.PointF;
-import android.graphics.Rect;
import android.graphics.RectF;
-import androidx.annotation.IntDef;
import androidx.annotation.Nullable;
import androidx.dynamicanimation.animation.DynamicAnimation.OnAnimationEndListener;
import androidx.dynamicanimation.animation.FloatPropertyCompat;
import androidx.dynamicanimation.animation.SpringAnimation;
import androidx.dynamicanimation.animation.SpringForce;
-import com.android.launcher3.DeviceProfile;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.anim.FlingSpringAnim;
-import com.android.launcher3.touch.OverScroll;
import com.android.launcher3.util.DynamicResource;
import com.android.quickstep.RemoteAnimationTargets.ReleaseCheck;
import com.android.systemui.plugins.ResourceProvider;
-import java.lang.annotation.Retention;
import java.util.ArrayList;
import java.util.List;
@@ -101,6 +94,7 @@ public class RectFSpringAnim extends ReleaseCheck {
private float mCurrentCenterX;
private float mCurrentY;
// If true, tracking the bottom of the rects, else tracking the top.
+ private boolean mTrackingBottomY;
private float mCurrentScaleProgress;
private FlingSpringAnim mRectXAnim;
private FlingSpringAnim mRectYAnim;
@@ -111,68 +105,20 @@ public class RectFSpringAnim extends ReleaseCheck {
private boolean mRectScaleAnimEnded;
private float mMinVisChange;
- private int mMaxVelocityPxPerS;
-
- /**
- * Indicates which part of the start & target rects we are interpolating between.
- */
- public static final int TRACKING_TOP = 0;
- public static final int TRACKING_CENTER = 1;
- public static final int TRACKING_BOTTOM = 2;
-
- @Retention(SOURCE)
- @IntDef(value = {TRACKING_TOP,
- TRACKING_CENTER,
- TRACKING_BOTTOM})
- public @interface Tracking{}
+ private float mYOvershoot;
- @Tracking
- public final int mTracking;
-
- public RectFSpringAnim(RectF startRect, RectF targetRect, Context context,
- @Nullable DeviceProfile deviceProfile) {
+ public RectFSpringAnim(RectF startRect, RectF targetRect, Context context) {
mStartRect = startRect;
mTargetRect = targetRect;
mCurrentCenterX = mStartRect.centerX();
+ mTrackingBottomY = startRect.bottom < targetRect.bottom;
+ mCurrentY = mTrackingBottomY ? mStartRect.bottom : mStartRect.top;
+
ResourceProvider rp = DynamicResource.provider(context);
mMinVisChange = rp.getDimension(R.dimen.swipe_up_fling_min_visible_change);
- mMaxVelocityPxPerS = (int) rp.getDimension(R.dimen.swipe_up_max_velocity);
+ mYOvershoot = rp.getDimension(R.dimen.swipe_up_y_overshoot);
setCanRelease(true);
-
- if (deviceProfile == null) {
- mTracking = startRect.bottom < targetRect.bottom
- ? TRACKING_BOTTOM
- : TRACKING_TOP;
- } else {
- int heightPx = deviceProfile.heightPx;
- Rect padding = deviceProfile.workspacePadding;
-
- final float topThreshold = heightPx / 3f;
- final float bottomThreshold = deviceProfile.heightPx - padding.bottom;
-
- if (targetRect.bottom > bottomThreshold) {
- mTracking = TRACKING_BOTTOM;
- } else if (targetRect.top < topThreshold) {
- mTracking = TRACKING_TOP;
- } else {
- mTracking = TRACKING_CENTER;
- }
- }
-
- mCurrentY = getTrackedYFromRect(mStartRect);
- }
-
- private float getTrackedYFromRect(RectF rect) {
- switch (mTracking) {
- case TRACKING_TOP:
- return rect.top;
- case TRACKING_BOTTOM:
- return rect.bottom;
- case TRACKING_CENTER:
- default:
- return rect.centerY();
- }
}
public void onTargetPositionChanged() {
@@ -181,22 +127,10 @@ public class RectFSpringAnim extends ReleaseCheck {
}
if (mRectYAnim != null) {
- switch (mTracking) {
- case TRACKING_TOP:
- if (mRectYAnim.getTargetPosition() != mTargetRect.top) {
- mRectYAnim.updatePosition(mCurrentY, mTargetRect.top);
- }
- break;
- case TRACKING_BOTTOM:
- if (mRectYAnim.getTargetPosition() != mTargetRect.bottom) {
- mRectYAnim.updatePosition(mCurrentY, mTargetRect.bottom);
- }
- break;
- case TRACKING_CENTER:
- if (mRectYAnim.getTargetPosition() != mTargetRect.centerY()) {
- mRectYAnim.updatePosition(mCurrentY, mTargetRect.centerY());
- }
- break;
+ if (mTrackingBottomY && mRectYAnim.getTargetPosition() != mTargetRect.bottom) {
+ mRectYAnim.updatePosition(mCurrentY, mTargetRect.bottom);
+ } else if (!mTrackingBottomY && mRectYAnim.getTargetPosition() != mTargetRect.top) {
+ mRectYAnim.updatePosition(mCurrentY, mTargetRect.top);
}
}
}
@@ -225,29 +159,22 @@ public class RectFSpringAnim extends ReleaseCheck {
maybeOnEnd();
});
- // We dampen the user velocity here to keep the natural feeling and to prevent the
- // rect from straying too from a linear path.
- final float xVelocityPxPerS = velocityPxPerMs.x * 1000;
- final float yVelocityPxPerS = velocityPxPerMs.y * 1000;
- final float dampedXVelocityPxPerS = OverScroll.dampedScroll(
- Math.abs(xVelocityPxPerS), mMaxVelocityPxPerS) * Math.signum(xVelocityPxPerS);
- final float dampedYVelocityPxPerS = OverScroll.dampedScroll(
- Math.abs(yVelocityPxPerS), mMaxVelocityPxPerS) * Math.signum(yVelocityPxPerS);
-
float startX = mCurrentCenterX;
float endX = mTargetRect.centerX();
float minXValue = Math.min(startX, endX);
float maxXValue = Math.max(startX, endX);
-
mRectXAnim = new FlingSpringAnim(this, context, RECT_CENTER_X, startX, endX,
- dampedXVelocityPxPerS, mMinVisChange, minXValue, maxXValue, onXEndListener);
+ velocityPxPerMs.x * 1000, mMinVisChange, minXValue, maxXValue, 1f, onXEndListener);
+ float startVelocityY = velocityPxPerMs.y * 1000;
+ // Scale the Y velocity based on the initial velocity to tune the curves.
+ float springVelocityFactor = 0.1f + 0.9f * Math.abs(startVelocityY) / 20000.0f;
float startY = mCurrentY;
- float endY = getTrackedYFromRect(mTargetRect);
- float minYValue = Math.min(startY, endY);
+ float endY = mTrackingBottomY ? mTargetRect.bottom : mTargetRect.top;
+ float minYValue = Math.min(startY, endY - mYOvershoot);
float maxYValue = Math.max(startY, endY);
- mRectYAnim = new FlingSpringAnim(this, context, RECT_Y, startY, endY, dampedYVelocityPxPerS,
- mMinVisChange, minYValue, maxYValue, onYEndListener);
+ mRectYAnim = new FlingSpringAnim(this, context, RECT_Y, startY, endY, startVelocityY,
+ mMinVisChange, minYValue, maxYValue, springVelocityFactor, onYEndListener);
float minVisibleChange = Math.abs(1f / mStartRect.height());
ResourceProvider rp = DynamicResource.provider(context);
@@ -307,28 +234,15 @@ public class RectFSpringAnim extends ReleaseCheck {
mTargetRect.width());
float currentHeight = Utilities.mapRange(mCurrentScaleProgress, mStartRect.height(),
mTargetRect.height());
- switch (mTracking) {
- case TRACKING_TOP:
- mCurrentRect.set(mCurrentCenterX - currentWidth / 2,
- mCurrentY,
- mCurrentCenterX + currentWidth / 2,
- mCurrentY + currentHeight);
- break;
- case TRACKING_BOTTOM:
- mCurrentRect.set(mCurrentCenterX - currentWidth / 2,
- mCurrentY - currentHeight,
- mCurrentCenterX + currentWidth / 2,
- mCurrentY);
- break;
- case TRACKING_CENTER:
- mCurrentRect.set(mCurrentCenterX - currentWidth / 2,
- mCurrentY - currentHeight / 2,
- mCurrentCenterX + currentWidth / 2,
- mCurrentY + currentHeight / 2);
- break;
+ if (mTrackingBottomY) {
+ mCurrentRect.set(mCurrentCenterX - currentWidth / 2, mCurrentY - currentHeight,
+ mCurrentCenterX + currentWidth / 2, mCurrentY);
+ } else {
+ mCurrentRect.set(mCurrentCenterX - currentWidth / 2, mCurrentY,
+ mCurrentCenterX + currentWidth / 2, mCurrentY + currentHeight);
}
for (OnUpdateListener onUpdateListener : mOnUpdateListeners) {
- onUpdateListener.onUpdate(mCurrentRect, mCurrentScaleProgress);
+ onUpdateListener.onUpdate(null, mCurrentRect, mCurrentScaleProgress);
}
}
}
@@ -353,12 +267,7 @@ public class RectFSpringAnim extends ReleaseCheck {
}
public interface OnUpdateListener {
- /**
- * Called when an update is made to the animation.
- * @param currentRect The rect of the window.
- * @param progress [0, 1] The progress of the rect scale animation.
- */
- void onUpdate(RectF currentRect, float progress);
+ void onUpdate(@Nullable AppCloseConfig values, RectF currentRect, float progress);
default void onCancel() { }
}
diff --git a/quickstep/src/com/android/quickstep/util/RectFSpringAnim2.java b/quickstep/src/com/android/quickstep/util/RectFSpringAnim2.java
new file mode 100644
index 0000000000..c331a136d9
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/util/RectFSpringAnim2.java
@@ -0,0 +1,370 @@
+/*
+ * Copyright (C) 2021 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.quickstep.util;
+
+import static com.android.launcher3.Utilities.dpToPx;
+import static com.android.launcher3.anim.Interpolators.LINEAR;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ObjectAnimator;
+import android.animation.ValueAnimator;
+import android.content.Context;
+import android.graphics.PointF;
+import android.graphics.RectF;
+import android.util.PathParser;
+import android.util.Property;
+import android.view.animation.Interpolator;
+
+import androidx.core.view.animation.PathInterpolatorCompat;
+import androidx.dynamicanimation.animation.FloatPropertyCompat;
+import androidx.dynamicanimation.animation.SpringAnimation;
+import androidx.dynamicanimation.animation.SpringForce;
+
+import com.android.launcher3.R;
+import com.android.launcher3.Utilities;
+import com.android.launcher3.util.DynamicResource;
+import com.android.systemui.plugins.ResourceProvider;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+
+/**
+ * Applies spring forces to animate from a starting rect to a target rect,
+ * while providing update callbacks to the caller.
+ */
+public class RectFSpringAnim2 extends RectFSpringAnim {
+
+ private static final FloatPropertyCompat<RectFSpringAnim2> RECT_CENTER_X =
+ new FloatPropertyCompat<RectFSpringAnim2>("rectCenterXSpring") {
+ @Override
+ public float getValue(RectFSpringAnim2 anim) {
+ return anim.mCurrentCenterX;
+ }
+
+ @Override
+ public void setValue(RectFSpringAnim2 anim, float currentCenterX) {
+ anim.mCurrentCenterX = currentCenterX;
+ anim.onUpdate();
+ }
+ };
+
+ private static final FloatPropertyCompat<RectFSpringAnim2> RECT_Y =
+ new FloatPropertyCompat<RectFSpringAnim2>("rectYSpring") {
+ @Override
+ public float getValue(RectFSpringAnim2 anim) {
+ return anim.mCurrentCenterY;
+ }
+
+ @Override
+ public void setValue(RectFSpringAnim2 anim, float y) {
+ anim.mCurrentCenterY = y;
+ anim.onUpdate();
+ }
+ };
+
+ private static final Property<RectFSpringAnim2, Float> PROGRESS =
+ new Property<RectFSpringAnim2, Float>(Float.class, "rectFProgress") {
+ @Override
+ public Float get(RectFSpringAnim2 rectFSpringAnim) {
+ return rectFSpringAnim.mProgress;
+ }
+
+ @Override
+ public void set(RectFSpringAnim2 rectFSpringAnim, Float progress) {
+ rectFSpringAnim.mProgress = progress;
+ rectFSpringAnim.onUpdate();
+ }
+ };
+
+ private final RectF mStartRect;
+ private final RectF mTargetRect;
+ private final RectF mCurrentRect = new RectF();
+ private final List<OnUpdateListener> mOnUpdateListeners = new ArrayList<>();
+ private final List<Animator.AnimatorListener> mAnimatorListeners = new ArrayList<>();
+
+ private float mCurrentCenterX;
+ private float mCurrentCenterY;
+
+ private float mTargetX;
+ private float mTargetY;
+
+ // If true, tracking the bottom of the rects, else tracking the top.
+ private float mProgress;
+ private SpringAnimation mRectXAnim;
+ private SpringAnimation mRectYAnim;
+ private ValueAnimator mRectScaleAnim;
+ private boolean mAnimsStarted;
+ private boolean mRectXAnimEnded;
+ private boolean mRectYAnimEnded;
+ private boolean mRectScaleAnimEnded;
+
+ private final float mXDamping;
+ private final float mXStiffness;
+
+ private final float mYDamping;
+ private float mYStiffness;
+
+ private long mDuration;
+
+ private final Interpolator mCloseInterpolator;
+
+ private AppCloseConfig mValues;
+ final float mStartRadius;
+ final float mEndRadius;
+
+ final float mHomeTransYEnd;
+ final float mScaleStart;
+
+ public RectFSpringAnim2(RectF startRect, RectF targetRect, Context context, float startRadius,
+ float endRadius) {
+ super(startRect, targetRect, context);
+ mStartRect = startRect;
+ mTargetRect = targetRect;
+
+ mCurrentCenterY = mStartRect.centerY();
+ mCurrentCenterX = mStartRect.centerX();
+
+ mTargetY = mTargetRect.centerY();
+ mTargetX = mTargetRect.centerX();
+
+ ResourceProvider rp = DynamicResource.provider(context);
+ mXDamping = rp.getFloat(R.dimen.swipe_up_rect_2_x_damping_ratio);
+ mXStiffness = rp.getFloat(R.dimen.swipe_up_rect_2_x_stiffness);
+
+ mYDamping = rp.getFloat(R.dimen.swipe_up_rect_2_y_damping_ratio);
+ mYStiffness = rp.getFloat(R.dimen.swipe_up_rect_2_y_stiffness);
+ mDuration = Math.round(rp.getFloat(R.dimen.swipe_up_duration));
+
+ mHomeTransYEnd = dpToPx(rp.getFloat(R.dimen.swipe_up_trans_y_dp));
+ mScaleStart = rp.getFloat(R.dimen.swipe_up_scale_start);
+
+ mCloseInterpolator = getAppCloseInterpolator(context);
+
+ // End on a "round-enough" radius so that the shape reveal doesn't have to do too much
+ // rounding at the end of the animation.
+ mStartRadius = startRadius;
+ mEndRadius = endRadius;
+
+ setCanRelease(true);
+ }
+
+ public void onTargetPositionChanged() {
+ if (mRectXAnim != null && mTargetX != mTargetRect.centerX()) {
+ mTargetX = mTargetRect.centerX();
+ mRectXAnim.animateToFinalPosition(mTargetX);
+ }
+
+ if (mRectYAnim != null) {
+ if (mTargetY != mTargetRect.centerY()) {
+ mTargetY = mTargetRect.centerY();
+ mRectYAnim.animateToFinalPosition(mTargetY);
+ }
+ }
+ }
+
+ public void addOnUpdateListener(OnUpdateListener onUpdateListener) {
+ mOnUpdateListeners.add(onUpdateListener);
+ }
+
+ public void addAnimatorListener(Animator.AnimatorListener animatorListener) {
+ mAnimatorListeners.add(animatorListener);
+ }
+
+ /**
+ * Starts the fling/spring animation.
+ * @param context The activity context.
+ * @param velocityPxPerMs Velocity of swipe in px/ms.
+ */
+ public void start(Context context, PointF velocityPxPerMs) {
+ mRectXAnim = new SpringAnimation(this, RECT_CENTER_X)
+ .setStartValue(mCurrentCenterX)
+ .setStartVelocity(velocityPxPerMs.x * 1000)
+ .setSpring(new SpringForce(mTargetX)
+ .setStiffness(mXStiffness)
+ .setDampingRatio(mXDamping));
+ mRectXAnim.addEndListener(((animation, canceled, centerX, velocityX) -> {
+ mRectXAnimEnded = true;
+ maybeOnEnd();
+ }));
+
+ mRectYAnim = new SpringAnimation(this, RECT_Y)
+ .setStartValue(mCurrentCenterY)
+ .setStartVelocity(velocityPxPerMs.y * 1000)
+ .setSpring(new SpringForce(mTargetY)
+ .setStiffness(mYStiffness)
+ .setDampingRatio(mYDamping));
+ mRectYAnim.addEndListener(((animation, canceled, centerY, velocityY) -> {
+ mRectYAnimEnded = true;
+ maybeOnEnd();
+ }));
+
+ mRectScaleAnim = ObjectAnimator.ofFloat(this, PROGRESS, 0, 1f)
+ .setDuration(mDuration);
+ mRectScaleAnim.setInterpolator(mCloseInterpolator);
+ mRectScaleAnim.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mRectScaleAnimEnded = true;
+ maybeOnEnd();
+ }
+ });
+
+ mValues = buildConfig();
+ mRectScaleAnim.addUpdateListener(mValues);
+
+ setCanRelease(false);
+ mAnimsStarted = true;
+
+ mRectXAnim.start();
+ mRectYAnim.start();
+ mRectScaleAnim.start();
+ for (Animator.AnimatorListener animatorListener : mAnimatorListeners) {
+ animatorListener.onAnimationStart(null);
+ }
+ }
+
+ private AppCloseConfig buildConfig() {
+ return new AppCloseConfig() {
+ FloatProp mHomeTransY = new FloatProp(0, mHomeTransYEnd, 0, mDuration, LINEAR);
+ FloatProp mHomeScale = new FloatProp(mScaleStart, 1f, 0, mDuration, LINEAR);
+ FloatProp mWindowFadeOut = new FloatProp(1f, 0f, 0, 116, LINEAR);
+ // There should be a slight overlap b/w window fading out and fg fading in.
+ // (fg startDelay < window fade out duration)
+ FloatProp mFgFadeIn = new FloatProp(0, 255f, 100, mDuration - 100, LINEAR);
+ FloatProp mRadius = new FloatProp(mStartRadius, mEndRadius, 0, mDuration, LINEAR);
+ FloatProp mThreePointInterpolation = new FloatProp(0, 1, 0, mDuration, LINEAR);
+
+ @Override
+ public float getWorkspaceTransY() {
+ return mHomeTransY.value;
+ }
+
+ @Override
+ public float getWorkspaceScale() {
+ return mHomeScale.value;
+ }
+
+ @Override
+ public float getWindowAlpha() {
+ return mWindowFadeOut.value;
+ }
+
+ @Override
+ public int getFgAlpha() {
+ return (int) mFgFadeIn.value;
+ }
+
+ @Override
+ public float getCornerRadius() {
+ return mRadius.value;
+ }
+
+ @Override
+ public float getInterpolatedProgress() {
+ return mThreePointInterpolation.value;
+ }
+
+ @Override
+ public void onUpdate(float percent, boolean initOnly) {}
+ };
+ }
+
+ public void end() {
+ if (mAnimsStarted) {
+ if (mRectXAnim.canSkipToEnd()) {
+ mRectXAnim.skipToEnd();
+ }
+ if (mRectYAnim.canSkipToEnd()) {
+ mRectYAnim.skipToEnd();
+ }
+ mRectScaleAnim.end();
+ }
+ mRectXAnimEnded = true;
+ mRectYAnimEnded = true;
+ mRectScaleAnimEnded = true;
+ maybeOnEnd();
+ }
+
+ private boolean isEnded() {
+ return mRectXAnimEnded && mRectYAnimEnded && mRectScaleAnimEnded;
+ }
+
+ private void onUpdate() {
+ if (isEnded()) {
+ // Prevent further updates from being called. This can happen between callbacks for
+ // ending the x/y/scale animations.
+ return;
+ }
+
+ if (!mOnUpdateListeners.isEmpty()) {
+ float rectProgress = mProgress;
+ float currentWidth = Utilities.mapRange(rectProgress, mStartRect.width(),
+ mTargetRect.width());
+ float currentHeight = Utilities.mapRange(rectProgress, mStartRect.height(),
+ mTargetRect.height());
+
+ mCurrentRect.set(mCurrentCenterX - currentWidth / 2,
+ mCurrentCenterY - currentHeight / 2,
+ mCurrentCenterX + currentWidth / 2,
+ mCurrentCenterY + currentHeight / 2);
+
+ float currentPlayTime = mRectScaleAnimEnded ? mRectScaleAnim.getDuration()
+ : mRectScaleAnim.getCurrentPlayTime();
+ float linearProgress = Math.min(1f, currentPlayTime / mRectScaleAnim.getDuration());
+ for (OnUpdateListener onUpdateListener : mOnUpdateListeners) {
+ onUpdateListener.onUpdate(mValues, mCurrentRect, linearProgress);
+ }
+ }
+ }
+
+ private void maybeOnEnd() {
+ if (mAnimsStarted && isEnded()) {
+ mAnimsStarted = false;
+ setCanRelease(true);
+ for (Animator.AnimatorListener animatorListener : mAnimatorListeners) {
+ animatorListener.onAnimationEnd(null);
+ }
+ }
+ }
+
+ public void cancel() {
+ if (mAnimsStarted) {
+ for (OnUpdateListener onUpdateListener : mOnUpdateListeners) {
+ onUpdateListener.onCancel();
+ }
+ }
+ end();
+ }
+
+ private Interpolator getAppCloseInterpolator(Context context) {
+ ResourceProvider rp = DynamicResource.provider(context);
+ String path = String.format(Locale.ENGLISH,
+ "M 0,0 C %f, %f, %f, %f, %f, %f C %f, %f, %f, %f, 1, 1",
+ rp.getFloat(R.dimen.c1_a),
+ rp.getFloat(R.dimen.c1_b),
+ rp.getFloat(R.dimen.c1_c),
+ rp.getFloat(R.dimen.c1_d),
+ rp.getFloat(R.dimen.mp_x),
+ rp.getFloat(R.dimen.mp_y),
+ rp.getFloat(R.dimen.c2_a),
+ rp.getFloat(R.dimen.c2_b),
+ rp.getFloat(R.dimen.c2_c),
+ rp.getFloat(R.dimen.c2_d));
+ return PathInterpolatorCompat.create(PathParser.createPathFromPathData(path));
+ }
+}
diff --git a/quickstep/src/com/android/quickstep/util/RemoteAnimationProvider.java b/quickstep/src/com/android/quickstep/util/RemoteAnimationProvider.java
index ee82ae67df..98dbd47ba4 100644
--- a/quickstep/src/com/android/quickstep/util/RemoteAnimationProvider.java
+++ b/quickstep/src/com/android/quickstep/util/RemoteAnimationProvider.java
@@ -16,14 +16,32 @@
package com.android.quickstep.util;
import android.animation.AnimatorSet;
+import android.app.ActivityOptions;
+import android.content.Context;
+import android.os.Handler;
+import com.android.launcher3.LauncherAnimationRunner;
+import com.android.launcher3.LauncherAnimationRunner.RemoteAnimationFactory;
+import com.android.systemui.shared.system.ActivityOptionsCompat;
+import com.android.systemui.shared.system.RemoteAnimationAdapterCompat;
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
public abstract class RemoteAnimationProvider {
+ RemoteAnimationFactory mAnimationRunner;
+
public abstract AnimatorSet createWindowAnimation(RemoteAnimationTargetCompat[] appTargets,
RemoteAnimationTargetCompat[] wallpaperTargets);
+ ActivityOptions toActivityOptions(Handler handler, long duration, Context context) {
+ mAnimationRunner = (transit, appTargets, wallpaperTargets, nonApps, result) ->
+ result.setAnimation(createWindowAnimation(appTargets, wallpaperTargets), context);
+ final LauncherAnimationRunner wrapper = new LauncherAnimationRunner(
+ handler, mAnimationRunner, false /* startAtFrontOfQueue */);
+ return ActivityOptionsCompat.makeRemoteAnimation(
+ new RemoteAnimationAdapterCompat(wrapper, duration, 0));
+ }
+
/**
* @return the target with the lowest opaque layer for a certain app animation, or null.
*/
diff --git a/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java b/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java
index 250235925e..a147b6808c 100644
--- a/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java
+++ b/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java
@@ -16,235 +16,158 @@
package com.android.quickstep.util;
-import static android.app.ActivityTaskManager.INVALID_TASK_ID;
-import static android.app.PendingIntent.FLAG_MUTABLE;
+import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
-import static com.android.launcher3.Utilities.postAsyncCallback;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
-import static com.android.launcher3.util.SplitConfigurationOptions.DEFAULT_SPLIT_RATIO;
import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_BOTTOM_OR_RIGHT;
import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT;
-import android.annotation.NonNull;
+import android.animation.AnimatorSet;
import android.app.ActivityOptions;
-import android.app.ActivityThread;
-import android.app.PendingIntent;
-import android.content.Context;
-import android.content.Intent;
+import android.content.res.Resources;
+import android.graphics.Rect;
import android.os.Handler;
import android.os.IBinder;
-import android.text.TextUtils;
-import android.view.RemoteAnimationAdapter;
+import android.os.Looper;
+import android.util.Pair;
+import android.view.Gravity;
import android.view.SurfaceControl;
import android.window.TransitionInfo;
import androidx.annotation.Nullable;
-import com.android.launcher3.statehandlers.DepthController;
-import com.android.launcher3.statemanager.StateManager;
-import com.android.launcher3.util.SplitConfigurationOptions;
-import com.android.launcher3.util.SplitConfigurationOptions.StagePosition;
+import com.android.launcher3.BaseActivity;
+import com.android.launcher3.BaseQuickstepLauncher;
+import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.InsettableFrameLayout;
+import com.android.launcher3.LauncherAnimationRunner;
+import com.android.launcher3.LauncherAnimationRunner.RemoteAnimationFactory;
+import com.android.launcher3.R;
+import com.android.launcher3.util.SplitConfigurationOptions.SplitPositionOption;
import com.android.quickstep.SystemUiProxy;
import com.android.quickstep.TaskAnimationManager;
import com.android.quickstep.TaskViewUtils;
-import com.android.quickstep.views.GroupedTaskView;
import com.android.quickstep.views.TaskView;
-import com.android.systemui.shared.recents.model.Task;
+import com.android.systemui.shared.system.ActivityOptionsCompat;
import com.android.systemui.shared.system.RemoteAnimationAdapterCompat;
import com.android.systemui.shared.system.RemoteAnimationRunnerCompat;
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
import com.android.systemui.shared.system.RemoteTransitionCompat;
import com.android.systemui.shared.system.RemoteTransitionRunner;
-import java.util.function.Consumer;
-
/**
* Represent data needed for the transient state when user has selected one app for split screen
* and is in the process of either a) selecting a second app or b) exiting intention to invoke split
*/
public class SplitSelectStateController {
- private final Context mContext;
- private final Handler mHandler;
private final SystemUiProxy mSystemUiProxy;
- private final StateManager mStateManager;
- private final DepthController mDepthController;
- private @StagePosition int mStagePosition;
- private Intent mInitialTaskIntent;
- private int mInitialTaskId = INVALID_TASK_ID;
- private int mSecondTaskId = INVALID_TASK_ID;
- private String mSecondTaskPackageName;
- private boolean mRecentsAnimationRunning;
- /** If not null, this is the TaskView we want to launch from */
- @Nullable
- private GroupedTaskView mLaunchingTaskView;
+ private TaskView mInitialTaskView;
+ private SplitPositionOption mInitialPosition;
+ private Rect mInitialBounds;
+ private final Handler mHandler;
- public SplitSelectStateController(Context context, Handler handler, StateManager stateManager,
- DepthController depthController) {
- mContext = context;
+ public SplitSelectStateController(Handler handler, SystemUiProxy systemUiProxy) {
+ mSystemUiProxy = systemUiProxy;
mHandler = handler;
- mSystemUiProxy = SystemUiProxy.INSTANCE.get(mContext);
- mStateManager = stateManager;
- mDepthController = depthController;
}
/**
* To be called after first task selected
*/
- public void setInitialTaskSelect(int taskId, @StagePosition int stagePosition) {
- mInitialTaskId = taskId;
- mStagePosition = stagePosition;
- mInitialTaskIntent = null;
- }
-
- public void setInitialTaskSelect(Intent intent, @StagePosition int stagePosition) {
- mInitialTaskIntent = intent;
- mStagePosition = stagePosition;
- mInitialTaskId = INVALID_TASK_ID;
+ public void setInitialTaskSelect(TaskView taskView, SplitPositionOption positionOption,
+ Rect initialBounds) {
+ mInitialTaskView = taskView;
+ mInitialPosition = positionOption;
+ mInitialBounds = initialBounds;
}
/**
- * To be called when the actual tasks ({@link #mInitialTaskId}, {@link #mSecondTaskId}) are
- * to be launched. Call after launcher side animations are complete.
+ * To be called after second task selected
*/
- public void launchSplitTasks(Consumer<Boolean> callback) {
- final Intent fillInIntent;
- if (mInitialTaskIntent != null) {
- fillInIntent = new Intent();
- if (TextUtils.equals(mInitialTaskIntent.getComponent().getPackageName(),
- mSecondTaskPackageName)) {
- fillInIntent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
- }
- } else {
- fillInIntent = null;
- }
- final PendingIntent pendingIntent =
- mInitialTaskIntent == null ? null : PendingIntent.getActivity(mContext, 0,
- mInitialTaskIntent, FLAG_MUTABLE);
- launchTasks(mInitialTaskId, pendingIntent, fillInIntent, mSecondTaskId, mStagePosition,
- callback, false /* freezeTaskList */, DEFAULT_SPLIT_RATIO);
- }
-
+ public void setSecondTaskId(TaskView taskView) {
+ if (TaskAnimationManager.ENABLE_SHELL_TRANSITIONS) {
+ // Assume initial task is for top/left part of screen
+ final int[] taskIds = mInitialPosition.mStagePosition == STAGE_POSITION_TOP_OR_LEFT
+ ? new int[]{mInitialTaskView.getTask().key.id, taskView.getTask().key.id}
+ : new int[]{taskView.getTask().key.id, mInitialTaskView.getTask().key.id};
- /**
- * To be called as soon as user selects the second task (even if animations aren't complete)
- * @param task The second task that will be launched.
- */
- public void setSecondTask(Task task) {
- mSecondTaskId = task.key.id;
- if (mInitialTaskIntent != null) {
- mSecondTaskPackageName = task.getTopComponent().getPackageName();
+ RemoteSplitLaunchAnimationRunner animationRunner =
+ new RemoteSplitLaunchAnimationRunner(mInitialTaskView, taskView);
+ mSystemUiProxy.startTasks(taskIds[0], null /* mainOptions */, taskIds[1],
+ null /* sideOptions */, STAGE_POSITION_BOTTOM_OR_RIGHT,
+ new RemoteTransitionCompat(animationRunner, MAIN_EXECUTOR));
+ return;
}
+ // Assume initial mInitialTaskId is for top/left part of screen
+ RemoteAnimationFactory initialSplitRunnerWrapped = new SplitLaunchAnimationRunner(
+ mInitialTaskView, 0);
+ RemoteAnimationFactory secondarySplitRunnerWrapped = new SplitLaunchAnimationRunner(
+ taskView, 1);
+ RemoteAnimationRunnerCompat initialSplitRunner = new LauncherAnimationRunner(
+ new Handler(Looper.getMainLooper()), initialSplitRunnerWrapped,
+ true /* startAtFrontOfQueue */);
+ RemoteAnimationRunnerCompat secondarySplitRunner = new LauncherAnimationRunner(
+ new Handler(Looper.getMainLooper()), secondarySplitRunnerWrapped,
+ true /* startAtFrontOfQueue */);
+ ActivityOptions initialOptions = ActivityOptionsCompat.makeRemoteAnimation(
+ new RemoteAnimationAdapterCompat(initialSplitRunner, 300, 150));
+ ActivityOptions secondaryOptions = ActivityOptionsCompat.makeRemoteAnimation(
+ new RemoteAnimationAdapterCompat(secondarySplitRunner, 300, 150));
+ mSystemUiProxy.startTask(mInitialTaskView.getTask().key.id, mInitialPosition.mStageType,
+ mInitialPosition.mStagePosition,
+ /*null*/ initialOptions.toBundle());
+ Pair<Integer, Integer> compliment = getComplimentaryStageAndPosition(mInitialPosition);
+ mSystemUiProxy.startTask(taskView.getTask().key.id, compliment.first,
+ compliment.second,
+ /*null*/ secondaryOptions.toBundle());
+ // After successful launch, call resetState
+ resetState();
}
/**
- * To be called when we want to launch split pairs from an existing GroupedTaskView.
- */
- public void launchTasks(GroupedTaskView groupedTaskView,
- Consumer<Boolean> callback, boolean freezeTaskList) {
- mLaunchingTaskView = groupedTaskView;
- TaskView.TaskIdAttributeContainer[] taskIdAttributeContainers =
- groupedTaskView.getTaskIdAttributeContainers();
- launchTasks(taskIdAttributeContainers[0].getTask().key.id,
- taskIdAttributeContainers[1].getTask().key.id,
- taskIdAttributeContainers[0].getStagePosition(), callback, freezeTaskList,
- groupedTaskView.getSplitRatio());
- }
-
- /**
- * To be called when we want to launch split pairs from Overview when split is initiated from
- * Overview.
- */
- public void launchTasks(int taskId1, int taskId2, @StagePosition int stagePosition,
- Consumer<Boolean> callback, boolean freezeTaskList, float splitRatio) {
- launchTasks(taskId1, null /* taskPendingIntent */, null /* fillInIntent */, taskId2,
- stagePosition, callback, freezeTaskList, splitRatio);
- }
-
- /**
- * To be called when we want to launch split pairs from Overview. Split can be initiated from
- * either Overview or home, or all apps. Either both taskIds are set, or a pending intent + a
- * fill in intent with a taskId2 are set.
- * @param taskPendingIntent is null when split is initiated from Overview
- * @param stagePosition representing location of task1
+ * @return {@link InsettableFrameLayout.LayoutParams} to correctly position the
+ * split placeholder view
*/
- public void launchTasks(int taskId1, @Nullable PendingIntent taskPendingIntent,
- @Nullable Intent fillInIntent, int taskId2, @StagePosition int stagePosition,
- Consumer<Boolean> callback, boolean freezeTaskList, float splitRatio) {
- // Assume initial task is for top/left part of screen
- final int[] taskIds = stagePosition == STAGE_POSITION_TOP_OR_LEFT
- ? new int[]{taskId1, taskId2}
- : new int[]{taskId2, taskId1};
- if (TaskAnimationManager.ENABLE_SHELL_TRANSITIONS) {
- RemoteSplitLaunchTransitionRunner animationRunner =
- new RemoteSplitLaunchTransitionRunner(taskId1, taskPendingIntent, taskId2,
- callback);
- mSystemUiProxy.startTasks(taskIds[0], null /* mainOptions */, taskIds[1],
- null /* sideOptions */, STAGE_POSITION_BOTTOM_OR_RIGHT, splitRatio,
- new RemoteTransitionCompat(animationRunner, MAIN_EXECUTOR,
- ActivityThread.currentActivityThread().getApplicationThread()));
- // TODO: handle intent + task with shell transition
+ public InsettableFrameLayout.LayoutParams getLayoutParamsForActivePosition(Resources resources,
+ DeviceProfile deviceProfile) {
+ InsettableFrameLayout.LayoutParams params =
+ new InsettableFrameLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT);
+ boolean topLeftPosition = mInitialPosition.mStagePosition == STAGE_POSITION_TOP_OR_LEFT;
+ if (deviceProfile.isLandscape) {
+ params.width = (int) resources.getDimension(R.dimen.split_placeholder_size);
+ params.gravity = topLeftPosition ? Gravity.START : Gravity.END;
} else {
- RemoteSplitLaunchAnimationRunner animationRunner =
- new RemoteSplitLaunchAnimationRunner(taskId1, taskPendingIntent, taskId2,
- callback);
- final RemoteAnimationAdapter adapter = new RemoteAnimationAdapter(
- RemoteAnimationAdapterCompat.wrapRemoteAnimationRunner(animationRunner),
- 300, 150,
- ActivityThread.currentActivityThread().getApplicationThread());
-
- ActivityOptions mainOpts = ActivityOptions.makeBasic();
- if (freezeTaskList) {
- mainOpts.setFreezeRecentTasksReordering();
- }
- if (taskPendingIntent == null) {
- mSystemUiProxy.startTasksWithLegacyTransition(taskIds[0], mainOpts.toBundle(),
- taskIds[1], null /* sideOptions */, STAGE_POSITION_BOTTOM_OR_RIGHT,
- splitRatio, adapter);
- } else {
- mSystemUiProxy.startIntentAndTaskWithLegacyTransition(taskPendingIntent,
- fillInIntent, taskId2, mainOpts.toBundle(), null /* sideOptions */,
- stagePosition, splitRatio, adapter);
- }
+ params.height = (int) resources.getDimension(R.dimen.split_placeholder_size);
+ params.gravity = Gravity.TOP;
}
- }
- public @StagePosition int getActiveSplitStagePosition() {
- return mStagePosition;
+ return params;
}
- public void setRecentsAnimationRunning(boolean running) {
- this.mRecentsAnimationRunning = running;
+ @Nullable
+ public SplitPositionOption getActiveSplitPositionOption() {
+ return mInitialPosition;
}
/**
* Requires Shell Transitions
*/
- private class RemoteSplitLaunchTransitionRunner implements RemoteTransitionRunner {
+ private class RemoteSplitLaunchAnimationRunner implements RemoteTransitionRunner {
- private final int mInitialTaskId;
- private final PendingIntent mInitialTaskPendingIntent;
- private final int mSecondTaskId;
- private final Consumer<Boolean> mSuccessCallback;
+ private final TaskView mInitialTaskView;
+ private final TaskView mTaskView;
- RemoteSplitLaunchTransitionRunner(int initialTaskId, PendingIntent initialTaskPendingIntent,
- int secondTaskId, Consumer<Boolean> callback) {
- mInitialTaskId = initialTaskId;
- mInitialTaskPendingIntent = initialTaskPendingIntent;
- mSecondTaskId = secondTaskId;
- mSuccessCallback = callback;
+ RemoteSplitLaunchAnimationRunner(TaskView initialTaskView, TaskView taskView) {
+ mInitialTaskView = initialTaskView;
+ mTaskView = taskView;
}
@Override
- public void startAnimation(@NonNull IBinder transition, @NonNull TransitionInfo info,
- @NonNull SurfaceControl.Transaction t, @NonNull Runnable finishCallback) {
- TaskViewUtils.composeRecentsSplitLaunchAnimator(mInitialTaskId,
- mInitialTaskPendingIntent, mSecondTaskId, info, t, () -> {
- finishCallback.run();
- if (mSuccessCallback != null) {
- mSuccessCallback.accept(true);
- }
- });
+ public void startAnimation(IBinder transition, TransitionInfo info,
+ SurfaceControl.Transaction t, Runnable finishCallback) {
+ TaskViewUtils.composeRecentsSplitLaunchAnimator(mInitialTaskView, mTaskView,
+ info, t, finishCallback);
// After successful launch, call resetState
resetState();
}
@@ -252,82 +175,62 @@ public class SplitSelectStateController {
/**
* LEGACY
- * Remote animation runner for animation to launch an app.
+ * @return the opposite stage and position from the {@param position} provided as first and
+ * second object, respectively
+ * Ex. If position is has stage = Main and position = Top/Left, this will return
+ * Pair(stage=Side, position=Bottom/Left)
*/
- private class RemoteSplitLaunchAnimationRunner implements RemoteAnimationRunnerCompat {
+ private Pair<Integer, Integer> getComplimentaryStageAndPosition(SplitPositionOption position) {
+ // Right now this is as simple as flipping between 0 and 1
+ int complimentStageType = position.mStageType ^ 1;
+ int complimentStagePosition = position.mStagePosition ^ 1;
+ return new Pair<>(complimentStageType, complimentStagePosition);
+ }
- private final int mInitialTaskId;
- private final PendingIntent mInitialTaskPendingIntent;
- private final int mSecondTaskId;
- private final Consumer<Boolean> mSuccessCallback;
+ /**
+ * LEGACY
+ * Remote animation runner for animation to launch an app.
+ */
+ private class SplitLaunchAnimationRunner implements RemoteAnimationFactory {
- RemoteSplitLaunchAnimationRunner(int initialTaskId, PendingIntent initialTaskPendingIntent,
- int secondTaskId, Consumer<Boolean> successCallback) {
- mInitialTaskId = initialTaskId;
- mInitialTaskPendingIntent = initialTaskPendingIntent;
- mSecondTaskId = secondTaskId;
- mSuccessCallback = successCallback;
- }
+ private final TaskView mV;
+ private final int mTargetState;
- @Override
- public void onAnimationStart(int transit, RemoteAnimationTargetCompat[] apps,
- RemoteAnimationTargetCompat[] wallpapers, RemoteAnimationTargetCompat[] nonApps,
- Runnable finishedCallback) {
- postAsyncCallback(mHandler,
- () -> TaskViewUtils.composeRecentsSplitLaunchAnimatorLegacy(
- mLaunchingTaskView, mInitialTaskId, mInitialTaskPendingIntent,
- mSecondTaskId, apps, wallpapers, nonApps, mStateManager,
- mDepthController, () -> {
- finishedCallback.run();
- if (mSuccessCallback != null) {
- mSuccessCallback.accept(true);
- }
- resetState();
- }));
+ SplitLaunchAnimationRunner(TaskView v, int targetState) {
+ mV = v;
+ mTargetState = targetState;
}
@Override
- public void onAnimationCancelled() {
- postAsyncCallback(mHandler, () -> {
- if (mSuccessCallback != null) {
- // Launching legacy tasks while recents animation is running will always cause
- // onAnimationCancelled to be called (should be fixed w/ shell transitions?)
- mSuccessCallback.accept(mRecentsAnimationRunning);
- }
- resetState();
- });
+ public void onCreateAnimation(int transit,
+ RemoteAnimationTargetCompat[] appTargets,
+ RemoteAnimationTargetCompat[] wallpaperTargets,
+ RemoteAnimationTargetCompat[] nonAppTargets,
+ LauncherAnimationRunner.AnimationResult result) {
+ AnimatorSet anim = new AnimatorSet();
+ BaseQuickstepLauncher activity = BaseActivity.fromContext(mV.getContext());
+ TaskViewUtils.composeRecentsSplitLaunchAnimatorLegacy(anim, mV,
+ appTargets, wallpaperTargets, nonAppTargets, true, activity.getStateManager(),
+ activity.getDepthController(), mTargetState);
+ result.setAnimation(anim, activity);
}
}
+
/**
* To be called if split select was cancelled
*/
public void resetState() {
- mInitialTaskId = INVALID_TASK_ID;
- mInitialTaskIntent = null;
- mSecondTaskId = INVALID_TASK_ID;
- mStagePosition = SplitConfigurationOptions.STAGE_POSITION_UNDEFINED;
- mRecentsAnimationRunning = false;
- mLaunchingTaskView = null;
+ mInitialTaskView = null;
+ mInitialPosition = null;
+ mInitialBounds = null;
}
- /**
- * @return {@code true} if first task has been selected and waiting for the second task to be
- * chosen
- */
public boolean isSplitSelectActive() {
- return isInitialTaskIntentSet() && mSecondTaskId == INVALID_TASK_ID;
- }
-
- /**
- * @return {@code true} if the first and second task have been chosen and split is waiting to
- * be launched
- */
- public boolean isBothSplitAppsConfirmed() {
- return isInitialTaskIntentSet() && mSecondTaskId != INVALID_TASK_ID;
+ return mInitialTaskView != null;
}
- private boolean isInitialTaskIntentSet() {
- return (mInitialTaskId != INVALID_TASK_ID || mInitialTaskIntent != null);
+ public Rect getInitialBounds() {
+ return mInitialBounds;
}
}
diff --git a/quickstep/src/com/android/quickstep/util/StaggeredWorkspaceAnim.java b/quickstep/src/com/android/quickstep/util/StaggeredWorkspaceAnim.java
index 32e08ffa8d..ccc587cd87 100644
--- a/quickstep/src/com/android/quickstep/util/StaggeredWorkspaceAnim.java
+++ b/quickstep/src/com/android/quickstep/util/StaggeredWorkspaceAnim.java
@@ -18,7 +18,6 @@ package com.android.quickstep.util;
import static com.android.launcher3.LauncherAnimUtils.VIEW_TRANSLATE_Y;
import static com.android.launcher3.LauncherState.BACKGROUND_APP;
import static com.android.launcher3.LauncherState.NORMAL;
-import static com.android.launcher3.anim.AnimatorListeners.forEndCallback;
import static com.android.launcher3.anim.Interpolators.LINEAR;
import static com.android.launcher3.anim.PropertySetter.NO_ANIM_PROPERTY_SETTER;
import static com.android.launcher3.states.StateAnimationConfig.SKIP_DEPTH_CONTROLLER;
@@ -93,7 +92,7 @@ public class StaggeredWorkspaceAnim {
if (staggerWorkspace) {
DeviceProfile grid = launcher.getDeviceProfile();
- Workspace<?> workspace = launcher.getWorkspace();
+ Workspace workspace = launcher.getWorkspace();
Hotseat hotseat = launcher.getHotseat();
// Hotseat and QSB takes up two additional rows.
@@ -149,9 +148,6 @@ public class StaggeredWorkspaceAnim {
});
}
- launcher.pauseExpensiveViewUpdates();
- mAnimators.addListener(forEndCallback(launcher::resumeExpensiveViewUpdates));
-
if (animateOverviewScrim) {
PendingAnimation pendingAnimation = new PendingAnimation(DURATION_MS);
launcher.getWorkspace().getStateTransitionAnimation()
@@ -201,7 +197,7 @@ public class StaggeredWorkspaceAnim {
launcher.getStateManager().createAtomicAnimation(BACKGROUND_APP, NORMAL, config).start();
// Stop scrolling so that it doesn't interfere with the translation offscreen.
- launcher.<RecentsView>getOverviewPanel().forceFinishScroller();
+ launcher.<RecentsView>getOverviewPanel().getScroller().forceFinished(true);
if (animateOverviewScrim) {
launcher.getWorkspace().getStateTransitionAnimation()
diff --git a/quickstep/src/com/android/quickstep/util/SurfaceTransactionApplier.java b/quickstep/src/com/android/quickstep/util/SurfaceTransactionApplier.java
index 1200208e30..3b4fd31fa5 100644
--- a/quickstep/src/com/android/quickstep/util/SurfaceTransactionApplier.java
+++ b/quickstep/src/com/android/quickstep/util/SurfaceTransactionApplier.java
@@ -22,10 +22,10 @@ import android.os.Message;
import android.view.SurfaceControl;
import android.view.SurfaceControl.Transaction;
import android.view.View;
-import android.view.ViewRootImpl;
import com.android.quickstep.RemoteAnimationTargets.ReleaseCheck;
import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat.SurfaceParams;
+import com.android.systemui.shared.system.ViewRootImplCompat;
import java.util.function.Consumer;
@@ -41,7 +41,7 @@ public class SurfaceTransactionApplier extends ReleaseCheck {
private static final int MSG_UPDATE_SEQUENCE_NUMBER = 0;
private final SurfaceControl mBarrierSurfaceControl;
- private final ViewRootImpl mTargetViewRootImpl;
+ private final ViewRootImplCompat mTargetViewRootImpl;
private final Handler mApplyHandler;
private int mLastSequenceNumber = 0;
@@ -50,10 +50,9 @@ public class SurfaceTransactionApplier extends ReleaseCheck {
* @param targetView The view in the surface that acts as synchronization anchor.
*/
public SurfaceTransactionApplier(View targetView) {
- mTargetViewRootImpl = targetView.getViewRootImpl();
- mBarrierSurfaceControl = mTargetViewRootImpl.getSurfaceControl();
+ mTargetViewRootImpl = new ViewRootImplCompat(targetView);
+ mBarrierSurfaceControl = mTargetViewRootImpl.getRenderSurfaceControl();
mApplyHandler = new Handler(this::onApplyMessage);
- setCanRelease(true);
}
protected boolean onApplyMessage(Message msg) {
@@ -75,13 +74,6 @@ public class SurfaceTransactionApplier extends ReleaseCheck {
if (view == null) {
return;
}
- Transaction t = new Transaction();
- for (int i = params.length - 1; i >= 0; i--) {
- SurfaceParams surfaceParams = params[i];
- if (surfaceParams.surface.isValid()) {
- surfaceParams.applyTo(t);
- }
- }
mLastSequenceNumber++;
final int toApplySeqNo = mLastSequenceNumber;
@@ -92,6 +84,13 @@ public class SurfaceTransactionApplier extends ReleaseCheck {
.sendToTarget();
return;
}
+ Transaction t = new Transaction();
+ for (int i = params.length - 1; i >= 0; i--) {
+ SurfaceParams surfaceParams = params[i];
+ if (surfaceParams.surface.isValid()) {
+ surfaceParams.applyTo(t);
+ }
+ }
mTargetViewRootImpl.mergeWithNextTransaction(t, frame);
Message.obtain(mApplyHandler, MSG_UPDATE_SEQUENCE_NUMBER, toApplySeqNo, 0)
.sendToTarget();
@@ -110,7 +109,7 @@ public class SurfaceTransactionApplier extends ReleaseCheck {
if (targetView == null) {
// No target view, no applier
callback.accept(null);
- } else if (targetView.isAttachedToWindow()) {
+ } else if (new ViewRootImplCompat(targetView).isValid()) {
// Already attached, we're good to go
callback.accept(new SurfaceTransactionApplier(targetView));
} else {
diff --git a/quickstep/src/com/android/quickstep/util/SwipePipToHomeAnimator.java b/quickstep/src/com/android/quickstep/util/SwipePipToHomeAnimator.java
index b222f51e50..c0f5c14e3c 100644
--- a/quickstep/src/com/android/quickstep/util/SwipePipToHomeAnimator.java
+++ b/quickstep/src/com/android/quickstep/util/SwipePipToHomeAnimator.java
@@ -40,7 +40,6 @@ import com.android.launcher3.Utilities;
import com.android.launcher3.anim.AnimationSuccessListener;
import com.android.launcher3.anim.Interpolators;
import com.android.launcher3.util.Themes;
-import com.android.quickstep.TaskAnimationManager;
import com.android.systemui.shared.pip.PipSurfaceTransactionHelper;
import com.android.systemui.shared.system.InteractionJankMonitorWrapper;
@@ -56,7 +55,6 @@ public class SwipePipToHomeAnimator extends RectFSpringAnim {
private final int mTaskId;
private final ComponentName mComponentName;
private final SurfaceControl mLeash;
- private final Rect mSourceRectHint = new Rect();
private final Rect mAppBounds = new Rect();
private final Matrix mHomeToWindowPositionMap = new Matrix();
private final Rect mStartBounds = new Rect();
@@ -102,7 +100,6 @@ public class SwipePipToHomeAnimator extends RectFSpringAnim {
* @param fromRotation From rotation if different from final rotation, ROTATION_0 otherwise
* @param destinationBoundsTransformed Destination bounds in window space
* @param cornerRadius Corner radius in pixel value for PiP window
- * @param shadowRadius Shadow radius in pixel value for PiP window
* @param view Attached view for logging purpose
*/
private SwipePipToHomeAnimator(@NonNull Context context,
@@ -117,9 +114,8 @@ public class SwipePipToHomeAnimator extends RectFSpringAnim {
@RecentsOrientedState.SurfaceRotation int fromRotation,
@NonNull Rect destinationBoundsTransformed,
int cornerRadius,
- int shadowRadius,
@NonNull View view) {
- super(startBounds, new RectF(destinationBoundsTransformed), context, null);
+ super(startBounds, new RectF(destinationBoundsTransformed), context);
mTaskId = taskId;
mComponentName = componentName;
mLeash = leash;
@@ -129,7 +125,7 @@ public class SwipePipToHomeAnimator extends RectFSpringAnim {
mDestinationBounds.set(destinationBounds);
mFromRotation = fromRotation;
mDestinationBoundsTransformed.set(destinationBoundsTransformed);
- mSurfaceTransactionHelper = new PipSurfaceTransactionHelper(cornerRadius, shadowRadius);
+ mSurfaceTransactionHelper = new PipSurfaceTransactionHelper(cornerRadius);
if (sourceRectHint != null && (sourceRectHint.width() < destinationBounds.width()
|| sourceRectHint.height() < destinationBounds.height())) {
@@ -141,7 +137,6 @@ public class SwipePipToHomeAnimator extends RectFSpringAnim {
}
if (sourceRectHint == null) {
- mSourceRectHint.setEmpty();
mSourceHintRectInsets = null;
// Create a new overlay layer
@@ -162,7 +157,7 @@ public class SwipePipToHomeAnimator extends RectFSpringAnim {
t.reparent(mContentOverlay, mLeash);
t.apply();
- addOnUpdateListener((currentRect, progress) -> {
+ addOnUpdateListener((values, currentRect, progress) -> {
float alpha = progress < 0.5f
? 0
: Utilities.mapToRange(Math.min(progress, 1f), 0.5f, 1f,
@@ -171,7 +166,6 @@ public class SwipePipToHomeAnimator extends RectFSpringAnim {
t.apply();
});
} else {
- mSourceRectHint.set(sourceRectHint);
mSourceHintRectInsets = new Rect(sourceRectHint.left - appBounds.left,
sourceRectHint.top - appBounds.top,
appBounds.right - sourceRectHint.right,
@@ -206,7 +200,8 @@ public class SwipePipToHomeAnimator extends RectFSpringAnim {
addOnUpdateListener(this::onAnimationUpdate);
}
- private void onAnimationUpdate(RectF currentRect, float progress) {
+ private void onAnimationUpdate(@Nullable AppCloseConfig values, RectF currentRect,
+ float progress) {
if (mHasAnimationEnded) return;
final SurfaceControl.Transaction tx =
PipSurfaceTransactionHelper.newSurfaceControlTransaction();
@@ -252,8 +247,7 @@ public class SwipePipToHomeAnimator extends RectFSpringAnim {
return mSurfaceTransactionHelper.scaleAndRotate(tx, mLeash, mAppBounds, bounds, insets,
rotatedPosition.degree, rotatedPosition.positionX, rotatedPosition.positionY);
} else {
- return mSurfaceTransactionHelper.scaleAndCrop(tx, mLeash, mSourceRectHint, mAppBounds,
- bounds, insets);
+ return mSurfaceTransactionHelper.scaleAndCrop(tx, mLeash, mAppBounds, bounds, insets);
}
}
@@ -284,36 +278,19 @@ public class SwipePipToHomeAnimator extends RectFSpringAnim {
private RotatedPosition getRotatedPosition(float progress) {
final float degree, positionX, positionY;
- if (TaskAnimationManager.SHELL_TRANSITIONS_ROTATION) {
- if (mFromRotation == Surface.ROTATION_90) {
- degree = -90 * (1 - progress);
- positionX = progress * (mDestinationBoundsTransformed.left - mStartBounds.left)
- + mStartBounds.left;
- positionY = progress * (mDestinationBoundsTransformed.top - mStartBounds.top)
- + mStartBounds.top + mStartBounds.bottom * (1 - progress);
- } else {
- degree = 90 * (1 - progress);
- positionX = progress * (mDestinationBoundsTransformed.left - mStartBounds.left)
- + mStartBounds.left + mStartBounds.right * (1 - progress);
- positionY = progress * (mDestinationBoundsTransformed.top - mStartBounds.top)
- + mStartBounds.top;
- }
+ if (mFromRotation == Surface.ROTATION_90) {
+ degree = -90 * progress;
+ positionX = progress * (mDestinationBoundsTransformed.left - mStartBounds.left)
+ + mStartBounds.left;
+ positionY = progress * (mDestinationBoundsTransformed.bottom - mStartBounds.top)
+ + mStartBounds.top;
} else {
- if (mFromRotation == Surface.ROTATION_90) {
- degree = -90 * progress;
- positionX = progress * (mDestinationBoundsTransformed.left - mStartBounds.left)
- + mStartBounds.left;
- positionY = progress * (mDestinationBoundsTransformed.bottom - mStartBounds.top)
- + mStartBounds.top;
- } else {
- degree = 90 * progress;
- positionX = progress * (mDestinationBoundsTransformed.right - mStartBounds.left)
- + mStartBounds.left;
- positionY = progress * (mDestinationBoundsTransformed.top - mStartBounds.top)
- + mStartBounds.top;
- }
+ degree = 90 * progress;
+ positionX = progress * (mDestinationBoundsTransformed.right - mStartBounds.left)
+ + mStartBounds.left;
+ positionY = progress * (mDestinationBoundsTransformed.top - mStartBounds.top)
+ + mStartBounds.top;
}
-
return new RotatedPosition(degree, positionX, positionY);
}
@@ -330,7 +307,6 @@ public class SwipePipToHomeAnimator extends RectFSpringAnim {
private RectF mStartBounds;
private Rect mDestinationBounds;
private int mCornerRadius;
- private int mShadowRadius;
private View mAttachedView;
private @RecentsOrientedState.SurfaceRotation int mFromRotation = Surface.ROTATION_0;
private final Rect mDestinationBoundsTransformed = new Rect();
@@ -385,11 +361,6 @@ public class SwipePipToHomeAnimator extends RectFSpringAnim {
return this;
}
- public Builder setShadowRadius(int shadowRadius) {
- mShadowRadius = shadowRadius;
- return this;
- }
-
public Builder setAttachedView(View attachedView) {
mAttachedView = attachedView;
return this;
@@ -434,7 +405,7 @@ public class SwipePipToHomeAnimator extends RectFSpringAnim {
mSourceRectHint, mAppBounds,
mHomeToWindowPositionMap, mStartBounds, mDestinationBounds,
mFromRotation, mDestinationBoundsTransformed,
- mCornerRadius, mShadowRadius, mAttachedView);
+ mCornerRadius, mAttachedView);
}
}
diff --git a/quickstep/src/com/android/quickstep/util/SystemWindowManagerProxy.java b/quickstep/src/com/android/quickstep/util/SystemWindowManagerProxy.java
deleted file mode 100644
index 9bb3d56556..0000000000
--- a/quickstep/src/com/android/quickstep/util/SystemWindowManagerProxy.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.quickstep.util;
-
-import android.content.Context;
-import android.hardware.display.DisplayManager;
-import android.view.Display;
-
-import com.android.launcher3.util.window.WindowManagerProxy;
-
-/**
- * Extension of {@link WindowManagerProxy} with some assumption for the default system Launcher
- */
-public class SystemWindowManagerProxy extends WindowManagerProxy {
-
- public SystemWindowManagerProxy(Context context) {
- super(true);
- }
-
- @Override
- protected String getDisplayId(Display display) {
- return display.getUniqueId();
- }
-
- @Override
- public boolean isInternalDisplay(Display display) {
- return display.getType() == Display.TYPE_INTERNAL;
- }
-
- @Override
- public int getRotation(Context context) {
- return context.getResources().getConfiguration().windowConfiguration.getRotation();
- }
-
- @Override
- protected Display[] getDisplays(Context context) {
- return context.getSystemService(DisplayManager.class).getDisplays(
- DisplayManager.DISPLAY_CATEGORY_ALL_INCLUDING_DISABLED);
- }
-}
diff --git a/quickstep/src/com/android/quickstep/util/TISBindHelper.java b/quickstep/src/com/android/quickstep/util/TISBindHelper.java
deleted file mode 100644
index 7b122c6c66..0000000000
--- a/quickstep/src/com/android/quickstep/util/TISBindHelper.java
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Copyright (C) 2021 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.quickstep.util;
-
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.ServiceConnection;
-import android.os.Handler;
-import android.os.IBinder;
-import android.util.Log;
-
-import com.android.quickstep.TouchInteractionService;
-import com.android.quickstep.TouchInteractionService.TISBinder;
-
-import java.util.ArrayList;
-import java.util.function.Consumer;
-
-/**
- * Utility class to simplify binding to {@link TouchInteractionService}
- */
-public class TISBindHelper implements ServiceConnection {
-
- private static final String TAG = "TISBindHelper";
-
- private static final long BACKOFF_MILLIS = 1000;
-
- // Max backoff caps at 5 mins
- private static final long MAX_BACKOFF_MILLIS = 10 * 60 * 1000;
-
- private final Handler mHandler = new Handler();
- private final Runnable mConnectionRunnable = this::internalBindToTIS;
- private final Context mContext;
- private final Consumer<TISBinder> mConnectionCallback;
- private final ArrayList<Runnable> mPendingConnectedCallbacks = new ArrayList<>();
-
- private short mConnectionAttempts;
- private boolean mTisServiceBound;
- private boolean mIsConnected;
-
- public TISBindHelper(Context context, Consumer<TISBinder> connectionCallback) {
- mContext = context;
- mConnectionCallback = connectionCallback;
- internalBindToTIS();
- }
-
- @Override
- public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
- if (!(iBinder instanceof TISBinder)) {
- // Seems like there can be a race condition when user unlocks, which kills the TIS
- // process and re-starts it. I guess in the meantime service can be connected to
- // a killed TIS? Either way, unbind and try to re-connect in that case.
- internalUnbindToTIS();
- mHandler.postDelayed(mConnectionRunnable, BACKOFF_MILLIS);
- return;
- }
-
- Log.d(TAG, "TIS service connected");
- mIsConnected = true;
- mConnectionCallback.accept((TISBinder) iBinder);
- // Flush the pending callbacks
- for (Runnable r : mPendingConnectedCallbacks) {
- r.run();
- }
- mPendingConnectedCallbacks.clear();
- resetServiceBindRetryState();
- }
-
- @Override
- public void onServiceDisconnected(ComponentName componentName) { }
-
- @Override
- public void onBindingDied(ComponentName name) {
- Log.w(TAG, "TIS binding died");
- internalBindToTIS();
- }
-
- /**
- * Runs the given {@param r} runnable when the service is connected.
- */
- public void runOnBindToTouchInteractionService(Runnable r) {
- if (mIsConnected) {
- r.run();
- } else {
- mPendingConnectedCallbacks.add(r);
- }
- }
-
- /**
- * Binds to {@link TouchInteractionService}. If the binding fails, attempts to retry via
- * {@link #mConnectionRunnable}. Unbind via {@link #internalUnbindToTIS()}
- */
- private void internalBindToTIS() {
- mTisServiceBound = mContext.bindService(new Intent(mContext, TouchInteractionService.class),
- this, 0);
- if (mTisServiceBound) {
- resetServiceBindRetryState();
- return;
- }
-
- Log.w(TAG, "Retrying TIS Binder connection attempt: " + mConnectionAttempts);
- final long timeoutMs = (long) Math.min(
- Math.scalb(BACKOFF_MILLIS, mConnectionAttempts), MAX_BACKOFF_MILLIS);
- mHandler.postDelayed(mConnectionRunnable, timeoutMs);
- mConnectionAttempts++;
- }
-
- /** See {@link #internalBindToTIS()} */
- private void internalUnbindToTIS() {
- if (mTisServiceBound) {
- mContext.unbindService(this);
- mTisServiceBound = false;
- }
- }
-
- private void resetServiceBindRetryState() {
- if (mHandler.hasCallbacks(mConnectionRunnable)) {
- mHandler.removeCallbacks(mConnectionRunnable);
- }
- mConnectionAttempts = 0;
- }
-
- /**
- * Called when the activity is destroyed to clear the binding
- */
- public void onDestroy() {
- internalUnbindToTIS();
- resetServiceBindRetryState();
- mIsConnected = false;
- mPendingConnectedCallbacks.clear();
- }
-}
diff --git a/quickstep/src/com/android/quickstep/util/TaskKeyLruCache.java b/quickstep/src/com/android/quickstep/util/TaskKeyLruCache.java
index 08a65fa9d5..d87feec069 100644
--- a/quickstep/src/com/android/quickstep/util/TaskKeyLruCache.java
+++ b/quickstep/src/com/android/quickstep/util/TaskKeyLruCache.java
@@ -20,7 +20,6 @@ import android.util.Log;
import com.android.systemui.shared.recents.model.Task.TaskKey;
import java.util.LinkedHashMap;
-import java.util.Map;
import java.util.function.Predicate;
/**
@@ -118,7 +117,7 @@ public class TaskKeyLruCache<V> {
}
@Override
- protected boolean removeEldestEntry(Map.Entry<Integer, TaskKeyLruCache.Entry<V>> eldest) {
+ protected boolean removeEldestEntry(Entry<Integer, TaskKeyLruCache.Entry<V>> eldest) {
return size() > mMaxSize;
}
}
diff --git a/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java b/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java
index 5212755ec7..cceb872f78 100644
--- a/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java
+++ b/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java
@@ -18,10 +18,6 @@ package com.android.quickstep.util;
import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE;
import static com.android.launcher3.states.RotationHelper.deltaRotation;
import static com.android.launcher3.touch.PagedOrientationHandler.MATRIX_POST_TRANSLATE;
-import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_BOTTOM_OR_RIGHT;
-import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT;
-import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_UNDEFINED;
-import static com.android.launcher3.util.SplitConfigurationOptions.StagePosition;
import static com.android.quickstep.util.RecentsOrientedState.postDisplayRotation;
import static com.android.quickstep.util.RecentsOrientedState.preDisplayRotation;
import static com.android.systemui.shared.system.WindowManagerWrapper.WINDOWING_MODE_FULLSCREEN;
@@ -30,21 +26,19 @@ import android.animation.TimeInterpolator;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Matrix;
+import android.graphics.Point;
import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.RectF;
-import android.util.Log;
import androidx.annotation.NonNull;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Utilities;
import com.android.launcher3.anim.PendingAnimation;
-import com.android.launcher3.util.SplitConfigurationOptions.StagedSplitBounds;
import com.android.launcher3.util.TraceHelper;
import com.android.quickstep.AnimatedFloat;
import com.android.quickstep.BaseActivityInterface;
-import com.android.quickstep.TaskAnimationManager;
import com.android.quickstep.views.TaskThumbnailView.PreviewPositionHelper;
import com.android.quickstep.views.TaskView.FullscreenDrawParams;
import com.android.systemui.shared.recents.model.ThumbnailData;
@@ -56,28 +50,26 @@ import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat.
*/
public class TaskViewSimulator implements TransformParams.BuilderProxy {
- private static final String TAG = "TaskViewSimulator";
- private static final boolean DEBUG = false;
-
private final Rect mTmpCropRect = new Rect();
private final RectF mTempRectF = new RectF();
private final float[] mTempPoint = new float[2];
private final Context mContext;
private final BaseActivityInterface mSizeStrategy;
+ private final boolean mIsForLiveTile;
@NonNull
private RecentsOrientedState mOrientationState;
private final boolean mIsRecentsRtl;
private final Rect mTaskRect = new Rect();
+ private boolean mDrawsBelowRecents;
private final PointF mPivot = new PointF();
private DeviceProfile mDp;
- @StagePosition
- private int mStagePosition = STAGE_POSITION_UNDEFINED;
private final Matrix mMatrix = new Matrix();
private final Matrix mMatrixTmp = new Matrix();
+ private final Point mRunningTargetWindowPosition = new Point();
// Thumbnail view properties
private final Rect mThumbnailPosition = new Rect();
@@ -100,15 +92,16 @@ public class TaskViewSimulator implements TransformParams.BuilderProxy {
// Cached calculations
private boolean mLayoutValid = false;
private int mOrientationStateId;
- private StagedSplitBounds mStagedSplitBounds;
- private boolean mDrawsBelowRecents;
- private boolean mIsGridTask;
- private int mTaskRectTranslationX;
- private int mTaskRectTranslationY;
public TaskViewSimulator(Context context, BaseActivityInterface sizeStrategy) {
+ this(context, sizeStrategy, false);
+ }
+
+ public TaskViewSimulator(Context context, BaseActivityInterface sizeStrategy,
+ boolean isForLiveTile) {
mContext = context;
mSizeStrategy = sizeStrategy;
+ mIsForLiveTile = isForLiveTile;
// TODO(b/187074722): Don't create this per-TaskViewSimulator
mOrientationState = TraceHelper.allowIpcs("",
@@ -144,52 +137,18 @@ public class TaskViewSimulator implements TransformParams.BuilderProxy {
if (mDp == null) {
return 1;
}
- if (mIsGridTask) {
- mSizeStrategy.calculateGridTaskSize(mContext, mDp, mTaskRect,
- mOrientationState.getOrientationHandler());
- } else {
- mSizeStrategy.calculateTaskSize(mContext, mDp, mTaskRect);
- }
-
- Rect fullTaskSize;
- if (mStagedSplitBounds != null) {
- // The task rect changes according to the staged split task sizes, but recents
- // fullscreen scale and pivot remains the same since the task fits into the existing
- // sized task space bounds
- fullTaskSize = new Rect(mTaskRect);
- mOrientationState.getOrientationHandler()
- .setSplitTaskSwipeRect(mDp, mTaskRect, mStagedSplitBounds, mStagePosition);
- mTaskRect.offset(mTaskRectTranslationX, mTaskRectTranslationY);
- } else {
- fullTaskSize = mTaskRect;
- }
- fullTaskSize.offset(mTaskRectTranslationX, mTaskRectTranslationY);
- return mOrientationState.getFullScreenScaleAndPivot(fullTaskSize, mDp, mPivot);
+ mSizeStrategy.calculateTaskSize(mContext, mDp, mTaskRect,
+ mOrientationState.getOrientationHandler());
+ return mOrientationState.getFullScreenScaleAndPivot(mTaskRect, mDp, mPivot);
}
/**
* Sets the targets which the simulator will control
*/
public void setPreview(RemoteAnimationTargetCompat runningTarget) {
- setPreviewBounds(runningTarget.startScreenSpaceBounds, runningTarget.contentInsets);
- }
-
- /**
- * Sets the targets which the simulator will control specifically for targets to animate when
- * in split screen
- *
- * @param splitInfo set to {@code null} when not in staged split mode
- */
- public void setPreview(RemoteAnimationTargetCompat runningTarget, StagedSplitBounds splitInfo) {
- setPreview(runningTarget);
- mStagedSplitBounds = splitInfo;
- if (mStagedSplitBounds == null) {
- mStagePosition = STAGE_POSITION_UNDEFINED;
- return;
- }
- mStagePosition = mThumbnailPosition.equals(splitInfo.leftTopBounds) ?
- STAGE_POSITION_TOP_OR_LEFT :
- STAGE_POSITION_BOTTOM_OR_RIGHT;
+ setPreviewBounds(runningTarget.screenSpaceBounds, runningTarget.contentInsets);
+ mRunningTargetWindowPosition.set(runningTarget.screenSpaceBounds.left,
+ runningTarget.screenSpaceBounds.top);
}
/**
@@ -216,21 +175,6 @@ public class TaskViewSimulator implements TransformParams.BuilderProxy {
}
/**
- * Sets whether the task is part of overview grid and not being focused.
- */
- public void setIsGridTask(boolean isGridTask) {
- mIsGridTask = isGridTask;
- }
-
- /**
- * Apply translations on TaskRect's starting location.
- */
- public void setTaskRectTranslation(int taskRectTranslationX, int taskRectTranslationY) {
- mTaskRectTranslationX = taskRectTranslationX;
- mTaskRectTranslationY = taskRectTranslationY;
- }
-
- /**
* Adds animation for all the components corresponding to transition from an app to overview.
*/
public void addAppToOverviewAnim(PendingAnimation pa, TimeInterpolator interpolator) {
@@ -286,11 +230,12 @@ public class TaskViewSimulator implements TransformParams.BuilderProxy {
* window coordinate space.
*/
public void applyWindowToHomeRotation(Matrix matrix) {
- matrix.postTranslate(mDp.windowX, mDp.windowY);
+ mMatrix.postTranslate(mDp.windowX, mDp.windowY);
postDisplayRotation(deltaRotation(
mOrientationState.getRecentsActivityRotation(),
mOrientationState.getDisplayRotation()),
mDp.widthPx, mDp.heightPx, matrix);
+ matrix.postTranslate(-mRunningTargetWindowPosition.x, -mRunningTargetWindowPosition.y);
}
/**
@@ -305,13 +250,7 @@ public class TaskViewSimulator implements TransformParams.BuilderProxy {
mOrientationStateId = mOrientationState.getStateId();
getFullScreenScale();
- if (TaskAnimationManager.SHELL_TRANSITIONS_ROTATION) {
- // With shell transitions, the display is rotated early so we need to actually use
- // the rotation when the gesture starts
- mThumbnailData.rotation = mOrientationState.getTouchRotation();
- } else {
- mThumbnailData.rotation = mOrientationState.getDisplayRotation();
- }
+ mThumbnailData.rotation = mOrientationState.getDisplayRotation();
// mIsRecentsRtl is the inverse of TaskView RTL.
boolean isRtlEnabled = !mIsRecentsRtl;
@@ -320,14 +259,12 @@ public class TaskViewSimulator implements TransformParams.BuilderProxy {
mTaskRect.width(), mTaskRect.height(),
mDp, mOrientationState.getRecentsActivityRotation(), isRtlEnabled);
mPositionHelper.getMatrix().invert(mInversePositionMatrix);
- if (DEBUG) {
- Log.d(TAG, " taskRect: " + mTaskRect);
- }
}
float fullScreenProgress = Utilities.boundToRange(this.fullScreenProgress.value, 0, 1);
- mCurrentFullscreenParams.setProgress(fullScreenProgress, recentsViewScale.value,
- /* taskViewScale= */1f, mTaskRect.width(), mDp, mPositionHelper);
+ mCurrentFullscreenParams.setProgress(
+ fullScreenProgress, recentsViewScale.value, mTaskRect.width(), mDp,
+ mPositionHelper);
// Apply thumbnail matrix
RectF insets = mCurrentFullscreenParams.mCurrentDrawnInsets;
@@ -339,20 +276,20 @@ public class TaskViewSimulator implements TransformParams.BuilderProxy {
mMatrix.postTranslate(insets.left, insets.top);
mMatrix.postScale(scale, scale);
- // Apply TaskView matrix: taskRect, translate
+ // Apply TaskView matrix: translate, scroll
mMatrix.postTranslate(mTaskRect.left, mTaskRect.top);
- mOrientationState.getOrientationHandler().setPrimary(mMatrix, MATRIX_POST_TRANSLATE,
+ mOrientationState.getOrientationHandler().set(mMatrix, MATRIX_POST_TRANSLATE,
taskPrimaryTranslation.value);
mOrientationState.getOrientationHandler().setSecondary(mMatrix, MATRIX_POST_TRANSLATE,
taskSecondaryTranslation.value);
- mOrientationState.getOrientationHandler().setPrimary(
+ mOrientationState.getOrientationHandler().set(
mMatrix, MATRIX_POST_TRANSLATE, recentsViewScroll.value);
// Apply RecentsView matrix
mMatrix.postScale(recentsViewScale.value, recentsViewScale.value, mPivot.x, mPivot.y);
mOrientationState.getOrientationHandler().setSecondary(mMatrix, MATRIX_POST_TRANSLATE,
recentsViewSecondaryTranslation.value);
- mOrientationState.getOrientationHandler().setPrimary(mMatrix, MATRIX_POST_TRANSLATE,
+ mOrientationState.getOrientationHandler().set(mMatrix, MATRIX_POST_TRANSLATE,
recentsViewPrimaryTranslation.value);
applyWindowToHomeRotation(mMatrix);
@@ -363,24 +300,6 @@ public class TaskViewSimulator implements TransformParams.BuilderProxy {
mTempRectF.roundOut(mTmpCropRect);
params.applySurfaceParams(params.createSurfaceParams(this));
-
- if (!DEBUG) {
- return;
- }
- Log.d(TAG, "progress: " + fullScreenProgress
- + " scale: " + scale
- + " recentsViewScale: " + recentsViewScale.value
- + " crop: " + mTmpCropRect
- + " radius: " + getCurrentCornerRadius()
- + " taskW: " + taskWidth + " H: " + taskHeight
- + " taskRect: " + mTaskRect
- + " taskPrimaryT: " + taskPrimaryTranslation.value
- + " recentsPrimaryT: " + recentsViewPrimaryTranslation.value
- + " recentsSecondaryT: " + recentsViewSecondaryTranslation.value
- + " taskSecondaryT: " + taskSecondaryTranslation.value
- + " recentsScroll: " + recentsViewScroll.value
- + " pivot: " + mPivot
- );
}
@Override
@@ -390,7 +309,8 @@ public class TaskViewSimulator implements TransformParams.BuilderProxy {
.withWindowCrop(mTmpCropRect)
.withCornerRadius(getCurrentCornerRadius());
- if (ENABLE_QUICKSTEP_LIVE_TILE.get() && params.getRecentsSurface() != null) {
+ if (ENABLE_QUICKSTEP_LIVE_TILE.get() && mIsForLiveTile
+ && params.getRecentsSurface() != null) {
// When relativeLayer = 0, it reverts the surfaces back to the original order.
builder.withRelativeLayerTo(params.getRecentsSurface(),
mDrawsBelowRecents ? Integer.MIN_VALUE : 0);
diff --git a/quickstep/src/com/android/quickstep/util/TransformParams.java b/quickstep/src/com/android/quickstep/util/TransformParams.java
index 75d6001afd..03d7a37748 100644
--- a/quickstep/src/com/android/quickstep/util/TransformParams.java
+++ b/quickstep/src/com/android/quickstep/util/TransformParams.java
@@ -174,10 +174,10 @@ public class TransformParams {
RemoteAnimationTargetCompat app = targets.unfilteredApps[i];
if (app.mode == targets.targetMode) {
if (app.activityType == RemoteAnimationTargetCompat.ACTIVITY_TYPE_RECENTS) {
- return app.leash;
+ return app.leash.getSurfaceControl();
}
} else {
- return app.leash;
+ return app.leash.getSurfaceControl();
}
}
return null;
diff --git a/quickstep/src/com/android/quickstep/util/UnfoldMoveFromCenterHotseatAnimator.java b/quickstep/src/com/android/quickstep/util/UnfoldMoveFromCenterHotseatAnimator.java
deleted file mode 100644
index dc97dd6f86..0000000000
--- a/quickstep/src/com/android/quickstep/util/UnfoldMoveFromCenterHotseatAnimator.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2021 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.quickstep.util;
-
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.WindowManager;
-
-import com.android.launcher3.Hotseat;
-import com.android.launcher3.Launcher;
-
-/**
- * Animation that moves hotseat icons from center to the sides (final position)
- */
-public class UnfoldMoveFromCenterHotseatAnimator extends BaseUnfoldMoveFromCenterAnimator {
-
- private final Launcher mLauncher;
-
- public UnfoldMoveFromCenterHotseatAnimator(Launcher launcher, WindowManager windowManager) {
- super(windowManager);
- mLauncher = launcher;
- }
-
- @Override
- protected void onPrepareViewsForAnimation() {
- Hotseat hotseat = mLauncher.getHotseat();
-
- ViewGroup hotseatIcons = hotseat.getShortcutsAndWidgets();
- disableClipping(hotseat);
-
- for (int i = 0; i < hotseatIcons.getChildCount(); i++) {
- View child = hotseatIcons.getChildAt(i);
- registerViewForAnimation(child);
- }
- }
-
- @Override
- public void onTransitionFinished() {
- restoreClipping(mLauncher.getHotseat());
- super.onTransitionFinished();
- }
-}
diff --git a/quickstep/src/com/android/quickstep/util/UnfoldMoveFromCenterWorkspaceAnimator.java b/quickstep/src/com/android/quickstep/util/UnfoldMoveFromCenterWorkspaceAnimator.java
deleted file mode 100644
index 354d1579b0..0000000000
--- a/quickstep/src/com/android/quickstep/util/UnfoldMoveFromCenterWorkspaceAnimator.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2021 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.quickstep.util;
-
-import android.view.View;
-import android.view.WindowManager;
-
-import com.android.launcher3.CellLayout;
-import com.android.launcher3.Launcher;
-import com.android.launcher3.ShortcutAndWidgetContainer;
-import com.android.launcher3.Workspace;
-
-/**
- * Animation that moves launcher icons and widgets from center to the sides (final position)
- */
-public class UnfoldMoveFromCenterWorkspaceAnimator extends BaseUnfoldMoveFromCenterAnimator {
-
- private final Launcher mLauncher;
-
- public UnfoldMoveFromCenterWorkspaceAnimator(Launcher launcher, WindowManager windowManager) {
- super(windowManager);
- mLauncher = launcher;
- }
-
- @Override
- protected void onPrepareViewsForAnimation() {
- Workspace<?> workspace = mLauncher.getWorkspace();
-
- // App icons and widgets
- workspace
- .forEachVisiblePage(page -> {
- final CellLayout cellLayout = (CellLayout) page;
- ShortcutAndWidgetContainer itemsContainer = cellLayout
- .getShortcutsAndWidgets();
- disableClipping(cellLayout);
-
- for (int i = 0; i < itemsContainer.getChildCount(); i++) {
- View child = itemsContainer.getChildAt(i);
- registerViewForAnimation(child);
- }
- });
-
- disableClipping(workspace);
- }
-
- @Override
- public void onTransitionFinished() {
- restoreClipping(mLauncher.getWorkspace());
- mLauncher.getWorkspace().forEachVisiblePage(page -> restoreClipping((CellLayout) page));
- super.onTransitionFinished();
- }
-}
diff --git a/quickstep/src/com/android/quickstep/util/WorkspaceRevealAnim.java b/quickstep/src/com/android/quickstep/util/WorkspaceRevealAnim.java
index 5eb543e40d..df94d0bee6 100644
--- a/quickstep/src/com/android/quickstep/util/WorkspaceRevealAnim.java
+++ b/quickstep/src/com/android/quickstep/util/WorkspaceRevealAnim.java
@@ -15,9 +15,7 @@
*/
package com.android.quickstep.util;
-import static com.android.launcher3.LauncherAnimUtils.HOTSEAT_SCALE_PROPERTY_FACTORY;
-import static com.android.launcher3.LauncherAnimUtils.SCALE_INDEX_REVEAL_ANIM;
-import static com.android.launcher3.LauncherAnimUtils.WORKSPACE_SCALE_PROPERTY_FACTORY;
+import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY;
import static com.android.launcher3.LauncherState.BACKGROUND_APP;
import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.launcher3.anim.PropertySetter.NO_ANIM_PROPERTY_SETTER;
@@ -29,11 +27,9 @@ import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
-import android.util.FloatProperty;
import android.view.View;
import com.android.launcher3.BaseQuickstepLauncher;
-import com.android.launcher3.Hotseat;
import com.android.launcher3.Launcher;
import com.android.launcher3.R;
import com.android.launcher3.Workspace;
@@ -53,11 +49,6 @@ public class WorkspaceRevealAnim {
// Should be used for animations running alongside this WorkspaceRevealAnim.
public static final int DURATION_MS = 350;
- private static final FloatProperty<Workspace<?>> WORKSPACE_SCALE_PROPERTY =
- WORKSPACE_SCALE_PROPERTY_FACTORY.get(SCALE_INDEX_REVEAL_ANIM);
-
- private static final FloatProperty<Hotseat> HOTSEAT_SCALE_PROPERTY =
- HOTSEAT_SCALE_PROPERTY_FACTORY.get(SCALE_INDEX_REVEAL_ANIM);
private final float mScaleStart;
private final AnimatorSet mAnimators = new AnimatorSet();
@@ -68,12 +59,12 @@ public class WorkspaceRevealAnim {
ResourceProvider rp = DynamicResource.provider(launcher);
mScaleStart = rp.getFloat(R.dimen.swipe_up_scale_start);
- Workspace<?> workspace = launcher.getWorkspace();
+ Workspace workspace = launcher.getWorkspace();
workspace.setPivotToScaleWithSelf(launcher.getHotseat());
// Add reveal animations.
- addRevealAnimatorsForView(workspace, WORKSPACE_SCALE_PROPERTY);
- addRevealAnimatorsForView(launcher.getHotseat(), HOTSEAT_SCALE_PROPERTY);
+ addRevealAnimatorsForView(workspace);
+ addRevealAnimatorsForView(launcher.getHotseat());
// Add overview scrim animation.
if (animateOverviewScrim) {
@@ -98,8 +89,8 @@ public class WorkspaceRevealAnim {
mAnimators.setInterpolator(Interpolators.DECELERATED_EASE);
}
- private <T extends View> void addRevealAnimatorsForView(T v, FloatProperty<T> scaleProperty) {
- ObjectAnimator scale = ObjectAnimator.ofFloat(v, scaleProperty, mScaleStart, 1f);
+ private void addRevealAnimatorsForView(View v) {
+ ObjectAnimator scale = ObjectAnimator.ofFloat(v, SCALE_PROPERTY, mScaleStart, 1f);
scale.setDuration(DURATION_MS);
scale.setInterpolator(Interpolators.DECELERATED_EASE);
mAnimators.play(scale);
@@ -112,7 +103,7 @@ public class WorkspaceRevealAnim {
mAnimators.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
- scaleProperty.set(v, 1f);
+ SCALE_PROPERTY.set(v, 1f);
v.setAlpha(1f);
}
});
@@ -129,7 +120,7 @@ public class WorkspaceRevealAnim {
launcher.getStateManager().createAtomicAnimation(BACKGROUND_APP, NORMAL, config).start();
// Stop scrolling so that it doesn't interfere with the translation offscreen.
- launcher.<RecentsView>getOverviewPanel().forceFinishScroller();
+ launcher.<RecentsView>getOverviewPanel().getScroller().forceFinished(true);
if (animateOverviewScrim) {
launcher.getWorkspace().getStateTransitionAnimation()
diff --git a/quickstep/src/com/android/quickstep/views/AllAppsEduView.java b/quickstep/src/com/android/quickstep/views/AllAppsEduView.java
index d79b318023..e9d7c3cb31 100644
--- a/quickstep/src/com/android/quickstep/views/AllAppsEduView.java
+++ b/quickstep/src/com/android/quickstep/views/AllAppsEduView.java
@@ -35,7 +35,6 @@ import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
-import androidx.annotation.Nullable;
import androidx.core.graphics.ColorUtils;
import com.android.launcher3.AbstractFloatingView;
@@ -59,7 +58,6 @@ public class AllAppsEduView extends AbstractFloatingView {
private Launcher mLauncher;
private AllAppsEduTouchController mTouchController;
- @Nullable
private AnimatorSet mAnimation;
private GradientDrawable mCircle;
diff --git a/quickstep/src/com/android/quickstep/views/ClearAllButton.java b/quickstep/src/com/android/quickstep/views/ClearAllButton.java
index 50be5ea565..b9a90062b7 100644
--- a/quickstep/src/com/android/quickstep/views/ClearAllButton.java
+++ b/quickstep/src/com/android/quickstep/views/ClearAllButton.java
@@ -21,7 +21,6 @@ import android.util.AttributeSet;
import android.util.FloatProperty;
import android.widget.Button;
-import com.android.launcher3.DeviceProfile;
import com.android.launcher3.statemanager.StatefulActivity;
import com.android.launcher3.touch.PagedOrientationHandler;
@@ -40,24 +39,10 @@ public class ClearAllButton extends Button {
}
};
- public static final FloatProperty<ClearAllButton> DISMISS_ALPHA =
- new FloatProperty<ClearAllButton>("dismissAlpha") {
- @Override
- public Float get(ClearAllButton view) {
- return view.mDismissAlpha;
- }
-
- @Override
- public void setValue(ClearAllButton view, float v) {
- view.setDismissAlpha(v);
- }
- };
-
private final StatefulActivity mActivity;
private float mScrollAlpha = 1;
private float mContentAlpha = 1;
private float mVisibilityAlpha = 1;
- private float mDismissAlpha = 1;
private float mFullscreenProgress = 1;
private float mGridProgress = 1;
@@ -67,7 +52,6 @@ public class ClearAllButton extends Button {
private float mGridTranslationPrimary;
private float mGridScrollOffset;
private float mScrollOffsetPrimary;
- private float mSplitSelectScrollOffsetPrimary;
private int mSidePadding;
@@ -113,13 +97,6 @@ public class ClearAllButton extends Button {
}
}
- public void setDismissAlpha(float alpha) {
- if (mDismissAlpha != alpha) {
- mDismissAlpha = alpha;
- updateAlpha();
- }
- }
-
public void onRecentsViewScroll(int scroll, boolean gridEnabled) {
RecentsView recentsView = getRecentsView();
if (recentsView == null) {
@@ -141,15 +118,12 @@ public class ClearAllButton extends Button {
}
applyPrimaryTranslation();
applySecondaryTranslation();
- float clearAllSpacing =
- recentsView.getPageSpacing() + recentsView.getClearAllExtraPageSpacing();
- clearAllSpacing = mIsRtl ? -clearAllSpacing : clearAllSpacing;
- mScrollAlpha = Math.max((clearAllScroll + clearAllSpacing - scroll) / clearAllSpacing, 0);
+ mScrollAlpha = 1 - shift / orientationSize;
updateAlpha();
}
private void updateAlpha() {
- final float alpha = mScrollAlpha * mContentAlpha * mVisibilityAlpha * mDismissAlpha;
+ final float alpha = mScrollAlpha * mContentAlpha * mVisibilityAlpha;
setAlpha(alpha);
setClickable(Math.min(alpha, 1) == 1);
}
@@ -172,10 +146,6 @@ public class ClearAllButton extends Button {
mScrollOffsetPrimary = scrollOffsetPrimary;
}
- public void setSplitSelectScrollOffsetPrimary(float splitSelectScrollOffsetPrimary) {
- mSplitSelectScrollOffsetPrimary = splitSelectScrollOffsetPrimary;
- }
-
public float getScrollAdjustment(boolean fullscreenEnabled, boolean gridEnabled) {
float scrollAdjustment = 0;
if (fullscreenEnabled) {
@@ -185,7 +155,6 @@ public class ClearAllButton extends Button {
scrollAdjustment += mGridTranslationPrimary + mGridScrollOffset;
}
scrollAdjustment += mScrollOffsetPrimary;
- scrollAdjustment += mSplitSelectScrollOffsetPrimary;
return scrollAdjustment;
}
@@ -249,9 +218,6 @@ public class ClearAllButton extends Button {
* Get the Y translation that is set in the original layout position, before scrolling.
*/
private float getOriginalTranslationY() {
- DeviceProfile deviceProfile = mActivity.getDeviceProfile();
- return deviceProfile.isTablet
- ? deviceProfile.overviewRowSpacing
- : deviceProfile.overviewTaskThumbnailTopMarginPx / 2.0f;
+ return mActivity.getDeviceProfile().overviewTaskThumbnailTopMarginPx / 2.0f;
}
}
diff --git a/quickstep/src/com/android/quickstep/views/DigitalWellBeingToast.java b/quickstep/src/com/android/quickstep/views/DigitalWellBeingToast.java
index 79b15c713a..7c8041c992 100644
--- a/quickstep/src/com/android/quickstep/views/DigitalWellBeingToast.java
+++ b/quickstep/src/com/android/quickstep/views/DigitalWellBeingToast.java
@@ -17,6 +17,8 @@
package com.android.quickstep.views;
import static android.provider.Settings.ACTION_APP_USAGE_SETTINGS;
+import static android.view.Gravity.BOTTOM;
+import static android.view.Gravity.CENTER_HORIZONTAL;
import static com.android.launcher3.Utilities.prefixTextWithIcon;
import static com.android.launcher3.util.Executors.THREAD_POOL_EXECUTOR;
@@ -36,51 +38,25 @@ import android.icu.util.MeasureUnit;
import android.os.Build;
import android.os.UserHandle;
import android.util.Log;
-import android.util.Pair;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewOutlineProvider;
import android.widget.FrameLayout;
import android.widget.TextView;
-import androidx.annotation.IntDef;
-import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
import com.android.launcher3.BaseActivity;
import com.android.launcher3.BaseDraggingActivity;
-import com.android.launcher3.DeviceProfile;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
-import com.android.launcher3.touch.PagedOrientationHandler;
-import com.android.launcher3.util.SplitConfigurationOptions.StagedSplitBounds;
import com.android.systemui.shared.recents.model.Task;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
import java.time.Duration;
import java.util.Locale;
@TargetApi(Build.VERSION_CODES.Q)
public final class DigitalWellBeingToast {
-
- private static final float THRESHOLD_LEFT_ICON_ONLY = 0.4f;
- private static final float THRESHOLD_RIGHT_ICON_ONLY = 0.6f;
-
- /** Will span entire width of taskView with full text */
- private static final int SPLIT_BANNER_FULLSCREEN = 0;
- /** Used for grid task view, only showing icon and time */
- private static final int SPLIT_GRID_BANNER_LARGE = 1;
- /** Used for grid task view, only showing icon */
- private static final int SPLIT_GRID_BANNER_SMALL = 2;
- @IntDef(value = {
- SPLIT_BANNER_FULLSCREEN,
- SPLIT_GRID_BANNER_LARGE,
- SPLIT_GRID_BANNER_SMALL,
- })
- @Retention(RetentionPolicy.SOURCE)
- @interface SPLIT_BANNER_CONFIG{}
-
static final Intent OPEN_APP_USAGE_SETTINGS_TEMPLATE = new Intent(ACTION_APP_USAGE_SETTINGS);
static final int MINUTE_MS = 60000;
@@ -93,20 +69,10 @@ public final class DigitalWellBeingToast {
private Task mTask;
private boolean mHasLimit;
private long mAppRemainingTimeMs;
- @Nullable
private View mBanner;
private ViewOutlineProvider mOldBannerOutlineProvider;
private float mBannerOffsetPercentage;
- /**
- * Clips rect provided by {@link #mOldBannerOutlineProvider} when in the model state to
- * hide this banner as the taskView scales up and down
- */
- private float mModalOffset = 0f;
- @Nullable
- private StagedSplitBounds mStagedSplitBounds;
- private int mSplitBannerConfig = SPLIT_BANNER_FULLSCREEN;
- private float mSplitOffsetTranslationY;
- private float mSplitOffsetTranslationX;
+ private float mVerticalOffset = 0f;
public DigitalWellBeingToast(BaseDraggingActivity activity, TaskView taskView) {
mActivity = activity;
@@ -135,7 +101,7 @@ public final class DigitalWellBeingToast {
}
public String getText() {
- return getText(mAppRemainingTimeMs, false /* forContentDesc */);
+ return getText(mAppRemainingTimeMs);
}
public boolean hasLimit() {
@@ -144,6 +110,12 @@ public final class DigitalWellBeingToast {
public void initialize(Task task) {
mTask = task;
+
+ if (task.key.userId != UserHandle.myUserId()) {
+ setNoLimit();
+ return;
+ }
+
THREAD_POOL_EXECUTOR.execute(() -> {
final AppUsageLimit usageLimit = mLauncherApps.getAppUsageLimit(
task.getTopComponent().getPackageName(),
@@ -164,31 +136,6 @@ public final class DigitalWellBeingToast {
});
}
- public void setSplitConfiguration(StagedSplitBounds stagedSplitBounds) {
- mStagedSplitBounds = stagedSplitBounds;
- if (mStagedSplitBounds == null
- || !mActivity.getDeviceProfile().isTablet
- || mTaskView.isFocusedTask()) {
- mSplitBannerConfig = SPLIT_BANNER_FULLSCREEN;
- return;
- }
-
- // For portrait grid only height of task changes, not width. So we keep the text the same
- if (!mActivity.getDeviceProfile().isLandscape) {
- mSplitBannerConfig = SPLIT_GRID_BANNER_LARGE;
- return;
- }
-
- // For landscape grid, for 30% width we only show icon, otherwise show icon and time
- if (mTask.key.id == mStagedSplitBounds.leftTopTaskId) {
- mSplitBannerConfig = mStagedSplitBounds.leftTaskPercent < THRESHOLD_LEFT_ICON_ONLY ?
- SPLIT_GRID_BANNER_SMALL : SPLIT_GRID_BANNER_LARGE;
- } else {
- mSplitBannerConfig = mStagedSplitBounds.leftTaskPercent > THRESHOLD_RIGHT_ICON_ONLY ?
- SPLIT_GRID_BANNER_SMALL : SPLIT_GRID_BANNER_LARGE;
- }
- }
-
private String getReadableDuration(
Duration duration,
FormatWidth formatWidthHourAndMinute,
@@ -232,33 +179,30 @@ public final class DigitalWellBeingToast {
.formatMeasures(new Measure(0, MeasureUnit.MINUTE));
}
- /**
- * Returns text to show for the banner depending on {@link #mSplitBannerConfig}
- * If {@param forContentDesc} is {@code true}, this will always return the full
- * string corresponding to {@link #SPLIT_BANNER_FULLSCREEN}
- */
- private String getText(long remainingTime, boolean forContentDesc) {
+ private String getReadableDuration(
+ Duration duration,
+ FormatWidth formatWidthHourAndMinute,
+ @StringRes int durationLessThanOneMinuteStringId) {
+ return getReadableDuration(
+ duration,
+ formatWidthHourAndMinute,
+ durationLessThanOneMinuteStringId,
+ /* forceFormatWidth= */ false);
+ }
+
+ private String getRoundedUpToMinuteReadableDuration(long remainingTime) {
final Duration duration = Duration.ofMillis(
remainingTime > MINUTE_MS ?
(remainingTime + MINUTE_MS - 1) / MINUTE_MS * MINUTE_MS :
remainingTime);
- String readableDuration = getReadableDuration(duration,
- FormatWidth.NARROW,
- R.string.shorter_duration_less_than_one_minute,
- false /* forceFormatWidth */);
- if (forContentDesc || mSplitBannerConfig == SPLIT_BANNER_FULLSCREEN) {
- return mActivity.getString(
- R.string.time_left_for_app,
- readableDuration);
- }
+ return getReadableDuration(
+ duration, FormatWidth.NARROW, R.string.shorter_duration_less_than_one_minute);
+ }
- if (mSplitBannerConfig == SPLIT_GRID_BANNER_SMALL) {
- // show no text
- return "";
- } else { // SPLIT_GRID_BANNER_LARGE
- // only show time
- return readableDuration;
- }
+ private String getText(long remainingTime) {
+ return mActivity.getString(
+ R.string.time_left_for_app,
+ getRoundedUpToMinuteReadableDuration(remainingTime));
}
public void openAppUsageSettings(View view) {
@@ -286,11 +230,11 @@ public final class DigitalWellBeingToast {
mActivity.getString(
R.string.task_contents_description_with_remaining_time,
task.titleDescription,
- getText(appRemainingTimeMs, true /* forContentDesc */)) :
+ getText(appRemainingTimeMs)) :
task.titleDescription;
}
- private void replaceBanner(@Nullable View view) {
+ private void replaceBanner(View view) {
resetOldBanner();
setBanner(view);
}
@@ -304,9 +248,9 @@ public final class DigitalWellBeingToast {
}
}
- private void setBanner(@Nullable View view) {
+ private void setBanner(View view) {
mBanner = view;
- if (view != null && mTaskView.getRecentsView() != null) {
+ if (view != null) {
setupAndAddBanner();
setBannerOutline();
}
@@ -315,18 +259,10 @@ public final class DigitalWellBeingToast {
private void setupAndAddBanner() {
FrameLayout.LayoutParams layoutParams =
(FrameLayout.LayoutParams) mBanner.getLayoutParams();
- DeviceProfile deviceProfile = mActivity.getDeviceProfile();
+ layoutParams.gravity = BOTTOM | CENTER_HORIZONTAL;
layoutParams.bottomMargin = ((ViewGroup.MarginLayoutParams)
mTaskView.getThumbnail().getLayoutParams()).bottomMargin;
- PagedOrientationHandler orientationHandler = mTaskView.getPagedOrientationHandler();
- Pair<Float, Float> translations = orientationHandler
- .getDwbLayoutTranslations(mTaskView.getMeasuredWidth(),
- mTaskView.getMeasuredHeight(), mStagedSplitBounds, deviceProfile,
- mTaskView.getThumbnails(), mTask.key.id, mBanner);
- mSplitOffsetTranslationX = translations.first;
- mSplitOffsetTranslationY = translations.second;
- updateTranslationY();
- updateTranslationX();
+ mBanner.setTranslationY(mBannerOffsetPercentage * mBanner.getHeight());
mTaskView.addView(mBanner);
}
@@ -336,9 +272,7 @@ public final class DigitalWellBeingToast {
@Override
public void getOutline(View view, Outline outline) {
mOldBannerOutlineProvider.getOutline(view, outline);
- float verticalTranslation = -view.getTranslationY() + mModalOffset
- + mSplitOffsetTranslationY;
- outline.offset(0, Math.round(verticalTranslation));
+ outline.offset(0, Math.round(-view.getTranslationY() + mVerticalOffset));
}
});
mBanner.setClipToOutline(true);
@@ -346,33 +280,13 @@ public final class DigitalWellBeingToast {
void updateBannerOffset(float offsetPercentage, float verticalOffset) {
if (mBanner != null && mBannerOffsetPercentage != offsetPercentage) {
- mModalOffset = verticalOffset;
+ mVerticalOffset = verticalOffset;
mBannerOffsetPercentage = offsetPercentage;
- updateTranslationY();
+ mBanner.setTranslationY(offsetPercentage * mBanner.getHeight() + mVerticalOffset);
mBanner.invalidateOutline();
}
}
- private void updateTranslationY() {
- if (mBanner == null) {
- return;
- }
-
- mBanner.setTranslationY(
- (mBannerOffsetPercentage * mBanner.getHeight()) +
- mModalOffset +
- mSplitOffsetTranslationY
- );
- }
-
- private void updateTranslationX() {
- if (mBanner == null) {
- return;
- }
-
- mBanner.setTranslationX(mSplitOffsetTranslationX);
- }
-
void setBannerColorTint(int color, float amount) {
if (mBanner == null) {
return;
diff --git a/quickstep/src/com/android/quickstep/views/FloatingTaskThumbnailView.java b/quickstep/src/com/android/quickstep/views/FloatingTaskThumbnailView.java
deleted file mode 100644
index d869fed37e..0000000000
--- a/quickstep/src/com/android/quickstep/views/FloatingTaskThumbnailView.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.quickstep.views;
-
-import android.content.Context;
-import android.graphics.Bitmap;
-import android.graphics.BitmapShader;
-import android.graphics.Canvas;
-import android.graphics.Matrix;
-import android.graphics.Paint;
-import android.graphics.Shader;
-import android.util.AttributeSet;
-import android.view.View;
-
-import androidx.annotation.Nullable;
-
-/**
- * A child view of {@link com.android.quickstep.views.FloatingTaskView} to draw the thumbnail in a
- * rounded corner frame. While the purpose of this class sounds similar to
- * {@link TaskThumbnailView}, it doesn't need a lot of complex logic in {@link TaskThumbnailView}
- * in relation to moving with {@link RecentsView}.
- */
-public class FloatingTaskThumbnailView extends View {
-
- private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
- private final Matrix mMatrix = new Matrix();
-
- private @Nullable BitmapShader mBitmapShader;
- private @Nullable Bitmap mBitmap;
-
- public FloatingTaskThumbnailView(Context context) {
- this(context, null);
- }
-
- public FloatingTaskThumbnailView(Context context, AttributeSet attrs) {
- this(context, attrs, 0);
- }
-
- public FloatingTaskThumbnailView(Context context, AttributeSet attrs, int defStyleAttr) {
- super(context, attrs, defStyleAttr);
- }
-
- @Override
- protected void onDraw(Canvas canvas) {
- if (mBitmap == null) {
- return;
- }
-
- // Scale down the bitmap to fix x, and crop in y.
- float scale = 1.0f * getMeasuredWidth() / mBitmap.getWidth();
- mMatrix.reset();
- mMatrix.postScale(scale, scale);
- mBitmapShader.setLocalMatrix(mMatrix);
-
- FloatingTaskView parent = (FloatingTaskView) getParent();
- parent.drawRoundedRect(canvas, mPaint);
- }
-
- public void setThumbnail(Bitmap bitmap) {
- mBitmap = bitmap;
- if (bitmap != null) {
- mBitmapShader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
- mPaint.setShader(mBitmapShader);
- }
- }
-}
diff --git a/quickstep/src/com/android/quickstep/views/FloatingTaskView.java b/quickstep/src/com/android/quickstep/views/FloatingTaskView.java
deleted file mode 100644
index c980d1eac2..0000000000
--- a/quickstep/src/com/android/quickstep/views/FloatingTaskView.java
+++ /dev/null
@@ -1,308 +0,0 @@
-package com.android.quickstep.views;
-
-import static com.android.launcher3.anim.Interpolators.ACCEL;
-import static com.android.launcher3.anim.Interpolators.DEACCEL_3;
-import static com.android.launcher3.anim.Interpolators.LINEAR;
-
-import android.animation.ValueAnimator;
-import android.content.Context;
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.Paint;
-import android.graphics.Rect;
-import android.graphics.RectF;
-import android.graphics.drawable.Drawable;
-import android.util.AttributeSet;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.FrameLayout;
-
-import androidx.annotation.Nullable;
-
-import com.android.launcher3.BaseActivity;
-import com.android.launcher3.InsettableFrameLayout;
-import com.android.launcher3.LauncherAnimUtils;
-import com.android.launcher3.R;
-import com.android.launcher3.Utilities;
-import com.android.launcher3.anim.PendingAnimation;
-import com.android.launcher3.statemanager.StatefulActivity;
-import com.android.launcher3.touch.PagedOrientationHandler;
-import com.android.launcher3.util.SplitConfigurationOptions;
-import com.android.launcher3.views.BaseDragLayer;
-import com.android.quickstep.util.MultiValueUpdateListener;
-import com.android.quickstep.util.TaskCornerRadius;
-import com.android.systemui.shared.system.QuickStepContract;
-
-/**
- * Create an instance via
- * {@link #getFloatingTaskView(StatefulActivity, View, Bitmap, Drawable, RectF)} to
- * which will have the thumbnail from the provided existing TaskView overlaying the taskview itself.
- *
- * Can then animate the taskview using
- * {@link #addAnimation(PendingAnimation, RectF, Rect, boolean, boolean)}
- * giving a starting and ending bounds. Currently this is set to use the split placeholder view,
- * but it could be generified.
- *
- * TODO: Figure out how to copy thumbnail data from existing TaskView to this view.
- */
-public class FloatingTaskView extends FrameLayout {
-
- private FloatingTaskThumbnailView mThumbnailView;
- private SplitPlaceholderView mSplitPlaceholderView;
- private RectF mStartingPosition;
- private final StatefulActivity mActivity;
- private final boolean mIsRtl;
- private final FullscreenDrawParams mFullscreenParams;
- private PagedOrientationHandler mOrientationHandler;
- @SplitConfigurationOptions.StagePosition
- private int mStagePosition;
-
- public FloatingTaskView(Context context) {
- this(context, null);
- }
-
- public FloatingTaskView(Context context, @Nullable AttributeSet attrs) {
- this(context, attrs, 0);
- }
-
- public FloatingTaskView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
- super(context, attrs, defStyleAttr);
- mActivity = BaseActivity.fromContext(context);
- mIsRtl = Utilities.isRtl(getResources());
- mFullscreenParams = new FullscreenDrawParams(context);
- }
-
- @Override
- protected void onFinishInflate() {
- super.onFinishInflate();
- mThumbnailView = findViewById(R.id.thumbnail);
- mSplitPlaceholderView = findViewById(R.id.split_placeholder);
- mSplitPlaceholderView.setAlpha(0);
- }
-
- private void init(StatefulActivity launcher, View originalView, @Nullable Bitmap thumbnail,
- Drawable icon, RectF positionOut) {
- mStartingPosition = positionOut;
- updateInitialPositionForView(originalView);
- final InsettableFrameLayout.LayoutParams lp =
- (InsettableFrameLayout.LayoutParams) getLayoutParams();
-
- mSplitPlaceholderView.setLayoutParams(new FrameLayout.LayoutParams(lp.width, lp.height));
- setPivotX(0);
- setPivotY(0);
-
- // Copy bounds of exiting thumbnail into ImageView
- mThumbnailView.setThumbnail(thumbnail);
-
- mThumbnailView.setVisibility(VISIBLE);
-
- RecentsView recentsView = launcher.getOverviewPanel();
- mOrientationHandler = recentsView.getPagedOrientationHandler();
- mStagePosition = recentsView.getSplitPlaceholder().getActiveSplitStagePosition();
- mSplitPlaceholderView.setIcon(icon,
- mContext.getResources().getDimensionPixelSize(R.dimen.split_placeholder_icon_size));
- mSplitPlaceholderView.getIconView().setRotation(mOrientationHandler.getDegreesRotated());
- }
-
- /**
- * Configures and returns a an instance of {@link FloatingTaskView} initially matching the
- * appearance of {@code originalView}.
- */
- public static FloatingTaskView getFloatingTaskView(StatefulActivity launcher,
- View originalView, @Nullable Bitmap thumbnail, Drawable icon, RectF positionOut) {
- final BaseDragLayer dragLayer = launcher.getDragLayer();
- ViewGroup parent = (ViewGroup) dragLayer.getParent();
- final FloatingTaskView floatingView = (FloatingTaskView) launcher.getLayoutInflater()
- .inflate(R.layout.floating_split_select_view, parent, false);
-
- floatingView.init(launcher, originalView, thumbnail, icon, positionOut);
- parent.addView(floatingView);
- return floatingView;
- }
-
- public void updateInitialPositionForView(View originalView) {
- Rect viewBounds = new Rect(0, 0, originalView.getWidth(), originalView.getHeight());
- Utilities.getBoundsForViewInDragLayer(mActivity.getDragLayer(), originalView, viewBounds,
- false /* ignoreTransform */, null /* recycle */,
- mStartingPosition);
- final InsettableFrameLayout.LayoutParams lp = new InsettableFrameLayout.LayoutParams(
- Math.round(mStartingPosition.width()),
- Math.round(mStartingPosition.height()));
- initPosition(mStartingPosition, lp);
- setLayoutParams(lp);
- }
-
- public void update(RectF bounds, float progress) {
- MarginLayoutParams lp = (MarginLayoutParams) getLayoutParams();
-
- float dX = bounds.left - mStartingPosition.left;
- float dY = bounds.top - lp.topMargin;
- float scaleX = bounds.width() / lp.width;
- float scaleY = bounds.height() / lp.height;
-
- mFullscreenParams.updateParams(bounds, progress, scaleX, scaleY);
-
- setTranslationX(dX);
- setTranslationY(dY);
- setScaleX(scaleX);
- setScaleY(scaleY);
- mSplitPlaceholderView.invalidate();
- mThumbnailView.invalidate();
-
- float childScaleX = 1f / scaleX;
- float childScaleY = 1f / scaleY;
- mOrientationHandler.setPrimaryScale(mSplitPlaceholderView.getIconView(), childScaleX);
- mOrientationHandler.setSecondaryScale(mSplitPlaceholderView.getIconView(), childScaleY);
- }
-
- public void updateOrientationHandler(PagedOrientationHandler orientationHandler) {
- mOrientationHandler = orientationHandler;
- mSplitPlaceholderView.getIconView().setRotation(mOrientationHandler.getDegreesRotated());
- }
-
- protected void initPosition(RectF pos, InsettableFrameLayout.LayoutParams lp) {
- mStartingPosition.set(pos);
- lp.ignoreInsets = true;
- // Position the floating view exactly on top of the original
- lp.topMargin = Math.round(pos.top);
- if (mIsRtl) {
- lp.setMarginStart(mActivity.getDeviceProfile().widthPx - Math.round(pos.right));
- } else {
- lp.setMarginStart(Math.round(pos.left));
- }
-
- // Set the properties here already to make sure they are available when running the first
- // animation frame.
- int left = (int) pos.left;
- layout(left, lp.topMargin, left + lp.width, lp.topMargin + lp.height);
- }
-
- public void addAnimation(PendingAnimation animation, RectF startingBounds, Rect endBounds,
- boolean fadeWithThumbnail, boolean isStagedTask) {
- mFullscreenParams.setIsStagedTask(isStagedTask);
- final BaseDragLayer dragLayer = mActivity.getDragLayer();
- int[] dragLayerBounds = new int[2];
- dragLayer.getLocationOnScreen(dragLayerBounds);
- SplitOverlayProperties prop = new SplitOverlayProperties(endBounds,
- startingBounds, dragLayerBounds[0], dragLayerBounds[1]);
-
- ValueAnimator transitionAnimator = ValueAnimator.ofFloat(0, 1);
- animation.add(transitionAnimator);
- long animDuration = animation.getDuration();
- RectF floatingTaskViewBounds = new RectF();
-
- if (fadeWithThumbnail) {
- animation.addFloat(mSplitPlaceholderView, SplitPlaceholderView.ALPHA_FLOAT,
- 0, 1, ACCEL);
- animation.addFloat(mThumbnailView, LauncherAnimUtils.VIEW_ALPHA,
- 1, 0, DEACCEL_3);
- } else if (isStagedTask) {
- // Fade in the placeholder view when split is initiated from homescreen / all apps
- // icons.
- if (mSplitPlaceholderView.getAlpha() == 0) {
- animation.addFloat(mSplitPlaceholderView, SplitPlaceholderView.ALPHA_FLOAT,
- 0.3f, 1, ACCEL);
- }
- }
-
- MultiValueUpdateListener listener = new MultiValueUpdateListener() {
- final FloatProp mDx = new FloatProp(0, prop.dX, 0, animDuration, LINEAR);
- final FloatProp mDy = new FloatProp(0, prop.dY, 0, animDuration, LINEAR);
- final FloatProp mTaskViewScaleX = new FloatProp(1f, prop.finalTaskViewScaleX, 0,
- animDuration, LINEAR);
- final FloatProp mTaskViewScaleY = new FloatProp(1f, prop.finalTaskViewScaleY, 0,
- animDuration, LINEAR);
- @Override
- public void onUpdate(float percent, boolean initOnly) {
- // Calculate the icon position.
- floatingTaskViewBounds.set(startingBounds);
- floatingTaskViewBounds.offset(mDx.value, mDy.value);
- Utilities.scaleRectFAboutCenter(floatingTaskViewBounds, mTaskViewScaleX.value,
- mTaskViewScaleY.value);
-
- update(floatingTaskViewBounds, percent);
- }
- };
- transitionAnimator.addUpdateListener(listener);
- }
-
- void drawRoundedRect(Canvas canvas, Paint paint) {
- if (mFullscreenParams == null) {
- return;
- }
-
- canvas.drawRoundRect(0, 0, getMeasuredWidth(), getMeasuredHeight(),
- mFullscreenParams.mCurrentDrawnCornerRadius / mFullscreenParams.mScaleX,
- mFullscreenParams.mCurrentDrawnCornerRadius / mFullscreenParams.mScaleY,
- paint);
- }
-
- /**
- * When a split is staged, center the icon in the staging area. Accounts for device insets.
- * @param iconView The icon that should be centered.
- * @param onScreenRectCenterX The x-center of the on-screen staging area (most of the Rect is
- * offscreen).
- * @param onScreenRectCenterY The y-center of the on-screen staging area (most of the Rect is
- * offscreen).
- */
- void centerIconView(IconView iconView, float onScreenRectCenterX, float onScreenRectCenterY) {
- mOrientationHandler.updateStagedSplitIconParams(iconView, onScreenRectCenterX,
- onScreenRectCenterY, mFullscreenParams.mScaleX, mFullscreenParams.mScaleY,
- iconView.getDrawableWidth(), iconView.getDrawableHeight(),
- mActivity.getDeviceProfile(), mStagePosition);
- }
-
- private static class SplitOverlayProperties {
-
- private final float finalTaskViewScaleX;
- private final float finalTaskViewScaleY;
- private final float dX;
- private final float dY;
-
- SplitOverlayProperties(Rect endBounds, RectF startTaskViewBounds,
- int dragLayerLeft, int dragLayerTop) {
- float maxScaleX = endBounds.width() / startTaskViewBounds.width();
- float maxScaleY = endBounds.height() / startTaskViewBounds.height();
-
- finalTaskViewScaleX = maxScaleX;
- finalTaskViewScaleY = maxScaleY;
-
- // Animate to the center of the window bounds in screen coordinates.
- float centerX = endBounds.centerX() - dragLayerLeft;
- float centerY = endBounds.centerY() - dragLayerTop;
-
- dX = centerX - startTaskViewBounds.centerX();
- dY = centerY - startTaskViewBounds.centerY();
- }
- }
-
- public static class FullscreenDrawParams {
-
- private final float mCornerRadius;
- private final float mWindowCornerRadius;
- public boolean mIsStagedTask;
- public final RectF mBounds = new RectF();
- public float mCurrentDrawnCornerRadius;
- public float mScaleX = 1;
- public float mScaleY = 1;
-
- public FullscreenDrawParams(Context context) {
- mCornerRadius = TaskCornerRadius.get(context);
- mWindowCornerRadius = QuickStepContract.getWindowCornerRadius(context);
-
- mCurrentDrawnCornerRadius = mCornerRadius;
- }
-
- public void updateParams(RectF bounds, float progress, float scaleX, float scaleY) {
- mBounds.set(bounds);
- mScaleX = scaleX;
- mScaleY = scaleY;
- mCurrentDrawnCornerRadius = mIsStagedTask ? mWindowCornerRadius :
- Utilities.mapRange(progress, mCornerRadius, mWindowCornerRadius);
- }
-
- public void setIsStagedTask(boolean isStagedTask) {
- mIsStagedTask = isStagedTask;
- }
- }
-}
diff --git a/quickstep/src/com/android/quickstep/views/FloatingWidgetBackgroundView.java b/quickstep/src/com/android/quickstep/views/FloatingWidgetBackgroundView.java
index adea1a40cf..1548268891 100644
--- a/quickstep/src/com/android/quickstep/views/FloatingWidgetBackgroundView.java
+++ b/quickstep/src/com/android/quickstep/views/FloatingWidgetBackgroundView.java
@@ -27,8 +27,6 @@ import android.view.View;
import android.view.ViewOutlineProvider;
import android.widget.RemoteViews.RemoteViewOutlineProvider;
-import androidx.annotation.Nullable;
-
import com.android.launcher3.widget.LauncherAppWidgetHostView;
import com.android.launcher3.widget.RoundedCornerEnforcement;
@@ -44,9 +42,7 @@ final class FloatingWidgetBackgroundView extends View {
private final DrawableProperties mForegroundProperties = new DrawableProperties();
private final DrawableProperties mBackgroundProperties = new DrawableProperties();
- @Nullable
private Drawable mOriginalForeground;
- @Nullable
private Drawable mOriginalBackground;
private float mFinalRadius;
private float mInitialOutlineRadius;
@@ -54,7 +50,7 @@ final class FloatingWidgetBackgroundView extends View {
private boolean mIsUsingFallback;
private View mSourceView;
- FloatingWidgetBackgroundView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
+ FloatingWidgetBackgroundView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
setOutlineProvider(new ViewOutlineProvider() {
@Override
@@ -136,7 +132,7 @@ final class FloatingWidgetBackgroundView extends View {
}
/** Returns the maximum corner radius of {@param drawable}. */
- private static float getMaxRadius(@Nullable Drawable drawable) {
+ private static float getMaxRadius(Drawable drawable) {
if (!(drawable instanceof GradientDrawable)) return 0;
float[] cornerRadii = ((GradientDrawable) drawable).getCornerRadii();
float cornerRadius = ((GradientDrawable) drawable).getCornerRadius();
@@ -165,10 +161,8 @@ final class FloatingWidgetBackgroundView extends View {
/** Stores and modifies a drawable's properties through an animation. */
private static class DrawableProperties {
- @Nullable
private Drawable mDrawable;
private float mOriginalRadius;
- @Nullable
private float[] mOriginalRadii;
private final float[] mTmpRadii = new float[8];
diff --git a/quickstep/src/com/android/quickstep/views/FloatingWidgetView.java b/quickstep/src/com/android/quickstep/views/FloatingWidgetView.java
index 8a5f42afaf..88b11a0884 100644
--- a/quickstep/src/com/android/quickstep/views/FloatingWidgetView.java
+++ b/quickstep/src/com/android/quickstep/views/FloatingWidgetView.java
@@ -30,8 +30,6 @@ import android.view.ViewGroup;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.widget.FrameLayout;
-import androidx.annotation.Nullable;
-
import com.android.launcher3.Launcher;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
@@ -57,14 +55,10 @@ public class FloatingWidgetView extends FrameLayout implements AnimatorListener,
private LauncherAppWidgetHostView mAppWidgetView;
private View mAppWidgetBackgroundView;
private RectF mBackgroundPosition;
- @Nullable
private GhostView mForegroundOverlayView;
- @Nullable
private Runnable mEndRunnable;
- @Nullable
private Runnable mFastFinishRunnable;
- @Nullable
private Runnable mOnTargetChangeRunnable;
private boolean mAppTargetIsTranslucent;
@@ -74,11 +68,11 @@ public class FloatingWidgetView extends FrameLayout implements AnimatorListener,
this(context, null);
}
- public FloatingWidgetView(Context context, @Nullable AttributeSet attrs) {
+ public FloatingWidgetView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
- public FloatingWidgetView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
+ public FloatingWidgetView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mLauncher = Launcher.getLauncher(context);
mListenerView = new ListenerView(context, attrs);
diff --git a/quickstep/src/com/android/quickstep/views/GroupedTaskView.java b/quickstep/src/com/android/quickstep/views/GroupedTaskView.java
deleted file mode 100644
index 244a794562..0000000000
--- a/quickstep/src/com/android/quickstep/views/GroupedTaskView.java
+++ /dev/null
@@ -1,316 +0,0 @@
-package com.android.quickstep.views;
-
-import static com.android.launcher3.util.SplitConfigurationOptions.DEFAULT_SPLIT_RATIO;
-import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_BOTTOM_OR_RIGHT;
-import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT;
-
-import android.content.Context;
-import android.graphics.PointF;
-import android.util.AttributeSet;
-import android.view.MotionEvent;
-import android.view.View;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
-import com.android.launcher3.DeviceProfile;
-import com.android.launcher3.R;
-import com.android.launcher3.Utilities;
-import com.android.launcher3.util.RunnableList;
-import com.android.launcher3.util.SplitConfigurationOptions.StagedSplitBounds;
-import com.android.launcher3.util.TransformingTouchDelegate;
-import com.android.quickstep.RecentsModel;
-import com.android.quickstep.TaskIconCache;
-import com.android.quickstep.TaskThumbnailCache;
-import com.android.quickstep.util.CancellableTask;
-import com.android.quickstep.util.RecentsOrientedState;
-import com.android.systemui.shared.recents.model.Task;
-import com.android.systemui.shared.recents.model.ThumbnailData;
-import com.android.systemui.shared.system.InteractionJankMonitorWrapper;
-
-import java.util.HashMap;
-import java.util.function.Consumer;
-
-/**
- * TaskView that contains and shows thumbnails for not one, BUT TWO(!!) tasks
- *
- * That's right. If you call within the next 5 minutes we'll go ahead and double your order and
- * send you !! TWO !! Tasks along with their TaskThumbnailViews complimentary. On. The. House.
- * And not only that, we'll even clean up your thumbnail request if you don't like it.
- * All the benefits of one TaskView, except DOUBLED!
- *
- * (Icon loading sold separately, fees may apply. Shipping & Handling for Overlays not included).
- */
-public class GroupedTaskView extends TaskView {
-
- @Nullable
- private Task mSecondaryTask;
- private TaskThumbnailView mSnapshotView2;
- private IconView mIconView2;
- @Nullable
- private CancellableTask<ThumbnailData> mThumbnailLoadRequest2;
- @Nullable
- private CancellableTask mIconLoadRequest2;
- private final float[] mIcon2CenterCoords = new float[2];
- private TransformingTouchDelegate mIcon2TouchDelegate;
- @Nullable private StagedSplitBounds mSplitBoundsConfig;
- private final DigitalWellBeingToast mDigitalWellBeingToast2;
-
- public GroupedTaskView(Context context) {
- this(context, null);
- }
-
- public GroupedTaskView(Context context, AttributeSet attrs) {
- this(context, attrs, 0);
- }
-
- public GroupedTaskView(Context context, AttributeSet attrs, int defStyleAttr) {
- super(context, attrs, defStyleAttr);
- mDigitalWellBeingToast2 = new DigitalWellBeingToast(mActivity, this);
- }
-
- @Override
- protected void onFinishInflate() {
- super.onFinishInflate();
- mSnapshotView2 = findViewById(R.id.bottomright_snapshot);
- mIconView2 = findViewById(R.id.bottomRight_icon);
- mIcon2TouchDelegate = new TransformingTouchDelegate(mIconView2);
- }
-
- public void bind(Task primary, Task secondary, RecentsOrientedState orientedState,
- @Nullable StagedSplitBounds splitBoundsConfig) {
- super.bind(primary, orientedState);
- mSecondaryTask = secondary;
- mTaskIdContainer[1] = secondary.key.id;
- mTaskIdAttributeContainer[1] = new TaskIdAttributeContainer(secondary, mSnapshotView2,
- mIconView2, STAGE_POSITION_BOTTOM_OR_RIGHT);
- mTaskIdAttributeContainer[0].setStagePosition(STAGE_POSITION_TOP_OR_LEFT);
- mSnapshotView2.bind(secondary);
- mSplitBoundsConfig = splitBoundsConfig;
- }
-
- @Override
- public void onTaskListVisibilityChanged(boolean visible, int changes) {
- super.onTaskListVisibilityChanged(visible, changes);
- if (visible) {
- RecentsModel model = RecentsModel.INSTANCE.get(getContext());
- TaskThumbnailCache thumbnailCache = model.getThumbnailCache();
- TaskIconCache iconCache = model.getIconCache();
-
- if (needsUpdate(changes, FLAG_UPDATE_THUMBNAIL)) {
- mThumbnailLoadRequest2 = thumbnailCache.updateThumbnailInBackground(mSecondaryTask,
- thumbnailData -> mSnapshotView2.setThumbnail(
- mSecondaryTask, thumbnailData
- ));
- }
-
- if (needsUpdate(changes, FLAG_UPDATE_ICON)) {
- mIconLoadRequest2 = iconCache.updateIconInBackground(mSecondaryTask,
- (task) -> {
- setIcon(mIconView2, task.icon);
- mDigitalWellBeingToast2.initialize(mSecondaryTask);
- mDigitalWellBeingToast2.setSplitConfiguration(mSplitBoundsConfig);
- mDigitalWellBeingToast.setSplitConfiguration(mSplitBoundsConfig);
- });
- }
- } else {
- if (needsUpdate(changes, FLAG_UPDATE_THUMBNAIL)) {
- mSnapshotView2.setThumbnail(null, null);
- // Reset the task thumbnail reference as well (it will be fetched from the cache or
- // reloaded next time we need it)
- mSecondaryTask.thumbnail = null;
- }
- if (needsUpdate(changes, FLAG_UPDATE_ICON)) {
- setIcon(mIconView2, null);
- }
- }
- }
-
- public void updateSplitBoundsConfig(StagedSplitBounds stagedSplitBounds) {
- mSplitBoundsConfig = stagedSplitBounds;
- invalidate();
- }
-
- public float getSplitRatio() {
- if (mSplitBoundsConfig != null) {
- return mSplitBoundsConfig.appsStackedVertically
- ? mSplitBoundsConfig.topTaskPercent : mSplitBoundsConfig.leftTaskPercent;
- }
- return DEFAULT_SPLIT_RATIO;
- }
-
- @Override
- public boolean offerTouchToChildren(MotionEvent event) {
- computeAndSetIconTouchDelegate(mIconView2, mIcon2CenterCoords, mIcon2TouchDelegate);
- if (mIcon2TouchDelegate.onTouchEvent(event)) {
- return true;
- }
-
- return super.offerTouchToChildren(event);
- }
-
- @Override
- protected void cancelPendingLoadTasks() {
- super.cancelPendingLoadTasks();
- if (mThumbnailLoadRequest2 != null) {
- mThumbnailLoadRequest2.cancel();
- mThumbnailLoadRequest2 = null;
- }
- if (mIconLoadRequest2 != null) {
- mIconLoadRequest2.cancel();
- mIconLoadRequest2 = null;
- }
- }
-
- @Nullable
- @Override
- public RunnableList launchTaskAnimated() {
- if (mTask == null || mSecondaryTask == null) {
- return null;
- }
-
- RunnableList endCallback = new RunnableList();
- RecentsView recentsView = getRecentsView();
- // Callbacks run from remote animation when recents animation not currently running
- InteractionJankMonitorWrapper.begin(this,
- InteractionJankMonitorWrapper.CUJ_SPLIT_SCREEN_ENTER, "Enter form GroupedTaskView");
- recentsView.getSplitPlaceholder().launchTasks(this /*groupedTaskView*/,
- success -> {
- endCallback.executeAllAndDestroy();
- InteractionJankMonitorWrapper.end(
- InteractionJankMonitorWrapper.CUJ_SPLIT_SCREEN_ENTER);
- },
- false /* freezeTaskList */);
-
- // Callbacks get run from recentsView for case when recents animation already running
- recentsView.addSideTaskLaunchCallback(endCallback);
- return endCallback;
- }
-
- @Override
- public void launchTask(@NonNull Consumer<Boolean> callback, boolean freezeTaskList) {
- getRecentsView().getSplitPlaceholder().launchTasks(mTask.key.id, mSecondaryTask.key.id,
- STAGE_POSITION_TOP_OR_LEFT, callback, freezeTaskList, getSplitRatio());
- }
-
- @Override
- void refreshThumbnails(@Nullable HashMap<Integer, ThumbnailData> thumbnailDatas) {
- super.refreshThumbnails(thumbnailDatas);
- if (mSecondaryTask != null && thumbnailDatas != null) {
- final ThumbnailData thumbnailData = thumbnailDatas.get(mSecondaryTask.key.id);
- if (thumbnailData != null) {
- mSnapshotView2.setThumbnail(mSecondaryTask, thumbnailData);
- return;
- }
- }
-
- mSnapshotView2.refresh();
- }
-
- @Override
- public TaskThumbnailView[] getThumbnails() {
- return new TaskThumbnailView[]{mSnapshotView, mSnapshotView2};
- }
-
- @Override
- protected int getChildTaskIndexAtPosition(PointF position) {
- if (isCoordInView(mIconView2, position) || isCoordInView(mSnapshotView2, position)) {
- return 1;
- }
- return super.getChildTaskIndexAtPosition(position);
- }
-
- private boolean isCoordInView(View v, PointF position) {
- float[] localPos = new float[]{position.x, position.y};
- Utilities.mapCoordInSelfToDescendant(v, this, localPos);
- return Utilities.pointInView(v, localPos[0], localPos[1], 0f /* slop */);
- }
-
- @Override
- public void onRecycle() {
- super.onRecycle();
- mSnapshotView2.setThumbnail(mSecondaryTask, null);
- mSplitBoundsConfig = null;
- }
-
- @Override
- protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- super.onMeasure(widthMeasureSpec, heightMeasureSpec);
- int widthSize = MeasureSpec.getSize(widthMeasureSpec);
- int heightSize = MeasureSpec.getSize(heightMeasureSpec);
- setMeasuredDimension(widthSize, heightSize);
- if (mSplitBoundsConfig == null || mSnapshotView == null || mSnapshotView2 == null) {
- return;
- }
- getPagedOrientationHandler().measureGroupedTaskViewThumbnailBounds(mSnapshotView,
- mSnapshotView2, widthSize, heightSize, mSplitBoundsConfig,
- mActivity.getDeviceProfile(), getLayoutDirection() == LAYOUT_DIRECTION_RTL);
- updateIconPlacement();
- }
-
- @Override
- public void setOverlayEnabled(boolean overlayEnabled) {
- super.setOverlayEnabled(overlayEnabled);
- mSnapshotView2.setOverlayEnabled(overlayEnabled);
- }
-
- @Override
- public void setOrientationState(RecentsOrientedState orientationState) {
- super.setOrientationState(orientationState);
- DeviceProfile deviceProfile = mActivity.getDeviceProfile();
- boolean isGridTask = deviceProfile.isTablet && !isFocusedTask();
- int iconDrawableSize = isGridTask ? deviceProfile.overviewTaskIconDrawableSizeGridPx
- : deviceProfile.overviewTaskIconDrawableSizePx;
- mIconView2.setDrawableSize(iconDrawableSize, iconDrawableSize);
- mIconView2.setRotation(getPagedOrientationHandler().getDegreesRotated());
- updateIconPlacement();
- updateSecondaryDwbPlacement();
- }
-
- private void updateIconPlacement() {
- if (mSplitBoundsConfig == null) {
- return;
- }
-
- DeviceProfile deviceProfile = mActivity.getDeviceProfile();
- int taskIconHeight = deviceProfile.overviewTaskIconSizePx;
- boolean isRtl = getLayoutDirection() == LAYOUT_DIRECTION_RTL;
-
- getPagedOrientationHandler().setSplitIconParams(mIconView, mIconView2,
- taskIconHeight, mSnapshotView.getMeasuredWidth(), mSnapshotView.getMeasuredHeight(),
- getMeasuredHeight(), getMeasuredWidth(), isRtl, deviceProfile,
- mSplitBoundsConfig);
- }
-
- private void updateSecondaryDwbPlacement() {
- if (mSecondaryTask == null) {
- return;
- }
- mDigitalWellBeingToast2.initialize(mSecondaryTask);
- }
-
- @Override
- protected void updateSnapshotRadius() {
- super.updateSnapshotRadius();
- mSnapshotView2.setFullscreenParams(mCurrentFullscreenParams);
- }
-
- @Override
- protected void setIconAndDimTransitionProgress(float progress, boolean invert) {
- super.setIconAndDimTransitionProgress(progress, invert);
- // Value set by super call
- float scale = mIconView.getAlpha();
- mIconView2.setAlpha(scale);
- mDigitalWellBeingToast2.updateBannerOffset(1f - scale,
- mCurrentFullscreenParams.mCurrentDrawnInsets.top
- + mCurrentFullscreenParams.mCurrentDrawnInsets.bottom);
- }
-
- @Override
- public void setColorTint(float amount, int tintColor) {
- super.setColorTint(amount, tintColor);
- mIconView2.setIconColorTint(tintColor, amount);
- mSnapshotView2.setDimAlpha(amount);
- mDigitalWellBeingToast2.setBannerColorTint(tintColor, amount);
- }
-}
diff --git a/quickstep/src/com/android/quickstep/views/IconView.java b/quickstep/src/com/android/quickstep/views/IconView.java
index 5895c05dcd..5b0ade0d17 100644
--- a/quickstep/src/com/android/quickstep/views/IconView.java
+++ b/quickstep/src/com/android/quickstep/views/IconView.java
@@ -17,14 +17,10 @@ package com.android.quickstep.views;
import android.content.Context;
import android.graphics.Canvas;
-import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
-import android.view.Gravity;
import android.view.View;
-import androidx.annotation.Nullable;
-
import com.android.launcher3.Utilities;
/**
@@ -33,9 +29,7 @@ import com.android.launcher3.Utilities;
*/
public class IconView extends View {
- @Nullable
private Drawable mDrawable;
- private int mDrawableWidth, mDrawableHeight;
public IconView(Context context) {
super(context);
@@ -49,57 +43,27 @@ public class IconView extends View {
super(context, attrs, defStyleAttr);
}
- /**
- * Sets a {@link Drawable} to be displayed.
- */
- public void setDrawable(@Nullable Drawable d) {
+ public void setDrawable(Drawable d) {
if (mDrawable != null) {
mDrawable.setCallback(null);
}
mDrawable = d;
if (mDrawable != null) {
mDrawable.setCallback(this);
- setDrawableSizeInternal(getWidth(), getHeight());
+ mDrawable.setBounds(0, 0, getWidth(), getHeight());
}
invalidate();
}
- /**
- * Sets the size of the icon drawable.
- */
- public void setDrawableSize(int iconWidth, int iconHeight) {
- mDrawableWidth = iconWidth;
- mDrawableHeight = iconHeight;
- if (mDrawable != null) {
- setDrawableSizeInternal(getWidth(), getHeight());
- }
- }
-
- private void setDrawableSizeInternal(int selfWidth, int selfHeight) {
- Rect selfRect = new Rect(0, 0, selfWidth, selfHeight);
- Rect drawableRect = new Rect();
- Gravity.apply(Gravity.CENTER, mDrawableWidth, mDrawableHeight, selfRect, drawableRect);
- mDrawable.setBounds(drawableRect);
- }
-
- @Nullable
public Drawable getDrawable() {
return mDrawable;
}
- public int getDrawableWidth() {
- return mDrawableWidth;
- }
-
- public int getDrawableHeight() {
- return mDrawableHeight;
- }
-
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
if (mDrawable != null) {
- setDrawableSizeInternal(w, h);
+ mDrawable.setBounds(0, 0, w, h);
}
}
diff --git a/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java b/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
index 306ebd73c8..65956d578f 100644
--- a/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
@@ -21,27 +21,25 @@ import static com.android.launcher3.LauncherState.OVERVIEW;
import static com.android.launcher3.LauncherState.OVERVIEW_MODAL_TASK;
import static com.android.launcher3.LauncherState.OVERVIEW_SPLIT_SELECT;
import static com.android.launcher3.LauncherState.SPRING_LOADED;
-import static com.android.launcher3.testing.TestProtocol.BAD_STATE;
import android.annotation.TargetApi;
import android.content.Context;
+import android.content.res.Configuration;
import android.os.Build;
import android.util.AttributeSet;
-import android.util.Log;
import android.view.MotionEvent;
import android.view.Surface;
+import android.widget.FrameLayout;
-import androidx.annotation.Nullable;
-
-import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.BaseQuickstepLauncher;
import com.android.launcher3.LauncherState;
-import com.android.launcher3.popup.QuickstepSystemShortcut;
import com.android.launcher3.statehandlers.DepthController;
import com.android.launcher3.statemanager.StateManager.StateListener;
+import com.android.launcher3.uioverrides.plugins.PluginManagerWrapper;
import com.android.launcher3.util.SplitConfigurationOptions;
import com.android.quickstep.LauncherActivityInterface;
-import com.android.quickstep.util.SplitSelectStateController;
+import com.android.systemui.plugins.PluginListener;
+import com.android.systemui.plugins.RecentsExtraCard;
/**
* {@link RecentsView} used in Launcher activity
@@ -50,31 +48,47 @@ import com.android.quickstep.util.SplitSelectStateController;
public class LauncherRecentsView extends RecentsView<BaseQuickstepLauncher, LauncherState>
implements StateListener<LauncherState> {
+ private RecentsExtraCard mRecentsExtraCardPlugin;
+ private RecentsExtraViewContainer mRecentsExtraViewContainer;
+ private PluginListener<RecentsExtraCard> mRecentsExtraCardPluginListener =
+ new PluginListener<RecentsExtraCard>() {
+ @Override
+ public void onPluginConnected(RecentsExtraCard recentsExtraCard, Context context) {
+ createRecentsExtraCard();
+ mRecentsExtraCardPlugin = recentsExtraCard;
+ mRecentsExtraCardPlugin.setupView(context, mRecentsExtraViewContainer, mActivity);
+ }
+
+ @Override
+ public void onPluginDisconnected(RecentsExtraCard plugin) {
+ removeView(mRecentsExtraViewContainer);
+ mRecentsExtraCardPlugin = null;
+ mRecentsExtraViewContainer = null;
+ }
+ };
+
public LauncherRecentsView(Context context) {
this(context, null);
}
- public LauncherRecentsView(Context context, @Nullable AttributeSet attrs) {
+ public LauncherRecentsView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
- public LauncherRecentsView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
+ public LauncherRecentsView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr, LauncherActivityInterface.INSTANCE);
mActivity.getStateManager().addStateListener(this);
}
@Override
- public void init(OverviewActionsView actionsView,
- SplitSelectStateController splitPlaceholderView) {
+ public void init(OverviewActionsView actionsView, SplitPlaceholderView splitPlaceholderView) {
super.init(actionsView, splitPlaceholderView);
- Log.d(BAD_STATE, "LauncherRecentsView init setContentAlpha=0");
setContentAlpha(0);
}
@Override
public void startHome() {
mActivity.getStateManager().goToState(NORMAL);
- AbstractFloatingView.closeAllOpenViews(mActivity, mActivity.isStarted());
}
@Override
@@ -100,10 +114,6 @@ public class LauncherRecentsView extends RecentsView<BaseQuickstepLauncher, Laun
setOverviewStateEnabled(toState.overviewUi);
setOverviewGridEnabled(toState.displayOverviewTasksAsGrid(mActivity.getDeviceProfile()));
setOverviewFullscreenEnabled(toState.getOverviewFullscreenProgress() == 1);
- if (toState == OVERVIEW_MODAL_TASK) {
- setOverviewSelectEnabled(true);
- }
- Log.d(BAD_STATE, "LRV onStateTransitionStart setFreezeVisibility=true, toState=" + toState);
setFreezeViewVisibility(true);
}
@@ -113,19 +123,8 @@ public class LauncherRecentsView extends RecentsView<BaseQuickstepLauncher, Laun
// Clean-up logic that occurs when recents is no longer in use/visible.
reset();
}
- boolean isOverlayEnabled = finalState == OVERVIEW || finalState == OVERVIEW_MODAL_TASK;
- setOverlayEnabled(isOverlayEnabled);
- Log.d(BAD_STATE, "LRV onStateTransitionComplete setFreezeVisibility=false, finalState="
- + finalState);
+ setOverlayEnabled(finalState == OVERVIEW || finalState == OVERVIEW_MODAL_TASK);
setFreezeViewVisibility(false);
- if (finalState != OVERVIEW_MODAL_TASK) {
- setOverviewSelectEnabled(false);
- }
-
- if (isOverlayEnabled) {
- runActionOnRemoteHandles(remoteTargetHandle ->
- remoteTargetHandle.getTaskViewSimulator().setDrawsBelowRecents(true));
- }
}
@Override
@@ -147,6 +146,73 @@ public class LauncherRecentsView extends RecentsView<BaseQuickstepLauncher, Laun
}
@Override
+ protected void onAttachedToWindow() {
+ super.onAttachedToWindow();
+ PluginManagerWrapper.INSTANCE.get(getContext()).addPluginListener(
+ mRecentsExtraCardPluginListener, RecentsExtraCard.class);
+ }
+
+ @Override
+ protected void onDetachedFromWindow() {
+ super.onDetachedFromWindow();
+ PluginManagerWrapper.INSTANCE.get(getContext()).removePluginListener(
+ mRecentsExtraCardPluginListener);
+ }
+
+ @Override
+ protected int computeMinScroll() {
+ if (canComputeScrollX() && !mIsRtl) {
+ return computeScrollX();
+ }
+ return super.computeMinScroll();
+ }
+
+ @Override
+ protected int computeMaxScroll() {
+ if (canComputeScrollX() && mIsRtl) {
+ return computeScrollX();
+ }
+ return super.computeMaxScroll();
+ }
+
+ private boolean canComputeScrollX() {
+ return mRecentsExtraCardPlugin != null && getTaskViewCount() > 0
+ && !mDisallowScrollToClearAll;
+ }
+
+ private int computeScrollX() {
+ int scrollIndex = getTaskViewStartIndex() - 1;
+ while (scrollIndex >= 0 && getChildAt(scrollIndex) instanceof RecentsExtraViewContainer
+ && ((RecentsExtraViewContainer) getChildAt(scrollIndex)).isScrollable()) {
+ scrollIndex--;
+ }
+ return getScrollForPage(scrollIndex + 1);
+ }
+
+ private void createRecentsExtraCard() {
+ mRecentsExtraViewContainer = new RecentsExtraViewContainer(getContext());
+ FrameLayout.LayoutParams helpCardParams =
+ new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT,
+ FrameLayout.LayoutParams.MATCH_PARENT);
+ mRecentsExtraViewContainer.setLayoutParams(helpCardParams);
+ mRecentsExtraViewContainer.setScrollable(true);
+ addView(mRecentsExtraViewContainer, 0);
+ }
+
+ @Override
+ public boolean hasRecentsExtraCard() {
+ return mRecentsExtraViewContainer != null;
+ }
+
+ @Override
+ public void setContentAlpha(float alpha) {
+ super.setContentAlpha(alpha);
+ if (mRecentsExtraViewContainer != null) {
+ mRecentsExtraViewContainer.setAlpha(alpha);
+ }
+ }
+
+ @Override
protected DepthController getDepthController() {
return mActivity.getDepthController();
}
@@ -159,7 +225,6 @@ public class LauncherRecentsView extends RecentsView<BaseQuickstepLauncher, Laun
} else {
if (mActivity.isInState(LauncherState.OVERVIEW_MODAL_TASK)) {
mActivity.getStateManager().goToState(LauncherState.OVERVIEW);
- resetModalVisuals();
}
}
}
@@ -177,19 +242,19 @@ public class LauncherRecentsView extends RecentsView<BaseQuickstepLauncher, Laun
@Override
public void initiateSplitSelect(TaskView taskView,
- @SplitConfigurationOptions.StagePosition int stagePosition) {
- super.initiateSplitSelect(taskView, stagePosition);
+ SplitConfigurationOptions.SplitPositionOption splitPositionOption) {
+ super.initiateSplitSelect(taskView, splitPositionOption);
mActivity.getStateManager().goToState(LauncherState.OVERVIEW_SPLIT_SELECT);
}
@Override
- public void initiateSplitSelect(QuickstepSystemShortcut.SplitSelectSource splitSelectSource) {
- super.initiateSplitSelect(splitSelectSource);
- mActivity.getStateManager().goToState(LauncherState.OVERVIEW_SPLIT_SELECT);
- }
-
- @Override
- protected boolean canLaunchFullscreenTask() {
- return !mActivity.isInState(OVERVIEW_SPLIT_SELECT);
+ protected void onConfigurationChanged(Configuration newConfig) {
+ super.onConfigurationChanged(newConfig);
+ // If overview is in modal state when rotate, reset it to overview state without running
+ // animation.
+ if (mActivity.isInState(OVERVIEW_MODAL_TASK)) {
+ mActivity.getStateManager().goToState(LauncherState.OVERVIEW, false);
+ resetModalVisuals();
+ }
}
}
diff --git a/quickstep/src/com/android/quickstep/views/OverviewActionsView.java b/quickstep/src/com/android/quickstep/views/OverviewActionsView.java
index 1c4e497332..8c115e564c 100644
--- a/quickstep/src/com/android/quickstep/views/OverviewActionsView.java
+++ b/quickstep/src/com/android/quickstep/views/OverviewActionsView.java
@@ -16,16 +16,16 @@
package com.android.quickstep.views;
+import static com.android.launcher3.anim.Interpolators.ACCEL_DEACCEL;
+import static com.android.launcher3.config.FeatureFlags.ENABLE_OVERVIEW_SHARE;
+
import android.content.Context;
import android.content.res.Configuration;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.View;
import android.view.View.OnClickListener;
-import android.view.ViewGroup;
-import android.widget.Button;
import android.widget.FrameLayout;
-import android.widget.LinearLayout;
import androidx.annotation.IntDef;
import androidx.annotation.Nullable;
@@ -33,11 +33,11 @@ import androidx.annotation.Nullable;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Insettable;
import com.android.launcher3.R;
-import com.android.launcher3.uioverrides.ApiWrapper;
-import com.android.launcher3.util.DisplayController;
-import com.android.launcher3.util.DisplayController.NavigationMode;
+import com.android.launcher3.Utilities;
import com.android.launcher3.util.MultiValueAlpha;
import com.android.launcher3.util.MultiValueAlpha.AlphaProperty;
+import com.android.quickstep.SysUINavigationMode;
+import com.android.quickstep.SysUINavigationMode.Mode;
import com.android.quickstep.TaskOverlayFactory.OverlayUICallbacks;
import com.android.quickstep.util.LayoutUtils;
@@ -55,15 +55,13 @@ public class OverviewActionsView<T extends OverlayUICallbacks> extends FrameLayo
@IntDef(flag = true, value = {
HIDDEN_NON_ZERO_ROTATION,
HIDDEN_NO_TASKS,
- HIDDEN_NO_RECENTS,
- HIDDEN_SPLIT_SCREEN})
+ HIDDEN_NO_RECENTS})
@Retention(RetentionPolicy.SOURCE)
public @interface ActionsHiddenFlags { }
public static final int HIDDEN_NON_ZERO_ROTATION = 1 << 0;
public static final int HIDDEN_NO_TASKS = 1 << 1;
public static final int HIDDEN_NO_RECENTS = 1 << 2;
- public static final int HIDDEN_SPLIT_SCREEN = 1 << 3;
@IntDef(flag = true, value = {
DISABLED_SCROLLING,
@@ -80,9 +78,9 @@ public class OverviewActionsView<T extends OverlayUICallbacks> extends FrameLayo
private static final int INDEX_VISIBILITY_ALPHA = 1;
private static final int INDEX_FULLSCREEN_ALPHA = 2;
private static final int INDEX_HIDDEN_FLAGS_ALPHA = 3;
+ private static final int INDEX_SCROLL_ALPHA = 4;
private final MultiValueAlpha mMultiValueAlpha;
- private Button mSplitButton;
@ActionsHiddenFlags
private int mHiddenFlags;
@@ -90,12 +88,12 @@ public class OverviewActionsView<T extends OverlayUICallbacks> extends FrameLayo
@ActionsDisabledFlags
protected int mDisabledFlags;
- @Nullable
protected T mCallbacks;
- @Nullable
+ private float mModalness;
+ private float mModalTransformY;
+
protected DeviceProfile mDp;
- private final Rect mTaskSize = new Rect();
public OverviewActionsView(Context context) {
this(context, null);
@@ -114,10 +112,13 @@ public class OverviewActionsView<T extends OverlayUICallbacks> extends FrameLayo
@Override
protected void onFinishInflate() {
super.onFinishInflate();
+ View share = findViewById(R.id.action_share);
+ share.setOnClickListener(this);
findViewById(R.id.action_screenshot).setOnClickListener(this);
-
- mSplitButton = findViewById(R.id.action_split);
- mSplitButton.setOnClickListener(this);
+ if (ENABLE_OVERVIEW_SHARE.get()) {
+ share.setVisibility(VISIBLE);
+ findViewById(R.id.oav_three_button_space).setVisibility(VISIBLE);
+ }
}
/**
@@ -135,24 +136,24 @@ public class OverviewActionsView<T extends OverlayUICallbacks> extends FrameLayo
return;
}
int id = view.getId();
- if (id == R.id.action_screenshot) {
+ if (id == R.id.action_share) {
+ mCallbacks.onShare();
+ } else if (id == R.id.action_screenshot) {
mCallbacks.onScreenshot();
- } else if (id == R.id.action_split) {
- mCallbacks.onSplit();
}
}
@Override
protected void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
- updateVerticalMargin(DisplayController.getNavigationMode(getContext()));
+ updateVerticalMargin(SysUINavigationMode.getMode(getContext()));
}
@Override
public void setInsets(Rect insets) {
mInsets.set(insets);
- updateVerticalMargin(DisplayController.getNavigationMode(getContext()));
- updatePadding();
+ updateVerticalMargin(SysUINavigationMode.getMode(getContext()));
+ updateHorizontalPadding();
}
public void updateHiddenFlags(@ActionsHiddenFlags int visibilityFlags, boolean enable) {
@@ -179,6 +180,7 @@ public class OverviewActionsView<T extends OverlayUICallbacks> extends FrameLayo
} else {
mDisabledFlags &= ~disabledFlags;
}
+ //
boolean isEnabled = (mDisabledFlags & ~DISABLED_ROTATED) == 0;
LayoutUtils.setViewEnabled(this, isEnabled);
}
@@ -195,84 +197,86 @@ public class OverviewActionsView<T extends OverlayUICallbacks> extends FrameLayo
return mMultiValueAlpha.getProperty(INDEX_FULLSCREEN_ALPHA);
}
- /**
- * Offsets OverviewActionsView horizontal position based on 3 button nav container in taskbar.
- */
- private void updatePadding() {
- if (mDp == null) {
- return;
- }
- boolean alignFor3ButtonTaskbar = mDp.isTaskbarPresent && !mDp.isGestureMode;
- if (alignFor3ButtonTaskbar) {
- // Add extra horizontal spacing
- int additionalPadding = ApiWrapper.getHotseatEndOffset(getContext());
- if (isLayoutRtl()) {
- setPadding(mInsets.left + additionalPadding, 0, mInsets.right, 0);
- } else {
- setPadding(mInsets.left, 0, mInsets.right + additionalPadding, 0);
- }
- } else {
- setPadding(mInsets.left, 0, mInsets.right, 0);
- }
+ public AlphaProperty getScrollAlpha() {
+ return mMultiValueAlpha.getProperty(INDEX_SCROLL_ALPHA);
+ }
+
+ private void updateHorizontalPadding() {
+ setPadding(mInsets.left, 0, mInsets.right, 0);
}
/** Updates vertical margins for different navigation mode or configuration changes. */
- public void updateVerticalMargin(NavigationMode mode) {
+ public void updateVerticalMargin(Mode mode) {
if (mDp == null) {
return;
}
LayoutParams actionParams = (LayoutParams) findViewById(
R.id.action_buttons).getLayoutParams();
actionParams.setMargins(
- actionParams.leftMargin, mDp.overviewActionsTopMarginPx,
- actionParams.rightMargin, getBottomMargin());
+ actionParams.leftMargin, getOverviewActionsTopMarginPx(mode, mDp),
+ actionParams.rightMargin, getOverviewActionsBottomMarginPx(mode, mDp));
}
- private int getBottomMargin() {
- if (mDp == null) {
- return 0;
- }
+ /**
+ * Set the device profile for this view to draw with.
+ */
+ public void setDp(DeviceProfile dp) {
+ mDp = dp;
+ updateVerticalMargin(SysUINavigationMode.getMode(getContext()));
+ requestLayout();
+ }
- if (mDp.isVerticalBarLayout()) {
- return mDp.getInsets().bottom;
- }
+ /**
+ * The current task is fully modal (modalness = 1) when it is shown on its own in a modal
+ * way. Modalness 0 means the task is shown in context with all the other tasks.
+ */
+ public void setTaskModalness(float modalness) {
+ mModalness = modalness;
+ applyTranslationY();
+ }
- if (!mDp.isGestureMode && mDp.isTaskbarPresent) {
- return mDp.getOverviewActionsClaimedSpaceBelow();
- }
+ public void setModalTransformY(float modalTransformY) {
+ mModalTransformY = modalTransformY;
+ applyTranslationY();
+ }
- // Align to bottom of task Rect.
- return mDp.heightPx - mTaskSize.bottom - mDp.overviewActionsTopMarginPx
- - mDp.overviewActionsHeight;
+ private void applyTranslationY() {
+ setTranslationY(getModalTrans(mModalTransformY));
}
- /**
- * Updates device profile and task size for this view to draw with.
- */
- public void updateDimension(DeviceProfile dp, Rect taskSize) {
- mDp = dp;
- mTaskSize.set(taskSize);
- updateVerticalMargin(DisplayController.getNavigationMode(getContext()));
+ private float getModalTrans(float endTranslation) {
+ float progress = ACCEL_DEACCEL.getInterpolation(mModalness);
+ return Utilities.mapRange(progress, 0, endTranslation);
+ }
- LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
- dp.isVerticalBarLayout() ? 0 : dp.overviewActionsButtonSpacing,
- ViewGroup.LayoutParams.MATCH_PARENT);
- params.weight = dp.isVerticalBarLayout() ? 1 : 0;
- findViewById(R.id.action_split_space).setLayoutParams(params);
+ /** Get the top margin associated with the action buttons in Overview. */
+ public static int getOverviewActionsTopMarginPx(
+ SysUINavigationMode.Mode mode, DeviceProfile dp) {
+ // In vertical bar, use the smaller task margin for the top regardless of mode
+ if (dp.isVerticalBarLayout()) {
+ return dp.overviewTaskMarginPx;
+ }
- requestLayout();
+ if (mode == SysUINavigationMode.Mode.THREE_BUTTONS) {
+ return dp.overviewActionsMarginThreeButtonPx;
+ }
- mSplitButton.setCompoundDrawablesWithIntrinsicBounds(
- (dp.isLandscape ? R.drawable.ic_split_horizontal : R.drawable.ic_split_vertical),
- 0, 0, 0);
+ return dp.overviewActionsMarginGesturePx;
}
- public void setSplitButtonVisible(boolean visible) {
- if (mSplitButton == null) {
- return;
+ /** Get the bottom margin associated with the action buttons in Overview. */
+ public static int getOverviewActionsBottomMarginPx(
+ SysUINavigationMode.Mode mode, DeviceProfile dp) {
+ int inset = dp.getInsets().bottom;
+
+ if (dp.isVerticalBarLayout()) {
+ return inset;
+ }
+
+ if (mode == SysUINavigationMode.Mode.THREE_BUTTONS) {
+ return dp.overviewActionsMarginThreeButtonPx + inset;
}
- mSplitButton.setVisibility(visible ? VISIBLE : GONE);
- findViewById(R.id.action_split_space).setVisibility(visible ? VISIBLE : GONE);
+ return dp.overviewActionsMarginGesturePx + inset;
}
}
diff --git a/quickstep/src/com/android/quickstep/views/RecentsExtraViewContainer.java b/quickstep/src/com/android/quickstep/views/RecentsExtraViewContainer.java
new file mode 100644
index 0000000000..16bc3bc533
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/views/RecentsExtraViewContainer.java
@@ -0,0 +1,54 @@
+/*
+ * 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.
+ */
+
+package com.android.quickstep.views;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.widget.FrameLayout;
+
+/**
+ * Empty view to house recents overview extra card
+ */
+public class RecentsExtraViewContainer extends FrameLayout {
+
+ private boolean mScrollable = false;
+
+ public RecentsExtraViewContainer(Context context) {
+ super(context);
+ }
+
+ public RecentsExtraViewContainer(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public RecentsExtraViewContainer(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ }
+
+ /**
+ * Determine whether the view should be scrolled to in the recents overview, similar to the
+ * taskviews.
+ * @return true if viewed should be scrolled to, false if not
+ */
+ public boolean isScrollable() {
+ return mScrollable;
+ }
+
+ public void setScrollable(boolean scrollable) {
+ this.mScrollable = scrollable;
+ }
+}
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index 2360396cf7..388706071c 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -32,10 +32,10 @@ import static com.android.launcher3.Utilities.mapToRange;
import static com.android.launcher3.Utilities.squaredHypot;
import static com.android.launcher3.Utilities.squaredTouchSlop;
import static com.android.launcher3.anim.Interpolators.ACCEL;
+import static com.android.launcher3.anim.Interpolators.ACCEL_0_5;
import static com.android.launcher3.anim.Interpolators.ACCEL_0_75;
import static com.android.launcher3.anim.Interpolators.ACCEL_DEACCEL;
import static com.android.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN;
-import static com.android.launcher3.anim.Interpolators.FINAL_FRAME;
import static com.android.launcher3.anim.Interpolators.LINEAR;
import static com.android.launcher3.anim.Interpolators.clampToProgress;
import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE;
@@ -46,15 +46,11 @@ import static com.android.launcher3.statehandlers.DepthController.DEPTH;
import static com.android.launcher3.touch.PagedOrientationHandler.CANVAS_TRANSLATE;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
-import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_BOTTOM_OR_RIGHT;
-import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT;
import static com.android.launcher3.util.SystemUiController.UI_STATE_FULLSCREEN_TASK;
import static com.android.quickstep.TaskUtils.checkCurrentOrManagedUserId;
-import static com.android.quickstep.views.ClearAllButton.DISMISS_ALPHA;
import static com.android.quickstep.views.OverviewActionsView.HIDDEN_NON_ZERO_ROTATION;
import static com.android.quickstep.views.OverviewActionsView.HIDDEN_NO_RECENTS;
import static com.android.quickstep.views.OverviewActionsView.HIDDEN_NO_TASKS;
-import static com.android.quickstep.views.OverviewActionsView.HIDDEN_SPLIT_SCREEN;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
@@ -64,8 +60,8 @@ import android.animation.LayoutTransition.TransitionListener;
import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
import android.animation.ValueAnimator;
-import android.annotation.SuppressLint;
import android.annotation.TargetApi;
+import android.app.ActivityManager.RunningTaskInfo;
import android.content.Context;
import android.content.LocusId;
import android.content.res.Configuration;
@@ -81,17 +77,14 @@ import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Bundle;
-import android.os.SystemClock;
import android.os.UserHandle;
-import android.os.VibrationEffect;
import android.text.Layout;
import android.text.StaticLayout;
import android.text.TextPaint;
import android.util.AttributeSet;
import android.util.FloatProperty;
-import android.util.Log;
-import android.util.Pair;
import android.util.SparseBooleanArray;
+import android.view.Gravity;
import android.view.HapticFeedbackConstants;
import android.view.KeyEvent;
import android.view.LayoutInflater;
@@ -103,12 +96,10 @@ import android.view.ViewTreeObserver.OnScrollChangedListener;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.animation.Interpolator;
+import android.widget.FrameLayout;
import android.widget.ListView;
import android.widget.OverScroller;
-import android.widget.Toast;
-import android.window.PictureInPictureSurfaceTransaction;
-import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.UiThread;
import androidx.core.graphics.ColorUtils;
@@ -121,6 +112,7 @@ import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.PagedView;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
+import com.android.launcher3.anim.AnimationSuccessListener;
import com.android.launcher3.anim.AnimatorListeners;
import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.anim.PendingAnimation;
@@ -128,20 +120,18 @@ import com.android.launcher3.anim.SpringProperty;
import com.android.launcher3.compat.AccessibilityManagerCompat;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.icons.cache.HandlerRunnable;
-import com.android.launcher3.popup.QuickstepSystemShortcut;
import com.android.launcher3.statehandlers.DepthController;
import com.android.launcher3.statemanager.BaseState;
import com.android.launcher3.statemanager.StatefulActivity;
import com.android.launcher3.touch.OverScroll;
import com.android.launcher3.touch.PagedOrientationHandler;
import com.android.launcher3.util.DynamicResource;
-import com.android.launcher3.util.IntArray;
import com.android.launcher3.util.IntSet;
import com.android.launcher3.util.MultiValueAlpha;
import com.android.launcher3.util.ResourceBasedOverride.Overrides;
+import com.android.launcher3.util.SplitConfigurationOptions;
import com.android.launcher3.util.RunnableList;
-import com.android.launcher3.util.SplitConfigurationOptions.StagePosition;
-import com.android.launcher3.util.SplitConfigurationOptions.StagedSplitBounds;
+import com.android.launcher3.util.SplitConfigurationOptions.SplitPositionOption;
import com.android.launcher3.util.Themes;
import com.android.launcher3.util.TranslateEdgeEffect;
import com.android.launcher3.util.ViewPool;
@@ -153,16 +143,11 @@ import com.android.quickstep.RecentsAnimationTargets;
import com.android.quickstep.RecentsModel;
import com.android.quickstep.RecentsModel.TaskVisualsChangeListener;
import com.android.quickstep.RemoteAnimationTargets;
-import com.android.quickstep.RemoteTargetGluer;
-import com.android.quickstep.RemoteTargetGluer.RemoteTargetHandle;
-import com.android.quickstep.RotationTouchHelper;
import com.android.quickstep.SystemUiProxy;
import com.android.quickstep.TaskOverlayFactory;
import com.android.quickstep.TaskThumbnailCache;
import com.android.quickstep.TaskViewUtils;
-import com.android.quickstep.TopTaskTracker;
import com.android.quickstep.ViewUtils;
-import com.android.quickstep.util.GroupTask;
import com.android.quickstep.util.LayoutUtils;
import com.android.quickstep.util.RecentsOrientedState;
import com.android.quickstep.util.SplitScreenBounds;
@@ -170,12 +155,11 @@ import com.android.quickstep.util.SplitSelectStateController;
import com.android.quickstep.util.SurfaceTransactionApplier;
import com.android.quickstep.util.TaskViewSimulator;
import com.android.quickstep.util.TransformParams;
-import com.android.quickstep.util.VibratorWrapper;
import com.android.systemui.plugins.ResourceProvider;
import com.android.systemui.shared.recents.model.Task;
+import com.android.systemui.shared.recents.model.Task.TaskKey;
import com.android.systemui.shared.recents.model.ThumbnailData;
import com.android.systemui.shared.system.ActivityManagerWrapper;
-import com.android.systemui.shared.system.InteractionJankMonitorWrapper;
import com.android.systemui.shared.system.PackageManagerWrapper;
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat.SurfaceParams;
@@ -184,9 +168,7 @@ import com.android.systemui.shared.system.TaskStackChangeListeners;
import com.android.wm.shell.pip.IPipAnimationListener;
import java.util.ArrayList;
-import java.util.HashMap;
import java.util.List;
-import java.util.Objects;
import java.util.function.Consumer;
/**
@@ -198,9 +180,6 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
TaskThumbnailCache.HighResLoadingState.HighResLoadingStateChangedCallback,
TaskVisualsChangeListener, SplitScreenBounds.OnChangeListener {
- private static final String TAG = "RecentsView";
- private static final boolean DEBUG = false;
-
// TODO(b/184899234): We use this timeout to wait a fixed period after switching to the
// screenshot when dismissing the current live task to ensure the app can try and get stopped.
private static final int REMOVE_TASK_WAIT_FOR_APP_STOP_MS = 100;
@@ -260,12 +239,6 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
}
};
- public static final int SCROLL_VIBRATION_PRIMITIVE =
- Utilities.ATLEAST_S ? VibrationEffect.Composition.PRIMITIVE_LOW_TICK : -1;
- public static final float SCROLL_VIBRATION_PRIMITIVE_SCALE = 0.6f;
- public static final VibrationEffect SCROLL_VIBRATION_FALLBACK =
- VibratorWrapper.EFFECT_TEXTURE_TICK;
-
/**
* Can be used to tint the color of the RecentsView to simulate a scrim that can views
* excluded from. Really should be a proper scrim.
@@ -344,15 +317,8 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
view.setScaleY(scale);
view.mLastComputedTaskStartPushOutDistance = null;
view.mLastComputedTaskEndPushOutDistance = null;
- view.runActionOnRemoteHandles(new Consumer<RemoteTargetHandle>() {
- @Override
- public void accept(RemoteTargetHandle remoteTargetHandle) {
- remoteTargetHandle.getTaskViewSimulator().recentsViewScale.value =
- scale;
- }
- });
+ view.mLiveTileTaskViewSimulator.recentsViewScale.value = scale;
view.setTaskViewsResistanceTranslation(view.mTaskViewsSecondaryTranslation);
- view.updateTaskViewsSnapshotRadius();
view.updatePageOffsets();
}
@@ -378,47 +344,29 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
// OverScroll constants
private static final int OVERSCROLL_PAGE_SNAP_ANIMATION_DURATION = 270;
- private static final int DEFAULT_ACTIONS_VIEW_ALPHA_ANIMATION_DURATION = 300;
-
private static final int DISMISS_TASK_DURATION = 300;
private static final int ADDITION_TASK_DURATION = 200;
private static final float INITIAL_DISMISS_TRANSLATION_INTERPOLATION_OFFSET = 0.55f;
private static final float ADDITIONAL_DISMISS_TRANSLATION_INTERPOLATION_OFFSET = 0.05f;
- private static final float ANIMATION_DISMISS_PROGRESS_MIDPOINT = 0.5f;
- private static final float END_DISMISS_TRANSLATION_INTERPOLATION_OFFSET = 0.75f;
-
- private static final float SIGNIFICANT_MOVE_SCREEN_WIDTH_PERCENTAGE = 0.15f;
protected final RecentsOrientedState mOrientationState;
protected final BaseActivityInterface<STATE_TYPE, ACTIVITY_TYPE> mSizeStrategy;
- @Nullable
protected RecentsAnimationController mRecentsAnimationController;
- @Nullable
protected SurfaceTransactionApplier mSyncTransactionApplier;
protected int mTaskWidth;
protected int mTaskHeight;
- // Used to position the top of a task in the top row of the grid
- private float mTaskGridVerticalDiff;
- // The vertical space one grid task takes + space between top and bottom row.
- private float mTopBottomRowHeightDiff;
- // mTaskGridVerticalDiff and mTopBottomRowHeightDiff summed together provides the top
- // position for bottom row of grid tasks.
-
- @Nullable
- protected RemoteTargetHandle[] mRemoteTargetHandles;
+ protected final TransformParams mLiveTileParams = new TransformParams();
+ protected final TaskViewSimulator mLiveTileTaskViewSimulator;
protected final Rect mLastComputedTaskSize = new Rect();
protected final Rect mLastComputedGridSize = new Rect();
protected final Rect mLastComputedGridTaskSize = new Rect();
// How much a task that is directly offscreen will be pushed out due to RecentsView scale/pivot.
- @Nullable
protected Float mLastComputedTaskStartPushOutDistance = null;
- @Nullable
protected Float mLastComputedTaskEndPushOutDistance = null;
protected boolean mEnableDrawingLiveTile = false;
protected final Rect mTempRect = new Rect();
protected final RectF mTempRectF = new RectF();
private final PointF mTempPointF = new PointF();
- private final Matrix mTempMatrix = new Matrix();
private final float[] mTempFloat = new float[1];
private final List<OnScrollChangedListener> mScrollListeners = new ArrayList<>();
@@ -427,10 +375,9 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
protected final ACTIVITY_TYPE mActivity;
private final float mFastFlingVelocity;
- private final int mScrollHapticMinGapMillis;
private final RecentsModel mModel;
- private final int mSplitPlaceholderSize;
- private final int mSplitPlaceholderInset;
+ private final int mRowSpacing;
+ private final int mGridSideMargin;
private final ClearAllButton mClearAllButton;
private final Rect mClearAllButtonDeadZoneRect = new Rect();
private final Rect mTaskViewDeadZoneRect = new Rect();
@@ -444,11 +391,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
private final InvariantDeviceProfile mIdp;
- /**
- * Getting views should be done via {@link #getTaskViewFromPool(boolean)}
- */
private final ViewPool<TaskView> mTaskViewPool;
- private final ViewPool<GroupedTaskView> mGroupedTaskViewPool;
private final TaskOverlayFactory mTaskOverlayFactory;
@@ -457,7 +400,6 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
protected boolean mFreezeViewVisibility;
private boolean mOverviewGridEnabled;
private boolean mOverviewFullscreenEnabled;
- private boolean mOverviewSelectEnabled;
private float mAdjacentPageHorizontalOffset = 0;
protected float mTaskViewsSecondaryTranslation = 0;
@@ -465,21 +407,17 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
protected float mTaskViewsSecondarySplitTranslation = 0;
// Progress from 0 to 1 where 0 is a carousel and 1 is a 2 row grid.
private float mGridProgress = 0;
- private boolean mShowAsGridLastOnLayout = false;
private final IntSet mTopRowIdSet = new IntSet();
// The GestureEndTarget that is still in progress.
- @Nullable
protected GestureState.GestureEndTarget mCurrentGestureEndTarget;
// TODO(b/187528071): Remove these and replace with a real scrim.
private float mColorTint;
private final int mTintingColor;
- @Nullable
private ObjectAnimator mTintingAnimator;
private int mOverScrollShift = 0;
- private long mScrollLastHapticTimestamp;
/**
* TODO: Call reloadIdNeeded in onTaskStackChanged.
@@ -496,7 +434,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
}
// Remove the task immediately from the task list
- TaskView taskView = getTaskViewByTaskId(taskId);
+ TaskView taskView = getTaskView(taskId);
if (taskView != null) {
removeView(taskView);
}
@@ -518,7 +456,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
return;
}
- TaskView taskView = getTaskViewByTaskId(taskId);
+ TaskView taskView = getTaskView(taskId);
if (taskView == null) {
return;
}
@@ -545,26 +483,19 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
private final PinnedStackAnimationListener mIPipAnimationListener =
new PinnedStackAnimationListener();
private int mPipCornerRadius;
- private int mPipShadowRadius;
// Used to keep track of the last requested task list id, so that we do not request to load the
// tasks again if we have already requested it and the task list has not changed
private int mTaskListChangeId = -1;
// Only valid until the launcher state changes to NORMAL
- /**
- * ID for the current running TaskView view, unique amongst TaskView instances. ID's are set
- * through {@link #getTaskViewFromPool(boolean)} and incremented by {@link #mTaskViewIdCount}
- */
- protected int mRunningTaskViewId = -1;
- private int mTaskViewIdCount;
- private final int[] INVALID_TASK_IDS = new int[]{-1, -1};
+ protected int mRunningTaskId = -1;
protected boolean mRunningTaskTileHidden;
- @Nullable
- private Task[] mTmpRunningTasks;
- protected int mFocusedTaskViewId = -1;
+ private Task mTmpRunningTask;
+ protected int mFocusedTaskId = -1;
+ private float mFocusedTaskRatio;
- private boolean mTaskIconScaledDown = false;
+ private boolean mRunningTaskIconScaledDown = false;
private boolean mRunningTaskShowScreenshot = false;
private boolean mOverviewStateEnabled;
@@ -575,9 +506,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
private int mDownX;
private int mDownY;
- @Nullable
private PendingAnimation mPendingAnimation;
- @Nullable
private LayoutTransition mLayoutTransition;
@ViewDebug.ExportedProperty(category = "launcher")
@@ -593,7 +522,6 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
// Keeps track of task id whose visual state should not be reset
private int mIgnoreResetTaskId = -1;
- protected boolean mLoadPlanEverApplied;
// Variables for empty state
private final Drawable mEmptyIcon;
@@ -602,37 +530,21 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
private final Point mLastMeasureSize = new Point();
private final int mEmptyMessagePadding;
private boolean mShowEmptyMessage;
- @Nullable
private OnEmptyMessageUpdatedListener mOnEmptyMessageUpdatedListener;
- @Nullable
private Layout mEmptyTextLayout;
/**
* Placeholder view indicating where the first split screen selected app will be placed
*/
- private SplitSelectStateController mSplitSelectStateController;
+ private SplitPlaceholderView mSplitPlaceholderView;
/**
* The first task that split screen selection was initiated with. When split select state is
* initialized, we create a
- * {@link #createTaskDismissAnimation(TaskView, boolean, boolean, long, boolean)} for this
- * TaskView but don't actually remove the task since the user might back out. As such, we also
- * ensure this View doesn't go back into the {@link #mTaskViewPool},
- * see {@link #onViewRemoved(View)}
+ * {@link #createTaskDismissAnimation(TaskView, boolean, boolean, long)} for this TaskView but
+ * don't actually remove the task since the user might back out. As such, we also ensure this
+ * View doesn't go back into the {@link #mTaskViewPool}, see {@link #onViewRemoved(View)}
*/
- @Nullable
private TaskView mSplitHiddenTaskView;
- @Nullable
- private View mSecondSplitHiddenView;
- @Nullable
- private StagedSplitBounds mSplitBoundsConfig;
- private final Toast mSplitToast = Toast.makeText(getContext(),
- R.string.toast_split_select_app, Toast.LENGTH_SHORT);
- private final Toast mSplitUnsupportedToast = Toast.makeText(getContext(),
- R.string.toast_split_app_unsupported, Toast.LENGTH_SHORT);
-
- @Nullable
- private QuickstepSystemShortcut.SplitSelectSource mSplitSelectSource;
-
/**
* Keeps track of the index of the TaskView that split screen was initialized with so we know
* where to insert it back into list of taskViews in case user backs out of entering split
@@ -641,21 +553,11 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
* this doesn't get adjusted to reflect the new child count after the taskView is dismissed/
* removed from recentsView
*/
- private int mSplitHiddenTaskViewIndex = -1;
- @Nullable
- private FloatingTaskView mFirstFloatingTaskView;
- @Nullable
- private FloatingTaskView mSecondFloatingTaskView;
-
- /**
- * The task to be removed and immediately re-added. Should not be added to task pool.
- */
- @Nullable
- private TaskView mMovingTaskView;
+ private int mSplitHiddenTaskViewIndex;
+ // Keeps track of the index where the first TaskView should be
+ private int mTaskViewStartIndex = 0;
private OverviewActionsView mActionsView;
- private ObjectAnimator mActionsViewAlphaAnimator;
- private float mActionsViewAlphaAnimatorFinalValue;
private MultiWindowModeChangedListener mMultiWindowModeChangedListener =
new MultiWindowModeChangedListener() {
@@ -672,14 +574,12 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
}
};
- @Nullable
private RunnableList mSideTaskLaunchCallback;
- @Nullable
- private TaskLaunchListener mTaskLaunchListener;
- public RecentsView(Context context, @Nullable AttributeSet attrs, int defStyleAttr,
+ public RecentsView(Context context, AttributeSet attrs, int defStyleAttr,
BaseActivityInterface sizeStrategy) {
super(context, attrs, defStyleAttr);
+ setPageSpacing(getResources().getDimensionPixelSize(R.dimen.recents_page_spacing));
setEnableFreeScroll(true);
mSizeStrategy = sizeStrategy;
mActivity = BaseActivity.fromContext(context);
@@ -688,8 +588,6 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
final int rotation = mActivity.getDisplay().getRotation();
mOrientationState.setRecentsRotation(rotation);
- mScrollHapticMinGapMillis = getResources()
- .getInteger(R.integer.recentsScrollHapticMinGapMillis);
mFastFlingVelocity = getResources()
.getDimensionPixelSize(R.dimen.recents_fast_fling_velocity);
mModel = RecentsModel.INSTANCE.get(context);
@@ -700,15 +598,11 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
mClearAllButton.setOnClickListener(this::dismissAllTasks);
mTaskViewPool = new ViewPool<>(context, this, R.layout.task, 20 /* max size */,
10 /* initial size */);
- mGroupedTaskViewPool = new ViewPool<>(context, this,
- R.layout.task_grouped, 20 /* max size */, 10 /* initial size */);
mIsRtl = mOrientationHandler.getRecentsRtlSetting(getResources());
setLayoutDirection(mIsRtl ? View.LAYOUT_DIRECTION_RTL : View.LAYOUT_DIRECTION_LTR);
- mSplitPlaceholderSize = getResources().getDimensionPixelSize(
- R.dimen.split_placeholder_size);
- mSplitPlaceholderInset = getResources().getDimensionPixelSize(
- R.dimen.split_placeholder_inset);
+ mRowSpacing = getResources().getDimensionPixelSize(R.dimen.overview_grid_row_spacing);
+ mGridSideMargin = getResources().getDimensionPixelSize(R.dimen.overview_grid_side_margin);
mSquaredTouchSlop = squaredTouchSlop(context);
mEmptyIcon = context.getDrawable(R.drawable.ic_empty_recents);
@@ -735,6 +629,12 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
// Initialize quickstep specific cache params here, as this is constructed only once
mActivity.getViewCache().setCacheSize(R.layout.digital_wellbeing_toast, 5);
+ mLiveTileTaskViewSimulator = new TaskViewSimulator(getContext(), getSizeStrategy(),
+ true /* isForLiveTile */);
+ mLiveTileTaskViewSimulator.recentsViewScale.value = 1;
+ mLiveTileTaskViewSimulator.setOrientationState(mOrientationState);
+ mLiveTileTaskViewSimulator.setDrawsBelowRecents(true);
+
mTintingColor = getForegroundScrimDimColor(context);
}
@@ -765,7 +665,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
int primarySize = mOrientationHandler.getPrimaryValue(getWidth(), getHeight());
int scroll = OverScroll.dampedScroll(getUndampedOverScrollShift(), primarySize);
- mOrientationHandler.setPrimary(canvas, CANVAS_TRANSLATE, scroll);
+ mOrientationHandler.set(canvas, CANVAS_TRANSLATE, scroll);
if (mOverScrollShift != scroll) {
mOverScrollShift = scroll;
@@ -782,7 +682,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
super.dispatchDraw(canvas);
}
if (ENABLE_QUICKSTEP_LIVE_TILE.get() && mEnableDrawingLiveTile
- && mRemoteTargetHandles != null) {
+ && mLiveTileParams.getTargetSet() != null) {
redrawLiveTile();
}
}
@@ -820,18 +720,13 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
}
@Override
- @Nullable
public Task onTaskThumbnailChanged(int taskId, ThumbnailData thumbnailData) {
if (mHandleTaskStackChanges) {
- TaskView taskView = getTaskViewByTaskId(taskId);
+ TaskView taskView = getTaskView(taskId);
if (taskView != null) {
- for (TaskView.TaskIdAttributeContainer container :
- taskView.getTaskIdAttributeContainers()) {
- if (container == null || taskId != container.getTask().key.id) {
- continue;
- }
- container.getThumbnailView().setThumbnail(container.getTask(), thumbnailData);
- }
+ Task task = taskView.getTask();
+ taskView.getThumbnail().setThumbnail(task, thumbnailData);
+ return task;
}
}
return null;
@@ -840,7 +735,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
@Override
public void onTaskIconChanged(String pkg, UserHandle user) {
for (int i = 0; i < getTaskViewCount(); i++) {
- TaskView tv = requireTaskViewAt(i);
+ TaskView tv = getTaskViewAt(i);
Task task = tv.getTask();
if (task != null && task.key != null && pkg.equals(task.key.getPackageName())
&& task.key.userId == user.getIdentifier()) {
@@ -856,9 +751,8 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
* Update the thumbnail of the task.
* @param refreshNow Refresh immediately if it's true.
*/
- @Nullable
public TaskView updateThumbnail(int taskId, ThumbnailData thumbnailData, boolean refreshNow) {
- TaskView taskView = getTaskViewByTaskId(taskId);
+ TaskView taskView = getTaskView(taskId);
if (taskView != null) {
taskView.getThumbnail().setThumbnail(taskView.getTask(), thumbnailData, refreshNow);
}
@@ -871,26 +765,18 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
updateTaskStackListenerState();
}
- public void init(OverviewActionsView actionsView, SplitSelectStateController splitController) {
+ public void init(OverviewActionsView actionsView, SplitPlaceholderView splitPlaceholderView) {
mActionsView = actionsView;
mActionsView.updateHiddenFlags(HIDDEN_NO_TASKS, getTaskViewCount() == 0);
- mSplitSelectStateController = splitController;
+ mSplitPlaceholderView = splitPlaceholderView;
}
- public SplitSelectStateController getSplitPlaceholder() {
- return mSplitSelectStateController;
+ public SplitPlaceholderView getSplitPlaceholder() {
+ return mSplitPlaceholderView;
}
public boolean isSplitSelectionActive() {
- return mSplitSelectStateController.isSplitSelectActive();
- }
-
- /**
- * See overridden implementations
- * @return {@code true} if child TaskViews can be launched when user taps on them
- */
- protected boolean canLaunchFullscreenTask() {
- return true;
+ return mSplitPlaceholderView.getSplitController().isSplitSelectActive();
}
@Override
@@ -901,8 +787,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
mActivity.addMultiWindowModeChangedListener(mMultiWindowModeChangedListener);
TaskStackChangeListeners.getInstance().registerTaskStackListener(mTaskStackListener);
mSyncTransactionApplier = new SurfaceTransactionApplier(this);
- runActionOnRemoteHandles(remoteTargetHandle -> remoteTargetHandle.getTransformParams()
- .setSyncTransactionApplier(mSyncTransactionApplier));
+ mLiveTileParams.setSyncTransactionApplier(mSyncTransactionApplier);
RecentsModel.INSTANCE.get(getContext()).addThumbnailChangeListener(this);
mIPipAnimationListener.setActivityAndRecentsView(mActivity, this);
SystemUiProxy.INSTANCE.get(getContext()).setPinnedStackAnimationListener(
@@ -920,8 +805,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
mActivity.removeMultiWindowModeChangedListener(mMultiWindowModeChangedListener);
TaskStackChangeListeners.getInstance().unregisterTaskStackListener(mTaskStackListener);
mSyncTransactionApplier = null;
- runActionOnRemoteHandles(remoteTargetHandle -> remoteTargetHandle.getTransformParams()
- .setSyncTransactionApplier(null));
+ mLiveTileParams.setSyncTransactionApplier(null);
executeSideTaskLaunchCallback();
RecentsModel.INSTANCE.get(getContext()).removeThumbnailChangeListener(this);
SystemUiProxy.INSTANCE.get(getContext()).setPinnedStackAnimationListener(null);
@@ -935,24 +819,15 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
public void onViewRemoved(View child) {
super.onViewRemoved(child);
- // Clear the task data for the removed child if it was visible unless:
- // - It's the initial taskview for entering split screen, we only pretend to dismiss the
- // task
- // - It's the focused task to be moved to the front, we immediately re-add the task
- if (child instanceof TaskView && child != mSplitHiddenTaskView
- && child != mMovingTaskView) {
+ // Clear the task data for the removed child if it was visible unless it's the initial
+ // taskview for entering split screen, we only pretend to dismiss the task
+ if (child instanceof TaskView && child != mSplitHiddenTaskView) {
TaskView taskView = (TaskView) child;
- for (int i : taskView.getTaskIds()) {
- mHasVisibleTaskData.delete(i);
- }
- if (child instanceof GroupedTaskView) {
- mGroupedTaskViewPool.recycle((GroupedTaskView) taskView);
- } else {
- mTaskViewPool.recycle(taskView);
- }
- taskView.setTaskViewId(-1);
+ mHasVisibleTaskData.delete(taskView.getTask().key.id);
+ mTaskViewPool.recycle(taskView);
mActionsView.updateHiddenFlags(HIDDEN_NO_TASKS, getTaskViewCount() == 0);
}
+ updateTaskStartIndex(child);
}
@Override
@@ -962,6 +837,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
// RecentsView is set to RTL in the constructor when system is using LTR. Here we set the
// child direction back to match system settings.
child.setLayoutDirection(mIsRtl ? View.LAYOUT_DIRECTION_LTR : View.LAYOUT_DIRECTION_RTL);
+ updateTaskStartIndex(child);
mActionsView.updateHiddenFlags(HIDDEN_NO_TASKS, false);
updateEmptyMessage();
}
@@ -979,21 +855,6 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
mSideTaskLaunchCallback.add(callback::executeAllAndDestroy);
}
- /**
- * This is a one-time callback when touching in live tile mode. It's reset to null right
- * after it's called.
- */
- public void setTaskLaunchListener(TaskLaunchListener taskLaunchListener) {
- mTaskLaunchListener = taskLaunchListener;
- }
-
- public void onTaskLaunchedInLiveTileMode() {
- if (mTaskLaunchListener != null) {
- mTaskLaunchListener.onTaskLaunched();
- mTaskLaunchListener = null;
- }
- }
-
private void executeSideTaskLaunchCallback() {
if (mSideTaskLaunchCallback != null) {
mSideTaskLaunchCallback.executeAllAndDestroy();
@@ -1001,30 +862,20 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
}
}
- /**
- * TODO(b/195675206) Check both taskIDs from runningTaskViewId
- * and launch if either of them is {@param taskId}
- */
public void launchSideTaskInLiveTileModeForRestartedApp(int taskId) {
- int runningTaskViewId = getTaskViewIdFromTaskId(taskId);
- if (mRunningTaskViewId == -1 ||
- mRunningTaskViewId != runningTaskViewId ||
- mRemoteTargetHandles == null) {
- return;
- }
-
- TransformParams params = mRemoteTargetHandles[0].getTransformParams();
- RemoteAnimationTargets targets = params.getTargetSet();
- if (targets != null && targets.findTask(taskId) != null) {
- launchSideTaskInLiveTileMode(taskId, targets.apps, targets.wallpapers,
- targets.nonApps);
+ if (mRunningTaskId != -1 && mRunningTaskId == taskId) {
+ RemoteAnimationTargets targets = getLiveTileParams().getTargetSet();
+ if (targets != null && targets.findTask(taskId) != null) {
+ launchSideTaskInLiveTileMode(taskId, targets.apps, targets.wallpapers,
+ targets.nonApps);
+ }
}
}
public void launchSideTaskInLiveTileMode(int taskId, RemoteAnimationTargetCompat[] apps,
RemoteAnimationTargetCompat[] wallpaper, RemoteAnimationTargetCompat[] nonApps) {
AnimatorSet anim = new AnimatorSet();
- TaskView taskView = getTaskViewByTaskId(taskId);
+ TaskView taskView = getTaskView(taskId);
if (taskView == null || !isTaskViewVisible(taskView)) {
// TODO: Refine this animation.
SurfaceTransactionApplier surfaceApplier =
@@ -1058,6 +909,18 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
anim.start();
}
+ private void updateTaskStartIndex(View affectingView) {
+ if (!(affectingView instanceof TaskView) && !(affectingView instanceof ClearAllButton)) {
+ int childCount = getChildCount();
+
+ mTaskViewStartIndex = 0;
+ while (mTaskViewStartIndex < childCount
+ && !(getChildAt(mTaskViewStartIndex) instanceof TaskView)) {
+ mTaskViewStartIndex++;
+ }
+ }
+ }
+
public boolean isTaskViewVisible(TaskView tv) {
if (showAsGrid()) {
int screenStart = mOrientationHandler.getPrimaryScroll(this);
@@ -1069,58 +932,6 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
}
}
- public boolean isTaskViewFullyVisible(TaskView tv) {
- if (showAsGrid()) {
- int screenStart = mOrientationHandler.getPrimaryScroll(this);
- int screenEnd = screenStart + mOrientationHandler.getMeasuredSize(this);
- return isTaskViewFullyWithinBounds(tv, screenStart, screenEnd);
- } else {
- // For now, just check if it's the active task
- return indexOfChild(tv) == getNextPage();
- }
- }
-
- @Nullable
- private TaskView getLastGridTaskView() {
- return getLastGridTaskView(getTopRowIdArray(), getBottomRowIdArray());
- }
-
- @Nullable
- private TaskView getLastGridTaskView(IntArray topRowIdArray, IntArray bottomRowIdArray) {
- if (topRowIdArray.isEmpty() && bottomRowIdArray.isEmpty()) {
- return null;
- }
- int lastTaskViewId = topRowIdArray.size() >= bottomRowIdArray.size() ? topRowIdArray.get(
- topRowIdArray.size() - 1) : bottomRowIdArray.get(bottomRowIdArray.size() - 1);
- return getTaskViewFromTaskViewId(lastTaskViewId);
- }
-
- private int getSnapToLastTaskScrollDiff() {
- // Snap to a position where ClearAll is just invisible.
- int screenStart = mOrientationHandler.getPrimaryScroll(this);
- int clearAllScroll = getScrollForPage(indexOfChild(mClearAllButton));
- int clearAllWidth = mOrientationHandler.getPrimarySize(mClearAllButton);
- int lastTaskScroll = getLastTaskScroll(clearAllScroll, clearAllWidth);
- return screenStart - lastTaskScroll;
- }
-
- private int getLastTaskScroll(int clearAllScroll, int clearAllWidth) {
- int distance = clearAllWidth + getClearAllExtraPageSpacing();
- return clearAllScroll + (mIsRtl ? distance : -distance);
- }
-
- private int getSnapToFocusedTaskScrollDiff(boolean isClearAllHidden) {
- int screenStart = mOrientationHandler.getPrimaryScroll(this);
- int targetScroll = getScrollForPage(indexOfChild(getFocusedTaskView()));
- if (!isClearAllHidden) {
- int clearAllWidth = mOrientationHandler.getPrimarySize(mClearAllButton);
- int taskGridHorizontalDiff = mLastComputedTaskSize.right - mLastComputedGridSize.right;
- int clearAllFocusScrollDiff = taskGridHorizontalDiff - clearAllWidth;
- targetScroll += mIsRtl ? clearAllFocusScrollDiff : -clearAllFocusScrollDiff;
- }
- return screenStart - targetScroll;
- }
-
private boolean isTaskViewWithinBounds(TaskView tv, int start, int end) {
int taskStart = mOrientationHandler.getChildStart(tv) + (int) tv.getOffsetAdjustment(
showAsFullscreen(), showAsGrid());
@@ -1131,42 +942,10 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
&& taskEnd <= end);
}
- private boolean isTaskViewFullyWithinBounds(TaskView tv, int start, int end) {
- int taskStart = mOrientationHandler.getChildStart(tv) + (int) tv.getOffsetAdjustment(
- showAsFullscreen(), showAsGrid());
- int taskSize = (int) (mOrientationHandler.getMeasuredSize(tv) * tv.getSizeAdjustment(
- showAsFullscreen()));
- int taskEnd = taskStart + taskSize;
- return taskStart >= start && taskEnd <= end;
- }
-
- /**
- * Returns true if the task is in expected scroll position.
- *
- * @param taskIndex the index of the task
- */
- public boolean isTaskInExpectedScrollPosition(int taskIndex) {
- return getScrollForPage(taskIndex) == getPagedOrientationHandler().getPrimaryScroll(this);
- }
-
- private boolean isFocusedTaskInExpectedScrollPosition() {
- TaskView focusedTask = getFocusedTaskView();
- return focusedTask != null && isTaskInExpectedScrollPosition(indexOfChild(focusedTask));
- }
-
- /**
- * Returns a {@link TaskView} that has taskId matching {@code taskId} or null if no match.
- */
- @Nullable
- public TaskView getTaskViewByTaskId(int taskId) {
- if (taskId == -1) {
- return null;
- }
-
+ public TaskView getTaskView(int taskId) {
for (int i = 0; i < getTaskViewCount(); i++) {
- TaskView taskView = requireTaskViewAt(i);
- int[] taskIds = taskView.getTaskIds();
- if (taskIds[0] == taskId || taskIds[1] == taskId) {
+ TaskView taskView = getTaskViewAt(i);
+ if (taskView.hasTaskId(taskId)) {
return taskView;
}
}
@@ -1180,8 +959,10 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
if (!enabled) {
// Reset the running task when leaving overview since it can still have a reference to
// its thumbnail
- mTmpRunningTasks = null;
- mSplitBoundsConfig = null;
+ mTmpRunningTask = null;
+ if (mSplitPlaceholderView.getSplitController().isSplitSelectActive()) {
+ cancelSplitSelect(false);
+ }
}
updateLocusId();
}
@@ -1200,15 +981,13 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
@Override
protected void onPageBeginTransition() {
super.onPageBeginTransition();
- if (!mActivity.getDeviceProfile().isTablet) {
- mActionsView.updateDisabledFlags(OverviewActionsView.DISABLED_SCROLLING, true);
- }
+ mActionsView.updateDisabledFlags(OverviewActionsView.DISABLED_SCROLLING, true);
}
@Override
protected void onPageEndTransition() {
super.onPageEndTransition();
- if (isClearAllHidden() && !mActivity.getDeviceProfile().isTablet) {
+ if (isClearAllHidden()) {
mActionsView.updateDisabledFlags(OverviewActionsView.DISABLED_SCROLLING, false);
}
if (getNextPage() > 0) {
@@ -1217,24 +996,13 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
}
@Override
- protected boolean isSignificantMove(float absoluteDelta, int pageOrientedSize) {
- DeviceProfile deviceProfile = mActivity.getDeviceProfile();
- if (!deviceProfile.isTablet) {
- return super.isSignificantMove(absoluteDelta, pageOrientedSize);
- }
-
- return absoluteDelta
- > deviceProfile.availableWidthPx * SIGNIFICANT_MOVE_SCREEN_WIDTH_PERCENTAGE;
- }
-
- @Override
public boolean onTouchEvent(MotionEvent ev) {
super.onTouchEvent(ev);
if (showAsGrid()) {
int taskCount = getTaskViewCount();
for (int i = 0; i < taskCount; i++) {
- TaskView taskView = requireTaskViewAt(i);
+ TaskView taskView = getTaskViewAt(i);
if (isTaskViewVisible(taskView) && taskView.offerTouchToChildren(ev)) {
// Keep consuming events to pass to delegate
return true;
@@ -1297,7 +1065,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
@Override
protected void onNotSnappingToPageInFreeScroll() {
int finalPos = mScroller.getFinalX();
- if (finalPos > mMinScroll && finalPos < mMaxScroll) {
+ if (!showAsGrid() && finalPos > mMinScroll && finalPos < mMaxScroll) {
int firstPageScroll = getScrollForPage(!mIsRtl ? 0 : getPageCount() - 1);
int lastPageScroll = getScrollForPage(!mIsRtl ? getPageCount() - 1 : 0);
@@ -1311,20 +1079,6 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
? mMaxScroll
: getScrollForPage(mNextPage);
- if (showAsGrid()) {
- if (isSplitSelectionActive()) {
- return;
- }
- TaskView taskView = getTaskViewAt(mNextPage);
- // Snap to fully visible focused task and clear all button.
- boolean shouldSnapToFocusedTask = taskView != null && taskView.isFocusedTask()
- && isTaskViewFullyVisible(taskView);
- boolean shouldSnapToClearAll = mNextPage == indexOfChild(mClearAllButton);
- if (!shouldSnapToFocusedTask && !shouldSnapToClearAll) {
- return;
- }
- }
-
mScroller.setFinalX(pageSnapped);
// Ensure the scroll/snap doesn't happen too fast;
int extraScrollDuration = OVERSCROLL_PAGE_SNAP_ANIMATION_DURATION
@@ -1336,25 +1090,6 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
}
@Override
- protected void onEdgeAbsorbingScroll() {
- vibrateForScroll();
- }
-
- @Override
- protected void onScrollOverPageChanged() {
- vibrateForScroll();
- }
-
- private void vibrateForScroll() {
- long now = SystemClock.uptimeMillis();
- if (now - mScrollLastHapticTimestamp > mScrollHapticMinGapMillis) {
- mScrollLastHapticTimestamp = now;
- VibratorWrapper.INSTANCE.get(mContext).vibrate(SCROLL_VIBRATION_PRIMITIVE,
- SCROLL_VIBRATION_PRIMITIVE_SCALE, SCROLL_VIBRATION_FALLBACK);
- }
- }
-
- @Override
protected void determineScrollingStart(MotionEvent ev, float touchSlopScale) {
// Enables swiping to the left or right only if the task overlay is not modal.
if (!isModal()) {
@@ -1362,60 +1097,20 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
}
}
- /**
- * Moves the focused task to the front of the carousel in tablets, to minimize animation
- * required to focus the task in grid.
- */
- public void moveFocusedTaskToFront() {
- if (!mActivity.getDeviceProfile().isTablet) {
- return;
- }
-
- TaskView focusedTaskView = getFocusedTaskView();
- if (focusedTaskView == null) {
- return;
- }
-
- if (indexOfChild(focusedTaskView) != mCurrentPage) {
- return;
- }
-
- if (mCurrentPage == 0) {
- return;
- }
-
- int primaryScroll = mOrientationHandler.getPrimaryScroll(this);
- int currentPageScroll = getScrollForPage(mCurrentPage);
- mCurrentPageScrollDiff = primaryScroll - currentPageScroll;
-
- mMovingTaskView = focusedTaskView;
- removeView(focusedTaskView);
- mMovingTaskView = null;
- focusedTaskView.resetPersistentViewTransforms();
- addView(focusedTaskView, 0);
- setCurrentPage(0);
-
- updateGridProperties();
- }
-
- protected void applyLoadPlan(ArrayList<GroupTask> taskGroups) {
+ protected void applyLoadPlan(ArrayList<Task> tasks) {
if (mPendingAnimation != null) {
- mPendingAnimation.addEndListener(success -> applyLoadPlan(taskGroups));
+ mPendingAnimation.addEndListener(success -> applyLoadPlan(tasks));
return;
}
- mLoadPlanEverApplied = true;
- if (taskGroups == null || taskGroups.isEmpty()) {
+ if (tasks == null || tasks.isEmpty()) {
removeTasksViewsAndClearAllButton();
onTaskStackUpdated();
- // With all tasks removed, touch handling in PagedView is disabled and we need to reset
- // touch state or otherwise values will be obsolete.
- resetTouchState();
return;
}
int currentTaskId = -1;
- TaskView currentTaskView = getTaskViewAt(mCurrentPage);
+ TaskView currentTaskView = getTaskViewAtByAbsoluteIndex(mCurrentPage);
if (currentTaskView != null) {
currentTaskId = currentTaskView.getTask().key.id;
}
@@ -1424,81 +1119,44 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
unloadVisibleTaskData(TaskView.FLAG_UPDATE_ALL);
TaskView ignoreResetTaskView =
- mIgnoreResetTaskId == -1 ? null : getTaskViewByTaskId(mIgnoreResetTaskId);
-
- // Save running task ID if it exists before rebinding all taskViews, otherwise the task from
- // the runningTaskView currently bound could get assigned to another TaskView
- int runningTaskId = getTaskIdsForTaskViewId(mRunningTaskViewId)[0];
- int focusedTaskId = getTaskIdsForTaskViewId(mFocusedTaskViewId)[0];
-
- // Removing views sets the currentPage to 0, so we save this and restore it after
- // the new set of views are added
- int previousCurrentPage = mCurrentPage;
- removeAllViews();
-
- // Add views as children based on whether it's grouped or single task
- for (int i = taskGroups.size() - 1; i >= 0; i--) {
- GroupTask groupTask = taskGroups.get(i);
- boolean hasMultipleTasks = groupTask.hasMultipleTasks();
- TaskView taskView = getTaskViewFromPool(hasMultipleTasks);
- addView(taskView);
-
- if (hasMultipleTasks) {
- boolean firstTaskIsLeftTopTask =
- groupTask.mStagedSplitBounds.leftTopTaskId == groupTask.task1.key.id;
- Task leftTopTask = firstTaskIsLeftTopTask ? groupTask.task1 : groupTask.task2;
- Task rightBottomTask = firstTaskIsLeftTopTask ? groupTask.task2 : groupTask.task1;
- ((GroupedTaskView) taskView).bind(leftTopTask, rightBottomTask, mOrientationState,
- groupTask.mStagedSplitBounds);
- } else {
- taskView.bind(groupTask.task1, mOrientationState);
- }
- }
- if (!taskGroups.isEmpty()) {
- addView(mClearAllButton);
- }
+ mIgnoreResetTaskId == -1 ? null : getTaskView(mIgnoreResetTaskId);
- boolean settlingOnNewTask = mNextPage != INVALID_PAGE;
- if (settlingOnNewTask) {
- // Restore mCurrentPage but don't call setCurrentPage() as that clobbers the scroll.
- mCurrentPage = previousCurrentPage;
- } else {
- setCurrentPage(previousCurrentPage);
+ final int requiredTaskCount = tasks.size();
+ if (getTaskViewCount() != requiredTaskCount) {
+ if (indexOfChild(mClearAllButton) != -1) {
+ removeView(mClearAllButton);
+ }
+ for (int i = getTaskViewCount(); i < requiredTaskCount; i++) {
+ addView(mTaskViewPool.getView());
+ }
+ while (getTaskViewCount() > requiredTaskCount) {
+ removeView(getChildAt(getChildCount() - 1));
+ }
+ if (requiredTaskCount > 0) {
+ addView(mClearAllButton);
+ }
}
- // Keep same previous focused task
- TaskView newFocusedTaskView = getTaskViewByTaskId(focusedTaskId);
- // If the list changed, maybe the focused task doesn't exist anymore
- if (newFocusedTaskView == null && getTaskViewCount() > 0) {
- newFocusedTaskView = getTaskViewAt(0);
+ // Rebind and reset all task views
+ for (int i = requiredTaskCount - 1; i >= 0; i--) {
+ final int pageIndex = requiredTaskCount - i - 1 + mTaskViewStartIndex;
+ final Task task = tasks.get(i);
+ final TaskView taskView = (TaskView) getChildAt(pageIndex);
+ taskView.bind(task, mOrientationState);
}
- mFocusedTaskViewId = newFocusedTaskView != null ?
- newFocusedTaskView.getTaskViewId() : -1;
updateTaskSize();
- updateChildTaskOrientations();
-
- TaskView newRunningTaskView = null;
- if (runningTaskId != -1) {
- // Update mRunningTaskViewId to be the new TaskView that was assigned by binding
- // the full list of tasks to taskViews
- newRunningTaskView = getTaskViewByTaskId(runningTaskId);
- if (newRunningTaskView != null) {
- mRunningTaskViewId = newRunningTaskView.getTaskViewId();
- } else {
- mRunningTaskViewId = -1;
- }
- }
int targetPage = -1;
- if (!settlingOnNewTask) {
+ if (mNextPage == INVALID_PAGE) {
// Set the current page to the running task, but not if settling on new task.
- if (runningTaskId != -1) {
- targetPage = indexOfChild(newRunningTaskView);
+ TaskView runningTaskView = getRunningTaskView();
+ if (runningTaskView != null) {
+ targetPage = indexOfChild(runningTaskView);
} else if (getTaskViewCount() > 0) {
- targetPage = indexOfChild(requireTaskViewAt(0));
+ targetPage = indexOfChild(getTaskViewAt(0));
}
} else if (currentTaskId != -1) {
- currentTaskView = getTaskViewByTaskId(currentTaskId);
+ currentTaskView = getTaskView(currentTaskId);
if (currentTaskView != null) {
targetPage = indexOfChild(currentTaskView);
}
@@ -1507,8 +1165,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
setCurrentPage(targetPage);
}
- if (mIgnoreResetTaskId != -1 &&
- getTaskViewByTaskId(mIgnoreResetTaskId) != ignoreResetTaskView) {
+ if (mIgnoreResetTaskId != -1 && getTaskView(mIgnoreResetTaskId) != ignoreResetTaskView) {
// If the taskView mapping is changing, do not preserve the visuals. Since we are
// mostly preserving the first task, and new taskViews are added to the end, it should
// generally map to the same task.
@@ -1529,7 +1186,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
private void removeTasksViewsAndClearAllButton() {
for (int i = getTaskViewCount() - 1; i >= 0; i--) {
- removeView(requireTaskViewAt(i));
+ removeView(getTaskViewAt(i));
}
if (indexOfChild(mClearAllButton) != -1) {
removeView(mClearAllButton);
@@ -1537,37 +1194,13 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
}
public int getTaskViewCount() {
- int taskViewCount = getChildCount();
+ int taskViewCount = getChildCount() - mTaskViewStartIndex;
if (indexOfChild(mClearAllButton) != -1) {
taskViewCount--;
}
return taskViewCount;
}
- public int getGroupedTaskViewCount() {
- int groupViewCount = 0;
- for (int i = 0; i < getChildCount(); i++) {
- if (getChildAt(i) instanceof GroupedTaskView) {
- groupViewCount++;
- }
- }
- return groupViewCount;
- }
-
- /**
- * Returns the number of tasks in the top row of the overview grid.
- */
- public int getTopRowTaskCountForTablet() {
- return mTopRowIdSet.size();
- }
-
- /**
- * Returns the number of tasks in the bottom row of the overview grid.
- */
- public int getBottomRowTaskCountForTablet() {
- return getTaskViewCount() - mTopRowIdSet.size() - 1;
- }
-
protected void onTaskStackUpdated() {
// Lazily update the empty message only when the task stack is reapplied
updateEmptyMessage();
@@ -1575,26 +1208,23 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
public void resetTaskVisuals() {
for (int i = getTaskViewCount() - 1; i >= 0; i--) {
- TaskView taskView = requireTaskViewAt(i);
- if (mIgnoreResetTaskId != taskView.getTaskIds()[0]) {
+ TaskView taskView = getTaskViewAt(i);
+ if (mIgnoreResetTaskId != taskView.getTask().key.id) {
taskView.resetViewTransforms();
- taskView.setIconScaleAndDim(mTaskIconScaledDown ? 0 : 1);
taskView.setStableAlpha(mContentAlpha);
taskView.setFullscreenProgress(mFullscreenProgress);
taskView.setModalness(mTaskModalness);
}
}
if (ENABLE_QUICKSTEP_LIVE_TILE.get()) {
- // resetTaskVisuals is called at the end of dismiss animation which could update
- // primary and secondary translation of the live tile cut out. We will need to do so
- // here accordingly.
- runActionOnRemoteHandles(remoteTargetHandle -> {
- TaskViewSimulator simulator = remoteTargetHandle.getTaskViewSimulator();
- simulator.taskPrimaryTranslation.value = 0;
- simulator.taskSecondaryTranslation.value = 0;
- simulator.fullScreenProgress.value = 0;
- simulator.recentsViewScale.value = 1;
- });
+ // Since we reuse the same mLiveTileTaskViewSimulator in the RecentsView, we need
+ // to reset the params after it settles in Overview from swipe up so that we don't
+ // render with obsolete param values.
+ mLiveTileTaskViewSimulator.taskPrimaryTranslation.value = 0;
+ mLiveTileTaskViewSimulator.taskSecondaryTranslation.value = 0;
+ mLiveTileTaskViewSimulator.fullScreenProgress.value = 0;
+ mLiveTileTaskViewSimulator.recentsViewScale.value = 1;
+
// Similar to setRunningTaskHidden below, reapply the state before runningTaskView is
// null.
if (!mRunningTaskShowScreenshot) {
@@ -1605,6 +1235,11 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
setRunningTaskHidden(mRunningTaskTileHidden);
}
+ // Force apply the scale.
+ if (mIgnoreResetTaskId != mRunningTaskId) {
+ applyRunningTaskIconScale();
+ }
+
updateCurveProperties();
// Update the set of visible task's data
loadVisibleTaskData(TaskView.FLAG_UPDATE_ALL);
@@ -1616,7 +1251,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
mFullscreenProgress = fullscreenProgress;
int taskCount = getTaskViewCount();
for (int i = 0; i < taskCount; i++) {
- requireTaskViewAt(i).setFullscreenProgress(mFullscreenProgress);
+ getTaskViewAt(i).setFullscreenProgress(mFullscreenProgress);
}
mClearAllButton.setFullscreenProgress(fullscreenProgress);
@@ -1644,16 +1279,14 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
DeviceProfile dp = mActivity.getDeviceProfile();
setOverviewGridEnabled(
mActivity.getStateManager().getState().displayOverviewTasksAsGrid(dp));
- setPageSpacing(dp.overviewPageSpacing);
// Propagate DeviceProfile change event.
- runActionOnRemoteHandles(
- remoteTargetHandle -> remoteTargetHandle.getTaskViewSimulator().setDp(dp));
+ mLiveTileTaskViewSimulator.setDp(dp);
+ mActionsView.setDp(dp);
mOrientationState.setDeviceProfile(dp);
- // Update RecentsView and TaskView's DeviceProfile dependent layout.
+ // Update RecentsView adn TaskView's DeviceProfile dependent layout.
updateOrientationHandler();
- mActionsView.updateDimension(dp, mLastComputedTaskSize);
}
private void updateOrientationHandler() {
@@ -1678,13 +1311,12 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|| !mOrientationHandler.equals(oldOrientationHandler)) {
// Changed orientations, update controllers so they intercept accordingly.
mActivity.getDragLayer().recreateControllers();
- onOrientationChanged();
}
boolean isInLandscape = mOrientationState.getTouchRotation() != ROTATION_0
|| mOrientationState.getRecentsActivityRotation() != ROTATION_0;
mActionsView.updateHiddenFlags(HIDDEN_NON_ZERO_ROTATION,
- !mOrientationState.isRecentsActivityRotationAllowed() && isInLandscape);
+ !mOrientationState.canRecentsActivityRotate() && isInLandscape);
// Update TaskView's DeviceProfile dependent layout.
updateChildTaskOrientations();
@@ -1697,15 +1329,6 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
setCurrentPage(mCurrentPage);
}
- private void onOrientationChanged() {
- // If overview is in modal state when rotate, reset it to overview state without running
- // animation.
- setModalStateEnabled(false);
- if (isSplitSelectionActive()) {
- onRotateInSplitSelectionState();
- }
- }
-
// Update task size and padding that are dependent on DeviceProfile and insets.
private void updateSizeAndPadding() {
DeviceProfile dp = mActivity.getDeviceProfile();
@@ -1718,33 +1341,41 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
dp.widthPx - mInsets.right - mTempRect.right,
dp.heightPx - mInsets.bottom - mTempRect.bottom);
- mSizeStrategy.calculateGridSize(mActivity.getDeviceProfile(),
+ mSizeStrategy.calculateGridSize(mActivity, mActivity.getDeviceProfile(),
mLastComputedGridSize);
mSizeStrategy.calculateGridTaskSize(mActivity, mActivity.getDeviceProfile(),
mLastComputedGridTaskSize, mOrientationHandler);
- mTaskGridVerticalDiff = mLastComputedGridTaskSize.top - mLastComputedTaskSize.top;
- mTopBottomRowHeightDiff =
- mLastComputedGridTaskSize.height() + dp.overviewTaskThumbnailTopMarginPx
- + dp.overviewRowSpacing;
-
// Force TaskView to update size from thumbnail
updateTaskSize();
- }
- /**
- * Updates TaskView scaling and translation required to support variable width.
- */
- private void updateTaskSize() {
- updateTaskSize(false);
+ // Update ActionsView position
+ if (mActionsView != null) {
+ FrameLayout.LayoutParams layoutParams =
+ (FrameLayout.LayoutParams) mActionsView.getLayoutParams();
+ if (dp.isTablet && FeatureFlags.ENABLE_OVERVIEW_GRID.get()) {
+ layoutParams.gravity = Gravity.BOTTOM;
+ layoutParams.bottomMargin =
+ dp.heightPx - mInsets.bottom - mLastComputedGridSize.bottom;
+ layoutParams.leftMargin = mLastComputedTaskSize.left;
+ layoutParams.rightMargin = dp.widthPx - mLastComputedTaskSize.right;
+ // When in modal state, remove bottom margin to avoid covering content.
+ mActionsView.setModalTransformY(layoutParams.bottomMargin);
+ } else {
+ layoutParams.gravity = Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
+ layoutParams.bottomMargin = 0;
+ layoutParams.leftMargin = 0;
+ layoutParams.rightMargin = 0;
+ mActionsView.setModalTransformY(0);
+ }
+ mActionsView.setLayoutParams(layoutParams);
+ }
}
/**
* Updates TaskView scaling and translation required to support variable width.
- *
- * @param isTaskDismissal indicates if update was called due to task dismissal
*/
- private void updateTaskSize(boolean isTaskDismissal) {
+ private void updateTaskSize() {
final int taskCount = getTaskViewCount();
if (taskCount == 0) {
return;
@@ -1752,23 +1383,25 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
float accumulatedTranslationX = 0;
for (int i = 0; i < taskCount; i++) {
- TaskView taskView = requireTaskViewAt(i);
+ TaskView taskView = getTaskViewAt(i);
taskView.updateTaskSize();
- taskView.getPrimaryNonGridTranslationProperty().set(taskView, accumulatedTranslationX);
- taskView.getSecondaryNonGridTranslationProperty().set(taskView, 0f);
+ taskView.getPrimaryFullscreenTranslationProperty().set(taskView,
+ accumulatedTranslationX);
+ taskView.getSecondaryFullscreenTranslationProperty().set(taskView, 0f);
// Compensate space caused by TaskView scaling.
float widthDiff =
- taskView.getLayoutParams().width * (1 - taskView.getNonGridScale());
+ taskView.getLayoutParams().width * (1 - taskView.getFullscreenScale());
accumulatedTranslationX += mIsRtl ? widthDiff : -widthDiff;
}
mClearAllButton.setFullscreenTranslationPrimary(accumulatedTranslationX);
- updateGridProperties(isTaskDismissal);
+ updateGridProperties();
}
public void getTaskSize(Rect outRect) {
- mSizeStrategy.calculateTaskSize(mActivity, mActivity.getDeviceProfile(), outRect);
+ mSizeStrategy.calculateTaskSize(mActivity, mActivity.getDeviceProfile(), outRect,
+ mOrientationHandler);
mLastComputedTaskSize.set(outRect);
}
@@ -1776,9 +1409,21 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
* Returns the size of task selected to enter modal state.
*/
public Point getSelectedTaskSize() {
- mSizeStrategy.calculateTaskSize(mActivity, mActivity.getDeviceProfile(),
- mTempRect);
- return new Point(mTempRect.width(), mTempRect.height());
+ mSizeStrategy.calculateTaskSize(mActivity, mActivity.getDeviceProfile(), mTempRect,
+ mOrientationHandler);
+ int taskWidth = mTempRect.width();
+ int taskHeight = mTempRect.height();
+ if (mFocusedTaskId != -1) {
+ int boxLength = Math.max(taskWidth, taskHeight);
+ if (mFocusedTaskRatio > 1) {
+ taskWidth = boxLength;
+ taskHeight = (int) (boxLength / mFocusedTaskRatio);
+ } else {
+ taskWidth = (int) (boxLength * mFocusedTaskRatio);
+ taskHeight = boxLength;
+ }
+ }
+ return new Point(taskWidth, taskHeight);
}
/** Gets the last computed task size */
@@ -1808,37 +1453,22 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
// After scrolling, update the visible task's data
loadVisibleTaskData(TaskView.FLAG_UPDATE_ALL);
- }
- // Update ActionsView's visibility when scroll changes.
- updateActionsViewFocusedScroll();
+ // After scrolling, update ActionsView's visibility.
+ TaskView focusedTaskView = getFocusedTaskView();
+ if (focusedTaskView != null) {
+ float scrollDiff = Math.abs(getScrollForPage(indexOfChild(focusedTaskView))
+ - mOrientationHandler.getPrimaryScroll(this));
+ float delta = (mGridSideMargin - scrollDiff) / (float) mGridSideMargin;
+ mActionsView.getScrollAlpha().setValue(Utilities.boundToRange(delta, 0, 1));
+ }
+ }
// Update the high res thumbnail loader state
mModel.getThumbnailCache().getHighResLoadingState().setFlingingFast(isFlingingFast);
return scrolling;
}
- private void updateActionsViewFocusedScroll() {
- if (showAsGrid()) {
- float actionsViewAlphaValue = isFocusedTaskInExpectedScrollPosition() ? 1 : 0;
- // If animation is already in progress towards the same end value, do not restart.
- if (mActionsViewAlphaAnimator == null || !mActionsViewAlphaAnimator.isStarted()
- || (mActionsViewAlphaAnimator.isStarted()
- && mActionsViewAlphaAnimatorFinalValue != actionsViewAlphaValue)) {
- animateActionsViewAlpha(actionsViewAlphaValue,
- DEFAULT_ACTIONS_VIEW_ALPHA_ANIMATION_DURATION);
- }
- }
- }
-
- private void animateActionsViewAlpha(float alphaValue, long duration) {
- mActionsViewAlphaAnimator = ObjectAnimator.ofFloat(
- mActionsView.getVisibilityAlpha(), MultiValueAlpha.VALUE, alphaValue);
- mActionsViewAlphaAnimatorFinalValue = alphaValue;
- mActionsViewAlphaAnimator.setDuration(duration);
- mActionsViewAlphaAnimator.start();
- }
-
/**
* Scales and adjusts translation of adjacent pages as if on a curved carousel.
*/
@@ -1852,21 +1482,20 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
@Override
protected int getDestinationPage(int scaledScroll) {
- if (!mActivity.getDeviceProfile().isTablet) {
+ if (!(mActivity.getDeviceProfile().isTablet && FeatureFlags.ENABLE_OVERVIEW_GRID.get())) {
return super.getDestinationPage(scaledScroll);
}
- if (!pageScrollsInitialized()) {
- Log.e(TAG,
- "Cannot get destination page: RecentsView not properly initialized",
- new IllegalStateException());
- return INVALID_PAGE;
+
+ final int childCount = getChildCount();
+ if (mPageScrolls == null || childCount != mPageScrolls.length) {
+ return -1;
}
// When in tablet with variable task width, return the page which scroll is closest to
// screenStart instead of page nearest to center of screen.
int minDistanceFromScreenStart = Integer.MAX_VALUE;
- int minDistanceFromScreenStartIndex = INVALID_PAGE;
- for (int i = 0; i < getChildCount(); ++i) {
+ int minDistanceFromScreenStartIndex = -1;
+ for (int i = 0; i < childCount; ++i) {
int distanceFromScreenStart = Math.abs(mPageScrolls[i] - scaledScroll);
if (distanceFromScreenStart < minDistanceFromScreenStart) {
minDistanceFromScreenStart = distanceFromScreenStart;
@@ -1881,8 +1510,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
* and unloads the associated task data for tasks that are no longer visible.
*/
public void loadVisibleTaskData(@TaskView.TaskDataChanges int dataChanges) {
- boolean hasLeftOverview = !mOverviewStateEnabled && mScroller.isFinished();
- if (hasLeftOverview || mTaskListChangeId == -1) {
+ if (!mOverviewStateEnabled || mTaskListChangeId == -1) {
// Skip loading visible task data if we've already left the overview state, or if the
// task list hasn't been loaded yet (the task views will not reflect the task list)
return;
@@ -1908,7 +1536,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
// Update the task data for the in/visible children
for (int i = 0; i < getTaskViewCount(); i++) {
- TaskView taskView = requireTaskViewAt(i);
+ TaskView taskView = getTaskViewAt(i);
Task task = taskView.getTask();
int index = indexOfChild(taskView);
boolean visible;
@@ -1918,17 +1546,8 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
visible = lower <= index && index <= upper;
}
if (visible) {
- boolean skipLoadingTask = false;
- if (mTmpRunningTasks != null) {
- for (Task t : mTmpRunningTasks) {
- if (task == t) {
- // Skip loading if this is the task that we are animating into
- skipLoadingTask = true;
- break;
- }
- }
- }
- if (skipLoadingTask) {
+ if (task == mTmpRunningTask) {
+ // Skip loading if this is the task that we are animating into
continue;
}
if (!mHasVisibleTaskData.get(task.key.id)) {
@@ -1956,7 +1575,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
private void unloadVisibleTaskData(@TaskView.TaskDataChanges int dataChanges) {
for (int i = 0; i < mHasVisibleTaskData.size(); i++) {
if (mHasVisibleTaskData.valueAt(i)) {
- TaskView taskView = getTaskViewByTaskId(mHasVisibleTaskData.keyAt(i));
+ TaskView taskView = getTaskView(mHasVisibleTaskData.keyAt(i));
if (taskView != null) {
taskView.onTaskListVisibilityChanged(false /* visible */, dataChanges);
}
@@ -1971,7 +1590,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
// they want to updated their thumbnail state
for (int i = 0; i < mHasVisibleTaskData.size(); i++) {
if (mHasVisibleTaskData.valueAt(i)) {
- TaskView taskView = getTaskViewByTaskId(mHasVisibleTaskData.keyAt(i));
+ TaskView taskView = getTaskView(mHasVisibleTaskData.keyAt(i));
if (taskView != null) {
// Poke the view again, which will trigger it to load high res if the state
// is enabled
@@ -1983,12 +1602,16 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
public abstract void startHome();
+ /** `true` if there is a +1 space available in overview. */
+ public boolean hasRecentsExtraCard() {
+ return false;
+ }
+
public void reset() {
setCurrentTask(-1);
- mCurrentPageScrollDiff = 0;
mIgnoreResetTaskId = -1;
mTaskListChangeId = -1;
- mFocusedTaskViewId = -1;
+ mFocusedTaskId = -1;
if (mRecentsAnimationController != null) {
if (ENABLE_QUICKSTEP_LIVE_TILE.get() && mEnableDrawingLiveTile) {
@@ -1999,12 +1622,8 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
}
}
setEnableDrawingLiveTile(false);
- runActionOnRemoteHandles(remoteTargetHandle -> {
- remoteTargetHandle.getTransformParams().setTargetSet(null);
- remoteTargetHandle.getTaskViewSimulator().setDrawsBelowRecents(false);
- });
- resetFromSplitSelectionState();
- mSplitSelectStateController.resetState();
+ mLiveTileParams.setTargetSet(null);
+ mLiveTileTaskViewSimulator.setDrawsBelowRecents(true);
// These are relatively expensive and don't need to be done this frame (RecentsView isn't
// visible anyway), so defer by a frame to get off the critical path, e.g. app to home.
@@ -2018,72 +1637,27 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
});
}
- public int getRunningTaskViewId() {
- return mRunningTaskViewId;
- }
-
- protected int[] getTaskIdsForRunningTaskView() {
- return getTaskIdsForTaskViewId(mRunningTaskViewId);
- }
-
- private int[] getTaskIdsForTaskViewId(int taskViewId) {
- // For now 2 distinct task IDs is max for split screen
- TaskView runningTaskView = getTaskViewFromTaskViewId(taskViewId);
- if (runningTaskView == null) {
- return INVALID_TASK_IDS;
- }
-
- return runningTaskView.getTaskIds();
+ public int getRunningTaskId() {
+ return mRunningTaskId;
}
public @Nullable TaskView getRunningTaskView() {
- return getTaskViewFromTaskViewId(mRunningTaskViewId);
- }
-
- public @Nullable TaskView getFocusedTaskView() {
- return getTaskViewFromTaskViewId(mFocusedTaskViewId);
- }
-
- @Nullable
- private TaskView getTaskViewFromTaskViewId(int taskViewId) {
- if (taskViewId == -1) {
- return null;
- }
-
- for (int i = 0; i < getTaskViewCount(); i++) {
- TaskView taskView = requireTaskViewAt(i);
- if (taskView.getTaskViewId() == taskViewId) {
- return taskView;
- }
- }
- return null;
+ return getTaskView(mRunningTaskId);
}
public int getRunningTaskIndex() {
- TaskView taskView = getRunningTaskView();
- return taskView == null ? -1 : indexOfChild(taskView);
+ return getTaskIndexForId(mRunningTaskId);
}
- protected @Nullable TaskView getHomeTaskView() {
- return null;
+ public @Nullable TaskView getFocusedTaskView() {
+ return getTaskView(mFocusedTaskId);
}
/**
- * Handle the edge case where Recents could increment task count very high over long
- * period of device usage. Probably will never happen, but meh.
+ * Returns the width to height ratio of the focused {@link TaskView}.
*/
- private <T extends TaskView> T getTaskViewFromPool(boolean isGrouped) {
- T taskView = isGrouped ?
- (T) mGroupedTaskViewPool.getView() :
- (T) mTaskViewPool.getView();
- taskView.setTaskViewId(mTaskViewIdCount);
- if (mTaskViewIdCount == Integer.MAX_VALUE) {
- mTaskViewIdCount = 0;
- } else {
- mTaskViewIdCount++;
- }
-
- return taskView;
+ public float getFocusedTaskRatio() {
+ return mFocusedTaskRatio;
}
/**
@@ -2091,10 +1665,14 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
* @return -1 if there is no task view for the task id, else the index of the task view.
*/
public int getTaskIndexForId(int taskId) {
- TaskView tv = getTaskViewByTaskId(taskId);
+ TaskView tv = getTaskView(taskId);
return tv == null ? -1 : indexOfChild(tv);
}
+ public int getTaskViewStartIndex() {
+ return mTaskViewStartIndex;
+ }
+
/**
* Reloads the view if anything in recents changed.
*/
@@ -2107,23 +1685,18 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
/**
* Called when a gesture from an app is starting.
*/
- public void onGestureAnimationStart(
- Task[] runningTasks, RotationTouchHelper rotationTouchHelper) {
+ public void onGestureAnimationStart(RunningTaskInfo runningTaskInfo) {
mGestureActive = true;
// This needs to be called before the other states are set since it can create the task view
if (mOrientationState.setGestureActive(true)) {
- setLayoutRotation(rotationTouchHelper.getCurrentActiveRotation(),
- rotationTouchHelper.getDisplayRotation());
- // Force update to ensure the initial task size is computed even if the orientation has
- // not changed.
- updateSizeAndPadding();
+ updateOrientationHandler();
}
- showCurrentTask(runningTasks);
+ showCurrentTask(runningTaskInfo);
setEnableFreeScroll(false);
setEnableDrawingLiveTile(false);
setRunningTaskHidden(true);
- setTaskIconScaledDown(true);
+ setRunningTaskIconScaledDown(true);
}
/**
@@ -2131,12 +1704,14 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
* {@link #onGestureAnimationStart} and {@link #onGestureAnimationEnd()}.
*/
public void onSwipeUpAnimationSuccess() {
- animateUpTaskIconScale();
+ if (getRunningTaskView() != null) {
+ animateUpRunningTaskIconScale();
+ }
setSwipeDownShouldLaunchApp(true);
}
private void animateRecentsRotationInPlace(int newRotation) {
- if (mOrientationState.isRecentsActivityRotationAllowed()) {
+ if (mOrientationState.canRecentsActivityRotate()) {
// Let system take care of the rotation
return;
}
@@ -2154,18 +1729,19 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
int runningIndex = getCurrentPage();
AnimatorSet as = new AnimatorSet();
for (int i = 0; i < getTaskViewCount(); i++) {
- View taskView = requireTaskViewAt(i);
- if (runningIndex == i && taskView.getAlpha() != 0) {
+ if (runningIndex == i) {
continue;
}
+ View taskView = getTaskViewAt(i);
as.play(ObjectAnimator.ofFloat(taskView, View.ALPHA, fadeInChildren ? 0 : 1));
}
return as;
}
+
private void updateChildTaskOrientations() {
for (int i = 0; i < getTaskViewCount(); i++) {
- requireTaskViewAt(i).setOrientationState(mOrientationState);
+ getTaskViewAt(i).setOrientationState(mOrientationState);
}
TaskMenuView tv = (TaskMenuView) getTopOpenViewWithType(mActivity, TYPE_TASK_MENU);
if (tv != null) {
@@ -2177,38 +1753,24 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
* Called when a gesture from an app has finished, and an end target has been determined.
*/
public void onPrepareGestureEndAnimation(
- @Nullable AnimatorSet animatorSet, GestureState.GestureEndTarget endTarget,
- TaskViewSimulator[] taskViewSimulators) {
- mCurrentGestureEndTarget = endTarget;
- if (endTarget == GestureState.GestureEndTarget.RECENTS) {
- updateGridProperties();
- }
-
+ @Nullable AnimatorSet animatorSet, GestureState.GestureEndTarget endTarget) {
if (mSizeStrategy.stateFromGestureEndTarget(endTarget)
.displayOverviewTasksAsGrid(mActivity.getDeviceProfile())) {
- TaskView runningTaskView = getRunningTaskView();
- float runningTaskPrimaryGridTranslation = 0;
- if (runningTaskView != null) {
- // Apply the grid translation to running task unless it's being snapped to
- // and removes the current translation applied to the running task.
- runningTaskPrimaryGridTranslation = mOrientationHandler.getPrimaryValue(
- runningTaskView.getGridTranslationX(),
- runningTaskView.getGridTranslationY())
- - runningTaskView.getPrimaryNonGridTranslationProperty().get(
- runningTaskView);
- }
- for (TaskViewSimulator tvs : taskViewSimulators) {
- if (animatorSet == null) {
- setGridProgress(1);
- tvs.taskPrimaryTranslation.value =
- runningTaskPrimaryGridTranslation;
- } else {
- animatorSet.play(ObjectAnimator.ofFloat(this, RECENTS_GRID_PROGRESS, 1));
- animatorSet.play(tvs.taskPrimaryTranslation.animateToValue(
- runningTaskPrimaryGridTranslation));
- }
+ if (animatorSet == null) {
+ setGridProgress(1);
+ } else {
+ animatorSet.play(ObjectAnimator.ofFloat(this, RECENTS_GRID_PROGRESS, 1));
}
}
+ mCurrentGestureEndTarget = endTarget;
+ if (endTarget == GestureState.GestureEndTarget.NEW_TASK
+ || endTarget == GestureState.GestureEndTarget.LAST_TASK) {
+ // When switching to tasks in quick switch, ensures the snapped page's scroll maintain
+ // invariant between quick switch and overview, to ensure a smooth animation transition.
+ updateGridProperties();
+ } else if (endTarget == GestureState.GestureEndTarget.RECENTS) {
+ setEnableFreeScroll(true);
+ }
}
/**
@@ -2217,7 +1779,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
public void onGestureAnimationEnd() {
mGestureActive = false;
if (mOrientationState.setGestureActive(false)) {
- updateOrientationHandler(/* forceRecreateDragLayerControllers = */ false);
+ updateOrientationHandler();
}
setEnableFreeScroll(true);
@@ -2226,28 +1788,27 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
setRunningTaskViewShowScreenshot(true);
}
setRunningTaskHidden(false);
- animateUpTaskIconScale();
- animateActionsViewIn();
+ animateUpRunningTaskIconScale();
+
+ if (mCurrentGestureEndTarget == GestureState.GestureEndTarget.RECENTS
+ && (!showAsGrid() || getFocusedTaskView() != null)) {
+ animateActionsViewIn();
+ }
mCurrentGestureEndTarget = null;
+
+ if (ENABLE_QUICKSTEP_LIVE_TILE.get() && mActivity.getDeviceProfile().isMultiWindowMode) {
+ switchToScreenshot(
+ () -> finishRecentsAnimation(true /* toRecents */, false /* shouldPip */,
+ null));
+ }
}
/**
* Returns true if we should add a stub taskView for the running task id
*/
- protected boolean shouldAddStubTaskView(Task[] runningTasks) {
- if (runningTasks.length > 1) {
- TaskView primaryTaskView = getTaskViewByTaskId(runningTasks[0].key.id);
- TaskView secondaryTaskView = getTaskViewByTaskId(runningTasks[1].key.id);
- int leftTopTaskViewId =
- (primaryTaskView == null) ? -1 : primaryTaskView.getTaskViewId();
- int rightBottomTaskViewId =
- (secondaryTaskView == null) ? -1 : secondaryTaskView.getTaskViewId();
- // Add a new stub view if both taskIds don't match any taskViews
- return leftTopTaskViewId != rightBottomTaskViewId || leftTopTaskViewId == -1;
- }
- Task runningTaskInfo = runningTasks[0];
- return runningTaskInfo != null && getTaskViewByTaskId(runningTaskInfo.key.id) == null;
+ protected boolean shouldAddStubTaskView(RunningTaskInfo runningTaskInfo) {
+ return runningTaskInfo != null && getTaskView(runningTaskInfo.taskId) == null;
}
/**
@@ -2256,85 +1817,71 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
* All subsequent calls to reload will keep the task as the first item until {@link #reset()}
* is called. Also scrolls the view to this task.
*/
- private void showCurrentTask(Task[] runningTasks) {
- if (runningTasks.length == 0) {
- return;
- }
- int runningTaskViewId = -1;
- boolean needGroupTaskView = runningTasks.length > 1;
- if (shouldAddStubTaskView(runningTasks)) {
+ public void showCurrentTask(RunningTaskInfo runningTaskInfo) {
+ if (shouldAddStubTaskView(runningTaskInfo)) {
boolean wasEmpty = getChildCount() == 0;
// Add an empty view for now until the task plan is loaded and applied
- final TaskView taskView;
- if (needGroupTaskView) {
- taskView = getTaskViewFromPool(true);
- mTmpRunningTasks = new Task[]{runningTasks[0], runningTasks[1]};
- addView(taskView, 0);
- // When we create a placeholder task view mSplitBoundsConfig will be null, but with
- // the actual app running we won't need to show the thumbnail until all the tasks
- // load later anyways
- ((GroupedTaskView)taskView).bind(mTmpRunningTasks[0], mTmpRunningTasks[1],
- mOrientationState, mSplitBoundsConfig);
- } else {
- taskView = getTaskViewFromPool(false);
- addView(taskView, 0);
- // The temporary running task is only used for the duration between the start of the
- // gesture and the task list is loaded and applied
- mTmpRunningTasks = new Task[]{runningTasks[0]};
- taskView.bind(mTmpRunningTasks[0], mOrientationState);
- }
- runningTaskViewId = taskView.getTaskViewId();
+ final TaskView taskView = mTaskViewPool.getView();
+ addView(taskView, mTaskViewStartIndex);
if (wasEmpty) {
addView(mClearAllButton);
}
+ // The temporary running task is only used for the duration between the start of the
+ // gesture and the task list is loaded and applied
+ mTmpRunningTask = Task.from(new TaskKey(runningTaskInfo), runningTaskInfo, false);
+ taskView.bind(mTmpRunningTask, mOrientationState);
// Measure and layout immediately so that the scroll values is updated instantly
// as the user might be quick-switching
measure(makeMeasureSpec(getMeasuredWidth(), EXACTLY),
makeMeasureSpec(getMeasuredHeight(), EXACTLY));
layout(getLeft(), getTop(), getRight(), getBottom());
- } else if (getTaskViewByTaskId(runningTasks[0].key.id) != null) {
- runningTaskViewId = getTaskViewByTaskId(runningTasks[0].key.id).getTaskViewId();
}
boolean runningTaskTileHidden = mRunningTaskTileHidden;
- setCurrentTask(runningTaskViewId);
- mFocusedTaskViewId = runningTaskViewId;
+ int runningTaskId = runningTaskInfo == null ? -1 : runningTaskInfo.taskId;
+ setCurrentTask(runningTaskId);
+ if (mActivity.getDeviceProfile().isTablet && FeatureFlags.ENABLE_OVERVIEW_GRID.get()) {
+ setFocusedTask(runningTaskId);
+ }
setCurrentPage(getRunningTaskIndex());
setRunningTaskViewShowScreenshot(false);
setRunningTaskHidden(runningTaskTileHidden);
// Update task size after setting current task.
updateTaskSize();
- updateChildTaskOrientations();
// Reload the task list
- reloadIfNeeded();
+ mTaskListChangeId = mModel.getTasks(this::applyLoadPlan);
}
/**
* Sets the running task id, cleaning up the old running task if necessary.
*/
- public void setCurrentTask(int runningTaskViewId) {
- if (mRunningTaskViewId == runningTaskViewId) {
+ public void setCurrentTask(int runningTaskId) {
+ if (mRunningTaskId == runningTaskId) {
return;
}
- if (mRunningTaskViewId != -1) {
+ if (mRunningTaskId != -1) {
// Reset the state on the old running task view
- setTaskIconScaledDown(false);
+ setRunningTaskIconScaledDown(false);
setRunningTaskViewShowScreenshot(true);
setRunningTaskHidden(false);
}
- mRunningTaskViewId = runningTaskViewId;
+ mRunningTaskId = runningTaskId;
}
- private int getTaskViewIdFromTaskId(int taskId) {
- TaskView taskView = getTaskViewByTaskId(taskId);
- return taskView != null ? taskView.getTaskViewId() : -1;
+ /**
+ * Sets the focused task id and store the width to height ratio of the focused task.
+ */
+ protected void setFocusedTask(int focusedTaskId) {
+ mFocusedTaskId = focusedTaskId;
+ mFocusedTaskRatio =
+ mLastComputedTaskSize.width() / (float) mLastComputedTaskSize.height();
}
/**
- * Hides the tile associated with {@link #mRunningTaskViewId}
+ * Hides the tile associated with {@link #mRunningTaskId}
*/
public void setRunningTaskHidden(boolean isHidden) {
mRunningTaskTileHidden = isHidden;
@@ -2358,79 +1905,90 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
}
}
- public void setTaskIconScaledDown(boolean isScaledDown) {
- if (mTaskIconScaledDown != isScaledDown) {
- mTaskIconScaledDown = isScaledDown;
- int taskCount = getTaskViewCount();
- for (int i = 0; i < taskCount; i++) {
- requireTaskViewAt(i).setIconScaleAndDim(mTaskIconScaledDown ? 0 : 1);
- }
+ public void setRunningTaskIconScaledDown(boolean isScaledDown) {
+ if (mRunningTaskIconScaledDown != isScaledDown) {
+ mRunningTaskIconScaledDown = isScaledDown;
+ applyRunningTaskIconScale();
}
}
- private void animateActionsViewIn() {
- if (!showAsGrid() || isFocusedTaskInExpectedScrollPosition()) {
- animateActionsViewAlpha(1, TaskView.SCALE_ICON_DURATION);
+ public boolean isTaskIconScaledDown(TaskView taskView) {
+ return mRunningTaskIconScaledDown && getRunningTaskView() == taskView;
+ }
+
+ private void applyRunningTaskIconScale() {
+ TaskView firstTask = getRunningTaskView();
+ if (firstTask != null) {
+ firstTask.setIconScaleAndDim(mRunningTaskIconScaledDown ? 0 : 1);
}
}
- public void animateUpTaskIconScale() {
- mTaskIconScaledDown = false;
- int taskCount = getTaskViewCount();
- for (int i = 0; i < taskCount; i++) {
- TaskView taskView = requireTaskViewAt(i);
- taskView.setIconScaleAnimStartProgress(0f);
- taskView.animateIconScaleAndDimIntoView();
+ private void animateActionsViewIn() {
+ ObjectAnimator anim = ObjectAnimator.ofFloat(
+ mActionsView.getVisibilityAlpha(), MultiValueAlpha.VALUE, 0, 1);
+ anim.setDuration(TaskView.SCALE_ICON_DURATION);
+ anim.start();
+ }
+
+ private void animateActionsViewOut() {
+ ObjectAnimator anim = ObjectAnimator.ofFloat(
+ mActionsView.getVisibilityAlpha(), MultiValueAlpha.VALUE, 1, 0);
+ anim.setDuration(TaskView.SCALE_ICON_DURATION);
+ anim.start();
+ }
+
+ public void animateUpRunningTaskIconScale() {
+ mRunningTaskIconScaledDown = false;
+ TaskView firstTask = getRunningTaskView();
+ if (firstTask != null) {
+ firstTask.setIconScaleAnimStartProgress(0f);
+ firstTask.animateIconScaleAndDimIntoView();
}
}
- /**
- * Updates TaskView and ClearAllButtion scaling and translation required to turn into grid
+ /** Updates TaskView and ClearAllButtion scaling and translation required to turn into grid
* layout.
* This method is used when no task dismissal has occurred.
*/
private void updateGridProperties() {
- updateGridProperties(false, Integer.MAX_VALUE);
- }
-
- /**
- * Updates TaskView and ClearAllButtion scaling and translation required to turn into grid
- * layout.
- *
- * This method is used when task dismissal has occurred, but rebalance is not needed.
- *
- * @param isTaskDismissal indicates if update was called due to task dismissal
- */
- private void updateGridProperties(boolean isTaskDismissal) {
- updateGridProperties(isTaskDismissal, Integer.MAX_VALUE);
+ updateGridProperties(false);
}
/**
* Updates TaskView and ClearAllButton scaling and translation required to turn into grid
* layout.
- *
* This method only calculates the potential position and depends on {@link #setGridProgress} to
* apply the actual scaling and translation.
*
- * @param isTaskDismissal indicates if update was called due to task dismissal
- * @param startRebalanceAfter which view index to start rebalancing from. Use Integer.MAX_VALUE
- * to skip rebalance
+ * @param isTaskDismissal indicates if update was called due to task dismissal
*/
- private void updateGridProperties(boolean isTaskDismissal, int startRebalanceAfter) {
+ private void updateGridProperties(boolean isTaskDismissal) {
int taskCount = getTaskViewCount();
if (taskCount == 0) {
return;
}
+ final int boxLength = Math.max(mLastComputedGridTaskSize.width(),
+ mLastComputedGridTaskSize.height());
int taskTopMargin = mActivity.getDeviceProfile().overviewTaskThumbnailTopMarginPx;
+ /*
+ * taskGridVerticalDiff is used to position the top of a task in the top row of the grid
+ * heightOffset is the vertical space one grid task takes + space between top and
+ * bottom row
+ * Summed together they provide the top position for bottom row of grid tasks
+ */
+ final float taskGridVerticalDiff =
+ mLastComputedGridTaskSize.top - mLastComputedTaskSize.top;
+ final float heightOffset = (boxLength + taskTopMargin) + mRowSpacing;
+
int topRowWidth = 0;
int bottomRowWidth = 0;
float topAccumulatedTranslationX = 0;
float bottomAccumulatedTranslationX = 0;
// Contains whether the child index is in top or bottom of grid (for non-focused task)
- // Different from mTopRowIdSet, which contains the taskViewId of what task is in top row
+ // Different from mTopRowIdSet, which contains the taskId of what task is in top row
IntSet topSet = new IntSet();
IntSet bottomSet = new IntSet();
@@ -2442,15 +2000,13 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
int focusedTaskWidthAndSpacing = 0;
int snappedTaskRowWidth = 0;
int snappedPage = getNextPage();
- TaskView snappedTaskView = getTaskViewAt(snappedPage);
- TaskView homeTaskView = getHomeTaskView();
- TaskView nextFocusedTaskView = null;
+ TaskView snappedTaskView = getTaskViewAtByAbsoluteIndex(snappedPage);
if (!isTaskDismissal) {
mTopRowIdSet.clear();
}
for (int i = 0; i < taskCount; i++) {
- TaskView taskView = requireTaskViewAt(i);
+ TaskView taskView = getTaskViewAt(i);
int taskWidthAndSpacing = taskView.getLayoutParams().width + mPageSpacing;
// Evenly distribute tasks between rows unless rearranging due to task dismissal, in
// which case keep tasks in their respective rows. For the running task, don't join
@@ -2482,32 +2038,15 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
// calculate the distance focused task need to shift.
focusedTaskShift += mIsRtl ? taskWidthAndSpacing : -taskWidthAndSpacing;
}
- int taskViewId = taskView.getTaskViewId();
-
- // Rebalance the grid starting after a certain index
- boolean isTopRow;
- if (isTaskDismissal) {
- if (i > startRebalanceAfter) {
- mTopRowIdSet.remove(taskViewId);
- isTopRow = topRowWidth <= bottomRowWidth;
- } else {
- isTopRow = mTopRowIdSet.contains(taskViewId);
- }
- } else {
- isTopRow = topRowWidth <= bottomRowWidth;
- }
-
+ int taskId = taskView.getTask().key.id;
+ boolean isTopRow = isTaskDismissal ? mTopRowIdSet.contains(taskId)
+ : topRowWidth <= bottomRowWidth;
if (isTopRow) {
- if (homeTaskView != null && nextFocusedTaskView == null) {
- // TaskView will be focused when swipe up, don't count towards row width.
- nextFocusedTaskView = taskView;
- } else {
- topRowWidth += taskWidthAndSpacing;
- }
+ topRowWidth += taskWidthAndSpacing;
topSet.add(i);
- mTopRowIdSet.add(taskViewId);
+ mTopRowIdSet.add(taskId);
- taskView.setGridTranslationY(mTaskGridVerticalDiff);
+ taskView.setGridTranslationY(taskGridVerticalDiff);
// Move horizontally into empty space.
float widthOffset = 0;
@@ -2515,7 +2054,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
if (j == focusedTaskIndex) {
continue;
}
- widthOffset += requireTaskViewAt(j).getLayoutParams().width + mPageSpacing;
+ widthOffset += getTaskViewAt(j).getLayoutParams().width + mPageSpacing;
}
float currentTaskTranslationX = mIsRtl ? widthOffset : -widthOffset;
@@ -2526,7 +2065,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
bottomSet.add(i);
// Move into bottom row.
- taskView.setGridTranslationY(mTopBottomRowHeightDiff + mTaskGridVerticalDiff);
+ taskView.setGridTranslationY(heightOffset + taskGridVerticalDiff);
// Move horizontally into empty space.
float widthOffset = 0;
@@ -2534,7 +2073,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
if (j == focusedTaskIndex) {
continue;
}
- widthOffset += requireTaskViewAt(j).getLayoutParams().width + mPageSpacing;
+ widthOffset += getTaskViewAt(j).getLayoutParams().width + mPageSpacing;
}
float currentTaskTranslationX = mIsRtl ? widthOffset : -widthOffset;
@@ -2550,12 +2089,20 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
// We need to maintain snapped task's page scroll invariant between quick switch and
// overview, so we sure snapped task's grid translation is 0, and add a non-fullscreen
// translationX that is the same as snapped task's full scroll adjustment.
- float snappedTaskNonGridScrollAdjustment = 0;
+ float snappedTaskFullscreenScrollAdjustment = 0;
float snappedTaskGridTranslationX = 0;
if (snappedTaskView != null) {
- snappedTaskNonGridScrollAdjustment = snappedTaskView.getScrollAdjustment(
+ snappedTaskFullscreenScrollAdjustment = snappedTaskView.getScrollAdjustment(
/*fullscreenEnabled=*/true, /*gridEnabled=*/false);
- snappedTaskGridTranslationX = gridTranslations[snappedPage];
+ snappedTaskGridTranslationX = gridTranslations[snappedPage - mTaskViewStartIndex];
+ }
+
+ for (int i = 0; i < taskCount; i++) {
+ TaskView taskView = getTaskViewAt(i);
+ taskView.setGridTranslationX(gridTranslations[i] - snappedTaskGridTranslationX);
+ taskView.getPrimaryNonFullscreenTranslationProperty().set(taskView,
+ snappedTaskFullscreenScrollAdjustment);
+ taskView.getSecondaryNonFullscreenTranslationProperty().set(taskView, 0f);
}
// Use the accumulated translation of the row containing the last task.
@@ -2590,7 +2137,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
float clearAllTotalTranslationX =
clearAllAccumulatedTranslation + clearAllShorterRowCompensation
- + clearAllShortTotalCompensation + snappedTaskNonGridScrollAdjustment;
+ + clearAllShortTotalCompensation + snappedTaskFullscreenScrollAdjustment;
if (focusedTaskIndex < taskCount) {
// Shift by focused task's width and spacing if a task is focused.
clearAllTotalTranslationX +=
@@ -2600,23 +2147,15 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
// Make sure there are enough space between snapped page and ClearAllButton, for the case
// of swiping up after quick switch.
if (snappedTaskView != null) {
- int distanceFromClearAll = longRowWidth - snappedTaskRowWidth + mPageSpacing;
- // ClearAllButton should be off screen when snapped task is in its snapped position.
+ int distanceFromClearAll = longRowWidth - snappedTaskRowWidth;
int minimumDistance =
- mTaskWidth - snappedTaskView.getLayoutParams().width
- + (mLastComputedGridSize.width() - mTaskWidth) / 2;
+ mLastComputedGridSize.width() - snappedTaskView.getLayoutParams().width;
if (distanceFromClearAll < minimumDistance) {
int distanceDifference = minimumDistance - distanceFromClearAll;
- snappedTaskGridTranslationX += mIsRtl ? distanceDifference : -distanceDifference;
+ clearAllTotalTranslationX += mIsRtl ? -distanceDifference : distanceDifference;
}
}
- for (int i = 0; i < taskCount; i++) {
- TaskView taskView = requireTaskViewAt(i);
- taskView.setGridTranslationX(gridTranslations[i] - snappedTaskGridTranslationX
- + snappedTaskNonGridScrollAdjustment);
- }
-
mClearAllButton.setGridTranslationPrimary(
clearAllTotalTranslationX - snappedTaskGridTranslationX);
mClearAllButton.setGridScrollOffset(
@@ -2630,13 +2169,13 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
if (taskView1 == null || taskView2 == null) {
return false;
}
- int taskViewId1 = taskView1.getTaskViewId();
- int taskViewId2 = taskView2.getTaskViewId();
- if (taskViewId1 == mFocusedTaskViewId || taskViewId2 == mFocusedTaskViewId) {
+ int taskId1 = taskView1.getTask().key.id;
+ int taskId2 = taskView2.getTask().key.id;
+ if (taskId1 == mFocusedTaskId || taskId2 == mFocusedTaskId) {
return false;
}
- return (mTopRowIdSet.contains(taskViewId1) && mTopRowIdSet.contains(taskViewId2)) || (
- !mTopRowIdSet.contains(taskViewId1) && !mTopRowIdSet.contains(taskViewId2));
+ return (mTopRowIdSet.contains(taskId1) && mTopRowIdSet.contains(taskId2)) || (
+ !mTopRowIdSet.contains(taskId1) && !mTopRowIdSet.contains(taskId2));
}
/**
@@ -2653,7 +2192,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
mGridProgress = gridProgress;
for (int i = 0; i < taskCount; i++) {
- requireTaskViewAt(i).setGridProgress(gridProgress);
+ getTaskViewAt(i).setGridProgress(gridProgress);
}
mClearAllButton.setGridProgress(gridProgress);
}
@@ -2708,89 +2247,61 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
PendingAnimation anim) {
// Use setFloat instead of setViewAlpha as we want to keep the view visible even when it's
// alpha is set to 0 so that it can be recycled in the view pool properly
- anim.setFloat(taskView, VIEW_ALPHA, 0,
- clampToProgress(isOnGridBottomRow(taskView) ? ACCEL : FINAL_FRAME, 0, 0.5f));
- FloatProperty<TaskView> secondaryViewTranslate =
- taskView.getSecondaryDissmissTranslationProperty();
- int secondaryTaskDimension = mOrientationHandler.getSecondaryDimension(taskView);
- int verticalFactor = mOrientationHandler.getSecondaryTranslationDirectionFactor();
+ anim.setFloat(taskView, VIEW_ALPHA, 0, clampToProgress(ACCEL, 0, 0.5f));
+ SplitSelectStateController splitController = mSplitPlaceholderView.getSplitController();
ResourceProvider rp = DynamicResource.provider(mActivity);
SpringProperty sp = new SpringProperty(SpringProperty.FLAG_CAN_SPRING_ON_START)
.setDampingRatio(rp.getFloat(R.dimen.dismiss_task_trans_y_damping_ratio))
.setStiffness(rp.getFloat(R.dimen.dismiss_task_trans_y_stiffness));
+ FloatProperty<TaskView> dismissingTaskViewTranslate =
+ taskView.getSecondaryDissmissTranslationProperty();
+ // TODO(b/186800707) translate entire grid size distance
+ int translateDistance = mOrientationHandler.getSecondaryDimension(taskView);
+ int positiveNegativeFactor = mOrientationHandler.getSecondaryTranslationDirectionFactor();
+ if (splitController.isSplitSelectActive()) {
+ // Have the task translate towards whatever side was just pinned
+ int dir = mOrientationHandler.getSplitTaskViewDismissDirection(splitController
+ .getActiveSplitPositionOption(), mActivity.getDeviceProfile());
+ switch (dir) {
+ case PagedOrientationHandler.SPLIT_TRANSLATE_SECONDARY_NEGATIVE:
+ dismissingTaskViewTranslate = taskView
+ .getSecondaryDissmissTranslationProperty();
+ positiveNegativeFactor = -1;
+ break;
- anim.add(ObjectAnimator.ofFloat(taskView, secondaryViewTranslate,
- verticalFactor * secondaryTaskDimension * 2).setDuration(duration), LINEAR, sp);
+ case PagedOrientationHandler.SPLIT_TRANSLATE_PRIMARY_POSITIVE:
+ dismissingTaskViewTranslate = taskView.getPrimaryDismissTranslationProperty();
+ positiveNegativeFactor = 1;
+ break;
+
+ case PagedOrientationHandler.SPLIT_TRANSLATE_PRIMARY_NEGATIVE:
+ dismissingTaskViewTranslate = taskView.getPrimaryDismissTranslationProperty();
+ positiveNegativeFactor = -1;
+ break;
+ default:
+ throw new IllegalStateException("Invalid split task translation: " + dir);
+ }
+ }
+ // Double translation distance so dismissal drag is the full height, as we only animate
+ // the drag for the first half of the progress.
+ anim.add(ObjectAnimator.ofFloat(taskView, dismissingTaskViewTranslate,
+ positiveNegativeFactor * translateDistance * 2).setDuration(duration), LINEAR, sp);
if (ENABLE_QUICKSTEP_LIVE_TILE.get() && mEnableDrawingLiveTile
&& taskView.isRunningTask()) {
anim.addOnFrameCallback(() -> {
- runActionOnRemoteHandles(
- remoteTargetHandle -> remoteTargetHandle.getTaskViewSimulator()
- .taskSecondaryTranslation.value = mOrientationHandler
- .getSecondaryValue(taskView.getTranslationX(),
- taskView.getTranslationY()
- ));
+ mLiveTileTaskViewSimulator.taskSecondaryTranslation.value =
+ mOrientationHandler.getSecondaryValue(
+ taskView.getTranslationX(),
+ taskView.getTranslationY());
redrawLiveTile();
});
}
}
- /**
- * Places an {@link FloatingTaskView} on top of the thumbnail for {@link #mSplitHiddenTaskView}
- * and then animates it into the split position that was desired
- */
- private void createInitialSplitSelectAnimation(PendingAnimation anim) {
- mOrientationHandler.getInitialSplitPlaceholderBounds(mSplitPlaceholderSize,
- mSplitPlaceholderInset, mActivity.getDeviceProfile(),
- mSplitSelectStateController.getActiveSplitStagePosition(), mTempRect);
-
- RectF startingTaskRect = new RectF();
- if (mSplitHiddenTaskView != null) {
- mSplitHiddenTaskView.setVisibility(INVISIBLE);
- mFirstFloatingTaskView = FloatingTaskView.getFloatingTaskView(mActivity,
- mSplitHiddenTaskView.getThumbnail(),
- mSplitHiddenTaskView.getThumbnail().getThumbnail(),
- mSplitHiddenTaskView.getIconView().getDrawable(), startingTaskRect);
- mFirstFloatingTaskView.setAlpha(1);
- mFirstFloatingTaskView.addAnimation(anim, startingTaskRect, mTempRect,
- true /* fadeWithThumbnail */, true /* isStagedTask */);
- } else {
- mFirstFloatingTaskView = FloatingTaskView.getFloatingTaskView(mActivity,
- mSplitSelectSource.view, null /* thumbnail */,
- mSplitSelectSource.drawable, startingTaskRect);
- mFirstFloatingTaskView.setAlpha(1);
- mFirstFloatingTaskView.addAnimation(anim, startingTaskRect, mTempRect,
- false /* fadeWithThumbnail */, true /* isStagedTask */);
- }
- InteractionJankMonitorWrapper.begin(this,
- InteractionJankMonitorWrapper.CUJ_SPLIT_SCREEN_ENTER, "First tile selected");
- anim.addEndListener(success -> {
- if (success) {
- mSplitToast.show();
- InteractionJankMonitorWrapper.end(
- InteractionJankMonitorWrapper.CUJ_SPLIT_SCREEN_ENTER);
- } else {
- InteractionJankMonitorWrapper.cancel(
- InteractionJankMonitorWrapper.CUJ_SPLIT_SCREEN_ENTER);
- }
- });
- }
-
- /**
- * Creates a {@link PendingAnimation} for dismissing the specified {@link TaskView}.
- * @param dismissedTaskView the {@link TaskView} to be dismissed
- * @param animateTaskView whether the {@link TaskView} to be dismissed should be animated
- * @param shouldRemoveTask whether the associated {@link Task} should be removed from
- * ActivityManager after dismissal
- * @param duration duration of the animation
- * @param dismissingForSplitSelection task dismiss animation is used for entering split
- * selection state from app icon
- */
- public PendingAnimation createTaskDismissAnimation(TaskView dismissedTaskView,
- boolean animateTaskView, boolean shouldRemoveTask, long duration,
- boolean dismissingForSplitSelection) {
+ public PendingAnimation createTaskDismissAnimation(TaskView taskView, boolean animateTaskView,
+ boolean shouldRemoveTask, long duration) {
if (mPendingAnimation != null) {
mPendingAnimation.createPlaybackController().dispatchOnCancel().dispatchOnEnd();
}
@@ -2801,183 +2312,30 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
return anim;
}
- boolean showAsGrid = showAsGrid();
- int taskCount = getTaskViewCount();
- int dismissedIndex = indexOfChild(dismissedTaskView);
- int dismissedTaskViewId = dismissedTaskView.getTaskViewId();
-
- // Grid specific properties.
- boolean isFocusedTaskDismissed = false;
- TaskView nextFocusedTaskView = null;
- boolean nextFocusedTaskFromTop = false;
- float dismissedTaskWidth = 0;
- float nextFocusedTaskWidth = 0;
-
- // Non-grid specific properties.
int[] oldScroll = new int[count];
int[] newScroll = new int[count];
+ getPageScrolls(oldScroll, false, SIMPLE_SCROLL_LOGIC);
+ getPageScrolls(newScroll, false, (v) -> v.getVisibility() != GONE && v != taskView);
+ int taskCount = getTaskViewCount();
int scrollDiffPerPage = 0;
- boolean needsCurveUpdates = false;
-
- if (showAsGrid) {
- dismissedTaskWidth = dismissedTaskView.getLayoutParams().width + mPageSpacing;
- isFocusedTaskDismissed = dismissedTaskViewId == mFocusedTaskViewId;
- if (isFocusedTaskDismissed && !isSplitSelectionActive()) {
- nextFocusedTaskFromTop =
- mTopRowIdSet.size() > 0 && mTopRowIdSet.size() >= (taskCount - 1) / 2f;
- // Pick the next focused task from the preferred row.
- for (int i = 0; i < taskCount; i++) {
- TaskView taskView = requireTaskViewAt(i);
- if (taskView == dismissedTaskView) {
- continue;
- }
- boolean isTopRow = mTopRowIdSet.contains(taskView.getTaskViewId());
- if ((nextFocusedTaskFromTop && isTopRow
- || (!nextFocusedTaskFromTop && !isTopRow))) {
- nextFocusedTaskView = taskView;
- break;
- }
- }
- if (nextFocusedTaskView != null) {
- nextFocusedTaskWidth =
- nextFocusedTaskView.getLayoutParams().width + mPageSpacing;
- }
- }
- } else {
- getPageScrolls(oldScroll, false, SIMPLE_SCROLL_LOGIC);
- getPageScrolls(newScroll, false,
- v -> v.getVisibility() != GONE && v != dismissedTaskView);
- if (count > 1) {
- scrollDiffPerPage = Math.abs(oldScroll[1] - oldScroll[0]);
- }
+ if (count > 1) {
+ scrollDiffPerPage = Math.abs(oldScroll[1] - oldScroll[0]);
}
+ int draggedIndex = indexOfChild(taskView);
- announceForAccessibility(getResources().getString(R.string.task_view_closed));
-
- float dismissTranslationInterpolationEnd = 1;
- boolean closeGapBetweenClearAll = false;
- boolean isClearAllHidden = isClearAllHidden();
- boolean snapToLastTask = false;
- boolean isLandscapeSplit =
- mActivity.getDeviceProfile().isLandscape && isSplitSelectionActive();
- boolean isSplitPlaceholderFirstInGrid = isSplitPlaceholderFirstInGrid();
- boolean isSplitPlaceholderLastInGrid = isSplitPlaceholderLastInGrid();
- TaskView lastGridTaskView = showAsGrid ? getLastGridTaskView() : null;
- int currentPageScroll = getScrollForPage(mCurrentPage);
- int lastGridTaskScroll = getScrollForPage(indexOfChild(lastGridTaskView));
- boolean currentPageSnapsToEndOfGrid = currentPageScroll == lastGridTaskScroll;
- if (lastGridTaskView != null && lastGridTaskView.isVisibleToUser()) {
- // After dismissal, animate translation of the remaining tasks to fill any gap left
- // between the end of the grid and the clear all button. Only animate if the clear
- // all button is visible or would become visible after dismissal.
- float longGridRowWidthDiff = 0;
-
- int topGridRowSize = mTopRowIdSet.size();
- int bottomGridRowSize = taskCount - mTopRowIdSet.size() - 1;
- boolean topRowLonger = topGridRowSize > bottomGridRowSize;
- boolean bottomRowLonger = bottomGridRowSize > topGridRowSize;
- boolean dismissedTaskFromTop = mTopRowIdSet.contains(dismissedTaskViewId);
- boolean dismissedTaskFromBottom = !dismissedTaskFromTop && !isFocusedTaskDismissed;
- float gapWidth = 0;
- if ((topRowLonger && dismissedTaskFromTop)
- || (bottomRowLonger && dismissedTaskFromBottom)) {
- gapWidth = dismissedTaskWidth;
- } else if ((topRowLonger && nextFocusedTaskFromTop)
- || (bottomRowLonger && !nextFocusedTaskFromTop)) {
- gapWidth = nextFocusedTaskWidth;
- }
- if (gapWidth > 0) {
- if (taskCount > 2) {
- // Compensate the removed gap.
- longGridRowWidthDiff += mIsRtl ? -gapWidth : gapWidth;
- if (isClearAllHidden) {
- // If ClearAllButton isn't fully shown, snap to the last task.
- snapToLastTask = true;
- }
- } else {
- // If only focused task will be left, snap to focused task instead.
- longGridRowWidthDiff += getSnapToFocusedTaskScrollDiff(isClearAllHidden);
- }
- }
- if (mClearAllButton.getAlpha() != 0f && isLandscapeSplit) {
- // ClearAllButton will not be available in split select, snap to last task instead.
- snapToLastTask = true;
- }
- if (snapToLastTask) {
- longGridRowWidthDiff += getSnapToLastTaskScrollDiff();
- if (isSplitPlaceholderLastInGrid) {
- // Shift all the tasks to make space for split placeholder.
- longGridRowWidthDiff += mIsRtl ? mSplitPlaceholderSize : -mSplitPlaceholderSize;
- }
- } else if (isLandscapeSplit && currentPageSnapsToEndOfGrid) {
- // Use last task as reference point for scroll diff and snapping calculation as it's
- // the only invariant point in landscape split screen.
- snapToLastTask = true;
- }
-
- // If we need to animate the grid to compensate the clear all gap, we split the second
- // half of the dismiss pending animation (in which the non-dismissed tasks slide into
- // place) in half again, making the first quarter the existing non-dismissal sliding
- // and the second quarter this new animation of gap filling. This is due to the fact
- // that PendingAnimation is a single animation, not a sequence of animations, so we
- // fake it using interpolation.
- if (longGridRowWidthDiff != 0) {
- closeGapBetweenClearAll = true;
- // Stagger the offsets of each additional task for a delayed animation. We use
- // half here as this animation is half of half of an animation (1/4th).
- float halfAdditionalDismissTranslationOffset =
- (0.5f * ADDITIONAL_DISMISS_TRANSLATION_INTERPOLATION_OFFSET);
- dismissTranslationInterpolationEnd = Utilities.boundToRange(
- END_DISMISS_TRANSLATION_INTERPOLATION_OFFSET
- + (taskCount - 1) * halfAdditionalDismissTranslationOffset,
- END_DISMISS_TRANSLATION_INTERPOLATION_OFFSET, 1);
- for (int i = 0; i < taskCount; i++) {
- TaskView taskView = requireTaskViewAt(i);
- anim.setFloat(taskView, TaskView.GRID_END_TRANSLATION_X, longGridRowWidthDiff,
- clampToProgress(LINEAR, dismissTranslationInterpolationEnd, 1));
- dismissTranslationInterpolationEnd = Utilities.boundToRange(
- dismissTranslationInterpolationEnd
- - halfAdditionalDismissTranslationOffset,
- END_DISMISS_TRANSLATION_INTERPOLATION_OFFSET, 1);
- if (ENABLE_QUICKSTEP_LIVE_TILE.get() && mEnableDrawingLiveTile
- && taskView.isRunningTask()) {
- anim.addOnFrameCallback(() -> {
- runActionOnRemoteHandles(
- remoteTargetHandle ->
- remoteTargetHandle.getTaskViewSimulator()
- .taskPrimaryTranslation.value =
- TaskView.GRID_END_TRANSLATION_X.get(taskView));
- redrawLiveTile();
- });
- }
- }
-
- // Change alpha of clear all if translating grid to hide it
- if (isClearAllHidden) {
- anim.setFloat(mClearAllButton, DISMISS_ALPHA, 0, LINEAR);
- anim.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- super.onAnimationEnd(animation);
- mClearAllButton.setDismissAlpha(1);
- }
- });
- }
- }
+ boolean isFocusedTaskDismissed = taskView.getTask().key.id == mFocusedTaskId;
+ if (isFocusedTaskDismissed && showAsGrid()) {
+ anim.setFloat(mActionsView, VIEW_ALPHA, 0, clampToProgress(ACCEL_0_5, 0, 0.5f));
}
-
- int distanceFromDismissedTask = 0;
+ float dismissedTaskWidth = taskView.getLayoutParams().width + mPageSpacing;
+ boolean needsCurveUpdates = false;
for (int i = 0; i < count; i++) {
View child = getChildAt(i);
- if (child == dismissedTaskView) {
+ if (child == taskView) {
if (animateTaskView) {
- if (dismissingForSplitSelection) {
- createInitialSplitSelectAnimation(anim);
- } else {
- addDismissedTaskAnimations(dismissedTaskView, duration, anim);
- }
+ addDismissedTaskAnimations(taskView, duration, anim);
}
- } else if (!showAsGrid) {
+ } else if (!showAsGrid()) {
// Compute scroll offsets from task dismissal for animation.
// If we just take newScroll - oldScroll, everything to the right of dragged task
// translates to the left. We need to offset this in some cases:
@@ -2986,15 +2344,15 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
// - Current page is rightmost page (leftmost for RTL)
// - Dragging an adjacent page on the left side (right side for RTL)
int offset = mIsRtl ? scrollDiffPerPage : 0;
- if (mCurrentPage == dismissedIndex) {
+ if (mCurrentPage == draggedIndex) {
int lastPage = taskCount - 1;
if (mCurrentPage == lastPage) {
offset += mIsRtl ? -scrollDiffPerPage : scrollDiffPerPage;
}
} else {
- // Dismissing an adjacent page.
+ // Dragging an adjacent page.
int negativeAdjacent = mCurrentPage - 1; // (Right in RTL, left in LTR)
- if (dismissedIndex == negativeAdjacent) {
+ if (draggedIndex == negativeAdjacent) {
offset += mIsRtl ? -scrollDiffPerPage : scrollDiffPerPage;
}
}
@@ -3007,7 +2365,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
float additionalDismissDuration =
ADDITIONAL_DISMISS_TRANSLATION_INTERPOLATION_OFFSET * Math.abs(
- i - dismissedIndex);
+ i - draggedIndex);
anim.setFloat(child, translationProperty, scrollDiff, clampToProgress(LINEAR,
Utilities.boundToRange(INITIAL_DISMISS_TRANSLATION_INTERPOLATION_OFFSET
+ additionalDismissDuration, 0f, 1f), 1));
@@ -3015,79 +2373,30 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
&& child instanceof TaskView
&& ((TaskView) child).isRunningTask()) {
anim.addOnFrameCallback(() -> {
- runActionOnRemoteHandles(
- remoteTargetHandle ->
- remoteTargetHandle.getTaskViewSimulator()
- .taskPrimaryTranslation.value =
- mOrientationHandler.getPrimaryValue(
- child.getTranslationX(),
- child.getTranslationY()
- ));
+ mLiveTileTaskViewSimulator.taskPrimaryTranslation.value =
+ mOrientationHandler.getPrimaryValue(child.getTranslationX(),
+ child.getTranslationY());
redrawLiveTile();
});
}
needsCurveUpdates = true;
}
} else if (child instanceof TaskView) {
- TaskView taskView = (TaskView) child;
- if (isFocusedTaskDismissed) {
- if (nextFocusedTaskView != null &&
- !isSameGridRow(taskView, nextFocusedTaskView)) {
- continue;
- }
- } else {
- if (i < dismissedIndex || !isSameGridRow(taskView, dismissedTaskView)) {
- continue;
- }
- }
// Animate task with index >= dismissed index and in the same row as the
- // dismissed index or next focused index. Offset successive task dismissal
- // durations for a staggered effect.
- float animationStartProgress = Utilities.boundToRange(
- INITIAL_DISMISS_TRANSLATION_INTERPOLATION_OFFSET
- + ADDITIONAL_DISMISS_TRANSLATION_INTERPOLATION_OFFSET
- * ++distanceFromDismissedTask, 0f,
- dismissTranslationInterpolationEnd);
- if (taskView == nextFocusedTaskView) {
- // Enlarge the task to be focused next, and translate into focus position.
- float scale = mTaskWidth / (float) mLastComputedGridTaskSize.width();
- anim.setFloat(taskView, TaskView.SNAPSHOT_SCALE, scale,
- clampToProgress(LINEAR, animationStartProgress,
- dismissTranslationInterpolationEnd));
- anim.setFloat(taskView, taskView.getPrimaryDismissTranslationProperty(),
- mIsRtl ? dismissedTaskWidth : -dismissedTaskWidth,
- clampToProgress(LINEAR, animationStartProgress,
- dismissTranslationInterpolationEnd));
- float secondaryTranslation = -mTaskGridVerticalDiff;
- if (!nextFocusedTaskFromTop) {
- secondaryTranslation -= mTopBottomRowHeightDiff;
- }
- anim.setFloat(taskView, taskView.getSecondaryDissmissTranslationProperty(),
- secondaryTranslation, clampToProgress(LINEAR, animationStartProgress,
- dismissTranslationInterpolationEnd));
- anim.setFloat(taskView, TaskView.FOCUS_TRANSITION, 0f,
- clampToProgress(LINEAR, 0f, ANIMATION_DISMISS_PROGRESS_MIDPOINT));
- } else {
- float primaryTranslation =
- nextFocusedTaskView != null ? nextFocusedTaskWidth : dismissedTaskWidth;
- if (isFocusedTaskDismissed && nextFocusedTaskView == null) {
- // Moves less if focused task is not in scroll position.
- int focusedTaskScroll = getScrollForPage(dismissedIndex);
- int primaryScroll = mOrientationHandler.getPrimaryScroll(this);
- int focusedTaskScrollDiff = primaryScroll - focusedTaskScroll;
- primaryTranslation +=
- mIsRtl ? focusedTaskScrollDiff : -focusedTaskScrollDiff;
- if (isSplitPlaceholderFirstInGrid) {
- // Moves less if split placeholder is at the start.
- primaryTranslation +=
- mIsRtl ? -mSplitPlaceholderSize : mSplitPlaceholderSize;
- }
- }
-
- anim.setFloat(taskView, taskView.getPrimaryDismissTranslationProperty(),
- mIsRtl ? primaryTranslation : -primaryTranslation,
- clampToProgress(LINEAR, animationStartProgress,
- dismissTranslationInterpolationEnd));
+ // dismissed index, or if the dismissed task was the focused task. Offset
+ // successive task dismissal durations for a staggered effect.
+ if (isFocusedTaskDismissed || (i >= draggedIndex && isSameGridRow((TaskView) child,
+ taskView))) {
+ FloatProperty translationProperty =
+ ((TaskView) child).getPrimaryDismissTranslationProperty();
+ float additionalDismissDuration =
+ ADDITIONAL_DISMISS_TRANSLATION_INTERPOLATION_OFFSET * Math.abs(
+ i - draggedIndex);
+ anim.setFloat(child, translationProperty,
+ !mIsRtl ? -dismissedTaskWidth : dismissedTaskWidth,
+ clampToProgress(LINEAR, Utilities.boundToRange(
+ INITIAL_DISMISS_TRANSLATION_INTERPOLATION_OFFSET
+ + additionalDismissDuration, 0f, 1f), 1));
}
}
}
@@ -3098,19 +2407,15 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
// Add a tiny bit of translation Z, so that it draws on top of other views
if (animateTaskView) {
- dismissedTaskView.setTranslationZ(0.1f);
+ taskView.setTranslationZ(0.1f);
}
mPendingAnimation = anim;
- final TaskView finalNextFocusedTaskView = nextFocusedTaskView;
- final boolean finalCloseGapBetweenClearAll = closeGapBetweenClearAll;
- final boolean finalSnapToLastTask = snapToLastTask;
- final boolean finalIsFocusedTaskDismissed = isFocusedTaskDismissed;
mPendingAnimation.addEndListener(new Consumer<Boolean>() {
@Override
public void accept(Boolean success) {
if (ENABLE_QUICKSTEP_LIVE_TILE.get() && mEnableDrawingLiveTile
- && dismissedTaskView.isRunningTask() && success) {
+ && taskView.isRunningTask() && success) {
finishRecentsAnimation(true /* toRecents */, false /* shouldPip */,
() -> onEnd(success));
} else {
@@ -3120,199 +2425,53 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
@SuppressWarnings("WrongCall")
private void onEnd(boolean success) {
- // Reset task translations as they may have updated via animations in
- // createTaskDismissAnimation
- resetTaskVisuals();
-
if (success) {
if (shouldRemoveTask) {
- if (dismissedTaskView.getTask() != null) {
- if (ENABLE_QUICKSTEP_LIVE_TILE.get()
- && dismissedTaskView.isRunningTask()) {
+ if (taskView.getTask() != null) {
+ if (ENABLE_QUICKSTEP_LIVE_TILE.get() && taskView.isRunningTask()) {
finishRecentsAnimation(true /* toRecents */, false /* shouldPip */,
- () -> removeTaskInternal(dismissedTaskViewId));
+ () -> removeTaskInternal(taskView));
} else {
- removeTaskInternal(dismissedTaskViewId);
+ removeTaskInternal(taskView);
}
mActivity.getStatsLogManager().logger()
- .withItemInfo(dismissedTaskView.getItemInfo())
+ .withItemInfo(taskView.getItemInfo())
.log(LAUNCHER_TASK_DISMISS_SWIPE_UP);
}
}
- int pageToSnapTo = mCurrentPage;
- mCurrentPageScrollDiff = 0;
- int taskViewIdToSnapTo = -1;
- if (showAsGrid) {
- if (finalCloseGapBetweenClearAll) {
- if (finalSnapToLastTask) {
- // Last task will be determined after removing dismissed task.
- pageToSnapTo = -1;
- } else if (taskCount > 2) {
- pageToSnapTo = indexOfChild(mClearAllButton);
- } else if (isClearAllHidden) {
- // Snap to focused task if clear all is hidden.
- pageToSnapTo = 0;
- }
- } else {
- // Get the id of the task view we will snap to based on the current
- // page's relative position as the order of indices change over time due
- // to dismissals.
- TaskView snappedTaskView = getTaskViewAt(mCurrentPage);
- boolean calculateScrollDiff = true;
- if (snappedTaskView != null && !finalSnapToLastTask) {
- if (snappedTaskView.getTaskViewId() == mFocusedTaskViewId) {
- if (finalNextFocusedTaskView != null) {
- taskViewIdToSnapTo =
- finalNextFocusedTaskView.getTaskViewId();
- } else if (dismissedTaskViewId != mFocusedTaskViewId) {
- taskViewIdToSnapTo = mFocusedTaskViewId;
- } else {
- // Won't focus next task in split select, so snap to the
- // first task.
- pageToSnapTo = 0;
- calculateScrollDiff = false;
- }
- } else {
- int snappedTaskViewId = snappedTaskView.getTaskViewId();
- boolean isSnappedTaskInTopRow = mTopRowIdSet.contains(
- snappedTaskViewId);
- IntArray taskViewIdArray =
- isSnappedTaskInTopRow ? getTopRowIdArray()
- : getBottomRowIdArray();
- int snappedIndex = taskViewIdArray.indexOf(snappedTaskViewId);
- taskViewIdArray.removeValue(dismissedTaskViewId);
- if (finalNextFocusedTaskView != null) {
- taskViewIdArray.removeValue(
- finalNextFocusedTaskView.getTaskViewId());
- }
- if (snappedIndex < taskViewIdArray.size()) {
- taskViewIdToSnapTo = taskViewIdArray.get(snappedIndex);
- } else if (snappedIndex == taskViewIdArray.size()) {
- // If the snapped task is the last item from the
- // dismissed row,
- // snap to the same column in the other grid row
- IntArray inverseRowTaskViewIdArray =
- isSnappedTaskInTopRow ? getBottomRowIdArray()
- : getTopRowIdArray();
- if (snappedIndex < inverseRowTaskViewIdArray.size()) {
- taskViewIdToSnapTo = inverseRowTaskViewIdArray.get(
- snappedIndex);
- }
- }
- }
- }
+ // Reset task translations as they may have updated via animations in
+ // createTaskDismissAnimation
+ resetTaskVisuals();
- if (calculateScrollDiff) {
- int primaryScroll = mOrientationHandler.getPrimaryScroll(
- RecentsView.this);
- int currentPageScroll = getScrollForPage(mCurrentPage);
- mCurrentPageScrollDiff = primaryScroll - currentPageScroll;
- // Compensate for coordinate shift by split placeholder.
- if (isSplitPlaceholderFirstInGrid && !finalSnapToLastTask) {
- mCurrentPageScrollDiff +=
- mIsRtl ? -mSplitPlaceholderSize : mSplitPlaceholderSize;
- } else if (isSplitPlaceholderLastInGrid && finalSnapToLastTask) {
- mCurrentPageScrollDiff +=
- mIsRtl ? mSplitPlaceholderSize : -mSplitPlaceholderSize;
- }
- }
- }
- } else if (dismissedIndex < pageToSnapTo || pageToSnapTo == taskCount - 1) {
- pageToSnapTo--;
+ int pageToSnapTo = mCurrentPage;
+ // Snap to start if focused task was dismissed, as after quick switch it could
+ // be at any page but the focused task always displays at the start.
+ if (taskView.getTask().key.id == mFocusedTaskId) {
+ pageToSnapTo = mTaskViewStartIndex;
+ } else if (draggedIndex < pageToSnapTo || pageToSnapTo == (getTaskViewCount()
+ - 1)) {
+ pageToSnapTo -= 1;
}
- boolean isHomeTaskDismissed = dismissedTaskView == getHomeTaskView();
- removeViewInLayout(dismissedTaskView);
- mTopRowIdSet.remove(dismissedTaskViewId);
+ removeViewInLayout(taskView);
- if (taskCount == 1) {
+ if (getTaskViewCount() == 0) {
removeViewInLayout(mClearAllButton);
- if (isHomeTaskDismissed) {
- updateEmptyMessage();
- } else {
- startHome();
- }
+ startHome();
} else {
- // Update focus task and its size.
- if (finalIsFocusedTaskDismissed && finalNextFocusedTaskView != null) {
- mFocusedTaskViewId = finalNextFocusedTaskView.getTaskViewId();
- mTopRowIdSet.remove(mFocusedTaskViewId);
- finalNextFocusedTaskView.animateIconScaleAndDimIntoView();
- }
- updateTaskSize(/*isTaskDismissal=*/ true);
- updateChildTaskOrientations();
- // Update scroll and snap to page.
- updateScrollSynchronously();
-
- if (showAsGrid) {
- // Rebalance tasks in the grid
- int highestVisibleTaskIndex = getHighestVisibleTaskIndex();
- if (highestVisibleTaskIndex < Integer.MAX_VALUE) {
- TaskView taskView = requireTaskViewAt(highestVisibleTaskIndex);
-
- boolean shouldRebalance;
- int screenStart = mOrientationHandler.getPrimaryScroll(
- RecentsView.this);
- int taskStart = mOrientationHandler.getChildStart(taskView)
- + (int) taskView.getOffsetAdjustment(/*fullscreenEnabled=*/
- false, /*gridEnabled=*/ true);
-
- // Rebalance only if there is a maximum gap between the task and the
- // screen's edge; this ensures that rebalanced tasks are outside the
- // visible screen.
- if (mIsRtl) {
- shouldRebalance = taskStart <= screenStart + mPageSpacing;
- } else {
- int screenEnd =
- screenStart + mOrientationHandler.getMeasuredSize(
- RecentsView.this);
- int taskSize = (int) (mOrientationHandler.getMeasuredSize(
- taskView) * taskView
- .getSizeAdjustment(/*fullscreenEnabled=*/false));
- int taskEnd = taskStart + taskSize;
-
- shouldRebalance = taskEnd >= screenEnd - mPageSpacing;
- }
-
- if (shouldRebalance) {
- updateGridProperties(/*isTaskDismissal=*/ true,
- highestVisibleTaskIndex);
- updateScrollSynchronously();
- }
- }
-
- IntArray topRowIdArray = getTopRowIdArray();
- IntArray bottomRowIdArray = getBottomRowIdArray();
- if (finalSnapToLastTask) {
- // If snapping to last task, find the last task after dismissal.
- pageToSnapTo = indexOfChild(
- getLastGridTaskView(topRowIdArray, bottomRowIdArray));
- } else if (taskViewIdToSnapTo != -1) {
- // If snapping to another page due to indices rearranging, find
- // the new index after dismissal & rearrange using the task view id.
- pageToSnapTo = indexOfChild(
- getTaskViewFromTaskViewId(taskViewIdToSnapTo));
- if (!currentPageSnapsToEndOfGrid) {
- // If it wasn't snapped to one of the last pages, but is now
- // snapped to last pages, we'll need to compensate for the
- // offset from the page's scroll to its visual position.
- mCurrentPageScrollDiff += getOffsetFromScrollPosition(
- pageToSnapTo, topRowIdArray, bottomRowIdArray);
- }
- }
- }
- pageBeginTransition();
- setCurrentPage(pageToSnapTo);
- // Update various scroll-dependent UI.
+ snapToPageImmediately(pageToSnapTo);
dispatchScrollChanged();
- updateActionsViewFocusedScroll();
- if (isClearAllHidden() && !mActivity.getDeviceProfile().isTablet) {
- mActionsView.updateDisabledFlags(OverviewActionsView.DISABLED_SCROLLING,
- false);
+ // Grid got messed up, reapply.
+ updateGridProperties(true);
+ if (showAsGrid() && getFocusedTaskView() == null
+ && mActionsView.getVisibilityAlpha().getValue() == 1) {
+ animateActionsViewOut();
}
}
+ // Update the layout synchronously so that the position of next view is
+ // immediately available.
+ onLayout(false /* changed */, getLeft(), getTop(), getRight(), getBottom());
}
- updateCurrentTaskActionsVisibility();
onDismissAnimationEnds();
mPendingAnimation = null;
}
@@ -3320,111 +2479,55 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
return anim;
}
- /**
- * Hides all overview actions if current page is for split apps, shows otherwise
- * If actions are showing, we only show split option if
- * * Device is large screen
- * * There are at least 2 tasks to invoke split
- */
- private void updateCurrentTaskActionsVisibility() {
- boolean isCurrentSplit = getCurrentPageTaskView() instanceof GroupedTaskView;
- mActionsView.updateHiddenFlags(HIDDEN_SPLIT_SCREEN, isCurrentSplit);
- if (isCurrentSplit) {
- return;
- }
- mActionsView.setSplitButtonVisible(
- mActivity.getDeviceProfile().isTablet && getTaskViewCount() > 1);
+ private void removeTaskInternal(TaskView taskView) {
+ UI_HELPER_EXECUTOR.getHandler().postDelayed(() ->
+ ActivityManagerWrapper.getInstance().removeTask(
+ taskView.getTask().key.id),
+ REMOVE_TASK_WAIT_FOR_APP_STOP_MS);
}
/**
- * Returns all the tasks in the top row, without the focused task
+ * @return {@code true} if one of the task thumbnails would intersect/overlap with the
+ * {@link #mSplitPlaceholderView}
*/
- private IntArray getTopRowIdArray() {
- if (mTopRowIdSet.isEmpty()) {
- return new IntArray(0);
- }
- IntArray topArray = new IntArray(mTopRowIdSet.size());
- int taskViewCount = getTaskViewCount();
- for (int i = 0; i < taskViewCount; i++) {
- int taskViewId = requireTaskViewAt(i).getTaskViewId();
- if (mTopRowIdSet.contains(taskViewId)) {
- topArray.add(taskViewId);
- }
+ public boolean shouldShiftThumbnailsForSplitSelect(@SplitConfigurationOptions.StagePosition
+ int stagePosition) {
+ if (!mActivity.getDeviceProfile().isTablet) {
+ // Never enough space on phones
+ return true;
+ } else if (!mActivity.getDeviceProfile().isLandscape) {
+ return false;
}
- return topArray;
- }
- /**
- * Returns all the tasks in the bottom row, without the focused task
- */
- private IntArray getBottomRowIdArray() {
- int bottomRowIdArraySize = getBottomRowTaskCountForTablet();
- if (bottomRowIdArraySize <= 0) {
- return new IntArray(0);
- }
- IntArray bottomArray = new IntArray(bottomRowIdArraySize);
- int taskViewCount = getTaskViewCount();
- for (int i = 0; i < taskViewCount; i++) {
- int taskViewId = requireTaskViewAt(i).getTaskViewId();
- if (!mTopRowIdSet.contains(taskViewId) && taskViewId != mFocusedTaskViewId) {
- bottomArray.add(taskViewId);
- }
+ Rect splitBounds = new Rect();
+ float placeholderSize = getResources().getDimension(R.dimen.split_placeholder_size);
+ // This acts as a best approximation on where the splitplaceholder view would be,
+ // doesn't need to be exact necessarily. This also doesn't need to take translations
+ // into account since placeholder view is not translated
+ if (stagePosition == SplitConfigurationOptions.STAGE_POSITION_BOTTOM_OR_RIGHT) {
+ splitBounds.set((int) (getWidth() - placeholderSize), 0, getWidth(), getHeight());
+ } else {
+ splitBounds.set(0, 0, (int) (placeholderSize), getHeight());
}
- return bottomArray;
- }
-
- /**
- * Iterate the grid by columns instead of by TaskView index, starting after the focused task and
- * up to the last balanced column.
- *
- * @return the highest visible TaskView index between both rows
- */
- private int getHighestVisibleTaskIndex() {
- if (mTopRowIdSet.isEmpty()) return Integer.MAX_VALUE; // return earlier
-
- int lastVisibleIndex = Integer.MAX_VALUE;
- IntArray topRowIdArray = getTopRowIdArray();
- IntArray bottomRowIdArray = getBottomRowIdArray();
- int balancedColumns = Math.min(bottomRowIdArray.size(), topRowIdArray.size());
-
- for (int i = 0; i < balancedColumns; i++) {
- TaskView topTask = getTaskViewFromTaskViewId(topRowIdArray.get(i));
-
- if (isTaskViewVisible(topTask)) {
- TaskView bottomTask = getTaskViewFromTaskViewId(bottomRowIdArray.get(i));
- lastVisibleIndex = Math.max(indexOfChild(topTask), indexOfChild(bottomTask));
- } else if (lastVisibleIndex < Integer.MAX_VALUE) {
- break;
+ Rect taskBounds = new Rect();
+ int taskCount = getTaskViewCount();
+ for (int i = 0; i < taskCount; i++) {
+ TaskView taskView = getTaskViewAt(i);
+ if (taskView == mSplitHiddenTaskView && taskView != getFocusedTaskView()) {
+ // Case where the hidden task view would have overlapped w/ placeholder,
+ // but because it's going to hide we don't care
+ // TODO (b/187312247) edge case for thumbnails that are off screen but scroll on
+ continue;
+ }
+ taskView.getBoundsOnScreen(taskBounds);
+ if (Rect.intersects(taskBounds, splitBounds)) {
+ return true;
}
}
-
- return lastVisibleIndex;
- }
-
- private void removeTaskInternal(int dismissedTaskViewId) {
- int[] taskIds = getTaskIdsForTaskViewId(dismissedTaskViewId);
- int primaryTaskId = taskIds[0];
- int secondaryTaskId = taskIds[1];
- UI_HELPER_EXECUTOR.getHandler().postDelayed(
- () -> {
- ActivityManagerWrapper.getInstance().removeTask(primaryTaskId);
- if (secondaryTaskId != -1) {
- ActivityManagerWrapper.getInstance().removeTask(secondaryTaskId);
- }
- },
- REMOVE_TASK_WAIT_FOR_APP_STOP_MS);
- }
-
- /**
- * Returns {@code true} if one of the task thumbnails would intersect/overlap with the
- * {@link #mFirstFloatingTaskView}.
- */
- public boolean shouldShiftThumbnailsForSplitSelect() {
- return !mActivity.getDeviceProfile().isTablet || !mActivity.getDeviceProfile().isLandscape;
+ return false;
}
protected void onDismissAnimationEnds() {
- AccessibilityManagerCompat.sendDismissAnimationEndsEventToTest(getContext());
}
public PendingAnimation createAllTasksDismissAnimation(long duration) {
@@ -3435,7 +2538,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
int count = getTaskViewCount();
for (int i = 0; i < count; i++) {
- addDismissedTaskAnimations(requireTaskViewAt(i), duration, anim);
+ addDismissedTaskAnimations(getTaskViewAt(i), duration, anim);
}
mPendingAnimation = anim;
@@ -3477,7 +2580,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
@UiThread
private void dismissTask(int taskId) {
- TaskView taskView = getTaskViewByTaskId(taskId);
+ TaskView taskView = getTaskView(taskId);
if (taskView == null) {
return;
}
@@ -3486,7 +2589,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
public void dismissTask(TaskView taskView, boolean animateTaskView, boolean removeTask) {
runDismissAnimation(createTaskDismissAnimation(taskView, animateTaskView, removeTask,
- DISMISS_TASK_DURATION, false /* dismissingForSplitSelection*/));
+ DISMISS_TASK_DURATION));
}
@SuppressWarnings("unused")
@@ -3556,12 +2659,9 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
}
alpha = Utilities.boundToRange(alpha, 0, 1);
mContentAlpha = alpha;
- int runningTaskId = getTaskIdsForRunningTaskView()[0];
for (int i = getTaskViewCount() - 1; i >= 0; i--) {
- TaskView child = requireTaskViewAt(i);
- int[] childTaskIds = child.getTaskIds();
- if (!mRunningTaskTileHidden ||
- (childTaskIds[0] != runningTaskId && childTaskIds[1] != runningTaskId)) {
+ TaskView child = getTaskViewAt(i);
+ if (!mRunningTaskTileHidden || child.getTask().key.id != mRunningTaskId) {
child.setStableAlpha(alpha);
}
}
@@ -3606,7 +2706,6 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
protected void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
updateRecentsRotation();
- onOrientationChanged();
}
/**
@@ -3633,22 +2732,22 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
@Nullable
public TaskView getNextTaskView() {
- return getTaskViewAt(getRunningTaskIndex() + 1);
+ return getTaskViewAtByAbsoluteIndex(getRunningTaskIndex() + 1);
}
@Nullable
public TaskView getCurrentPageTaskView() {
- return getTaskViewAt(getCurrentPage());
+ return getTaskViewAtByAbsoluteIndex(getCurrentPage());
}
@Nullable
public TaskView getNextPageTaskView() {
- return getTaskViewAt(getNextPage());
+ return getTaskViewAtByAbsoluteIndex(getNextPage());
}
@Nullable
public TaskView getTaskViewNearestToCenterOfScreen() {
- return getTaskViewAt(getPageNearestToCenterOfScreen());
+ return getTaskViewAtByAbsoluteIndex(getPageNearestToCenterOfScreen());
}
/**
@@ -3656,16 +2755,16 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
*/
@Nullable
public TaskView getTaskViewAt(int index) {
- View child = getChildAt(index);
- return child instanceof TaskView ? (TaskView) child : null;
+ return getTaskViewAtByAbsoluteIndex(index + mTaskViewStartIndex);
}
- /**
- * A version of {@link #getTaskViewAt} when the caller is sure about the input index.
- */
- @NonNull
- private TaskView requireTaskViewAt(int index) {
- return Objects.requireNonNull(getTaskViewAt(index));
+ @Nullable
+ private TaskView getTaskViewAtByAbsoluteIndex(int index) {
+ if (index < getChildCount() && index >= 0) {
+ View child = getChildAt(index);
+ return child instanceof TaskView ? (TaskView) child : null;
+ }
+ return null;
}
public void setOnEmptyMessageUpdatedListener(OnEmptyMessageUpdatedListener listener) {
@@ -3691,51 +2790,31 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
- // If we're going to a state without overview panel, avoid unnecessary onLayout that
- // cause TaskViews to re-arrange during animation to that state.
- if (!mOverviewStateEnabled && !mFirstLayout) {
- return;
- }
-
- mShowAsGridLastOnLayout = showAsGrid();
-
super.onLayout(changed, left, top, right, bottom);
updateEmptyStateUi(changed);
// Update the pivots such that when the task is scaled, it fills the full page
getTaskSize(mTempRect);
- updatePivots();
+ getPagedViewOrientedState().getFullScreenScaleAndPivot(mTempRect,
+ mActivity.getDeviceProfile(), mTempPointF);
+ setPivotX(mTempPointF.x);
+ setPivotY(mTempPointF.y);
setTaskModalness(mTaskModalness);
mLastComputedTaskStartPushOutDistance = null;
mLastComputedTaskEndPushOutDistance = null;
updatePageOffsets();
- runActionOnRemoteHandles(
- remoteTargetHandle -> remoteTargetHandle.getTaskViewSimulator()
- .setScroll(getScrollOffset()));
setImportantForAccessibility(isModal() ? IMPORTANT_FOR_ACCESSIBILITY_NO
: IMPORTANT_FOR_ACCESSIBILITY_AUTO);
}
- private void updatePivots() {
- if (mOverviewSelectEnabled) {
- setPivotX(mLastComputedTaskSize.centerX());
- setPivotY(mLastComputedTaskSize.bottom);
- } else {
- getPagedViewOrientedState().getFullScreenScaleAndPivot(mTempRect,
- mActivity.getDeviceProfile(), mTempPointF);
- setPivotX(mTempPointF.x);
- setPivotY(mTempPointF.y);
- }
- }
-
private void updatePageOffsets() {
float offset = mAdjacentPageHorizontalOffset;
float modalOffset = ACCEL_0_75.getInterpolation(mTaskModalness);
int count = getChildCount();
- TaskView runningTask = mRunningTaskViewId == -1 || !mRunningTaskTileHidden
- ? null : getRunningTaskView();
+ TaskView runningTask = mRunningTaskId == -1 || !mRunningTaskTileHidden
+ ? null : getTaskView(mRunningTaskId);
int midpoint = runningTask == null ? -1 : indexOfChild(runningTask);
int modalMidpoint = getCurrentPage();
@@ -3788,9 +2867,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
translationProperty.set(child, totalTranslation);
if (ENABLE_QUICKSTEP_LIVE_TILE.get() && mEnableDrawingLiveTile
&& i == getRunningTaskIndex()) {
- runActionOnRemoteHandles(
- remoteTargetHandle -> remoteTargetHandle.getTaskViewSimulator()
- .taskPrimaryTranslation.value = totalTranslation);
+ mLiveTileTaskViewSimulator.taskPrimaryTranslation.value = totalTranslation;
redrawLiveTile();
}
}
@@ -3809,12 +2886,6 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
outRect.offset(taskView.getPersistentTranslationX(),
taskView.getPersistentTranslationY());
outRect.top += mActivity.getDeviceProfile().overviewTaskThumbnailTopMarginPx;
-
- mTempMatrix.reset();
- float persistentScale = taskView.getPersistentScale();
- mTempMatrix.postScale(persistentScale, persistentScale,
- mIsRtl ? outRect.right : outRect.left, outRect.top);
- mTempMatrix.mapRect(outRect);
}
outRect.offset(mOrientationHandler.getPrimaryValue(-midPointScroll, 0),
mOrientationHandler.getSecondaryValue(-midPointScroll, 0));
@@ -3839,11 +2910,8 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
boolean isStartShift;
if (midpointIndex > -1) {
// When there is a midpoint reference task, adjacent tasks have less distance to travel
- // to reach offscreen. Offset the task position to the task's starting point, and offset
- // by current page's scroll diff.
- int midpointScroll = getScrollForPage(midpointIndex)
- + mOrientationHandler.getPrimaryScroll(this) - getScrollForPage(mCurrentPage);
-
+ // to reach offscreen. Offset the task position to the task's starting point.
+ int midpointScroll = getScrollForPage(midpointIndex);
getPersistentChildPosition(midpointIndex, midpointScroll, taskPosition);
float midpointStart = mOrientationHandler.getStart(taskPosition);
@@ -3893,24 +2961,16 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
protected void setTaskViewsResistanceTranslation(float translation) {
mTaskViewsSecondaryTranslation = translation;
for (int i = 0; i < getTaskViewCount(); i++) {
- TaskView task = requireTaskViewAt(i);
+ TaskView task = getTaskViewAt(i);
task.getTaskResistanceTranslationProperty().set(task, translation / getScaleY());
}
- runActionOnRemoteHandles(
- remoteTargetHandle -> remoteTargetHandle.getTaskViewSimulator()
- .recentsViewSecondaryTranslation.value = translation);
- }
-
- private void updateTaskViewsSnapshotRadius() {
- for (int i = 0; i < getTaskViewCount(); i++) {
- requireTaskViewAt(i).updateSnapshotRadius();
- }
+ mLiveTileTaskViewSimulator.recentsViewSecondaryTranslation.value = translation;
}
protected void setTaskViewsPrimarySplitTranslation(float translation) {
mTaskViewsPrimarySplitTranslation = translation;
for (int i = 0; i < getTaskViewCount(); i++) {
- TaskView task = requireTaskViewAt(i);
+ TaskView task = getTaskViewAt(i);
task.getPrimarySplitTranslationProperty().set(task, translation);
}
}
@@ -3918,74 +2978,12 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
protected void setTaskViewsSecondarySplitTranslation(float translation) {
mTaskViewsSecondarySplitTranslation = translation;
for (int i = 0; i < getTaskViewCount(); i++) {
- TaskView taskView = requireTaskViewAt(i);
- if (taskView == mSplitHiddenTaskView) {
- continue;
- }
- taskView.getSecondarySplitTranslationProperty().set(taskView, translation);
+ TaskView task = getTaskViewAt(i);
+ task.getSecondarySplitTranslationProperty().set(task, translation);
}
}
/**
- * Apply scroll offset to children of RecentsView when entering split select.
- */
- public void applySplitPrimaryScrollOffset() {
- float taskSplitScrollOffsetPrimary = 0f;
- float clearAllSplitScrollOffsetPrimar = 0f;
- if (isSplitPlaceholderFirstInGrid()) {
- taskSplitScrollOffsetPrimary = mIsRtl ? mSplitPlaceholderSize : -mSplitPlaceholderSize;
- } else if (isSplitPlaceholderLastInGrid()) {
- clearAllSplitScrollOffsetPrimar =
- mIsRtl ? -mSplitPlaceholderSize : mSplitPlaceholderSize;
- }
-
- for (int i = 0; i < getTaskViewCount(); i++) {
- requireTaskViewAt(i).setSplitScrollOffsetPrimary(taskSplitScrollOffsetPrimary);
- }
- mClearAllButton.setSplitSelectScrollOffsetPrimary(clearAllSplitScrollOffsetPrimar);
- }
-
- /**
- * Returns if split placeholder is at the beginning of RecentsView. Always returns {@code false}
- * if RecentsView is in portrait or RecentsView isn't shown as grid.
- */
- private boolean isSplitPlaceholderFirstInGrid() {
- if (!mActivity.getDeviceProfile().isLandscape || !showAsGrid()
- || !isSplitSelectionActive()) {
- return false;
- }
- @StagePosition int position = mSplitSelectStateController.getActiveSplitStagePosition();
- return mIsRtl
- ? position == STAGE_POSITION_BOTTOM_OR_RIGHT
- : position == STAGE_POSITION_TOP_OR_LEFT;
- }
-
- /**
- * Returns if split placeholder is at the end of RecentsView. Always returns {@code false} if
- * RecentsView is in portrait or RecentsView isn't shown as grid.
- */
- private boolean isSplitPlaceholderLastInGrid() {
- if (!mActivity.getDeviceProfile().isLandscape || !showAsGrid()
- || !isSplitSelectionActive()) {
- return false;
- }
- @StagePosition int position = mSplitSelectStateController.getActiveSplitStagePosition();
- return mIsRtl
- ? position == STAGE_POSITION_TOP_OR_LEFT
- : position == STAGE_POSITION_BOTTOM_OR_RIGHT;
- }
-
- /**
- * Reset scroll offset on children of RecentsView when exiting split select.
- */
- public void resetSplitPrimaryScrollOffset() {
- for (int i = 0; i < getTaskViewCount(); i++) {
- requireTaskViewAt(i).setSplitScrollOffsetPrimary(0);
- }
- mClearAllButton.setSplitSelectScrollOffsetPrimary(0);
- }
-
- /**
* Resets the visuals when exit modal state.
*/
public void resetModalVisuals() {
@@ -3995,127 +2993,134 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
}
}
- public void initiateSplitSelect(TaskView taskView) {
- int defaultSplitPosition = mOrientationHandler
- .getDefaultSplitPosition(mActivity.getDeviceProfile());
- initiateSplitSelect(taskView, defaultSplitPosition);
- }
-
- public void initiateSplitSelect(TaskView taskView, @StagePosition int stagePosition) {
+ public void initiateSplitSelect(TaskView taskView, SplitPositionOption splitPositionOption) {
mSplitHiddenTaskView = taskView;
- mSplitSelectStateController.setInitialTaskSelect(taskView.getTask().key.id,
- stagePosition);
+ SplitSelectStateController splitController = mSplitPlaceholderView.getSplitController();
+ Rect initialBounds = new Rect(taskView.getLeft(), taskView.getTop(), taskView.getRight(),
+ taskView.getBottom());
+ splitController.setInitialTaskSelect(taskView, splitPositionOption, initialBounds);
mSplitHiddenTaskViewIndex = indexOfChild(taskView);
- if (ENABLE_QUICKSTEP_LIVE_TILE.get()) {
- finishRecentsAnimation(true, null);
- }
+ mSplitPlaceholderView.setLayoutParams(
+ splitController.getLayoutParamsForActivePosition(getResources(),
+ mActivity.getDeviceProfile()));
+ mSplitPlaceholderView.setIcon(taskView.getIconView());
}
- public void initiateSplitSelect(QuickstepSystemShortcut.SplitSelectSource splitSelectSource) {
- mSplitSelectSource = splitSelectSource;
- mSplitSelectStateController.setInitialTaskSelect(splitSelectSource.intent,
- splitSelectSource.position.stagePosition);
+ public PendingAnimation createSplitSelectInitAnimation() {
+ int duration = mActivity.getStateManager().getState().getTransitionDuration(getContext());
+ return createTaskDismissAnimation(mSplitHiddenTaskView, true, false, duration);
}
- public PendingAnimation createSplitSelectInitAnimation(int duration) {
- if (mSplitHiddenTaskView != null) {
- return createTaskDismissAnimation(mSplitHiddenTaskView, true, false, duration,
- true /* dismissingForSplitSelection*/);
- } else {
- PendingAnimation anim = new PendingAnimation(duration);
- createInitialSplitSelectAnimation(anim);
- return anim;
- }
+ public void confirmSplitSelect(TaskView taskView) {
+ mSplitPlaceholderView.getSplitController().setSecondTaskId(taskView);
+ resetTaskVisuals();
+ setTranslationY(0);
}
- /**
- * Confirms the selection of the next split task. The extra data is passed through because the
- * user may be selecting a subtask in a group.
- *
- * @return true if waiting for confirmation of second app or if split animations are running,
- * false otherwise
- */
- public boolean confirmSplitSelect(TaskView containerTaskView, Task task, IconView iconView,
- TaskThumbnailView thumbnailView) {
- if (canLaunchFullscreenTask()) {
- return false;
- }
- if (mSplitSelectStateController.isBothSplitAppsConfirmed()) {
- return true;
- }
- mSplitToast.cancel();
- if (!task.isDockable) {
- // Task not split screen supported
- mSplitUnsupportedToast.show();
- return true;
- }
- mSplitSelectStateController.setSecondTask(task);
- RectF secondTaskStartingBounds = new RectF();
- Rect secondTaskEndingBounds = new Rect();
- // TODO(194414938) starting bounds seem slightly off, investigate
- Rect firstTaskStartingBounds = new Rect();
- Rect firstTaskEndingBounds = mTempRect;
- int duration = mActivity.getStateManager().getState().getTransitionDuration(mActivity,
- false /* isToState */);
- PendingAnimation pendingAnimation = new PendingAnimation(duration);
-
- int halfDividerSize = getResources()
- .getDimensionPixelSize(R.dimen.multi_window_task_divider_size) / 2;
- mOrientationHandler.getFinalSplitPlaceholderBounds(halfDividerSize,
- mActivity.getDeviceProfile(),
- mSplitSelectStateController.getActiveSplitStagePosition(), firstTaskEndingBounds,
- secondTaskEndingBounds);
-
- mFirstFloatingTaskView.getBoundsOnScreen(firstTaskStartingBounds);
- mFirstFloatingTaskView.addAnimation(pendingAnimation,
- new RectF(firstTaskStartingBounds), firstTaskEndingBounds,
- false /* fadeWithThumbnail */, true /* isStagedTask */);
-
- mSecondFloatingTaskView = FloatingTaskView.getFloatingTaskView(mActivity,
- thumbnailView, thumbnailView.getThumbnail(),
- iconView.getDrawable(), secondTaskStartingBounds);
- mSecondFloatingTaskView.setAlpha(1);
- mSecondFloatingTaskView.addAnimation(pendingAnimation, secondTaskStartingBounds,
- secondTaskEndingBounds, true /* fadeWithThumbnail */, false /* isStagedTask */);
- pendingAnimation.addEndListener(aBoolean -> {
- mSplitSelectStateController.launchSplitTasks(
- aBoolean1 -> RecentsView.this.resetFromSplitSelectionState());
- InteractionJankMonitorWrapper.end(InteractionJankMonitorWrapper.CUJ_SPLIT_SCREEN_ENTER);
- });
- if (containerTaskView.containsMultipleTasks()) {
- // If we are launching from a child task, then only hide the thumbnail itself
- mSecondSplitHiddenView = thumbnailView;
- } else {
- mSecondSplitHiddenView = containerTaskView;
+ public PendingAnimation cancelSplitSelect(boolean animate) {
+ SplitSelectStateController splitController = mSplitPlaceholderView.getSplitController();
+ SplitPositionOption splitOption = splitController.getActiveSplitPositionOption();
+ Rect initialBounds = splitController.getInitialBounds();
+ splitController.resetState();
+ int duration = mActivity.getStateManager().getState().getTransitionDuration(getContext());
+ PendingAnimation pendingAnim = new PendingAnimation(duration);
+ if (!animate) {
+ resetFromSplitSelectionState();
+ return pendingAnim;
}
- mSecondSplitHiddenView.setVisibility(INVISIBLE);
- InteractionJankMonitorWrapper.begin(this,
- InteractionJankMonitorWrapper.CUJ_SPLIT_SCREEN_ENTER, "Second tile selected");
- pendingAnimation.buildAnim().start();
- return true;
- }
- /** TODO(b/181707736) More gracefully handle exiting split selection state */
- @SuppressLint("WrongCall")
- protected void resetFromSplitSelectionState() {
- if (mSplitSelectSource != null || mSplitHiddenTaskViewIndex != -1) {
- if (mFirstFloatingTaskView != null) {
- mActivity.getRootView().removeView(mFirstFloatingTaskView);
- mFirstFloatingTaskView = null;
- }
- if (mSecondFloatingTaskView != null) {
- mActivity.getRootView().removeView(mSecondFloatingTaskView);
- mSecondFloatingTaskView = null;
- mSecondSplitHiddenView.setVisibility(VISIBLE);
- mSecondSplitHiddenView = null;
+ addViewInLayout(mSplitHiddenTaskView, mSplitHiddenTaskViewIndex,
+ mSplitHiddenTaskView.getLayoutParams());
+ mSplitHiddenTaskView.setAlpha(0);
+ int[] oldScroll = new int[getChildCount()];
+ getPageScrolls(oldScroll, false,
+ view -> view.getVisibility() != GONE && view != mSplitHiddenTaskView);
+
+ int[] newScroll = new int[getChildCount()];
+ getPageScrolls(newScroll, false, SIMPLE_SCROLL_LOGIC);
+
+ boolean needsCurveUpdates = false;
+ for (int i = mSplitHiddenTaskViewIndex; i >= 0; i--) {
+ View child = getChildAt(i);
+ if (child == mSplitHiddenTaskView) {
+ TaskView taskView = (TaskView) child;
+
+ int dir = mOrientationHandler.getSplitTaskViewDismissDirection(splitOption,
+ mActivity.getDeviceProfile());
+ FloatProperty<TaskView> dismissingTaskViewTranslate;
+ Rect hiddenBounds = new Rect(taskView.getLeft(), taskView.getTop(),
+ taskView.getRight(), taskView.getBottom());
+ int distanceDelta = 0;
+ if (dir == PagedOrientationHandler.SPLIT_TRANSLATE_SECONDARY_NEGATIVE) {
+ dismissingTaskViewTranslate = taskView
+ .getSecondaryDissmissTranslationProperty();
+ distanceDelta = initialBounds.top - hiddenBounds.top;
+ taskView.layout(initialBounds.left, hiddenBounds.top, initialBounds.right,
+ hiddenBounds.bottom);
+ } else {
+ dismissingTaskViewTranslate = taskView
+ .getPrimaryDismissTranslationProperty();
+ distanceDelta = initialBounds.left - hiddenBounds.left;
+ taskView.layout(hiddenBounds.left, initialBounds.top, hiddenBounds.right,
+ initialBounds.bottom);
+ if (dir == PagedOrientationHandler.SPLIT_TRANSLATE_PRIMARY_POSITIVE) {
+ distanceDelta *= -1;
+ }
+ }
+ pendingAnim.add(ObjectAnimator.ofFloat(mSplitHiddenTaskView,
+ dismissingTaskViewTranslate,
+ distanceDelta));
+ pendingAnim.add(ObjectAnimator.ofFloat(mSplitHiddenTaskView, ALPHA, 1));
+ } else {
+ // If insertion is on last index (furthest from clear all), we directly add the view
+ // else we translate all views to the right of insertion index further right,
+ // ignore views to left
+ if (showAsGrid()) {
+ // TODO(b/186800707) handle more elegantly for grid
+ continue;
+ }
+ int scrollDiff = newScroll[i] - oldScroll[i];
+ if (scrollDiff != 0) {
+ FloatProperty translationProperty = child instanceof TaskView
+ ? ((TaskView) child).getPrimaryDismissTranslationProperty()
+ : mOrientationHandler.getPrimaryViewTranslate();
+
+ ResourceProvider rp = DynamicResource.provider(mActivity);
+ SpringProperty sp = new SpringProperty(SpringProperty.FLAG_CAN_SPRING_ON_END)
+ .setDampingRatio(
+ rp.getFloat(R.dimen.dismiss_task_trans_x_damping_ratio))
+ .setStiffness(rp.getFloat(R.dimen.dismiss_task_trans_x_stiffness));
+ pendingAnim.add(ObjectAnimator.ofFloat(child, translationProperty, scrollDiff)
+ .setDuration(duration), ACCEL, sp);
+ needsCurveUpdates = true;
+ }
}
- mSplitSelectSource = null;
}
- if (mSplitHiddenTaskViewIndex == -1) {
- return;
+ if (needsCurveUpdates) {
+ pendingAnim.addOnFrameCallback(this::updateCurveProperties);
}
- if (!mActivity.getDeviceProfile().isTablet) {
+
+ pendingAnim.addListener(new AnimationSuccessListener() {
+ @Override
+ public void onAnimationSuccess(Animator animator) {
+ // TODO(b/186800707) Figure out how to undo for grid view
+ // Need to handle cases where dismissed task is
+ // * Top Row
+ // * Bottom Row
+ // * Focused Task
+ updateGridProperties();
+ resetFromSplitSelectionState();
+ }
+ });
+
+ return pendingAnim;
+ }
+
+ private void resetFromSplitSelectionState() {
+ mSplitHiddenTaskView.setTranslationY(0);
+ if (!showAsGrid()) {
+ // TODO(b/186800707)
int pageToSnapTo = mCurrentPage;
if (mSplitHiddenTaskViewIndex <= pageToSnapTo) {
pageToSnapTo += 1;
@@ -4126,45 +3131,8 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
}
onLayout(false /* changed */, getLeft(), getTop(), getRight(), getBottom());
resetTaskVisuals();
+ mSplitHiddenTaskView = null;
mSplitHiddenTaskViewIndex = -1;
- if (mSplitHiddenTaskView != null) {
- mSplitHiddenTaskView.setVisibility(VISIBLE);
- mSplitHiddenTaskView = null;
- }
- }
-
- /**
- * Returns how much additional translation there should be for each of the child TaskViews.
- * Note that the translation can be its primary or secondary dimension.
- */
- public float getSplitSelectTranslation() {
- int splitPosition = getSplitPlaceholder().getActiveSplitStagePosition();
- if (!shouldShiftThumbnailsForSplitSelect()) {
- return 0f;
- }
- PagedOrientationHandler orientationHandler = getPagedOrientationHandler();
- int direction = orientationHandler.getSplitTranslationDirectionFactor(
- splitPosition, mActivity.getDeviceProfile());
- return mActivity.getResources().getDimension(R.dimen.split_placeholder_size) * direction;
- }
-
- protected void onRotateInSplitSelectionState() {
- mOrientationHandler.getInitialSplitPlaceholderBounds(mSplitPlaceholderSize,
- mSplitPlaceholderInset, mActivity.getDeviceProfile(),
- mSplitSelectStateController.getActiveSplitStagePosition(), mTempRect);
- mTempRectF.set(mTempRect);
- mFirstFloatingTaskView.updateOrientationHandler(mOrientationHandler);
- mFirstFloatingTaskView.update(mTempRectF, /*progress=*/1f);
-
- PagedOrientationHandler orientationHandler = getPagedOrientationHandler();
- Pair<FloatProperty, FloatProperty> taskViewsFloat =
- orientationHandler.getSplitSelectTaskOffset(
- TASK_PRIMARY_SPLIT_TRANSLATION, TASK_SECONDARY_SPLIT_TRANSLATION,
- mActivity.getDeviceProfile());
- taskViewsFloat.first.set(this, getSplitSelectTranslation());
- taskViewsFloat.second.set(this, 0f);
-
- applySplitPrimaryScrollOffset();
}
private void updateDeadZoneRects() {
@@ -4181,8 +3149,8 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
mTaskViewDeadZoneRect.setEmpty();
int count = getTaskViewCount();
if (count > 0) {
- final View taskView = requireTaskViewAt(0);
- requireTaskViewAt(count - 1).getHitRect(mTaskViewDeadZoneRect);
+ final View taskView = getTaskViewAt(0);
+ getTaskViewAt(count - 1).getHitRect(mTaskViewDeadZoneRect);
mTaskViewDeadZoneRect.union(taskView.getLeft(), taskView.getTop(), taskView.getRight(),
taskView.getBottom());
}
@@ -4257,16 +3225,12 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
anim.play(ObjectAnimator.ofFloat(getPageAt(centerTaskIndex),
mOrientationHandler.getPrimaryViewTranslate(), primaryTranslation));
int runningTaskIndex = recentsView.getRunningTaskIndex();
- if (ENABLE_QUICKSTEP_LIVE_TILE.get()
- && runningTaskIndex != -1
- && runningTaskIndex != taskIndex
- && recentsView.getRemoteTargetHandles() != null) {
- for (RemoteTargetHandle remoteHandle : recentsView.getRemoteTargetHandles()) {
- anim.play(ObjectAnimator.ofFloat(
- remoteHandle.getTaskViewSimulator().taskPrimaryTranslation,
- AnimatedFloat.VALUE,
- primaryTranslation));
- }
+ if (ENABLE_QUICKSTEP_LIVE_TILE.get() && runningTaskIndex != -1
+ && runningTaskIndex != taskIndex) {
+ anim.play(ObjectAnimator.ofFloat(
+ recentsView.getLiveTileTaskViewSimulator().taskPrimaryTranslation,
+ AnimatedFloat.VALUE,
+ primaryTranslation));
}
int otherAdjacentTaskIndex = centerTaskIndex + (centerTaskIndex - taskIndex);
@@ -4346,22 +3310,11 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
mPendingAnimation = new PendingAnimation(duration);
mPendingAnimation.add(anim);
if (ENABLE_QUICKSTEP_LIVE_TILE.get()) {
- runActionOnRemoteHandles(
- remoteTargetHandle -> remoteTargetHandle.getTaskViewSimulator()
- .addOverviewToAppAnim(mPendingAnimation, interpolator));
+ mLiveTileTaskViewSimulator.addOverviewToAppAnim(mPendingAnimation, interpolator);
mPendingAnimation.addOnFrameCallback(this::redrawLiveTile);
}
mPendingAnimation.addEndListener(isSuccess -> {
if (isSuccess) {
- if (tv.getTaskIds()[1] != -1 && mRemoteTargetHandles != null) {
- // TODO(b/194414938): make this part of the animations instead.
- TaskViewUtils.createSplitAuxiliarySurfacesAnimator(
- mRemoteTargetHandles[0].getTransformParams().getTargetSet().nonApps,
- true /*shown*/, (dividerAnimator) -> {
- dividerAnimator.start();
- dividerAnimator.end();
- });
- }
if (ENABLE_QUICKSTEP_LIVE_TILE.get() && tv.isRunningTask()) {
finishRecentsAnimation(false /* toRecents */, null);
onTaskLaunchAnimationEnd(true /* success */);
@@ -4390,7 +3343,6 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
@Override
protected void notifyPageSwitchListener(int prevPage) {
super.notifyPageSwitchListener(prevPage);
- updateCurrentTaskActionsVisibility();
loadVisibleTaskData(TaskView.FLAG_UPDATE_ALL);
updateEnabledOverlays();
}
@@ -4449,85 +3401,47 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
}
public void redrawLiveTile() {
- runActionOnRemoteHandles(remoteTargetHandle -> {
- TransformParams params = remoteTargetHandle.getTransformParams();
- if (params.getTargetSet() != null) {
- remoteTargetHandle.getTaskViewSimulator().apply(params);
- }
- });
+ if (mLiveTileParams.getTargetSet() != null) {
+ mLiveTileTaskViewSimulator.apply(mLiveTileParams);
+ }
+ }
+
+ public TaskViewSimulator getLiveTileTaskViewSimulator() {
+ return mLiveTileTaskViewSimulator;
}
- public RemoteTargetHandle[] getRemoteTargetHandles() {
- return mRemoteTargetHandles;
+ public TransformParams getLiveTileParams() {
+ return mLiveTileParams;
}
// TODO: To be removed in a follow up CL
public void setRecentsAnimationTargets(RecentsAnimationController recentsAnimationController,
RecentsAnimationTargets recentsAnimationTargets) {
mRecentsAnimationController = recentsAnimationController;
- mSplitSelectStateController.setRecentsAnimationRunning(true);
- if (recentsAnimationTargets == null || recentsAnimationTargets.apps.length == 0) {
- return;
- }
-
- RemoteTargetGluer gluer = new RemoteTargetGluer(getContext(), getSizeStrategy());
- mRemoteTargetHandles = gluer.assignTargetsForSplitScreen(
- getContext(), recentsAnimationTargets);
- mSplitBoundsConfig = gluer.getStagedSplitBounds();
- // Add release check to the targets from the RemoteTargetGluer and not the targets
- // passed in because in the event we're in split screen, we use the passed in targets
- // to create new RemoteAnimationTargets in assignTargetsForSplitScreen(), and the
- // mSyncTransactionApplier doesn't get transferred over
- runActionOnRemoteHandles(remoteTargetHandle -> {
- final TransformParams params = remoteTargetHandle.getTransformParams();
+ if (recentsAnimationTargets != null && recentsAnimationTargets.apps.length > 0) {
if (mSyncTransactionApplier != null) {
- params.setSyncTransactionApplier(mSyncTransactionApplier);
- params.getTargetSet().addReleaseCheck(mSyncTransactionApplier);
+ recentsAnimationTargets.addReleaseCheck(mSyncTransactionApplier);
}
-
- TaskViewSimulator tvs = remoteTargetHandle.getTaskViewSimulator();
- tvs.setOrientationState(mOrientationState);
- tvs.setDp(mActivity.getDeviceProfile());
- tvs.recentsViewScale.value = 1;
- });
-
- TaskView runningTaskView = getRunningTaskView();
- if (runningTaskView instanceof GroupedTaskView) {
- // We initially create a GroupedTaskView in showCurrentTask() before launcher even
- // receives the leashes for the remote apps, so the mSplitBoundsConfig that gets passed
- // in there is either null or outdated, so we need to update here as soon as we're
- // notified.
- ((GroupedTaskView) runningTaskView).updateSplitBoundsConfig(mSplitBoundsConfig);
- }
- }
-
- /** Helper to avoid writing some for-loops to iterate over {@link #mRemoteTargetHandles} */
- public void runActionOnRemoteHandles(Consumer<RemoteTargetHandle> consumer) {
- if (mRemoteTargetHandles == null) {
- return;
- }
-
- for (RemoteTargetHandle handle : mRemoteTargetHandles) {
- consumer.accept(handle);
+ mLiveTileTaskViewSimulator.setPreview(
+ recentsAnimationTargets.apps[recentsAnimationTargets.apps.length - 1]);
+ mLiveTileParams.setTargetSet(recentsAnimationTargets);
}
}
- /**
- * Finish recents animation.
- */
- public void finishRecentsAnimation(boolean toRecents, @Nullable Runnable onFinishComplete) {
+ public void finishRecentsAnimation(boolean toRecents, Runnable onFinishComplete) {
finishRecentsAnimation(toRecents, true /* shouldPip */, onFinishComplete);
}
public void finishRecentsAnimation(boolean toRecents, boolean shouldPip,
- @Nullable Runnable onFinishComplete) {
- // TODO(b/197232424#comment#10) Move this back into onRecentsAnimationComplete(). Maybe?
- cleanupRemoteTargets();
+ Runnable onFinishComplete) {
if (!toRecents && ENABLE_QUICKSTEP_LIVE_TILE.get()) {
// Reset the minimized state since we force-toggled the minimized state when entering
// overview, but never actually finished the recents animation. This is a catch all for
// cases where we haven't already reset it.
- SystemUiProxy.INSTANCE.get(getContext()).setSplitScreenMinimized(false);
+ SystemUiProxy p = SystemUiProxy.INSTANCE.getNoCreate();
+ if (p != null) {
+ p.setSplitScreenMinimized(false);
+ }
}
if (mRecentsAnimationController == null) {
@@ -4543,17 +3457,6 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
final SystemUiProxy systemUiProxy = SystemUiProxy.INSTANCE.get(getContext());
systemUiProxy.notifySwipeToHomeFinished();
systemUiProxy.setShelfHeight(true, mActivity.getDeviceProfile().hotseatBarSizePx);
- // Transaction to hide the task to avoid flicker for entering PiP from split-screen.
- // See also {@link AbsSwipeUpHandler#maybeFinishSwipeToHome}.
- PictureInPictureSurfaceTransaction tx =
- new PictureInPictureSurfaceTransaction.Builder()
- .setAlpha(0f)
- .build();
- int[] taskIds = TopTaskTracker.INSTANCE.get(getContext()).getRunningSplitTaskIds();
- for (int taskId : taskIds) {
- mRecentsAnimationController.setFinishTaskTransaction(taskId,
- tx, null /* overlay */);
- }
}
mRecentsAnimationController.finish(toRecents, () -> {
if (onFinishComplete != null) {
@@ -4577,7 +3480,6 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
// taps on QSB (3) user goes back to Overview and launch the most recent task.
setCurrentTask(-1);
mRecentsAnimationController = null;
- mSplitSelectStateController.setRecentsAnimationRunning(false);
executeSideTaskLaunchCallback();
}
@@ -4589,69 +3491,45 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
}
/**
- * Updates page scroll synchronously after measure and layout child views.
+ * Updates page scroll synchronously and layout child views.
*/
- @SuppressLint("WrongCall")
public void updateScrollSynchronously() {
- // onMeasure is needed to update child's measured width which is used in scroll calculation,
- // in case TaskView sizes has changed when being focused/unfocused.
- onMeasure(makeMeasureSpec(getMeasuredWidth(), EXACTLY),
- makeMeasureSpec(getMeasuredHeight(), EXACTLY));
onLayout(false /* changed */, getLeft(), getTop(), getRight(), getBottom());
updateMinAndMaxScrollX();
}
@Override
- protected int getChildGap(int fromIndex, int toIndex) {
- int clearAllIndex = indexOfChild(mClearAllButton);
- return fromIndex == clearAllIndex || toIndex == clearAllIndex
- ? getClearAllExtraPageSpacing() : 0;
- }
-
- protected int getClearAllExtraPageSpacing() {
- return showAsGrid()
- ? Math.max(mActivity.getDeviceProfile().overviewGridSideMargin - mPageSpacing, 0)
- : 0;
- }
-
- @Override
- protected void updateMinAndMaxScrollX() {
- super.updateMinAndMaxScrollX();
- if (DEBUG) {
- Log.d(TAG, "updateMinAndMaxScrollX - mMinScroll: " + mMinScroll);
- Log.d(TAG, "updateMinAndMaxScrollX - mMaxScroll: " + mMaxScroll);
- }
- }
-
- @Override
protected int computeMinScroll() {
- if (getTaskViewCount() <= 0) {
- return super.computeMinScroll();
+ if (getTaskViewCount() > 0) {
+ if (mIsRtl) {
+ // If we aren't showing the clear all button, use the rightmost task as the min
+ // scroll.
+ return getScrollForPage(mDisallowScrollToClearAll ? indexOfChild(
+ getTaskViewAt(getTaskViewCount() - 1)) : indexOfChild(mClearAllButton));
+ } else {
+ TaskView focusedTaskView = showAsGrid() ? getFocusedTaskView() : null;
+ return getScrollForPage(focusedTaskView != null ? indexOfChild(focusedTaskView)
+ : mTaskViewStartIndex);
+ }
}
-
- return getScrollForPage(mIsRtl ? getLastViewIndex() : getFirstViewIndex());
+ return super.computeMinScroll();
}
@Override
protected int computeMaxScroll() {
- if (getTaskViewCount() <= 0) {
- return super.computeMaxScroll();
+ if (getTaskViewCount() > 0) {
+ if (mIsRtl) {
+ TaskView focusedTaskView = showAsGrid() ? getFocusedTaskView() : null;
+ return getScrollForPage(focusedTaskView != null ? indexOfChild(focusedTaskView)
+ : mTaskViewStartIndex);
+ } else {
+ // If we aren't showing the clear all button, use the leftmost task as the min
+ // scroll.
+ return getScrollForPage(mDisallowScrollToClearAll ? indexOfChild(
+ getTaskViewAt(getTaskViewCount() - 1)) : indexOfChild(mClearAllButton));
+ }
}
-
- return getScrollForPage(mIsRtl ? getFirstViewIndex() : getLastViewIndex());
- }
-
- private int getFirstViewIndex() {
- TaskView focusedTaskView = mShowAsGridLastOnLayout ? getFocusedTaskView() : null;
- return focusedTaskView != null ? indexOfChild(focusedTaskView) : 0;
- }
-
- private int getLastViewIndex() {
- return mDisallowScrollToClearAll
- ? mShowAsGridLastOnLayout
- ? indexOfChild(getLastGridTaskView())
- : getTaskViewCount() - 1
- : indexOfChild(mClearAllButton);
+ return super.computeMaxScroll();
}
/**
@@ -4678,39 +3556,22 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
}
boolean pageScrollChanged = false;
-
- int clearAllIndex = indexOfChild(mClearAllButton);
- int clearAllScroll = 0;
- int clearAllWidth = mOrientationHandler.getPrimarySize(mClearAllButton);
- if (clearAllIndex != -1 && clearAllIndex < outPageScrolls.length) {
- float scrollDiff = mClearAllButton.getScrollAdjustment(showAsFullscreen, showAsGrid);
- clearAllScroll = newPageScrolls[clearAllIndex] + (int) scrollDiff;
- if (outPageScrolls[clearAllIndex] != clearAllScroll) {
- pageScrollChanged = true;
- outPageScrolls[clearAllIndex] = clearAllScroll;
+ final int childCount = getChildCount();
+ for (int i = 0; i < childCount; i++) {
+ View child = getChildAt(i);
+ float scrollDiff = 0;
+ if (child instanceof TaskView) {
+ scrollDiff = ((TaskView) child).getScrollAdjustment(showAsFullscreen, showAsGrid);
+ } else if (child instanceof ClearAllButton) {
+ scrollDiff = ((ClearAllButton) child).getScrollAdjustment(showAsFullscreen,
+ showAsGrid);
}
- }
- final int taskCount = getTaskViewCount();
- for (int i = 0; i < taskCount; i++) {
- TaskView taskView = requireTaskViewAt(i);
- float scrollDiff = taskView.getScrollAdjustment(showAsFullscreen, showAsGrid);
- int pageScroll = newPageScrolls[i] + (int) scrollDiff;
- int lastTaskScroll = getLastTaskScroll(clearAllScroll, clearAllWidth);
- if ((mIsRtl && pageScroll < lastTaskScroll)
- || (!mIsRtl && pageScroll > lastTaskScroll)) {
- pageScroll = lastTaskScroll;
- }
+ final int pageScroll = newPageScrolls[i] + (int) scrollDiff;
if (outPageScrolls[i] != pageScroll) {
pageScrollChanged = true;
outPageScrolls[i] = pageScroll;
}
- if (DEBUG) {
- Log.d(TAG, "getPageScrolls - outPageScrolls[" + i + "]: " + outPageScrolls[i]);
- }
- }
- if (DEBUG) {
- Log.d(TAG, "getPageScrolls - clearAllScroll: " + clearAllScroll);
}
return pageScrollChanged;
}
@@ -4731,7 +3592,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
@Override
protected int getChildVisibleSize(int index) {
- final TaskView taskView = getTaskViewAt(index);
+ final TaskView taskView = getTaskViewAtByAbsoluteIndex(index);
if (taskView == null) {
return super.getChildVisibleSize(index);
}
@@ -4766,67 +3627,21 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
overScrollShift, getUndampedOverScrollShift());
}
return getScrollForPage(pageIndex) - mOrientationHandler.getPrimaryScroll(this)
- + overScrollShift + getOffsetFromScrollPosition(pageIndex);
+ + overScrollShift;
}
/**
- * Returns how many pixels the page is offset from its scroll position.
+ * Returns how many pixels the task is offset on the currently laid out secondary axis
+ * according to {@link #mGridProgress}.
*/
- private int getOffsetFromScrollPosition(int pageIndex) {
- return getOffsetFromScrollPosition(pageIndex, getTopRowIdArray(), getBottomRowIdArray());
- }
-
- private int getOffsetFromScrollPosition(
- int pageIndex, IntArray topRowIdArray, IntArray bottomRowIdArray) {
- if (!showAsGrid()) {
- return 0;
- }
-
- TaskView taskView = getTaskViewAt(pageIndex);
+ public float getGridTranslationSecondary(int pageIndex) {
+ TaskView taskView = getTaskViewAtByAbsoluteIndex(pageIndex);
if (taskView == null) {
return 0;
}
- TaskView lastGridTaskView = getLastGridTaskView(topRowIdArray, bottomRowIdArray);
- if (lastGridTaskView == null) {
- return 0;
- }
-
- if (getScrollForPage(pageIndex) != getScrollForPage(indexOfChild(lastGridTaskView))) {
- return 0;
- }
-
- // Check distance from lastGridTaskView to taskView.
- int lastGridTaskViewPosition =
- getPositionInRow(lastGridTaskView, topRowIdArray, bottomRowIdArray);
- int taskViewPosition = getPositionInRow(taskView, topRowIdArray, bottomRowIdArray);
- int gridTaskSizeAndSpacing = mLastComputedGridTaskSize.width() + mPageSpacing;
- int positionDiff = gridTaskSizeAndSpacing * (lastGridTaskViewPosition - taskViewPosition);
-
- int lastTaskEnd = (mIsRtl
- ? mLastComputedGridSize.left
- : mLastComputedGridSize.right)
- + (mIsRtl ? mPageSpacing : -mPageSpacing);
- int taskEnd = lastTaskEnd + (mIsRtl ? positionDiff : -positionDiff);
- int normalTaskEnd = mIsRtl
- ? mLastComputedGridTaskSize.left
- : mLastComputedGridTaskSize.right;
- return taskEnd - normalTaskEnd;
- }
-
- private int getPositionInRow(
- TaskView taskView, IntArray topRowIdArray, IntArray bottomRowIdArray) {
- int position = topRowIdArray.indexOf(taskView.getTaskViewId());
- return position != -1 ? position : bottomRowIdArray.indexOf(taskView.getTaskViewId());
- }
-
- /**
- * @return true if the task in on the top of the grid
- */
- public boolean isOnGridBottomRow(TaskView taskView) {
- return showAsGrid()
- && !mTopRowIdSet.contains(taskView.getTaskViewId())
- && taskView.getTaskViewId() != mFocusedTaskViewId;
+ return mOrientationHandler.getSecondaryValue(taskView.getGridTranslationX(),
+ taskView.getGridTranslationY());
}
public Consumer<MotionEvent> getEventDispatcher(float navbarRotation) {
@@ -4861,8 +3676,8 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
private void updateEnabledOverlays() {
int overlayEnabledPage = mOverlayEnabled ? getNextPage() : -1;
int taskCount = getTaskViewCount();
- for (int i = 0; i < taskCount; i++) {
- requireTaskViewAt(i).setOverlayEnabled(i == overlayEnabledPage);
+ for (int i = mTaskViewStartIndex; i < mTaskViewStartIndex + taskCount; i++) {
+ getTaskViewAtByAbsoluteIndex(i).setOverlayEnabled(i == overlayEnabledPage);
}
}
@@ -4876,7 +3691,6 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
public void setOverviewGridEnabled(boolean overviewGridEnabled) {
if (mOverviewGridEnabled != overviewGridEnabled) {
mOverviewGridEnabled = overviewGridEnabled;
- updateActionsViewFocusedScroll();
// Request layout to ensure scroll position is recalculated with updated mGridProgress.
requestLayout();
}
@@ -4892,17 +3706,6 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
}
/**
- * Update whether RecentsView is in select mode. Should be enabled before transitioning to
- * select mode, and only disabled after transitioning from select mode.
- */
- public void setOverviewSelectEnabled(boolean overviewSelectEnabled) {
- if (mOverviewSelectEnabled != overviewSelectEnabled) {
- mOverviewSelectEnabled = overviewSelectEnabled;
- updatePivots();
- }
- }
-
- /**
* Switch the current running task view to static snapshot mode,
* capturing the snapshot at the same time.
*/
@@ -4913,49 +3716,23 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
}
return;
}
-
- switchToScreenshotInternal(onFinishRunnable);
- }
-
- private void switchToScreenshotInternal(Runnable onFinishRunnable) {
- TaskView taskView = getRunningTaskView();
- if (taskView == null) {
- onFinishRunnable.run();
- return;
- }
-
- taskView.setShowScreenshot(true);
- for (TaskView.TaskIdAttributeContainer container :
- taskView.getTaskIdAttributeContainers()) {
- if (container == null) {
- continue;
- }
-
- ThumbnailData td =
- mRecentsAnimationController.screenshotTask(container.getTask().key.id);
- TaskThumbnailView thumbnailView = container.getThumbnailView();
- if (td != null) {
- thumbnailView.setThumbnail(container.getTask(), td);
- } else {
- thumbnailView.refresh();
- }
- }
- ViewUtils.postFrameDrawn(taskView, onFinishRunnable);
+ switchToScreenshot(mRunningTaskId == -1 ? null
+ : mRecentsAnimationController.screenshotTask(mRunningTaskId), onFinishRunnable);
}
/**
* Switch the current running task view to static snapshot mode, using the
* provided thumbnail data as the snapshot.
- * TODO(b/195609063) Consolidate this method w/ the one above, except this thumbnail data comes
- * from gesture state, which is a larger change of it having to keep track of multiple tasks.
- * OR. Maybe it doesn't need to pass in a thumbnail and we can use the exact same flow as above
*/
- public void switchToScreenshot(@Nullable HashMap<Integer, ThumbnailData> thumbnailDatas,
- Runnable onFinishRunnable) {
- final TaskView taskView = getRunningTaskView();
+ public void switchToScreenshot(ThumbnailData thumbnailData, Runnable onFinishRunnable) {
+ TaskView taskView = getRunningTaskView();
if (taskView != null) {
taskView.setShowScreenshot(true);
- taskView.refreshThumbnails(thumbnailDatas);
+ if (thumbnailData != null) {
+ taskView.getThumbnail().setThumbnail(taskView.getTask(), thumbnailData);
+ } else {
+ taskView.getThumbnail().refresh();
+ }
ViewUtils.postFrameDrawn(taskView, onFinishRunnable);
} else {
onFinishRunnable.run();
@@ -4973,9 +3750,10 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
getCurrentPageTaskView().setModalness(modalness);
}
// Only show actions view when it's modal for in-place landscape mode.
- boolean inPlaceLandscape = !mOrientationState.isRecentsActivityRotationAllowed()
+ boolean inPlaceLandscape = !mOrientationState.canRecentsActivityRotate()
&& mOrientationState.getTouchRotation() != ROTATION_0;
mActionsView.updateHiddenFlags(HIDDEN_NON_ZERO_ROTATION, modalness < 1 && inPlaceLandscape);
+ mActionsView.setTaskModalness(modalness);
}
@Nullable
@@ -5027,7 +3805,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
mColorTint = tintAmount;
for (int i = 0; i < getTaskViewCount(); i++) {
- requireTaskViewAt(i).setColorTint(mColorTint, mTintingColor);
+ getTaskViewAt(i).setColorTint(mColorTint, mTintingColor);
}
Drawable scrimBg = mActivity.getScrimView().getBackground();
@@ -5058,8 +3836,9 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
&& mCurrentGestureEndTarget != GestureState.GestureEndTarget.RECENTS;
}
- public void cleanupRemoteTargets() {
- mRemoteTargetHandles = null;
+ public boolean shouldShowOverviewActionsForState(STATE_TYPE state) {
+ return !state.displayOverviewTasksAsGrid(mActivity.getDeviceProfile())
+ || getFocusedTaskView() != null;
}
/**
@@ -5095,70 +3874,6 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
return mPipCornerRadius;
}
- /**
- * @return Shadow radius in pixel value for PiP window, which is updated via
- * {@link #mIPipAnimationListener}
- */
- public int getPipShadowRadius() {
- return mPipShadowRadius;
- }
-
- @Override
- public boolean scrollLeft() {
- if (!showAsGrid()) {
- return super.scrollLeft();
- }
-
- int targetPage = getNextPage();
- if (targetPage >= 0) {
- // Find the next page that is not fully visible.
- TaskView taskView = getTaskViewAt(targetPage);
- while ((taskView == null || isTaskViewFullyVisible(taskView)) && targetPage - 1 >= 0) {
- taskView = getTaskViewAt(--targetPage);
- }
- // Target a scroll where targetPage is on left of screen but still fully visible.
- int lastTaskEnd = (mIsRtl
- ? mLastComputedGridSize.left
- : mLastComputedGridSize.right)
- + (mIsRtl ? mPageSpacing : -mPageSpacing);
- int normalTaskEnd = mIsRtl
- ? mLastComputedGridTaskSize.left
- : mLastComputedGridTaskSize.right;
- int targetScroll = getScrollForPage(targetPage) + normalTaskEnd - lastTaskEnd;
- // Find a page that is close to targetScroll while not over it.
- while (targetPage - 1 >= 0
- && (mIsRtl
- ? getScrollForPage(targetPage - 1) < targetScroll
- : getScrollForPage(targetPage - 1) > targetScroll)) {
- targetPage--;
- }
- snapToPage(targetPage);
- return true;
- }
-
- return mAllowOverScroll;
- }
-
- @Override
- public boolean scrollRight() {
- if (!showAsGrid()) {
- return super.scrollRight();
- }
-
- int targetPage = getNextPage();
- if (targetPage < getChildCount()) {
- // Find the next page that is not fully visible.
- TaskView taskView = getTaskViewAt(targetPage);
- while ((taskView != null && isTaskViewFullyVisible(taskView))
- && targetPage + 1 < getChildCount()) {
- taskView = getTaskViewAt(++targetPage);
- }
- snapToPage(targetPage);
- return true;
- }
- return mAllowOverScroll;
- }
-
@Override
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
super.onScrollChanged(l, t, oldl, oldt);
@@ -5166,8 +3881,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
}
private void dispatchScrollChanged() {
- runActionOnRemoteHandles(remoteTargetHandle ->
- remoteTargetHandle.getTaskViewSimulator().setScroll(getScrollOffset()));
+ mLiveTileTaskViewSimulator.setScroll(getScrollOffset());
for (int i = mScrollListeners.size() - 1; i >= 0; i--) {
mScrollListeners.get(i).onScrollChanged();
}
@@ -5175,13 +3889,10 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
private static class PinnedStackAnimationListener<T extends BaseActivity> extends
IPipAnimationListener.Stub {
- @Nullable
private T mActivity;
- @Nullable
private RecentsView mRecentsView;
- public void setActivityAndRecentsView(@Nullable T activity,
- @Nullable RecentsView recentsView) {
+ public void setActivityAndRecentsView(T activity, RecentsView recentsView) {
mActivity = activity;
mRecentsView = recentsView;
}
@@ -5198,25 +3909,11 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
}
@Override
- public void onPipResourceDimensionsChanged(int cornerRadius, int shadowRadius) {
+ public void onPipCornerRadiusChanged(int cornerRadius) {
if (mRecentsView != null) {
mRecentsView.mPipCornerRadius = cornerRadius;
- mRecentsView.mPipShadowRadius = shadowRadius;
}
}
-
- @Override
- public void onExpandPip() {
- MAIN_EXECUTOR.execute(() -> {
- if (mRecentsView == null
- || mRecentsView.mSizeStrategy.getTaskbarController() == null) {
- return;
- }
- // Hide the task bar when leaving PiP to prevent it from flickering once
- // the app settles in full-screen mode.
- mRecentsView.mSizeStrategy.getTaskbarController().onExpandPip();
- });
- }
}
/** Get the color used for foreground scrimming the RecentsView for sharing. */
@@ -5246,8 +3943,4 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
// Set locus context is a binder call, don't want it to happen during a transition
UI_HELPER_EXECUTOR.post(() -> mActivity.setLocusContext(id, Bundle.EMPTY));
}
-
- public interface TaskLaunchListener {
- void onTaskLaunched();
- }
}
diff --git a/quickstep/src/com/android/quickstep/views/SplitPlaceholderView.java b/quickstep/src/com/android/quickstep/views/SplitPlaceholderView.java
index 28080d477f..bb8bc11e4a 100644
--- a/quickstep/src/com/android/quickstep/views/SplitPlaceholderView.java
+++ b/quickstep/src/com/android/quickstep/views/SplitPlaceholderView.java
@@ -17,22 +17,15 @@
package com.android.quickstep.views;
import android.content.Context;
-import android.graphics.Canvas;
-import android.graphics.Paint;
-import android.graphics.Rect;
-import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.FloatProperty;
-import android.util.TypedValue;
+import android.view.Gravity;
import android.widget.FrameLayout;
-import androidx.annotation.Nullable;
+import com.android.quickstep.util.SplitSelectStateController;
public class SplitPlaceholderView extends FrameLayout {
- private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
- private final Rect mTempRect = new Rect();
-
public static final FloatProperty<SplitPlaceholderView> ALPHA_FLOAT =
new FloatProperty<SplitPlaceholderView>("SplitViewAlpha") {
@Override
@@ -47,55 +40,29 @@ public class SplitPlaceholderView extends FrameLayout {
}
};
- @Nullable
- private IconView mIconView;
+ private SplitSelectStateController mSplitController;
+ private IconView mIcon;
public SplitPlaceholderView(Context context, AttributeSet attrs) {
super(context, attrs);
-
- mPaint.setColor(getThemeBackgroundColor(context));
- setWillNotDraw(false);
}
- @Override
- protected void dispatchDraw(Canvas canvas) {
- // Call this before super call to draw below the children.
- drawBackground(canvas);
-
- super.dispatchDraw(canvas);
-
- if (mIconView != null) {
- // Center the icon view in the visible area.
- getLocalVisibleRect(mTempRect);
- FloatingTaskView parent = (FloatingTaskView) getParent();
- parent.centerIconView(mIconView, mTempRect.centerX(), mTempRect.centerY());
- }
+ public void init(SplitSelectStateController controller) {
+ this.mSplitController = controller;
}
- @Nullable
- public IconView getIconView() {
- return mIconView;
+ public SplitSelectStateController getSplitController() {
+ return mSplitController;
}
- public void setIcon(Drawable drawable, int iconSize) {
- if (mIconView == null) {
- mIconView = new IconView(getContext());
- addView(mIconView);
+ public void setIcon(IconView icon) {
+ if (mIcon == null) {
+ mIcon = new IconView(getContext());
+ addView(mIcon);
}
- mIconView.setDrawable(drawable);
- mIconView.setDrawableSize(iconSize, iconSize);
- FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(iconSize, iconSize);
- mIconView.setLayoutParams(params);
- }
-
- private void drawBackground(Canvas canvas) {
- FloatingTaskView parent = (FloatingTaskView) getParent();
- parent.drawRoundedRect(canvas, mPaint);
- }
-
- private static int getThemeBackgroundColor(Context context) {
- final TypedValue value = new TypedValue();
- context.getTheme().resolveAttribute(android.R.attr.colorBackground, value, true);
- return value.data;
+ mIcon.setDrawable(icon.getDrawable());
+ FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(icon.getLayoutParams());
+ params.gravity = Gravity.CENTER;
+ mIcon.setLayoutParams(params);
}
}
diff --git a/quickstep/src/com/android/quickstep/views/TaskMenuView.java b/quickstep/src/com/android/quickstep/views/TaskMenuView.java
index 3803f1b426..906e854127 100644
--- a/quickstep/src/com/android/quickstep/views/TaskMenuView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskMenuView.java
@@ -17,8 +17,6 @@
package com.android.quickstep.views;
import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE;
-import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_BOTTOM_OR_RIGHT;
-import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_UNDEFINED;
import static com.android.quickstep.views.TaskThumbnailView.DIM_ALPHA;
import android.animation.Animator;
@@ -34,27 +32,25 @@ import android.util.AttributeSet;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
+import android.view.ViewGroup;
import android.view.ViewOutlineProvider;
import android.view.ViewTreeObserver.OnScrollChangedListener;
import android.widget.LinearLayout;
import android.widget.TextView;
-import androidx.annotation.Nullable;
-
import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.BaseDraggingActivity;
-import com.android.launcher3.DeviceProfile;
import com.android.launcher3.R;
import com.android.launcher3.anim.AnimationSuccessListener;
import com.android.launcher3.anim.Interpolators;
import com.android.launcher3.anim.RoundedRectRevealOutlineProvider;
+import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.popup.SystemShortcut;
import com.android.launcher3.touch.PagedOrientationHandler;
import com.android.launcher3.views.BaseDragLayer;
import com.android.quickstep.TaskOverlayFactory;
import com.android.quickstep.TaskUtils;
import com.android.quickstep.util.TaskCornerRadius;
-import com.android.quickstep.views.TaskView.TaskIdAttributeContainer;
/**
* Contains options for a recent task when long-pressing its icon.
@@ -69,10 +65,8 @@ public class TaskMenuView extends AbstractFloatingView implements OnScrollChange
private BaseDraggingActivity mActivity;
private TextView mTaskName;
- @Nullable
private AnimatorSet mOpenCloseAnimator;
private TaskView mTaskView;
- private TaskIdAttributeContainer mTaskContainer;
private LinearLayout mOptionLayout;
public TaskMenuView(Context context, AttributeSet attrs) {
@@ -137,8 +131,7 @@ public class TaskMenuView extends AbstractFloatingView implements OnScrollChange
// Inset due to margin
PointF additionalInset = pagedOrientationHandler
.getAdditionalInsetForTaskMenu(mTaskInsetMargin);
- DeviceProfile deviceProfile = mActivity.getDeviceProfile();
- int taskTopMargin = deviceProfile.overviewTaskThumbnailTopMarginPx;
+ int taskTopMargin = mActivity.getDeviceProfile().overviewTaskThumbnailTopMarginPx;
float adjustedY = y + taskTopMargin - additionalInset.y;
float adjustedX = x - additionalInset.x;
@@ -146,7 +139,7 @@ public class TaskMenuView extends AbstractFloatingView implements OnScrollChange
// NOTE: Changing the pivots means the rotated view gets rotated about the new pivots set,
// which would render the X and Y position set here incorrect
setPivotX(0);
- if (deviceProfile.isTablet) {
+ if (mActivity.getDeviceProfile().isTablet && FeatureFlags.ENABLE_OVERVIEW_GRID.get()) {
// In tablet, set pivotY to original position without mThumbnailTopMargin adjustment.
setPivotY(-taskTopMargin);
} else {
@@ -154,26 +147,9 @@ public class TaskMenuView extends AbstractFloatingView implements OnScrollChange
}
setRotation(pagedOrientationHandler.getDegreesRotated());
setX(pagedOrientationHandler.getTaskMenuX(adjustedX,
- mTaskContainer.getThumbnailView(), overscrollShift, deviceProfile));
+ mTaskView.getThumbnail(), overscrollShift));
setY(pagedOrientationHandler.getTaskMenuY(
- adjustedY, mTaskContainer.getThumbnailView(), overscrollShift));
-
- // TODO(b/193432925) temporary menu placement for split screen task menus
- TaskIdAttributeContainer[] taskIdAttributeContainers =
- mTaskView.getTaskIdAttributeContainers();
- if (taskIdAttributeContainers[0].getStagePosition() != STAGE_POSITION_UNDEFINED) {
- if (mTaskContainer.getStagePosition() != STAGE_POSITION_BOTTOM_OR_RIGHT) {
- return;
- }
- Rect r = new Rect();
- mTaskContainer.getThumbnailView().getBoundsOnScreen(r);
- if (deviceProfile.isLandscape) {
- setX(r.left);
- } else {
- setY(r.top);
-
- }
- }
+ adjustedY, mTaskView.getThumbnail(), overscrollShift));
}
public void onRotationChanged() {
@@ -188,21 +164,19 @@ public class TaskMenuView extends AbstractFloatingView implements OnScrollChange
}
}
- public static boolean showForTask(TaskIdAttributeContainer taskContainer) {
- BaseDraggingActivity activity = BaseDraggingActivity.fromContext(
- taskContainer.getTaskView().getContext());
+ public static boolean showForTask(TaskView taskView) {
+ BaseDraggingActivity activity = BaseDraggingActivity.fromContext(taskView.getContext());
final TaskMenuView taskMenuView = (TaskMenuView) activity.getLayoutInflater().inflate(
R.layout.task_menu, activity.getDragLayer(), false);
- return taskMenuView.populateAndShowForTask(taskContainer);
+ return taskMenuView.populateAndShowForTask(taskView);
}
- private boolean populateAndShowForTask(TaskIdAttributeContainer taskContainer) {
+ private boolean populateAndShowForTask(TaskView taskView) {
if (isAttachedToWindow()) {
return false;
}
mActivity.getDragLayer().addView(this);
- mTaskView = taskContainer.getTaskView();
- mTaskContainer = taskContainer;
+ mTaskView = taskView;
if (!populateAndLayoutMenu()) {
return false;
}
@@ -213,27 +187,27 @@ public class TaskMenuView extends AbstractFloatingView implements OnScrollChange
@Override
public void onScrollChanged() {
- RecentsView rv = mActivity.getOverviewPanel();
+ RecentsView rv = mTaskView.getRecentsView();
setPosition(mTaskView.getX() - rv.getScrollX(), mTaskView.getY() - rv.getScrollY(),
rv.getOverScrollShift());
}
/** @return true if successfully able to populate task view menu, false otherwise */
private boolean populateAndLayoutMenu() {
- if (mTaskContainer.getTask().icon == null) {
+ if (mTaskView.getTask().icon == null) {
// Icon may not be loaded
return false;
}
- addMenuOptions(mTaskContainer);
- orientAroundTaskView(mTaskContainer);
+ addMenuOptions(mTaskView);
+ orientAroundTaskView(mTaskView);
return true;
}
- private void addMenuOptions(TaskIdAttributeContainer taskContainer) {
- mTaskName.setText(TaskUtils.getTitle(getContext(), taskContainer.getTask()));
+ private void addMenuOptions(TaskView taskView) {
+ mTaskName.setText(TaskUtils.getTitle(getContext(), taskView.getTask()));
mTaskName.setOnClickListener(v -> close(true));
- TaskOverlayFactory.getEnabledShortcuts(mTaskView, mActivity.getDeviceProfile(),
- taskContainer)
+
+ TaskOverlayFactory.getEnabledShortcuts(taskView, mActivity.getDeviceProfile())
.forEach(this::addMenuOption);
}
@@ -245,8 +219,10 @@ public class TaskMenuView extends AbstractFloatingView implements OnScrollChange
LayoutParams lp = (LayoutParams) menuOptionView.getLayoutParams();
mTaskView.getPagedOrientationHandler().setLayoutParamsForTaskMenuOptionItem(lp,
menuOptionView, mActivity.getDeviceProfile());
+ menuOptionView.setEnabled(menuOption.isEnabled());
+ menuOptionView.setAlpha(menuOption.isEnabled() ? 1 : 0.5f);
menuOptionView.setOnClickListener(view -> {
- if (ENABLE_QUICKSTEP_LIVE_TILE.get()) {
+ if (ENABLE_QUICKSTEP_LIVE_TILE.get() && !menuOption.hasFinishRecentsInAction()) {
RecentsView recentsView = mTaskView.getRecentsView();
recentsView.switchToScreenshot(null,
() -> recentsView.finishRecentsAnimation(true /* toRecents */,
@@ -259,27 +235,23 @@ public class TaskMenuView extends AbstractFloatingView implements OnScrollChange
mOptionLayout.addView(menuOptionView);
}
- private void orientAroundTaskView(TaskIdAttributeContainer taskContainer) {
- RecentsView recentsView = mActivity.getOverviewPanel();
- PagedOrientationHandler orientationHandler = recentsView.getPagedOrientationHandler();
+ private void orientAroundTaskView(TaskView taskView) {
+ PagedOrientationHandler orientationHandler = taskView.getPagedOrientationHandler();
measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
orientationHandler.setTaskMenuAroundTaskView(this, mTaskInsetMargin);
// Get Position
- DeviceProfile deviceProfile = mActivity.getDeviceProfile();
- mActivity.getDragLayer().getDescendantRectRelativeToSelf(mTaskView, sTempRect);
+ mActivity.getDragLayer().getDescendantRectRelativeToSelf(taskView, sTempRect);
Rect insets = mActivity.getDragLayer().getInsets();
BaseDragLayer.LayoutParams params = (BaseDragLayer.LayoutParams) getLayoutParams();
int padding = getResources()
.getDimensionPixelSize(R.dimen.task_menu_vertical_padding);
- params.width = orientationHandler
- .getTaskMenuWidth(taskContainer.getThumbnailView(),
- deviceProfile) - (2 * padding);
+ params.width = orientationHandler.getTaskMenuWidth(taskView.getThumbnail()) - (2 * padding);
// Gravity set to Left instead of Start as sTempRect.left measures Left distance not Start
params.gravity = Gravity.LEFT;
setLayoutParams(params);
- setScaleX(mTaskView.getScaleX());
- setScaleY(mTaskView.getScaleY());
+ setScaleX(taskView.getScaleX());
+ setScaleY(taskView.getScaleY());
// Set divider spacing
ShapeDrawable divider = new ShapeDrawable(new RectShape());
@@ -288,7 +260,7 @@ public class TaskMenuView extends AbstractFloatingView implements OnScrollChange
mOptionLayout.setShowDividers(SHOW_DIVIDER_MIDDLE);
orientationHandler.setTaskOptionsMenuLayoutOrientation(
- deviceProfile, mOptionLayout, dividerSpacing, divider);
+ mActivity.getDeviceProfile(), mOptionLayout, dividerSpacing, divider);
setPosition(sTempRect.left - insets.left, sTempRect.top - insets.top, 0);
}
@@ -312,7 +284,7 @@ public class TaskMenuView extends AbstractFloatingView implements OnScrollChange
revealAnimator.setInterpolator(Interpolators.DEACCEL);
mOpenCloseAnimator.playTogether(revealAnimator,
ObjectAnimator.ofFloat(
- mTaskContainer.getThumbnailView(), DIM_ALPHA,
+ mTaskView.getThumbnail(), DIM_ALPHA,
closing ? 0 : TaskView.MAX_PAGE_SCRIM_ALPHA),
ObjectAnimator.ofFloat(this, ALPHA, closing ? 0 : 1));
mOpenCloseAnimator.addListener(new AnimationSuccessListener() {
@@ -345,4 +317,13 @@ public class TaskMenuView extends AbstractFloatingView implements OnScrollChange
return new RoundedRectRevealOutlineProvider(radius, radius, fromRect, toRect);
}
+ public View findMenuItemByText(String text) {
+ for (int i = mOptionLayout.getChildCount() - 1; i >= 0; --i) {
+ final ViewGroup menuOptionView = (ViewGroup) mOptionLayout.getChildAt(i);
+ if (text.equals(menuOptionView.<TextView>findViewById(R.id.text).getText())) {
+ return menuOptionView;
+ }
+ }
+ return null;
+ }
}
diff --git a/quickstep/src/com/android/quickstep/views/TaskMenuViewWithArrow.kt b/quickstep/src/com/android/quickstep/views/TaskMenuViewWithArrow.kt
deleted file mode 100644
index 06a579300a..0000000000
--- a/quickstep/src/com/android/quickstep/views/TaskMenuViewWithArrow.kt
+++ /dev/null
@@ -1,344 +0,0 @@
-/*
- * Copyright (C) 2021 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.quickstep.views
-
-import android.animation.AnimatorSet
-import android.animation.ObjectAnimator
-import android.content.Context
-import android.graphics.Rect
-import android.graphics.drawable.ShapeDrawable
-import android.graphics.drawable.shapes.RectShape
-import android.util.AttributeSet
-import android.view.Gravity
-import android.view.MotionEvent
-import android.view.View
-import android.view.ViewGroup
-import android.widget.FrameLayout
-import android.widget.LinearLayout
-import com.android.launcher3.BaseDraggingActivity
-import com.android.launcher3.DeviceProfile
-import com.android.launcher3.InsettableFrameLayout
-import com.android.launcher3.R
-import com.android.launcher3.popup.ArrowPopup
-import com.android.launcher3.popup.RoundedArrowDrawable
-import com.android.launcher3.popup.SystemShortcut
-import com.android.launcher3.util.Themes
-import com.android.quickstep.KtR
-import com.android.quickstep.TaskOverlayFactory
-import com.android.quickstep.views.TaskView.TaskIdAttributeContainer
-
-class TaskMenuViewWithArrow<T : BaseDraggingActivity> : ArrowPopup<T> {
- companion object {
- const val TAG = "TaskMenuViewWithArrow"
-
- fun showForTask(
- taskContainer: TaskIdAttributeContainer,
- alignSecondRow: Boolean = false
- ): Boolean {
- val activity = BaseDraggingActivity
- .fromContext<BaseDraggingActivity>(taskContainer.taskView.context)
- val taskMenuViewWithArrow = activity.layoutInflater
- .inflate(
- KtR.layout.task_menu_with_arrow,
- activity.dragLayer,
- false
- ) as TaskMenuViewWithArrow<*>
-
- return taskMenuViewWithArrow.populateAndShowForTask(taskContainer, alignSecondRow)
- }
- }
-
- constructor(context: Context) : super(context)
- constructor(context: Context, attrs: AttributeSet) : super(context, attrs)
- constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(
- context,
- attrs,
- defStyleAttr
- )
-
- init {
- clipToOutline = true
-
- shouldScaleArrow = true
- // This synchronizes the arrow and menu to open at the same time
- OPEN_CHILD_FADE_START_DELAY = OPEN_FADE_START_DELAY
- OPEN_CHILD_FADE_DURATION = OPEN_FADE_DURATION
- CLOSE_FADE_START_DELAY = CLOSE_CHILD_FADE_START_DELAY
- CLOSE_FADE_DURATION = CLOSE_CHILD_FADE_DURATION
- }
-
- private var alignSecondRow: Boolean = false
- private val extraSpaceForSecondRowAlignment: Int
- get() = if (alignSecondRow) optionMeasuredHeight else 0
- private val menuWidth = context.resources.getDimensionPixelSize(R.dimen.task_menu_width_grid)
-
- private lateinit var taskView: TaskView
- private lateinit var optionLayout: LinearLayout
- private lateinit var taskContainer: TaskIdAttributeContainer
-
- private var optionMeasuredHeight = 0
- private val arrowHorizontalPadding: Int
- get() = if (taskView.isFocusedTask)
- resources.getDimensionPixelSize(KtR.dimen.task_menu_horizontal_padding)
- else
- 0
-
- private var iconView: IconView? = null
- private var scrim: View? = null
- private val scrimAlpha = 0.8f
-
- override fun isOfType(type: Int): Boolean = type and TYPE_TASK_MENU != 0
-
- override fun getTargetObjectLocation(outPos: Rect?) {
- popupContainer.getDescendantRectRelativeToSelf(taskContainer.iconView, outPos)
- }
-
- override fun onControllerInterceptTouchEvent(ev: MotionEvent?): Boolean {
- if (ev?.action == MotionEvent.ACTION_DOWN) {
- if (!popupContainer.isEventOverView(this, ev)) {
- close(true)
- return true
- }
- }
- return false
- }
-
- override fun onFinishInflate() {
- super.onFinishInflate()
- optionLayout = findViewById(KtR.id.menu_option_layout)
- }
-
- private fun populateAndShowForTask(
- taskContainer: TaskIdAttributeContainer,
- alignSecondRow: Boolean
- ): Boolean {
- if (isAttachedToWindow) {
- return false
- }
-
- taskView = taskContainer.taskView
- this.taskContainer = taskContainer
- this.alignSecondRow = alignSecondRow
- if (!populateMenu()) return false
- addScrim()
- show()
- return true
- }
-
- private fun addScrim() {
- scrim = View(context).apply {
- layoutParams = FrameLayout.LayoutParams(
- FrameLayout.LayoutParams.MATCH_PARENT,
- FrameLayout.LayoutParams.MATCH_PARENT
- )
- setBackgroundColor(Themes.getAttrColor(context, R.attr.overviewScrimColor))
- alpha = 0f
- }
- popupContainer.addView(scrim)
- }
-
- /** @return true if successfully able to populate task view menu, false otherwise
- */
- private fun populateMenu(): Boolean {
- // Icon may not be loaded
- if (taskContainer.task.icon == null) return false
-
- addMenuOptions()
- return true
- }
-
- private fun addMenuOptions() {
- // Add the options
- TaskOverlayFactory
- .getEnabledShortcuts(taskView, mActivityContext.deviceProfile, taskContainer)
- .forEach { this.addMenuOption(it) }
-
- // Add the spaces between items
- val divider = ShapeDrawable(RectShape())
- divider.paint.color = resources.getColor(android.R.color.transparent)
- val dividerSpacing = resources.getDimension(KtR.dimen.task_menu_spacing).toInt()
- optionLayout.showDividers = SHOW_DIVIDER_MIDDLE
-
- // Set the orientation, which makes the menu show
- val recentsView: RecentsView<*, *> = mActivityContext.getOverviewPanel()
- val orientationHandler = recentsView.pagedOrientationHandler
- val deviceProfile: DeviceProfile = mActivityContext.deviceProfile
- orientationHandler.setTaskOptionsMenuLayoutOrientation(
- deviceProfile,
- optionLayout,
- dividerSpacing,
- divider
- )
- }
-
- private fun addMenuOption(menuOption: SystemShortcut<*>) {
- val menuOptionView = mActivityContext.layoutInflater.inflate(
- KtR.layout.task_view_menu_option, this, false
- ) as LinearLayout
- menuOption.setIconAndLabelFor(
- menuOptionView.findViewById(R.id.icon),
- menuOptionView.findViewById(R.id.text)
- )
- val lp = menuOptionView.layoutParams as LayoutParams
- lp.width = menuWidth
- menuOptionView.setOnClickListener { view: View? -> menuOption.onClick(view) }
- optionLayout.addView(menuOptionView)
- }
-
- override fun assignMarginsAndBackgrounds(viewGroup: ViewGroup) {
- assignMarginsAndBackgrounds(
- this,
- Themes.getAttrColor(context, com.android.internal.R.attr.colorSurface)
- )
- }
-
- override fun onCreateOpenAnimation(anim: AnimatorSet) {
- scrim?.let {
- anim.play(
- ObjectAnimator.ofFloat(it, View.ALPHA, 0f, scrimAlpha)
- .setDuration(OPEN_DURATION.toLong())
- )
- }
- }
-
- override fun onCreateCloseAnimation(anim: AnimatorSet) {
- scrim?.let {
- anim.play(
- ObjectAnimator.ofFloat(it, View.ALPHA, scrimAlpha, 0f)
- .setDuration(CLOSE_DURATION.toLong())
- )
- }
- }
-
- override fun closeComplete() {
- super.closeComplete()
- popupContainer.removeView(scrim)
- popupContainer.removeView(iconView)
- }
-
- /**
- * Copy the iconView from taskView to dragLayer so it can stay on top of the scrim.
- * It needs to be called after [getTargetObjectLocation] because [mTempRect] needs to be
- * populated.
- */
- private fun copyIconToDragLayer(insets: Rect) {
- iconView = IconView(context).apply {
- layoutParams = FrameLayout.LayoutParams(
- taskContainer.iconView.width,
- taskContainer.iconView.height
- )
- x = mTempRect.left.toFloat() - insets.left
- y = mTempRect.top.toFloat() - insets.top
- drawable = taskContainer.iconView.drawable
- setDrawableSize(
- taskContainer.iconView.drawableWidth,
- taskContainer.iconView.drawableHeight
- )
- }
-
- popupContainer.addView(iconView)
- }
-
- /**
- * Orients this container to the left or right of the given icon, aligning with the first option
- * or second.
- *
- * These are the preferred orientations, in order (RTL prefers right-aligned over left):
- * - Right and first option aligned
- * - Right and second option aligned
- * - Left and first option aligned
- * - Left and second option aligned
- *
- * So we always align right if there is enough horizontal space
- */
- override fun orientAboutObject() {
- measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED)
- // Needed for offsets later
- optionMeasuredHeight = optionLayout.getChildAt(0).measuredHeight
- val extraHorizontalSpace = (mArrowHeight + mArrowOffsetVertical + arrowHorizontalPadding)
-
- val widthWithArrow = measuredWidth + paddingLeft + paddingRight + extraHorizontalSpace
- getTargetObjectLocation(mTempRect)
- val dragLayer: InsettableFrameLayout = popupContainer
- val insets = dragLayer.insets
-
- copyIconToDragLayer(insets)
-
- // Put this menu to the right of the icon if there is space,
- // which means the arrow is left aligned with the menu
- val rightAlignedMenuStartX = mTempRect.left - widthWithArrow
- val leftAlignedMenuStartX = mTempRect.right + extraHorizontalSpace
- mIsLeftAligned = if (mIsRtl) {
- rightAlignedMenuStartX + insets.left < 0
- } else {
- leftAlignedMenuStartX + (widthWithArrow - extraHorizontalSpace) + insets.left <
- dragLayer.width - insets.right
- }
-
- var menuStartX = if (mIsLeftAligned) leftAlignedMenuStartX else rightAlignedMenuStartX
-
- // Offset y so that the arrow and row are center-aligned with the original icon.
- val iconHeight = mTempRect.height()
- val yOffset = (optionMeasuredHeight - iconHeight) / 2
- var menuStartY = mTempRect.top - yOffset - extraSpaceForSecondRowAlignment
-
- // Insets are added later, so subtract them now.
- menuStartX -= insets.left
- menuStartY -= insets.top
-
- x = menuStartX.toFloat()
- y = menuStartY.toFloat()
-
- val lp = layoutParams as FrameLayout.LayoutParams
- val arrowLp = mArrow.layoutParams as FrameLayout.LayoutParams
- lp.gravity = Gravity.TOP
- arrowLp.gravity = lp.gravity
- }
-
- override fun addArrow() {
- popupContainer.addView(mArrow)
- mArrow.x = getArrowX()
- mArrow.y = y + (optionMeasuredHeight / 2) - (mArrowHeight / 2) +
- extraSpaceForSecondRowAlignment
-
- updateArrowColor()
-
- // This is inverted (x = height, y = width) because the arrow is rotated
- mArrow.pivotX = if (mIsLeftAligned) 0f else mArrowHeight.toFloat()
- mArrow.pivotY = 0f
- }
-
- private fun getArrowX(): Float {
- return if (mIsLeftAligned)
- x - mArrowHeight
- else
- x + measuredWidth + mArrowOffsetVertical
- }
-
- override fun updateArrowColor() {
- mArrow.background = RoundedArrowDrawable(
- mArrowWidth.toFloat(),
- mArrowHeight.toFloat(),
- mArrowPointRadius.toFloat(),
- mIsLeftAligned,
- mArrowColor
- )
- elevation = mElevation
- mArrow.elevation = mElevation
- }
-
-} \ No newline at end of file
diff --git a/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java b/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java
index d8120ff255..c70596d88e 100644
--- a/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java
@@ -19,6 +19,7 @@ package com.android.quickstep.views;
import static android.view.WindowInsetsController.APPEARANCE_LIGHT_NAVIGATION_BARS;
import static android.view.WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS;
+import static com.android.launcher3.Utilities.comp;
import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE;
import static com.android.systemui.shared.system.WindowManagerWrapper.WINDOWING_MODE_FULLSCREEN;
@@ -43,24 +44,27 @@ import android.util.Property;
import android.view.Surface;
import android.view.View;
-import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.core.graphics.ColorUtils;
import com.android.launcher3.BaseActivity;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Utilities;
+import com.android.launcher3.config.FeatureFlags;
+import com.android.launcher3.uioverrides.plugins.PluginManagerWrapper;
import com.android.launcher3.util.MainThreadInitializedObject;
import com.android.launcher3.util.SystemUiController;
import com.android.quickstep.TaskOverlayFactory.TaskOverlay;
import com.android.quickstep.views.TaskView.FullscreenDrawParams;
+import com.android.systemui.plugins.OverviewScreenshotActions;
+import com.android.systemui.plugins.PluginListener;
import com.android.systemui.shared.recents.model.Task;
import com.android.systemui.shared.recents.model.ThumbnailData;
/**
* A task in the Recents view.
*/
-public class TaskThumbnailView extends View {
+public class TaskThumbnailView extends View implements PluginListener<OverviewScreenshotActions> {
private static final MainThreadInitializedObject<FullscreenDrawParams> TEMP_PARAMS =
new MainThreadInitializedObject<>(FullscreenDrawParams::new);
@@ -78,7 +82,6 @@ public class TaskThumbnailView extends View {
};
private final BaseActivity mActivity;
- @Nullable
private TaskOverlay mOverlay;
private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private final Paint mBackgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
@@ -91,27 +94,25 @@ public class TaskThumbnailView extends View {
private final PreviewPositionHelper mPreviewPositionHelper = new PreviewPositionHelper();
private TaskView.FullscreenDrawParams mFullscreenParams;
- @Nullable
private Task mTask;
- @Nullable
private ThumbnailData mThumbnailData;
- @Nullable
protected BitmapShader mBitmapShader;
/** How much this thumbnail is dimmed, 0 not dimmed at all, 1 totally dimmed. */
private float mDimAlpha = 0f;
private boolean mOverlayEnabled;
+ private OverviewScreenshotActions mOverviewScreenshotActionsPlugin;
public TaskThumbnailView(Context context) {
this(context, null);
}
- public TaskThumbnailView(Context context, @Nullable AttributeSet attrs) {
+ public TaskThumbnailView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
- public TaskThumbnailView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
+ public TaskThumbnailView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mPaint.setFilterBitmap(true);
mBackgroundPaint.setColor(Color.WHITE);
@@ -145,47 +146,37 @@ public class TaskThumbnailView extends View {
* upon swipe up so that a usable screenshot is accessible immediately when
* recents animation needs to be finished / cancelled.
*/
- public void setThumbnail(@Nullable Task task, @Nullable ThumbnailData thumbnailData,
- boolean refreshNow) {
+ public void setThumbnail(Task task, ThumbnailData thumbnailData, boolean refreshNow) {
mTask = task;
- boolean thumbnailWasNull = mThumbnailData == null;
mThumbnailData =
(thumbnailData != null && thumbnailData.thumbnail != null) ? thumbnailData : null;
if (refreshNow) {
- refresh(thumbnailWasNull && mThumbnailData != null);
+ refresh();
}
}
/** See {@link #setThumbnail(Task, ThumbnailData, boolean)} */
- public void setThumbnail(@Nullable Task task, @Nullable ThumbnailData thumbnailData) {
+ public void setThumbnail(Task task, ThumbnailData thumbnailData) {
setThumbnail(task, thumbnailData, true /* refreshNow */);
}
/** Updates the shader, paint, matrix to redraw. */
public void refresh() {
- refresh(false);
- }
-
- /**
- * Updates the shader, paint, matrix to redraw.
- * @param shouldRefreshOverlay whether to re-initialize overlay
- */
- private void refresh(boolean shouldRefreshOverlay) {
if (mThumbnailData != null && mThumbnailData.thumbnail != null) {
Bitmap bm = mThumbnailData.thumbnail;
bm.prepareToDraw();
mBitmapShader = new BitmapShader(bm, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
mPaint.setShader(mBitmapShader);
updateThumbnailMatrix();
- if (shouldRefreshOverlay) {
- refreshOverlay();
- }
} else {
mBitmapShader = null;
mThumbnailData = null;
mPaint.setShader(null);
getTaskOverlay().reset();
}
+ if (mOverviewScreenshotActionsPlugin != null) {
+ mOverviewScreenshotActionsPlugin.setupActions(getTaskView(), getThumbnail(), mActivity);
+ }
updateThumbnailPaintFilter();
}
@@ -223,6 +214,10 @@ public class TaskThumbnailView extends View {
return Insets.NONE;
}
+ if (!TaskView.CLIP_STATUS_AND_NAV_BARS) {
+ return Insets.NONE;
+ }
+
RectF bitmapRect = new RectF(
0, 0,
mThumbnailData.thumbnail.getWidth(), mThumbnailData.thumbnail.getHeight());
@@ -236,14 +231,11 @@ public class TaskThumbnailView extends View {
RectF boundsInBitmapSpace = new RectF();
boundsToBitmapSpace.mapRect(boundsInBitmapSpace, viewRect);
- DeviceProfile dp = mActivity.getDeviceProfile();
- int leftInset = TaskView.clipLeft(dp) ? Math.round(boundsInBitmapSpace.left) : 0;
- int topInset = TaskView.clipTop(dp) ? Math.round(boundsInBitmapSpace.top) : 0;
- int rightInset = TaskView.clipRight(dp) ? Math.round(
- bitmapRect.right - boundsInBitmapSpace.right) : 0;
- int bottomInset = TaskView.clipBottom(dp)
- ? Math.round(bitmapRect.bottom - boundsInBitmapSpace.bottom) : 0;
- return Insets.of(leftInset, topInset, rightInset, bottomInset);
+ return Insets.of(
+ Math.round(boundsInBitmapSpace.left),
+ Math.round(boundsInBitmapSpace.top),
+ Math.round(bitmapRect.right - boundsInBitmapSpace.right),
+ Math.round(bitmapRect.bottom - boundsInBitmapSpace.bottom));
}
@@ -277,13 +269,39 @@ public class TaskThumbnailView extends View {
canvas.restore();
}
+ @Override
+ public void onPluginConnected(OverviewScreenshotActions overviewScreenshotActions,
+ Context context) {
+ mOverviewScreenshotActionsPlugin = overviewScreenshotActions;
+ mOverviewScreenshotActionsPlugin.setupActions(getTaskView(), getThumbnail(), mActivity);
+ }
+
+ @Override
+ public void onPluginDisconnected(OverviewScreenshotActions plugin) {
+ if (mOverviewScreenshotActionsPlugin != null) {
+ mOverviewScreenshotActionsPlugin = null;
+ }
+ }
+
+ @Override
+ protected void onAttachedToWindow() {
+ super.onAttachedToWindow();
+ PluginManagerWrapper.INSTANCE.get(getContext())
+ .addPluginListener(this, OverviewScreenshotActions.class);
+ }
+
+ @Override
+ protected void onDetachedFromWindow() {
+ super.onDetachedFromWindow();
+ PluginManagerWrapper.INSTANCE.get(getContext()).removePluginListener(this);
+ }
+
public PreviewPositionHelper getPreviewPositionHelper() {
return mPreviewPositionHelper;
}
public void setFullscreenParams(TaskView.FullscreenDrawParams fullscreenParams) {
mFullscreenParams = fullscreenParams;
- getTaskOverlay().setFullscreenParams(fullscreenParams);
invalidate();
}
@@ -291,23 +309,30 @@ public class TaskThumbnailView extends View {
float cornerRadius) {
if (ENABLE_QUICKSTEP_LIVE_TILE.get()) {
if (mTask != null && getTaskView().isRunningTask() && !getTaskView().showScreenshot()) {
- canvas.drawRoundRect(x, y, width, height, cornerRadius, cornerRadius, mClearPaint);
- canvas.drawRoundRect(x, y, width, height, cornerRadius, cornerRadius,
+ // TODO(b/189265196): Temporary fix to align the surface with the cutout perfectly.
+ // Round up only when the live tile task is displayed in Overview.
+ float rounding = comp(mFullscreenParams.mFullscreenProgress);
+ float left = x + rounding / 2;
+ float top = y + rounding / 2;
+ float right = width - rounding;
+ float bottom = height - rounding;
+
+ canvas.drawRoundRect(left, top, right, bottom, cornerRadius, cornerRadius,
+ mClearPaint);
+ canvas.drawRoundRect(left, top, right, bottom, cornerRadius, cornerRadius,
mDimmingPaintAfterClearing);
return;
}
}
- // Always draw the background since the snapshots might be translucent or partially empty
- // (For example, tasks been reparented out of dismissing split root when drag-to-dismiss
- // split screen).
- canvas.drawRoundRect(x, y + 1, width, height - 1, cornerRadius,
- cornerRadius, mBackgroundPaint);
-
+ // Draw the background in all cases, except when the thumbnail data is opaque
final boolean drawBackgroundOnly = mTask == null || mTask.isLocked || mBitmapShader == null
|| mThumbnailData == null;
- if (drawBackgroundOnly) {
- return;
+ if (drawBackgroundOnly || mThumbnailData.isTranslucent) {
+ canvas.drawRoundRect(x, y, width, height, cornerRadius, cornerRadius, mBackgroundPaint);
+ if (drawBackgroundOnly) {
+ return;
+ }
}
canvas.drawRoundRect(x, y, width, height, cornerRadius, cornerRadius, mPaint);
@@ -383,10 +408,6 @@ public class TaskThumbnailView extends View {
return Utilities.makeColorTintingColorFilter(mDimColor, dimAmount);
}
- /**
- * Returns current thumbnail or null if none is set.
- */
- @Nullable
public Bitmap getThumbnail() {
if (mThumbnailData == null) {
return null;
@@ -410,9 +431,7 @@ public class TaskThumbnailView extends View {
*/
public static class PreviewPositionHelper {
- private static final RectF EMPTY_RECT_F = new RectF();
-
- // Contains the portion of the thumbnail that is unclipped when fullscreen progress = 1.
+ // Contains the portion of the thumbnail that is clipped when fullscreen progress = 0.
private final RectF mClippedInsets = new RectF();
private final Matrix mMatrix = new Matrix();
private boolean mIsOrientationChanged;
@@ -432,19 +451,8 @@ public class TaskThumbnailView extends View {
int thumbnailRotation = thumbnailData.rotation;
int deltaRotate = getRotationDelta(currentRotation, thumbnailRotation);
- RectF thumbnailClipHint = new RectF();
- if (TaskView.clipLeft(dp)) {
- thumbnailClipHint.left = thumbnailData.insets.left;
- }
- if (TaskView.clipRight(dp)) {
- thumbnailClipHint.right = thumbnailData.insets.right;
- }
- if (TaskView.clipTop(dp)) {
- thumbnailClipHint.top = thumbnailData.insets.top;
- }
- if (TaskView.clipBottom(dp)) {
- thumbnailClipHint.bottom = thumbnailData.insets.bottom;
- }
+ RectF thumbnailClipHint = TaskView.CLIP_STATUS_AND_NAV_BARS
+ ? new RectF(thumbnailData.insets) : new RectF();
float scale = thumbnailData.scale;
final float thumbnailScale;
@@ -453,7 +461,7 @@ public class TaskThumbnailView extends View {
// Note: Disable rotation in grid layout.
boolean windowingModeSupportsRotation = !dp.isMultiWindowMode
&& thumbnailData.windowingMode == WINDOWING_MODE_FULLSCREEN
- && !dp.isTablet;
+ && !(dp.isTablet && FeatureFlags.ENABLE_OVERVIEW_GRID.get());
isOrientationDifferent = isOrientationChange(deltaRotate)
&& windowingModeSupportsRotation;
if (canvasWidth == 0 || canvasHeight == 0 || scale == 0) {
@@ -471,36 +479,15 @@ public class TaskThumbnailView extends View {
float availableHeight = surfaceHeight
- (thumbnailClipHint.top + thumbnailClipHint.bottom);
- float canvasAspect = canvasWidth / (float) canvasHeight;
- float availableAspect = isRotated
- ? availableHeight / availableWidth
- : availableWidth / availableHeight;
- boolean isAspectLargelyDifferent = Utilities.isRelativePercentDifferenceGreaterThan(
- canvasAspect, availableAspect, 0.1f);
- if (isRotated && isAspectLargelyDifferent) {
+ if (isRotated) {
+ float canvasAspect = canvasWidth / (float) canvasHeight;
+ float availableAspect = availableHeight / availableWidth;
// Do not rotate thumbnail if it would not improve fit
- isRotated = false;
- isOrientationDifferent = false;
- }
-
- if (isAspectLargelyDifferent) {
- // Crop letterbox insets if insets isn't already clipped
- if (!TaskView.clipLeft(dp)) {
- thumbnailClipHint.left = thumbnailData.letterboxInsets.left;
- }
- if (!TaskView.clipRight(dp)) {
- thumbnailClipHint.right = thumbnailData.letterboxInsets.right;
+ if (Utilities.isRelativePercentDifferenceGreaterThan(canvasAspect,
+ availableAspect, 0.1f)) {
+ isRotated = false;
+ isOrientationDifferent = false;
}
- if (!TaskView.clipTop(dp)) {
- thumbnailClipHint.top = thumbnailData.letterboxInsets.top;
- }
- if (!TaskView.clipBottom(dp)) {
- thumbnailClipHint.bottom = thumbnailData.letterboxInsets.bottom;
- }
- availableWidth = surfaceWidth
- - (thumbnailClipHint.left + thumbnailClipHint.right);
- availableHeight = surfaceHeight
- - (thumbnailClipHint.top + thumbnailClipHint.bottom);
}
final float targetW, targetH;
@@ -511,25 +498,30 @@ public class TaskThumbnailView extends View {
targetW = canvasWidth;
targetH = canvasHeight;
}
- float targetAspect = targetW / targetH;
+ float canvasAspect = targetW / targetH;
// Update the clipHint such that
// > the final clipped position has same aspect ratio as requested by canvas
- // > first fit the width and crop the extra height
- // > if that will leave empty space, fit the height and crop the width instead
+ // > the clipped region is within the task insets if possible
+ // > the clipped region is not scaled up when drawing. If that is not possible
+ // while staying within the taskInsets, move outside the insets.
float croppedWidth = availableWidth;
- float croppedHeight = croppedWidth / targetAspect;
+ if (croppedWidth < targetW) {
+ croppedWidth = Math.min(targetW, surfaceWidth);
+ }
+
+ float croppedHeight = croppedWidth / canvasAspect;
if (croppedHeight > availableHeight) {
croppedHeight = availableHeight;
if (croppedHeight < targetH) {
croppedHeight = Math.min(targetH, surfaceHeight);
}
- croppedWidth = croppedHeight * targetAspect;
+ croppedWidth = croppedHeight * canvasAspect;
// One last check in case the task aspect radio messed up something
if (croppedWidth > surfaceWidth) {
croppedWidth = surfaceWidth;
- croppedHeight = croppedWidth / targetAspect;
+ croppedHeight = croppedWidth / canvasAspect;
}
}
@@ -573,7 +565,7 @@ public class TaskThumbnailView extends View {
-thumbnailClipHint.left * scale,
-thumbnailClipHint.top * scale);
} else {
- setThumbnailRotation(deltaRotate, thumbnailClipHint, scale, thumbnailBounds, dp);
+ setThumbnailRotation(deltaRotate, thumbnailClipHint, scale, thumbnailBounds);
}
final float widthWithInsets;
@@ -618,7 +610,7 @@ public class TaskThumbnailView extends View {
}
private void setThumbnailRotation(int deltaRotate, RectF thumbnailInsets, float scale,
- Rect thumbnailPosition, DeviceProfile dp) {
+ Rect thumbnailPosition) {
float newLeftInset = 0;
float newTopInset = 0;
float translateX = 0;
@@ -644,17 +636,15 @@ public class TaskThumbnailView extends View {
break;
}
mClippedInsets.offsetTo(newLeftInset * scale, newTopInset * scale);
- mMatrix.postTranslate(translateX, translateY);
- if (TaskView.useFullThumbnail(dp)) {
- mMatrix.postTranslate(-mClippedInsets.left, -mClippedInsets.top);
- }
+ mMatrix.postTranslate(translateX - mClippedInsets.left,
+ translateY - mClippedInsets.top);
}
/**
* Insets to used for clipping the thumbnail (in case it is drawing outside its own space)
*/
- public RectF getInsetsToDrawInFullscreen(DeviceProfile dp) {
- return TaskView.useFullThumbnail(dp) ? mClippedInsets : EMPTY_RECT_F;
+ public RectF getInsetsToDrawInFullscreen() {
+ return mClippedInsets;
}
}
}
diff --git a/quickstep/src/com/android/quickstep/views/TaskView.java b/quickstep/src/com/android/quickstep/views/TaskView.java
index d58bb7c719..2d322e96ae 100644
--- a/quickstep/src/com/android/quickstep/views/TaskView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskView.java
@@ -16,10 +16,19 @@
package com.android.quickstep.views;
-import static android.view.Display.DEFAULT_DISPLAY;
+import static android.view.Gravity.BOTTOM;
+import static android.view.Gravity.CENTER_HORIZONTAL;
+import static android.view.Gravity.CENTER_VERTICAL;
+import static android.view.Gravity.END;
+import static android.view.Gravity.START;
+import static android.view.Gravity.TOP;
+import static android.view.Surface.ROTATION_180;
+import static android.view.Surface.ROTATION_270;
+import static android.view.Surface.ROTATION_90;
import static android.widget.Toast.LENGTH_SHORT;
import static com.android.launcher3.AbstractFloatingView.TYPE_TASK_MENU;
+import static com.android.launcher3.LauncherState.OVERVIEW_SPLIT_SELECT;
import static com.android.launcher3.Utilities.comp;
import static com.android.launcher3.Utilities.getDescendantCoordRelativeToAncestor;
import static com.android.launcher3.anim.Interpolators.ACCEL_DEACCEL;
@@ -30,8 +39,6 @@ import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCH
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASK_LAUNCH_TAP;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
-import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_BOTTOM_OR_RIGHT;
-import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_UNDEFINED;
import static java.lang.annotation.RetentionPolicy.SOURCE;
@@ -39,12 +46,10 @@ import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
-import android.annotation.IdRes;
import android.app.ActivityOptions;
import android.content.Context;
import android.content.Intent;
import android.graphics.Outline;
-import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
@@ -52,8 +57,8 @@ import android.os.Bundle;
import android.util.AttributeSet;
import android.util.FloatProperty;
import android.util.Log;
-import android.view.Display;
import android.view.MotionEvent;
+import android.view.Surface;
import android.view.TouchDelegate;
import android.view.View;
import android.view.ViewGroup;
@@ -65,7 +70,6 @@ import android.widget.Toast;
import androidx.annotation.IntDef;
import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.DeviceProfile;
@@ -73,6 +77,7 @@ import com.android.launcher3.LauncherSettings;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.anim.Interpolators;
+import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.launcher3.popup.SystemShortcut;
import com.android.launcher3.statemanager.StatefulActivity;
@@ -82,13 +87,11 @@ import com.android.launcher3.touch.PagedOrientationHandler;
import com.android.launcher3.util.ActivityOptionsWrapper;
import com.android.launcher3.util.ComponentKey;
import com.android.launcher3.util.RunnableList;
-import com.android.launcher3.util.SplitConfigurationOptions;
import com.android.launcher3.util.SplitConfigurationOptions.SplitPositionOption;
import com.android.launcher3.util.TransformingTouchDelegate;
import com.android.launcher3.util.ViewPool.Reusable;
import com.android.quickstep.RecentsModel;
import com.android.quickstep.RemoteAnimationTargets;
-import com.android.quickstep.RemoteTargetGluer.RemoteTargetHandle;
import com.android.quickstep.SystemUiProxy;
import com.android.quickstep.TaskIconCache;
import com.android.quickstep.TaskOverlayFactory;
@@ -98,22 +101,16 @@ import com.android.quickstep.TaskViewUtils;
import com.android.quickstep.util.CancellableTask;
import com.android.quickstep.util.RecentsOrientedState;
import com.android.quickstep.util.TaskCornerRadius;
-import com.android.quickstep.util.TransformParams;
import com.android.quickstep.views.TaskThumbnailView.PreviewPositionHelper;
import com.android.systemui.shared.recents.model.Task;
-import com.android.systemui.shared.recents.model.ThumbnailData;
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.ActivityOptionsCompat;
import com.android.systemui.shared.system.QuickStepContract;
-import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
import java.lang.annotation.Retention;
-import java.util.Arrays;
import java.util.Collections;
-import java.util.HashMap;
import java.util.List;
import java.util.function.Consumer;
-import java.util.stream.Stream;
/**
* A task in the Recents view.
@@ -121,7 +118,6 @@ import java.util.stream.Stream;
public class TaskView extends FrameLayout implements Reusable {
private static final String TAG = TaskView.class.getSimpleName();
- private static final boolean DEBUG = false;
public static final int FLAG_UPDATE_ICON = 1;
public static final int FLAG_UPDATE_THUMBNAIL = FLAG_UPDATE_ICON << 1;
@@ -136,43 +132,20 @@ public class TaskView extends FrameLayout implements Reusable {
@IntDef({FLAG_UPDATE_ALL, FLAG_UPDATE_ICON, FLAG_UPDATE_THUMBNAIL})
public @interface TaskDataChanges {}
- /** The maximum amount that a task view can be scrimmed, dimmed or tinted. */
- public static final float MAX_PAGE_SCRIM_ALPHA = 0.4f;
-
/**
- * Should the TaskView display clip off the left inset in RecentsView.
+ * Should the layout account for space for a proactive action (or chip) to be added under
+ * the task.
*/
- public static boolean clipLeft(DeviceProfile deviceProfile) {
- return false;
- }
+ public static final boolean SHOW_PROACTIVE_ACTIONS = false;
- /**
- * Should the TaskView display clip off the top inset in RecentsView.
- */
- public static boolean clipTop(DeviceProfile deviceProfile) {
- return false;
- }
-
- /**
- * Should the TaskView display clip off the right inset in RecentsView.
- */
- public static boolean clipRight(DeviceProfile deviceProfile) {
- return false;
- }
-
- /**
- * Should the TaskView display clip off the bottom inset in RecentsView.
- */
- public static boolean clipBottom(DeviceProfile deviceProfile) {
- return deviceProfile.isTablet;
- }
+ /** The maximum amount that a task view can be scrimmed, dimmed or tinted. */
+ public static final float MAX_PAGE_SCRIM_ALPHA = 0.4f;
/**
- * Should the TaskView scale down to fit whole thumbnail in fullscreen.
+ * Should the TaskView display clip off the status and navigation bars in recents. When this
+ * is false the overview shows the whole screen scaled down instead.
*/
- public static boolean useFullThumbnail(DeviceProfile deviceProfile) {
- return deviceProfile.isTablet && !deviceProfile.isTaskbarPresentInApps;
- }
+ public static final boolean CLIP_STATUS_AND_NAV_BARS = false;
private static final float EDGE_SCALE_DOWN_FACTOR_CAROUSEL = 0.03f;
private static final float EDGE_SCALE_DOWN_FACTOR_GRID = 0.00f;
@@ -180,7 +153,7 @@ public class TaskView extends FrameLayout implements Reusable {
public static final long SCALE_ICON_DURATION = 120;
private static final long DIM_ANIM_DURATION = 700;
- private static final Interpolator GRID_INTERPOLATOR = ACCEL_DEACCEL;
+ private static final Interpolator FULLSCREEN_INTERPOLATOR = ACCEL_DEACCEL;
/**
* This technically can be a vanilla {@link TouchDelegate} class, however that class requires
@@ -189,11 +162,12 @@ public class TaskView extends FrameLayout implements Reusable {
* delegated bounds only to be updated.
*/
private TransformingTouchDelegate mIconTouchDelegate;
+ private TransformingTouchDelegate mChipTouchDelegate;
private static final List<Rect> SYSTEM_GESTURE_EXCLUSION_RECT =
Collections.singletonList(new Rect());
- public static final FloatProperty<TaskView> FOCUS_TRANSITION =
+ private static final FloatProperty<TaskView> FOCUS_TRANSITION =
new FloatProperty<TaskView>("focusTransition") {
@Override
public void setValue(TaskView taskView, float v) {
@@ -310,71 +284,69 @@ public class TaskView extends FrameLayout implements Reusable {
}
};
- private static final FloatProperty<TaskView> NON_GRID_TRANSLATION_X =
- new FloatProperty<TaskView>("nonGridTranslationX") {
+ private static final FloatProperty<TaskView> FULLSCREEN_TRANSLATION_X =
+ new FloatProperty<TaskView>("fullscreenTranslationX") {
@Override
public void setValue(TaskView taskView, float v) {
- taskView.setNonGridTranslationX(v);
+ taskView.setFullscreenTranslationX(v);
}
@Override
public Float get(TaskView taskView) {
- return taskView.mNonGridTranslationX;
+ return taskView.mFullscreenTranslationX;
}
};
- private static final FloatProperty<TaskView> NON_GRID_TRANSLATION_Y =
- new FloatProperty<TaskView>("nonGridTranslationY") {
+ private static final FloatProperty<TaskView> FULLSCREEN_TRANSLATION_Y =
+ new FloatProperty<TaskView>("fullscreenTranslationY") {
@Override
public void setValue(TaskView taskView, float v) {
- taskView.setNonGridTranslationY(v);
+ taskView.setFullscreenTranslationY(v);
}
@Override
public Float get(TaskView taskView) {
- return taskView.mNonGridTranslationY;
+ return taskView.mFullscreenTranslationY;
}
};
- public static final FloatProperty<TaskView> GRID_END_TRANSLATION_X =
- new FloatProperty<TaskView>("gridEndTranslationX") {
+ private static final FloatProperty<TaskView> NON_FULLSCREEN_TRANSLATION_X =
+ new FloatProperty<TaskView>("nonFullscreenTranslationX") {
@Override
public void setValue(TaskView taskView, float v) {
- taskView.setGridEndTranslationX(v);
+ taskView.setNonFullscreenTranslationX(v);
}
@Override
public Float get(TaskView taskView) {
- return taskView.mGridEndTranslationX;
+ return taskView.mNonFullscreenTranslationX;
}
};
- public static final FloatProperty<TaskView> SNAPSHOT_SCALE =
- new FloatProperty<TaskView>("snapshotScale") {
+ private static final FloatProperty<TaskView> NON_FULLSCREEN_TRANSLATION_Y =
+ new FloatProperty<TaskView>("nonFullscreenTranslationY") {
@Override
public void setValue(TaskView taskView, float v) {
- taskView.setSnapshotScale(v);
+ taskView.setNonFullscreenTranslationY(v);
}
@Override
public Float get(TaskView taskView) {
- return taskView.mSnapshotView.getScaleX();
+ return taskView.mNonFullscreenTranslationY;
}
};
private final TaskOutlineProvider mOutlineProvider;
- @Nullable
- protected Task mTask;
- protected TaskThumbnailView mSnapshotView;
- protected IconView mIconView;
- protected final DigitalWellBeingToast mDigitalWellBeingToast;
+ private Task mTask;
+ private TaskThumbnailView mSnapshotView;
+ private IconView mIconView;
+ private final DigitalWellBeingToast mDigitalWellBeingToast;
private float mFullscreenProgress;
private float mGridProgress;
- private float mNonGridScale = 1;
- private float mDismissScale = 1;
- protected final FullscreenDrawParams mCurrentFullscreenParams;
- protected final StatefulActivity mActivity;
+ private float mFullscreenScale = 1;
+ private final FullscreenDrawParams mCurrentFullscreenParams;
+ private final StatefulActivity mActivity;
// Various causes of changing primary translation, which we aggregate to setTranslationX/Y().
private float mDismissTranslationX;
@@ -384,62 +356,49 @@ public class TaskView extends FrameLayout implements Reusable {
private float mTaskResistanceTranslationX;
private float mTaskResistanceTranslationY;
// The following translation variables should only be used in the same orientation as Launcher.
+ private float mFullscreenTranslationX;
+ private float mFullscreenTranslationY;
+ // Applied as a complement to fullscreenTranslation, for adjusting the carousel overview, or the
+ // in transition carousel before forming the grid on tablets.
+ private float mNonFullscreenTranslationX;
+ private float mNonFullscreenTranslationY;
private float mBoxTranslationY;
// The following grid translations scales with mGridProgress.
private float mGridTranslationX;
private float mGridTranslationY;
- // The following grid translation is used to animate closing the gap between grid and clear all.
- private float mGridEndTranslationX;
- // Applied as a complement to gridTranslation, for adjusting the carousel overview and quick
- // switch.
- private float mNonGridTranslationX;
- private float mNonGridTranslationY;
// Used when in SplitScreenSelectState
private float mSplitSelectTranslationY;
private float mSplitSelectTranslationX;
- private float mSplitSelectScrollOffsetPrimary;
- @Nullable
private ObjectAnimator mIconAndDimAnimator;
private float mIconScaleAnimStartProgress = 0;
private float mFocusTransitionProgress = 1;
private float mModalness = 0;
private float mStableAlpha = 1;
- private int mTaskViewId = -1;
- /**
- * Index 0 will contain taskID of left/top task, index 1 will contain taskId of bottom/right
- */
- protected final int[] mTaskIdContainer = new int[]{-1, -1};
- protected final TaskIdAttributeContainer[] mTaskIdAttributeContainer =
- new TaskIdAttributeContainer[2];
-
private boolean mShowScreenshot;
// The current background requests to load the task thumbnail and icon
- @Nullable
private CancellableTask mThumbnailLoadRequest;
- @Nullable
private CancellableTask mIconLoadRequest;
private boolean mEndQuickswitchCuj;
+ private View mContextualChipWrapper;
private final float[] mIconCenterCoords = new float[2];
-
- private final PointF mLastTouchDownPosition = new PointF();
+ private final float[] mChipCenterCoords = new float[2];
private boolean mIsClickableAsLiveTile = true;
-
public TaskView(Context context) {
this(context, null);
}
- public TaskView(Context context, @Nullable AttributeSet attrs) {
+ public TaskView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
- public TaskView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
+ public TaskView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mActivity = StatefulActivity.fromContext(context);
setOnClickListener(this::onClick);
@@ -452,36 +411,19 @@ public class TaskView extends FrameLayout implements Reusable {
setOutlineProvider(mOutlineProvider);
}
- public void setTaskViewId(int id) {
- this.mTaskViewId = id;
- }
-
- public int getTaskViewId() {
- return mTaskViewId;
- }
-
/**
* Builds proto for logging
*/
public WorkspaceItemInfo getItemInfo() {
- return getItemInfo(mTask);
- }
-
- protected WorkspaceItemInfo getItemInfo(@Nullable Task task) {
+ final Task task = getTask();
+ ComponentKey componentKey = TaskUtils.getLaunchComponentKeyForTask(task.key);
WorkspaceItemInfo stubInfo = new WorkspaceItemInfo();
stubInfo.itemType = LauncherSettings.Favorites.ITEM_TYPE_TASK;
stubInfo.container = LauncherSettings.Favorites.CONTAINER_TASKSWITCHER;
- if (task == null) {
- return stubInfo;
- }
-
- ComponentKey componentKey = TaskUtils.getLaunchComponentKeyForTask(task.key);
stubInfo.user = componentKey.user;
stubInfo.intent = new Intent().setComponent(componentKey.componentName);
stubInfo.title = task.title;
- if (getRecentsView() != null) {
- stubInfo.screenId = getRecentsView().indexOfChild(this);
- }
+ stubInfo.screenId = getRecentsView().indexOfChild(this);
return stubInfo;
}
@@ -499,25 +441,45 @@ public class TaskView extends FrameLayout implements Reusable {
*/
public boolean offerTouchToChildren(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
- computeAndSetIconTouchDelegate(mIconView, mIconCenterCoords, mIconTouchDelegate);
+ computeAndSetIconTouchDelegate();
+ computeAndSetChipTouchDelegate();
}
if (mIconTouchDelegate != null && mIconTouchDelegate.onTouchEvent(event)) {
return true;
}
+ if (mChipTouchDelegate != null && mChipTouchDelegate.onTouchEvent(event)) {
+ return true;
+ }
return false;
}
- protected void computeAndSetIconTouchDelegate(IconView iconView, float[] tempCenterCoords,
- TransformingTouchDelegate transformingTouchDelegate) {
- float iconHalfSize = iconView.getWidth() / 2f;
- tempCenterCoords[0] = tempCenterCoords[1] = iconHalfSize;
- getDescendantCoordRelativeToAncestor(iconView, mActivity.getDragLayer(), tempCenterCoords,
+ private void computeAndSetIconTouchDelegate() {
+ float iconHalfSize = mIconView.getWidth() / 2f;
+ mIconCenterCoords[0] = mIconCenterCoords[1] = iconHalfSize;
+ getDescendantCoordRelativeToAncestor(mIconView, mActivity.getDragLayer(), mIconCenterCoords,
false);
- transformingTouchDelegate.setBounds(
- (int) (tempCenterCoords[0] - iconHalfSize),
- (int) (tempCenterCoords[1] - iconHalfSize),
- (int) (tempCenterCoords[0] + iconHalfSize),
- (int) (tempCenterCoords[1] + iconHalfSize));
+ mIconTouchDelegate.setBounds(
+ (int) (mIconCenterCoords[0] - iconHalfSize),
+ (int) (mIconCenterCoords[1] - iconHalfSize),
+ (int) (mIconCenterCoords[0] + iconHalfSize),
+ (int) (mIconCenterCoords[1] + iconHalfSize));
+ }
+
+ private void computeAndSetChipTouchDelegate() {
+ if (mContextualChipWrapper != null) {
+ float chipHalfWidth = mContextualChipWrapper.getWidth() / 2f;
+ float chipHalfHeight = mContextualChipWrapper.getHeight() / 2f;
+ mChipCenterCoords[0] = chipHalfWidth;
+ mChipCenterCoords[1] = chipHalfHeight;
+ getDescendantCoordRelativeToAncestor(mContextualChipWrapper, mActivity.getDragLayer(),
+ mChipCenterCoords,
+ false);
+ mChipTouchDelegate.setBounds(
+ (int) (mChipCenterCoords[0] - chipHalfWidth),
+ (int) (mChipCenterCoords[1] - chipHalfHeight),
+ (int) (mChipCenterCoords[0] + chipHalfWidth),
+ (int) (mChipCenterCoords[1] + chipHalfHeight));
+ }
}
/**
@@ -532,6 +494,10 @@ public class TaskView extends FrameLayout implements Reusable {
}
mModalness = modalness;
mIconView.setAlpha(comp(modalness));
+ if (mContextualChipWrapper != null) {
+ mContextualChipWrapper.setScaleX(comp(modalness));
+ mContextualChipWrapper.setScaleY(comp(modalness));
+ }
mDigitalWellBeingToast.updateBannerOffset(modalness,
mCurrentFullscreenParams.mCurrentDrawnInsets.top
+ mCurrentFullscreenParams.mCurrentDrawnInsets.bottom);
@@ -550,119 +516,103 @@ public class TaskView extends FrameLayout implements Reusable {
public void bind(Task task, RecentsOrientedState orientedState) {
cancelPendingLoadTasks();
mTask = task;
- mTaskIdContainer[0] = mTask.key.id;
- mTaskIdAttributeContainer[0] = new TaskIdAttributeContainer(task, mSnapshotView,
- mIconView, STAGE_POSITION_UNDEFINED);
mSnapshotView.bind(task);
setOrientationState(orientedState);
}
- public TaskIdAttributeContainer[] getTaskIdAttributeContainers() {
- return mTaskIdAttributeContainer;
- }
-
- @Nullable
public Task getTask() {
return mTask;
}
- /**
- * @return integer array of two elements to be size consistent with max number of tasks possible
- * index 0 will contain the taskId, index 1 will be -1 indicating a null taskID value
- */
- public int[] getTaskIds() {
- return mTaskIdContainer;
- }
-
- public boolean containsMultipleTasks() {
- return mTaskIdContainer[1] != -1;
+ public boolean hasTaskId(int taskId) {
+ return mTask != null && mTask.key != null && mTask.key.id == taskId;
}
public TaskThumbnailView getThumbnail() {
return mSnapshotView;
}
- void refreshThumbnails(@Nullable HashMap<Integer, ThumbnailData> thumbnailDatas) {
- if (mTask != null && thumbnailDatas != null) {
- final ThumbnailData thumbnailData = thumbnailDatas.get(mTask.key.id);
- if (thumbnailData != null) {
- mSnapshotView.setThumbnail(mTask, thumbnailData);
- return;
- }
- }
-
- mSnapshotView.refresh();
- }
-
- /** TODO(b/197033698) Remove all usages of above method and migrate to this one */
- public TaskThumbnailView[] getThumbnails() {
- return new TaskThumbnailView[]{mSnapshotView};
- }
-
public IconView getIconView() {
return mIconView;
}
- @Override
- public boolean dispatchTouchEvent(MotionEvent ev) {
- if (ev.getAction() == MotionEvent.ACTION_DOWN) {
- mLastTouchDownPosition.set(ev.getX(), ev.getY());
- }
- return super.dispatchTouchEvent(ev);
- }
-
private void onClick(View view) {
if (getTask() == null) {
return;
}
- if (confirmSecondSplitSelectApp()) {
- return;
+ if (ENABLE_QUICKSTEP_LIVE_TILE.get() && isRunningTask()) {
+ if (!mIsClickableAsLiveTile) {
+ return;
+ }
+
+ // Reset the minimized state since we force-toggled the minimized state when entering
+ // overview, but never actually finished the recents animation
+ SystemUiProxy p = SystemUiProxy.INSTANCE.getNoCreate();
+ if (p != null) {
+ p.setSplitScreenMinimized(false);
+ }
+
+ mIsClickableAsLiveTile = false;
+ RecentsView recentsView = getRecentsView();
+ final RemoteAnimationTargets targets = recentsView.getLiveTileParams().getTargetSet();
+ if (targets == null) {
+ // If the recents animation is cancelled somehow between the parent if block and
+ // here, try to launch the task as a non live tile task.
+ launcherNonLiveTileTask();
+ return;
+ }
+
+ AnimatorSet anim = new AnimatorSet();
+ TaskViewUtils.composeRecentsLaunchAnimator(
+ anim, this, targets.apps,
+ targets.wallpapers, targets.nonApps, true /* launcherClosing */,
+ mActivity.getStateManager(), recentsView,
+ recentsView.getDepthController());
+ anim.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationStart(Animator animator) {
+ recentsView.getLiveTileTaskViewSimulator().setDrawsBelowRecents(false);
+ }
+
+ @Override
+ public void onAnimationEnd(Animator animator) {
+ recentsView.getLiveTileTaskViewSimulator().setDrawsBelowRecents(true);
+ mIsClickableAsLiveTile = true;
+ }
+ });
+ anim.start();
+ } else {
+ launcherNonLiveTileTask();
}
- launchTasks();
mActivity.getStatsLogManager().logger().withItemInfo(getItemInfo())
.log(LAUNCHER_TASK_LAUNCH_TAP);
}
- /**
- * @return {@code true} if user is already in split select mode and this tap was to choose the
- * second app. {@code false} otherwise
- */
- private boolean confirmSecondSplitSelectApp() {
- int index = getChildTaskIndexAtPosition(mLastTouchDownPosition);
- TaskIdAttributeContainer container = mTaskIdAttributeContainer[index];
- return getRecentsView().confirmSplitSelect(this, container.getTask(),
- container.getIconView(), container.getThumbnailView());
- }
-
- /**
- * Returns the task under the given position in the local coordinates of this task view.
- */
- protected int getChildTaskIndexAtPosition(PointF position) {
- return 0;
+ private void launcherNonLiveTileTask() {
+ if (mActivity.isInState(OVERVIEW_SPLIT_SELECT)) {
+ // User tapped to select second split screen app
+ getRecentsView().confirmSplitSelect(this);
+ } else {
+ launchTaskAnimated();
+ }
}
/**
* Starts the task associated with this view and animates the startup.
* @return CompletionStage to indicate the animation completion or null if the launch failed.
*/
- @Nullable
public RunnableList launchTaskAnimated() {
if (mTask != null) {
TestLogging.recordEvent(
TestProtocol.SEQUENCE_MAIN, "startActivityFromRecentsAsync", mTask);
ActivityOptionsWrapper opts = mActivity.getActivityLaunchOptions(this, null);
- opts.options.setLaunchDisplayId(
- getDisplay() == null ? DEFAULT_DISPLAY : getDisplay().getDisplayId());
if (ActivityManagerWrapper.getInstance()
.startActivityFromRecents(mTask.key, opts.options)) {
- RecentsView recentsView = getRecentsView();
- if (ENABLE_QUICKSTEP_LIVE_TILE.get() && recentsView.getRunningTaskViewId() != -1) {
- recentsView.onTaskLaunchedInLiveTileMode();
-
+ if (ENABLE_QUICKSTEP_LIVE_TILE.get() && getRecentsView().getRunningTaskId() != -1) {
// Return a fresh callback in the live tile case, so that it's not accidentally
// triggered by QuickstepTransitionManager.AppLaunchAnimationRunner.
RunnableList callbackList = new RunnableList();
- recentsView.addSideTaskLaunchCallback(callbackList);
+ getRecentsView().addSideTaskLaunchCallback(callbackList);
return callbackList;
}
return opts.onEndCallback;
@@ -693,8 +643,6 @@ public class TaskView extends FrameLayout implements Reusable {
// Indicate success once the system has indicated that the transition has started
ActivityOptions opts = ActivityOptionsCompat.makeCustomAnimation(
getContext(), 0, 0, () -> callback.accept(true), MAIN_EXECUTOR.getHandler());
- opts.setLaunchDisplayId(
- getDisplay() == null ? DEFAULT_DISPLAY : getDisplay().getDisplayId());
if (freezeTaskList) {
ActivityOptionsCompat.setFreezeRecentTasksList(opts);
}
@@ -716,79 +664,6 @@ public class TaskView extends FrameLayout implements Reusable {
}
/**
- * Launch of the current task (both live and inactive tasks) with an animation.
- */
- public void launchTasks() {
- RecentsView recentsView = getRecentsView();
- RemoteTargetHandle[] remoteTargetHandles = recentsView.mRemoteTargetHandles;
- if (ENABLE_QUICKSTEP_LIVE_TILE.get() && isRunningTask() && remoteTargetHandles != null) {
- if (!mIsClickableAsLiveTile) {
- return;
- }
-
- // Reset the minimized state since we force-toggled the minimized state when entering
- // overview, but never actually finished the recents animation
- SystemUiProxy.INSTANCE.get(getContext()).setSplitScreenMinimized(false);
-
- mIsClickableAsLiveTile = false;
- RemoteAnimationTargets targets;
- if (remoteTargetHandles.length == 1) {
- targets = remoteTargetHandles[0].getTransformParams().getTargetSet();
- } else {
- TransformParams topLeftParams = remoteTargetHandles[0].getTransformParams();
- TransformParams rightBottomParams = remoteTargetHandles[1].getTransformParams();
- RemoteAnimationTargetCompat[] apps = Stream.concat(
- Arrays.stream(topLeftParams.getTargetSet().apps),
- Arrays.stream(rightBottomParams.getTargetSet().apps))
- .toArray(RemoteAnimationTargetCompat[]::new);
- RemoteAnimationTargetCompat[] wallpapers = Stream.concat(
- Arrays.stream(topLeftParams.getTargetSet().wallpapers),
- Arrays.stream(rightBottomParams.getTargetSet().wallpapers))
- .toArray(RemoteAnimationTargetCompat[]::new);
- targets = new RemoteAnimationTargets(apps, wallpapers,
- topLeftParams.getTargetSet().nonApps,
- topLeftParams.getTargetSet().targetMode);
- }
- if (targets == null) {
- // If the recents animation is cancelled somehow between the parent if block and
- // here, try to launch the task as a non live tile task.
- launchTaskAnimated();
- mIsClickableAsLiveTile = true;
- return;
- }
-
- AnimatorSet anim = new AnimatorSet();
- TaskViewUtils.composeRecentsLaunchAnimator(
- anim, this, targets.apps,
- targets.wallpapers, targets.nonApps, true /* launcherClosing */,
- mActivity.getStateManager(), recentsView,
- recentsView.getDepthController());
- anim.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationStart(Animator animation) {
- recentsView.runActionOnRemoteHandles(
- (Consumer<RemoteTargetHandle>) remoteTargetHandle ->
- remoteTargetHandle
- .getTaskViewSimulator()
- .setDrawsBelowRecents(false));
- }
-
- @Override
- public void onAnimationEnd(Animator animator) {
- if (mTask != null && mTask.key.displayId != getRootViewDisplayId()) {
- launchTaskAnimated();
- }
- mIsClickableAsLiveTile = true;
- }
- });
- anim.start();
- recentsView.onTaskLaunchedInLiveTileMode();
- } else {
- launchTaskAnimated();
- }
- }
-
- /**
* See {@link TaskDataChanges}
* @param visible If this task view will be visible to the user in overview or hidden
*/
@@ -821,7 +696,7 @@ public class TaskView extends FrameLayout implements Reusable {
if (needsUpdate(changes, FLAG_UPDATE_ICON)) {
mIconLoadRequest = iconCache.updateIconInBackground(mTask,
(task) -> {
- setIcon(mIconView, task.icon);
+ setIcon(task.icon);
mDigitalWellBeingToast.initialize(mTask);
});
}
@@ -833,16 +708,16 @@ public class TaskView extends FrameLayout implements Reusable {
mTask.thumbnail = null;
}
if (needsUpdate(changes, FLAG_UPDATE_ICON)) {
- setIcon(mIconView, null);
+ setIcon(null);
}
}
}
- protected boolean needsUpdate(@TaskDataChanges int dataChange, @TaskDataChanges int flag) {
+ private boolean needsUpdate(@TaskDataChanges int dataChange, @TaskDataChanges int flag) {
return (dataChange & flag) == flag;
}
- protected void cancelPendingLoadTasks() {
+ private void cancelPendingLoadTasks() {
if (mThumbnailLoadRequest != null) {
mThumbnailLoadRequest.cancel();
mThumbnailLoadRequest = null;
@@ -853,95 +728,82 @@ public class TaskView extends FrameLayout implements Reusable {
}
}
- private boolean showTaskMenu(IconView iconView) {
- if (!getRecentsView().canLaunchFullscreenTask()) {
+ private boolean showTaskMenu() {
+ if (getRecentsView().mActivity.isInState(OVERVIEW_SPLIT_SELECT)) {
// Don't show menu when selecting second split screen app
return true;
}
- if (!mActivity.getDeviceProfile().isTablet
- && !getRecentsView().isClearAllHidden()) {
+ if (!getRecentsView().isClearAllHidden()) {
getRecentsView().snapToPage(getRecentsView().indexOfChild(this));
return false;
} else {
mActivity.getStatsLogManager().logger().withItemInfo(getItemInfo())
.log(LAUNCHER_TASK_ICON_TAP_OR_LONGPRESS);
- return showTaskMenuWithContainer(iconView);
- }
- }
-
- protected boolean showTaskMenuWithContainer(IconView iconView) {
- TaskIdAttributeContainer menuContainer =
- mTaskIdAttributeContainer[iconView == mIconView ? 0 : 1];
- if (mActivity.getDeviceProfile().isTablet) {
- boolean alignSecondRow = getRecentsView().isOnGridBottomRow(menuContainer.getTaskView())
- && mActivity.getDeviceProfile().isLandscape;
- return TaskMenuViewWithArrow.Companion.showForTask(menuContainer, alignSecondRow);
- } else {
- return TaskMenuView.showForTask(menuContainer);
+ return TaskMenuView.showForTask(this);
}
}
- protected void setIcon(IconView iconView, @Nullable Drawable icon) {
+ private void setIcon(Drawable icon) {
if (icon != null) {
- iconView.setDrawable(icon);
- iconView.setOnClickListener(v -> {
- if (confirmSecondSplitSelectApp()) {
- return;
- }
- showTaskMenu(iconView);
- });
- iconView.setOnLongClickListener(v -> {
+ mIconView.setDrawable(icon);
+ mIconView.setOnClickListener(v -> showTaskMenu());
+ mIconView.setOnLongClickListener(v -> {
requestDisallowInterceptTouchEvent(true);
- return showTaskMenu(iconView);
+ return showTaskMenu();
});
} else {
- iconView.setDrawable(null);
- iconView.setOnClickListener(null);
- iconView.setOnLongClickListener(null);
+ mIconView.setDrawable(null);
+ mIconView.setOnClickListener(null);
+ mIconView.setOnLongClickListener(null);
}
}
public void setOrientationState(RecentsOrientedState orientationState) {
PagedOrientationHandler orientationHandler = orientationState.getOrientationHandler();
boolean isRtl = getLayoutDirection() == LAYOUT_DIRECTION_RTL;
+ LayoutParams snapshotParams = (LayoutParams) mSnapshotView.getLayoutParams();
DeviceProfile deviceProfile = mActivity.getDeviceProfile();
-
- boolean isGridTask = isGridTask();
- LayoutParams iconParams = (LayoutParams) mIconView.getLayoutParams();
-
- int thumbnailTopMargin = deviceProfile.overviewTaskThumbnailTopMarginPx;
+ snapshotParams.topMargin = deviceProfile.overviewTaskThumbnailTopMarginPx;
+ int taskIconMargin = deviceProfile.overviewTaskMarginPx;
int taskIconHeight = deviceProfile.overviewTaskIconSizePx;
- int taskMargin = isGridTask ? deviceProfile.overviewTaskMarginGridPx
- : deviceProfile.overviewTaskMarginPx;
- int taskIconMargin = thumbnailTopMargin - taskIconHeight - taskMargin;
- orientationHandler.setTaskIconParams(iconParams, taskIconMargin, taskIconHeight,
- thumbnailTopMargin, isRtl);
+ LayoutParams iconParams = (LayoutParams) mIconView.getLayoutParams();
+ switch (orientationHandler.getRotation()) {
+ case ROTATION_90:
+ iconParams.gravity = (isRtl ? START : END) | CENTER_VERTICAL;
+ iconParams.rightMargin = -taskIconHeight - taskIconMargin / 2;
+ iconParams.leftMargin = 0;
+ iconParams.topMargin = snapshotParams.topMargin / 2;
+ break;
+ case ROTATION_180:
+ iconParams.gravity = BOTTOM | CENTER_HORIZONTAL;
+ iconParams.bottomMargin = -snapshotParams.topMargin;
+ iconParams.leftMargin = iconParams.rightMargin = 0;
+ iconParams.topMargin = taskIconMargin;
+ break;
+ case ROTATION_270:
+ iconParams.gravity = (isRtl ? END : START) | CENTER_VERTICAL;
+ iconParams.leftMargin = -taskIconHeight - taskIconMargin / 2;
+ iconParams.rightMargin = 0;
+ iconParams.topMargin = snapshotParams.topMargin / 2;
+ break;
+ case Surface.ROTATION_0:
+ default:
+ iconParams.gravity = TOP | CENTER_HORIZONTAL;
+ iconParams.leftMargin = iconParams.rightMargin = 0;
+ iconParams.topMargin = taskIconMargin;
+ break;
+ }
+ mSnapshotView.setLayoutParams(snapshotParams);
iconParams.width = iconParams.height = taskIconHeight;
mIconView.setLayoutParams(iconParams);
-
mIconView.setRotation(orientationHandler.getDegreesRotated());
- int iconDrawableSize = isGridTask ? deviceProfile.overviewTaskIconDrawableSizeGridPx
- : deviceProfile.overviewTaskIconDrawableSizePx;
- mIconView.setDrawableSize(iconDrawableSize, iconDrawableSize);
-
- LayoutParams snapshotParams = (LayoutParams) mSnapshotView.getLayoutParams();
- snapshotParams.topMargin = thumbnailTopMargin;
+ snapshotParams.topMargin = deviceProfile.overviewTaskThumbnailTopMarginPx;
mSnapshotView.setLayoutParams(snapshotParams);
-
- mSnapshotView.getTaskOverlay().updateOrientationState(orientationState);
- mDigitalWellBeingToast.initialize(mTask);
- }
-
- /**
- * Returns whether the task is part of overview grid and not being focused.
- */
- public boolean isGridTask() {
- DeviceProfile deviceProfile = mActivity.getDeviceProfile();
- return deviceProfile.isTablet && !isFocusedTask();
+ getThumbnail().getTaskOverlay().updateOrientationState(orientationState);
}
- protected void setIconAndDimTransitionProgress(float progress, boolean invert) {
+ private void setIconAndDimTransitionProgress(float progress, boolean invert) {
if (invert) {
progress = 1 - progress;
}
@@ -952,6 +814,11 @@ public class TaskView extends FrameLayout implements Reusable {
float scale = Interpolators.clampToProgress(FAST_OUT_SLOW_IN, lowerClamp, upperClamp)
.getInterpolation(progress);
mIconView.setAlpha(scale);
+ if (mContextualChipWrapper != null && mContextualChipWrapper != null) {
+ mContextualChipWrapper.setAlpha(scale);
+ mContextualChipWrapper.setScaleX(Math.min(scale, comp(mModalness)));
+ mContextualChipWrapper.setScaleY(Math.min(scale, comp(mModalness)));
+ }
mDigitalWellBeingToast.updateBannerOffset(1f - scale,
mCurrentFullscreenParams.mCurrentDrawnInsets.top
+ mCurrentFullscreenParams.mCurrentDrawnInsets.bottom);
@@ -988,23 +855,13 @@ public class TaskView extends FrameLayout implements Reusable {
setIconAndDimTransitionProgress(iconScale, invert);
}
- protected void resetPersistentViewTransforms() {
- mNonGridTranslationX = mNonGridTranslationY =
- mGridTranslationX = mGridTranslationY = mBoxTranslationY = 0f;
- resetViewTransforms();
- }
-
protected void resetViewTransforms() {
// fullscreenTranslation and accumulatedTranslation should not be reset, as
// resetViewTransforms is called during Quickswitch scrolling.
- mDismissTranslationX = mTaskOffsetTranslationX =
- mTaskResistanceTranslationX = mSplitSelectTranslationX = mGridEndTranslationX = 0f;
- mDismissTranslationY = mTaskOffsetTranslationY = mTaskResistanceTranslationY = 0f;
- if (getRecentsView() == null || !getRecentsView().isSplitSelectionActive()) {
- mSplitSelectTranslationY = 0f;
- }
-
- setSnapshotScale(1f);
+ mDismissTranslationX = mTaskOffsetTranslationX = mTaskResistanceTranslationX =
+ mSplitSelectTranslationX = 0f;
+ mDismissTranslationY = mTaskOffsetTranslationY = mTaskResistanceTranslationY =
+ mSplitSelectTranslationY = 0f;
applyTranslationX();
applyTranslationY();
setTranslationZ(0);
@@ -1020,7 +877,10 @@ public class TaskView extends FrameLayout implements Reusable {
@Override
public void onRecycle() {
- resetPersistentViewTransforms();
+ mFullscreenTranslationX = mFullscreenTranslationY = mNonFullscreenTranslationX =
+ mNonFullscreenTranslationY = mGridTranslationX = mGridTranslationY =
+ mBoxTranslationY = 0f;
+ resetViewTransforms();
// Clear any references to the thumbnail (it will be re-read either from the cache or the
// system on next bind)
mSnapshotView.setThumbnail(mTask, null);
@@ -1028,14 +888,57 @@ public class TaskView extends FrameLayout implements Reusable {
onTaskListVisibilityChanged(false);
}
+ /**
+ * Sets the contextual chip.
+ *
+ * @param view Wrapper view containing contextual chip.
+ */
+ public void setContextualChip(View view) {
+ if (mContextualChipWrapper != null) {
+ removeView(mContextualChipWrapper);
+ }
+ if (view != null) {
+ mContextualChipWrapper = view;
+ LayoutParams layoutParams = new LayoutParams(((View) getParent()).getMeasuredWidth(),
+ LayoutParams.WRAP_CONTENT);
+ layoutParams.gravity = BOTTOM | CENTER_HORIZONTAL;
+ int expectedChipHeight = getExpectedViewHeight(view);
+ float chipOffset = getResources().getDimension(R.dimen.chip_hint_vertical_offset);
+ layoutParams.bottomMargin = -expectedChipHeight - (int) chipOffset;
+ mContextualChipWrapper.setScaleX(0f);
+ mContextualChipWrapper.setScaleY(0f);
+ addView(view, getChildCount(), layoutParams);
+ if (mContextualChipWrapper != null) {
+ float scale = comp(mModalness);
+ mContextualChipWrapper.animate().scaleX(scale).scaleY(scale).setDuration(50);
+ mChipTouchDelegate = new TransformingTouchDelegate(mContextualChipWrapper);
+ }
+ }
+ }
+
public float getTaskCornerRadius() {
- return mCurrentFullscreenParams.mCornerRadius;
+ return TaskCornerRadius.get(mActivity);
+ }
+
+ /**
+ * Clears the contextual chip from TaskView.
+ *
+ * @return The contextual chip wrapper view to be recycled.
+ */
+ public View clearContextualChip() {
+ if (mContextualChipWrapper != null) {
+ removeView(mContextualChipWrapper);
+ }
+ View oldContextualChipWrapper = mContextualChipWrapper;
+ mContextualChipWrapper = null;
+ mChipTouchDelegate = null;
+ return oldContextualChipWrapper;
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
- if (mActivity.getDeviceProfile().isTablet) {
+ if (mActivity.getDeviceProfile().isTablet && FeatureFlags.ENABLE_OVERVIEW_GRID.get()) {
setPivotX(getLayoutDirection() == LAYOUT_DIRECTION_RTL ? 0 : right - left);
setPivotY(mSnapshotView.getTop());
} else {
@@ -1052,22 +955,20 @@ public class TaskView extends FrameLayout implements Reusable {
* How much to scale down pages near the edge of the screen.
*/
public static float getEdgeScaleDownFactor(DeviceProfile deviceProfile) {
- return deviceProfile.isTablet ? EDGE_SCALE_DOWN_FACTOR_GRID
- : EDGE_SCALE_DOWN_FACTOR_CAROUSEL;
+ if (deviceProfile.isTablet && FeatureFlags.ENABLE_OVERVIEW_GRID.get()) {
+ return EDGE_SCALE_DOWN_FACTOR_GRID;
+ } else {
+ return EDGE_SCALE_DOWN_FACTOR_CAROUSEL;
+ }
}
- private void setNonGridScale(float nonGridScale) {
- mNonGridScale = nonGridScale;
+ private void setFullscreenScale(float fullscreenScale) {
+ mFullscreenScale = fullscreenScale;
applyScale();
}
- public float getNonGridScale() {
- return mNonGridScale;
- }
-
- private void setSnapshotScale(float dismissScale) {
- mDismissScale = dismissScale;
- applyScale();
+ public float getFullscreenScale() {
+ return mFullscreenScale;
}
/**
@@ -1084,22 +985,10 @@ public class TaskView extends FrameLayout implements Reusable {
private void applyScale() {
float scale = 1;
- scale *= getPersistentScale();
- scale *= mDismissScale;
+ float fullScreenProgress = FULLSCREEN_INTERPOLATOR.getInterpolation(mFullscreenProgress);
+ scale *= Utilities.mapRange(fullScreenProgress, 1f, mFullscreenScale);
setScaleX(scale);
setScaleY(scale);
- updateSnapshotRadius();
- }
-
- /**
- * Returns multiplication of scale that is persistent (e.g. fullscreen and grid), and does not
- * change according to a temporary state.
- */
- public float getPersistentScale() {
- float scale = 1;
- float gridProgress = GRID_INTERPOLATOR.getInterpolation(mGridProgress);
- scale *= Utilities.mapRange(gridProgress, mNonGridScale, 1f);
- return scale;
}
private void setSplitSelectTranslationX(float x) {
@@ -1111,11 +1000,6 @@ public class TaskView extends FrameLayout implements Reusable {
mSplitSelectTranslationY = y;
applyTranslationY();
}
-
- public void setSplitScrollOffsetPrimary(float splitSelectScrollOffsetPrimary) {
- mSplitSelectScrollOffsetPrimary = splitSelectScrollOffsetPrimary;
- }
-
private void setDismissTranslationX(float x) {
mDismissTranslationX = x;
applyTranslationX();
@@ -1146,13 +1030,23 @@ public class TaskView extends FrameLayout implements Reusable {
applyTranslationY();
}
- private void setNonGridTranslationX(float nonGridTranslationX) {
- mNonGridTranslationX = nonGridTranslationX;
+ private void setFullscreenTranslationX(float fullscreenTranslationX) {
+ mFullscreenTranslationX = fullscreenTranslationX;
applyTranslationX();
}
- private void setNonGridTranslationY(float nonGridTranslationY) {
- mNonGridTranslationY = nonGridTranslationY;
+ private void setFullscreenTranslationY(float fullscreenTranslationY) {
+ mFullscreenTranslationY = fullscreenTranslationY;
+ applyTranslationY();
+ }
+
+ private void setNonFullscreenTranslationX(float nonFullscreenTranslationX) {
+ mNonFullscreenTranslationX = nonFullscreenTranslationX;
+ applyTranslationX();
+ }
+
+ private void setNonFullscreenTranslationY(float nonFullscreenTranslationY) {
+ mNonFullscreenTranslationY = nonFullscreenTranslationY;
applyTranslationY();
}
@@ -1174,19 +1068,16 @@ public class TaskView extends FrameLayout implements Reusable {
return mGridTranslationY;
}
- private void setGridEndTranslationX(float gridEndTranslationX) {
- mGridEndTranslationX = gridEndTranslationX;
- applyTranslationX();
- }
-
public float getScrollAdjustment(boolean fullscreenEnabled, boolean gridEnabled) {
float scrollAdjustment = 0;
+ if (fullscreenEnabled) {
+ scrollAdjustment += getPrimaryFullscreenTranslationProperty().get(this);
+ } else {
+ scrollAdjustment += getPrimaryNonFullscreenTranslationProperty().get(this);
+ }
if (gridEnabled) {
scrollAdjustment += mGridTranslationX;
- } else {
- scrollAdjustment += getPrimaryNonGridTranslationProperty().get(this);
}
- scrollAdjustment += mSplitSelectScrollOffsetPrimary;
return scrollAdjustment;
}
@@ -1197,7 +1088,7 @@ public class TaskView extends FrameLayout implements Reusable {
public float getSizeAdjustment(boolean fullscreenEnabled) {
float sizeAdjustment = 1;
if (fullscreenEnabled) {
- sizeAdjustment *= mNonGridScale;
+ sizeAdjustment *= mFullscreenScale;
}
return sizeAdjustment;
}
@@ -1209,7 +1100,7 @@ public class TaskView extends FrameLayout implements Reusable {
private void applyTranslationX() {
setTranslationX(mDismissTranslationX + mTaskOffsetTranslationX + mTaskResistanceTranslationX
- + mSplitSelectTranslationX + mGridEndTranslationX + getPersistentTranslationX());
+ + mSplitSelectTranslationX + getPersistentTranslationX());
}
private void applyTranslationY() {
@@ -1222,7 +1113,9 @@ public class TaskView extends FrameLayout implements Reusable {
* change according to a temporary state (e.g. task offset).
*/
public float getPersistentTranslationX() {
- return getNonGridTrans(mNonGridTranslationX) + getGridTrans(mGridTranslationX);
+ return getFullscreenTrans(mFullscreenTranslationX)
+ + getNonFullscreenTrans(mNonFullscreenTranslationX)
+ + getGridTrans(mGridTranslationX);
}
/**
@@ -1231,7 +1124,8 @@ public class TaskView extends FrameLayout implements Reusable {
*/
public float getPersistentTranslationY() {
return mBoxTranslationY
- + getNonGridTrans(mNonGridTranslationY)
+ + getFullscreenTrans(mFullscreenTranslationY)
+ + getNonFullscreenTrans(mNonFullscreenTranslationY)
+ getGridTrans(mGridTranslationY);
}
@@ -1265,14 +1159,24 @@ public class TaskView extends FrameLayout implements Reusable {
TASK_RESISTANCE_TRANSLATION_X, TASK_RESISTANCE_TRANSLATION_Y);
}
- public FloatProperty<TaskView> getPrimaryNonGridTranslationProperty() {
+ public FloatProperty<TaskView> getPrimaryFullscreenTranslationProperty() {
return getPagedOrientationHandler().getPrimaryValue(
- NON_GRID_TRANSLATION_X, NON_GRID_TRANSLATION_Y);
+ FULLSCREEN_TRANSLATION_X, FULLSCREEN_TRANSLATION_Y);
}
- public FloatProperty<TaskView> getSecondaryNonGridTranslationProperty() {
+ public FloatProperty<TaskView> getSecondaryFullscreenTranslationProperty() {
return getPagedOrientationHandler().getSecondaryValue(
- NON_GRID_TRANSLATION_X, NON_GRID_TRANSLATION_Y);
+ FULLSCREEN_TRANSLATION_X, FULLSCREEN_TRANSLATION_Y);
+ }
+
+ public FloatProperty<TaskView> getPrimaryNonFullscreenTranslationProperty() {
+ return getPagedOrientationHandler().getPrimaryValue(
+ NON_FULLSCREEN_TRANSLATION_X, NON_FULLSCREEN_TRANSLATION_Y);
+ }
+
+ public FloatProperty<TaskView> getSecondaryNonFullscreenTranslationProperty() {
+ return getPagedOrientationHandler().getSecondaryValue(
+ NON_FULLSCREEN_TRANSLATION_X, NON_FULLSCREEN_TRANSLATION_Y);
}
@Override
@@ -1338,14 +1242,9 @@ public class TaskView extends FrameLayout implements Reusable {
getContext().getText(R.string.accessibility_close)));
final Context context = getContext();
- for (TaskIdAttributeContainer taskContainer : mTaskIdAttributeContainer) {
- if (taskContainer == null) {
- continue;
- }
- for (SystemShortcut s : TaskOverlayFactory.getEnabledShortcuts(this,
- mActivity.getDeviceProfile(), taskContainer)) {
- info.addAction(s.createAccessibilityAction(context));
- }
+ for (SystemShortcut s : TaskOverlayFactory.getEnabledShortcuts(this,
+ mActivity.getDeviceProfile())) {
+ info.addAction(s.createAccessibilityAction(context));
}
if (mDigitalWellBeingToast.hasLimit()) {
@@ -1376,16 +1275,11 @@ public class TaskView extends FrameLayout implements Reusable {
return true;
}
- for (TaskIdAttributeContainer taskContainer : mTaskIdAttributeContainer) {
- if (taskContainer == null) {
- continue;
- }
- for (SystemShortcut s : TaskOverlayFactory.getEnabledShortcuts(this,
- mActivity.getDeviceProfile(), taskContainer)) {
- if (s.hasHandlerForAction(action)) {
- s.onClick(this);
- return true;
- }
+ for (SystemShortcut s : TaskOverlayFactory.getEnabledShortcuts(this,
+ mActivity.getDeviceProfile())) {
+ if (s.hasHandlerForAction(action)) {
+ s.onClick(this);
+ return true;
}
}
@@ -1418,27 +1312,37 @@ public class TaskView extends FrameLayout implements Reusable {
progress = Utilities.boundToRange(progress, 0, 1);
mFullscreenProgress = progress;
mIconView.setVisibility(progress < 1 ? VISIBLE : INVISIBLE);
- mSnapshotView.getTaskOverlay().setFullscreenProgress(progress);
+ getThumbnail().getTaskOverlay().setFullscreenProgress(progress);
- updateSnapshotRadius();
+ applyTranslationX();
+ applyTranslationY();
+ applyScale();
+
+ TaskThumbnailView thumbnail = getThumbnail();
+ updateCurrentFullscreenParams(thumbnail.getPreviewPositionHelper());
+ if (!getRecentsView().isTaskIconScaledDown(this)) {
+ // Some of the items in here are dependent on the current fullscreen params, but don't
+ // update them if the icon is supposed to be scaled down.
+ setIconScaleAndDim(progress, true /* invert */);
+ }
+
+ thumbnail.setFullscreenParams(mCurrentFullscreenParams);
mOutlineProvider.updateParams(
mCurrentFullscreenParams,
mActivity.getDeviceProfile().overviewTaskThumbnailTopMarginPx);
invalidateOutline();
}
- protected void updateSnapshotRadius() {
- updateCurrentFullscreenParams(mSnapshotView.getPreviewPositionHelper());
- mSnapshotView.setFullscreenParams(mCurrentFullscreenParams);
- }
-
void updateCurrentFullscreenParams(PreviewPositionHelper previewPositionHelper) {
if (getRecentsView() == null) {
return;
}
- mCurrentFullscreenParams.setProgress(mFullscreenProgress, getRecentsView().getScaleX(),
- getScaleX(), getWidth(), mActivity.getDeviceProfile(), previewPositionHelper);
+ mCurrentFullscreenParams.setProgress(
+ mFullscreenProgress,
+ getRecentsView().getScaleX(),
+ getWidth(), mActivity.getDeviceProfile(),
+ previewPositionHelper);
}
/**
@@ -1447,49 +1351,69 @@ public class TaskView extends FrameLayout implements Reusable {
*/
void updateTaskSize() {
ViewGroup.LayoutParams params = getLayoutParams();
- float nonGridScale;
+ float fullscreenScale;
float boxTranslationY;
int expectedWidth;
int expectedHeight;
- DeviceProfile deviceProfile = mActivity.getDeviceProfile();
- if (deviceProfile.isTablet) {
- final int thumbnailPadding = deviceProfile.overviewTaskThumbnailTopMarginPx;
+ if (mActivity.getDeviceProfile().isTablet && FeatureFlags.ENABLE_OVERVIEW_GRID.get()) {
+ final int thumbnailPadding =
+ mActivity.getDeviceProfile().overviewTaskThumbnailTopMarginPx;
final Rect lastComputedTaskSize = getRecentsView().getLastComputedTaskSize();
final int taskWidth = lastComputedTaskSize.width();
final int taskHeight = lastComputedTaskSize.height();
int boxWidth;
int boxHeight;
+ float thumbnailRatio;
boolean isFocusedTask = isFocusedTask();
if (isFocusedTask) {
// Task will be focused and should use focused task size. Use focusTaskRatio
// that is associated with the original orientation of the focused task.
boxWidth = taskWidth;
boxHeight = taskHeight;
+ thumbnailRatio = getRecentsView().getFocusedTaskRatio();
} else {
// Otherwise task is in grid, and should use lastComputedGridTaskSize.
Rect lastComputedGridTaskSize = getRecentsView().getLastComputedGridTaskSize();
boxWidth = lastComputedGridTaskSize.width();
boxHeight = lastComputedGridTaskSize.height();
+ thumbnailRatio = mTask != null ? mTask.getVisibleThumbnailRatio(
+ TaskView.CLIP_STATUS_AND_NAV_BARS) : 0f;
}
+ int boxLength = Math.max(boxWidth, boxHeight);
// Bound width/height to the box size.
- expectedWidth = boxWidth;
- expectedHeight = boxHeight + thumbnailPadding;
+ if (thumbnailRatio == 0f) {
+ expectedWidth = boxWidth;
+ expectedHeight = boxHeight + thumbnailPadding;
+ } else if (thumbnailRatio > 1) {
+ expectedWidth = boxLength;
+ expectedHeight = (int) (boxLength / thumbnailRatio) + thumbnailPadding;
+ } else {
+ expectedWidth = (int) (boxLength * thumbnailRatio);
+ expectedHeight = boxLength + thumbnailPadding;
+ }
// Scale to to fit task Rect.
- nonGridScale = taskWidth / (float) boxWidth;
+ fullscreenScale = taskWidth / (float) boxWidth;
+
+ // In full screen, scale back TaskView to original size.
+ if (expectedWidth > boxWidth) {
+ fullscreenScale *= boxWidth / (float) expectedWidth;
+ } else if (expectedHeight - thumbnailPadding > boxHeight) {
+ fullscreenScale *= boxHeight / (float) (expectedHeight - thumbnailPadding);
+ }
// Align to top of task Rect.
boxTranslationY = (expectedHeight - thumbnailPadding - taskHeight) / 2.0f;
} else {
- nonGridScale = 1f;
+ fullscreenScale = 1f;
boxTranslationY = 0f;
expectedWidth = ViewGroup.LayoutParams.MATCH_PARENT;
expectedHeight = ViewGroup.LayoutParams.MATCH_PARENT;
}
- setNonGridScale(nonGridScale);
+ setFullscreenScale(fullscreenScale);
setBoxTranslationY(boxTranslationY);
if (params.width != expectedWidth || params.height != expectedHeight) {
params.width = expectedWidth;
@@ -1498,13 +1422,18 @@ public class TaskView extends FrameLayout implements Reusable {
}
}
- private float getGridTrans(float endTranslation) {
- float progress = GRID_INTERPOLATOR.getInterpolation(mGridProgress);
+ private float getFullscreenTrans(float endTranslation) {
+ float progress = FULLSCREEN_INTERPOLATOR.getInterpolation(mFullscreenProgress);
return Utilities.mapRange(progress, 0, endTranslation);
}
- private float getNonGridTrans(float endTranslation) {
- return endTranslation - getGridTrans(endTranslation);
+ private float getNonFullscreenTrans(float endTranslation) {
+ return endTranslation - getFullscreenTrans(endTranslation);
+ }
+
+ private float getGridTrans(float endTranslation) {
+ float progress = ACCEL_DEACCEL.getInterpolation(mGridProgress);
+ return Utilities.mapRange(progress, 0, endTranslation);
}
public boolean isRunningTask() {
@@ -1538,7 +1467,7 @@ public class TaskView extends FrameLayout implements Reusable {
public void initiateSplitSelect(SplitPositionOption splitPositionOption) {
AbstractFloatingView.closeOpenViews(mActivity, false, TYPE_TASK_MENU);
- getRecentsView().initiateSplitSelect(this, splitPositionOption.stagePosition);
+ getRecentsView().initiateSplitSelect(this, splitPositionOption);
}
/**
@@ -1550,12 +1479,6 @@ public class TaskView extends FrameLayout implements Reusable {
mDigitalWellBeingToast.setBannerColorTint(tintColor, amount);
}
-
- private int getRootViewDisplayId() {
- Display display = getRootView().getDisplay();
- return display != null ? display.getDisplayId() : DEFAULT_DISPLAY;
- }
-
/**
* We update and subsequently draw these in {@link #setFullscreenProgress(float)}.
*/
@@ -1564,6 +1487,7 @@ public class TaskView extends FrameLayout implements Reusable {
private final float mCornerRadius;
private final float mWindowCornerRadius;
+ public float mFullscreenProgress;
public RectF mCurrentDrawnInsets = new RectF();
public float mCurrentDrawnCornerRadius;
/** The current scale we apply to the thumbnail to adjust for new left/right insets. */
@@ -1571,7 +1495,7 @@ public class TaskView extends FrameLayout implements Reusable {
public FullscreenDrawParams(Context context) {
mCornerRadius = TaskCornerRadius.get(context);
- mWindowCornerRadius = QuickStepContract.getWindowCornerRadius(context);
+ mWindowCornerRadius = QuickStepContract.getWindowCornerRadius(context.getResources());
mCurrentDrawnCornerRadius = mCornerRadius;
}
@@ -1579,23 +1503,20 @@ public class TaskView extends FrameLayout implements Reusable {
/**
* Sets the progress in range [0, 1]
*/
- public void setProgress(float fullscreenProgress, float parentScale, float taskViewScale,
- int previewWidth, DeviceProfile dp, PreviewPositionHelper pph) {
- RectF insets = pph.getInsetsToDrawInFullscreen(dp);
+ public void setProgress(float fullscreenProgress, float parentScale, int previewWidth,
+ DeviceProfile dp, PreviewPositionHelper pph) {
+ mFullscreenProgress = fullscreenProgress;
+ RectF insets = pph.getInsetsToDrawInFullscreen();
float currentInsetsLeft = insets.left * fullscreenProgress;
float currentInsetsRight = insets.right * fullscreenProgress;
- float insetsBottom = insets.bottom;
- if (dp.isTaskbarPresentInApps) {
- insetsBottom = Math.max(0, insetsBottom - dp.taskbarSize);
- }
mCurrentDrawnInsets.set(currentInsetsLeft, insets.top * fullscreenProgress,
- currentInsetsRight, insetsBottom * fullscreenProgress);
+ currentInsetsRight, insets.bottom * fullscreenProgress);
float fullscreenCornerRadius = dp.isMultiWindowMode ? 0 : mWindowCornerRadius;
mCurrentDrawnCornerRadius =
Utilities.mapRange(fullscreenProgress, mCornerRadius, fullscreenCornerRadius)
- / parentScale / taskViewScale;
+ / parentScale;
// We scaled the thumbnail to fit the content (excluding insets) within task view width.
// Now that we are drawing left/right insets again, we need to scale down to fit them.
@@ -1603,57 +1524,6 @@ public class TaskView extends FrameLayout implements Reusable {
mScale = previewWidth / (previewWidth + currentInsetsLeft + currentInsetsRight);
}
}
- }
-
- public class TaskIdAttributeContainer {
- private final TaskThumbnailView mThumbnailView;
- private final Task mTask;
- private final IconView mIconView;
- /** Defaults to STAGE_POSITION_UNDEFINED if in not a split screen task view */
- private @SplitConfigurationOptions.StagePosition int mStagePosition;
- @IdRes
- private final int mA11yNodeId;
-
- public TaskIdAttributeContainer(Task task, TaskThumbnailView thumbnailView,
- IconView iconView, int stagePosition) {
- this.mTask = task;
- this.mThumbnailView = thumbnailView;
- this.mIconView = iconView;
- this.mStagePosition = stagePosition;
- this.mA11yNodeId = (stagePosition == STAGE_POSITION_BOTTOM_OR_RIGHT) ?
- R.id.split_bottomRight_appInfo : R.id.split_topLeft_appInfo;
- }
-
- public TaskThumbnailView getThumbnailView() {
- return mThumbnailView;
- }
-
- public Task getTask() {
- return mTask;
- }
-
- public WorkspaceItemInfo getItemInfo() {
- return TaskView.this.getItemInfo(mTask);
- }
-
- public TaskView getTaskView() {
- return TaskView.this;
- }
-
- public IconView getIconView() {
- return mIconView;
- }
-
- public int getStagePosition() {
- return mStagePosition;
- }
-
- void setStagePosition(@SplitConfigurationOptions.StagePosition int stagePosition) {
- this.mStagePosition = stagePosition;
- }
- public int getA11yNodeId() {
- return mA11yNodeId;
- }
}
}
diff --git a/quickstep/tests/src/com/android/launcher3/taskbar/RecentsHitboxExtenderTest.java b/quickstep/tests/src/com/android/launcher3/taskbar/RecentsHitboxExtenderTest.java
deleted file mode 100644
index 929bff3004..0000000000
--- a/quickstep/tests/src/com/android/launcher3/taskbar/RecentsHitboxExtenderTest.java
+++ /dev/null
@@ -1,125 +0,0 @@
-package com.android.launcher3.taskbar;
-
-import static android.view.MotionEvent.ACTION_DOWN;
-
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyLong;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.app.Instrumentation;
-import android.content.Context;
-import android.os.Handler;
-import android.view.MotionEvent;
-import android.view.View;
-
-import androidx.test.platform.app.InstrumentationRegistry;
-import androidx.test.runner.AndroidJUnit4;
-
-import com.android.launcher3.DeviceProfile;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import java.util.function.Supplier;
-
-@RunWith(AndroidJUnit4.class)
-public class RecentsHitboxExtenderTest {
-
- private static final int TASKBAR_OFFSET_Y = 35;
- private static final int BUTTON_WIDTH = 10;
- private static final int BUTTON_HEIGHT = 10;
-
- private final RecentsHitboxExtender mHitboxExtender = new RecentsHitboxExtender();
- @Mock
- View mMockRecentsButton;
- @Mock
- View mMockRecentsParent;
- @Mock
- DeviceProfile mMockDeviceProfile;
- @Mock
- Handler mMockHandler;
- Context mContext;
-
- float[] mRecentsCoords = new float[]{0,0};
- private final Supplier<float[]> mSupplier = () -> mRecentsCoords;
-
- @Before
- public void setup() {
- MockitoAnnotations.initMocks(this);
- Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
- mContext = instrumentation.getContext();
- mHitboxExtender.init(mMockRecentsButton, mMockRecentsParent, mMockDeviceProfile, mSupplier,
- mMockHandler);
- when(mMockDeviceProfile.getTaskbarOffsetY()).thenReturn(TASKBAR_OFFSET_Y);
- when(mMockRecentsButton.getContext()).thenReturn(mContext);
- when(mMockRecentsButton.getWidth()).thenReturn(BUTTON_WIDTH);
- when(mMockRecentsButton.getHeight()).thenReturn(BUTTON_HEIGHT);
- }
-
- @Test
- public void noRecentsButtonClick_notActive() {
- mHitboxExtender.onAnimationProgressToOverview(0);
- mHitboxExtender.onAnimationProgressToOverview(0.5f);
- assertFalse(mHitboxExtender.extendedHitboxEnabled());
- }
-
- @Test
- public void recentsButtonClick_active() {
- mHitboxExtender.onRecentsButtonClicked();
- mHitboxExtender.onAnimationProgressToOverview(0);
- mHitboxExtender.onAnimationProgressToOverview(0.5f);
- assertTrue(mHitboxExtender.extendedHitboxEnabled());
- }
-
- @Test
- public void homeToTaskbar_notActive() {
- mHitboxExtender.onAnimationProgressToOverview(1);
- mHitboxExtender.onAnimationProgressToOverview(0.5f);
- assertFalse(mHitboxExtender.extendedHitboxEnabled());
- }
-
- @Test
- public void animationEndReset() {
- mHitboxExtender.onRecentsButtonClicked();
- mHitboxExtender.onAnimationProgressToOverview(0);
- mHitboxExtender.onAnimationProgressToOverview(0.5f);
- assertTrue(mHitboxExtender.extendedHitboxEnabled());
- mHitboxExtender.onAnimationProgressToOverview(1);
- verify(mMockHandler, times(1)).postDelayed(any(), anyLong());
- }
-
- @Test
- public void motionWithinHitbox() {
- mHitboxExtender.onRecentsButtonClicked();
- mHitboxExtender.onAnimationProgressToOverview(0);
- mHitboxExtender.onAnimationProgressToOverview(0.5f);
- assertTrue(mHitboxExtender.extendedHitboxEnabled());
- // Center width, past height but w/in offset bounds
- MotionEvent motionEvent = getMotionEvent(ACTION_DOWN,
- BUTTON_WIDTH / 2, BUTTON_HEIGHT + TASKBAR_OFFSET_Y / 2);
- assertTrue(mHitboxExtender.onControllerInterceptTouchEvent(motionEvent));
- }
-
- @Test
- public void motionOutsideHitbox() {
- mHitboxExtender.onRecentsButtonClicked();
- mHitboxExtender.onAnimationProgressToOverview(0);
- mHitboxExtender.onAnimationProgressToOverview(0.5f);
- assertTrue(mHitboxExtender.extendedHitboxEnabled());
- // Center width, past height and offset
- MotionEvent motionEvent = getMotionEvent(ACTION_DOWN,
- BUTTON_WIDTH / 2, BUTTON_HEIGHT + TASKBAR_OFFSET_Y * 2);
- assertFalse(mHitboxExtender.onControllerInterceptTouchEvent(motionEvent));
- }
-
- private MotionEvent getMotionEvent(int action, int x, int y) {
- return MotionEvent.obtain(0, 0, action, x, y, 0);
- }
-}
diff --git a/quickstep/tests/src/com/android/launcher3/taskbar/TaskbarNavButtonControllerTest.java b/quickstep/tests/src/com/android/launcher3/taskbar/TaskbarNavButtonControllerTest.java
deleted file mode 100644
index d8be30728e..0000000000
--- a/quickstep/tests/src/com/android/launcher3/taskbar/TaskbarNavButtonControllerTest.java
+++ /dev/null
@@ -1,224 +0,0 @@
-package com.android.launcher3.taskbar;
-
-import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASKBAR_BACK_BUTTON_LONGPRESS;
-import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASKBAR_BACK_BUTTON_TAP;
-import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASKBAR_HOME_BUTTON_LONGPRESS;
-import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASKBAR_HOME_BUTTON_TAP;
-import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASKBAR_OVERVIEW_BUTTON_LONGPRESS;
-import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASKBAR_OVERVIEW_BUTTON_TAP;
-import static com.android.launcher3.taskbar.TaskbarNavButtonController.BUTTON_A11Y;
-import static com.android.launcher3.taskbar.TaskbarNavButtonController.BUTTON_BACK;
-import static com.android.launcher3.taskbar.TaskbarNavButtonController.BUTTON_HOME;
-import static com.android.launcher3.taskbar.TaskbarNavButtonController.BUTTON_IME_SWITCH;
-import static com.android.launcher3.taskbar.TaskbarNavButtonController.BUTTON_RECENTS;
-import static com.android.launcher3.taskbar.TaskbarNavButtonController.SCREEN_PIN_LONG_PRESS_THRESHOLD;
-import static com.android.quickstep.OverviewCommandHelper.TYPE_HOME;
-import static com.android.quickstep.OverviewCommandHelper.TYPE_TOGGLE;
-import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_SCREEN_PINNING;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.os.Handler;
-
-import androidx.test.runner.AndroidJUnit4;
-
-import com.android.launcher3.logging.StatsLogManager;
-import com.android.quickstep.OverviewCommandHelper;
-import com.android.quickstep.SystemUiProxy;
-import com.android.quickstep.TouchInteractionService;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-@RunWith(AndroidJUnit4.class)
-public class TaskbarNavButtonControllerTest {
-
- private final static int DISPLAY_ID = 2;
-
- @Mock
- SystemUiProxy mockSystemUiProxy;
- @Mock
- TouchInteractionService mockService;
- @Mock
- OverviewCommandHelper mockCommandHelper;
- @Mock
- Handler mockHandler;
- @Mock
- StatsLogManager mockStatsLogManager;
- @Mock
- StatsLogManager.StatsLogger mockStatsLogger;
- @Mock
- TaskbarControllers mockTaskbarControllers;
- @Mock
- TaskbarActivityContext mockTaskbarActivityContext;
-
- private TaskbarNavButtonController mNavButtonController;
-
- @Before
- public void setup() {
- MockitoAnnotations.initMocks(this);
- when(mockService.getDisplayId()).thenReturn(DISPLAY_ID);
- when(mockService.getOverviewCommandHelper()).thenReturn(mockCommandHelper);
- when(mockStatsLogManager.logger()).thenReturn(mockStatsLogger);
- when(mockTaskbarControllers.getTaskbarActivityContext())
- .thenReturn(mockTaskbarActivityContext);
- doReturn(mockStatsLogManager).when(mockTaskbarActivityContext).getStatsLogManager();
- mNavButtonController = new TaskbarNavButtonController(mockService,
- mockSystemUiProxy, mockHandler);
- }
-
- @Test
- public void testPressBack() {
- mNavButtonController.onButtonClick(BUTTON_BACK);
- verify(mockSystemUiProxy, times(1)).onBackPressed();
- }
-
- @Test
- public void testPressImeSwitcher() {
- mNavButtonController.onButtonClick(BUTTON_IME_SWITCH);
- verify(mockSystemUiProxy, times(1)).onImeSwitcherPressed();
- }
-
- @Test
- public void testPressA11yShortClick() {
- mNavButtonController.onButtonClick(BUTTON_A11Y);
- verify(mockSystemUiProxy, times(1))
- .notifyAccessibilityButtonClicked(DISPLAY_ID);
- }
-
- @Test
- public void testPressA11yLongClick() {
- mNavButtonController.onButtonLongClick(BUTTON_A11Y);
- verify(mockSystemUiProxy, times(1)).notifyAccessibilityButtonLongClicked();
- }
-
- @Test
- public void testLongPressHome() {
- mNavButtonController.onButtonLongClick(BUTTON_HOME);
- verify(mockSystemUiProxy, times(1)).startAssistant(any());
- }
-
- @Test
- public void testPressHome() {
- mNavButtonController.onButtonClick(BUTTON_HOME);
- verify(mockCommandHelper, times(1)).addCommand(TYPE_HOME);
- }
-
- @Test
- public void testPressRecents() {
- mNavButtonController.onButtonClick(BUTTON_RECENTS);
- verify(mockCommandHelper, times(1)).addCommand(TYPE_TOGGLE);
- }
-
- @Test
- public void testPressRecentsWithScreenPinned() {
- mNavButtonController.updateSysuiFlags(SYSUI_STATE_SCREEN_PINNING);
- mNavButtonController.onButtonClick(BUTTON_RECENTS);
- verify(mockCommandHelper, times(0)).addCommand(TYPE_TOGGLE);
- }
-
- @Test
- public void testLongPressBackRecentsNotPinned() {
- mNavButtonController.onButtonLongClick(BUTTON_RECENTS);
- mNavButtonController.onButtonLongClick(BUTTON_BACK);
- verify(mockSystemUiProxy, times(0)).stopScreenPinning();
- }
-
- @Test
- public void testLongPressBackRecentsPinned() {
- mNavButtonController.updateSysuiFlags(SYSUI_STATE_SCREEN_PINNING);
- mNavButtonController.onButtonLongClick(BUTTON_RECENTS);
- mNavButtonController.onButtonLongClick(BUTTON_BACK);
- verify(mockSystemUiProxy, times(1)).stopScreenPinning();
- }
-
- @Test
- public void testLongPressBackRecentsTooLongPinned() {
- mNavButtonController.updateSysuiFlags(SYSUI_STATE_SCREEN_PINNING);
- mNavButtonController.onButtonLongClick(BUTTON_RECENTS);
- try {
- Thread.sleep(SCREEN_PIN_LONG_PRESS_THRESHOLD + 5);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- mNavButtonController.onButtonLongClick(BUTTON_BACK);
- verify(mockSystemUiProxy, times(0)).stopScreenPinning();
- }
-
- @Test
- public void testLongPressBackRecentsMultipleAttemptPinned() {
- mNavButtonController.updateSysuiFlags(SYSUI_STATE_SCREEN_PINNING);
- mNavButtonController.onButtonLongClick(BUTTON_RECENTS);
- try {
- Thread.sleep(SCREEN_PIN_LONG_PRESS_THRESHOLD + 5);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- mNavButtonController.onButtonLongClick(BUTTON_BACK);
- verify(mockSystemUiProxy, times(0)).stopScreenPinning();
-
- // Try again w/in threshold
- mNavButtonController.onButtonLongClick(BUTTON_RECENTS);
- mNavButtonController.onButtonLongClick(BUTTON_BACK);
- verify(mockSystemUiProxy, times(1)).stopScreenPinning();
- }
-
- @Test
- public void testLongPressHomeScreenPinned() {
- mNavButtonController.updateSysuiFlags(SYSUI_STATE_SCREEN_PINNING);
- mNavButtonController.onButtonLongClick(BUTTON_HOME);
- verify(mockSystemUiProxy, times(0)).startAssistant(any());
- }
-
- @Test
- public void testNoCallsToNullLogger() {
- mNavButtonController.onButtonClick(BUTTON_HOME);
- verify(mockStatsLogManager, times(0)).logger();
- verify(mockStatsLogger, times(0)).log(any());
- }
-
- @Test
- public void testNoCallsAfterNullingOut() {
- mNavButtonController.init(mockTaskbarControllers);
- mNavButtonController.onButtonClick(BUTTON_HOME);
- mNavButtonController.onDestroy();
- mNavButtonController.onButtonClick(BUTTON_HOME);
- verify(mockStatsLogger, times(1)).log(LAUNCHER_TASKBAR_HOME_BUTTON_TAP);
- verify(mockStatsLogger, times(0)).log(LAUNCHER_TASKBAR_HOME_BUTTON_LONGPRESS);
- }
-
- @Test
- public void testLogOnTap() {
- mNavButtonController.init(mockTaskbarControllers);
- mNavButtonController.onButtonClick(BUTTON_HOME);
- verify(mockStatsLogger, times(1)).log(LAUNCHER_TASKBAR_HOME_BUTTON_TAP);
- verify(mockStatsLogger, times(0)).log(LAUNCHER_TASKBAR_HOME_BUTTON_LONGPRESS);
- }
-
- @Test
- public void testLogOnLongpress() {
- mNavButtonController.init(mockTaskbarControllers);
- mNavButtonController.onButtonLongClick(BUTTON_HOME);
- verify(mockStatsLogger, times(1)).log(LAUNCHER_TASKBAR_HOME_BUTTON_LONGPRESS);
- verify(mockStatsLogger, times(0)).log(LAUNCHER_TASKBAR_HOME_BUTTON_TAP);
- }
-
- @Test
- public void testBackOverviewLogOnLongpress() {
- mNavButtonController.init(mockTaskbarControllers);
- mNavButtonController.onButtonLongClick(BUTTON_RECENTS);
- verify(mockStatsLogger, times(1)).log(LAUNCHER_TASKBAR_OVERVIEW_BUTTON_LONGPRESS);
- verify(mockStatsLogger, times(0)).log(LAUNCHER_TASKBAR_OVERVIEW_BUTTON_TAP);
-
- mNavButtonController.onButtonLongClick(BUTTON_BACK);
- verify(mockStatsLogger, times(1)).log(LAUNCHER_TASKBAR_BACK_BUTTON_LONGPRESS);
- verify(mockStatsLogger, times(0)).log(LAUNCHER_TASKBAR_BACK_BUTTON_TAP);
- }
-}
diff --git a/quickstep/tests/src/com/android/quickstep/AbstractQuickStepTest.java b/quickstep/tests/src/com/android/quickstep/AbstractQuickStepTest.java
index 09f0858618..7c463a7b46 100644
--- a/quickstep/tests/src/com/android/quickstep/AbstractQuickStepTest.java
+++ b/quickstep/tests/src/com/android/quickstep/AbstractQuickStepTest.java
@@ -20,8 +20,6 @@ import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TI
import static org.junit.Assert.assertTrue;
-import android.os.SystemProperties;
-
import com.android.launcher3.Launcher;
import com.android.launcher3.tapl.LauncherInstrumentation;
import com.android.launcher3.tapl.LauncherInstrumentation.ContainerType;
@@ -35,8 +33,6 @@ import org.junit.rules.TestRule;
* Base class for all instrumentation tests that deal with Quickstep.
*/
public abstract class AbstractQuickStepTest extends AbstractLauncherUiTest {
- static final boolean ENABLE_SHELL_TRANSITIONS =
- SystemProperties.getBoolean("persist.wm.debug.shell_transit", false);
@Override
protected TestRule getRulesInsideActivityMonitor() {
return RuleChain.
@@ -55,7 +51,7 @@ public abstract class AbstractQuickStepTest extends AbstractLauncherUiTest {
@Override
protected void checkLauncherState(Launcher launcher, ContainerType expectedContainerType,
boolean isResumed, boolean isStarted) {
- if (ENABLE_SHELL_TRANSITIONS || !isInLiveTileMode(launcher, expectedContainerType)) {
+ if (!isInLiveTileMode(launcher, expectedContainerType)) {
super.checkLauncherState(launcher, expectedContainerType, isResumed, isStarted);
} else {
assertTrue("[Live Tile] hasBeenResumed() == isStarted(), hasBeenResumed(): "
@@ -66,7 +62,7 @@ public abstract class AbstractQuickStepTest extends AbstractLauncherUiTest {
@Override
protected void checkLauncherStateInOverview(Launcher launcher,
ContainerType expectedContainerType, boolean isStarted, boolean isResumed) {
- if (ENABLE_SHELL_TRANSITIONS || !isInLiveTileMode(launcher, expectedContainerType)) {
+ if (!isInLiveTileMode(launcher, expectedContainerType)) {
super.checkLauncherStateInOverview(launcher, expectedContainerType, isStarted,
isResumed);
} else {
@@ -86,6 +82,6 @@ public abstract class AbstractQuickStepTest extends AbstractLauncherUiTest {
RecentsView recentsView = launcher.getOverviewPanel();
return recentsView.getSizeStrategy().isInLiveTileMode()
- && recentsView.getRunningTaskViewId() != -1;
+ && recentsView.getRunningTaskId() != -1;
}
}
diff --git a/quickstep/tests/src/com/android/quickstep/DigitalWellBeingToastTest.java b/quickstep/tests/src/com/android/quickstep/DigitalWellBeingToastTest.java
index 5c2e14f119..3e84a76695 100644
--- a/quickstep/tests/src/com/android/quickstep/DigitalWellBeingToastTest.java
+++ b/quickstep/tests/src/com/android/quickstep/DigitalWellBeingToastTest.java
@@ -46,10 +46,9 @@ public class DigitalWellBeingToastTest extends AbstractQuickStepTest {
runWithShellPermission(() ->
usageStatsManager.registerAppUsageLimitObserver(observerId, packages,
Duration.ofSeconds(600), Duration.ofSeconds(300),
- PendingIntent.getActivity(mTargetContext, -1, new Intent(),
- PendingIntent.FLAG_MUTABLE)));
+ PendingIntent.getActivity(mTargetContext, -1, new Intent(), 0)));
- mLauncher.goHome();
+ mLauncher.pressHome();
final DigitalWellBeingToast toast = getToast();
waitForLauncherCondition("Toast is not visible", launcher -> toast.hasLimit());
@@ -59,7 +58,7 @@ public class DigitalWellBeingToastTest extends AbstractQuickStepTest {
runWithShellPermission(
() -> usageStatsManager.unregisterAppUsageLimitObserver(observerId));
- mLauncher.goHome();
+ mLauncher.pressHome();
assertFalse("Toast is visible", getToast().hasLimit());
} finally {
runWithShellPermission(
diff --git a/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java b/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java
index f7600ff9bb..a683d01f6c 100644
--- a/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java
+++ b/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java
@@ -42,6 +42,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.os.RemoteException;
+import android.util.Log;
import androidx.test.filters.LargeTest;
import androidx.test.runner.AndroidJUnit4;
@@ -55,10 +56,9 @@ import com.android.launcher3.tapl.LauncherInstrumentation;
import com.android.launcher3.tapl.OverviewTask;
import com.android.launcher3.tapl.TestHelpers;
import com.android.launcher3.testcomponent.TestCommandReceiver;
+import com.android.launcher3.testing.TestProtocol;
import com.android.launcher3.util.Wait;
import com.android.launcher3.util.rule.FailureWatcher;
-import com.android.launcher3.util.rule.SamplerRule;
-import com.android.launcher3.util.rule.ScreenRecordRule;
import com.android.quickstep.views.RecentsView;
import org.junit.After;
@@ -79,8 +79,6 @@ import java.util.function.Function;
@RunWith(AndroidJUnit4.class)
public class FallbackRecentsTest {
- private static final String FALLBACK_LAUNCHER_TITLE = "Test launcher";
-
private final UiDevice mDevice;
private final LauncherInstrumentation mLauncher;
private final ActivityInfo mOtherLauncherActivity;
@@ -94,16 +92,12 @@ public class FallbackRecentsTest {
@Rule
public final TestRule mOrderSensitiveRules;
- @Rule
- public ScreenRecordRule mScreenRecordRule = new ScreenRecordRule();
-
public FallbackRecentsTest() throws RemoteException {
Instrumentation instrumentation = getInstrumentation();
Context context = instrumentation.getContext();
mDevice = UiDevice.getInstance(instrumentation);
mDevice.setOrientationNatural();
mLauncher = new LauncherInstrumentation();
- mLauncher.enableDebugTracing();
// b/143488140
//mLauncher.enableCheckEventsForSuccessfulGestures();
@@ -112,8 +106,7 @@ public class FallbackRecentsTest {
}
mOrderSensitiveRules = RuleChain
- .outerRule(new SamplerRule())
- .around(new NavigationModeSwitchRule(mLauncher))
+ .outerRule(new NavigationModeSwitchRule(mLauncher))
.around(new FailureWatcher(mDevice, mLauncher));
mOtherLauncherActivity = context.getPackageManager().queryIntentActivities(
@@ -171,9 +164,9 @@ public class FallbackRecentsTest {
public void goToOverviewFromHome() {
mDevice.pressHome();
assertTrue("Fallback Launcher not visible", mDevice.wait(Until.hasObject(By.pkg(
- mOtherLauncherActivity.packageName).text(FALLBACK_LAUNCHER_TITLE)), WAIT_TIME_MS));
+ mOtherLauncherActivity.packageName)), WAIT_TIME_MS));
- mLauncher.getLaunchedAppState().switchToOverview();
+ mLauncher.getBackground().switchToOverview();
}
// b/143488140
@@ -182,7 +175,7 @@ public class FallbackRecentsTest {
public void goToOverviewFromApp() {
startAppFast(resolveSystemApp(Intent.CATEGORY_APP_CALCULATOR));
- mLauncher.getLaunchedAppState().switchToOverview();
+ mLauncher.getBackground().switchToOverview();
}
protected void executeOnRecents(Consumer<RecentsActivity> f) {
@@ -194,9 +187,15 @@ public class FallbackRecentsTest {
protected <T> T getFromRecents(Function<RecentsActivity, T> f) {
if (!TestHelpers.isInLauncherProcess()) return null;
+ if (TestProtocol.sDebugTracing) {
+ Log.d(TestProtocol.FALLBACK_ACTIVITY_NO_SET, "getFromRecents");
+ }
Object[] result = new Object[1];
Wait.atMost("Failed to get from recents", () -> MAIN_EXECUTOR.submit(() -> {
RecentsActivity activity = RecentsActivity.ACTIVITY_TRACKER.getCreatedActivity();
+ if (TestProtocol.sDebugTracing) {
+ Log.d(TestProtocol.FALLBACK_ACTIVITY_NO_SET, "activity=" + activity);
+ }
if (activity == null) {
return false;
}
@@ -208,7 +207,7 @@ public class FallbackRecentsTest {
private BaseOverview pressHomeAndGoToOverview() {
mDevice.pressHome();
- return mLauncher.getLaunchedAppState().switchToOverview();
+ return mLauncher.getBackground().switchToOverview();
}
// b/143488140
@@ -221,7 +220,7 @@ public class FallbackRecentsTest {
Wait.atMost("Expected three apps in the task list",
() -> mLauncher.getRecentTasks().size() >= 3, DEFAULT_ACTIVITY_TIMEOUT, mLauncher);
- BaseOverview overview = mLauncher.getLaunchedAppState().switchToOverview();
+ BaseOverview overview = mLauncher.getBackground().switchToOverview();
executeOnRecents(recents -> {
assertTrue("Don't have at least 3 tasks", getTaskCount(recents) >= 3);
});
@@ -260,7 +259,7 @@ public class FallbackRecentsTest {
// Test dismissing all tasks.
pressHomeAndGoToOverview().dismissAllTasks();
assertTrue("Fallback Launcher not visible", TestHelpers.wait(Until.hasObject(By.pkg(
- mOtherLauncherActivity.packageName).text(FALLBACK_LAUNCHER_TITLE)), WAIT_TIME_MS));
+ mOtherLauncherActivity.packageName)), WAIT_TIME_MS));
}
private int getCurrentOverviewPage(RecentsActivity recents) {
diff --git a/quickstep/tests/src/com/android/quickstep/NavigationBarRotationContextTest.java b/quickstep/tests/src/com/android/quickstep/NavigationBarRotationContextTest.java
deleted file mode 100644
index de6740d3b3..0000000000
--- a/quickstep/tests/src/com/android/quickstep/NavigationBarRotationContextTest.java
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Copyright 2021 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.quickstep;
-
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-
-import android.content.Context;
-import android.graphics.drawable.AnimatedVectorDrawable;
-import android.view.View;
-import android.view.WindowInsetsController;
-
-import androidx.test.InstrumentationRegistry;
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import com.android.systemui.shared.rotation.RotationButton;
-import com.android.systemui.shared.rotation.RotationButtonController;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.MockitoAnnotations;
-
-/** SysUI equivalent */
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class NavigationBarRotationContextTest {
- private static final int DEFAULT_ROTATE = 0;
- private static final int DEFAULT_DISPLAY = 0;
-
-
- private RotationButtonController mRotationButtonController;
-
- @Before
- public void setup() {
- MockitoAnnotations.initMocks(this);
- Context mTargetContext = InstrumentationRegistry.getTargetContext();
- final View view = new View(mTargetContext);
- RotationButton rotationButton = mock(RotationButton.class);
- mRotationButtonController = new RotationButtonController(mTargetContext, 0, 0, 0, 0, 0, 0,
- () -> 0);
- mRotationButtonController.setRotationButton(rotationButton, null);
- // Due to a mockito issue, only spy the object after setting the initial state
- mRotationButtonController = spy(mRotationButtonController);
- final AnimatedVectorDrawable kbd = mock(AnimatedVectorDrawable.class);
- doReturn(view).when(rotationButton).getCurrentView();
- doReturn(true).when(rotationButton).acceptRotationProposal();
- }
-
- @Test
- public void testOnInvalidRotationProposal() {
- mRotationButtonController.onRotationProposal(DEFAULT_ROTATE + 1,
- false /* isValid */);
- verify(mRotationButtonController, times(1))
- .setRotateSuggestionButtonState(false /* visible */);
- }
-
- @Test
- public void testOnSameRotationProposal() {
- mRotationButtonController.onRotationProposal(DEFAULT_ROTATE,
- true /* isValid */);
- verify(mRotationButtonController, times(1))
- .setRotateSuggestionButtonState(false /* visible */);
- }
-
- @Test
- public void testOnRotationProposalShowButtonShowNav() {
- // No navigation bar should not call to set visibility state
- mRotationButtonController.onBehaviorChanged(DEFAULT_DISPLAY,
- WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE);
- mRotationButtonController.onNavigationBarWindowVisibilityChange(false /* showing */);
- verify(mRotationButtonController, times(0)).setRotateSuggestionButtonState(
- false /* visible */);
- verify(mRotationButtonController, times(0)).setRotateSuggestionButtonState(
- true /* visible */);
-
- // No navigation bar with rotation change should not call to set visibility state
- mRotationButtonController.onRotationProposal(DEFAULT_ROTATE + 1,
- true /* isValid */);
- verify(mRotationButtonController, times(0)).setRotateSuggestionButtonState(
- false /* visible */);
- verify(mRotationButtonController, times(0)).setRotateSuggestionButtonState(
- true /* visible */);
-
- // Since rotation has changed rotation should be pending, show mButton when showing nav bar
- mRotationButtonController.onNavigationBarWindowVisibilityChange(true /* showing */);
- verify(mRotationButtonController, times(1)).setRotateSuggestionButtonState(
- true /* visible */);
- }
-
- @Test
- public void testOnRotationProposalShowButton() {
- // Navigation bar being visible should not call to set visibility state
- mRotationButtonController.onNavigationBarWindowVisibilityChange(true /* showing */);
- verify(mRotationButtonController, times(0))
- .setRotateSuggestionButtonState(false /* visible */);
- verify(mRotationButtonController, times(0))
- .setRotateSuggestionButtonState(true /* visible */);
-
- // Navigation bar is visible and rotation requested
- mRotationButtonController.onRotationProposal(DEFAULT_ROTATE + 1,
- true /* isValid */);
- verify(mRotationButtonController, times(1))
- .setRotateSuggestionButtonState(true /* visible */);
- }
-}
diff --git a/quickstep/tests/src/com/android/quickstep/NavigationModeSwitchRule.java b/quickstep/tests/src/com/android/quickstep/NavigationModeSwitchRule.java
index e5e2cf3337..67840d1a9e 100644
--- a/quickstep/tests/src/com/android/quickstep/NavigationModeSwitchRule.java
+++ b/quickstep/tests/src/com/android/quickstep/NavigationModeSwitchRule.java
@@ -20,7 +20,9 @@ import static androidx.test.InstrumentationRegistry.getInstrumentation;
import static com.android.quickstep.NavigationModeSwitchRule.Mode.ALL;
import static com.android.quickstep.NavigationModeSwitchRule.Mode.THREE_BUTTON;
+import static com.android.quickstep.NavigationModeSwitchRule.Mode.TWO_BUTTON;
import static com.android.quickstep.NavigationModeSwitchRule.Mode.ZERO_BUTTON;
+import static com.android.systemui.shared.system.QuickStepContract.NAV_BAR_MODE_2BUTTON_OVERLAY;
import static com.android.systemui.shared.system.QuickStepContract.NAV_BAR_MODE_3BUTTON_OVERLAY;
import static com.android.systemui.shared.system.QuickStepContract.NAV_BAR_MODE_GESTURAL_OVERLAY;
@@ -28,12 +30,12 @@ import android.content.Context;
import android.content.pm.PackageManager;
import android.util.Log;
+import androidx.test.uiautomator.By;
import androidx.test.uiautomator.UiDevice;
import com.android.launcher3.tapl.LauncherInstrumentation;
import com.android.launcher3.tapl.TestHelpers;
import com.android.launcher3.ui.AbstractLauncherUiTest;
-import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.Wait;
import com.android.launcher3.util.rule.FailureWatcher;
import com.android.systemui.shared.system.QuickStepContract;
@@ -47,7 +49,6 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
/**
* Test rule that allows executing a test with Quickstep on and then Quickstep off.
@@ -60,7 +61,7 @@ public class NavigationModeSwitchRule implements TestRule {
public static final int WAIT_TIME_MS = 10000;
public enum Mode {
- THREE_BUTTON, ZERO_BUTTON, ALL
+ THREE_BUTTON, TWO_BUTTON, ZERO_BUTTON, ALL
}
// Annotation for tests that need to be run with quickstep enabled and disabled.
@@ -72,8 +73,8 @@ public class NavigationModeSwitchRule implements TestRule {
private final LauncherInstrumentation mLauncher;
- static final DisplayController DISPLAY_CONTROLLER =
- DisplayController.INSTANCE.get(getInstrumentation().getTargetContext());
+ static final SysUINavigationMode SYS_UI_NAVIGATION_MODE =
+ SysUINavigationMode.INSTANCE.get(getInstrumentation().getTargetContext());
public NavigationModeSwitchRule(LauncherInstrumentation launcher) {
mLauncher = launcher;
@@ -98,6 +99,9 @@ public class NavigationModeSwitchRule implements TestRule {
if (mode == ZERO_BUTTON || mode == ALL) {
evaluateWithZeroButtons();
}
+ if (mode == TWO_BUTTON || mode == ALL) {
+ evaluateWithTwoButtons();
+ }
if (mode == THREE_BUTTON || mode == ALL) {
evaluateWithThreeButtons();
}
@@ -119,6 +123,13 @@ public class NavigationModeSwitchRule implements TestRule {
}
}
+ private void evaluateWithTwoButtons() throws Throwable {
+ if (setActiveOverlay(mLauncher, NAV_BAR_MODE_2BUTTON_OVERLAY,
+ LauncherInstrumentation.NavigationModel.TWO_BUTTON, description)) {
+ base.evaluate();
+ }
+ }
+
private void evaluateWithZeroButtons() throws Throwable {
if (setActiveOverlay(mLauncher, NAV_BAR_MODE_GESTURAL_OVERLAY,
LauncherInstrumentation.NavigationModel.ZERO_BUTTON, description)) {
@@ -134,12 +145,14 @@ public class NavigationModeSwitchRule implements TestRule {
public static String getCurrentOverlayPackage(int currentInteractionMode) {
return QuickStepContract.isGesturalMode(currentInteractionMode)
? NAV_BAR_MODE_GESTURAL_OVERLAY
- : NAV_BAR_MODE_3BUTTON_OVERLAY;
+ : QuickStepContract.isSwipeUpMode(currentInteractionMode)
+ ? NAV_BAR_MODE_2BUTTON_OVERLAY
+ : NAV_BAR_MODE_3BUTTON_OVERLAY;
}
private static LauncherInstrumentation.NavigationModel currentSysUiNavigationMode() {
return LauncherInstrumentation.getNavigationModel(
- DisplayController.getNavigationMode(
+ SysUINavigationMode.getMode(
getInstrumentation().
getTargetContext()).
resValue);
@@ -160,21 +173,26 @@ public class NavigationModeSwitchRule implements TestRule {
if (currentSysUiNavigationMode() != expectedMode) {
final CountDownLatch latch = new CountDownLatch(1);
final Context targetContext = getInstrumentation().getTargetContext();
- final DisplayController.DisplayInfoChangeListener listener =
- (context, info, flags) -> {
- if (LauncherInstrumentation.getNavigationModel(info.navigationMode.resValue)
+ final SysUINavigationMode.NavigationModeChangeListener listener =
+ newMode -> {
+ if (LauncherInstrumentation.getNavigationModel(newMode.resValue)
== expectedMode) {
latch.countDown();
}
};
targetContext.getMainExecutor().execute(() ->
- DISPLAY_CONTROLLER.addChangeListener(listener));
- latch.await(60, TimeUnit.SECONDS);
+ SYS_UI_NAVIGATION_MODE.addModeChangeListener(listener));
+ // b/139137636
+// latch.await(60, TimeUnit.SECONDS);
targetContext.getMainExecutor().execute(() ->
- DISPLAY_CONTROLLER.removeChangeListener(listener));
+ SYS_UI_NAVIGATION_MODE.removeModeChangeListener(listener));
- assertTrue(launcher, "Navigation mode didn't change to " + expectedMode,
- currentSysUiNavigationMode() == expectedMode, description);
+ Wait.atMost(() -> "Navigation mode didn't change to " + expectedMode,
+ () -> currentSysUiNavigationMode() == expectedMode, WAIT_TIME_MS,
+ launcher);
+ // b/139137636
+// assertTrue(launcher, "Navigation mode didn't change to " + expectedMode,
+// currentSysUiNavigationMode() == expectedMode, description);
}
@@ -203,11 +221,16 @@ public class NavigationModeSwitchRule implements TestRule {
private static void assertTrue(LauncherInstrumentation launcher, String message,
boolean condition, Description description) {
- launcher.checkForAnomaly(true, true);
+ if (launcher.getDevice().hasObject(By.textStartsWith(""))) {
+ // The condition above is "screen is not empty". We are not treating
+ // "Screen is empty" as an anomaly here. It's an acceptable state when
+ // Launcher just starts under instrumentation.
+ launcher.checkForAnomaly();
+ }
if (!condition) {
final AssertionError assertionError = new AssertionError(message);
if (description != null) {
- FailureWatcher.onError(launcher, description, assertionError);
+ FailureWatcher.onError(launcher.getDevice(), description, assertionError);
}
throw assertionError;
}
diff --git a/quickstep/tests/src/com/android/quickstep/RecentTasksListTest.java b/quickstep/tests/src/com/android/quickstep/RecentTasksListTest.java
index 4e497163b5..79ddf7a399 100644
--- a/quickstep/tests/src/com/android/quickstep/RecentTasksListTest.java
+++ b/quickstep/tests/src/com/android/quickstep/RecentTasksListTest.java
@@ -30,76 +30,70 @@ import android.app.ActivityManager;
import androidx.test.filters.SmallTest;
import com.android.launcher3.util.LooperExecutor;
-import com.android.quickstep.util.GroupTask;
+import com.android.systemui.shared.recents.model.Task;
+import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.KeyguardManagerCompat;
-import com.android.wm.shell.util.GroupedRecentTaskInfo;
import org.junit.Before;
import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@SmallTest
public class RecentTasksListTest {
- @Mock
- private SystemUiProxy mockSystemUiProxy;
+ private ActivityManagerWrapper mockActivityManagerWrapper;
// Class under test
private RecentTasksList mRecentTasksList;
@Before
public void setup() {
- MockitoAnnotations.initMocks(this);
LooperExecutor mockMainThreadExecutor = mock(LooperExecutor.class);
KeyguardManagerCompat mockKeyguardManagerCompat = mock(KeyguardManagerCompat.class);
+ mockActivityManagerWrapper = mock(ActivityManagerWrapper.class);
mRecentTasksList = new RecentTasksList(mockMainThreadExecutor, mockKeyguardManagerCompat,
- mockSystemUiProxy);
+ mockActivityManagerWrapper);
}
@Test
- public void onRecentTasksChanged_doesNotFetchTasks() {
- mRecentTasksList.onRecentTasksChanged();
- verify(mockSystemUiProxy, times(0))
+ public void onTaskRemoved_doesNotFetchTasks() {
+ mRecentTasksList.onTaskRemoved(0);
+ verify(mockActivityManagerWrapper, times(0))
+ .getRecentTasks(anyInt(), anyInt());
+ }
+
+ @Test
+ public void onTaskStackChanged_doesNotFetchTasks() {
+ mRecentTasksList.onTaskStackChanged();
+ verify(mockActivityManagerWrapper, times(0))
.getRecentTasks(anyInt(), anyInt());
}
@Test
public void loadTasksInBackground_onlyKeys_noValidTaskDescription() {
- GroupedRecentTaskInfo recentTaskInfos = new GroupedRecentTaskInfo(
- new ActivityManager.RecentTaskInfo(), new ActivityManager.RecentTaskInfo(), null);
- when(mockSystemUiProxy.getRecentTasks(anyInt(), anyInt()))
- .thenReturn(new ArrayList<>(Collections.singletonList(recentTaskInfos)));
+ ActivityManager.RecentTaskInfo recentTaskInfo = new ActivityManager.RecentTaskInfo();
+ when(mockActivityManagerWrapper.getRecentTasks(anyInt(), anyInt()))
+ .thenReturn(Collections.singletonList(recentTaskInfo));
- List<GroupTask> taskList = mRecentTasksList.loadTasksInBackground(Integer.MAX_VALUE, -1,
- true);
+ List<Task> taskList = mRecentTasksList.loadTasksInBackground(Integer.MAX_VALUE, -1, true);
assertEquals(1, taskList.size());
- assertNull(taskList.get(0).task1.taskDescription.getLabel());
- assertNull(taskList.get(0).task2.taskDescription.getLabel());
+ assertNull(taskList.get(0).taskDescription.getLabel());
}
@Test
public void loadTasksInBackground_moreThanKeys_hasValidTaskDescription() {
String taskDescription = "Wheeee!";
- ActivityManager.RecentTaskInfo task1 = new ActivityManager.RecentTaskInfo();
- task1.taskDescription = new ActivityManager.TaskDescription(taskDescription);
- ActivityManager.RecentTaskInfo task2 = new ActivityManager.RecentTaskInfo();
- task2.taskDescription = new ActivityManager.TaskDescription();
- GroupedRecentTaskInfo recentTaskInfos = new GroupedRecentTaskInfo(
- task1, task2, null);
- when(mockSystemUiProxy.getRecentTasks(anyInt(), anyInt()))
- .thenReturn(new ArrayList<>(Collections.singletonList(recentTaskInfos)));
-
- List<GroupTask> taskList = mRecentTasksList.loadTasksInBackground(Integer.MAX_VALUE, -1,
- false);
+ ActivityManager.RecentTaskInfo recentTaskInfo = new ActivityManager.RecentTaskInfo();
+ recentTaskInfo.taskDescription = new ActivityManager.TaskDescription(taskDescription);
+ when(mockActivityManagerWrapper.getRecentTasks(anyInt(), anyInt()))
+ .thenReturn(Collections.singletonList(recentTaskInfo));
+
+ List<Task> taskList = mRecentTasksList.loadTasksInBackground(Integer.MAX_VALUE, -1, false);
assertEquals(1, taskList.size());
- assertEquals(taskDescription, taskList.get(0).task1.taskDescription.getLabel());
- assertNull(taskList.get(0).task2.taskDescription.getLabel());
+ assertEquals(taskDescription, taskList.get(0).taskDescription.getLabel());
}
}
diff --git a/quickstep/tests/src/com/android/quickstep/StartLauncherViaGestureTests.java b/quickstep/tests/src/com/android/quickstep/StartLauncherViaGestureTests.java
index 6ec62695af..6e19436c90 100644
--- a/quickstep/tests/src/com/android/quickstep/StartLauncherViaGestureTests.java
+++ b/quickstep/tests/src/com/android/quickstep/StartLauncherViaGestureTests.java
@@ -16,16 +16,22 @@
package com.android.quickstep;
+import static com.android.launcher3.util.RaceConditionReproducer.enterEvt;
+import static com.android.launcher3.util.RaceConditionReproducer.exitEvt;
+
import android.content.Intent;
import androidx.test.filters.LargeTest;
import androidx.test.runner.AndroidJUnit4;
-import com.android.launcher3.ui.TaplTestsLauncher3;
+import com.android.launcher3.Launcher;
import com.android.launcher3.util.RaceConditionReproducer;
+import com.android.quickstep.NavigationModeSwitchRule.Mode;
import com.android.quickstep.NavigationModeSwitchRule.NavigationModeSwitch;
+import com.android.quickstep.inputconsumers.OtherActivityInputConsumer;
import org.junit.Before;
+import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -39,9 +45,8 @@ public class StartLauncherViaGestureTests extends AbstractQuickStepTest {
@Before
public void setUp() throws Exception {
super.setUp();
- TaplTestsLauncher3.initialize(this);
// b/143488140
- mLauncher.goHome();
+ mLauncher.pressHome();
// Start an activity where the gestures start.
startAppFast(resolveSystemApp(Intent.CATEGORY_APP_CALCULATOR));
}
@@ -54,11 +59,26 @@ public class StartLauncherViaGestureTests extends AbstractQuickStepTest {
// The test action.
eventProcessor.startIteration();
- mLauncher.goHome();
+ mLauncher.pressHome();
eventProcessor.finishIteration();
}
@Test
+ @Ignore // Ignoring until race condition repro framework is changes for multi-process case.
+ @NavigationModeSwitch(mode = Mode.TWO_BUTTON)
+ public void testPressHome() {
+ runTest(enterEvt(Launcher.ON_CREATE_EVT),
+ exitEvt(Launcher.ON_CREATE_EVT),
+ enterEvt(OtherActivityInputConsumer.DOWN_EVT),
+ exitEvt(OtherActivityInputConsumer.DOWN_EVT));
+
+ runTest(enterEvt(OtherActivityInputConsumer.DOWN_EVT),
+ exitEvt(OtherActivityInputConsumer.DOWN_EVT),
+ enterEvt(Launcher.ON_CREATE_EVT),
+ exitEvt(Launcher.ON_CREATE_EVT));
+ }
+
+ @Test
@NavigationModeSwitch
public void testStressPressHome() {
for (int i = 0; i < STRESS_REPEAT_COUNT; ++i) {
@@ -66,7 +86,7 @@ public class StartLauncherViaGestureTests extends AbstractQuickStepTest {
closeLauncherActivity();
// The test action.
- mLauncher.goHome();
+ mLauncher.pressHome();
}
}
@@ -78,9 +98,9 @@ public class StartLauncherViaGestureTests extends AbstractQuickStepTest {
closeLauncherActivity();
// The test action.
- mLauncher.getLaunchedAppState().switchToOverview();
+ mLauncher.getBackground().switchToOverview();
}
closeLauncherActivity();
- mLauncher.goHome();
+ mLauncher.pressHome();
}
}
diff --git a/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java b/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java
index 4bf247c75d..a5038a1fb0 100644
--- a/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java
+++ b/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java
@@ -21,9 +21,9 @@ import static com.android.launcher3.ui.TaplTestsLauncher3.getAppPackageName;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
-import static org.junit.Assume.assumeTrue;
import android.content.Intent;
+import android.util.Log;
import androidx.test.filters.LargeTest;
import androidx.test.runner.AndroidJUnit4;
@@ -32,13 +32,13 @@ import androidx.test.uiautomator.Until;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherState;
-import com.android.launcher3.tapl.LaunchedAppState;
+import com.android.launcher3.tapl.Background;
import com.android.launcher3.tapl.LauncherInstrumentation.NavigationModel;
import com.android.launcher3.tapl.Overview;
import com.android.launcher3.tapl.OverviewActions;
import com.android.launcher3.tapl.OverviewTask;
+import com.android.launcher3.testing.TestProtocol;
import com.android.launcher3.ui.TaplTestsLauncher3;
-import com.android.launcher3.util.rule.ScreenRecordRule.ScreenRecord;
import com.android.quickstep.NavigationModeSwitchRule.NavigationModeSwitch;
import com.android.quickstep.views.RecentsView;
@@ -50,11 +50,6 @@ import org.junit.runner.RunWith;
@LargeTest
@RunWith(AndroidJUnit4.class)
public class TaplTestsQuickstep extends AbstractQuickStepTest {
-
- private static final String APP_NAME = "LauncherTestApp";
- private static final String CALCULATOR_APP_PACKAGE =
- resolveSystemApp(Intent.CATEGORY_APP_CALCULATOR);
-
@Before
public void setUp() throws Exception {
super.setUp();
@@ -75,7 +70,7 @@ public class TaplTestsQuickstep extends AbstractQuickStepTest {
public static void startTestApps() throws Exception {
startAppFast(getAppPackageName());
- startAppFast(CALCULATOR_APP_PACKAGE);
+ startAppFast(resolveSystemApp(Intent.CATEGORY_APP_CALCULATOR));
startTestActivity(2);
}
@@ -84,7 +79,7 @@ public class TaplTestsQuickstep extends AbstractQuickStepTest {
executeOnLauncher(launcher -> assertTrue(
"Launcher activity is the top activity; expecting another activity to be the top "
+ "one",
- isInLaunchedApp(launcher)));
+ isInBackground(launcher)));
}
@Test
@@ -102,7 +97,7 @@ public class TaplTestsQuickstep extends AbstractQuickStepTest {
public void testOverview() throws Exception {
startTestAppsWithCheck();
// mLauncher.pressHome() also tests an important case of pressing home while in background.
- Overview overview = mLauncher.goHome().switchToOverview();
+ Overview overview = mLauncher.pressHome().switchToOverview();
assertTrue("Launcher internal state didn't switch to Overview",
isInState(() -> LauncherState.OVERVIEW));
executeOnLauncher(
@@ -127,7 +122,7 @@ public class TaplTestsQuickstep extends AbstractQuickStepTest {
getCurrentOverviewPage(launcher) < currentTaskAfterFlingForward));
// Test opening a task.
- OverviewTask task = mLauncher.goHome().switchToOverview().getCurrentTask();
+ OverviewTask task = mLauncher.pressHome().switchToOverview().getCurrentTask();
assertNotNull("overview.getCurrentTask() returned null (1)", task);
assertNotNull("OverviewTask.open returned null", task.open());
assertTrue("Test activity didn't open from Overview", mDevice.wait(Until.hasObject(
@@ -136,10 +131,10 @@ public class TaplTestsQuickstep extends AbstractQuickStepTest {
executeOnLauncher(launcher -> assertTrue(
"Launcher activity is the top activity; expecting another activity to be the top "
+ "one",
- isInLaunchedApp(launcher)));
+ isInBackground(launcher)));
// Test dismissing a task.
- overview = mLauncher.goHome().switchToOverview();
+ overview = mLauncher.pressHome().switchToOverview();
assertTrue("Launcher internal state didn't switch to Overview",
isInState(() -> LauncherState.OVERVIEW));
final Integer numTasks = getFromLauncher(launcher -> getTaskCount(launcher));
@@ -150,10 +145,13 @@ public class TaplTestsQuickstep extends AbstractQuickStepTest {
launcher -> assertEquals("Dismissing a task didn't remove 1 task from Overview",
numTasks - 1, getTaskCount(launcher)));
+ // Test UIDevice.pressHome, once we are in AllApps.
+ mDevice.pressHome();
+ waitForState("Launcher internal state didn't switch to Home", () -> LauncherState.NORMAL);
+
// Test dismissing all tasks.
- mLauncher.goHome().switchToOverview().dismissAllTasks();
- assertTrue("Launcher internal state is not Home",
- isInState(() -> LauncherState.NORMAL));
+ mLauncher.getWorkspace().switchToOverview().dismissAllTasks();
+ waitForState("Launcher internal state didn't switch to Home", () -> LauncherState.NORMAL);
executeOnLauncher(
launcher -> assertEquals("Still have tasks after dismissing all",
0, getTaskCount(launcher)));
@@ -165,18 +163,18 @@ public class TaplTestsQuickstep extends AbstractQuickStepTest {
@Test
@NavigationModeSwitch
@PortraitLandscape
- @ScreenRecord // b/195673272
public void testOverviewActions() throws Exception {
// Experimenting for b/165029151:
- final Overview overview = mLauncher.goHome().switchToOverview();
+ final Overview overview = mLauncher.pressHome().switchToOverview();
if (overview.hasTasks()) overview.dismissAllTasks();
- mLauncher.goHome();
+ mLauncher.pressHome();
//
startTestAppsWithCheck();
OverviewActions actionsView =
- mLauncher.goHome().switchToOverview().getOverviewActions();
+ mLauncher.pressHome().switchToOverview().getOverviewActions();
actionsView.clickAndDismissScreenshot();
+ actionsView.clickAndDismissShare();
}
private int getCurrentOverviewPage(Launcher launcher) {
@@ -187,20 +185,12 @@ public class TaplTestsQuickstep extends AbstractQuickStepTest {
return launcher.<RecentsView>getOverviewPanel().getTaskViewCount();
}
- private int getTopRowTaskCountForTablet(Launcher launcher) {
- return launcher.<RecentsView>getOverviewPanel().getTopRowTaskCountForTablet();
- }
-
- private int getBottomRowTaskCountForTablet(Launcher launcher) {
- return launcher.<RecentsView>getOverviewPanel().getBottomRowTaskCountForTablet();
- }
-
@Test
@NavigationModeSwitch
@PortraitLandscape
public void testSwitchToOverview() throws Exception {
assertNotNull("Workspace.switchToOverview() returned null",
- mLauncher.goHome().switchToOverview());
+ mLauncher.pressHome().switchToOverview());
assertTrue("Launcher internal state didn't switch to Overview",
isInState(() -> LauncherState.OVERVIEW));
}
@@ -209,23 +199,22 @@ public class TaplTestsQuickstep extends AbstractQuickStepTest {
@NavigationModeSwitch
@PortraitLandscape
public void testBackground() throws Exception {
- startAppFast(CALCULATOR_APP_PACKAGE);
- final LaunchedAppState launchedAppState = getAndAssertLaunchedApp();
+ startAppFast(resolveSystemApp(Intent.CATEGORY_APP_CALCULATOR));
+ final Background background = getAndAssertBackground();
- assertNotNull("Background.switchToOverview() returned null",
- launchedAppState.switchToOverview());
+ assertNotNull("Background.switchToOverview() returned null", background.switchToOverview());
assertTrue("Launcher internal state didn't switch to Overview",
isInState(() -> LauncherState.OVERVIEW));
}
- private LaunchedAppState getAndAssertLaunchedApp() {
- final LaunchedAppState launchedAppState = mLauncher.getLaunchedAppState();
- assertNotNull("Launcher.getLaunchedApp() returned null", launchedAppState);
+ private Background getAndAssertBackground() {
+ final Background background = mLauncher.getBackground();
+ assertNotNull("Launcher.getBackground() returned null", background);
executeOnLauncher(launcher -> assertTrue(
"Launcher activity is the top activity; expecting another activity to be the top "
+ "one",
- isInLaunchedApp(launcher)));
- return launchedAppState;
+ isInBackground(launcher)));
+ return background;
}
@Test
@@ -240,7 +229,7 @@ public class TaplTestsQuickstep extends AbstractQuickStepTest {
// Testing pressHome.
assertTrue("Launcher internal state is not All Apps",
isInState(() -> LauncherState.ALL_APPS));
- assertNotNull("pressHome returned null", mLauncher.goHome());
+ assertNotNull("pressHome returned null", mLauncher.pressHome());
assertTrue("Launcher internal state is not Home",
isInState(() -> LauncherState.NORMAL));
assertNotNull("getHome returned null", mLauncher.getWorkspace());
@@ -254,13 +243,13 @@ public class TaplTestsQuickstep extends AbstractQuickStepTest {
startTestActivity(3);
startTestActivity(4);
- LaunchedAppState launchedAppState = getAndAssertLaunchedApp();
- launchedAppState.quickSwitchToPreviousApp();
+ Background background = getAndAssertBackground();
+ background.quickSwitchToPreviousApp();
assertTrue("The first app we should have quick switched to is not running",
isTestActivityRunning(3));
- launchedAppState = getAndAssertLaunchedApp();
- launchedAppState.quickSwitchToPreviousApp();
+ background = getAndAssertBackground();
+ background.quickSwitchToPreviousApp();
if (mLauncher.getNavigationModel() == NavigationModel.THREE_BUTTON) {
// 3-button mode toggles between 2 apps, rather than going back further.
assertTrue("Second quick switch should have returned to the first app.",
@@ -269,13 +258,11 @@ public class TaplTestsQuickstep extends AbstractQuickStepTest {
assertTrue("The second app we should have quick switched to is not running",
isTestActivityRunning(2));
}
- launchedAppState = getAndAssertLaunchedApp();
- launchedAppState.quickSwitchToPreviousAppSwipeLeft();
+ background = getAndAssertBackground();
+ background.quickSwitchToPreviousAppSwipeLeft();
assertTrue("The 2nd app we should have quick switched to is not running",
isTestActivityRunning(3));
-
- launchedAppState = getAndAssertLaunchedApp();
- launchedAppState.switchToOverview();
+ getAndAssertBackground();
}
private boolean isTestActivityRunning(int activityNumber) {
@@ -289,89 +276,9 @@ public class TaplTestsQuickstep extends AbstractQuickStepTest {
@PortraitLandscape
public void testQuickSwitchFromHome() throws Exception {
startTestActivity(2);
- mLauncher.goHome().quickSwitchToPreviousApp();
+ mLauncher.pressHome().quickSwitchToPreviousApp();
assertTrue("The most recent task is not running after quick switching from home",
isTestActivityRunning(2));
- getAndAssertLaunchedApp();
- }
-
- @Test
- @PortraitLandscape
- @NavigationModeSwitch
- public void testPressBack() throws Exception {
- mLauncher.getWorkspace().switchToAllApps();
- mLauncher.pressBack();
- mLauncher.getWorkspace();
- waitForState("Launcher internal state didn't switch to Home", () -> LauncherState.NORMAL);
-
- startAppFast(CALCULATOR_APP_PACKAGE);
- mLauncher.pressBack();
- mLauncher.getWorkspace();
- waitForState("Launcher internal state didn't switch to Home", () -> LauncherState.NORMAL);
- }
-
- @Test
- @PortraitLandscape
- public void testOverviewForTablet() throws Exception {
- assumeTrue(mLauncher.isTablet());
-
- for (int i = 2; i <= 14; i++) {
- startTestActivity(i);
- }
-
- Overview overview = mLauncher.goHome().switchToOverview();
- executeOnLauncher(
- launcher -> assertTrue("Don't have at least 13 tasks",
- getTaskCount(launcher) >= 13));
-
- // Test scroll the first task off screen
- overview.scrollCurrentTaskOffScreen();
- assertTrue("Launcher internal state is not Overview",
- isInState(() -> LauncherState.OVERVIEW));
- executeOnLauncher(launcher -> assertTrue("Current task in Overview is still 0",
- getCurrentOverviewPage(launcher) > 0));
-
- // Test opening the task.
- overview.getCurrentTask().open();
- assertTrue("Test activity didn't open from Overview",
- mDevice.wait(Until.hasObject(By.pkg(getAppPackageName()).text("TestActivity10")),
- DEFAULT_UI_TIMEOUT));
-
- // Scroll the task offscreen as it is now first
- overview = mLauncher.goHome().switchToOverview();
- overview.scrollCurrentTaskOffScreen();
- assertTrue("Launcher internal state is not Overview",
- isInState(() -> LauncherState.OVERVIEW));
- executeOnLauncher(launcher -> assertTrue("Current task in Overview is still 0",
- getCurrentOverviewPage(launcher) > 0));
-
- // Test dismissing the later task.
- final Integer numTasks = getFromLauncher(this::getTaskCount);
- overview.getCurrentTask().dismiss();
- executeOnLauncher(
- launcher -> assertEquals("Dismissing a task didn't remove 1 task from Overview",
- numTasks - 1, getTaskCount(launcher)));
- executeOnLauncher(launcher -> assertTrue("Grid did not rebalance after dismissal",
- (Math.abs(getTopRowTaskCountForTablet(launcher) - getBottomRowTaskCountForTablet(
- launcher)) <= 1)));
-
- // Test dismissing more tasks.
- assertTrue("Launcher internal state didn't remain in Overview",
- isInState(() -> LauncherState.OVERVIEW));
- overview.getCurrentTask().dismiss();
- assertTrue("Launcher internal state didn't remain in Overview",
- isInState(() -> LauncherState.OVERVIEW));
- overview.getCurrentTask().dismiss();
- executeOnLauncher(launcher -> assertTrue("Grid did not rebalance after multiple dismissals",
- (Math.abs(getTopRowTaskCountForTablet(launcher) - getBottomRowTaskCountForTablet(
- launcher)) <= 1)));
-
- // Test dismissing all tasks.
- mLauncher.goHome().switchToOverview().dismissAllTasks();
- assertTrue("Launcher internal state is not Home",
- isInState(() -> LauncherState.NORMAL));
- executeOnLauncher(
- launcher -> assertEquals("Still have tasks after dismissing all",
- 0, getTaskCount(launcher)));
+ getAndAssertBackground();
}
}
diff --git a/quickstep/tests/src/com/android/quickstep/TaplTestsTaskbar.java b/quickstep/tests/src/com/android/quickstep/TaplTestsTaskbar.java
deleted file mode 100644
index 1df9c02ee8..0000000000
--- a/quickstep/tests/src/com/android/quickstep/TaplTestsTaskbar.java
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.quickstep;
-
-import static androidx.test.InstrumentationRegistry.getInstrumentation;
-
-import static junit.framework.TestCase.assertEquals;
-
-import android.content.Intent;
-
-import androidx.test.filters.LargeTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import com.android.launcher3.tapl.Taskbar;
-import com.android.launcher3.ui.TaplTestsLauncher3;
-import com.android.launcher3.util.rule.ScreenRecordRule.ScreenRecord;
-
-import org.junit.After;
-import org.junit.Assume;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.List;
-
-@LargeTest
-@RunWith(AndroidJUnit4.class)
-public class TaplTestsTaskbar extends AbstractQuickStepTest {
-
- private static final String TEST_APP_NAME = "LauncherTestApp";
- private static final String TEST_APP_PACKAGE =
- getInstrumentation().getContext().getPackageName();
- private static final String CALCULATOR_APP_PACKAGE =
- resolveSystemApp(Intent.CATEGORY_APP_CALCULATOR);
-
- @Override
- public void setUp() throws Exception {
- Assume.assumeTrue(mLauncher.isTablet());
- super.setUp();
- mLauncher.useTestWorkspaceLayoutOnReload();
- TaplTestsLauncher3.initialize(this);
-
- startAppFast(CALCULATOR_APP_PACKAGE);
- mLauncher.showTaskbarIfHidden();
- }
-
- @After
- public void tearDown() {
- mLauncher.useDefaultWorkspaceLayoutOnReload();
- }
-
- @Test
- public void testHideShowTaskbar() {
- getTaskbar().hide();
- mLauncher.getLaunchedAppState().showTaskbar();
- }
-
- @Test
- public void testLaunchApp() throws Exception {
- getTaskbar().getAppIcon(TEST_APP_NAME).launch(TEST_APP_PACKAGE);
- }
-
- @Test
- public void testOpenMenu() throws Exception {
- getTaskbar().getAppIcon(TEST_APP_NAME).openMenu();
- }
-
- @Test
- public void testLaunchShortcut() throws Exception {
- getTaskbar().getAppIcon(TEST_APP_NAME)
- .openDeepShortcutMenu()
- .getMenuItem("Shortcut 1")
- .launch(TEST_APP_PACKAGE);
- }
-
- @Test
- @ScreenRecord // b/231615831
- @PortraitLandscape
- public void testLaunchAppInSplitscreen() throws Exception {
- getTaskbar().getAppIcon(TEST_APP_NAME).dragToSplitscreen(
- TEST_APP_PACKAGE, CALCULATOR_APP_PACKAGE);
- }
-
- @Test
- @ScreenRecord // b/231615831
- @PortraitLandscape
- public void testLaunchShortcutInSplitscreen() throws Exception {
- getTaskbar().getAppIcon(TEST_APP_NAME)
- .openDeepShortcutMenu()
- .getMenuItem("Shortcut 1")
- .dragToSplitscreen(TEST_APP_PACKAGE, CALCULATOR_APP_PACKAGE);
- }
-
- @Test
- public void testLaunchApp_FromTaskbarAllApps() throws Exception {
- getTaskbar().openAllApps().getAppIcon(TEST_APP_NAME).launch(TEST_APP_PACKAGE);
- }
-
- @Test
- public void testOpenMenu_FromTaskbarAllApps() throws Exception {
- getTaskbar().openAllApps().getAppIcon(TEST_APP_NAME).openMenu();
- }
-
- @Test
- public void testLaunchShortcut_FromTaskbarAllApps() throws Exception {
- getTaskbar().openAllApps()
- .getAppIcon(TEST_APP_NAME)
- .openDeepShortcutMenu()
- .getMenuItem("Shortcut 1")
- .launch(TEST_APP_PACKAGE);
- }
-
- @Test
- @ScreenRecord // b/231615831
- @PortraitLandscape
- public void testLaunchAppInSplitscreen_FromTaskbarAllApps() throws Exception {
- getTaskbar().openAllApps()
- .getAppIcon(TEST_APP_NAME)
- .dragToSplitscreen(TEST_APP_PACKAGE, CALCULATOR_APP_PACKAGE);
- }
-
- @Test
- @ScreenRecord // b/231615831
- @PortraitLandscape
- public void testLaunchShortcutInSplitscreen_FromTaskbarAllApps() throws Exception {
- getTaskbar().openAllApps()
- .getAppIcon(TEST_APP_NAME)
- .openDeepShortcutMenu()
- .getMenuItem("Shortcut 1")
- .dragToSplitscreen(TEST_APP_PACKAGE, CALCULATOR_APP_PACKAGE);
- }
-
- private Taskbar getTaskbar() {
- Taskbar taskbar = mLauncher.getLaunchedAppState().getTaskbar();
- List<String> taskbarIconNames = taskbar.getIconNames();
- List<String> hotseatIconNames = mLauncher.getHotseatIconNames();
-
- assertEquals("Taskbar and hotseat icon counts do not match",
- taskbarIconNames.size(), hotseatIconNames.size());
-
- for (int i = 0; i < taskbarIconNames.size(); i++) {
- assertEquals("Taskbar and Hotseat icons do not match",
- taskbarIconNames, hotseatIconNames);
- }
-
- return taskbar;
- }
-}
diff --git a/quickstep/tests/src/com/android/quickstep/ViewInflationDuringSwipeUp.java b/quickstep/tests/src/com/android/quickstep/ViewInflationDuringSwipeUp.java
index 7e408a8587..f33abb06fc 100644
--- a/quickstep/tests/src/com/android/quickstep/ViewInflationDuringSwipeUp.java
+++ b/quickstep/tests/src/com/android/quickstep/ViewInflationDuringSwipeUp.java
@@ -19,9 +19,9 @@ import static androidx.test.InstrumentationRegistry.getContext;
import static androidx.test.InstrumentationRegistry.getInstrumentation;
import static androidx.test.InstrumentationRegistry.getTargetContext;
+import static com.android.launcher3.common.WidgetUtils.createWidgetInfo;
import static com.android.launcher3.testcomponent.TestCommandReceiver.EXTRA_VALUE;
import static com.android.launcher3.testcomponent.TestCommandReceiver.SET_LIST_VIEW_SERVICE_BINDER;
-import static com.android.launcher3.util.WidgetUtils.createWidgetInfo;
import static com.android.quickstep.NavigationModeSwitchRule.Mode.ZERO_BUTTON;
import static org.junit.Assert.assertEquals;
@@ -51,7 +51,7 @@ import androidx.test.uiautomator.Until;
import com.android.launcher3.LauncherSettings;
import com.android.launcher3.model.data.LauncherAppWidgetInfo;
-import com.android.launcher3.tapl.LaunchedAppState;
+import com.android.launcher3.tapl.Background;
import com.android.launcher3.testcomponent.ListViewService;
import com.android.launcher3.testcomponent.ListViewService.SimpleViewsFactory;
import com.android.launcher3.testcomponent.TestCommandReceiver;
@@ -119,13 +119,13 @@ public class ViewInflationDuringSwipeUp extends AbstractQuickStepTest {
try {
// Go to overview once so that all views are initialized and cached
startAppFast(resolveSystemApp(Intent.CATEGORY_APP_CALCULATOR));
- mLauncher.getLaunchedAppState().switchToOverview().dismissAllTasks();
+ mLauncher.getBackground().switchToOverview().dismissAllTasks();
// Track view creations
mInitTracker.startTracking();
startTestActivity(2);
- mLauncher.getLaunchedAppState().switchToOverview();
+ mLauncher.getBackground().switchToOverview();
assertEquals("Views inflated during swipe up", 0, mInitTracker.viewInitCount);
} finally {
@@ -197,7 +197,7 @@ public class ViewInflationDuringSwipeUp extends AbstractQuickStepTest {
addItemToScreen(item);
assertTrue("Widget is not present",
- mLauncher.goHome().tryGetWidget(info.label, DEFAULT_UI_TIMEOUT) != null);
+ mLauncher.pressHome().tryGetWidget(info.label, DEFAULT_UI_TIMEOUT) != null);
int widgetId = item.appWidgetId;
// Verify widget id
@@ -205,23 +205,23 @@ public class ViewInflationDuringSwipeUp extends AbstractQuickStepTest {
// Go to overview once so that all views are initialized and cached
startAppFast(resolveSystemApp(Intent.CATEGORY_APP_CALCULATOR));
- mLauncher.getLaunchedAppState().switchToOverview().dismissAllTasks();
+ mLauncher.getBackground().switchToOverview().dismissAllTasks();
// Track view creations
mInitTracker.startTracking();
startTestActivity(2);
- LaunchedAppState launchedAppState = mLauncher.getLaunchedAppState();
+ Background background = mLauncher.getBackground();
// Update widget
updateBeforeSwipeUp.accept(widgetId);
- launchedAppState.switchToOverview();
+ background.switchToOverview();
assertEquals("Views inflated during swipe up", 0, mInitTracker.viewInitCount);
// Widget is updated when going home
mInitTracker.disableLog();
- mLauncher.goHome();
+ mLauncher.pressHome();
verifyWidget(finalWidgetText);
assertNotEquals(1, mInitTracker.viewInitCount);
} finally {
diff --git a/res/anim-v33/shared_x_axis_activity_close_enter.xml b/res/anim-v33/shared_x_axis_activity_close_enter.xml
deleted file mode 100644
index 94ef06c604..0000000000
--- a/res/anim-v33/shared_x_axis_activity_close_enter.xml
+++ /dev/null
@@ -1,42 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2022 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-
-<set xmlns:android="http://schemas.android.com/apk/res/android"
- android:shareInterpolator="false"
- android:showBackdrop="true">
-
- <alpha
- android:fromAlpha="0.0"
- android:toAlpha="1.0"
- android:fillEnabled="true"
- android:fillBefore="true"
- android:fillAfter="true"
- android:interpolator="@interpolator/standard_decelerate"
- android:startOffset="100"
- android:duration="350" />
-
- <translate
- android:fromXDelta="-25%"
- android:toXDelta="0"
- android:fillEnabled="true"
- android:fillBefore="true"
- android:fillAfter="true"
- android:interpolator="@interpolator/fast_out_extra_slow_in"
- android:startOffset="0"
- android:duration="450" />
-
-</set> \ No newline at end of file
diff --git a/res/anim-v33/shared_x_axis_activity_close_exit.xml b/res/anim-v33/shared_x_axis_activity_close_exit.xml
deleted file mode 100644
index 19eb09e4d3..0000000000
--- a/res/anim-v33/shared_x_axis_activity_close_exit.xml
+++ /dev/null
@@ -1,41 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2022 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-
-<set xmlns:android="http://schemas.android.com/apk/res/android"
- android:shareInterpolator="false">
-
- <alpha
- android:fromAlpha="1.0"
- android:toAlpha="0.0"
- android:fillEnabled="true"
- android:fillBefore="true"
- android:fillAfter="true"
- android:interpolator="@interpolator/standard_accelerate"
- android:startOffset="0"
- android:duration="100" />
-
- <translate
- android:fromXDelta="0"
- android:toXDelta="25%"
- android:fillEnabled="true"
- android:fillBefore="true"
- android:fillAfter="true"
- android:interpolator="@interpolator/fast_out_extra_slow_in"
- android:startOffset="0"
- android:duration="450" />
-
-</set> \ No newline at end of file
diff --git a/res/anim-v33/shared_x_axis_activity_open_enter.xml b/res/anim-v33/shared_x_axis_activity_open_enter.xml
deleted file mode 100644
index f699ceca70..0000000000
--- a/res/anim-v33/shared_x_axis_activity_open_enter.xml
+++ /dev/null
@@ -1,42 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2022 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-
-<set xmlns:android="http://schemas.android.com/apk/res/android"
- android:shareInterpolator="false"
- android:showBackdrop="true">
-
- <alpha
- android:fromAlpha="0.0"
- android:toAlpha="1.0"
- android:fillEnabled="true"
- android:fillBefore="true"
- android:fillAfter="true"
- android:interpolator="@interpolator/standard_decelerate"
- android:startOffset="100"
- android:duration="350" />
-
- <translate
- android:fromXDelta="25%"
- android:toXDelta="0"
- android:fillEnabled="true"
- android:fillBefore="true"
- android:fillAfter="true"
- android:interpolator="@interpolator/fast_out_extra_slow_in"
- android:startOffset="0"
- android:duration="450" />
-
-</set> \ No newline at end of file
diff --git a/res/anim-v33/shared_x_axis_activity_open_exit.xml b/res/anim-v33/shared_x_axis_activity_open_exit.xml
deleted file mode 100644
index 85988ecfd2..0000000000
--- a/res/anim-v33/shared_x_axis_activity_open_exit.xml
+++ /dev/null
@@ -1,41 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2022 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-
-<set xmlns:android="http://schemas.android.com/apk/res/android"
- android:shareInterpolator="false">
-
- <alpha
- android:fromAlpha="1.0"
- android:toAlpha="0.0"
- android:fillEnabled="true"
- android:fillBefore="true"
- android:fillAfter="true"
- android:interpolator="@interpolator/standard_accelerate"
- android:startOffset="0"
- android:duration="100" />
-
- <translate
- android:fromXDelta="0"
- android:toXDelta="-25%"
- android:fillEnabled="true"
- android:fillBefore="true"
- android:fillAfter="true"
- android:interpolator="@interpolator/fast_out_extra_slow_in"
- android:startOffset="0"
- android:duration="450" />
-
-</set> \ No newline at end of file
diff --git a/res/color-night-v31/accent_ripple_color.xml b/res/color-night-v31/accent_ripple_color.xml
deleted file mode 100644
index cb149d6786..0000000000
--- a/res/color-night-v31/accent_ripple_color.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:color="@android:color/system_accent1_300"/>
-</selector> \ No newline at end of file
diff --git a/res/color-night-v31/all_apps_button_color_2.xml b/res/color-night-v31/all_apps_button_color_2.xml
deleted file mode 100644
index e4005439ff..0000000000
--- a/res/color-night-v31/all_apps_button_color_2.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2022 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<selector xmlns:android="http://schemas.android.com/apk/res/android" >
- <item
- android:color="@android:color/system_accent2_500"
- android:lStar="98" />
-</selector>
diff --git a/res/color-night-v31/folder_background_dark.xml b/res/color-night-v31/folder_background_dark.xml
index 696e8ea67e..a5bd6367d5 100644
--- a/res/color-night-v31/folder_background_dark.xml
+++ b/res/color-night-v31/folder_background_dark.xml
@@ -15,6 +15,6 @@
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item
- android:color="@android:color/system_neutral2_500"
- android:lStar="35" />
+ android:color="@android:color/system_neutral2_50"
+ android:lStar="30" />
</selector>
diff --git a/res/color-night/accent_ripple_color.xml b/res/color-night/accent_ripple_color.xml
deleted file mode 100644
index 4a37b00ab8..0000000000
--- a/res/color-night/accent_ripple_color.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:color="#53BCAC"/>
-</selector> \ No newline at end of file
diff --git a/res/color-v31/accent_ripple_color.xml b/res/color-v31/accent_ripple_color.xml
deleted file mode 100644
index a996228daa..0000000000
--- a/res/color-v31/accent_ripple_color.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:color="@android:color/system_accent2_50"/>
-</selector> \ No newline at end of file
diff --git a/res/color-v31/all_apps_button_bg_color.xml b/res/color-v31/all_apps_button_bg_color.xml
deleted file mode 100644
index 89590207d5..0000000000
--- a/res/color-v31/all_apps_button_bg_color.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2022 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<selector xmlns:android="http://schemas.android.com/apk/res/android" >
- <item
- android:color="@android:color/system_neutral1_500"
- android:lStar="98" />
-</selector>
diff --git a/res/color-v31/all_apps_button_color_1.xml b/res/color-v31/all_apps_button_color_1.xml
deleted file mode 100644
index 71c7d8dc49..0000000000
--- a/res/color-v31/all_apps_button_color_1.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2022 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<selector xmlns:android="http://schemas.android.com/apk/res/android" >
- <item
- android:color="@android:color/system_accent1_500"
- android:lStar="40" />
-</selector>
diff --git a/res/color-v31/all_apps_button_color_2.xml b/res/color-v31/all_apps_button_color_2.xml
deleted file mode 100644
index 608c8a929b..0000000000
--- a/res/color-v31/all_apps_button_color_2.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2022 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<selector xmlns:android="http://schemas.android.com/apk/res/android" >
- <item
- android:color="@android:color/system_accent2_500"
- android:lStar="48" />
-</selector>
diff --git a/res/color-v31/all_apps_button_color_3.xml b/res/color-v31/all_apps_button_color_3.xml
deleted file mode 100644
index dbb97b13b2..0000000000
--- a/res/color-v31/all_apps_button_color_3.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2022 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<selector xmlns:android="http://schemas.android.com/apk/res/android" >
- <item
- android:color="@android:color/system_accent1_500"
- android:lStar="35" />
-</selector>
diff --git a/res/color-v31/all_apps_button_color_4.xml b/res/color-v31/all_apps_button_color_4.xml
deleted file mode 100644
index d02528f638..0000000000
--- a/res/color-v31/all_apps_button_color_4.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2022 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<selector xmlns:android="http://schemas.android.com/apk/res/android" >
- <item
- android:color="@android:color/system_accent3_500"
- android:lStar="48" />
-</selector>
diff --git a/res/color-v31/folder_background_light.xml b/res/color-v31/folder_background_light.xml
index eb2fdd7367..e3c7e7dab1 100644
--- a/res/color-v31/folder_background_light.xml
+++ b/res/color-v31/folder_background_light.xml
@@ -15,6 +15,6 @@
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item
- android:color="@android:color/system_neutral1_500"
+ android:color="@android:color/system_neutral1_50"
android:lStar="98" />
</selector>
diff --git a/res/color-v31/folder_preview_light.xml b/res/color-v31/folder_preview_light.xml
deleted file mode 100644
index ed1205ebb9..0000000000
--- a/res/color-v31/folder_preview_light.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2021 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.
--->
-<selector xmlns:android="http://schemas.android.com/apk/res/android" >
- <item
- android:color="@android:color/system_accent2_500"
- android:lStar="80" />
-</selector>
diff --git a/res/color-v31/home_settings_switch_thumb_color.xml b/res/color-v31/home_settings_switch_thumb_color.xml
deleted file mode 100644
index 91d3d9b5e4..0000000000
--- a/res/color-v31/home_settings_switch_thumb_color.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2021 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.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <!-- Disabled status of thumb -->
- <item android:state_enabled="false"
- android:color="@color/home_settings_thumb_off_color" />
- <!-- Toggle off status of thumb -->
- <item android:state_checked="false"
- android:color="@color/home_settings_thumb_off_color" />
- <!-- Enabled or toggle on status of thumb -->
- <item android:color="@color/home_settings_state_on_color" />
-</selector>
diff --git a/res/color-v31/home_settings_switch_track_color.xml b/res/color-v31/home_settings_switch_track_color.xml
deleted file mode 100644
index 50784f527d..0000000000
--- a/res/color-v31/home_settings_switch_track_color.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2021 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.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <!-- Disabled status of thumb -->
- <item android:state_enabled="false"
- android:color="@color/home_settings_track_off_color"
- android:alpha="?android:attr/disabledAlpha" />
- <!-- Toggle off status of thumb -->
- <item android:state_checked="false"
- android:color="@color/home_settings_track_off_color" />
- <!-- Enabled or toggle on status of thumb -->
- <item android:color="@color/home_settings_track_on_color" />
-</selector>
diff --git a/res/color-v31/overview_scrim.xml b/res/color-v31/overview_scrim.xml
index 212518ff65..80799957ff 100644
--- a/res/color-v31/overview_scrim.xml
+++ b/res/color-v31/overview_scrim.xml
@@ -14,5 +14,5 @@
limitations under the License.
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:color="@android:color/system_neutral2_200" />
+ <item android:color="@android:color/system_neutral2_500" android:lStar="87" />
</selector>
diff --git a/res/color-v31/overview_scrim_dark.xml b/res/color-v31/overview_scrim_dark.xml
index 2ab8ecdec9..b8ed7747e0 100644
--- a/res/color-v31/overview_scrim_dark.xml
+++ b/res/color-v31/overview_scrim_dark.xml
@@ -14,5 +14,5 @@
limitations under the License.
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:color="@android:color/system_neutral1_500" android:lStar="35" />
+ <item android:color="@android:color/system_neutral1_800" />
</selector>
diff --git a/res/color-v31/taskbar_background.xml b/res/color-v31/taskbar_background.xml
deleted file mode 100644
index eaf676f8f7..0000000000
--- a/res/color-v31/taskbar_background.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2022 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:color="@android:color/system_neutral1_500" android:lStar="15" />
-</selector>
diff --git a/res/color/accent_ripple_color.xml b/res/color/accent_ripple_color.xml
deleted file mode 100644
index 697f415ec7..0000000000
--- a/res/color/accent_ripple_color.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:color="#CDFAF1"/>
-</selector> \ No newline at end of file
diff --git a/res/color/system_shortcut_text.xml b/res/color/system_shortcut_text.xml
deleted file mode 100644
index f9f8239a99..0000000000
--- a/res/color/system_shortcut_text.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2021 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.
--->
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:color="?android:attr/textColorTertiary" android:state_enabled="false"/>
- <item android:color="?android:attr/textColorPrimary"/>
-</selector> \ No newline at end of file
diff --git a/res/drawable-v28/round_rect_folder.xml b/res/drawable-v28/round_rect_folder.xml
index 77a4aa4e98..0403be09b0 100644
--- a/res/drawable-v28/round_rect_folder.xml
+++ b/res/drawable-v28/round_rect_folder.xml
@@ -16,6 +16,6 @@
-->
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
- <solid android:color="?attr/folderBackgroundColor" />
+ <solid android:color="?attr/folderFillColor" />
<corners android:radius="?android:attr/dialogCornerRadius" />
</shape>
diff --git a/res/drawable/bg_widgets_full_sheet.xml b/res/drawable-v28/widgets_bottom_sheet_background.xml
index dfcd354ce7..7fb8681301 100644
--- a/res/drawable/bg_widgets_full_sheet.xml
+++ b/res/drawable-v28/widgets_bottom_sheet_background.xml
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2021 The Android Open Source Project
+<!--
+ Copyright (C) 2021 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.
@@ -13,11 +14,13 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-
<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle" >
- <solid android:color="?android:attr/colorBackground" />
+ android:shape="rectangle">
+ <solid android:color="@color/surface" />
<corners
- android:topLeftRadius="@dimen/dialogCornerRadius"
- android:topRightRadius="@dimen/dialogCornerRadius" />
+ android:topLeftRadius="?android:attr/dialogCornerRadius"
+ android:topRightRadius="?android:attr/dialogCornerRadius"
+ android:bottomLeftRadius="0dp"
+ android:bottomRightRadius="0dp"
+ />
</shape> \ No newline at end of file
diff --git a/res/drawable-v31/bg_deferred_app_widget.xml b/res/drawable-v31/bg_deferred_app_widget.xml
deleted file mode 100644
index a08998de7b..0000000000
--- a/res/drawable-v31/bg_deferred_app_widget.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2021 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.
--->
-<inset xmlns:android="http://schemas.android.com/apk/res/android"
- android:inset="8dp">
- <shape android:shape="rectangle">
- <corners android:radius="@android:dimen/system_app_widget_background_radius" />
- <solid android:color="#77000000" />
- </shape>
-</inset>
diff --git a/res/drawable-v31/home_settings_switch_thumb.xml b/res/drawable-v31/home_settings_switch_thumb.xml
deleted file mode 100644
index 260d5ea35f..0000000000
--- a/res/drawable-v31/home_settings_switch_thumb.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2021 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.
--->
-
-<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
- <item
- android:top="4dp"
- android:left="4dp"
- android:right="4dp"
- android:bottom="4dp">
- <shape android:shape="oval" >
- <size android:height="20dp" android:width="20dp" />
- <solid android:color="@color/home_settings_switch_thumb_color" />
- </shape>
- </item>
-</layer-list> \ No newline at end of file
diff --git a/res/drawable-v31/home_settings_switch_track.xml b/res/drawable-v31/home_settings_switch_track.xml
deleted file mode 100644
index 502a3007a9..0000000000
--- a/res/drawable-v31/home_settings_switch_track.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2021 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.
--->
-
-<shape
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle"
- android:width="52dp"
- android:height="28dp">
-
- <solid android:color="@color/home_settings_switch_track_color" />
- <corners android:radius="35dp" />
-</shape> \ No newline at end of file
diff --git a/res/drawable/all_apps_tabs_background.xml b/res/drawable/all_apps_tabs_background.xml
index 8471cd4539..aea2e7a98b 100644
--- a/res/drawable/all_apps_tabs_background.xml
+++ b/res/drawable/all_apps_tabs_background.xml
@@ -13,36 +13,23 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<ripple xmlns:android="http://schemas.android.com/apk/res/android"
- android:color="@color/accent_ripple_color">
-
- <item android:id="@android:id/mask">
+<selector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:enterFadeDuration="100">
+ <item
+ android:id="@+id/unselected"
+ android:state_selected="false">
<shape android:shape="rectangle">
<corners android:radius="@dimen/all_apps_header_pill_corner_radius" />
- <solid android:color="@color/accent_ripple_color" />
+ <solid android:color="@color/all_apps_tabs_background" />
</shape>
</item>
- <item>
- <selector android:enterFadeDuration="100">
- <item
- android:id="@+id/unselected"
- android:state_selected="false">
- <shape android:shape="rectangle">
- <corners android:radius="@dimen/all_apps_header_pill_corner_radius" />
- <solid android:color="@color/all_apps_tabs_background" />
- </shape>
- </item>
-
- <item
- android:id="@+id/selected"
- android:state_selected="true">
- <shape android:shape="rectangle">
- <corners android:radius="@dimen/all_apps_header_pill_corner_radius" />
- <solid android:color="@color/all_apps_tab_background_selected" />
- </shape>
- </item>
- </selector>
+ <item
+ android:id="@+id/selected"
+ android:state_selected="true">
+ <shape android:shape="rectangle">
+ <corners android:radius="@dimen/all_apps_header_pill_corner_radius" />
+ <solid android:color="@color/all_apps_tab_background_selected" />
+ </shape>
</item>
-
-</ripple> \ No newline at end of file
+</selector> \ No newline at end of file
diff --git a/res/drawable/bg_rounded_corner_bottom_sheet.xml b/res/drawable/bg_rounded_corner_bottom_sheet.xml
index dfcd354ce7..aa49bced7a 100644
--- a/res/drawable/bg_rounded_corner_bottom_sheet.xml
+++ b/res/drawable/bg_rounded_corner_bottom_sheet.xml
@@ -16,7 +16,7 @@
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
- <solid android:color="?android:attr/colorBackground" />
+ <solid android:color="@color/surface" />
<corners
android:topLeftRadius="@dimen/dialogCornerRadius"
android:topRightRadius="@dimen/dialogCornerRadius" />
diff --git a/quickstep/res/layout/taskbar_nav_button.xml b/res/drawable/bg_widgets_picker_handle.xml
index aea4885d15..68681a684d 100644
--- a/quickstep/res/layout/taskbar_nav_button.xml
+++ b/res/drawable/bg_widgets_picker_handle.xml
@@ -13,12 +13,17 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<ImageView
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="@dimen/taskbar_nav_buttons_size"
- android:layout_height="@dimen/taskbar_nav_buttons_size"
- android:background="@drawable/taskbar_icon_click_feedback_roundrect"
- android:scaleType="center"
- android:tint="@color/taskbar_nav_icon_light_color"
- tools:ignore="UseAppTint" /> \ No newline at end of file
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+ <item>
+ <shape android:shape="rectangle">
+ <solid android:color="?android:attr/colorBackground" />
+ <padding android:top="16dp"/>
+ </shape>
+ </item>
+ <item android:gravity="center">
+ <shape android:shape="rectangle">
+ <solid android:color="?android:attr/textColorSecondary" />
+ <size android:width="48dp" android:height="2dp" />
+ </shape>
+ </item>
+</layer-list> \ No newline at end of file
diff --git a/res/drawable/drop_target_frame.xml b/res/drawable/drop_target_frame.xml
index 9f04103510..666a96e940 100644
--- a/res/drawable/drop_target_frame.xml
+++ b/res/drawable/drop_target_frame.xml
@@ -17,6 +17,6 @@
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="@android:color/transparent" />
- <corners android:radius="80dp" />
+ <corners android:radius="28dp" />
<stroke android:width="2dp" android:color="?attr/workspaceAccentColor" />
</shape> \ No newline at end of file
diff --git a/res/drawable/gesture_tutorial_motion_overview_light_mode.xml b/res/drawable/gesture_tutorial_motion_overview_light_mode.xml
new file mode 100644
index 0000000000..75887c9352
--- /dev/null
+++ b/res/drawable/gesture_tutorial_motion_overview_light_mode.xml
@@ -0,0 +1,1587 @@
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:aapt="http://schemas.android.com/aapt">
+ <target android:name="_R_G_L_4_G_N_3_T_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="1050"
+ android:pathData="M 206,446C 206,446 206,395 206,395"
+ android:propertyName="translateXY"
+ android:propertyXName="translateX"
+ android:propertyYName="translateY"
+ android:startOffset="217">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.5,0 0.5,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_4_G_N_3_T_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="1050"
+ android:propertyName="scaleX"
+ android:startOffset="217"
+ android:valueFrom="1"
+ android:valueTo="0.6"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.5,0 0.5,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="1050"
+ android:propertyName="scaleY"
+ android:startOffset="217"
+ android:valueFrom="1"
+ android:valueTo="0.6"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.5,0 0.5,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_4_G_N_3_T_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="0"
+ android:propertyName="scaleY"
+ android:startOffset="3400"
+ android:valueFrom="1"
+ android:valueTo="0"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_L_0_G_L_27_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="0"
+ android:propertyName="scaleY"
+ android:startOffset="2083"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_L_0_G_L_26_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="0"
+ android:propertyName="scaleY"
+ android:startOffset="2083"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_L_0_G_L_25_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="0"
+ android:propertyName="scaleY"
+ android:startOffset="2083"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_L_0_G_L_24_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="0"
+ android:propertyName="scaleY"
+ android:startOffset="2083"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_L_0_G_L_23_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="0"
+ android:propertyName="scaleY"
+ android:startOffset="2083"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_L_0_G_L_22_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="0"
+ android:propertyName="scaleY"
+ android:startOffset="2083"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_L_0_G_L_21_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="0"
+ android:propertyName="scaleY"
+ android:startOffset="2083"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_L_0_G_L_20_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="0"
+ android:propertyName="scaleY"
+ android:startOffset="2083"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_L_0_G_L_19_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="0"
+ android:propertyName="scaleY"
+ android:startOffset="2083"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_L_0_G_L_18_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="0"
+ android:propertyName="scaleY"
+ android:startOffset="2083"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_L_0_G_L_17_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="0"
+ android:propertyName="scaleY"
+ android:startOffset="2083"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_L_0_G_L_16_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="0"
+ android:propertyName="scaleY"
+ android:startOffset="2083"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_L_0_G_L_15_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="0"
+ android:propertyName="scaleY"
+ android:startOffset="2083"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_L_0_G_L_14_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="0"
+ android:propertyName="scaleY"
+ android:startOffset="2083"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_L_0_G_L_13_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="0"
+ android:propertyName="scaleY"
+ android:startOffset="2083"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_L_0_G_L_12_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="0"
+ android:propertyName="scaleY"
+ android:startOffset="2083"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_L_0_G_L_11_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="0"
+ android:propertyName="scaleY"
+ android:startOffset="2083"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_L_0_G_L_10_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="0"
+ android:propertyName="scaleY"
+ android:startOffset="2083"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_L_0_G_L_9_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="0"
+ android:propertyName="scaleY"
+ android:startOffset="2083"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_L_0_G_L_8_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="0"
+ android:propertyName="scaleY"
+ android:startOffset="2083"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_L_0_G_L_7_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="0"
+ android:propertyName="scaleY"
+ android:startOffset="2083"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_L_0_G_L_6_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="0"
+ android:propertyName="scaleY"
+ android:startOffset="2083"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_L_0_G_L_5_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="0"
+ android:propertyName="scaleY"
+ android:startOffset="2083"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_L_0_G_L_4_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="0"
+ android:propertyName="scaleY"
+ android:startOffset="2083"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_L_0_G_L_3_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="0"
+ android:propertyName="scaleY"
+ android:startOffset="2083"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_L_0_G_L_2_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="0"
+ android:propertyName="scaleY"
+ android:startOffset="2083"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_L_0_G_L_1_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="0"
+ android:propertyName="scaleY"
+ android:startOffset="2083"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_L_0_G_L_0_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="0"
+ android:propertyName="scaleY"
+ android:startOffset="2083"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_L_0_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="0"
+ android:propertyName="scaleY"
+ android:startOffset="2083"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_N_2_T_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="350"
+ android:pathData="M 206,395C 206,403.5 206,437.5 206,446"
+ android:propertyName="translateXY"
+ android:propertyXName="translateX"
+ android:propertyYName="translateY"
+ android:startOffset="2083">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.34,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_N_2_T_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="350"
+ android:propertyName="scaleX"
+ android:startOffset="2083"
+ android:valueFrom="0.6"
+ android:valueTo="0.72718"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.34,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="350"
+ android:propertyName="scaleY"
+ android:startOffset="2083"
+ android:valueFrom="0.6"
+ android:valueTo="0.72718"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.34,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="217"
+ android:propertyName="scaleX"
+ android:startOffset="2433"
+ android:valueFrom="0.72718"
+ android:valueTo="0.72"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0 0.51,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="217"
+ android:propertyName="scaleY"
+ android:startOffset="2433"
+ android:valueFrom="0.72718"
+ android:valueTo="0.72"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0 0.51,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_3_G_N_2_T_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="0"
+ android:propertyName="scaleY"
+ android:startOffset="2083"
+ android:valueFrom="0"
+ android:valueTo="0.6"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_2_G_D_0_P_0_G_0_T_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="167"
+ android:propertyName="scaleX"
+ android:startOffset="2567"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="167"
+ android:propertyName="scaleY"
+ android:startOffset="2567"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_2_G_N_2_T_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="350"
+ android:pathData="M 206,395C 206,403.5 206,437.5 206,446"
+ android:propertyName="translateXY"
+ android:propertyXName="translateX"
+ android:propertyYName="translateY"
+ android:startOffset="2083">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.34,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_2_G_N_2_T_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="350"
+ android:propertyName="scaleX"
+ android:startOffset="2083"
+ android:valueFrom="0.6"
+ android:valueTo="0.72718"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.34,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="350"
+ android:propertyName="scaleY"
+ android:startOffset="2083"
+ android:valueFrom="0.6"
+ android:valueTo="0.72718"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.34,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="217"
+ android:propertyName="scaleX"
+ android:startOffset="2433"
+ android:valueFrom="0.72718"
+ android:valueTo="0.72"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0 0.51,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="217"
+ android:propertyName="scaleY"
+ android:startOffset="2433"
+ android:valueFrom="0.72718"
+ android:valueTo="0.72"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0 0.51,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_2_G_N_2_T_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="0"
+ android:propertyName="scaleY"
+ android:startOffset="2567"
+ android:valueFrom="0"
+ android:valueTo="0.6"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="250"
+ android:pathData="M -556.176,-7.307C -556.176,-7.307 -421.176,-7.307 -421.176,-7.307"
+ android:propertyName="translateXY"
+ android:propertyXName="translateX"
+ android:propertyYName="translateY"
+ android:startOffset="1350">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.272,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="417"
+ android:pathData="M -421.176,-7.307C -421.176,-7.307 -429.51,-7.307 -429.51,-7.307"
+ android:propertyName="translateXY"
+ android:propertyXName="translateX"
+ android:propertyYName="translateY"
+ android:startOffset="1600">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G_N_2_T_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="350"
+ android:pathData="M 206,395C 206,403.5 206,437.5 206,446"
+ android:propertyName="translateXY"
+ android:propertyXName="translateX"
+ android:propertyYName="translateY"
+ android:startOffset="2083">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.34,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G_N_2_T_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="350"
+ android:propertyName="scaleX"
+ android:startOffset="2083"
+ android:valueFrom="0.6"
+ android:valueTo="0.72718"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.34,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="350"
+ android:propertyName="scaleY"
+ android:startOffset="2083"
+ android:valueFrom="0.6"
+ android:valueTo="0.72718"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.34,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="217"
+ android:propertyName="scaleX"
+ android:startOffset="2433"
+ android:valueFrom="0.72718"
+ android:valueTo="0.72"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0 0.51,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="217"
+ android:propertyName="scaleY"
+ android:startOffset="2433"
+ android:valueFrom="0.72718"
+ android:valueTo="0.72"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0 0.51,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G_N_2_T_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="0"
+ android:propertyName="scaleY"
+ android:startOffset="1350"
+ android:valueFrom="0"
+ android:valueTo="0.6"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_D_0_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="217"
+ android:propertyName="fillAlpha"
+ android:startOffset="0"
+ android:valueFrom="0"
+ android:valueTo="0.75"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,0.833 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="1833"
+ android:propertyName="fillAlpha"
+ android:startOffset="217"
+ android:valueFrom="0.75"
+ android:valueTo="0.75"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0 0.667,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="167"
+ android:propertyName="fillAlpha"
+ android:startOffset="2050"
+ android:valueFrom="0.75"
+ android:valueTo="0"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_D_0_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="217"
+ android:propertyName="pathData"
+ android:startOffset="0"
+ android:valueFrom="M0 406 C21.54,406 39,423.46 39,445 C39,466.54 21.54,484 0,484 C-21.54,484 -39,466.54 -39,445 C-39,423.46 -21.54,406 0,406c "
+ android:valueTo="M0 395 C27.61,395 50,417.39 50,445 C50,472.61 27.61,495 0,495 C-27.61,495 -50,472.61 -50,445 C-50,417.39 -27.61,395 0,395c "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="1050"
+ android:propertyName="pathData"
+ android:startOffset="217"
+ android:valueFrom="M0 395 C27.61,395 50,417.39 50,445 C50,472.61 27.61,495 0,495 C-27.61,495 -50,472.61 -50,445 C-50,417.39 -27.61,395 0,395c "
+ android:valueTo="M0 166 C27.61,166 50,188.39 50,216 C50,243.61 27.61,266 0,266 C-27.61,266 -50,243.61 -50,216 C-50,188.39 -27.61,166 0,166c "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.5,0 0.5,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="783"
+ android:propertyName="pathData"
+ android:startOffset="1267"
+ android:valueFrom="M0 166 C27.61,166 50,188.39 50,216 C50,243.61 27.61,266 0,266 C-27.61,266 -50,243.61 -50,216 C-50,188.39 -27.61,166 0,166c "
+ android:valueTo="M0 166 C27.61,166 50,188.39 50,216 C50,243.61 27.61,266 0,266 C-27.61,266 -50,243.61 -50,216 C-50,188.39 -27.61,166 0,166c "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="167"
+ android:propertyName="pathData"
+ android:startOffset="2050"
+ android:valueFrom="M0 166 C27.61,166 50,188.39 50,216 C50,243.61 27.61,266 0,266 C-27.61,266 -50,243.61 -50,216 C-50,188.39 -27.61,166 0,166c "
+ android:valueTo="M0 180 C19.88,180 36,196.12 36,216 C36,235.88 19.88,252 0,252 C-19.88,252 -36,235.88 -36,216 C-36,196.12 -19.88,180 0,180c "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="time_group">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator
+ android:duration="2750"
+ android:propertyName="translateX"
+ android:startOffset="0"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+ <aapt:attr name="android:drawable">
+ <vector
+ android:width="412dp"
+ android:height="892dp"
+ android:viewportHeight="892"
+ android:viewportWidth="412">
+ <group android:name="_R_G">
+ <group
+ android:name="_R_G_L_5_G"
+ android:translateX="206"
+ android:translateY="446">
+ <path
+ android:name="_R_G_L_5_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="@color/fake_wallpaper_color_light_mode"
+ android:fillType="nonZero"
+ android:pathData=" M206 -446 C206,-446 206,446 206,446 C206,446 -206,446 -206,446 C-206,446 -206,-446 -206,-446 C-206,-446 206,-446 206,-446c " />
+ </group>
+ <group
+ android:name="_R_G_L_4_G_N_3_T_0"
+ android:scaleX="1"
+ android:scaleY="1"
+ android:translateX="206"
+ android:translateY="446">
+ <group
+ android:name="_R_G_L_4_G"
+ android:translateX="-206"
+ android:translateY="-446">
+ <group android:name="_R_G_L_4_G_L_0_G">
+ <group
+ android:name="_R_G_L_4_G_L_0_G_L_27_G"
+ android:translateX="206"
+ android:translateY="422.5">
+ <path
+ android:name="_R_G_L_4_G_L_0_G_L_27_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#dadce0"
+ android:fillType="nonZero"
+ android:pathData=" M206 -395.5 C206,-395.5 206,395.5 206,395.5 C206,395.5 -206,395.5 -206,395.5 C-206,395.5 -206,-395.5 -206,-395.5 C-206,-395.5 206,-395.5 206,-395.5c " />
+ </group>
+ <group
+ android:name="_R_G_L_4_G_L_0_G_L_26_G"
+ android:translateX="206"
+ android:translateY="496.5">
+ <path
+ android:name="_R_G_L_4_G_L_0_G_L_26_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#dadce0"
+ android:fillType="nonZero"
+ android:pathData=" M206 -377.5 C206,-377.5 206,377.5 206,377.5 C206,387.43 197.93,395.5 188,395.5 C188,395.5 -188,395.5 -188,395.5 C-197.93,395.5 -206,387.43 -206,377.5 C-206,377.5 -206,-377.5 -206,-377.5 C-206,-387.43 -197.93,-395.5 -188,-395.5 C-188,-395.5 188,-395.5 188,-395.5 C197.93,-395.5 206,-387.43 206,-377.5c " />
+ </group>
+ <group
+ android:name="_R_G_L_4_G_L_0_G_L_25_G"
+ android:translateX="206"
+ android:translateY="50.5">
+ <path
+ android:name="_R_G_L_4_G_L_0_G_L_25_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#e8eaed"
+ android:fillType="nonZero"
+ android:pathData=" M206 -23.5 C206,-23.5 206,50.5 206,50.5 C206,50.5 -206,50.5 -206,50.5 C-206,50.5 -206,-23.5 -206,-23.5 C-206,-23.5 206,-23.5 206,-23.5c " />
+ </group>
+ <group
+ android:name="_R_G_L_4_G_L_0_G_L_24_G"
+ android:translateX="206"
+ android:translateY="50.5">
+ <path
+ android:name="_R_G_L_4_G_L_0_G_L_24_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#e8eaed"
+ android:fillType="nonZero"
+ android:pathData=" M206 -32.5 C206,-32.5 206,32.5 206,32.5 C206,42.43 197.93,50.5 188,50.5 C188,50.5 -188,50.5 -188,50.5 C-197.93,50.5 -206,42.43 -206,32.5 C-206,32.5 -206,-32.5 -206,-32.5 C-206,-42.43 -197.93,-50.5 -188,-50.5 C-188,-50.5 188,-50.5 188,-50.5 C197.93,-50.5 206,-42.43 206,-32.5c " />
+ </group>
+ <group
+ android:name="_R_G_L_4_G_L_0_G_L_23_G"
+ android:translateX="54"
+ android:translateY="157">
+ <path
+ android:name="_R_G_L_4_G_L_0_G_L_23_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#9aa0a6"
+ android:fillType="nonZero"
+ android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
+ </group>
+ <group
+ android:name="_R_G_L_4_G_L_0_G_L_22_G"
+ android:translateX="54"
+ android:translateY="157">
+ <path
+ android:name="_R_G_L_4_G_L_0_G_L_22_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#9aa0a6"
+ android:fillType="nonZero"
+ android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
+ </group>
+ <group
+ android:name="_R_G_L_4_G_L_0_G_L_21_G"
+ android:translateX="148.5"
+ android:translateY="148">
+ <path
+ android:name="_R_G_L_4_G_L_0_G_L_21_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M46.5 -5 C46.5,-5 46.5,5 46.5,5 C46.5,7.21 44.71,9 42.5,9 C42.5,9 -42.5,9 -42.5,9 C-44.71,9 -46.5,7.21 -46.5,5 C-46.5,5 -46.5,-5 -46.5,-5 C-46.5,-7.21 -44.71,-9 -42.5,-9 C-42.5,-9 42.5,-9 42.5,-9 C44.71,-9 46.5,-7.21 46.5,-5c " />
+ </group>
+ <group
+ android:name="_R_G_L_4_G_L_0_G_L_20_G"
+ android:translateX="186"
+ android:translateY="169">
+ <path
+ android:name="_R_G_L_4_G_L_0_G_L_20_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M84 -4 C84,-4 84,4 84,4 C84,6.21 82.21,8 80,8 C80,8 -80,8 -80,8 C-82.21,8 -84,6.21 -84,4 C-84,4 -84,-4 -84,-4 C-84,-6.21 -82.21,-8 -80,-8 C-80,-8 80,-8 80,-8 C82.21,-8 84,-6.21 84,-4c " />
+ </group>
+ <group
+ android:name="_R_G_L_4_G_L_0_G_L_19_G"
+ android:translateX="54"
+ android:translateY="245">
+ <path
+ android:name="_R_G_L_4_G_L_0_G_L_19_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#9aa0a6"
+ android:fillType="nonZero"
+ android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
+ </group>
+ <group
+ android:name="_R_G_L_4_G_L_0_G_L_18_G"
+ android:translateX="162"
+ android:translateY="236">
+ <path
+ android:name="_R_G_L_4_G_L_0_G_L_18_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M60 -5 C60,-5 60,5 60,5 C60,7.21 58.21,9 56,9 C56,9 -56,9 -56,9 C-58.21,9 -60,7.21 -60,5 C-60,5 -60,-5 -60,-5 C-60,-7.21 -58.21,-9 -56,-9 C-56,-9 56,-9 56,-9 C58.21,-9 60,-7.21 60,-5c " />
+ </group>
+ <group
+ android:name="_R_G_L_4_G_L_0_G_L_17_G"
+ android:translateX="171.5"
+ android:translateY="257">
+ <path
+ android:name="_R_G_L_4_G_L_0_G_L_17_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M69.5 -4 C69.5,-4 69.5,4 69.5,4 C69.5,6.21 67.71,8 65.5,8 C65.5,8 -65.5,8 -65.5,8 C-67.71,8 -69.5,6.21 -69.5,4 C-69.5,4 -69.5,-4 -69.5,-4 C-69.5,-6.21 -67.71,-8 -65.5,-8 C-65.5,-8 65.5,-8 65.5,-8 C67.71,-8 69.5,-6.21 69.5,-4c " />
+ </group>
+ <group
+ android:name="_R_G_L_4_G_L_0_G_L_16_G"
+ android:translateX="54"
+ android:translateY="333">
+ <path
+ android:name="_R_G_L_4_G_L_0_G_L_16_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#9aa0a6"
+ android:fillType="nonZero"
+ android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
+ </group>
+ <group
+ android:name="_R_G_L_4_G_L_0_G_L_15_G"
+ android:translateX="158"
+ android:translateY="324">
+ <path
+ android:name="_R_G_L_4_G_L_0_G_L_15_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M56 -5 C56,-5 56,5 56,5 C56,7.21 54.21,9 52,9 C52,9 -52,9 -52,9 C-54.21,9 -56,7.21 -56,5 C-56,5 -56,-5 -56,-5 C-56,-7.21 -54.21,-9 -52,-9 C-52,-9 52,-9 52,-9 C54.21,-9 56,-7.21 56,-5c " />
+ </group>
+ <group
+ android:name="_R_G_L_4_G_L_0_G_L_14_G"
+ android:translateX="217.5"
+ android:translateY="345">
+ <path
+ android:name="_R_G_L_4_G_L_0_G_L_14_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M115.5 -4 C115.5,-4 115.5,4 115.5,4 C115.5,6.21 113.71,8 111.5,8 C111.5,8 -111.5,8 -111.5,8 C-113.71,8 -115.5,6.21 -115.5,4 C-115.5,4 -115.5,-4 -115.5,-4 C-115.5,-6.21 -113.71,-8 -111.5,-8 C-111.5,-8 111.5,-8 111.5,-8 C113.71,-8 115.5,-6.21 115.5,-4c " />
+ </group>
+ <group
+ android:name="_R_G_L_4_G_L_0_G_L_13_G"
+ android:translateX="54"
+ android:translateY="421">
+ <path
+ android:name="_R_G_L_4_G_L_0_G_L_13_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#9aa0a6"
+ android:fillType="nonZero"
+ android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
+ </group>
+ <group
+ android:name="_R_G_L_4_G_L_0_G_L_12_G"
+ android:translateX="170"
+ android:translateY="412">
+ <path
+ android:name="_R_G_L_4_G_L_0_G_L_12_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M68 -5 C68,-5 68,5 68,5 C68,7.21 66.21,9 64,9 C64,9 -64,9 -64,9 C-66.21,9 -68,7.21 -68,5 C-68,5 -68,-5 -68,-5 C-68,-7.21 -66.21,-9 -64,-9 C-64,-9 64,-9 64,-9 C66.21,-9 68,-7.21 68,-5c " />
+ </group>
+ <group
+ android:name="_R_G_L_4_G_L_0_G_L_11_G"
+ android:translateX="198.5"
+ android:translateY="433">
+ <path
+ android:name="_R_G_L_4_G_L_0_G_L_11_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M96.5 -4 C96.5,-4 96.5,4 96.5,4 C96.5,6.21 94.71,8 92.5,8 C92.5,8 -92.5,8 -92.5,8 C-94.71,8 -96.5,6.21 -96.5,4 C-96.5,4 -96.5,-4 -96.5,-4 C-96.5,-6.21 -94.71,-8 -92.5,-8 C-92.5,-8 92.5,-8 92.5,-8 C94.71,-8 96.5,-6.21 96.5,-4c " />
+ </group>
+ <group
+ android:name="_R_G_L_4_G_L_0_G_L_10_G"
+ android:translateX="54"
+ android:translateY="509">
+ <path
+ android:name="_R_G_L_4_G_L_0_G_L_10_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#9aa0a6"
+ android:fillType="nonZero"
+ android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
+ </group>
+ <group
+ android:name="_R_G_L_4_G_L_0_G_L_9_G"
+ android:translateX="135"
+ android:translateY="500">
+ <path
+ android:name="_R_G_L_4_G_L_0_G_L_9_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M33 -5 C33,-5 33,5 33,5 C33,7.21 31.21,9 29,9 C29,9 -29,9 -29,9 C-31.21,9 -33,7.21 -33,5 C-33,5 -33,-5 -33,-5 C-33,-7.21 -31.21,-9 -29,-9 C-29,-9 29,-9 29,-9 C31.21,-9 33,-7.21 33,-5c " />
+ </group>
+ <group
+ android:name="_R_G_L_4_G_L_0_G_L_8_G"
+ android:translateX="185.5"
+ android:translateY="521">
+ <path
+ android:name="_R_G_L_4_G_L_0_G_L_8_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M83.5 -4 C83.5,-4 83.5,4 83.5,4 C83.5,6.21 81.71,8 79.5,8 C79.5,8 -79.5,8 -79.5,8 C-81.71,8 -83.5,6.21 -83.5,4 C-83.5,4 -83.5,-4 -83.5,-4 C-83.5,-6.21 -81.71,-8 -79.5,-8 C-79.5,-8 79.5,-8 79.5,-8 C81.71,-8 83.5,-6.21 83.5,-4c " />
+ </group>
+ <group
+ android:name="_R_G_L_4_G_L_0_G_L_7_G"
+ android:translateX="54"
+ android:translateY="597">
+ <path
+ android:name="_R_G_L_4_G_L_0_G_L_7_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#9aa0a6"
+ android:fillType="nonZero"
+ android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
+ </group>
+ <group
+ android:name="_R_G_L_4_G_L_0_G_L_6_G"
+ android:translateX="168.5"
+ android:translateY="588">
+ <path
+ android:name="_R_G_L_4_G_L_0_G_L_6_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M66.5 -5 C66.5,-5 66.5,5 66.5,5 C66.5,7.21 64.71,9 62.5,9 C62.5,9 -62.5,9 -62.5,9 C-64.71,9 -66.5,7.21 -66.5,5 C-66.5,5 -66.5,-5 -66.5,-5 C-66.5,-7.21 -64.71,-9 -62.5,-9 C-62.5,-9 62.5,-9 62.5,-9 C64.71,-9 66.5,-7.21 66.5,-5c " />
+ </group>
+ <group
+ android:name="_R_G_L_4_G_L_0_G_L_5_G"
+ android:translateX="198.5"
+ android:translateY="609">
+ <path
+ android:name="_R_G_L_4_G_L_0_G_L_5_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M96.5 -4 C96.5,-4 96.5,4 96.5,4 C96.5,6.21 94.71,8 92.5,8 C92.5,8 -92.5,8 -92.5,8 C-94.71,8 -96.5,6.21 -96.5,4 C-96.5,4 -96.5,-4 -96.5,-4 C-96.5,-6.21 -94.71,-8 -92.5,-8 C-92.5,-8 92.5,-8 92.5,-8 C94.71,-8 96.5,-6.21 96.5,-4c " />
+ </group>
+ <group
+ android:name="_R_G_L_4_G_L_0_G_L_4_G"
+ android:translateX="54"
+ android:translateY="685">
+ <path
+ android:name="_R_G_L_4_G_L_0_G_L_4_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#9aa0a6"
+ android:fillType="nonZero"
+ android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
+ </group>
+ <group
+ android:name="_R_G_L_4_G_L_0_G_L_3_G"
+ android:translateX="162.5"
+ android:translateY="676">
+ <path
+ android:name="_R_G_L_4_G_L_0_G_L_3_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M60.5 -5 C60.5,-5 60.5,5 60.5,5 C60.5,7.21 58.71,9 56.5,9 C56.5,9 -56.5,9 -56.5,9 C-58.71,9 -60.5,7.21 -60.5,5 C-60.5,5 -60.5,-5 -60.5,-5 C-60.5,-7.21 -58.71,-9 -56.5,-9 C-56.5,-9 56.5,-9 56.5,-9 C58.71,-9 60.5,-7.21 60.5,-5c " />
+ </group>
+ <group
+ android:name="_R_G_L_4_G_L_0_G_L_2_G"
+ android:translateX="174"
+ android:translateY="697">
+ <path
+ android:name="_R_G_L_4_G_L_0_G_L_2_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M72 -4 C72,-4 72,4 72,4 C72,6.21 70.21,8 68,8 C68,8 -68,8 -68,8 C-70.21,8 -72,6.21 -72,4 C-72,4 -72,-4 -72,-4 C-72,-6.21 -70.21,-8 -68,-8 C-68,-8 68,-8 68,-8 C70.21,-8 72,-6.21 72,-4c " />
+ </group>
+ <group
+ android:name="_R_G_L_4_G_L_0_G_L_1_G"
+ android:translateX="313.5"
+ android:translateY="798">
+ <path
+ android:name="_R_G_L_4_G_L_0_G_L_1_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M74.5 0 C74.5,0 74.5,0 74.5,0 C74.5,15.45 61.95,28 46.5,28 C46.5,28 -46.5,28 -46.5,28 C-61.95,28 -74.5,15.45 -74.5,0 C-74.5,0 -74.5,0 -74.5,0 C-74.5,-15.45 -61.95,-28 -46.5,-28 C-46.5,-28 46.5,-28 46.5,-28 C61.95,-28 74.5,-15.45 74.5,0c " />
+ </group>
+ <group
+ android:name="_R_G_L_4_G_L_0_G_L_0_G"
+ android:translateX="205.5"
+ android:translateY="61">
+ <path
+ android:name="_R_G_L_4_G_L_0_G_L_0_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#f8f9fa"
+ android:fillType="nonZero"
+ android:pathData=" M171.5 -14 C171.5,-14 171.5,14 171.5,14 C171.5,16.21 169.71,18 167.5,18 C167.5,18 -167.5,18 -167.5,18 C-169.71,18 -171.5,16.21 -171.5,14 C-171.5,14 -171.5,-14 -171.5,-14 C-171.5,-16.21 -169.71,-18 -167.5,-18 C-167.5,-18 167.5,-18 167.5,-18 C169.71,-18 171.5,-16.21 171.5,-14c " />
+ </group>
+ </group>
+ </group>
+ </group>
+ <group
+ android:name="_R_G_L_3_G_N_2_T_0"
+ android:scaleX="0.6"
+ android:scaleY="0"
+ android:translateX="206"
+ android:translateY="395">
+ <group
+ android:name="_R_G_L_3_G"
+ android:translateX="-206"
+ android:translateY="-446">
+ <group
+ android:name="_R_G_L_3_G_L_0_G"
+ android:scaleY="0">
+ <group
+ android:name="_R_G_L_3_G_L_0_G_L_27_G"
+ android:scaleY="0"
+ android:translateX="206"
+ android:translateY="422.5">
+ <path
+ android:name="_R_G_L_3_G_L_0_G_L_27_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#dadce0"
+ android:fillType="nonZero"
+ android:pathData=" M206 -395.5 C206,-395.5 206,395.5 206,395.5 C206,395.5 -206,395.5 -206,395.5 C-206,395.5 -206,-395.5 -206,-395.5 C-206,-395.5 206,-395.5 206,-395.5c " />
+ </group>
+ <group
+ android:name="_R_G_L_3_G_L_0_G_L_26_G"
+ android:scaleY="0"
+ android:translateX="206"
+ android:translateY="496.5">
+ <path
+ android:name="_R_G_L_3_G_L_0_G_L_26_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#dadce0"
+ android:fillType="nonZero"
+ android:pathData=" M206 -377.5 C206,-377.5 206,377.5 206,377.5 C206,387.43 197.93,395.5 188,395.5 C188,395.5 -188,395.5 -188,395.5 C-197.93,395.5 -206,387.43 -206,377.5 C-206,377.5 -206,-377.5 -206,-377.5 C-206,-387.43 -197.93,-395.5 -188,-395.5 C-188,-395.5 188,-395.5 188,-395.5 C197.93,-395.5 206,-387.43 206,-377.5c " />
+ </group>
+ <group
+ android:name="_R_G_L_3_G_L_0_G_L_25_G"
+ android:scaleY="0"
+ android:translateX="206"
+ android:translateY="50.5">
+ <path
+ android:name="_R_G_L_3_G_L_0_G_L_25_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#e8eaed"
+ android:fillType="nonZero"
+ android:pathData=" M206 -23.5 C206,-23.5 206,50.5 206,50.5 C206,50.5 -206,50.5 -206,50.5 C-206,50.5 -206,-23.5 -206,-23.5 C-206,-23.5 206,-23.5 206,-23.5c " />
+ </group>
+ <group
+ android:name="_R_G_L_3_G_L_0_G_L_24_G"
+ android:scaleY="0"
+ android:translateX="206"
+ android:translateY="50.5">
+ <path
+ android:name="_R_G_L_3_G_L_0_G_L_24_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#e8eaed"
+ android:fillType="nonZero"
+ android:pathData=" M206 -32.5 C206,-32.5 206,32.5 206,32.5 C206,42.43 197.93,50.5 188,50.5 C188,50.5 -188,50.5 -188,50.5 C-197.93,50.5 -206,42.43 -206,32.5 C-206,32.5 -206,-32.5 -206,-32.5 C-206,-42.43 -197.93,-50.5 -188,-50.5 C-188,-50.5 188,-50.5 188,-50.5 C197.93,-50.5 206,-42.43 206,-32.5c " />
+ </group>
+ <group
+ android:name="_R_G_L_3_G_L_0_G_L_23_G"
+ android:scaleY="0"
+ android:translateX="54"
+ android:translateY="157">
+ <path
+ android:name="_R_G_L_3_G_L_0_G_L_23_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#9aa0a6"
+ android:fillType="nonZero"
+ android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
+ </group>
+ <group
+ android:name="_R_G_L_3_G_L_0_G_L_22_G"
+ android:scaleY="0"
+ android:translateX="54"
+ android:translateY="157">
+ <path
+ android:name="_R_G_L_3_G_L_0_G_L_22_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#9aa0a6"
+ android:fillType="nonZero"
+ android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
+ </group>
+ <group
+ android:name="_R_G_L_3_G_L_0_G_L_21_G"
+ android:scaleY="0"
+ android:translateX="148.5"
+ android:translateY="148">
+ <path
+ android:name="_R_G_L_3_G_L_0_G_L_21_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M46.5 -5 C46.5,-5 46.5,5 46.5,5 C46.5,7.21 44.71,9 42.5,9 C42.5,9 -42.5,9 -42.5,9 C-44.71,9 -46.5,7.21 -46.5,5 C-46.5,5 -46.5,-5 -46.5,-5 C-46.5,-7.21 -44.71,-9 -42.5,-9 C-42.5,-9 42.5,-9 42.5,-9 C44.71,-9 46.5,-7.21 46.5,-5c " />
+ </group>
+ <group
+ android:name="_R_G_L_3_G_L_0_G_L_20_G"
+ android:scaleY="0"
+ android:translateX="186"
+ android:translateY="169">
+ <path
+ android:name="_R_G_L_3_G_L_0_G_L_20_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M84 -4 C84,-4 84,4 84,4 C84,6.21 82.21,8 80,8 C80,8 -80,8 -80,8 C-82.21,8 -84,6.21 -84,4 C-84,4 -84,-4 -84,-4 C-84,-6.21 -82.21,-8 -80,-8 C-80,-8 80,-8 80,-8 C82.21,-8 84,-6.21 84,-4c " />
+ </group>
+ <group
+ android:name="_R_G_L_3_G_L_0_G_L_19_G"
+ android:scaleY="0"
+ android:translateX="54"
+ android:translateY="245">
+ <path
+ android:name="_R_G_L_3_G_L_0_G_L_19_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#9aa0a6"
+ android:fillType="nonZero"
+ android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
+ </group>
+ <group
+ android:name="_R_G_L_3_G_L_0_G_L_18_G"
+ android:scaleY="0"
+ android:translateX="162"
+ android:translateY="236">
+ <path
+ android:name="_R_G_L_3_G_L_0_G_L_18_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M60 -5 C60,-5 60,5 60,5 C60,7.21 58.21,9 56,9 C56,9 -56,9 -56,9 C-58.21,9 -60,7.21 -60,5 C-60,5 -60,-5 -60,-5 C-60,-7.21 -58.21,-9 -56,-9 C-56,-9 56,-9 56,-9 C58.21,-9 60,-7.21 60,-5c " />
+ </group>
+ <group
+ android:name="_R_G_L_3_G_L_0_G_L_17_G"
+ android:scaleY="0"
+ android:translateX="171.5"
+ android:translateY="257">
+ <path
+ android:name="_R_G_L_3_G_L_0_G_L_17_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M69.5 -4 C69.5,-4 69.5,4 69.5,4 C69.5,6.21 67.71,8 65.5,8 C65.5,8 -65.5,8 -65.5,8 C-67.71,8 -69.5,6.21 -69.5,4 C-69.5,4 -69.5,-4 -69.5,-4 C-69.5,-6.21 -67.71,-8 -65.5,-8 C-65.5,-8 65.5,-8 65.5,-8 C67.71,-8 69.5,-6.21 69.5,-4c " />
+ </group>
+ <group
+ android:name="_R_G_L_3_G_L_0_G_L_16_G"
+ android:scaleY="0"
+ android:translateX="54"
+ android:translateY="333">
+ <path
+ android:name="_R_G_L_3_G_L_0_G_L_16_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#9aa0a6"
+ android:fillType="nonZero"
+ android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
+ </group>
+ <group
+ android:name="_R_G_L_3_G_L_0_G_L_15_G"
+ android:scaleY="0"
+ android:translateX="158"
+ android:translateY="324">
+ <path
+ android:name="_R_G_L_3_G_L_0_G_L_15_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M56 -5 C56,-5 56,5 56,5 C56,7.21 54.21,9 52,9 C52,9 -52,9 -52,9 C-54.21,9 -56,7.21 -56,5 C-56,5 -56,-5 -56,-5 C-56,-7.21 -54.21,-9 -52,-9 C-52,-9 52,-9 52,-9 C54.21,-9 56,-7.21 56,-5c " />
+ </group>
+ <group
+ android:name="_R_G_L_3_G_L_0_G_L_14_G"
+ android:scaleY="0"
+ android:translateX="217.5"
+ android:translateY="345">
+ <path
+ android:name="_R_G_L_3_G_L_0_G_L_14_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M115.5 -4 C115.5,-4 115.5,4 115.5,4 C115.5,6.21 113.71,8 111.5,8 C111.5,8 -111.5,8 -111.5,8 C-113.71,8 -115.5,6.21 -115.5,4 C-115.5,4 -115.5,-4 -115.5,-4 C-115.5,-6.21 -113.71,-8 -111.5,-8 C-111.5,-8 111.5,-8 111.5,-8 C113.71,-8 115.5,-6.21 115.5,-4c " />
+ </group>
+ <group
+ android:name="_R_G_L_3_G_L_0_G_L_13_G"
+ android:scaleY="0"
+ android:translateX="54"
+ android:translateY="421">
+ <path
+ android:name="_R_G_L_3_G_L_0_G_L_13_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#9aa0a6"
+ android:fillType="nonZero"
+ android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
+ </group>
+ <group
+ android:name="_R_G_L_3_G_L_0_G_L_12_G"
+ android:scaleY="0"
+ android:translateX="170"
+ android:translateY="412">
+ <path
+ android:name="_R_G_L_3_G_L_0_G_L_12_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M68 -5 C68,-5 68,5 68,5 C68,7.21 66.21,9 64,9 C64,9 -64,9 -64,9 C-66.21,9 -68,7.21 -68,5 C-68,5 -68,-5 -68,-5 C-68,-7.21 -66.21,-9 -64,-9 C-64,-9 64,-9 64,-9 C66.21,-9 68,-7.21 68,-5c " />
+ </group>
+ <group
+ android:name="_R_G_L_3_G_L_0_G_L_11_G"
+ android:scaleY="0"
+ android:translateX="198.5"
+ android:translateY="433">
+ <path
+ android:name="_R_G_L_3_G_L_0_G_L_11_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M96.5 -4 C96.5,-4 96.5,4 96.5,4 C96.5,6.21 94.71,8 92.5,8 C92.5,8 -92.5,8 -92.5,8 C-94.71,8 -96.5,6.21 -96.5,4 C-96.5,4 -96.5,-4 -96.5,-4 C-96.5,-6.21 -94.71,-8 -92.5,-8 C-92.5,-8 92.5,-8 92.5,-8 C94.71,-8 96.5,-6.21 96.5,-4c " />
+ </group>
+ <group
+ android:name="_R_G_L_3_G_L_0_G_L_10_G"
+ android:scaleY="0"
+ android:translateX="54"
+ android:translateY="509">
+ <path
+ android:name="_R_G_L_3_G_L_0_G_L_10_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#9aa0a6"
+ android:fillType="nonZero"
+ android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
+ </group>
+ <group
+ android:name="_R_G_L_3_G_L_0_G_L_9_G"
+ android:scaleY="0"
+ android:translateX="135"
+ android:translateY="500">
+ <path
+ android:name="_R_G_L_3_G_L_0_G_L_9_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M33 -5 C33,-5 33,5 33,5 C33,7.21 31.21,9 29,9 C29,9 -29,9 -29,9 C-31.21,9 -33,7.21 -33,5 C-33,5 -33,-5 -33,-5 C-33,-7.21 -31.21,-9 -29,-9 C-29,-9 29,-9 29,-9 C31.21,-9 33,-7.21 33,-5c " />
+ </group>
+ <group
+ android:name="_R_G_L_3_G_L_0_G_L_8_G"
+ android:scaleY="0"
+ android:translateX="185.5"
+ android:translateY="521">
+ <path
+ android:name="_R_G_L_3_G_L_0_G_L_8_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M83.5 -4 C83.5,-4 83.5,4 83.5,4 C83.5,6.21 81.71,8 79.5,8 C79.5,8 -79.5,8 -79.5,8 C-81.71,8 -83.5,6.21 -83.5,4 C-83.5,4 -83.5,-4 -83.5,-4 C-83.5,-6.21 -81.71,-8 -79.5,-8 C-79.5,-8 79.5,-8 79.5,-8 C81.71,-8 83.5,-6.21 83.5,-4c " />
+ </group>
+ <group
+ android:name="_R_G_L_3_G_L_0_G_L_7_G"
+ android:scaleY="0"
+ android:translateX="54"
+ android:translateY="597">
+ <path
+ android:name="_R_G_L_3_G_L_0_G_L_7_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#9aa0a6"
+ android:fillType="nonZero"
+ android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
+ </group>
+ <group
+ android:name="_R_G_L_3_G_L_0_G_L_6_G"
+ android:scaleY="0"
+ android:translateX="168.5"
+ android:translateY="588">
+ <path
+ android:name="_R_G_L_3_G_L_0_G_L_6_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M66.5 -5 C66.5,-5 66.5,5 66.5,5 C66.5,7.21 64.71,9 62.5,9 C62.5,9 -62.5,9 -62.5,9 C-64.71,9 -66.5,7.21 -66.5,5 C-66.5,5 -66.5,-5 -66.5,-5 C-66.5,-7.21 -64.71,-9 -62.5,-9 C-62.5,-9 62.5,-9 62.5,-9 C64.71,-9 66.5,-7.21 66.5,-5c " />
+ </group>
+ <group
+ android:name="_R_G_L_3_G_L_0_G_L_5_G"
+ android:scaleY="0"
+ android:translateX="198.5"
+ android:translateY="609">
+ <path
+ android:name="_R_G_L_3_G_L_0_G_L_5_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M96.5 -4 C96.5,-4 96.5,4 96.5,4 C96.5,6.21 94.71,8 92.5,8 C92.5,8 -92.5,8 -92.5,8 C-94.71,8 -96.5,6.21 -96.5,4 C-96.5,4 -96.5,-4 -96.5,-4 C-96.5,-6.21 -94.71,-8 -92.5,-8 C-92.5,-8 92.5,-8 92.5,-8 C94.71,-8 96.5,-6.21 96.5,-4c " />
+ </group>
+ <group
+ android:name="_R_G_L_3_G_L_0_G_L_4_G"
+ android:scaleY="0"
+ android:translateX="54"
+ android:translateY="685">
+ <path
+ android:name="_R_G_L_3_G_L_0_G_L_4_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#9aa0a6"
+ android:fillType="nonZero"
+ android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
+ </group>
+ <group
+ android:name="_R_G_L_3_G_L_0_G_L_3_G"
+ android:scaleY="0"
+ android:translateX="162.5"
+ android:translateY="676">
+ <path
+ android:name="_R_G_L_3_G_L_0_G_L_3_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M60.5 -5 C60.5,-5 60.5,5 60.5,5 C60.5,7.21 58.71,9 56.5,9 C56.5,9 -56.5,9 -56.5,9 C-58.71,9 -60.5,7.21 -60.5,5 C-60.5,5 -60.5,-5 -60.5,-5 C-60.5,-7.21 -58.71,-9 -56.5,-9 C-56.5,-9 56.5,-9 56.5,-9 C58.71,-9 60.5,-7.21 60.5,-5c " />
+ </group>
+ <group
+ android:name="_R_G_L_3_G_L_0_G_L_2_G"
+ android:scaleY="0"
+ android:translateX="174"
+ android:translateY="697">
+ <path
+ android:name="_R_G_L_3_G_L_0_G_L_2_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M72 -4 C72,-4 72,4 72,4 C72,6.21 70.21,8 68,8 C68,8 -68,8 -68,8 C-70.21,8 -72,6.21 -72,4 C-72,4 -72,-4 -72,-4 C-72,-6.21 -70.21,-8 -68,-8 C-68,-8 68,-8 68,-8 C70.21,-8 72,-6.21 72,-4c " />
+ </group>
+ <group
+ android:name="_R_G_L_3_G_L_0_G_L_1_G"
+ android:scaleY="0"
+ android:translateX="313.5"
+ android:translateY="798">
+ <path
+ android:name="_R_G_L_3_G_L_0_G_L_1_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#bdc1c6"
+ android:fillType="nonZero"
+ android:pathData=" M74.5 0 C74.5,0 74.5,0 74.5,0 C74.5,15.45 61.95,28 46.5,28 C46.5,28 -46.5,28 -46.5,28 C-61.95,28 -74.5,15.45 -74.5,0 C-74.5,0 -74.5,0 -74.5,0 C-74.5,-15.45 -61.95,-28 -46.5,-28 C-46.5,-28 46.5,-28 46.5,-28 C61.95,-28 74.5,-15.45 74.5,0c " />
+ </group>
+ <group
+ android:name="_R_G_L_3_G_L_0_G_L_0_G"
+ android:scaleY="0"
+ android:translateX="205.5"
+ android:translateY="61">
+ <path
+ android:name="_R_G_L_3_G_L_0_G_L_0_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#f8f9fa"
+ android:fillType="nonZero"
+ android:pathData=" M171.5 -14 C171.5,-14 171.5,14 171.5,14 C171.5,16.21 169.71,18 167.5,18 C167.5,18 -167.5,18 -167.5,18 C-169.71,18 -171.5,16.21 -171.5,14 C-171.5,14 -171.5,-14 -171.5,-14 C-171.5,-16.21 -169.71,-18 -167.5,-18 C-167.5,-18 167.5,-18 167.5,-18 C169.71,-18 171.5,-16.21 171.5,-14c " />
+ </group>
+ </group>
+ </group>
+ </group>
+ <group
+ android:name="_R_G_L_2_G_N_2_T_0"
+ android:scaleX="0.6"
+ android:scaleY="0"
+ android:translateX="206"
+ android:translateY="395">
+ <group
+ android:name="_R_G_L_2_G"
+ android:scaleX="1.3767699999999998"
+ android:scaleY="1.3767699999999998"
+ android:translateY="-508.163">
+ <group
+ android:name="_R_G_L_2_G_D_0_P_0_G_0_T_0"
+ android:scaleX="0"
+ android:scaleY="0">
+ <path
+ android:name="_R_G_L_2_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#9aa0a6"
+ android:fillType="nonZero"
+ android:pathData=" M0 25 C13.81,25 25,13.81 25,0 C25,-13.81 13.81,-25 0,-25 C-13.81,-25 -25,-13.81 -25,0 C-25,13.81 -13.81,25 0,25c " />
+ </group>
+ </group>
+ </group>
+ <group
+ android:name="_R_G_L_1_G_N_2_T_0"
+ android:scaleX="0.6"
+ android:scaleY="0"
+ android:translateX="206"
+ android:translateY="395">
+ <group
+ android:name="_R_G_L_1_G"
+ android:scaleX="1.39"
+ android:scaleY="1.39"
+ android:translateX="-556.176"
+ android:translateY="-7.307">
+ <path
+ android:name="_R_G_L_1_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="@color/gesture_tutorial_fake_previous_task_view_color"
+ android:fillType="nonZero"
+ android:pathData=" M135 -301 C135,-301 135,311 135,311 C135,319.28 128.28,326 120,326 C120,326 -120,326 -120,326 C-128.28,326 -135,319.28 -135,311 C-135,311 -135,-301 -135,-301 C-135,-309.28 -128.28,-316 -120,-316 C-120,-316 120,-316 120,-316 C128.28,-316 135,-309.28 135,-301c " />
+ </group>
+ </group>
+ <group
+ android:name="_R_G_L_0_G"
+ android:translateX="206"
+ android:translateY="446">
+ <path
+ android:name="_R_G_L_0_G_D_0_P_0"
+ android:fillAlpha="0"
+ android:fillColor="#84ba69"
+ android:fillType="nonZero"
+ android:pathData=" M0 406 C21.54,406 39,423.46 39,445 C39,466.54 21.54,484 0,484 C-21.54,484 -39,466.54 -39,445 C-39,423.46 -21.54,406 0,406c " />
+ </group>
+ </group>
+ <group android:name="time_group" />
+ </vector>
+ </aapt:attr>
+</animated-vector> \ No newline at end of file
diff --git a/quickstep/res/drawable/gesture_tutorial_ripple.xml b/res/drawable/gesture_tutorial_ripple.xml
index 782af33ab3..782af33ab3 100644
--- a/quickstep/res/drawable/gesture_tutorial_ripple.xml
+++ b/res/drawable/gesture_tutorial_ripple.xml
diff --git a/res/drawable/gm_edit_24.xml b/res/drawable/gm_edit_24.xml
index f7413334f9..59a0dc2faf 100644
--- a/res/drawable/gm_edit_24.xml
+++ b/res/drawable/gm_edit_24.xml
@@ -5,6 +5,6 @@
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
- android:fillColor="?android:attr/textColorPrimaryInverse"
+ android:fillColor="@android:color/white"
android:pathData="M20.41,4.94l-1.35,-1.35c-0.78,-0.78 -2.05,-0.78 -2.83,0L3,16.82L3,21h4.18L20.41,7.77c0.79,-0.78 0.79,-2.05 0,-2.83zM6.41,19.06L5,19v-1.36l9.82,-9.82 1.41,1.41 -9.82,9.83z"/>
</vector>
diff --git a/res/drawable/ic_all_apps_button.xml b/res/drawable/ic_all_apps_button.xml
deleted file mode 100644
index 5770d3cf19..0000000000
--- a/res/drawable/ic_all_apps_button.xml
+++ /dev/null
@@ -1,44 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2022 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="80dp"
- android:height="80dp"
- android:viewportWidth="80"
- android:viewportHeight="80"
- android:theme="@style/AllAppsTheme">
- <path
- android:pathData="M40,0.5L40,0.5c21.8,0 39.5,17.7 39.5,39.5l0,0c0,21.8 -17.7,39.5 -39.5,39.5l0,0C18.2,79.5 0.5,61.8 0.5,40l0,0C0.5,18.2 18.2,0.5 40,0.5z"
- android:fillColor="?attr/allAppsButtonBgColor"/>
- <path
- android:pathData="M26.8,32.1m-5.3,0a5.3,5.3 0,1 1,10.6 0a5.3,5.3 0,1 1,-10.6 0"
- android:fillColor="?attr/allAppsButtonColor1"/>
- <path
- android:pathData="M26.8,47.9m-5.3,0a5.3,5.3 0,1 1,10.6 0a5.3,5.3 0,1 1,-10.6 0"
- android:fillColor="?attr/allAppsButtonColor2"/>
- <path
- android:pathData="M40,32.1m-5.3,0a5.3,5.3 0,1 1,10.6 0a5.3,5.3 0,1 1,-10.6 0"
- android:fillColor="?attr/allAppsButtonColor3"/>
- <path
- android:pathData="M40,47.9m-5.3,0a5.3,5.3 0,1 1,10.6 0a5.3,5.3 0,1 1,-10.6 0"
- android:fillColor="?attr/allAppsButtonColor2"/>
- <path
- android:pathData="M53.2,32.1m-5.3,0a5.3,5.3 0,1 1,10.6 0a5.3,5.3 0,1 1,-10.6 0"
- android:fillColor="?attr/allAppsButtonColor4"/>
- <path
- android:pathData="M53.2,47.9m-5.3,0a5.3,5.3 0,1 1,10.6 0a5.3,5.3 0,1 1,-10.6 0"
- android:fillColor="?attr/allAppsButtonColor2"/>
-</vector>
diff --git a/res/drawable/ic_split_horizontal.xml b/res/drawable/ic_split_horizontal.xml
deleted file mode 100644
index ee710d0797..0000000000
--- a/res/drawable/ic_split_horizontal.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="20dp"
- android:height="16dp"
- android:viewportWidth="20"
- android:viewportHeight="16">
- <path
- android:pathData="M18,14L13,14L13,2L18,2L18,14ZM20,14L20,2C20,0.9 19.1,-0 18,-0L13,-0C11.9,-0 11,0.9 11,2L11,14C11,15.1 11.9,16 13,16L18,16C19.1,16 20,15.1 20,14ZM7,14L2,14L2,2L7,2L7,14ZM9,14L9,2C9,0.9 8.1,-0 7,-0L2,-0C0.9,-0 -0,0.9 -0,2L-0,14C-0,15.1 0.9,16 2,16L7,16C8.1,16 9,15.1 9,14Z"
- android:fillColor="#000000"/>
-</vector>
diff --git a/res/drawable/ic_split_left.xml b/res/drawable/ic_split_left.xml
deleted file mode 100644
index fc9f699c29..0000000000
--- a/res/drawable/ic_split_left.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="20dp"
- android:height="16dp"
- android:viewportWidth="20"
- android:viewportHeight="16">
- <path
- android:pathData="M-0,2L-0,14C-0,15.1 0.9,16 2,16L7,16C8.1,16 9,15.1 9,14L9,2C9,0.9 8.1,-0 7,-0L2,-0C0.9,-0 -0,0.9 -0,2ZM13,2L18,2L18,14L13,14L13,2ZM11,2L11,14C11,15.1 11.9,16 13,16L18,16C19.1,16 20,15.1 20,14L20,2C20,0.9 19.1,-0 18,-0L13,-0C11.9,-0 11,0.9 11,2Z"
- android:fillColor="#000000"/>
-</vector>
diff --git a/res/drawable/ic_split_right.xml b/res/drawable/ic_split_right.xml
deleted file mode 100644
index cc156225e8..0000000000
--- a/res/drawable/ic_split_right.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="20dp"
- android:height="16dp"
- android:viewportWidth="20"
- android:viewportHeight="16">
- <path
- android:pathData="M20,14L20,2C20,0.9 19.1,-0 18,-0L13,-0C11.9,-0 11,0.9 11,2L11,14C11,15.1 11.9,16 13,16L18,16C19.1,16 20,15.1 20,14ZM7,14L2,14L2,2L7,2L7,14ZM9,14L9,2C9,0.9 8.1,-0 7,-0L2,-0C0.9,-0 -0,0.9 -0,2L-0,14C-0,15.1 0.9,16 2,16L7,16C8.1,16 9,15.1 9,14Z"
- android:fillColor="#000000"/>
-</vector>
diff --git a/res/drawable/ic_split_top.xml b/res/drawable/ic_split_top.xml
deleted file mode 100644
index f8c15bd44d..0000000000
--- a/res/drawable/ic_split_top.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="16dp"
- android:height="20dp"
- android:viewportWidth="16"
- android:viewportHeight="20">
- <path
- android:pathData="M14,0H2C0.9,0 0,0.9 0,2V7C0,8.1 0.9,9 2,9H14C15.1,9 16,8.1 16,7V2C16,0.9 15.1,0 14,0ZM14,13V18H2V13H14ZM14,11H2C0.9,11 0,11.9 0,13V18C0,19.1 0.9,20 2,20H14C15.1,20 16,19.1 16,18V13C16,11.9 15.1,11 14,11Z"
- android:fillColor="#000000"/>
-</vector>
diff --git a/res/drawable/ic_split_vertical.xml b/res/drawable/ic_split_vertical.xml
deleted file mode 100644
index 9bc97851ab..0000000000
--- a/res/drawable/ic_split_vertical.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="24dp"
- android:height="24dp"
- android:viewportWidth="24"
- android:viewportHeight="24">
- <path
- android:pathData="M18,4V9H6V4H18ZM18,2H6C4.9,2 4,2.9 4,4V9C4,10.1 4.9,11 6,11H18C19.1,11 20,10.1 20,9V4C20,2.9 19.1,2 18,2ZM18,15V20H6V15H18ZM18,13H6C4.9,13 4,13.9 4,15V20C4,21.1 4.9,22 6,22H18C19.1,22 20,21.1 20,20V15C20,13.9 19.1,13 18,13Z"
- android:fillColor="#000000"/>
-</vector>
diff --git a/res/drawable/padded_rounded_action_button.xml b/res/drawable/padded_rounded_action_button.xml
index 6863f92f0c..6432efd539 100644
--- a/res/drawable/padded_rounded_action_button.xml
+++ b/res/drawable/padded_rounded_action_button.xml
@@ -14,11 +14,18 @@
~ limitations under the License.
-->
-<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
<item
- android:drawable="@drawable/rounded_action_button"
android:left="@dimen/padded_rounded_button_padding"
android:top="@dimen/padded_rounded_button_padding"
android:right="@dimen/padded_rounded_button_padding"
- android:bottom="@dimen/padded_rounded_button_padding" />
+ android:bottom="@dimen/padded_rounded_button_padding">
+ <shape android:shape="rectangle">
+ <corners android:radius="@dimen/rounded_button_radius" />
+ <stroke android:width="1dp"
+ android:color="?androidprv:attr/colorAccentPrimaryVariant" />
+ </shape>
+ </item>
</layer-list>
+
diff --git a/res/color-night-v31/folder_preview_dark.xml b/res/drawable/personal_work_tabs_ripple.xml
index bdd48a24bd..2e57b80570 100644
--- a/res/color-night-v31/folder_preview_dark.xml
+++ b/res/drawable/personal_work_tabs_ripple.xml
@@ -13,8 +13,10 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<selector xmlns:android="http://schemas.android.com/apk/res/android" >
- <item
- android:color="@android:color/system_neutral2_500"
- android:lStar="30" />
-</selector>
+<ripple xmlns:android="http://schemas.android.com/apk/res/android"
+ android:color="?android:attr/colorControlHighlight">
+ <shape android:shape="rectangle">
+ <solid android:color="@android:color/transparent" />
+ <corners android:radius="@dimen/all_apps_header_pill_corner_radius" />
+ </shape>
+</ripple> \ No newline at end of file
diff --git a/res/drawable/round_rect_folder.xml b/res/drawable/round_rect_folder.xml
index 6c5864e2e9..8b3d06ca9b 100644
--- a/res/drawable/round_rect_folder.xml
+++ b/res/drawable/round_rect_folder.xml
@@ -16,6 +16,6 @@
-->
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
- <solid android:color="?attr/folderBackgroundColor" />
+ <solid android:color="?attr/folderFillColor" />
<corners android:radius="@dimen/bg_round_rect_radius" />
</shape>
diff --git a/res/drawable/rounded_action_button.xml b/res/drawable/rounded_action_button.xml
index 81e94f7e2b..f04389399f 100644
--- a/res/drawable/rounded_action_button.xml
+++ b/res/drawable/rounded_action_button.xml
@@ -18,11 +18,8 @@
<shape xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
android:shape="rectangle">
- <solid android:color="?androidprv:attr/colorSurfaceVariant" />
<corners android:radius="@dimen/rounded_button_radius" />
- <stroke
- android:width="1dp"
- android:color="?androidprv:attr/colorSurfaceVariant" />
+ <stroke android:width="1dp" android:color="@color/all_apps_tab_background_selected" />
<padding
android:left="@dimen/rounded_button_padding"
android:right="@dimen/rounded_button_padding" />
diff --git a/res/drawable/bg_rounded_corner_bottom_sheet_handle.xml b/res/drawable/widgets_bottom_sheet_background.xml
index c5021787c5..b877546656 100644
--- a/res/drawable/bg_rounded_corner_bottom_sheet_handle.xml
+++ b/res/drawable/widgets_bottom_sheet_background.xml
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2022 The Android Open Source Project
+<!--
+ Copyright (C) 2021 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.
@@ -13,10 +14,13 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-
<shape xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
- android:shape="rectangle" >
- <solid android:color="?androidprv:attr/colorSurfaceVariant"/>
- <corners android:radius="@dimen/bottom_sheet_handle_corner_radius" />
-</shape>
+ android:shape="rectangle">
+ <solid android:color="@color/surface" />
+ <corners
+ android:topLeftRadius="@dimen/default_dialog_corner_radius"
+ android:topRightRadius="@dimen/default_dialog_corner_radius"
+ android:bottomLeftRadius="0dp"
+ android:bottomRightRadius="0dp"
+ />
+</shape> \ No newline at end of file
diff --git a/res/interpolator/back_cancel.xml b/res/interpolator/back_cancel.xml
deleted file mode 100644
index 2165457c72..0000000000
--- a/res/interpolator/back_cancel.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 2022, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
- android:controlX1="0.2"
- android:controlY1="0"
- android:controlX2="0"
- android:controlY2="1"/> \ No newline at end of file
diff --git a/res/interpolator/fast_out_extra_slow_in.xml b/res/interpolator/fast_out_extra_slow_in.xml
deleted file mode 100644
index f296a8224f..0000000000
--- a/res/interpolator/fast_out_extra_slow_in.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2022 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License
- -->
-
-<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
- android:pathData="M 0,0 C 0.05, 0, 0.133333, 0.06, 0.166666, 0.4 C 0.208333, 0.82, 0.25, 1, 1, 1"/> \ No newline at end of file
diff --git a/res/interpolator/standard_accelerate.xml b/res/interpolator/standard_accelerate.xml
deleted file mode 100644
index 394393dc36..0000000000
--- a/res/interpolator/standard_accelerate.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2022 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-
-<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
- android:controlX1="0.3"
- android:controlY1="0"
- android:controlX2="1"
- android:controlY2="1"/> \ No newline at end of file
diff --git a/res/interpolator/standard_decelerate.xml b/res/interpolator/standard_decelerate.xml
deleted file mode 100644
index 579f4f5644..0000000000
--- a/res/interpolator/standard_decelerate.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2022 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-
-<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
- android:controlX1="0"
- android:controlY1="0"
- android:controlX2="0"
- android:controlY2="1"/> \ No newline at end of file
diff --git a/res/layout-v31/settings_activity.xml b/res/layout-v31/settings_activity.xml
deleted file mode 100644
index 59e14f22dd..0000000000
--- a/res/layout-v31/settings_activity.xml
+++ /dev/null
@@ -1,69 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2021 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.
--->
-<androidx.coordinatorlayout.widget.CoordinatorLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:app="http://schemas.android.com/apk/res-auto"
- android:id="@+id/content_parent"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:fitsSystemWindows="true">
-
- <com.google.android.material.appbar.AppBarLayout
- android:id="@+id/app_bar"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:background="?android:attr/colorPrimary"
- android:fitsSystemWindows="true"
- android:outlineAmbientShadowColor="@android:color/transparent"
- android:outlineSpotShadowColor="@android:color/transparent"
- android:theme="@style/HomeSettings.CollapsingToolbar">
-
- <com.google.android.material.appbar.CollapsingToolbarLayout
- android:id="@+id/collapsing_toolbar"
- android:layout_width="match_parent"
- android:layout_height="226dp"
- android:clipToPadding="false"
- app:collapsedTitleTextAppearance="@style/HomeSettings.CollapsedToolbarTitle"
- app:contentScrim="@color/home_settings_header_collapsed"
- app:expandedTitleMarginEnd="24dp"
- app:expandedTitleMarginStart="24dp"
- app:expandedTitleTextAppearance="@style/HomeSettings.ExpandedToolbarTitle"
- app:layout_scrollFlags="scroll|exitUntilCollapsed|snap"
- app:maxLines="3"
- app:scrimAnimationDuration="50"
- app:scrimVisibleHeightTrigger="174dp"
- app:statusBarScrim="@null"
- app:titleCollapseMode="fade"
- app:toolbarId="@id/action_bar">
-
- <Toolbar
- android:id="@+id/action_bar"
- android:layout_width="match_parent"
- android:layout_height="?attr/actionBarSize"
- android:theme="?android:attr/actionBarTheme"
- android:transitionName="shared_element_view"
- app:layout_collapseMode="pin" />
-
- </com.google.android.material.appbar.CollapsingToolbarLayout>
- </com.google.android.material.appbar.AppBarLayout>
-
- <FrameLayout
- android:id="@+id/content_frame"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- app:layout_behavior="@string/appbar_scrolling_view_behavior" />
-</androidx.coordinatorlayout.widget.CoordinatorLayout> \ No newline at end of file
diff --git a/res/layout/add_item_confirmation_activity.xml b/res/layout/add_item_confirmation_activity.xml
index e29e1b1fef..0e066908d0 100644
--- a/res/layout/add_item_confirmation_activity.xml
+++ b/res/layout/add_item_confirmation_activity.xml
@@ -37,7 +37,7 @@
android:id="@+id/add_item_bottom_sheet_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:paddingVertical="24dp"
+ android:padding="24dp"
android:background="@drawable/add_item_dialog_background"
android:orientation="vertical" >
@@ -46,7 +46,6 @@
android:id="@+id/widget_appName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_marginHorizontal="@dimen/widget_list_horizontal_margin"
android:gravity="center_horizontal"
android:textColor="?android:attr/textColorPrimary"
android:textSize="24sp"
@@ -56,10 +55,8 @@
android:maxLines="1" />
<TextView
- android:id="@+id/widget_drag_instruction"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_marginHorizontal="@dimen/widget_list_horizontal_margin"
android:gravity="center_horizontal"
android:paddingTop="8dp"
android:text="@string/add_item_request_drag_hint"
@@ -67,37 +64,25 @@
android:textColor="?android:attr/textColorSecondary"
android:alpha="0.7"/>
- <ScrollView
- android:id="@+id/widget_preview_scroll_view"
+ <include layout="@layout/widget_cell"
+ android:id="@+id/widget_cell"
android:layout_width="match_parent"
android:layout_height="0dp"
- android:layout_marginVertical="16dp"
- android:layout_weight="1">
-
- <include
- android:id="@+id/widget_cell"
- layout="@layout/widget_cell"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginHorizontal="@dimen/widget_list_horizontal_margin" />
- </ScrollView>
+ android:layout_weight="1"
+ android:layout_marginVertical="16dp" />
<LinearLayout
- android:id="@+id/actions_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_marginHorizontal="@dimen/widget_list_horizontal_margin"
android:gravity="center_vertical|end"
android:paddingVertical="8dp"
android:orientation="horizontal">
<Button
style="@style/Button.FullRounded.Colored"
android:layout_width="wrap_content"
- android:layout_height="wrap_content"
+ android:layout_height="36dp"
android:paddingHorizontal="16dp"
android:textSize="14sp"
- android:maxLines="2"
- android:ellipsize="end"
android:textColor="@color/button_text"
android:text="@android:string/cancel"
android:onClick="onCancelClick"/>
@@ -109,11 +94,9 @@
<Button
style="@style/Button.FullRounded.Colored"
android:layout_width="wrap_content"
- android:layout_height="wrap_content"
+ android:layout_height="36dp"
android:paddingHorizontal="16dp"
android:textSize="14sp"
- android:maxLines="2"
- android:ellipsize="end"
android:textColor="@color/button_text"
android:text="@string/add_to_home_screen"
android:onClick="onPlaceAutomaticallyClick"/>
diff --git a/res/layout/all_apps.xml b/res/layout/all_apps.xml
index d0d82d48bd..9ac6ed0f77 100644
--- a/res/layout/all_apps.xml
+++ b/res/layout/all_apps.xml
@@ -26,14 +26,6 @@
android:saveEnabled="false">
<include
- layout="@layout/all_apps_bottom_sheet_background"
- android:visibility="gone" />
-
- <include
- layout="@layout/search_results_rv_layout"
- android:visibility="gone" />
-
- <include
layout="@layout/all_apps_rv_layout"
android:visibility="gone" />
@@ -41,6 +33,7 @@
android:id="@+id/all_apps_header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
+ android:layout_below="@id/search_container_all_apps"
android:clipToPadding="false"
android:paddingTop="@dimen/all_apps_header_top_padding"
android:paddingBottom="@dimen/all_apps_header_bottom_padding"
@@ -49,10 +42,10 @@
<include layout="@layout/floating_header_content" />
<include layout="@layout/all_apps_personal_work_tabs" />
-
</com.android.launcher3.allapps.FloatingHeaderView>
- <include layout="@layout/search_container_all_apps" />
+ <include
+ layout="@layout/search_container_all_apps"/>
<include layout="@layout/all_apps_fast_scroller" />
</com.android.launcher3.allapps.LauncherAllAppsContainerView> \ No newline at end of file
diff --git a/res/layout/all_apps_bottom_sheet_background.xml b/res/layout/all_apps_bottom_sheet_background.xml
deleted file mode 100644
index 12b6b7bb55..0000000000
--- a/res/layout/all_apps_bottom_sheet_background.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2022 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/bottom_sheet_background"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:background="@drawable/bg_rounded_corner_bottom_sheet">
-
- <View
- android:id="@+id/bottom_sheet_handle_area"
- android:layout_width="match_parent"
- android:layout_height="36dp" />
-
- <View
- android:id="@+id/bottom_sheet_handle"
- android:layout_width="@dimen/bottom_sheet_handle_width"
- android:layout_height="@dimen/bottom_sheet_handle_height"
- android:layout_gravity="center_horizontal"
- android:layout_marginTop="@dimen/bottom_sheet_handle_margin"
- android:layout_marginBottom="@dimen/bottom_sheet_handle_margin"
- android:background="@drawable/bg_rounded_corner_bottom_sheet_handle" />
-</FrameLayout>
diff --git a/res/layout/search_results_rv_layout.xml b/res/layout/all_apps_content_layout.xml
index 567cb5f4fc..5698977e3e 100644
--- a/res/layout/search_results_rv_layout.xml
+++ b/res/layout/all_apps_content_layout.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
- ~ Copyright (C) 2022 The Android Open Source Project
+ ~ Copyright (C) 2020 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.
@@ -14,11 +14,14 @@
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
-<com.android.launcher3.allapps.SearchRecyclerView
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/search_results_list_view"
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/apps_list_view_override"
android:layout_width="match_parent"
- android:layout_height="wrap_content"
+ android:layout_height="match_parent"
+ android:layout_below="@id/search_container_all_apps"
android:clipToPadding="false"
android:descendantFocusability="afterDescendants"
- android:focusable="true" />
+ android:focusable="true"
+ android:layout_marginTop="@dimen/all_apps_header_top_padding"
+ android:orientation="vertical">
+</LinearLayout>
diff --git a/res/layout/all_apps_fast_scroller.xml b/res/layout/all_apps_fast_scroller.xml
index 0f1d9330a6..5537bc60a5 100644
--- a/res/layout/all_apps_fast_scroller.xml
+++ b/res/layout/all_apps_fast_scroller.xml
@@ -21,8 +21,7 @@
android:id="@+id/fast_scroller_popup"
style="@style/FastScrollerPopup"
android:layout_alignParentEnd="true"
- android:layout_alignTop="@+id/all_apps_header"
- android:layout_marginTop="@dimen/all_apps_header_bottom_padding"
+ android:layout_below="@+id/search_container_all_apps"
android:layout_marginEnd="@dimen/fastscroll_popup_margin" />
<com.android.launcher3.views.RecyclerViewFastScroller
@@ -31,8 +30,7 @@
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentEnd="true"
- android:layout_alignTop="@+id/all_apps_header"
- android:layout_marginTop="@dimen/all_apps_header_bottom_padding"
+ android:layout_below="@+id/search_container_all_apps"
android:layout_marginEnd="@dimen/fastscroll_end_margin"
launcher:canThumbDetach="true" />
diff --git a/res/layout/all_apps_icon_twoline.xml b/res/layout/all_apps_icon_twoline.xml
deleted file mode 100644
index 54c714734c..0000000000
--- a/res/layout/all_apps_icon_twoline.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2021 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.
--->
-<com.android.launcher3.BubbleTextView xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:launcher="http://schemas.android.com/apk/res-auto"
- style="@style/BaseIcon.AllApps"
- android:id="@+id/icon"
- android:singleLine="false"
- android:lines="2"
- android:inputType="textMultiLine"
- launcher:iconDisplay="all_apps"
- launcher:centerVertically="true" />
-
diff --git a/res/layout/all_apps_rv_layout.xml b/res/layout/all_apps_rv_layout.xml
index 26d8ecc4c6..c353b361cf 100644
--- a/res/layout/all_apps_rv_layout.xml
+++ b/res/layout/all_apps_rv_layout.xml
@@ -19,6 +19,7 @@
android:id="@+id/apps_list_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
+ android:layout_below="@id/search_container_all_apps"
android:clipToPadding="false"
android:descendantFocusability="afterDescendants"
android:focusable="true" />
diff --git a/res/layout/all_apps_tabs.xml b/res/layout/all_apps_tabs.xml
index 6dcae21911..de4a69d6cc 100644
--- a/res/layout/all_apps_tabs.xml
+++ b/res/layout/all_apps_tabs.xml
@@ -20,12 +20,13 @@
android:id="@+id/all_apps_tabs_view_pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
+ android:layout_below="@id/search_container_all_apps"
android:layout_gravity="center_horizontal|top"
android:layout_marginTop="@dimen/all_apps_header_pill_height"
android:clipChildren="true"
android:clipToPadding="false"
android:descendantFocusability="afterDescendants"
- android:paddingTop="@dimen/all_apps_paged_view_top_padding"
+ android:paddingTop="@dimen/all_apps_header_top_padding"
launcher:pageIndicator="@+id/tabs" >
<include layout="@layout/all_apps_rv_layout" />
diff --git a/res/layout/arrow_toast.xml b/res/layout/arrow_toast.xml
index 88a92eb565..9a6f8c35bd 100644
--- a/res/layout/arrow_toast.xml
+++ b/res/layout/arrow_toast.xml
@@ -27,13 +27,15 @@
android:gravity="center"
android:padding="16dp"
android:background="@drawable/arrow_toast_rounded_background"
- android:elevation="@dimen/arrow_toast_elevation"
+ android:elevation="2dp"
+ android:outlineProvider="none"
android:textColor="@color/arrow_tip_view_content"
android:textSize="14sp"/>
<View
android:id="@+id/arrow"
- android:elevation="@dimen/arrow_toast_elevation"
+ android:elevation="2dp"
+ android:outlineProvider="none"
android:layout_width="@dimen/arrow_toast_arrow_width"
android:layout_height="10dp"/>
</merge>
diff --git a/res/layout/floating_split_select_view.xml b/res/layout/floating_split_select_view.xml
deleted file mode 100644
index e4ca52e371..0000000000
--- a/res/layout/floating_split_select_view.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<com.android.quickstep.views.FloatingTaskView
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent">
-
- <com.android.quickstep.views.FloatingTaskThumbnailView
- android:id="@+id/thumbnail"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:visibility="gone" />
-
- <com.android.quickstep.views.SplitPlaceholderView
- android:id="@+id/split_placeholder"
- android:layout_width="match_parent"
- android:layout_height="@dimen/split_placeholder_size"
- android:visibility="gone" />
-
-</com.android.quickstep.views.FloatingTaskView> \ No newline at end of file
diff --git a/res/layout/keyboard_drag_and_drop.xml b/res/layout/keyboard_drag_and_drop.xml
index bc3a9c145a..e9463c40a0 100644
--- a/res/layout/keyboard_drag_and_drop.xml
+++ b/res/layout/keyboard_drag_and_drop.xml
@@ -26,7 +26,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
- android:background="?attr/folderBackgroundColor"
+ android:background="?attr/folderFillColor"
android:padding="8dp"
android:textColor="?attr/folderTextColor"
/>
diff --git a/res/layout/launcher_preview_two_panel_layout.xml b/res/layout/launcher_preview_two_panel_layout.xml
deleted file mode 100644
index f76fc5a337..0000000000
--- a/res/layout/launcher_preview_two_panel_layout.xml
+++ /dev/null
@@ -1,57 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2018 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.
--->
-<view class="com.android.launcher3.graphics.LauncherPreviewRenderer$LauncherPreviewLayout"
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:launcher="http://schemas.android.com/apk/res-auto"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:focusable="false">
-
- <androidx.constraintlayout.widget.ConstraintLayout
- android:layout_width="match_parent"
- android:layout_height="match_parent">
-
- <com.android.launcher3.CellLayout
- android:id="@+id/workspace"
- android:layout_width="0dp"
- android:layout_height="0dp"
- android:theme="@style/HomeScreenElementTheme"
- launcher:containerType="workspace"
- launcher:layout_constraintStart_toStartOf="parent"
- launcher:layout_constraintTop_toTopOf="parent"
- launcher:layout_constraintEnd_toStartOf="@id/workspace_right"
- launcher:layout_constraintBottom_toBottomOf="parent"
- launcher:pageIndicator="@+id/page_indicator" />
-
- <com.android.launcher3.CellLayout
- android:id="@+id/workspace_right"
- android:layout_width="0dp"
- android:layout_height="0dp"
- android:theme="@style/HomeScreenElementTheme"
- launcher:containerType="workspace"
- launcher:layout_constraintStart_toEndOf="@id/workspace"
- launcher:layout_constraintTop_toTopOf="parent"
- launcher:layout_constraintEnd_toEndOf="parent"
- launcher:layout_constraintBottom_toBottomOf="parent"
- launcher:pageIndicator="@+id/page_indicator" />
-
- </androidx.constraintlayout.widget.ConstraintLayout>
-
- <include
- android:id="@+id/hotseat"
- layout="@layout/hotseat" />
-
-</view> \ No newline at end of file
diff --git a/res/layout/notification_content.xml b/res/layout/notification_content.xml
index 91897e9e75..84822a671b 100644
--- a/res/layout/notification_content.xml
+++ b/res/layout/notification_content.xml
@@ -14,11 +14,10 @@
limitations under the License.
-->
-<com.android.launcher3.notification.NotificationMainView
+<merge
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="vertical">
+ android:layout_height="wrap_content">
<!-- header -->
<FrameLayout
@@ -50,7 +49,7 @@
</FrameLayout>
<!-- Main view -->
- <FrameLayout
+ <com.android.launcher3.notification.NotificationMainView
android:id="@+id/main_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@@ -60,6 +59,7 @@
android:id="@+id/text_and_background"
android:layout_width="match_parent"
android:layout_height="match_parent"
+ android:background="?attr/popupColorPrimary"
android:gravity="center_vertical"
android:orientation="vertical"
android:paddingTop="@dimen/notification_padding"
@@ -95,5 +95,5 @@
android:layout_marginTop="@dimen/notification_padding"
android:layout_marginStart="@dimen/notification_icon_padding" />
- </FrameLayout>
-</com.android.launcher3.notification.NotificationMainView> \ No newline at end of file
+ </com.android.launcher3.notification.NotificationMainView>
+</merge> \ No newline at end of file
diff --git a/res/layout/popup_container.xml b/res/layout/popup_container.xml
index 9327287018..18014bb1d0 100644
--- a/res/layout/popup_container.xml
+++ b/res/layout/popup_container.xml
@@ -31,9 +31,12 @@
android:elevation="@dimen/deep_shortcuts_elevation"
android:orientation="vertical"/>
- <com.android.launcher3.notification.NotificationContainer
+ <LinearLayout
android:id="@+id/notification_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:visibility="gone"/>
+ android:visibility="gone"
+ android:background="?attr/popupColorPrimary"
+ android:elevation="@dimen/deep_shortcuts_elevation"
+ android:orientation="vertical"/>
</com.android.launcher3.popup.PopupContainerWithArrow> \ No newline at end of file
diff --git a/res/layout/qsb_preview.xml b/res/layout/qsb_preview.xml
deleted file mode 100644
index 801fb04789..0000000000
--- a/res/layout/qsb_preview.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2021 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.
--->
-<com.android.launcher3.qsb.QsbContainerView
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical"
- android:layout_width="match_parent"
- android:layout_height="0dp"
- android:id="@id/search_container_workspace"
- android:padding="0dp" >
-
- <fragment
- android:name="com.android.launcher3.qsb.QsbContainerView$QsbFragment"
- android:layout_width="match_parent"
- android:tag="qsb_view"
- android:layout_height="match_parent"/>
-</com.android.launcher3.qsb.QsbContainerView> \ No newline at end of file
diff --git a/res/layout/secondary_launcher.xml b/res/layout/secondary_launcher.xml
index 635db141dd..b15a320bba 100644
--- a/res/layout/secondary_launcher.xml
+++ b/res/layout/secondary_launcher.xml
@@ -41,8 +41,7 @@
android:contentDescription="@string/all_apps_button_label"
android:onClick="onAppsButtonClicked" />
- <view
- class="com.android.launcher3.allapps.SecondaryLauncherAllAppsContainerView"
+ <com.android.launcher3.allapps.AllAppsContainerView
android:id="@+id/apps_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
@@ -56,14 +55,6 @@
android:visibility="invisible" >
<include
- layout="@layout/all_apps_bottom_sheet_background"
- android:visibility="gone" />
-
- <include
- layout="@layout/search_results_rv_layout"
- android:visibility="gone" />
-
- <include
layout="@layout/all_apps_rv_layout"
android:visibility="gone" />
@@ -130,5 +121,5 @@
android:textSize="16sp" />
<include layout="@layout/all_apps_fast_scroller" />
- </view>
+ </com.android.launcher3.allapps.AllAppsContainerView>
</com.android.launcher3.secondarydisplay.SecondaryDragLayer> \ No newline at end of file
diff --git a/res/layout/system_shortcut.xml b/res/layout/system_shortcut.xml
index 21d532eb91..de091c51c7 100644
--- a/res/layout/system_shortcut.xml
+++ b/res/layout/system_shortcut.xml
@@ -16,13 +16,36 @@
<com.android.launcher3.shortcuts.DeepShortcutView
xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:launcher="http://schemas.android.com/apk/res-auto"
android:layout_width="@dimen/bg_popup_item_width"
- android:layout_height="wrap_content"
- android:minHeight="@dimen/bg_popup_item_height"
+ android:layout_height="@dimen/bg_popup_item_height"
android:elevation="@dimen/deep_shortcuts_elevation"
android:background="@drawable/middle_item_primary"
android:theme="@style/PopupItem" >
- <include layout="@layout/system_shortcut_content" />
+ <com.android.launcher3.BubbleTextView
+ style="@style/BaseIconUnBounded"
+ android:id="@+id/bubble_text"
+ android:background="?android:attr/selectableItemBackground"
+ android:gravity="start|center_vertical"
+ android:textAlignment="viewStart"
+ android:paddingStart="@dimen/deep_shortcuts_text_padding_start"
+ android:paddingEnd="@dimen/popup_padding_end"
+ android:textSize="14sp"
+ android:minLines="1"
+ android:maxLines="2"
+ android:ellipsize="end"
+ android:textColor="?android:attr/textColorPrimary"
+ launcher:iconDisplay="shortcut_popup"
+ launcher:layoutHorizontal="true"
+ android:focusable="false" />
+
+ <View
+ android:id="@+id/icon"
+ android:layout_width="@dimen/system_shortcut_icon_size"
+ android:layout_height="@dimen/system_shortcut_icon_size"
+ android:layout_marginStart="@dimen/system_shortcut_margin_start"
+ android:layout_gravity="start|center_vertical"
+ android:backgroundTint="?android:attr/textColorPrimary"/>
</com.android.launcher3.shortcuts.DeepShortcutView>
diff --git a/res/layout/system_shortcut_content.xml b/res/layout/system_shortcut_content.xml
deleted file mode 100644
index ddcef096e0..0000000000
--- a/res/layout/system_shortcut_content.xml
+++ /dev/null
@@ -1,48 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2021 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.
--->
-<merge
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:launcher="http://schemas.android.com/apk/res-auto" >
-
- <com.android.launcher3.BubbleTextView
- style="@style/BaseIconUnBounded"
- android:id="@+id/bubble_text"
- android:background="?android:attr/selectableItemBackground"
- android:gravity="start|center_vertical"
- android:paddingTop="@dimen/bg_popup_item_vertical_padding"
- android:paddingBottom="@dimen/bg_popup_item_vertical_padding"
- android:minHeight="@dimen/bg_popup_item_height"
- android:textAlignment="viewStart"
- android:paddingStart="@dimen/deep_shortcuts_text_padding_start"
- android:paddingEnd="@dimen/popup_padding_end"
- android:textSize="14sp"
- android:minLines="1"
- android:maxLines="2"
- android:ellipsize="end"
- android:hyphenationFrequency="full"
- android:textColor="@color/system_shortcut_text"
- launcher:iconDisplay="shortcut_popup"
- launcher:layoutHorizontal="true"
- android:focusable="false" />
-
- <View
- android:id="@+id/icon"
- android:layout_width="@dimen/system_shortcut_icon_size"
- android:layout_height="@dimen/system_shortcut_icon_size"
- android:layout_marginStart="@dimen/system_shortcut_margin_start"
- android:layout_gravity="start|center_vertical"
- android:backgroundTint="@color/system_shortcut_text"/>
-</merge>
diff --git a/res/layout/widget_cell_content.xml b/res/layout/widget_cell_content.xml
index feebfe10d8..b27b50560e 100644
--- a/res/layout/widget_cell_content.xml
+++ b/res/layout/widget_cell_content.xml
@@ -22,7 +22,7 @@
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1"
- android:importantForAccessibility="noHideDescendants"
+ android:importantForAccessibility="no"
android:layout_marginVertical="8dp">
<!-- The image of the widget. This view does not support padding. Any placement adjustment
should be done using margins. Width & height are set at runtime after scaling the
@@ -33,14 +33,6 @@
android:layout_height="match_parent"
android:importantForAccessibility="no"
android:layout_gravity="fill"/>
-
- <ImageView
- android:id="@+id/widget_badge"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:importantForAccessibility="no"
- android:layout_gravity="end|bottom"
- android:layout_margin="@dimen/profile_badge_margin"/>
</com.android.launcher3.widget.WidgetCellPreview>
<!-- The name of the widget. -->
diff --git a/res/layout/widgets_bottom_sheet_content.xml b/res/layout/widgets_bottom_sheet_content.xml
index a5f72ef30a..3b3ff8b426 100644
--- a/res/layout/widgets_bottom_sheet_content.xml
+++ b/res/layout/widgets_bottom_sheet_content.xml
@@ -18,17 +18,17 @@
android:id="@+id/widgets_bottom_sheet"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:background="@drawable/bg_rounded_corner_bottom_sheet"
- android:paddingTop="@dimen/bottom_sheet_handle_margin"
+ android:background="@drawable/widgets_bottom_sheet_background"
+ android:paddingTop="16dp"
android:orientation="vertical">
<View
android:id="@+id/collapse_handle"
- android:layout_width="@dimen/bottom_sheet_handle_width"
- android:layout_height="@dimen/bottom_sheet_handle_height"
+ android:layout_width="48dp"
+ android:layout_height="2dp"
android:layout_gravity="center_horizontal"
- android:layout_marginBottom="@dimen/bottom_sheet_handle_margin"
+ android:layout_marginBottom="16dp"
android:visibility="gone"
- android:background="@drawable/bg_rounded_corner_bottom_sheet_handle"/>
+ android:background="?android:attr/textColorSecondary"/>
<TextView
style="@style/TextHeadline"
android:id="@+id/title"
@@ -47,7 +47,6 @@
<include layout="@layout/widgets_table_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_marginHorizontal="@dimen/widget_list_horizontal_margin"
android:layout_gravity="center_horizontal" />
</ScrollView>
</LinearLayout>
diff --git a/res/layout/widgets_full_sheet.xml b/res/layout/widgets_full_sheet.xml
index e3f1fca91b..1b4f3b984e 100644
--- a/res/layout/widgets_full_sheet.xml
+++ b/res/layout/widgets_full_sheet.xml
@@ -19,33 +19,22 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
- android:theme="?attr/widgetsTheme">
+ android:theme="?attr/widgetsTheme" >
- <com.android.launcher3.views.SpringRelativeLayout
+ <com.android.launcher3.views.TopRoundedCornerView
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:background="@drawable/bg_widgets_full_sheet"
- android:focusable="true"
- android:importantForAccessibility="no">
-
- <View
- android:id="@+id/collapse_handle"
- android:layout_width="@dimen/bottom_sheet_handle_width"
- android:layout_height="@dimen/bottom_sheet_handle_height"
- android:layout_marginTop="@dimen/bottom_sheet_handle_margin"
- android:layout_centerHorizontal="true"
- android:background="@drawable/bg_rounded_corner_bottom_sheet_handle"/>
+ android:background="?android:attr/colorBackground">
<TextView
- style="@style/PrimaryHeadline"
android:id="@+id/no_widgets_text"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:visibility="gone"
- android:textSize="18sp"
- android:layout_below="@id/search_and_recommendations_container"
+ android:fontFamily="sans-serif-medium"
+ android:textSize="20sp"
tools:text="No widgets available" />
<!-- Fast scroller popup -->
@@ -68,10 +57,8 @@
android:id="@+id/search_widgets_list_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_below="@id/collapse_handle"
- android:paddingHorizontal="@dimen/widget_list_horizontal_margin"
android:visibility="gone"
android:clipToPadding="false" />
- </com.android.launcher3.views.SpringRelativeLayout>
+ </com.android.launcher3.views.TopRoundedCornerView>
</com.android.launcher3.widget.picker.WidgetsFullSheet> \ No newline at end of file
diff --git a/res/layout/widgets_full_sheet_paged_view.xml b/res/layout/widgets_full_sheet_paged_view.xml
index dfe226a8bd..f0ddc2bb66 100644
--- a/res/layout/widgets_full_sheet_paged_view.xml
+++ b/res/layout/widgets_full_sheet_paged_view.xml
@@ -21,7 +21,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
- android:layout_below="@id/collapse_handle"
+ android:paddingTop="@dimen/widget_picker_view_pager_top_padding"
android:descendantFocusability="afterDescendants"
launcher:pageIndicator="@+id/tabs">
@@ -29,96 +29,15 @@
android:id="@+id/primary_widgets_list_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:paddingHorizontal="@dimen/widget_list_horizontal_margin"
android:clipToPadding="false" />
<com.android.launcher3.widget.picker.WidgetsRecyclerView
android:id="@+id/work_widgets_list_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:paddingHorizontal="@dimen/widget_list_horizontal_margin"
android:clipToPadding="false" />
</com.android.launcher3.workprofile.PersonalWorkPagedView>
- <!-- SearchAndRecommendationsView contains the tab layout as well -->
- <com.android.launcher3.widget.picker.SearchAndRecommendationsView
- android:id="@+id/search_and_recommendations_container"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginHorizontal="@dimen/widget_list_horizontal_margin"
- android:layout_below="@id/collapse_handle"
- android:paddingBottom="0dp"
- android:orientation="vertical">
-
- <TextView
- android:id="@+id/title"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:gravity="center_horizontal"
- android:textSize="24sp"
- android:layout_marginTop="24dp"
- android:textColor="?android:attr/textColorSecondary"
- android:text="@string/widget_button_text"/>
-
- <FrameLayout
- android:id="@+id/search_bar_container"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:elevation="0.1dp"
- android:background="?android:attr/colorBackground"
- android:paddingBottom="8dp"
- android:clipToPadding="false">
- <include layout="@layout/widgets_search_bar" />
- </FrameLayout>
-
- <com.android.launcher3.widget.picker.WidgetsRecommendationTableLayout
- android:id="@+id/recommended_widget_table"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginTop="8dp"
- android:background="@drawable/widgets_recommendation_background"
- android:paddingVertical="@dimen/recommended_widgets_table_vertical_padding"
- android:visibility="gone" />
-
- <com.android.launcher3.workprofile.PersonalWorkSlidingTabStrip
- android:id="@+id/tabs"
- android:layout_width="match_parent"
- android:layout_height="64dp"
- android:gravity="center_horizontal"
- android:orientation="horizontal"
- android:paddingVertical="8dp"
- android:paddingLeft="@dimen/widget_tabs_horizontal_padding"
- android:paddingRight="@dimen/widget_tabs_horizontal_padding"
- android:background="?android:attr/colorBackground"
- style="@style/TextHeadline">
-
- <Button
- android:id="@+id/tab_personal"
- android:layout_width="0dp"
- android:layout_height="match_parent"
- android:layout_marginEnd="@dimen/widget_tabs_button_horizontal_padding"
- android:layout_marginVertical="@dimen/widget_apps_tabs_vertical_padding"
- android:layout_weight="1"
- android:background="@drawable/all_apps_tabs_background"
- android:text="@string/widgets_full_sheet_personal_tab"
- android:textColor="@color/all_apps_tab_text"
- android:textSize="14sp"
- style="?android:attr/borderlessButtonStyle" />
-
- <Button
- android:id="@+id/tab_work"
- android:layout_width="0dp"
- android:layout_height="match_parent"
- android:layout_marginEnd="@dimen/widget_tabs_button_horizontal_padding"
- android:layout_marginVertical="@dimen/widget_apps_tabs_vertical_padding"
- android:layout_weight="1"
- android:background="@drawable/all_apps_tabs_background"
- android:text="@string/widgets_full_sheet_work_tab"
- android:textColor="@color/all_apps_tab_text"
- android:textSize="14sp"
- style="?android:attr/borderlessButtonStyle" />
- </com.android.launcher3.workprofile.PersonalWorkSlidingTabStrip>
-
- </com.android.launcher3.widget.picker.SearchAndRecommendationsView>
+ <include layout="@layout/widgets_personal_work_tabs"/>
</merge> \ No newline at end of file
diff --git a/res/layout/widgets_full_sheet_recyclerview.xml b/res/layout/widgets_full_sheet_recyclerview.xml
index 6a5d6cb416..fbe559c663 100644
--- a/res/layout/widgets_full_sheet_recyclerview.xml
+++ b/res/layout/widgets_full_sheet_recyclerview.xml
@@ -13,54 +13,9 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<merge xmlns:android="http://schemas.android.com/apk/res/android">
- <com.android.launcher3.widget.picker.WidgetsRecyclerView
- android:id="@+id/primary_widgets_list_view"
- android:layout_below="@id/collapse_handle"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:paddingHorizontal="@dimen/widget_list_horizontal_margin"
- android:clipToPadding="false" />
-
- <!-- SearchAndRecommendationsView without the tab layout as well -->
- <com.android.launcher3.widget.picker.SearchAndRecommendationsView
- android:id="@+id/search_and_recommendations_container"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginHorizontal="@dimen/widget_list_horizontal_margin"
- android:layout_below="@id/collapse_handle"
- android:paddingBottom="16dp"
- android:orientation="vertical">
-
- <TextView
- android:id="@+id/title"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:gravity="center_horizontal"
- android:textSize="24sp"
- android:layout_marginTop="24dp"
- android:textColor="?android:attr/textColorSecondary"
- android:text="@string/widget_button_text"/>
-
- <FrameLayout
- android:id="@+id/search_bar_container"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:elevation="0.1dp"
- android:background="?android:attr/colorBackground"
- android:paddingBottom="8dp"
- android:clipToPadding="false">
- <include layout="@layout/widgets_search_bar" />
- </FrameLayout>
-
- <com.android.launcher3.widget.picker.WidgetsRecommendationTableLayout
- android:id="@+id/recommended_widget_table"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginTop="8dp"
- android:background="@drawable/widgets_recommendation_background"
- android:paddingVertical="@dimen/recommended_widgets_table_vertical_padding"
- android:visibility="gone" />
- </com.android.launcher3.widget.picker.SearchAndRecommendationsView>
-
-</merge> \ No newline at end of file
+<com.android.launcher3.widget.picker.WidgetsRecyclerView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/primary_widgets_list_view"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:clipToPadding="false" /> \ No newline at end of file
diff --git a/res/layout/widgets_full_sheet_search_and_recommendations.xml b/res/layout/widgets_full_sheet_search_and_recommendations.xml
new file mode 100644
index 0000000000..4a3e20d8ba
--- /dev/null
+++ b/res/layout/widgets_full_sheet_search_and_recommendations.xml
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2021 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.
+-->
+<com.android.launcher3.widget.picker.SearchAndRecommendationsView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/search_and_recommendations_container"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="16dp"
+ android:orientation="vertical">
+
+ <View
+ android:id="@+id/collapse_handle"
+ android:layout_width="match_parent"
+ android:layout_height="18dp"
+ android:elevation="0.1dp"
+ android:background="@drawable/bg_widgets_picker_handle"/>
+
+ <TextView
+ android:id="@+id/title"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:gravity="center_horizontal"
+ android:textSize="24sp"
+ android:layout_marginTop="24dp"
+ android:textColor="?android:attr/textColorSecondary"
+ android:text="@string/widget_button_text"/>
+
+ <FrameLayout
+ android:id="@+id/search_bar_container"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:elevation="0.1dp"
+ android:background="?android:attr/colorBackground"
+ android:paddingBottom="8dp"
+ android:clipToPadding="false">
+ <include layout="@layout/widgets_search_bar" />
+ </FrameLayout>
+
+ <com.android.launcher3.widget.picker.WidgetsRecommendationTableLayout
+ android:id="@+id/recommended_widget_table"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginHorizontal="@dimen/widget_list_horizontal_margin"
+ android:layout_marginTop="8dp"
+ android:background="@drawable/widgets_recommendation_background"
+ android:paddingVertical="@dimen/recommended_widgets_table_vertical_padding"
+ android:visibility="gone" />
+</com.android.launcher3.widget.picker.SearchAndRecommendationsView>
diff --git a/res/layout/widgets_list_row_header.xml b/res/layout/widgets_list_row_header.xml
index 3cdc2e844b..7f84050a47 100644
--- a/res/layout/widgets_list_row_header.xml
+++ b/res/layout/widgets_list_row_header.xml
@@ -19,12 +19,10 @@
android:id="@+id/widgets_list_header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
+ android:layout_marginHorizontal="@dimen/widget_list_horizontal_margin"
android:paddingVertical="@dimen/widget_list_header_view_vertical_padding"
android:orientation="horizontal"
- android:importantForAccessibility="yes"
- android:focusable="true"
- launcher:appIconSize="48dp"
- android:descendantFocusability="afterDescendants">
+ launcher:appIconSize="48dp">
<ImageView
android:id="@+id/app_icon"
@@ -35,11 +33,14 @@
tools:src="@drawable/ic_corp"/>
<LinearLayout
+ android:id="@+id/app_container"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_weight="1"
- android:orientation="vertical">
+ android:orientation="vertical"
+ android:focusable="true"
+ android:descendantFocusability="afterDescendants">
<TextView
android:id="@+id/app_title"
diff --git a/res/layout/widgets_personal_work_tabs.xml b/res/layout/widgets_personal_work_tabs.xml
new file mode 100644
index 0000000000..532c42233e
--- /dev/null
+++ b/res/layout/widgets_personal_work_tabs.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2021 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.
+-->
+
+<com.android.launcher3.workprofile.PersonalWorkSlidingTabStrip
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/tabs"
+ android:layout_width="match_parent"
+ android:layout_height="@dimen/all_apps_header_pill_height"
+ android:gravity="center_horizontal"
+ android:orientation="horizontal"
+ android:layout_marginHorizontal="@dimen/widget_tabs_horizontal_margin"
+ style="@style/TextHeadline">
+
+ <Button
+ android:id="@+id/tab_personal"
+ android:layout_width="0dp"
+ android:layout_height="match_parent"
+ android:layout_marginEnd="@dimen/widget_tabs_button_horizontal_padding"
+ android:layout_marginVertical="@dimen/widget_apps_tabs_vertical_padding"
+ android:layout_weight="1"
+ android:background="@drawable/all_apps_tabs_background"
+ android:text="@string/widgets_full_sheet_personal_tab"
+ android:textColor="@color/all_apps_tab_text"
+ android:textSize="14sp"
+ style="?android:attr/borderlessButtonStyle" />
+
+ <Button
+ android:id="@+id/tab_work"
+ android:layout_width="0dp"
+ android:layout_height="match_parent"
+ android:layout_marginEnd="@dimen/widget_tabs_button_horizontal_padding"
+ android:layout_marginVertical="@dimen/widget_apps_tabs_vertical_padding"
+ android:layout_weight="1"
+ android:background="@drawable/all_apps_tabs_background"
+ android:text="@string/widgets_full_sheet_work_tab"
+ android:textColor="@color/all_apps_tab_text"
+ android:textSize="14sp"
+ style="?android:attr/borderlessButtonStyle" />
+</com.android.launcher3.workprofile.PersonalWorkSlidingTabStrip> \ No newline at end of file
diff --git a/res/layout/widgets_search_bar.xml b/res/layout/widgets_search_bar.xml
index 9178a75076..cb27f4fb6f 100644
--- a/res/layout/widgets_search_bar.xml
+++ b/res/layout/widgets_search_bar.xml
@@ -6,6 +6,7 @@
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginTop="24dp"
+ android:layout_marginHorizontal="@dimen/widget_list_horizontal_margin"
android:background="@drawable/bg_widgets_searchbox">
<com.android.launcher3.ExtendedEditText
diff --git a/res/layout/widgets_table_container.xml b/res/layout/widgets_table_container.xml
index ab96b13431..ab470d8fa5 100644
--- a/res/layout/widgets_table_container.xml
+++ b/res/layout/widgets_table_container.xml
@@ -17,4 +17,5 @@
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/widgets_table"
android:layout_width="match_parent"
- android:layout_height="wrap_content" />
+ android:layout_height="wrap_content"
+ android:layout_marginHorizontal="@dimen/widget_list_horizontal_margin" />
diff --git a/res/layout/work_apps_edu.xml b/res/layout/work_apps_edu.xml
index eeb7f4f073..1517087fe2 100644
--- a/res/layout/work_apps_edu.xml
+++ b/res/layout/work_apps_edu.xml
@@ -16,52 +16,40 @@
<com.android.launcher3.allapps.WorkEduCard xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:paddingTop="@dimen/work_edu_card_margin"
- android:paddingBottom="@dimen/work_edu_card_bottom_margin"
+ android:layout_marginTop="8dp"
android:gravity="center">
- <RelativeLayout
+
+ <LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:orientation="horizontal"
+ android:orientation="vertical"
+ android:paddingHorizontal="@dimen/work_card_padding_horizontal"
+ android:paddingVertical="@dimen/work_card_padding_horizontal"
android:background="@drawable/work_card"
android:layout_gravity="center_horizontal"
- android:paddingEnd="@dimen/work_card_margin"
- android:paddingStart="@dimen/work_card_margin"
- android:paddingTop="@dimen/work_card_margin"
+ android:gravity="center"
android:id="@+id/wrapper">
+
<TextView
style="@style/PrimaryHeadline"
android:textColor="?android:attr/textColorPrimary"
android:id="@+id/work_apps_paused_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_marginBottom="@dimen/work_card_margin"
- android:layout_marginEnd="@dimen/work_card_margin"
+ android:layout_marginBottom="@dimen/work_card_padding_horizontal"
android:text="@string/work_profile_edu_work_apps"
- android:textDirection="locale"
- android:textSize="18sp" />
- <RelativeLayout
- android:layout_width="match_parent"
- android:layout_height="@dimen/padded_rounded_button_height"
- android:orientation="horizontal">
- <FrameLayout
- android:layout_width="@dimen/rounded_button_width"
- android:layout_height="@dimen/rounded_button_width"
- android:layout_alignParentEnd="true"
- android:background="@drawable/rounded_action_button"
- android:padding="@dimen/rounded_button_padding">
- <ImageButton
- android:id="@+id/action_btn"
- android:layout_width="@dimen/x_icon_size"
- android:layout_height="@dimen/x_icon_size"
- android:layout_gravity="center"
- android:padding="@dimen/x_icon_padding"
- android:contentDescription="@string/accessibility_close"
- android:src="@drawable/ic_remove_no_shadow" />
- </FrameLayout>
- </RelativeLayout>
- </RelativeLayout>
-
+ android:textAlignment="center"
+ android:textSize="20sp" />
+ <Button
+ android:layout_width="match_parent"
+ android:layout_height="@dimen/work_card_button_height"
+ android:id="@+id/action_btn"
+ android:textColor="?attr/workProfileOverlayTextColor"
+ android:text="@string/work_profile_edu_accept"
+ android:textAlignment="center"
+ android:background="@drawable/rounded_action_button"
+ android:textSize="14sp" />
+ </LinearLayout>
</com.android.launcher3.allapps.WorkEduCard> \ No newline at end of file
diff --git a/res/layout/work_apps_paused.xml b/res/layout/work_apps_paused.xml
index 79bce70287..ec34b47364 100644
--- a/res/layout/work_apps_paused.xml
+++ b/res/layout/work_apps_paused.xml
@@ -28,7 +28,7 @@
android:layout_marginTop="40dp"
android:text="@string/work_apps_paused_title"
android:textAlignment="center"
- android:textSize="18sp" />
+ android:textSize="22sp" />
<TextView
android:layout_width="wrap_content"
diff --git a/res/layout/work_mode_fab.xml b/res/layout/work_mode_fab.xml
index d2fa5fa066..04faa15271 100644
--- a/res/layout/work_mode_fab.xml
+++ b/res/layout/work_mode_fab.xml
@@ -21,14 +21,12 @@
android:layout_width="wrap_content"
android:gravity="center"
android:includeFontPadding="false"
- android:textDirection="locale"
android:drawableTint="@color/all_apps_tab_text"
android:textColor="@color/all_apps_tab_text"
android:textSize="14sp"
android:background="@drawable/work_apps_toggle_background"
android:drawablePadding="8dp"
android:drawableStart="@drawable/ic_corp_off"
- android:layout_marginBottom="@dimen/work_fab_margin_bottom"
- android:paddingLeft="@dimen/work_mode_fab_padding"
- android:paddingRight="@dimen/work_mode_fab_padding"
+ android:layout_marginBottom="@dimen/work_fab_margin"
+ android:layout_marginEnd="@dimen/work_fab_margin"
android:text="@string/work_apps_pause_btn_text" /> \ No newline at end of file
diff --git a/res/raw/all_set_page_bg.json b/res/raw/all_set_page_bg.json
deleted file mode 100644
index 9705837912..0000000000
--- a/res/raw/all_set_page_bg.json
+++ /dev/null
@@ -1 +0,0 @@
-{"v":"5.7.8","fr":24,"ip":0,"op":72,"w":2472,"h":5352,"nm":"3Second_MAIN_Welcome","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":3,"nm":"Null 60","sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1508,1364,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"ip":0,"op":240,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"PinkFlower","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"t":72,"s":[56]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.07,"y":0.986},"o":{"x":0.167,"y":0.167},"t":0,"s":[1505.832,1379.455,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.773,"y":0.01},"t":38,"s":[1505.832,575,0],"to":[0,0,0],"ti":[0,0,0]},{"t":72,"s":[1505.832,1379.455,0]}],"ix":2,"l":2},"a":{"a":0,"k":[-3514.717,-358.642,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[75.615,-96.908],[89.338,-70.276],[111.99,-50.668],[111.764,-20.709],[122.709,7.18],[108.586,33.602],[105.316,63.383],[80.533,80.216],[63.797,105.066],[34.03,108.453],[7.663,122.679],[-20.269,111.845],[-50.226,112.189],[-69.924,89.614],[-96.61,75.997],[-103.56,46.854],[-120.861,22.395],[-113.472,-6.639],[-117.425,-36.337],[-97.389,-58.612],[-87.087,-86.745],[-58.996,-97.158],[-36.8,-117.281],[-7.086,-113.445],[21.918,-120.948],[46.446,-103.744]],"o":[[-75.615,96.909],[-89.338,70.276],[-111.99,50.668],[-111.764,20.709],[-122.709,-7.18],[-108.586,-33.602],[-105.316,-63.383],[-80.533,-80.216],[-63.797,-105.066],[-34.03,-108.453],[-7.663,-122.679],[20.269,-111.845],[50.226,-112.188],[69.924,-89.614],[96.61,-75.997],[103.56,-46.854],[120.861,-22.395],[113.472,6.64],[117.425,36.337],[97.389,58.612],[87.088,86.745],[58.995,97.158],[36.8,117.281],[7.087,113.445],[-21.918,120.948],[-46.446,103.744]],"v":[[733.209,572.105],[531.711,675.932],[383.354,847.313],[156.685,845.606],[-54.323,928.412],[-254.235,821.562],[-479.555,796.823],[-606.913,609.309],[-794.927,482.691],[-820.554,257.47],[-928.191,57.981],[-846.217,-153.353],[-848.817,-380.013],[-678.021,-529.044],[-574.99,-730.949],[-354.499,-783.537],[-169.439,-914.435],[50.234,-858.532],[274.928,-888.434],[443.46,-736.847],[656.313,-658.903],[735.094,-446.359],[887.344,-278.426],[858.327,-53.616],[915.095,165.835],[784.928,351.409]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.839215686275,0.439215686275,0.388235294118,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.839215746113,0.439215716194,0.388235324037,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":true},{"ty":"tr","p":{"a":0,"k":[-3509.952,-363.731],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Polystar 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":288,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Ellipse_Bottom","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.07],"y":[1.248]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[-56]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.719],"y":[0.172]},"t":38,"s":[-38]},{"t":72,"s":[-56]}],"ix":10},"p":{"s":true,"x":{"a":1,"k":[{"i":{"x":[0.07],"y":[1.032]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[1720]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.719],"y":[0.022]},"t":38,"s":[1544]},{"t":72,"s":[1720]}],"ix":3},"y":{"a":1,"k":[{"i":{"x":[0.07],"y":[1.034]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[4069]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.719],"y":[0.024]},"t":38,"s":[3872]},{"t":72,"s":[4069]}],"ix":4}},"a":{"a":0,"k":[164.438,1433.781,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[3079.125,4685.989],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.305882352941,0.309803921569,0.321568627451,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.882353001015,0.894118006089,0.886274988511,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":true},{"ty":"tr","p":{"a":0,"k":[164.438,1481.781],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":240,"st":0,"bm":0}],"markers":[]}
diff --git a/res/raw/downgrade_schema.json b/res/raw/downgrade_schema.json
index b8d0c6ff49..bc25cece2d 100644
--- a/res/raw/downgrade_schema.json
+++ b/res/raw/downgrade_schema.json
@@ -2,10 +2,8 @@
// Note: Comments are not supported in JSON schema, but android parser is lenient.
// Maximum DB version supported by this schema
- "version" : 31,
+ "version" : 29,
- "downgrade_to_30" : [],
- "downgrade_to_29" : [],
"downgrade_to_28" : [
"ALTER TABLE favorites RENAME TO temp_favorites;",
"CREATE TABLE favorites(_id INTEGER PRIMARY KEY, title TEXT, intent TEXT, container INTEGER, screen INTEGER, cellX INTEGER, cellY INTEGER, spanX INTEGER, spanY INTEGER, itemType INTEGER, appWidgetId INTEGER NOT NULL DEFAULT - 1, iconPackage TEXT, iconResource TEXT, icon BLOB, appWidgetProvider TEXT, modified INTEGER NOT NULL DEFAULT 0, restored INTEGER NOT NULL DEFAULT 0, profileId INTEGER DEFAULT 0, rank INTEGER NOT NULL DEFAULT 0, options INTEGER NOT NULL DEFAULT 0);",
diff --git a/res/values-af/strings.xml b/res/values-af/strings.xml
index 18fa12fa16..ca59afa558 100644
--- a/res/values-af/strings.xml
+++ b/res/values-af/strings.xml
@@ -20,63 +20,39 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="649227358658669779">"Launcher3"</string>
+ <string name="folder_name" msgid="7371454440695724752"></string>
<string name="work_folder_name" msgid="3753320833950115786">"Werk"</string>
<string name="activity_not_found" msgid="8071924732094499514">"Program is nie geïnstalleer nie."</string>
<string name="activity_not_available" msgid="7456344436509528827">"Program is nie beskikbaar nie"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"Afgelaaide program in veiligmodus gedeaktiveer"</string>
<string name="safemode_widget_error" msgid="4863470563535682004">"Legstukke gedeaktiveer in Veiligmodus"</string>
<string name="shortcut_not_available" msgid="2536503539825726397">"Kortpad is nie beskikbaar nie"</string>
- <string name="home_screen" msgid="5629429142036709174">"Tuis"</string>
- <string name="recent_task_option_split_screen" msgid="6690461455618725183">"Verdeelde skerm"</string>
- <string name="split_screen_position_top" msgid="1504965011158689649">"Verdeel bo"</string>
- <string name="split_screen_position_left" msgid="7537793098851830883">"Verdeel links"</string>
- <string name="split_screen_position_right" msgid="1569377524925193369">"Verdeel regs"</string>
- <string name="split_app_info_accessibility" msgid="5475288491241414932">"Programinligting vir %1$s"</string>
- <string name="long_press_widget_to_add" msgid="3587712543577675817">"Raak en hou om \'n legstuk te skuif."</string>
- <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Dubbeltik en hou om \'n legstuk te skuif of gebruik gepasmaakte handelinge."</string>
+ <string name="home_screen" msgid="806512411299847073">"Tuisskerm"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"Gepasmaakte handelinge"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"Raak en hou om \'n legstuk op te tel."</string>
+ <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Dubbeltik en hou om \'n legstuk op te tel of gebruik gepasmaakte handelinge."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d breed by %2$d hoog"</string>
- <string name="widget_preview_context_description" msgid="9045841361655787574">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g>-legstuk"</string>
- <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Raak en hou die legstuk om dit op die Tuisskerm rond te beweeg"</string>
- <string name="add_to_home_screen" msgid="8631549138215492708">"Voeg by Tuisskerm"</string>
- <string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g>-legstuk by tuisskerm gevoeg"</string>
- <string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# legstuk}other{# legstukke}}"</string>
- <string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{# kortpad}other{# kortpaaie}}"</string>
- <string name="widgets_and_shortcuts_count" msgid="7209136747878365116">"<xliff:g id="WIDGETS_COUNT">%1$s</xliff:g>, <xliff:g id="SHORTCUTS_COUNT">%2$s</xliff:g>"</string>
- <string name="widget_button_text" msgid="2880537293434387943">"Legstukke"</string>
- <string name="widgets_full_sheet_search_bar_hint" msgid="8484659090860596457">"Soek"</string>
- <string name="widgets_full_sheet_cancel_button_description" msgid="5766167035728653605">"Vee teks in hierdie soekkasie uit"</string>
- <string name="no_widgets_available" msgid="4337693382501046170">"Legstukke en kortpaaie is nie beskikbaar nie"</string>
- <string name="no_search_results" msgid="3787956167293097509">"Geen legstukke of kortpaaie gekry nie"</string>
- <string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Persoonlik"</string>
- <string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Werk"</string>
- <string name="widget_category_conversations" msgid="8894438636213590446">"Gesprekke"</string>
- <string name="widget_education_header" msgid="4874760613775913787">"Nuttige inligting binne jou bereik"</string>
- <string name="widget_education_content" msgid="745542879510751525">"Jy kan legstukke by jou tuisskerm voeg om inligting te kry sonder om programme oop te maak"</string>
- <string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Tik om legstukinstellings te verander"</string>
- <string name="widget_education_close_button" msgid="8676165703104836580">"Het dit"</string>
- <string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Verander legstukinstellings"</string>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Raak en hou om self te plaas"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"Voeg outomaties by"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Deursoek programme"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Laai tans programme …"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"Kon geen programme kry wat by \"<xliff:g id="QUERY">%1$s</xliff:g>\" pas nie"</string>
<string name="all_apps_search_market_message" msgid="1366263386197059176">"Soek meer programme"</string>
<string name="label_application" msgid="8531721983832654978">"Program"</string>
- <string name="all_apps_label" msgid="5015784846527570951">"Alle programme"</string>
<string name="notifications_header" msgid="1404149926117359025">"Kennisgewings"</string>
- <string name="long_press_shortcut_to_add" msgid="5405328730817637737">"Raak en hou om \'n kortpad te skuif."</string>
- <string name="long_accessible_way_to_add_shortcut" msgid="2199537273817090740">"Dubbeltik en hou om \'n kortpad te skuif of gebruik gepasmaakte handelinge."</string>
- <string name="out_of_space" msgid="6692471482459245734">"Geen plek op hierdie tuisskerm nie"</string>
+ <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"Raak en hou om \'n kortpad op te tel."</string>
+ <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"Dubbeltik en hou om \'n kortpad op te tel of gebruik gepasmaakte handelinge."</string>
+ <string name="out_of_space" msgid="4691004494942118364">"Niks meer spasie op die tuisskerm nie."</string>
<string name="hotseat_out_of_space" msgid="7448809638125333693">"Geen plek meer in die Gunstelinge-laai nie"</string>
<string name="all_apps_button_label" msgid="8130441508702294465">"Programmelys"</string>
- <string name="all_apps_search_results" msgid="5889367432531296759">"Soekresultate"</string>
<string name="all_apps_button_personal_label" msgid="1315764287305224468">"Lys persoonlike programme"</string>
<string name="all_apps_button_work_label" msgid="7270707118948892488">"Lys werkprogramme"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"Tuis"</string>
<string name="remove_drop_target_label" msgid="7812859488053230776">"Verwyder"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"Deïnstalleer"</string>
<string name="app_info_drop_target_label" msgid="692894985365717661">"Programinligting"</string>
<string name="install_drop_target_label" msgid="2539096853673231757">"Installeer"</string>
- <string name="dismiss_prediction_label" msgid="3357562989568808658">"Moenie program voorstel nie"</string>
- <string name="pin_prediction" msgid="4196423321649756498">"Vasspeldvoorspelling"</string>
<string name="permlab_install_shortcut" msgid="5632423390354674437">"installeer kortpaaie"</string>
<string name="permdesc_install_shortcut" msgid="923466509822011139">"Laat \'n program toe om kortpaaie by te voeg sonder gebruikerinmenging."</string>
<string name="permlab_read_settings" msgid="1941457408239617576">"lees Tuis-instellings en -kortpaaie"</string>
@@ -84,13 +60,15 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"skryf Tuis-instellings en -kortpaaie"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"Laat die program toe om die instellings en kortpaaie in Tuis te verander."</string>
<string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> word nie toegelaat om foonoproepe te maak nie"</string>
- <string name="gadget_error_text" msgid="740356548025791839">"Kan nie legstuk laai nie"</string>
- <string name="gadget_setup_text" msgid="8348374825537681407">"Legstukinstellings"</string>
- <string name="gadget_complete_setup_text" msgid="309040266978007925">"Tik om opstelling te voltooi"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"Kon nie legstuk laai nie"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"Stel op"</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"Dit is \'n stelselprogram en kan nie gedeïnstalleer word nie."</string>
- <string name="folder_hint_text" msgid="5174843001373488816">"Wysig naam"</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"Naamlose vouer"</string>
<string name="disabled_app_label" msgid="6673129024321402780">"Het <xliff:g id="APP_NAME">%1$s</xliff:g> gedeaktiveer"</string>
- <string name="dotted_app_label" msgid="1704091277755818896">"{count,plural,offset:1 =1{{app_name} het # kennisgewing}other{{app_name} het # kennisgewings}}"</string>
+ <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+ <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, het <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> kennisgewings</item>
+ <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g>, het <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> kennisgewing</item>
+ </plurals>
<string name="default_scroll_format" msgid="7475544710230993317">"Bladsy %1$d van %2$d"</string>
<string name="workspace_scroll_format" msgid="8458889198184077399">"Tuisskerm %1$d van %2$d"</string>
<string name="workspace_new_page" msgid="257366611030256142">"Nuwe tuisskermbladsy"</string>
@@ -99,10 +77,10 @@
<string name="folder_tap_to_rename" msgid="4017685068016979677">"Tik om nuwe naam te stoor"</string>
<string name="folder_closed" msgid="4100806530910930934">"Vouer is gesluit"</string>
<string name="folder_renamed" msgid="1794088362165669656">"Vouer hernoem na <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="folder_name_format_exact" msgid="8626242716117004803">"Vouer: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> items"</string>
- <string name="folder_name_format_overflow" msgid="4270108890534995199">"Vouer: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> of meer items"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"Vouer: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"Legstukke"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Muurpapiere"</string>
- <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Muurpapier en styl"</string>
+ <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Style en muurpapiere"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Tuis-instellings"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Gedeaktiveer deur jou administrateur"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Laat toe dat tuisskerm gedraai word"</string>
@@ -114,16 +92,16 @@
<string name="msg_missing_notification_access" msgid="281113995110910548">"Skakel programkennisgewings vir <xliff:g id="NAME">%1$s</xliff:g> aan om kennisgewingkolle te sien"</string>
<string name="title_change_settings" msgid="1376365968844349552">"Verander instellings"</string>
<string name="notification_dots_service_title" msgid="4284221181793592871">"Wys kennisgewingkolle"</string>
- <string name="auto_add_shortcuts_label" msgid="3698776050751790653">"Voeg programikone by tuisskerm"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Voeg ikoon by tuisskerm"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Vir nuwe programme"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"Onbekend"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"Verwyder"</string>
<string name="abandoned_search" msgid="891119232568284442">"Soek"</string>
<string name="abandoned_promises_title" msgid="7096178467971716750">"Hierdie program is nie geïnstalleer nie"</string>
<string name="abandoned_promise_explanation" msgid="3990027586878167529">"Die program vir hierdie ikoon is nie geïnstalleer nie. Jy kan dit verwyder of die program soek en dit self installeer."</string>
- <string name="app_installing_title" msgid="5864044122733792085">"<xliff:g id="NAME">%1$s</xliff:g> installeer tans; <xliff:g id="PROGRESS">%2$s</xliff:g> voltooi"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> laai tans af, <xliff:g id="PROGRESS">%2$s</xliff:g> voltooid"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> wag tans om te installeer"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"<xliff:g id="NAME">%1$s</xliff:g>-legstukke"</string>
<string name="widgets_list" msgid="796804551140113767">"Legstukkelys"</string>
<string name="widgets_list_closed" msgid="6141506579418771922">"Legstukkelys is toegemaak"</string>
<string name="action_add_to_workspace" msgid="8902165848117513641">"Voeg by tuisskerm"</string>
@@ -151,20 +129,15 @@
<string name="action_deep_shortcut" msgid="2864038805849372848">"Kortpaaie"</string>
<string name="shortcuts_menu_with_notifications_description" msgid="2676582286544232849">"Kortpaaie en kennisgewings"</string>
<string name="action_dismiss_notification" msgid="5909461085055959187">"Maak toe"</string>
- <string name="accessibility_close" msgid="2277148124685870734">"Maak toe"</string>
<string name="notification_dismissed" msgid="6002233469409822874">"Kennisgewing is toegemaak"</string>
<string name="all_apps_personal_tab" msgid="4190252696685155002">"Persoonlik"</string>
<string name="all_apps_work_tab" msgid="4884822796154055118">"Werk"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"Werkprofiel"</string>
- <string name="work_profile_edu_work_apps" msgid="7895468576497746520">"Werkprogramme het \'n kenteken en is sigbaar vir jou IT-administrateur"</string>
- <string name="work_profile_edu_accept" msgid="6069788082535149071">"Het dit"</string>
- <string name="work_apps_paused_title" msgid="3040901117349444598">"Werkprogramme is onderbreek"</string>
- <string name="work_apps_paused_body" msgid="261634750995824906">"Jou werkprogramme kan nie vir jou kennisgewings stuur, jou battery gebruik of toegang tot jou ligging kry nie"</string>
- <string name="work_apps_paused_content_description" msgid="5149623040804051095">"Werkprogramme is af. Jou werkprogramme kan nie vir jou kennisgewings stuur, jou battery gebruik of toegang tot jou ligging kry nie"</string>
- <string name="work_apps_paused_edu_banner" msgid="8872412121608402058">"Werkprogramme het \'n kenteken en is sigbaar vir jou IT-administrateur"</string>
- <string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"Het dit"</string>
- <string name="work_apps_pause_btn_text" msgid="1921059713673767460">"Skakel werkprogramme af"</string>
- <string name="work_apps_enable_btn_text" msgid="1156432622148413741">"Skakel werkprogramme aan"</string>
- <string name="developer_options_filter_hint" msgid="5896817443635989056">"Filter"</string>
+ <string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"Kry werkprogramme hier"</string>
+ <string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"Elke werkprogram het \'n kenteken en word deur jou organisasie veilig gehou. Skuif programme na jou tuisskerm toe vir makliker toegang."</string>
+ <string name="work_mode_on_label" msgid="4781128097185272916">"Bestuur deur jou organisasie"</string>
+ <string name="work_mode_off_label" msgid="3194894777601421047">"Kennisgewings en programme is af"</string>
+ <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Maak toe"</string>
+ <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Toe"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Misluk: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
</resources>
diff --git a/res/values-am/strings.xml b/res/values-am/strings.xml
index f75e7e12cc..0396df6179 100644
--- a/res/values-am/strings.xml
+++ b/res/values-am/strings.xml
@@ -26,57 +26,32 @@
<string name="safemode_shortcut_error" msgid="9160126848219158407">"የወረደው መተግበሪያ ደህንነቱ በተጠበቀ ሁኔታ ውስጥ ተሰናክሏል"</string>
<string name="safemode_widget_error" msgid="4863470563535682004">"ምግብሮች በደህንነቱ የተጠበቀ ሁኔታ ተሰናክለዋል"</string>
<string name="shortcut_not_available" msgid="2536503539825726397">"አቋራጭ አይገኝም"</string>
- <string name="home_screen" msgid="5629429142036709174">"መነሻ"</string>
- <string name="recent_task_option_split_screen" msgid="6690461455618725183">"የተከፈለ ማያ ገጽ"</string>
- <string name="split_screen_position_top" msgid="1504965011158689649">"ወደ ላይ ክፈል"</string>
- <string name="split_screen_position_left" msgid="7537793098851830883">"ወደ ግራ ክፈል"</string>
- <string name="split_screen_position_right" msgid="1569377524925193369">"ወደ ቀኝ ክፈል"</string>
- <string name="split_app_info_accessibility" msgid="5475288491241414932">"የመተግበሪያ መረጃ ለ%1$s"</string>
- <string name="long_press_widget_to_add" msgid="3587712543577675817">"ምግብርን ለማንቀሳቀስ ይንኩ እና ይያዙ።"</string>
- <string name="long_accessible_way_to_add" msgid="2733588281439571974">"ምግብርን ለማንቀሳቀስ ወይም ብጁ እርምጃዎችን ለመጠቀም ሁለቴ መታ ያድርጉ እና ይያዙ።"</string>
+ <string name="home_screen" msgid="806512411299847073">"መነሻ ገጽ"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"ብጁ እርምጃዎች"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"ፍርግም ለማንሳት ይንኩ እና ይያዙት"</string>
+ <string name="long_accessible_way_to_add" msgid="4289502106628154155">"አንድ ንዑስ ፕሮግራም ለመምረጥ ወይም ብጁ እርምጃዎችን ለመጠቀም ሁለቴ መታ አድርገው ይያዙ።"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d ስፋት በ%2$d ከፍታ"</string>
- <string name="widget_preview_context_description" msgid="9045841361655787574">"የ<xliff:g id="WIDGET_NAME">%1$s</xliff:g> ምግብር"</string>
- <string name="add_item_request_drag_hint" msgid="5653291305078645405">"በመነሻ ገጽ አካባቢ ላይ ለማንቀሳቀስ ነክተው ይያዙት"</string>
- <string name="add_to_home_screen" msgid="8631549138215492708">"ወደ መነሻ ገጽ አክል"</string>
- <string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g> ምግብር ወደ መነሻ ማያ ገጽ ታክሏል"</string>
- <string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# ምግብር}one{# ምግብሮች}other{# ምግብሮች}}"</string>
- <string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{# አቋራጭ}one{# አቋራጭ}other{# አቋራጮች}}"</string>
- <string name="widgets_and_shortcuts_count" msgid="7209136747878365116">"<xliff:g id="WIDGETS_COUNT">%1$s</xliff:g>፣ <xliff:g id="SHORTCUTS_COUNT">%2$s</xliff:g>"</string>
- <string name="widget_button_text" msgid="2880537293434387943">"ፍርግሞች"</string>
- <string name="widgets_full_sheet_search_bar_hint" msgid="8484659090860596457">"ፍለጋ"</string>
- <string name="widgets_full_sheet_cancel_button_description" msgid="5766167035728653605">"ጽሁፍን ከፍለጋ ሳጥን አጽዳ"</string>
- <string name="no_widgets_available" msgid="4337693382501046170">"መግብሮች እና አቋራጮች አይገኙም"</string>
- <string name="no_search_results" msgid="3787956167293097509">"ምንም መግብሮች ወይም አቋራጮች አልተገኙም"</string>
- <string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"የግል"</string>
- <string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"ስራ"</string>
- <string name="widget_category_conversations" msgid="8894438636213590446">"ውይይቶች"</string>
- <string name="widget_education_header" msgid="4874760613775913787">"በጣቶችዎ ጫፎች ላይ ጠቃሚ መረጃ"</string>
- <string name="widget_education_content" msgid="745542879510751525">"መተግበሪያዎችን ሳይከፍቱ መረጃ ለማግኘት በመነሻ ማያ ገጽዎ ላይ ምግብሮችን ማከል ይችላሉ"</string>
- <string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"የምግብር ቅንብሮችን ለመለወጥ መታ ያድርጉ"</string>
- <string name="widget_education_close_button" msgid="8676165703104836580">"ገባኝ"</string>
- <string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"የምግብር ቅንብሮችን ይለውጡ"</string>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"ራስዎ ለማስቀመጥ ነክተው ይያዙት"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"በራስ-ሰር አክል"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"መተግበሪያዎችን ፈልግ"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"መተግበሪያዎችን በመጫን ላይ…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"ከ«<xliff:g id="QUERY">%1$s</xliff:g>» ጋር የሚዛመዱ ምንም መተግበሪያዎች አልተገኙም"</string>
<string name="all_apps_search_market_message" msgid="1366263386197059176">"ተጨማሪ መተግበሪያዎች ይፈልጉ"</string>
<string name="label_application" msgid="8531721983832654978">"መተግበሪያ"</string>
- <string name="all_apps_label" msgid="5015784846527570951">"ሁሉም መተግበሪያዎች"</string>
<string name="notifications_header" msgid="1404149926117359025">"ማሳወቂያዎች"</string>
- <string name="long_press_shortcut_to_add" msgid="5405328730817637737">"አቋራጭን ለማንቀሳቀስ ይንኩ እና ይያዙ"</string>
- <string name="long_accessible_way_to_add_shortcut" msgid="2199537273817090740">"አቋራጭን ለማንቀሳቀስ ወይም ብጁ እርምጃዎችን ለመጠቀም ሁለቴ መታ ያድርጉ እና ይያዙ።"</string>
- <string name="out_of_space" msgid="6692471482459245734">"በዚህ የመነሻ ማያ ገጽ ላይ ምንም ክፍል የለም"</string>
+ <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"አንድ አቋራጭ ለመውሰድ ነክተው ይያዙ።"</string>
+ <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"አንድ አቋራጭ ለመውሰድ ወይም ብጁ እርምጃዎችን ለመጠቀም ሁለቴ መታ አድርገው ይያዙ።"</string>
+ <string name="out_of_space" msgid="4691004494942118364">"በዚህ መነሻ ማያ ገጽ ላይ ምንም ቦታ የለም።"</string>
<string name="hotseat_out_of_space" msgid="7448809638125333693">"በተወዳጆች መሣቢያ ውስጥ ተጨማሪ ቦታ የለም"</string>
<string name="all_apps_button_label" msgid="8130441508702294465">"የመተግበሪያዎች ዝርዝር"</string>
- <string name="all_apps_search_results" msgid="5889367432531296759">"የፍለጋ ውጤቶች"</string>
<string name="all_apps_button_personal_label" msgid="1315764287305224468">"የግል መተግበሪያዎች ዝርዝር"</string>
<string name="all_apps_button_work_label" msgid="7270707118948892488">"የሥራ መተግበሪያዎች ዝርዝር"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"መነሻ"</string>
<string name="remove_drop_target_label" msgid="7812859488053230776">"አስወግድ"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"አራግፍ"</string>
<string name="app_info_drop_target_label" msgid="692894985365717661">"የመተግበሪያ መረጃ"</string>
<string name="install_drop_target_label" msgid="2539096853673231757">"ጫን"</string>
- <string name="dismiss_prediction_label" msgid="3357562989568808658">"መተግበሪያውን አይጠቁሙ"</string>
- <string name="pin_prediction" msgid="4196423321649756498">"የፒን ግምት"</string>
<string name="permlab_install_shortcut" msgid="5632423390354674437">"አቋራጮችን ይጭናል"</string>
<string name="permdesc_install_shortcut" msgid="923466509822011139">"መተግበሪያው ያለተጠቃሚ ጣልቃ ገብነት አቋራጭ እንዲያክል ያስችለዋል።"</string>
<string name="permlab_read_settings" msgid="1941457408239617576">"የመነሻ ቅንብሮች እና አቋራጮችን ያነባል"</string>
@@ -84,13 +59,15 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"የመነሻ ቅንብሮችን እና አቋራጮችን ይጽፋል"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"መተግብሪያው ቅንብሮችን እና አቋራጮችን በመነሻ ውስጥ እንዲቀይራቸው ያስችለዋል።"</string>
<string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> የስልክ ጥሪዎችን ለማድረግ አልተፈቀደለትም"</string>
- <string name="gadget_error_text" msgid="740356548025791839">"ምግብርን መጫን አልተቻለም"</string>
- <string name="gadget_setup_text" msgid="8348374825537681407">"የምግብር ቅንብሮች"</string>
- <string name="gadget_complete_setup_text" msgid="309040266978007925">"ማዋቀርን ለመጨረስ መታ ያድርጉ"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"ፍርግም የመጫን ችግር"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"ማዋቀሪያ"</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"ይህ የስርዓት መተግበሪያ ነው እና ማራገፍ አይቻልም።"</string>
- <string name="folder_hint_text" msgid="5174843001373488816">"ስም ያርትዑ"</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"ስም-አልባ አቃፊ"</string>
<string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> ተሰናክሏል"</string>
- <string name="dotted_app_label" msgid="1704091277755818896">"{count,plural,offset:1 =1{{app_name}፣ # ማሳወቂያ አለው}one{{app_name}፣ # ማሳወቂያ አለው}other{{app_name}፣ # ማሳወቂያዎች አሉት}}"</string>
+ <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+ <item quantity="one"><xliff:g id="APP_NAME_2">%1$s</xliff:g>፣ <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> ማሳወቂያ አለው</item>
+ <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>፣ <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> ማሳወቂያ አለው</item>
+ </plurals>
<string name="default_scroll_format" msgid="7475544710230993317">"ገጽ %1$d ከ%2$d"</string>
<string name="workspace_scroll_format" msgid="8458889198184077399">"መነሻ ማያ ገጽ %1$d ከ%2$d"</string>
<string name="workspace_new_page" msgid="257366611030256142">"አዲስ የመነሻ ማያ ገጽ"</string>
@@ -99,10 +76,10 @@
<string name="folder_tap_to_rename" msgid="4017685068016979677">"ዳግም የተሰጠውን ስም ለማስቀመጥ መታ ያድርጉ"</string>
<string name="folder_closed" msgid="4100806530910930934">"አቃፊ ተዘግቷል"</string>
<string name="folder_renamed" msgid="1794088362165669656">"አቃፊ <xliff:g id="NAME">%1$s</xliff:g> ተብሎ ዳግም ተሰይሟል"</string>
- <string name="folder_name_format_exact" msgid="8626242716117004803">"አቃፊ፦ <xliff:g id="NAME">%1$s</xliff:g>፣ <xliff:g id="SIZE">%2$d</xliff:g> ንጥሎች"</string>
- <string name="folder_name_format_overflow" msgid="4270108890534995199">"አቃፊ፦ <xliff:g id="NAME">%1$s</xliff:g>፣ <xliff:g id="SIZE">%2$d</xliff:g> ወይም ተጨማሪ ንጥሎች"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"አቃፊ፦ <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"ፍርግሞች"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"የግድግዳ ወረቀቶች"</string>
- <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"ልጣፍ እና ቅጥ"</string>
+ <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"ቅጦች እና ልጣፎች"</string>
<string name="settings_button_text" msgid="8873672322605444408">"የመነሻ ቅንብሮች"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"በእርስዎ አስተዳዳሪ የተሰናከለ"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"የመነሻ ማያ ገጽ ማሽከርከርን ይፍቀዱ"</string>
@@ -114,16 +91,16 @@
<string name="msg_missing_notification_access" msgid="281113995110910548">"የማሳወቂያ ነጥቦችን ለማሳየት የመተግብሪያ ማሳወቂያዎችን ለ<xliff:g id="NAME">%1$s</xliff:g> ያብሩ"</string>
<string name="title_change_settings" msgid="1376365968844349552">"ቅንብሮችን ቀይር"</string>
<string name="notification_dots_service_title" msgid="4284221181793592871">"የማሳወቂያ ነጥቦችን አሳይ"</string>
- <string name="auto_add_shortcuts_label" msgid="3698776050751790653">"የመተግበሪያ አዶዎችን ወደ መነሻ ገጹ ያክሉ"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"አዶ ወደ የመነሻ ማያ ገጽ አክል"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"ለአዲስ መተግበሪያዎች"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"የማይታወቅ"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"አስወግድ"</string>
<string name="abandoned_search" msgid="891119232568284442">"ፈልግ"</string>
<string name="abandoned_promises_title" msgid="7096178467971716750">"ይህ መተግበሪያ አልተጫነም"</string>
<string name="abandoned_promise_explanation" msgid="3990027586878167529">"የዚህ አዶ መተግበሪያ አልተጫነም። ማስወገድ ወይም መተግበሪያውን መፈለግና ራስዎ መጫን ይችላሉ።"</string>
- <string name="app_installing_title" msgid="5864044122733792085">"<xliff:g id="NAME">%1$s</xliff:g> በመጫን ላይ፣ <xliff:g id="PROGRESS">%2$s</xliff:g> ተጠናቅቋል"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> በመውረድ ላይ፣ <xliff:g id="PROGRESS">%2$s</xliff:g> ተጠናቋል"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> ለመጫን በመጠበቅ ላይ"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"<xliff:g id="NAME">%1$s</xliff:g> ንዑስ ፕሮግራሞች"</string>
<string name="widgets_list" msgid="796804551140113767">"የመግብሮች ዝርዝር"</string>
<string name="widgets_list_closed" msgid="6141506579418771922">"የመግብሮች ዝርዝር ተዘግቷል"</string>
<string name="action_add_to_workspace" msgid="8902165848117513641">"ወደ መነሻ ማያ ገጽ ያክሉ"</string>
@@ -151,20 +128,15 @@
<string name="action_deep_shortcut" msgid="2864038805849372848">"አቋራጮች"</string>
<string name="shortcuts_menu_with_notifications_description" msgid="2676582286544232849">"አቋራጮች እና ማሳወቂያዎች"</string>
<string name="action_dismiss_notification" msgid="5909461085055959187">"አሰናብት"</string>
- <string name="accessibility_close" msgid="2277148124685870734">"ዝጋ"</string>
<string name="notification_dismissed" msgid="6002233469409822874">"ማሳወቂያ ተሰናብቷል"</string>
<string name="all_apps_personal_tab" msgid="4190252696685155002">"የግል"</string>
<string name="all_apps_work_tab" msgid="4884822796154055118">"ሥራ"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"የሥራ መገለጫ"</string>
- <string name="work_profile_edu_work_apps" msgid="7895468576497746520">"የሥራ መተግበሪያዎች ባጅ የተደረገባቸው እና ለእርስዎ የአይቲ አስተዳዳሪ የሚታዩ ናቸው"</string>
- <string name="work_profile_edu_accept" msgid="6069788082535149071">"ገባኝ"</string>
- <string name="work_apps_paused_title" msgid="3040901117349444598">"የስራ መተግበሪያዎች ባሉበት ቆመዋል"</string>
- <string name="work_apps_paused_body" msgid="261634750995824906">"የስራ መተግበሪያዎችዎ ማሳወቂያዎችን ሊልክልዎ፣ ባትሪዎን መጠቀም ወይም አካባቢዎን መድረስ አይችሉም"</string>
- <string name="work_apps_paused_content_description" msgid="5149623040804051095">"የሥራ መተግበሪያዎች ጠፍተዋል። የስራ መተግበሪያዎችዎ ማሳወቂያዎችን ሊልክልዎ፣ ባትሪዎን መጠቀም ወይም አካባቢዎን መድረስ አይችሉም"</string>
- <string name="work_apps_paused_edu_banner" msgid="8872412121608402058">"የሥራ መተግበሪያዎች ባጅ የተደረገባቸው ሲሆን ለእርስዎ IT ቡድን ታይ ናቸው"</string>
- <string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"ገባኝ"</string>
- <string name="work_apps_pause_btn_text" msgid="1921059713673767460">"የሥራ መተግበሪያዎችን ያጥፉ"</string>
- <string name="work_apps_enable_btn_text" msgid="1156432622148413741">"የሥራ መተግበሪያዎችን ያብሩ"</string>
- <string name="developer_options_filter_hint" msgid="5896817443635989056">"አጣራ"</string>
+ <string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"የስራ መተግበሪያዎችን እዚህ ያግኙ"</string>
+ <string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"እያንዳንዱ የሥራ መተግበሪያ ባጅ አለው፣ እና በድርጅትዎ ደህንነቱ ተጠብቋል። ለቀለለ መዳረሻ መተግበሪያዎችን ወደ የእርስዎ መነሻ ማያ ገጽ ይውሰዷቸው።"</string>
+ <string name="work_mode_on_label" msgid="4781128097185272916">"በእርስዎ ድርጅት የሚተዳደር"</string>
+ <string name="work_mode_off_label" msgid="3194894777601421047">"ማሳወቂያዎች እና መተግበሪያዎች ጠፍተዋል"</string>
+ <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"ዝጋ"</string>
+ <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"ዝግ"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"አልተሳካም፦ <xliff:g id="WHAT">%1$s</xliff:g>"</string>
</resources>
diff --git a/res/values-ar/strings.xml b/res/values-ar/strings.xml
index 8571d46711..a80ecb0b14 100644
--- a/res/values-ar/strings.xml
+++ b/res/values-ar/strings.xml
@@ -20,63 +20,39 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="649227358658669779">"Launcher3"</string>
+ <string name="folder_name" msgid="7371454440695724752"></string>
<string name="work_folder_name" msgid="3753320833950115786">"العمل"</string>
<string name="activity_not_found" msgid="8071924732094499514">"لم يتم تثبيت التطبيق."</string>
<string name="activity_not_available" msgid="7456344436509528827">"التطبيق ليس متاحًا"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"تم إيقاف التطبيق الذي تم تنزيله في الوضع الآمن"</string>
<string name="safemode_widget_error" msgid="4863470563535682004">"الأدوات غير مفعّلة في الوضع الآمن"</string>
<string name="shortcut_not_available" msgid="2536503539825726397">"الاختصار غير متاح"</string>
- <string name="home_screen" msgid="5629429142036709174">"الشاشة الرئيسية"</string>
- <string name="recent_task_option_split_screen" msgid="6690461455618725183">"تقسيم الشاشة"</string>
- <string name="split_screen_position_top" msgid="1504965011158689649">"تقسيم للأعلى"</string>
- <string name="split_screen_position_left" msgid="7537793098851830883">"تقسيم لليسار"</string>
- <string name="split_screen_position_right" msgid="1569377524925193369">"تقسيم لليمين"</string>
- <string name="split_app_info_accessibility" msgid="5475288491241414932">"‏معلومات تطبيق %1$s"</string>
- <string name="long_press_widget_to_add" msgid="3587712543577675817">"انقر مع الاستمرار لنقل أداة"</string>
- <string name="long_accessible_way_to_add" msgid="2733588281439571974">"انقر مرتين مع تثبيت إصبعك لنقل أداة أو استخدام الإجراءات المخصّصة."</string>
+ <string name="home_screen" msgid="806512411299847073">"الشاشة الرئيسية"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"الإجراءات المخصّصة"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"المس مع الاستمرار لاختيار إحدى الأدوات."</string>
+ <string name="long_accessible_way_to_add" msgid="4289502106628154155">"انقر مرّتين مع الاستمرار لاختيار أداة أو استخدم الإجراءات المخصصة."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"‏العرض %1$d الطول %2$d"</string>
- <string name="widget_preview_context_description" msgid="9045841361655787574">"أداة <xliff:g id="WIDGET_NAME">%1$s</xliff:g>"</string>
- <string name="add_item_request_drag_hint" msgid="5653291305078645405">"يمكنك النقر على الأداة مع الاستمرار لتحريكها على الشاشة الرئيسية."</string>
- <string name="add_to_home_screen" msgid="8631549138215492708">"إضافة إلى الشاشة الرئيسية"</string>
- <string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"تمت إضافة الأداة <xliff:g id="WIDGET_NAME">%1$s</xliff:g> إلى الشاشة الرئيسية."</string>
- <string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{أداة واحدة}zero{# أداة}two{أداتان}few{# أدوات}many{# أداة}other{# أداة}}"</string>
- <string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{اختصار واحد}zero{# اختصار}two{اختصاران}few{# اختصارات}many{# اختصارًا}other{# اختصار}}"</string>
- <string name="widgets_and_shortcuts_count" msgid="7209136747878365116">"<xliff:g id="WIDGETS_COUNT">%1$s</xliff:g>، <xliff:g id="SHORTCUTS_COUNT">%2$s</xliff:g>"</string>
- <string name="widget_button_text" msgid="2880537293434387943">"الأدوات"</string>
- <string name="widgets_full_sheet_search_bar_hint" msgid="8484659090860596457">"بحث"</string>
- <string name="widgets_full_sheet_cancel_button_description" msgid="5766167035728653605">"محو النص من مربّع البحث"</string>
- <string name="no_widgets_available" msgid="4337693382501046170">"الأدوات والاختصارات غير متاحة."</string>
- <string name="no_search_results" msgid="3787956167293097509">"لم يتم العثور على أدوات أو اختصارات."</string>
- <string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"الأدوات الشخصية"</string>
- <string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"أدوات العمل"</string>
- <string name="widget_category_conversations" msgid="8894438636213590446">"المحادثات"</string>
- <string name="widget_education_header" msgid="4874760613775913787">"معلومات مفيدة في متناول يديك"</string>
- <string name="widget_education_content" msgid="745542879510751525">"للحصول على معلومات بدون فتح التطبيقات، يمكنك إضافة الأدوات إلى الشاشة الرئيسية."</string>
- <string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"انقر لتغيير إعدادات الأداة"</string>
- <string name="widget_education_close_button" msgid="8676165703104836580">"حسنًا"</string>
- <string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"تغيير إعدادات الأداة"</string>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"انقر مع الاستمرار لإضافة العنصر يدويًا"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"الإضافة تلقائيًا"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"بحث في التطبيقات"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"جارٍ تحميل التطبيقات…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"لم يتم العثور على أي تطبيقات تتطابق مع \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
<string name="all_apps_search_market_message" msgid="1366263386197059176">"البحث عن مزيد من التطبيقات"</string>
<string name="label_application" msgid="8531721983832654978">"تطبيق"</string>
- <string name="all_apps_label" msgid="5015784846527570951">"جميع التطبيقات"</string>
<string name="notifications_header" msgid="1404149926117359025">"الإشعارات"</string>
- <string name="long_press_shortcut_to_add" msgid="5405328730817637737">"انقر مع الاستمرار لنقل اختصار"</string>
- <string name="long_accessible_way_to_add_shortcut" msgid="2199537273817090740">"انقر مرتين مع تثبيت إصبعك لنقل اختصار أو استخدام الإجراءات المخصّصة."</string>
- <string name="out_of_space" msgid="6692471482459245734">"ما مِن مساحة على هذه الشاشة الرئيسية."</string>
+ <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"انقر مع الاستمرار لاختيار اختصار."</string>
+ <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"يمكنك النقر مرّتين مع الاستمرار لاختيار اختصار أو استخدام الإجراءات المخصصة."</string>
+ <string name="out_of_space" msgid="4691004494942118364">"ليس هناك مساحة أخرى في هذه الشاشة الرئيسية."</string>
<string name="hotseat_out_of_space" msgid="7448809638125333693">"لا يوجد المزيد من الحقول في علبة المفضلة"</string>
<string name="all_apps_button_label" msgid="8130441508702294465">"قائمة التطبيقات"</string>
- <string name="all_apps_search_results" msgid="5889367432531296759">"نتائج البحث"</string>
<string name="all_apps_button_personal_label" msgid="1315764287305224468">"قائمة التطبيقات الشخصية"</string>
<string name="all_apps_button_work_label" msgid="7270707118948892488">"قائمة تطبيقات العمل"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"الرئيسية"</string>
<string name="remove_drop_target_label" msgid="7812859488053230776">"إزالة"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"إلغاء التثبيت"</string>
<string name="app_info_drop_target_label" msgid="692894985365717661">"معلومات عن التطبيق"</string>
<string name="install_drop_target_label" msgid="2539096853673231757">"تثبيت"</string>
- <string name="dismiss_prediction_label" msgid="3357562989568808658">"عدم اقتراح التطبيق"</string>
- <string name="pin_prediction" msgid="4196423321649756498">"تثبيت التطبيق المتوقّع"</string>
<string name="permlab_install_shortcut" msgid="5632423390354674437">"تثبيت اختصارات"</string>
<string name="permdesc_install_shortcut" msgid="923466509822011139">"للسماح لتطبيق ما بإضافة اختصارات بدون تدخل المستخدم."</string>
<string name="permlab_read_settings" msgid="1941457408239617576">"قراءة إعدادات واختصارات الشاشة الرئيسية"</string>
@@ -84,13 +60,19 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"كتابة إعدادات واختصارات الشاشة الرئيسية"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"للسماح للتطبيق بتغيير الإعدادات والاختصارات في الشاشة الرئيسية."</string>
<string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> غير مسموح به لإجراء مكالمات هاتفية"</string>
- <string name="gadget_error_text" msgid="740356548025791839">"يتعذّر تحميل الأداة."</string>
- <string name="gadget_setup_text" msgid="8348374825537681407">"إعدادات الأداة"</string>
- <string name="gadget_complete_setup_text" msgid="309040266978007925">"انقر لإكمال الإعداد."</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"حدثت مشكلة أثناء تحميل الأداة"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"الإعداد"</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"هذا تطبيق نظام وتتعذر إزالته."</string>
- <string name="folder_hint_text" msgid="5174843001373488816">"تعديل الاسم"</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"مجلد بدون اسم"</string>
<string name="disabled_app_label" msgid="6673129024321402780">"تم إيقاف <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
- <string name="dotted_app_label" msgid="1704091277755818896">"{count,plural,offset:1 =1{هناك إشعار واحد في تطبيق {app_name}.}zero{هناك # إشعار في تطبيق {app_name}.}two{هناك إشعاران في تطبيق {app_name}.}few{هناك # إشعارات في تطبيق {app_name}.}many{هناك # إشعارًا في تطبيق {app_name}.}other{هناك # إشعار في تطبيق {app_name}.}}"</string>
+ <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+ <item quantity="zero">يتضمن تطبيق <xliff:g id="APP_NAME_2">%1$s</xliff:g> <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> إشعار.​</item>
+ <item quantity="two">يتضمن تطبيق <xliff:g id="APP_NAME_2">%1$s</xliff:g> إشعارين (<xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g>).</item>
+ <item quantity="few">يتضمن تطبيق <xliff:g id="APP_NAME_2">%1$s</xliff:g> <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> إشعارات.​</item>
+ <item quantity="many">يتضمن تطبيق <xliff:g id="APP_NAME_2">%1$s</xliff:g> <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> إشعارًا.</item>
+ <item quantity="other">يتضمن تطبيق <xliff:g id="APP_NAME_2">%1$s</xliff:g> <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> إشعار.</item>
+ <item quantity="one">يتضمن تطبيق <xliff:g id="APP_NAME_0">%1$s</xliff:g> إشعارًا واحدًا (<xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g>).</item>
+ </plurals>
<string name="default_scroll_format" msgid="7475544710230993317">"‏الصفحة %1$d من %2$d"</string>
<string name="workspace_scroll_format" msgid="8458889198184077399">"‏الشاشة الرئيسية %1$d من %2$d"</string>
<string name="workspace_new_page" msgid="257366611030256142">"صفحة الشاشة الرئيسية الجديدة"</string>
@@ -99,37 +81,37 @@
<string name="folder_tap_to_rename" msgid="4017685068016979677">"انقر لحفظ الاسم الجديد"</string>
<string name="folder_closed" msgid="4100806530910930934">"تم إغلاق المجلد"</string>
<string name="folder_renamed" msgid="1794088362165669656">"تمت إعادة تسمية المجلد إلى <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="folder_name_format_exact" msgid="8626242716117004803">"المجلد: <xliff:g id="NAME">%1$s</xliff:g>، <xliff:g id="SIZE">%2$d</xliff:g> عنصر"</string>
- <string name="folder_name_format_overflow" msgid="4270108890534995199">"المجلد: <xliff:g id="NAME">%1$s</xliff:g>، <xliff:g id="SIZE">%2$d</xliff:g> عنصر أو أكثر"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"المجلد: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"الأدوات"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"الخلفيات"</string>
- <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"الخلفية والنمط"</string>
+ <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"الأنماط والخلفيات"</string>
<string name="settings_button_text" msgid="8873672322605444408">"إعدادات الشاشة الرئيسية"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"أوقف المشرف هذه الميزة"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"السماح بتدوير الشاشة الرئيسية"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"عند تدوير الهاتف"</string>
<string name="notification_dots_title" msgid="9062440428204120317">"نقاط الإشعارات"</string>
- <string name="notification_dots_desc_on" msgid="1679848116452218908">"مفعّلة"</string>
+ <string name="notification_dots_desc_on" msgid="1679848116452218908">"مفعّل"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"غير مفعّل"</string>
- <string name="title_missing_notification_access" msgid="7503287056163941064">"يلزم تمكين الوصول إلى الإشعارات"</string>
- <string name="msg_missing_notification_access" msgid="281113995110910548">"لعرض نقاط الإشعارات، يجب تفعيل إشعارات التطبيق في <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="title_missing_notification_access" msgid="7503287056163941064">"يلزم تفعيل الوصول إلى الإشعارات"</string>
+ <string name="msg_missing_notification_access" msgid="281113995110910548">"لعرض نقاط الإشعارات، يجب تشغيل إشعارات التطبيق في <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="title_change_settings" msgid="1376365968844349552">"تغيير الإعدادات"</string>
<string name="notification_dots_service_title" msgid="4284221181793592871">"عرض نقاط الإشعارات"</string>
- <string name="auto_add_shortcuts_label" msgid="3698776050751790653">"إضافة رموز التطبيقات إلى الشاشة الرئيسية"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"إضافة رمز إلى الشاشة الرئيسية"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"للتطبيقات الجديدة"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"غير معروفة"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"إزالة"</string>
<string name="abandoned_search" msgid="891119232568284442">"بحث"</string>
<string name="abandoned_promises_title" msgid="7096178467971716750">"لم يتم تثبيت هذا التطبيق"</string>
<string name="abandoned_promise_explanation" msgid="3990027586878167529">"لم يتم تثبيت تطبيق لهذا الرمز. يمكنك إزالته أو البحث عن التطبيق وتثبيته يدويًا."</string>
- <string name="app_installing_title" msgid="5864044122733792085">"جارٍ تثبيت <xliff:g id="NAME">%1$s</xliff:g>، مستوى التقدم: <xliff:g id="PROGRESS">%2$s</xliff:g>"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"جارٍ تنزيل <xliff:g id="NAME">%1$s</xliff:g>، اكتمل <xliff:g id="PROGRESS">%2$s</xliff:g>"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> في انتظار التثبيت"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"أدوات <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="widgets_list" msgid="796804551140113767">"قائمة الأدوات"</string>
<string name="widgets_list_closed" msgid="6141506579418771922">"تم إغلاق قائمة الأدوات."</string>
- <string name="action_add_to_workspace" msgid="8902165848117513641">"الإضافة إلى شاشة الصفحة الرئيسية"</string>
+ <string name="action_add_to_workspace" msgid="8902165848117513641">"الإضافة إلى الشاشة الرئيسية"</string>
<string name="action_move_here" msgid="2170188780612570250">"نقل العنصر إلى هنا"</string>
<string name="item_added_to_workspace" msgid="4211073925752213539">"تمت إضافة العنصر إلى الشاشة الرئيسية"</string>
- <string name="item_removed" msgid="851119963877842327">"تمّت إزالة العنصر."</string>
+ <string name="item_removed" msgid="851119963877842327">"تم حذف العنصر"</string>
<string name="undo" msgid="4151576204245173321">"تراجع"</string>
<string name="action_move" msgid="4339390619886385032">"نقل العنصر"</string>
<string name="move_to_empty_cell" msgid="2833711483015685619">"نقل إلى الصف <xliff:g id="NUMBER_0">%1$s</xliff:g> العمود <xliff:g id="NUMBER_1">%2$s</xliff:g>"</string>
@@ -151,20 +133,15 @@
<string name="action_deep_shortcut" msgid="2864038805849372848">"الاختصارات"</string>
<string name="shortcuts_menu_with_notifications_description" msgid="2676582286544232849">"الاختصارات والإشعارات"</string>
<string name="action_dismiss_notification" msgid="5909461085055959187">"تجاهل"</string>
- <string name="accessibility_close" msgid="2277148124685870734">"إغلاق"</string>
<string name="notification_dismissed" msgid="6002233469409822874">"تم تجاهل الإشعار"</string>
<string name="all_apps_personal_tab" msgid="4190252696685155002">"شخصية"</string>
<string name="all_apps_work_tab" msgid="4884822796154055118">"للعمل"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"الملف الشخصي للعمل"</string>
- <string name="work_profile_edu_work_apps" msgid="7895468576497746520">"تحمل تطبيقات العمل شارة وتكون مرئية لمشرف تكنولوجيا المعلومات."</string>
- <string name="work_profile_edu_accept" msgid="6069788082535149071">"حسنًا"</string>
- <string name="work_apps_paused_title" msgid="3040901117349444598">"تطبيقات العمل متوقفة مؤقتًا"</string>
- <string name="work_apps_paused_body" msgid="261634750995824906">"لا يمكن لتطبيقات العمل إرسال إشعارات إليك أو استخدام بطاريتك أو الوصول إلى موقعك الجغرافي."</string>
- <string name="work_apps_paused_content_description" msgid="5149623040804051095">"تطبيقات العمل غير مفعّلة، وبالتالي لا يمكنها إرسال إشعارات إليك أو استخدام بطاريتك أو الوصول إلى موقعك الجغرافي."</string>
- <string name="work_apps_paused_edu_banner" msgid="8872412121608402058">"تحمل تطبيقات العمل شارة وتكون مرئية لمشرف تكنولوجيا المعلومات."</string>
- <string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"حسنًا"</string>
- <string name="work_apps_pause_btn_text" msgid="1921059713673767460">"إيقاف تطبيقات العمل"</string>
- <string name="work_apps_enable_btn_text" msgid="1156432622148413741">"تفعيل تطبيقات العمل"</string>
- <string name="developer_options_filter_hint" msgid="5896817443635989056">"فلتر"</string>
+ <string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"البحث عن تطبيقات العمل هنا"</string>
+ <string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"يحتوي كل تطبيق للعمل على شارة ويظل تحت حماية مؤسستك. يمكنك نقل التطبيقات إلى شاشتك الرئيسية لتسهيل الوصول إليها."</string>
+ <string name="work_mode_on_label" msgid="4781128097185272916">"ملف شخصي للعمل تديره مؤسستك"</string>
+ <string name="work_mode_off_label" msgid="3194894777601421047">"الإشعارات والتطبيقات متوقفة."</string>
+ <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"إغلاق"</string>
+ <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"تمّ الإغلاق"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"تعذَّر <xliff:g id="WHAT">%1$s</xliff:g>."</string>
</resources>
diff --git a/res/values-as/strings.xml b/res/values-as/strings.xml
index 5dc35cb4b8..2984603818 100644
--- a/res/values-as/strings.xml
+++ b/res/values-as/strings.xml
@@ -20,63 +20,39 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="649227358658669779">"Launcher3"</string>
+ <string name="folder_name" msgid="7371454440695724752"></string>
<string name="work_folder_name" msgid="3753320833950115786">"কৰ্মস্থান"</string>
<string name="activity_not_found" msgid="8071924732094499514">"এপটো ইনষ্টল কৰা নহ\'ল।"</string>
<string name="activity_not_available" msgid="7456344436509528827">"এপটো নাই"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"ডাউনল’ড কৰা এপটোক সুৰক্ষিত ম\'ডত অক্ষম কৰা হ’ল"</string>
<string name="safemode_widget_error" msgid="4863470563535682004">"ৱিজেটবোৰক সুৰক্ষিত ম\'ডত অক্ষম কৰা হ’ল"</string>
<string name="shortcut_not_available" msgid="2536503539825726397">"শ্বৰ্টকাট নাই"</string>
- <string name="home_screen" msgid="5629429142036709174">"গৃহ স্ক্ৰীন"</string>
- <string name="recent_task_option_split_screen" msgid="6690461455618725183">"বিভাজিত স্ক্ৰীন"</string>
- <string name="split_screen_position_top" msgid="1504965011158689649">"একেবাৰে ওপৰৰফালে বিভাজন কৰক"</string>
- <string name="split_screen_position_left" msgid="7537793098851830883">"বাওঁফালে বিভাজন কৰক"</string>
- <string name="split_screen_position_right" msgid="1569377524925193369">"সোঁফালে বিভাজন কৰক"</string>
- <string name="split_app_info_accessibility" msgid="5475288491241414932">"%1$sৰ বাবে এপৰ তথ্য"</string>
- <string name="long_press_widget_to_add" msgid="3587712543577675817">"ৱিজেট স্থানান্তৰ কৰিবলৈ টিপি ধৰি ৰাখক।"</string>
- <string name="long_accessible_way_to_add" msgid="2733588281439571974">"কোনো ৱিজেট স্থানান্তৰ কৰিবলৈ দুবাৰ টিপি ধৰি ৰাখক অথবা কাষ্টম কাৰ্য ব্যৱহাৰ কৰক।"</string>
+ <string name="home_screen" msgid="806512411299847073">"গৃহ স্ক্ৰীণ"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"উপযোগিতা অনুসৰি কৰা কাৰ্যবিলাক"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"কোনো ৱিজেট বাছনি কৰিবলৈ স্পৰ্শ কৰি থাকক।"</string>
+ <string name="long_accessible_way_to_add" msgid="4289502106628154155">"কোনো ৱিজেট বাছনি কৰিবলৈ অথবা উপযোগিতা অনুসৰি কাৰ্যবিলাক ব্য়ৱহাৰ কৰিবলৈ দুবাৰ টিপি থাকক।"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d বহল x %2$d ওখ"</string>
- <string name="widget_preview_context_description" msgid="9045841361655787574">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g> ৱিজেট"</string>
- <string name="add_item_request_drag_hint" msgid="5653291305078645405">"ৱিজেটটো গৃহ স্ক্ৰীনৰ আশে-পাশে নিবলৈ সেইটোত স্পৰ্শ কৰি ধৰি ৰাখক"</string>
- <string name="add_to_home_screen" msgid="8631549138215492708">"গৃহ স্ক্ৰীনত যোগ কৰক"</string>
- <string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g> ৱিজেটটো গৃহ স্ক্ৰীনত যোগ দিয়া হৈছে"</string>
- <string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# টা ৱিজেট}one{# টা ৱিজেট}other{# টা ৱিজেট}}"</string>
- <string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{# টা শ্বৰ্টকাট}one{# টা শ্বৰ্টকাট}other{# টা শ্বৰ্টকাট}}"</string>
- <string name="widgets_and_shortcuts_count" msgid="7209136747878365116">"<xliff:g id="WIDGETS_COUNT">%1$s</xliff:g>, <xliff:g id="SHORTCUTS_COUNT">%2$s</xliff:g>"</string>
- <string name="widget_button_text" msgid="2880537293434387943">"ৱিজেটসমূহ"</string>
- <string name="widgets_full_sheet_search_bar_hint" msgid="8484659090860596457">"সন্ধান"</string>
- <string name="widgets_full_sheet_cancel_button_description" msgid="5766167035728653605">"সন্ধান বাকচত থকা পাঠ মচক"</string>
- <string name="no_widgets_available" msgid="4337693382501046170">"ৱিজেট আৰু শ্বৰ্টকাট উপলব্ধ নহয়"</string>
- <string name="no_search_results" msgid="3787956167293097509">"কোনো ৱিজেট আৰু শ্বৰ্টকাট পোৱা নগ’ল"</string>
- <string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"ব্যক্তিগত"</string>
- <string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"কৰ্মস্থান"</string>
- <string name="widget_category_conversations" msgid="8894438636213590446">"বাৰ্তালাপ"</string>
- <string name="widget_education_header" msgid="4874760613775913787">"আপোনাৰ আঙুলিৰে টিপতে উপযোগী তথ্য পাওক"</string>
- <string name="widget_education_content" msgid="745542879510751525">"এপ্‌ নোখোলাকৈ তথ্য পাবলৈ আপুনি নিজৰ গৃহ স্ক্ৰীনত ৱিজেট যোগ দিব পাৰে"</string>
- <string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"ৱিজেটৰ ছেটিং সলনি কৰিবলৈ টিপক"</string>
- <string name="widget_education_close_button" msgid="8676165703104836580">"বুজি পালোঁ"</string>
- <string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"ৱিজেটৰ ছেটিং সলনি কৰক"</string>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"মেনুৱেলভাৱে ৰাখিবলৈ স্পৰ্শ কৰি থাকক"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"স্বয়ংক্ৰিয়ভাবে যোগ কৰক"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"এপসমূহ সন্ধান কৰক"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"এপসমূহ ল’ড কৰি থকা হৈছে…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\"ৰ সৈতে মিলা কোনো এপ্ বিচাৰি পোৱা নগ\'ল"</string>
<string name="all_apps_search_market_message" msgid="1366263386197059176">"আৰু অধিক এপবোৰ সন্ধান কৰক"</string>
<string name="label_application" msgid="8531721983832654978">"এপ্"</string>
- <string name="all_apps_label" msgid="5015784846527570951">"আটাইবোৰ এপ্"</string>
<string name="notifications_header" msgid="1404149926117359025">"জাননীসমূহ"</string>
- <string name="long_press_shortcut_to_add" msgid="5405328730817637737">"শ্বৰ্টকাট স্থানান্তৰ কৰিবলৈ দুবাৰ টিপি ধৰি ৰাখক।"</string>
- <string name="long_accessible_way_to_add_shortcut" msgid="2199537273817090740">"কোনো শ্বৰ্টকাট স্থানান্তৰ কৰিবলৈ দুবাৰ টিপি ধৰি ৰাখক অথবা কাষ্টম কাৰ্য ব্যৱহাৰ কৰক।"</string>
- <string name="out_of_space" msgid="6692471482459245734">"এই গৃহ স্ক্ৰীনত খালী ঠাই নাই"</string>
+ <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"কোনো শ্বৰ্টকাট বাছনি কৰিবলৈ স্পৰ্শ কৰি হেঁচি ধৰক।"</string>
+ <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"কোনো শ্বৰ্টকাট বাছনি কৰিবলৈ দুবাৰ টিপি হেঁচি ধৰক, বা নিজৰ উপযোগিতা অনুসৰি সৃষ্টি কৰা কাৰ্যসমূহ ব্যৱহাৰ কৰক।"</string>
+ <string name="out_of_space" msgid="4691004494942118364">"এই গৃহ স্ক্ৰীণত আৰু বেছি ঠাই নাই।"</string>
<string name="hotseat_out_of_space" msgid="7448809638125333693">"পছন্দৰ ট্ৰে\'ত আৰু বেছি ঠাই নাই"</string>
<string name="all_apps_button_label" msgid="8130441508702294465">"এপৰ সূচী"</string>
- <string name="all_apps_search_results" msgid="5889367432531296759">"সন্ধানৰ ফলাফল"</string>
<string name="all_apps_button_personal_label" msgid="1315764287305224468">"ব্যক্তিগত এপৰ তালিকা"</string>
<string name="all_apps_button_work_label" msgid="7270707118948892488">"কৰ্মস্থানৰ এপৰ তালিকা"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"গৃহপৃষ্ঠা"</string>
<string name="remove_drop_target_label" msgid="7812859488053230776">"আঁতৰাওক"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"আনইনষ্টল কৰক"</string>
<string name="app_info_drop_target_label" msgid="692894985365717661">"এপ সম্পৰ্কীয় তথ্য"</string>
<string name="install_drop_target_label" msgid="2539096853673231757">"ইনষ্টল কৰক"</string>
- <string name="dismiss_prediction_label" msgid="3357562989568808658">"এপৰ পৰামৰ্শ নিদিব"</string>
- <string name="pin_prediction" msgid="4196423321649756498">"পূৰ্বানুমান কৰা এপ্‌টো পিন কৰক"</string>
<string name="permlab_install_shortcut" msgid="5632423390354674437">"শ্বৰ্টকাট ইনষ্টল কৰিব পাৰে"</string>
<string name="permdesc_install_shortcut" msgid="923466509822011139">"ব্য়ৱহাৰকাৰীৰ হস্তক্ষেপ অবিহনেই কোনো এপক শ্বৰ্টকাটবোৰ যোগ কৰাৰ অনুমতি দিয়ে।"</string>
<string name="permlab_read_settings" msgid="1941457408239617576">"গৃহ ছেটিং আৰু শ্বৰ্টকাটবোৰ পঢ়িব পাৰে"</string>
@@ -84,51 +60,53 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"গৃহ ছেটিং আৰু শ্বৰ্টকাটবোৰ লিখিব পাৰে"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"এপটোক গৃহ পৃষ্ঠাত ছেটিং আৰু শ্বৰ্টকাটসমূহ সলনি কৰাৰ অনুমতি দিয়ে।"</string>
<string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g>ক ফ\'ন কলবোৰ কৰাৰ অনুমতি দিয়া হোৱা নাই"</string>
- <string name="gadget_error_text" msgid="740356548025791839">"ৱিজেট ল’ড কৰিব নোৱাৰি"</string>
- <string name="gadget_setup_text" msgid="8348374825537681407">"ৱিজেটৰ ছেটিং"</string>
- <string name="gadget_complete_setup_text" msgid="309040266978007925">"ছেটআপ সমাপ্ত কৰিবলৈ টিপক"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"ৱিজেট ল\'ড কৰাত সমস্য়া"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"ছেটআপ কৰক"</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"এইটো এটা ছিষ্টেম এপ আৰু ইয়াক আনইনষ্টল কৰিব নোৱৰি"</string>
- <string name="folder_hint_text" msgid="5174843001373488816">"নাম সম্পাদনা কৰক"</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"নামবিহীন ফ\'ল্ডাৰ"</string>
<string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> অক্ষম কৰা হ’ল"</string>
- <string name="dotted_app_label" msgid="1704091277755818896">"{count,plural,offset:1 =1{{app_name}ৰ # টা জাননী আছে}one{{app_name}ৰ # টা জাননী আছে}other{{app_name}ৰ # টা জাননী আছে}}"</string>
+ <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+ <item quantity="one"><xliff:g id="APP_NAME_2">%1$s</xliff:g>ৰ <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g>টা জাননী আছে</item>
+ <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>ৰ <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g>টা জাননী আছে</item>
+ </plurals>
<string name="default_scroll_format" msgid="7475544710230993317">"%2$dৰ %1$d পৃষ্ঠা"</string>
- <string name="workspace_scroll_format" msgid="8458889198184077399">"গৃহ স্ক্ৰীন %2$dৰ %1$d"</string>
- <string name="workspace_new_page" msgid="257366611030256142">"গৃহ স্ক্ৰীনৰ নতুন পৃষ্ঠা"</string>
+ <string name="workspace_scroll_format" msgid="8458889198184077399">"গৃহ স্ক্ৰীণ %2$dৰ %1$d"</string>
+ <string name="workspace_new_page" msgid="257366611030256142">"গৃহ স্ক্ৰীণৰ নতুন পৃষ্ঠা"</string>
<string name="folder_opened" msgid="94695026776264709">"ফ’ল্ডাৰ খোলা হ’ল, <xliff:g id="WIDTH">%1$d</xliff:g> x <xliff:g id="HEIGHT">%2$d</xliff:g>"</string>
<string name="folder_tap_to_close" msgid="4625795376335528256">"ফ\'ল্ডাৰ বন্ধ কৰিবলৈ টিপক"</string>
<string name="folder_tap_to_rename" msgid="4017685068016979677">"সলনি কৰা নাম ছেভ কৰিবলৈ টিপক"</string>
<string name="folder_closed" msgid="4100806530910930934">"ফ\'ল্ডাৰ বন্ধ কৰা হ’ল"</string>
<string name="folder_renamed" msgid="1794088362165669656">"ফ\'ল্ডাৰৰ নাম সলনি কৰি <xliff:g id="NAME">%1$s</xliff:g> কৰা হৈছে"</string>
- <string name="folder_name_format_exact" msgid="8626242716117004803">"ফ’ল্ডাৰ: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> টা বস্তু"</string>
- <string name="folder_name_format_overflow" msgid="4270108890534995199">"ফ’ল্ডাৰ: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> টা অথবা তাতকৈ অধিক বস্তু"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"ফ’ল্ডাৰ: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"ৱিজেটসমূহ"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"ৱালপেপাৰসমূহ"</string>
- <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"ৱালপেপাৰ আৰু শৈলী"</string>
- <string name="settings_button_text" msgid="8873672322605444408">"গৃহ ছেটিং"</string>
+ <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"ষ্টাইল &amp; ৱালপেপাৰ"</string>
+ <string name="settings_button_text" msgid="8873672322605444408">"গৃহ ছেটিংসমূহ"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"আপোনাৰ প্ৰশাসকে অক্ষম কৰি ৰাখিছে"</string>
- <string name="allow_rotation_title" msgid="7728578836261442095">"গৃহ স্ক্ৰীন ঘূৰোৱাৰ অনুমতি দিয়ক"</string>
+ <string name="allow_rotation_title" msgid="7728578836261442095">"গৃহ স্ক্ৰীণ ঘূৰোৱাৰ অনুমতি দিয়ক"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"ফ\'নটো যেতিয়া ঘূৰোৱা হয়"</string>
<string name="notification_dots_title" msgid="9062440428204120317">"জাননী বিন্দু"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"অন আছে"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"অফ আছে"</string>
<string name="title_missing_notification_access" msgid="7503287056163941064">"জাননী চাবলৈ অনুমতিৰ প্ৰয়োজন"</string>
<string name="msg_missing_notification_access" msgid="281113995110910548">"জাননী সম্পৰ্কীয় বিন্দুবোৰ দেখুৱাবলৈ <xliff:g id="NAME">%1$s</xliff:g>ৰ বাবে এপৰ জাননীসমূহ অন কৰক"</string>
- <string name="title_change_settings" msgid="1376365968844349552">"ছেটিং সলনি কৰক"</string>
+ <string name="title_change_settings" msgid="1376365968844349552">"ছেটিংসমূহ সলনি কৰক"</string>
<string name="notification_dots_service_title" msgid="4284221181793592871">"জাননী বিন্দু দেখুৱাওক"</string>
- <string name="auto_add_shortcuts_label" msgid="3698776050751790653">"গৃহ স্ক্ৰীনত এপ্ চিহ্নসমূহ যোগ দিয়ক"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"গৃহ স্ক্ৰীণত আইকনটো যোগ কৰক"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"নতুন এপসমূহৰ বাবে"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"অজ্ঞাত"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"আঁতৰাওক"</string>
<string name="abandoned_search" msgid="891119232568284442">"সন্ধান কৰক"</string>
<string name="abandoned_promises_title" msgid="7096178467971716750">"এই এপটো ইনষ্টল কৰা হোৱা নাই"</string>
<string name="abandoned_promise_explanation" msgid="3990027586878167529">"এই আইকনৰ এপটো ইনষ্টল কৰা হোৱা নাই। আপুনি এইটো আঁতৰাব পাৰে অথবা এপটো বিচাৰি মেনুৱেলভাৱে ইনষ্টল কৰিব পাৰে।"</string>
- <string name="app_installing_title" msgid="5864044122733792085">"<xliff:g id="NAME">%1$s</xliff:g> ইনষ্টল কৰি থকা হৈছে, <xliff:g id="PROGRESS">%2$s</xliff:g> সম্পূৰ্ণ হৈছে"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> ডাউনল’ড কৰি থকা হৈছে, <xliff:g id="PROGRESS">%2$s</xliff:g> সম্পূৰ্ণ হ’ল"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> ইনষ্টল হোৱালৈ অপেক্ষা কৰি থকা হৈছে"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"<xliff:g id="NAME">%1$s</xliff:g> ৱিজেট"</string>
<string name="widgets_list" msgid="796804551140113767">"ৱিজেটৰ তালিকা"</string>
<string name="widgets_list_closed" msgid="6141506579418771922">"ৱিজেটৰ তালিকা বন্ধ কৰা হ’ল"</string>
- <string name="action_add_to_workspace" msgid="8902165848117513641">"গৃহ স্ক্ৰীনত যোগ দিয়ক"</string>
+ <string name="action_add_to_workspace" msgid="8902165848117513641">"গৃহ স্ক্ৰীণত যোগ কৰক"</string>
<string name="action_move_here" msgid="2170188780612570250">"বস্তুটো ইয়ালৈ স্থানান্তৰ কৰক"</string>
- <string name="item_added_to_workspace" msgid="4211073925752213539">"বস্তুটো গৃহ স্ক্ৰীনত যোগ কৰা হ’ল"</string>
+ <string name="item_added_to_workspace" msgid="4211073925752213539">"বস্তুটো গৃহ স্ক্ৰীণত যোগ কৰা হ’ল"</string>
<string name="item_removed" msgid="851119963877842327">"বস্তুটো আঁতৰোৱা হ’ল"</string>
<string name="undo" msgid="4151576204245173321">"আনডু কৰক"</string>
<string name="action_move" msgid="4339390619886385032">"বস্তু স্থানান্তৰ কৰক"</string>
@@ -141,7 +119,7 @@
<string name="added_to_folder" msgid="4793259502305558003">"বস্তুটো ফ\'ল্ডাৰত যোগ কৰা হ’ল"</string>
<string name="create_folder_with" msgid="4050141361160214248">"<xliff:g id="NAME">%1$s</xliff:g>: ৰ জৰিয়তে ফ\'ল্ডাৰ সৃষ্টি কৰক"</string>
<string name="folder_created" msgid="6409794597405184510">"ফ\'ল্ডাৰ সৃষ্টি কৰা হ’ল"</string>
- <string name="action_move_to_workspace" msgid="1603837886334246317">"গৃহ স্ক্ৰীনলৈ স্থানান্তৰ কৰক"</string>
+ <string name="action_move_to_workspace" msgid="1603837886334246317">"হ\'ম স্ক্ৰীণলৈ স্থানান্তৰ কৰক"</string>
<string name="action_resize" msgid="1802976324781771067">"আকাৰ সলনি কৰক"</string>
<string name="action_increase_width" msgid="8773715375078513326">"প্ৰস্থ বৃদ্ধি কৰক"</string>
<string name="action_increase_height" msgid="459390020612501122">"উচ্চতা বৃদ্ধি কৰক"</string>
@@ -151,20 +129,15 @@
<string name="action_deep_shortcut" msgid="2864038805849372848">"শ্বৰ্টকাটসমূহ"</string>
<string name="shortcuts_menu_with_notifications_description" msgid="2676582286544232849">"শ্বৰ্টকাট আৰু জাননীসমূহ"</string>
<string name="action_dismiss_notification" msgid="5909461085055959187">"অগ্ৰাহ্য কৰক"</string>
- <string name="accessibility_close" msgid="2277148124685870734">"বন্ধ কৰক"</string>
<string name="notification_dismissed" msgid="6002233469409822874">"জাননী অগ্ৰাহ্য কৰা হৈছে"</string>
<string name="all_apps_personal_tab" msgid="4190252696685155002">"ব্যক্তিগত"</string>
<string name="all_apps_work_tab" msgid="4884822796154055118">"কৰ্মস্থান"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"কৰ্মস্থানৰ প্ৰ\'ফাইল"</string>
- <string name="work_profile_edu_work_apps" msgid="7895468576497746520">"কৰ্মস্থানৰ এপ্‌সমূহ প্ৰতীকেৰে চিহ্নিত কৰা হয় আৰু সেইবোৰ আপোনাৰ আইটি প্ৰশাসকৰ বাবে দৃশ্যমান হয়"</string>
- <string name="work_profile_edu_accept" msgid="6069788082535149071">"বুজি পালোঁ"</string>
- <string name="work_apps_paused_title" msgid="3040901117349444598">"কৰ্মস্থানৰ এপ্‌সমূহ পজ হৈ আছে"</string>
- <string name="work_apps_paused_body" msgid="261634750995824906">"আপোনাৰ কৰ্মস্থানৰ এপ্‌সমূহে আপোনালৈ জাননী পঠিয়াব, আপোনাৰ বেটাৰী ব্যৱহাৰ কৰিব অথবা আপোনাৰ অৱস্থান এক্সেছ কৰিব নোৱাৰে"</string>
- <string name="work_apps_paused_content_description" msgid="5149623040804051095">"কৰ্মস্থানৰ এপ্‌সমূহ অফ হৈ আছে। আপোনাৰ কৰ্মস্থানৰ এপ্‌সমূহে আপোনালৈ জাননী পঠিয়াব, আপোনাৰ বেটাৰী ব্যৱহাৰ কৰিব অথবা আপোনাৰ অৱস্থান এক্সেছ কৰিব নোৱাৰে"</string>
- <string name="work_apps_paused_edu_banner" msgid="8872412121608402058">"কর্মস্থানৰ এপ্‌সমূহ প্ৰতীকেৰে চিহ্নিত কৰা হয় আৰু সেইবোৰ আপোনাৰ আইটি প্ৰশাসকৰ বাবে দৃশ্যমান হয়"</string>
- <string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"বুজি পালোঁ"</string>
- <string name="work_apps_pause_btn_text" msgid="1921059713673767460">"কৰ্মস্থানৰ এপ্‌সমূহ অফ কৰক"</string>
- <string name="work_apps_enable_btn_text" msgid="1156432622148413741">"কৰ্মস্থানৰ এপ্‌সমূহ অন কৰক"</string>
- <string name="developer_options_filter_hint" msgid="5896817443635989056">"ফিল্টাৰ"</string>
+ <string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"ইয়াত কৰ্মস্থানৰ এপ্ বিচাৰি পাওক"</string>
+ <string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"কৰ্মস্থানৰ প্ৰতিটো এপৰে একোটা প্ৰতীক আছে আৰু তাক আপোনাৰ প্ৰতিষ্ঠানে সুৰক্ষিত কৰি ৰাখে। ব্যৱহাৰ কৰাত সুবিধা হ\'বলৈ এপসমূহ আপোনাৰ গৃহ স্ক্ৰীণলৈ স্থানান্তৰ কৰক।"</string>
+ <string name="work_mode_on_label" msgid="4781128097185272916">"আপোনাৰ প্ৰতিষ্ঠানৰ দ্বাৰা পৰিচালিত"</string>
+ <string name="work_mode_off_label" msgid="3194894777601421047">"জাননী আৰু এপসমূহ অফ হৈ আছে"</string>
+ <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"বন্ধ কৰক"</string>
+ <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"বন্ধ"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"বিফল: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
</resources>
diff --git a/res/values-az/strings.xml b/res/values-az/strings.xml
index c2ca56d516..7c1ce8447d 100644
--- a/res/values-az/strings.xml
+++ b/res/values-az/strings.xml
@@ -26,57 +26,32 @@
<string name="safemode_shortcut_error" msgid="9160126848219158407">"Güvənli rejimdə icazə verilməyən tətbiq endirildi"</string>
<string name="safemode_widget_error" msgid="4863470563535682004">"Vidcetlər Güvənli rejimdə deaktiv edilib"</string>
<string name="shortcut_not_available" msgid="2536503539825726397">"Qısayol əlçatan deyil"</string>
- <string name="home_screen" msgid="5629429142036709174">"Əsas səhifə"</string>
- <string name="recent_task_option_split_screen" msgid="6690461455618725183">"Ekran bölünməsi"</string>
- <string name="split_screen_position_top" msgid="1504965011158689649">"Yuxarı ayırın"</string>
- <string name="split_screen_position_left" msgid="7537793098851830883">"Sola ayırın"</string>
- <string name="split_screen_position_right" msgid="1569377524925193369">"Sağa ayırın"</string>
- <string name="split_app_info_accessibility" msgid="5475288491241414932">"%1$s ilə bağlı tətbiq məlumatı"</string>
- <string name="long_press_widget_to_add" msgid="3587712543577675817">"Vidceti daşımaq üçün toxunub saxlayın."</string>
- <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Vidceti daşımaq üçün iki dəfə toxunub saxlayın və ya fərdi əməliyyatlardan istifadə edin."</string>
+ <string name="home_screen" msgid="806512411299847073">"Əsas ekran"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"Fərdi əməliyyatlar"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"Vidceti götürmək üçün toxunub saxlayın."</string>
+ <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Vidceti götürmək üçün &amp; iki dəfə toxunub saxlayın və ya fərdi fəaliyyətləri istifadə edin."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%2$d hündürlük %1$d enində"</string>
- <string name="widget_preview_context_description" msgid="9045841361655787574">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g> vidceti"</string>
- <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Əsas ekranda hərəkət etdirmək üçün vidcetə toxunub saxlayın"</string>
- <string name="add_to_home_screen" msgid="8631549138215492708">"Əsas ekrana əlavə edin"</string>
- <string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g> vidceti əsas ekrana əlavə edildi"</string>
- <string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# vidcet}other{# vidcet}}"</string>
- <string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{# qısayol}other{# qısayol}}"</string>
- <string name="widgets_and_shortcuts_count" msgid="7209136747878365116">"<xliff:g id="WIDGETS_COUNT">%1$s</xliff:g>, <xliff:g id="SHORTCUTS_COUNT">%2$s</xliff:g>"</string>
- <string name="widget_button_text" msgid="2880537293434387943">"Vidcet"</string>
- <string name="widgets_full_sheet_search_bar_hint" msgid="8484659090860596457">"Axtarış"</string>
- <string name="widgets_full_sheet_cancel_button_description" msgid="5766167035728653605">"Axtarış qutusundan mətni silin"</string>
- <string name="no_widgets_available" msgid="4337693382501046170">"Vidcet və qısayollar əlçatan deyil"</string>
- <string name="no_search_results" msgid="3787956167293097509">"Vidcet və ya qısayol tapılmayıb"</string>
- <string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Şəxsi"</string>
- <string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"İş"</string>
- <string name="widget_category_conversations" msgid="8894438636213590446">"Söhbətlər"</string>
- <string name="widget_education_header" msgid="4874760613775913787">"Faydalı məlumatlar barmaqlarınızın ucunda"</string>
- <string name="widget_education_content" msgid="745542879510751525">"Tətbiqləri açmadan məlumat almaq üçün Əsas ekrana vidcet əlavə edə bilərsiniz"</string>
- <string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Vidcet ayarlarını dəyişmək üçün toxunun"</string>
- <string name="widget_education_close_button" msgid="8676165703104836580">"Anladım"</string>
- <string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Vidcet ayarlarını dəyişin"</string>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Manual olaraq yerləşdirmək üçün toxunaraq basıb saxlayın"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"Avtomatik əlavə edin"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Tətbiqləri axtarın"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Tətbiqlər yüklənir…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"<xliff:g id="QUERY">%1$s</xliff:g> sorğusuna uyğun tətbiq tapılmadı"</string>
<string name="all_apps_search_market_message" msgid="1366263386197059176">"Daha çox tətbiq üçün axtarış edin"</string>
<string name="label_application" msgid="8531721983832654978">"Tətbiq"</string>
- <string name="all_apps_label" msgid="5015784846527570951">"Bütün tətbiqlər"</string>
<string name="notifications_header" msgid="1404149926117359025">"Bildirişlər"</string>
- <string name="long_press_shortcut_to_add" msgid="5405328730817637737">"Qısayolu daşımaq üçün toxunub saxlayın."</string>
- <string name="long_accessible_way_to_add_shortcut" msgid="2199537273817090740">"Qısayolu daşımaq üçün iki dəfə toxunub saxlayın və ya fərdi əməliyyatlardan istifadə edin."</string>
- <string name="out_of_space" msgid="6692471482459245734">"Bu Əsas ekranda yer qalmayıb"</string>
+ <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"Qısayolu seçmək üçün basıb saxlayın."</string>
+ <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"Qısayolu seçmək üçün iki dəfə basıb saxlayın və ya fərdi əməliyyatlardan istifadə edin."</string>
+ <string name="out_of_space" msgid="4691004494942118364">"Bu Əsas ekranda boş yer yoxdur."</string>
<string name="hotseat_out_of_space" msgid="7448809638125333693">"Favoritlər-də yer yoxdur"</string>
<string name="all_apps_button_label" msgid="8130441508702294465">"Tətbiq siyahısı"</string>
- <string name="all_apps_search_results" msgid="5889367432531296759">"Axtarış nəticələri"</string>
<string name="all_apps_button_personal_label" msgid="1315764287305224468">"Şəxsi tətbiqlərin siyahısı"</string>
<string name="all_apps_button_work_label" msgid="7270707118948892488">"İş tətbiqlərinin siyahısı"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"Əsas səhifə"</string>
<string name="remove_drop_target_label" msgid="7812859488053230776">"Silin"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"Sistemdən sil"</string>
- <string name="app_info_drop_target_label" msgid="692894985365717661">"Tətbiq haqqında"</string>
+ <string name="app_info_drop_target_label" msgid="692894985365717661">"Tətbiq məlumatı"</string>
<string name="install_drop_target_label" msgid="2539096853673231757">"Quraşdırın"</string>
- <string name="dismiss_prediction_label" msgid="3357562989568808658">"Tətbiq təklif olunmasın"</string>
- <string name="pin_prediction" msgid="4196423321649756498">"Proqnozlaşdırılan tətbiqi bərkidin"</string>
<string name="permlab_install_shortcut" msgid="5632423390354674437">"qısayolları quraşdır"</string>
<string name="permdesc_install_shortcut" msgid="923466509822011139">"Tətbiqə istifadəçi müdaxiləsi olmadan qısayolları əlavə etməyə icazə verir."</string>
<string name="permlab_read_settings" msgid="1941457408239617576">"Əsas Səhifə ayarlarını və qısayolları oxuyun"</string>
@@ -84,13 +59,15 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"Əsas Səhifə ayarlarını və qısayolları yazın"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"Tətbiqə Əsas Səhifədə ayarları və qısayolları dəyişməyə icazə verir."</string>
<string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> tətbiqinə telefon zəngləri etmək üçün icazə verilmir"</string>
- <string name="gadget_error_text" msgid="740356548025791839">"Vidceti yükləmək olmur"</string>
- <string name="gadget_setup_text" msgid="8348374825537681407">"Vidcet ayarları"</string>
- <string name="gadget_complete_setup_text" msgid="309040266978007925">"Ayarlamanı tamamlamaq üçün toxunun"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"Vidcet yükləmə problemi"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"Quraşdırma"</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"Bu sistem tətbiqi olduğu üçün sistemdən silinə bilməz."</string>
- <string name="folder_hint_text" msgid="5174843001373488816">"Adı redaktə edin"</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"Adsız Qovluq"</string>
<string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> deaktiv edildi"</string>
- <string name="dotted_app_label" msgid="1704091277755818896">"{count,plural,offset:1 =1{{app_name} tətbiqində # bildiriş var}other{{app_name} tətbiqində # bildiriş var}}"</string>
+ <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+ <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g> tətbiqində <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> bildiriş var</item>
+ <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g> tətbiqində <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> bildiriş var</item>
+ </plurals>
<string name="default_scroll_format" msgid="7475544710230993317">"Səhifə %1$d of %2$d"</string>
<string name="workspace_scroll_format" msgid="8458889198184077399">"Əsas Səhifə ekranı %1$d of %2$d"</string>
<string name="workspace_new_page" msgid="257366611030256142">"Yeni əsas ekran səhifəsi"</string>
@@ -99,13 +76,13 @@
<string name="folder_tap_to_rename" msgid="4017685068016979677">"Ad dəyişikliyini yadda saxlamaq üçün toxunun"</string>
<string name="folder_closed" msgid="4100806530910930934">"Qovluq bağlıdır"</string>
<string name="folder_renamed" msgid="1794088362165669656">"Qovluq adı <xliff:g id="NAME">%1$s</xliff:g> ilə dəyişdirildi"</string>
- <string name="folder_name_format_exact" msgid="8626242716117004803">"Qovluq: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> element"</string>
- <string name="folder_name_format_overflow" msgid="4270108890534995199">"Qovluq: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> və ya daha çox element"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"Qovluq: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"Vidcet"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Divar kağızları"</string>
- <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Divar kağızı və üslub"</string>
+ <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Üslub və divar kağızları"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Home ayarları"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Admininiz tərəfindən deaktiv edilib"</string>
- <string name="allow_rotation_title" msgid="7728578836261442095">"Əsas ekran çevrilsin"</string>
+ <string name="allow_rotation_title" msgid="7728578836261442095">"Əsas ekranın firlanmağına icazə verin"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Telefon çevrilən zaman"</string>
<string name="notification_dots_title" msgid="9062440428204120317">"Bildiriş nöqtələri"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"Aktiv"</string>
@@ -114,16 +91,16 @@
<string name="msg_missing_notification_access" msgid="281113995110910548">"Bildiriş Nöqtələrini göstərmək üçün <xliff:g id="NAME">%1$s</xliff:g> bildirişlərini aktiv edin"</string>
<string name="title_change_settings" msgid="1376365968844349552">"Ayarları dəyişin"</string>
<string name="notification_dots_service_title" msgid="4284221181793592871">"Bildiriş nöqtələrini göstərin"</string>
- <string name="auto_add_shortcuts_label" msgid="3698776050751790653">"Əsas ekrana nişanlar əlavə edilsin"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Əsas ekrana ikona əlavə edin"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Yeni tətbiqlər üçün"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"Naməlum"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"Yığışdır"</string>
<string name="abandoned_search" msgid="891119232568284442">"Axtarış"</string>
<string name="abandoned_promises_title" msgid="7096178467971716750">"Bu tətbiq quraşdırılmayıb"</string>
<string name="abandoned_promise_explanation" msgid="3990027586878167529">"Bu ikona üçün tətbiq quraşdırılmayıb. Onu silə bilərsiniz, və ya tətbiqi taparaq manual yol ilə quraşdıra bilərsiniz."</string>
- <string name="app_installing_title" msgid="5864044122733792085">"<xliff:g id="NAME">%1$s</xliff:g> quraşdırır, <xliff:g id="PROGRESS">%2$s</xliff:g> tamamlanıb"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> endirilir, <xliff:g id="PROGRESS">%2$s</xliff:g> tamamlandı"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> yüklənmək üçün gözləyir"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"<xliff:g id="NAME">%1$s</xliff:g> vidcetləri"</string>
<string name="widgets_list" msgid="796804551140113767">"Vidcet siyahısı"</string>
<string name="widgets_list_closed" msgid="6141506579418771922">"Vidcet siyahısı bağlandı"</string>
<string name="action_add_to_workspace" msgid="8902165848117513641">"Əsas ekrana əlavə edin"</string>
@@ -151,20 +128,15 @@
<string name="action_deep_shortcut" msgid="2864038805849372848">"Qısa yollar"</string>
<string name="shortcuts_menu_with_notifications_description" msgid="2676582286544232849">"Qısayol və bildirişlər"</string>
<string name="action_dismiss_notification" msgid="5909461085055959187">"Rədd edin"</string>
- <string name="accessibility_close" msgid="2277148124685870734">"Bağlayın"</string>
<string name="notification_dismissed" msgid="6002233469409822874">"Bildiriş rədd edildi"</string>
<string name="all_apps_personal_tab" msgid="4190252696685155002">"Şəxsi"</string>
<string name="all_apps_work_tab" msgid="4884822796154055118">"İş"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"İş profili"</string>
- <string name="work_profile_edu_work_apps" msgid="7895468576497746520">"İş tətbiqləri nişanlanıb və İT administratorunuza görünür"</string>
- <string name="work_profile_edu_accept" msgid="6069788082535149071">"Anladım"</string>
- <string name="work_apps_paused_title" msgid="3040901117349444598">"İş tətbiqlərinə pauza verilib"</string>
- <string name="work_apps_paused_body" msgid="261634750995824906">"İş tətbiqləriniz sizə bildirişlər göndərə, batareyanızdan istifadə edə və ya məkanınıza daxil ola bilməz"</string>
- <string name="work_apps_paused_content_description" msgid="5149623040804051095">"İş tətbiqləri deaktivdir. İş tətbiqləriniz sizə bildirişlər göndərə, batareyanızdan istifadə edə və ya məkanınıza daxil ola bilməz"</string>
- <string name="work_apps_paused_edu_banner" msgid="8872412121608402058">"İş tətbiqləri nişanlanıb və İT administratorunuza görünür"</string>
- <string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"Anladım"</string>
- <string name="work_apps_pause_btn_text" msgid="1921059713673767460">"İş tətbiqlərini deaktiv edin"</string>
- <string name="work_apps_enable_btn_text" msgid="1156432622148413741">"İş tətbiqlərini aktiv edin"</string>
- <string name="developer_options_filter_hint" msgid="5896817443635989056">"Filtr"</string>
+ <string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"Burada iş tətbiqləri axtarın"</string>
+ <string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"Hər bir iş tətbiqində təşkilat tərəfindən qorunduğunu göstərən narıncı nişan var. Tətbiqləri daha asan giriş üçün Əsas Səhifə Ekranına köçürün."</string>
+ <string name="work_mode_on_label" msgid="4781128097185272916">"Təşkilatınız tərəfindən idarə olunur"</string>
+ <string name="work_mode_off_label" msgid="3194894777601421047">"Bildiriş və tətbiqlər deaktivdir"</string>
+ <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Bağlayın"</string>
+ <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Bağlıdır"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Alınmadı: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
</resources>
diff --git a/res/values-b+sr+Latn/strings.xml b/res/values-b+sr+Latn/strings.xml
index b10ae183c6..883003c5c0 100644
--- a/res/values-b+sr+Latn/strings.xml
+++ b/res/values-b+sr+Latn/strings.xml
@@ -20,63 +20,39 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="649227358658669779">"Launcher3"</string>
+ <string name="folder_name" msgid="7371454440695724752"></string>
<string name="work_folder_name" msgid="3753320833950115786">"Work"</string>
<string name="activity_not_found" msgid="8071924732094499514">"Aplikacija nije instalirana."</string>
<string name="activity_not_available" msgid="7456344436509528827">"Aplikacija nije dostupna"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"Preuzeta aplikacija je onemogućena u Bezbednom režimu"</string>
<string name="safemode_widget_error" msgid="4863470563535682004">"Vidžeti su onemogućeni u Bezbednom režimu"</string>
<string name="shortcut_not_available" msgid="2536503539825726397">"Prečica nije dostupna"</string>
- <string name="home_screen" msgid="5629429142036709174">"Početni ekran"</string>
- <string name="recent_task_option_split_screen" msgid="6690461455618725183">"Podeljeni ekran"</string>
- <string name="split_screen_position_top" msgid="1504965011158689649">"Podeli u vrhu"</string>
- <string name="split_screen_position_left" msgid="7537793098851830883">"Podeli levo"</string>
- <string name="split_screen_position_right" msgid="1569377524925193369">"Podeli desno"</string>
- <string name="split_app_info_accessibility" msgid="5475288491241414932">"Informacije o aplikaciji za: %1$s"</string>
- <string name="long_press_widget_to_add" msgid="3587712543577675817">"Dodirnite i zadržite radi pomeranja vidžeta."</string>
- <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Dvaput dodirnite i zadržite da biste pomerali vidžet ili koristite prilagođene radnje."</string>
+ <string name="home_screen" msgid="806512411299847073">"Početni ekran"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"Prilagođene radnje"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"Dodirnite i zadržite da biste izabrali vidžet."</string>
+ <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Dvaput dodirnite i zadržite da biste izabrali vidžet ili koristite prilagođene radnje."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d×%2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"širina od %1$d i visina od %2$d"</string>
- <string name="widget_preview_context_description" msgid="9045841361655787574">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g> vidžet"</string>
- <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Dodirnite i zadržite vidžet da biste ga pomerali po početnom ekranu"</string>
- <string name="add_to_home_screen" msgid="8631549138215492708">"Dodaj na početni ekran"</string>
- <string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"Dodali ste vidžet <xliff:g id="WIDGET_NAME">%1$s</xliff:g> na početni ekran"</string>
- <string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# vidžet}one{# vidžet}few{# vidžeta}other{# vidžeta}}"</string>
- <string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{# prečica}one{# prečica}few{# prečice}other{# prečica}}"</string>
- <string name="widgets_and_shortcuts_count" msgid="7209136747878365116">"<xliff:g id="WIDGETS_COUNT">%1$s</xliff:g>, <xliff:g id="SHORTCUTS_COUNT">%2$s</xliff:g>"</string>
- <string name="widget_button_text" msgid="2880537293434387943">"Vidžeti"</string>
- <string name="widgets_full_sheet_search_bar_hint" msgid="8484659090860596457">"Pretražite"</string>
- <string name="widgets_full_sheet_cancel_button_description" msgid="5766167035728653605">"Obrišite tekst iz okvira za pretragu"</string>
- <string name="no_widgets_available" msgid="4337693382501046170">"Vidžeti i prečice nisu dostupni"</string>
- <string name="no_search_results" msgid="3787956167293097509">"Nije pronađen nijedan vidžet ili prečica"</string>
- <string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Lično"</string>
- <string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Posao"</string>
- <string name="widget_category_conversations" msgid="8894438636213590446">"Konverzacije"</string>
- <string name="widget_education_header" msgid="4874760613775913787">"Korisne informacije nadohvat ruke"</string>
- <string name="widget_education_content" msgid="745542879510751525">"Da biste pronašli informacije bez otvaranja aplikacija, možete da dodate vidžete na početni ekran"</string>
- <string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Dodirnite da biste promenili podešavanja vidžeta"</string>
- <string name="widget_education_close_button" msgid="8676165703104836580">"Važi"</string>
- <string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Promenite podešavanja vidžeta"</string>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Dodirnite i zadržite da biste postavili ručno"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"Automatski dodaj"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Pretražite aplikacije"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Aplikacije se učitavaju…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"Nije pronađena nijedna aplikacija za „<xliff:g id="QUERY">%1$s</xliff:g>“"</string>
<string name="all_apps_search_market_message" msgid="1366263386197059176">"Pretraži još aplikacija"</string>
<string name="label_application" msgid="8531721983832654978">"Aplikacija"</string>
- <string name="all_apps_label" msgid="5015784846527570951">"Sve aplikacije"</string>
<string name="notifications_header" msgid="1404149926117359025">"Obaveštenja"</string>
- <string name="long_press_shortcut_to_add" msgid="5405328730817637737">"Dodirnite i zadržite radi pomeranja prečice."</string>
- <string name="long_accessible_way_to_add_shortcut" msgid="2199537273817090740">"Dvaput dodirnite i zadržite da biste pomerali prečicu ili koristite prilagođene radnje."</string>
- <string name="out_of_space" msgid="6692471482459245734">"Nema prostora na ovom početnom ekranu"</string>
+ <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"Dodirnite i zadržite da biste izabrali prečicu."</string>
+ <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"Dvaput dodirnite i zadržite da biste izabrali prečicu ili koristite prilagođene radnje."</string>
+ <string name="out_of_space" msgid="4691004494942118364">"Nema više prostora na ovom početnom ekranu."</string>
<string name="hotseat_out_of_space" msgid="7448809638125333693">"Nema više prostora na traci Omiljeno"</string>
<string name="all_apps_button_label" msgid="8130441508702294465">"Lista aplikacija"</string>
- <string name="all_apps_search_results" msgid="5889367432531296759">"Rezultati pretrage"</string>
<string name="all_apps_button_personal_label" msgid="1315764287305224468">"Lista ličnih aplikacija"</string>
<string name="all_apps_button_work_label" msgid="7270707118948892488">"Lista poslovnih aplikacija"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"Početna"</string>
<string name="remove_drop_target_label" msgid="7812859488053230776">"Ukloni"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"Deinstaliraj"</string>
- <string name="app_info_drop_target_label" msgid="692894985365717661">"Infor. o aplikaciji"</string>
+ <string name="app_info_drop_target_label" msgid="692894985365717661">"Inform. o aplikaciji"</string>
<string name="install_drop_target_label" msgid="2539096853673231757">"Instaliraj"</string>
- <string name="dismiss_prediction_label" msgid="3357562989568808658">"Ne predlaži aplikaciju"</string>
- <string name="pin_prediction" msgid="4196423321649756498">"Zakači predviđanje"</string>
<string name="permlab_install_shortcut" msgid="5632423390354674437">"instaliranje prečica"</string>
<string name="permdesc_install_shortcut" msgid="923466509822011139">"Dozvoljava aplikaciji da dodaje prečice bez intervencije korisnika."</string>
<string name="permlab_read_settings" msgid="1941457408239617576">"čitanje podešavanja i prečica na početnom ekranu"</string>
@@ -84,25 +60,28 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"upisivanje podešavanja i prečica na početnom ekranu"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"Dozvoljava aplikaciji da menja podešavanja i prečice na početnom ekranu."</string>
<string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> nema dozvolu za upućivanje telefonskih poziva"</string>
- <string name="gadget_error_text" msgid="740356548025791839">"Učitavanje vidžeta nije uspelo"</string>
- <string name="gadget_setup_text" msgid="8348374825537681407">"Podešavanja vidžeta"</string>
- <string name="gadget_complete_setup_text" msgid="309040266978007925">"Dodirnite da biste dovršili podešavanje"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"Problem pri učitavanju vidžeta"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"Podešavanje"</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"Ovo je sistemska aplikacija i ne može da se deinstalira."</string>
- <string name="folder_hint_text" msgid="5174843001373488816">"Izmenite naziv"</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"Neimenovani direktorijum"</string>
<string name="disabled_app_label" msgid="6673129024321402780">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> je onemogućena"</string>
- <string name="dotted_app_label" msgid="1704091277755818896">"{count,plural,offset:1 =1{{app_name}, ima # obaveštenje}one{{app_name}, ima # obaveštenje}few{{app_name}, ima # obaveštenja}other{{app_name}, ima # obaveštenja}}"</string>
+ <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+ <item quantity="one"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, ima <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> obaveštenje</item>
+ <item quantity="few"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, ima <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> obaveštenja</item>
+ <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, ima <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> obaveštenja</item>
+ </plurals>
<string name="default_scroll_format" msgid="7475544710230993317">"%1$d. stranica od %2$d"</string>
<string name="workspace_scroll_format" msgid="8458889198184077399">"%1$d. početni ekran od %2$d"</string>
<string name="workspace_new_page" msgid="257366611030256142">"Nova stranica početnog ekrana"</string>
- <string name="folder_opened" msgid="94695026776264709">"Folder je otvoren, <xliff:g id="WIDTH">%1$d</xliff:g> puta <xliff:g id="HEIGHT">%2$d</xliff:g>"</string>
- <string name="folder_tap_to_close" msgid="4625795376335528256">"Dodirnite da biste zatvorili folder"</string>
+ <string name="folder_opened" msgid="94695026776264709">"Direktorijum je otvoren, <xliff:g id="WIDTH">%1$d</xliff:g> puta <xliff:g id="HEIGHT">%2$d</xliff:g>"</string>
+ <string name="folder_tap_to_close" msgid="4625795376335528256">"Dodirnite da biste zatvorili direktorijum"</string>
<string name="folder_tap_to_rename" msgid="4017685068016979677">"Dodirnite da biste sačuvali preimenovanje"</string>
- <string name="folder_closed" msgid="4100806530910930934">"Folder je zatvoren"</string>
- <string name="folder_renamed" msgid="1794088362165669656">"Folder je preimenovan u <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="folder_name_format_exact" msgid="8626242716117004803">"Folder: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> stavke"</string>
- <string name="folder_name_format_overflow" msgid="4270108890534995199">"Folder: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> ili više stavki"</string>
+ <string name="folder_closed" msgid="4100806530910930934">"Direktorijum je zatvoren"</string>
+ <string name="folder_renamed" msgid="1794088362165669656">"Direktorijum je preimenovan u <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"Direktorijum: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"Vidžeti"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Pozadine"</string>
- <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Pozadina i stil"</string>
+ <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Stilovi i pozadine"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Podešavanja početnog ekrana"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Administrator je onemogućio"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Dozvoli rotaciju početnog ekrana"</string>
@@ -114,16 +93,16 @@
<string name="msg_missing_notification_access" msgid="281113995110910548">"Da biste prikazali tačke za obaveštenja, uključite obaveštenja za aplikaciju <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="title_change_settings" msgid="1376365968844349552">"Promenite podešavanja"</string>
<string name="notification_dots_service_title" msgid="4284221181793592871">"Prikazuj tačke za obaveštenja"</string>
- <string name="auto_add_shortcuts_label" msgid="3698776050751790653">"Dodaj ikone aplikacija na početni ekran"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Dodaj ikonu na početni ekran"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Za nove aplikacije"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"Nepoznato"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"Ukloni"</string>
<string name="abandoned_search" msgid="891119232568284442">"Pretraži"</string>
<string name="abandoned_promises_title" msgid="7096178467971716750">"Ova aplikacija nije instalirana"</string>
<string name="abandoned_promise_explanation" msgid="3990027586878167529">"Aplikacija za ovu ikonu nije instalirana. Možete da je uklonite ili da potražite aplikaciju i instalirate je ručno."</string>
- <string name="app_installing_title" msgid="5864044122733792085">"<xliff:g id="NAME">%1$s</xliff:g> se instalira, <xliff:g id="PROGRESS">%2$s</xliff:g> gotovo"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> se preuzima, završeno je <xliff:g id="PROGRESS">%2$s</xliff:g>"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> čeka na instaliranje"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"Vidžeti za <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="widgets_list" msgid="796804551140113767">"Lista vidžeta"</string>
<string name="widgets_list_closed" msgid="6141506579418771922">"Lista vidžeta je zatvorena"</string>
<string name="action_add_to_workspace" msgid="8902165848117513641">"Dodajte na početni ekran"</string>
@@ -136,11 +115,11 @@
<string name="move_to_position" msgid="6750008980455459790">"Premesti na <xliff:g id="NUMBER">%1$s</xliff:g>. poziciju"</string>
<string name="move_to_hotseat_position" msgid="6295412897075147808">"Premesti na <xliff:g id="NUMBER">%1$s</xliff:g>. poziciju u omiljenim"</string>
<string name="item_moved" msgid="4606538322571412879">"Stavka je premeštena"</string>
- <string name="add_to_folder" msgid="9040534766770853243">"Dodaj u folder: <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="add_to_folder_with_app" msgid="4534929978967147231">"Dodaj u folder u kome je <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="added_to_folder" msgid="4793259502305558003">"Stavka je dodata u folder"</string>
- <string name="create_folder_with" msgid="4050141361160214248">"Napravite folder sa: <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="folder_created" msgid="6409794597405184510">"Folder je napravljen"</string>
+ <string name="add_to_folder" msgid="9040534766770853243">"Dodaj u direktorijum: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="add_to_folder_with_app" msgid="4534929978967147231">"Dodaj u direktorijum u kome je <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="added_to_folder" msgid="4793259502305558003">"Stavka je dodata u direktorijum"</string>
+ <string name="create_folder_with" msgid="4050141361160214248">"Napravite direktorijum sa: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="folder_created" msgid="6409794597405184510">"Direktorijum je napravljen"</string>
<string name="action_move_to_workspace" msgid="1603837886334246317">"Premesti na početni ekran"</string>
<string name="action_resize" msgid="1802976324781771067">"Promeni veličinu"</string>
<string name="action_increase_width" msgid="8773715375078513326">"Povećaj širinu"</string>
@@ -151,20 +130,15 @@
<string name="action_deep_shortcut" msgid="2864038805849372848">"Prečice"</string>
<string name="shortcuts_menu_with_notifications_description" msgid="2676582286544232849">"Prečice i obaveštenja"</string>
<string name="action_dismiss_notification" msgid="5909461085055959187">"Odbaci"</string>
- <string name="accessibility_close" msgid="2277148124685870734">"Zatvori"</string>
<string name="notification_dismissed" msgid="6002233469409822874">"Obaveštenje je odbačeno"</string>
<string name="all_apps_personal_tab" msgid="4190252696685155002">"Lične"</string>
<string name="all_apps_work_tab" msgid="4884822796154055118">"Poslovne"</string>
- <string name="work_profile_toggle_label" msgid="3081029915775481146">"Poslovni profil"</string>
- <string name="work_profile_edu_work_apps" msgid="7895468576497746520">"Poslovne aplikacije su označene značkom i IT administrator može da ih vidi"</string>
- <string name="work_profile_edu_accept" msgid="6069788082535149071">"Važi"</string>
- <string name="work_apps_paused_title" msgid="3040901117349444598">"Poslovne aplikacije su pauzirane"</string>
- <string name="work_apps_paused_body" msgid="261634750995824906">"Poslovne aplikacije ne mogu da vam šalju obaveštenja, koriste bateriju niti pristupaju lokaciji"</string>
- <string name="work_apps_paused_content_description" msgid="5149623040804051095">"Poslovne aplikacije su isključene. Poslovne aplikacije ne mogu da vam šalju obaveštenja, koriste bateriju niti pristupaju lokaciji"</string>
- <string name="work_apps_paused_edu_banner" msgid="8872412121608402058">"Poslovne aplikacije su označene značkom i IT administrator može da ih vidi"</string>
- <string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"Važi"</string>
- <string name="work_apps_pause_btn_text" msgid="1921059713673767460">"Isključi poslovne aplikacije"</string>
- <string name="work_apps_enable_btn_text" msgid="1156432622148413741">"Uključi poslovne aplikacije"</string>
- <string name="developer_options_filter_hint" msgid="5896817443635989056">"Filter"</string>
+ <string name="work_profile_toggle_label" msgid="3081029915775481146">"Profil za Work"</string>
+ <string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"Pronađite poslovne aplikacije ovde"</string>
+ <string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"Svaka poslovna aplikacija ima značku i štiti je vaša organizacija. Premestite aplikacije na početni ekran da biste im lakše pristupali."</string>
+ <string name="work_mode_on_label" msgid="4781128097185272916">"Ovim upravlja organizacija"</string>
+ <string name="work_mode_off_label" msgid="3194894777601421047">"Obaveštenja i aplikacije su isključeni"</string>
+ <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Zatvori"</string>
+ <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Zatvoreno"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Nije uspelo: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
</resources>
diff --git a/res/values-be/strings.xml b/res/values-be/strings.xml
index 3d6bde48f6..b4cf913de4 100644
--- a/res/values-be/strings.xml
+++ b/res/values-be/strings.xml
@@ -20,77 +20,57 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="649227358658669779">"Launcher3"</string>
+ <string name="folder_name" msgid="7371454440695724752"></string>
<string name="work_folder_name" msgid="3753320833950115786">"Працоўная"</string>
<string name="activity_not_found" msgid="8071924732094499514">"Праграма не ўсталявана."</string>
<string name="activity_not_available" msgid="7456344436509528827">"Праграма недаступная"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"Спампаваная праграма адключана ў Бяспечным рэжыме"</string>
<string name="safemode_widget_error" msgid="4863470563535682004">"Віджэты адключаны ў Бяспечным рэжыме"</string>
<string name="shortcut_not_available" msgid="2536503539825726397">"Ярлык недаступны"</string>
- <string name="home_screen" msgid="5629429142036709174">"Галоўны экран"</string>
- <string name="recent_task_option_split_screen" msgid="6690461455618725183">"Падзелены экран"</string>
- <string name="split_screen_position_top" msgid="1504965011158689649">"Падзяліць уверсе"</string>
- <string name="split_screen_position_left" msgid="7537793098851830883">"Падзяліць злева"</string>
- <string name="split_screen_position_right" msgid="1569377524925193369">"Падзяліць справа"</string>
- <string name="split_app_info_accessibility" msgid="5475288491241414932">"Інфармацыя пра праграму для: %1$s"</string>
- <string name="long_press_widget_to_add" msgid="3587712543577675817">"Націсніце і ўтрымлівайце віджэт для перамяшчэння."</string>
- <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Дакраніцеся двойчы і ўтрымлівайце, каб перамясціць віджэт або выкарыстоўваць спецыяльныя дзеянні."</string>
+ <string name="home_screen" msgid="806512411299847073">"Галоўны экран"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"Спецыяльныя дзеянні"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"Дакраніцеся і ўтрымлiвайце віджэт, каб выбр. яго."</string>
+ <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Дакраніцеся двойчы і ўтрымлівайце, каб выбраць віджэт або выкарыстоўваць карыстальніцкія дзеянні."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"Шырына: %1$d, вышыня: %2$d"</string>
- <string name="widget_preview_context_description" msgid="9045841361655787574">"Віджэт \"<xliff:g id="WIDGET_NAME">%1$s</xliff:g>\""</string>
- <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Утрымліваючы віджэт націснутым, перамяшчайце яго па Галоўным экране"</string>
- <string name="add_to_home_screen" msgid="8631549138215492708">"Дадаць на Галоўны экран"</string>
- <string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"Віджэт \"<xliff:g id="WIDGET_NAME">%1$s</xliff:g>\" дададзены на галоўны экран"</string>
- <string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# віджэт}one{# віджэт}few{# віджэты}many{# віджэтаў}other{# віджэта}}"</string>
- <string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{# ярлык}one{# ярлык}few{# ярлыкі}many{# ярлыкоў}other{# ярлыка}}"</string>
- <string name="widgets_and_shortcuts_count" msgid="7209136747878365116">"<xliff:g id="WIDGETS_COUNT">%1$s</xliff:g>, <xliff:g id="SHORTCUTS_COUNT">%2$s</xliff:g>"</string>
- <string name="widget_button_text" msgid="2880537293434387943">"Віджэты"</string>
- <string name="widgets_full_sheet_search_bar_hint" msgid="8484659090860596457">"Пошук"</string>
- <string name="widgets_full_sheet_cancel_button_description" msgid="5766167035728653605">"Ачысціць тэкст у полі пошуку"</string>
- <string name="no_widgets_available" msgid="4337693382501046170">"Віджэты і ярлыкі недаступныя"</string>
- <string name="no_search_results" msgid="3787956167293097509">"Віджэтаў і ярлыкоў не знойдзена"</string>
- <string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Асабістыя"</string>
- <string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Працоўныя"</string>
- <string name="widget_category_conversations" msgid="8894438636213590446">"Размовы"</string>
- <string name="widget_education_header" msgid="4874760613775913787">"Карысная інфармацыя ў вас пад рукой"</string>
- <string name="widget_education_content" msgid="745542879510751525">"Каб не адкрываць праграмы для прагляду патрэбнай інфармацыі, дадайце віджэты на галоўны экран"</string>
- <string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Націсніце, каб змяніць налады віджэта"</string>
- <string name="widget_education_close_button" msgid="8676165703104836580">"Зразумела"</string>
- <string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Змяніць налады віджэта"</string>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Каб размясціць уручную, дакраніцеся і ўтрымлівайце"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"Дадаць аўтаматычна"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Пошук праграм"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Праграмы загружаюцца…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"Праграм, якія адпавядаюць запыту \"<xliff:g id="QUERY">%1$s</xliff:g>\", не знойдзена"</string>
<string name="all_apps_search_market_message" msgid="1366263386197059176">"Шукаць іншыя праграмы"</string>
<string name="label_application" msgid="8531721983832654978">"Праграма"</string>
- <string name="all_apps_label" msgid="5015784846527570951">"Усе праграмы"</string>
<string name="notifications_header" msgid="1404149926117359025">"Апавяшчэнні"</string>
- <string name="long_press_shortcut_to_add" msgid="5405328730817637737">"Націсніце і ўтрымлівайце ярлык для перамяшчэння."</string>
- <string name="long_accessible_way_to_add_shortcut" msgid="2199537273817090740">"Дакраніцеся двойчы і ўтрымлівайце, каб перамясціць ярлык або выкарыстоўваць спецыяльныя дзеянні."</string>
- <string name="out_of_space" msgid="6692471482459245734">"На галоўным экране няма месца"</string>
+ <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"Дакраніцеся і ўтрымлiвайце ярлык, каб дадаць яго."</string>
+ <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"Дакраніцеся двойчы і ўтрымлівайце, каб выбраць ярлык або выкарыстоўваць спецыяльныя дзеянні."</string>
+ <string name="out_of_space" msgid="4691004494942118364">"На гэтым Галоўным экране больш няма месца."</string>
<string name="hotseat_out_of_space" msgid="7448809638125333693">"У латку \"Абранае\" больш няма месца"</string>
<string name="all_apps_button_label" msgid="8130441508702294465">"Спіс праграм"</string>
- <string name="all_apps_search_results" msgid="5889367432531296759">"Вынікі пошуку"</string>
<string name="all_apps_button_personal_label" msgid="1315764287305224468">"Спіс персанальных праграм"</string>
<string name="all_apps_button_work_label" msgid="7270707118948892488">"Спіс працоўных праграм"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"Галоўная"</string>
<string name="remove_drop_target_label" msgid="7812859488053230776">"Выдаліць"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"Дэінсталяваць"</string>
- <string name="app_info_drop_target_label" msgid="692894985365717661">"Пра праграму"</string>
+ <string name="app_info_drop_target_label" msgid="692894985365717661">"Звесткі пра праграмы"</string>
<string name="install_drop_target_label" msgid="2539096853673231757">"Усталяваць"</string>
- <string name="dismiss_prediction_label" msgid="3357562989568808658">"Не прапаноўваць праграму"</string>
- <string name="pin_prediction" msgid="4196423321649756498">"Замацаваць прапанаваную праграму"</string>
- <string name="permlab_install_shortcut" msgid="5632423390354674437">"Стварэнне ярлыкоў"</string>
+ <string name="permlab_install_shortcut" msgid="5632423390354674437">"усталёўваць ярлыкі"</string>
<string name="permdesc_install_shortcut" msgid="923466509822011139">"Дазваляе праграмам дадаваць ярлыкі без умяшання карыстальніка."</string>
<string name="permlab_read_settings" msgid="1941457408239617576">"счытваць налады і ярлыкі на Галоўнай старонцы"</string>
<string name="permdesc_read_settings" msgid="5833423719057558387">"Дазваляе праграме счытваць налады і ярлыкі на Галоўнай старонцы."</string>
<string name="permlab_write_settings" msgid="3574213698004620587">"запісваць налады і ярлыкі на галоўнай старонцы"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"Дазваляе праграме змяняць налады і ярлыкі на Галоўнай старонцы."</string>
<string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> не мае дазволу на здзяйсненне тэлефонных званкоў"</string>
- <string name="gadget_error_text" msgid="740356548025791839">"Не ўдаецца загрузіць віджэт"</string>
- <string name="gadget_setup_text" msgid="8348374825537681407">"Налады віджэта"</string>
- <string name="gadget_complete_setup_text" msgid="309040266978007925">"Націсніце, каб завяршыць наладжванне"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"Праблема загрузкі віджэта"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"Наладжванне"</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"Гэта сістэмная праграма, яе нельга выдаліць."</string>
- <string name="folder_hint_text" msgid="5174843001373488816">"Змяніць назву"</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"Папка без назвы"</string>
<string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> адключана"</string>
- <string name="dotted_app_label" msgid="1704091277755818896">"{count,plural,offset:1 =1{У праграмы \"{app_name}\" ёсць # апавяшчэнне}one{У праграмы \"{app_name}\" ёсць # апавяшчэнне}few{У праграмы \"{app_name}\" ёсць # апавяшчэнні}many{У праграмы \"{app_name}\" ёсць # апавяшчэнняў}other{У праграмы \"{app_name}\" ёсць # апавяшчэння}}"</string>
+ <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+ <item quantity="one"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, мае <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> апавяшчэнне</item>
+ <item quantity="few"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, мае <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> апавяшчэнні</item>
+ <item quantity="many"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, мае <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> апавяшчэнняў</item>
+ <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, мае <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> апавяшчэння</item>
+ </plurals>
<string name="default_scroll_format" msgid="7475544710230993317">"Старонка %1$d з %2$d"</string>
<string name="workspace_scroll_format" msgid="8458889198184077399">"Галоўны экран %1$d з %2$d"</string>
<string name="workspace_new_page" msgid="257366611030256142">"Новая старонка галоўнага экрана"</string>
@@ -99,10 +79,10 @@
<string name="folder_tap_to_rename" msgid="4017685068016979677">"Краніце, каб захаваць новую назву"</string>
<string name="folder_closed" msgid="4100806530910930934">"Папка закрыта"</string>
<string name="folder_renamed" msgid="1794088362165669656">"Папка перайменавана ў <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="folder_name_format_exact" msgid="8626242716117004803">"Папка: <xliff:g id="NAME">%1$s</xliff:g>, элементы: <xliff:g id="SIZE">%2$d</xliff:g>"</string>
- <string name="folder_name_format_overflow" msgid="4270108890534995199">"Папка: <xliff:g id="NAME">%1$s</xliff:g>, элементы: <xliff:g id="SIZE">%2$d</xliff:g> ці больш"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"Папка: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"Віджэты"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Шпалеры"</string>
- <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Шпалеры і стыль"</string>
+ <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Стылі і шпалеры"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Налады галоўнага экрана"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Адключаная адміністратарам"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Дазволіць паварот галоўнага экрана"</string>
@@ -114,16 +94,16 @@
<string name="msg_missing_notification_access" msgid="281113995110910548">"Каб паказваліся значкі апавяшчэнняў, уключыце апавяшчэнні праграм для <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="title_change_settings" msgid="1376365968844349552">"Змяніць налады"</string>
<string name="notification_dots_service_title" msgid="4284221181793592871">"Паказваць значкі апавяшчэнняў"</string>
- <string name="auto_add_shortcuts_label" msgid="3698776050751790653">"Дадаваць значкі праграм на Галоўны экран"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Дадаць значок на Галоўны экран"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Для новых праграм"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"Невядома"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"Выдаліць"</string>
<string name="abandoned_search" msgid="891119232568284442">"Шукаць"</string>
<string name="abandoned_promises_title" msgid="7096178467971716750">"Гэта праграма не ўсталявана"</string>
<string name="abandoned_promise_explanation" msgid="3990027586878167529">"Праграма для гэтага значка не ўсталявана. Вы можаце выдаліць яе або выканаць пошук і ўсталяваць яе ўручную."</string>
- <string name="app_installing_title" msgid="5864044122733792085">"Усталёўваецца праграма \"<xliff:g id="NAME">%1$s</xliff:g>\", завершана <xliff:g id="PROGRESS">%2$s</xliff:g>"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"Ідзе спампоўка <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="PROGRESS">%2$s</xliff:g> завершана"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> чакае ўсталёўкі"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"Віджэты <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="widgets_list" msgid="796804551140113767">"Спіс віджэтаў"</string>
<string name="widgets_list_closed" msgid="6141506579418771922">"Спіс віджэтаў закрыты"</string>
<string name="action_add_to_workspace" msgid="8902165848117513641">"Дадаць на Галоўны экран"</string>
@@ -151,20 +131,15 @@
<string name="action_deep_shortcut" msgid="2864038805849372848">"Ярлыкі"</string>
<string name="shortcuts_menu_with_notifications_description" msgid="2676582286544232849">"Ярлыкі і апавяшчэнні"</string>
<string name="action_dismiss_notification" msgid="5909461085055959187">"Адхіліць"</string>
- <string name="accessibility_close" msgid="2277148124685870734">"Закрыць"</string>
<string name="notification_dismissed" msgid="6002233469409822874">"Апавяшчэнне адхілена"</string>
<string name="all_apps_personal_tab" msgid="4190252696685155002">"Асабістыя"</string>
- <string name="all_apps_work_tab" msgid="4884822796154055118">"Працоўныя"</string>
+ <string name="all_apps_work_tab" msgid="4884822796154055118">"Праца"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"Працоўны профіль"</string>
- <string name="work_profile_edu_work_apps" msgid="7895468576497746520">"Працоўныя праграмы пазначаны спецыяльнымі значкамі, а таксама бачныя IT-адміністратару"</string>
- <string name="work_profile_edu_accept" msgid="6069788082535149071">"Зразумела"</string>
- <string name="work_apps_paused_title" msgid="3040901117349444598">"Працоўныя праграмы прыпынены"</string>
- <string name="work_apps_paused_body" msgid="261634750995824906">"Працоўныя праграмы не могуць адпраўляць вам апавяшчэнні, выкарыстоўваць акумулятар або атрымліваць доступ да даных пра ваша месцазнаходжанне"</string>
- <string name="work_apps_paused_content_description" msgid="5149623040804051095">"Працоўныя праграмы выключаны. Яны не могуць адпраўляць вам апавяшчэнні, выкарыстоўваць акумулятар або атрымліваць доступ да вашага месцазнаходжання"</string>
- <string name="work_apps_paused_edu_banner" msgid="8872412121608402058">"Працоўныя праграмы пазначаны спецыяльнымі значкамі, а таксама бачныя IT-адміністратару"</string>
- <string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"Зразумела"</string>
- <string name="work_apps_pause_btn_text" msgid="1921059713673767460">"Выключыць працоўныя праграмы"</string>
- <string name="work_apps_enable_btn_text" msgid="1156432622148413741">"Уключыць працоўныя праграмы"</string>
- <string name="developer_options_filter_hint" msgid="5896817443635989056">"Фільтр"</string>
+ <string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"Знайдзіце працоўныя праграмы тут"</string>
+ <string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"Кожная працоўная праграма мае значок і знаходзіцца пад аховай вашай арганізацыі. Для больш простага доступу перамясціце праграмы на Галоўны экран."</string>
+ <string name="work_mode_on_label" msgid="4781128097185272916">"Пад кіраваннем вашай арганізацыі"</string>
+ <string name="work_mode_off_label" msgid="3194894777601421047">"Апавяшчэнні і праграмы выключаны"</string>
+ <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Закрыць"</string>
+ <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Закрытыя"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Не ўдалося: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
</resources>
diff --git a/res/values-bg/strings.xml b/res/values-bg/strings.xml
index 661c710aad..408f205004 100644
--- a/res/values-bg/strings.xml
+++ b/res/values-bg/strings.xml
@@ -20,63 +20,39 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="649227358658669779">"Launcher3"</string>
+ <string name="folder_name" msgid="7371454440695724752"></string>
<string name="work_folder_name" msgid="3753320833950115786">"Работа"</string>
<string name="activity_not_found" msgid="8071924732094499514">"Приложението не е инсталирано."</string>
<string name="activity_not_available" msgid="7456344436509528827">"Приложението не е налично"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"Изтегленото приложение е деактивирано в безопасния режим"</string>
<string name="safemode_widget_error" msgid="4863470563535682004">"Приспособленията са деактивирани в безопасния режим"</string>
<string name="shortcut_not_available" msgid="2536503539825726397">"Няма достъп до прекия път"</string>
- <string name="home_screen" msgid="5629429142036709174">"Начален екран"</string>
- <string name="recent_task_option_split_screen" msgid="6690461455618725183">"Разделен екран"</string>
- <string name="split_screen_position_top" msgid="1504965011158689649">"Разделяне в горната част"</string>
- <string name="split_screen_position_left" msgid="7537793098851830883">"Разделяне в лявата част"</string>
- <string name="split_screen_position_right" msgid="1569377524925193369">"Разделяне в дясната част"</string>
- <string name="split_app_info_accessibility" msgid="5475288491241414932">"Информация за приложението за %1$s"</string>
- <string name="long_press_widget_to_add" msgid="3587712543577675817">"Докоснете и задръжте за преместване на приспособление"</string>
- <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Докоснете двукратно и задръжте за преместване на приспособление или използвайте персонал. действия."</string>
+ <string name="home_screen" msgid="806512411299847073">"Начален екран"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"Персонализирани действия"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"Докоснете и задръжте за избор на приспособление."</string>
+ <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Докоснете двукратно и задръжте за избор на приспособление или използвайте персонализирани действия."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"Ширина %1$d и височина %2$d"</string>
- <string name="widget_preview_context_description" msgid="9045841361655787574">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g> приспособление"</string>
- <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Докоснете приспособлението и го задръжте, за да го местите по началния екран"</string>
- <string name="add_to_home_screen" msgid="8631549138215492708">"Добавяне към началния екран"</string>
- <string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"Приспособлението <xliff:g id="WIDGET_NAME">%1$s</xliff:g> е добавено към началния екран"</string>
- <string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# приспособление}other{# приспособления}}"</string>
- <string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{# пряк път}other{# преки пътя}}"</string>
- <string name="widgets_and_shortcuts_count" msgid="7209136747878365116">"<xliff:g id="WIDGETS_COUNT">%1$s</xliff:g>, <xliff:g id="SHORTCUTS_COUNT">%2$s</xliff:g>"</string>
- <string name="widget_button_text" msgid="2880537293434387943">"Приспособления"</string>
- <string name="widgets_full_sheet_search_bar_hint" msgid="8484659090860596457">"Търсене"</string>
- <string name="widgets_full_sheet_cancel_button_description" msgid="5766167035728653605">"Изчистване на текста от полето за търсене"</string>
- <string name="no_widgets_available" msgid="4337693382501046170">"Няма налице преки пътища и приспособления"</string>
- <string name="no_search_results" msgid="3787956167293097509">"Няма открити преки пътища или приспособления"</string>
- <string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Лични"</string>
- <string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Служебни"</string>
- <string name="widget_category_conversations" msgid="8894438636213590446">"Разговори"</string>
- <string name="widget_education_header" msgid="4874760613775913787">"Лесен достъп до полезна информация"</string>
- <string name="widget_education_content" msgid="745542879510751525">"За да получавате информация, без да отваряте приложенията, можете да добавите приспособления към началния екран"</string>
- <string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Докоснете, за да промените настройките на приспособлението"</string>
- <string name="widget_education_close_button" msgid="8676165703104836580">"Разбрах"</string>
- <string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Промяна на настройките на приспособлението"</string>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Докоснете и задръжте, за да поставите ръчно"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"Автоматично добавяне"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Търсене в приложенията"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Приложенията се зареждат…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"Няма намерени приложения, съответстващи на „<xliff:g id="QUERY">%1$s</xliff:g>“"</string>
<string name="all_apps_search_market_message" msgid="1366263386197059176">"Търсене на още приложения"</string>
<string name="label_application" msgid="8531721983832654978">"Приложение"</string>
- <string name="all_apps_label" msgid="5015784846527570951">"Всички приложения"</string>
<string name="notifications_header" msgid="1404149926117359025">"Известия"</string>
- <string name="long_press_shortcut_to_add" msgid="5405328730817637737">"Докоснете и задръжте за преместване на пряк път."</string>
- <string name="long_accessible_way_to_add_shortcut" msgid="2199537273817090740">"Докоснете двукратно и задръжте за преместване на пряк път или използвайте персонализирани действия."</string>
- <string name="out_of_space" msgid="6692471482459245734">"Няма място на този начален екран"</string>
+ <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"Докоснете и задръжте за избор на пряк път."</string>
+ <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"Докоснете двукратно и задръжте за избор на пряк път или използвайте персонализирани действия."</string>
+ <string name="out_of_space" msgid="4691004494942118364">"На този начален екран няма повече място."</string>
<string name="hotseat_out_of_space" msgid="7448809638125333693">"Няма повече място в областта с любимите"</string>
<string name="all_apps_button_label" msgid="8130441508702294465">"Списък с приложения"</string>
- <string name="all_apps_search_results" msgid="5889367432531296759">"Резултати от търсенето"</string>
<string name="all_apps_button_personal_label" msgid="1315764287305224468">"Списък с лични приложения"</string>
<string name="all_apps_button_work_label" msgid="7270707118948892488">"Списък със служебни приложения"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"Начало"</string>
<string name="remove_drop_target_label" msgid="7812859488053230776">"Премахване"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"Деинсталиране"</string>
- <string name="app_info_drop_target_label" msgid="692894985365717661">"Информация за прилож."</string>
+ <string name="app_info_drop_target_label" msgid="692894985365717661">"Данни за прилож."</string>
<string name="install_drop_target_label" msgid="2539096853673231757">"Инсталиране"</string>
- <string name="dismiss_prediction_label" msgid="3357562989568808658">"Без предлагане на приложение"</string>
- <string name="pin_prediction" msgid="4196423321649756498">"Фиксиране на предвиждането"</string>
<string name="permlab_install_shortcut" msgid="5632423390354674437">"инсталиране на преки пътища"</string>
<string name="permdesc_install_shortcut" msgid="923466509822011139">"Разрешава на приложението да добавя преки пътища без намеса на потребителя."</string>
<string name="permlab_read_settings" msgid="1941457408239617576">"четене на настройките и преките пътища в Начало"</string>
@@ -84,13 +60,15 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"запис на настройките и преките пътища в Начало"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"Разрешава на приложението да променя настройките и преките пътища в Начало."</string>
<string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> няма разрешение да извършва телефонни обаждания"</string>
- <string name="gadget_error_text" msgid="740356548025791839">"Приспособлението не може да се зареди"</string>
- <string name="gadget_setup_text" msgid="8348374825537681407">"Настройки за приспособленията"</string>
- <string name="gadget_complete_setup_text" msgid="309040266978007925">"Докоснете, за да завършите настройването"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"Проблем при зареждане на приспособлението"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"Настройване"</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"Това е системно приложение и не може да се деинсталира."</string>
- <string name="folder_hint_text" msgid="5174843001373488816">"Редактиране на името"</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"Папка без име"</string>
<string name="disabled_app_label" msgid="6673129024321402780">"Деактивирахте <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
- <string name="dotted_app_label" msgid="1704091277755818896">"{count,plural,offset:1 =1{{app_name} има # известие}other{{app_name} има # известия}}"</string>
+ <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+ <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g> – има <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> известия</item>
+ <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g> – има <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> известие</item>
+ </plurals>
<string name="default_scroll_format" msgid="7475544710230993317">"Страница %1$d от %2$d"</string>
<string name="workspace_scroll_format" msgid="8458889198184077399">"Начален екран %1$d от %2$d"</string>
<string name="workspace_new_page" msgid="257366611030256142">"Нова страница на началния екран"</string>
@@ -99,10 +77,10 @@
<string name="folder_tap_to_rename" msgid="4017685068016979677">"Докоснете, за да запазите новото име"</string>
<string name="folder_closed" msgid="4100806530910930934">"Папката бе затворена"</string>
<string name="folder_renamed" msgid="1794088362165669656">"Папката е преименувана на „<xliff:g id="NAME">%1$s</xliff:g>“"</string>
- <string name="folder_name_format_exact" msgid="8626242716117004803">"Папка: „<xliff:g id="NAME">%1$s</xliff:g>“ – <xliff:g id="SIZE">%2$d</xliff:g> елемента"</string>
- <string name="folder_name_format_overflow" msgid="4270108890534995199">"Папка: „<xliff:g id="NAME">%1$s</xliff:g>“ – <xliff:g id="SIZE">%2$d</xliff:g> или повече елементи"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"Папка: „<xliff:g id="NAME">%1$s</xliff:g>“"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"Приспособления"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Тапети"</string>
- <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Тапет и стил"</string>
+ <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Стилове и тапети"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Настройки за началния екран"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Деактивирано от администратора ви"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Разрешаване на завъртането на началния екран"</string>
@@ -114,16 +92,16 @@
<string name="msg_missing_notification_access" msgid="281113995110910548">"За да се показват точки за известия, включете известията за приложението <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="title_change_settings" msgid="1376365968844349552">"Промяна на настройките"</string>
<string name="notification_dots_service_title" msgid="4284221181793592871">"Показване на точките за известия"</string>
- <string name="auto_add_shortcuts_label" msgid="3698776050751790653">"Добавяне на икони на прил. на нач. екран"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Добавяне на икона към началния екран"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"За нови приложения"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"Няма информация"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"Премахване"</string>
<string name="abandoned_search" msgid="891119232568284442">"Търсене"</string>
<string name="abandoned_promises_title" msgid="7096178467971716750">"Това приложение не е инсталирано"</string>
<string name="abandoned_promise_explanation" msgid="3990027586878167529">"Приложението за тази икона не е инсталирано. Можете да я премахнете или да потърсите приложението и да го инсталирате ръчно."</string>
- <string name="app_installing_title" msgid="5864044122733792085">"<xliff:g id="NAME">%1$s</xliff:g> се инсталира, <xliff:g id="PROGRESS">%2$s</xliff:g> завършено"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> се изтегля. Завършено: <xliff:g id="PROGRESS">%2$s</xliff:g>"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> изчаква инсталиране"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"Приспособления за <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="widgets_list" msgid="796804551140113767">"Списък с приспособления"</string>
<string name="widgets_list_closed" msgid="6141506579418771922">"Списъкът с приспособления е затворен"</string>
<string name="action_add_to_workspace" msgid="8902165848117513641">"Добавяне към началния екран"</string>
@@ -151,20 +129,15 @@
<string name="action_deep_shortcut" msgid="2864038805849372848">"Преки пътища"</string>
<string name="shortcuts_menu_with_notifications_description" msgid="2676582286544232849">"Преки пътища и известия"</string>
<string name="action_dismiss_notification" msgid="5909461085055959187">"Отхвърляне"</string>
- <string name="accessibility_close" msgid="2277148124685870734">"Затваряне"</string>
<string name="notification_dismissed" msgid="6002233469409822874">"Известието е отхвърлено"</string>
<string name="all_apps_personal_tab" msgid="4190252696685155002">"Лични"</string>
<string name="all_apps_work_tab" msgid="4884822796154055118">"Служебни"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"Служебен потребителски профил"</string>
- <string name="work_profile_edu_work_apps" msgid="7895468576497746520">"Служебните приложения са означени със значка и са видими за системния администратор"</string>
- <string name="work_profile_edu_accept" msgid="6069788082535149071">"Разбрах"</string>
- <string name="work_apps_paused_title" msgid="3040901117349444598">"Служебните приложения са поставени на пауза"</string>
- <string name="work_apps_paused_body" msgid="261634750995824906">"Служебните ви приложения не могат да ви изпращат известия, да използват батерията или да осъществяват достъп до местоположението ви"</string>
- <string name="work_apps_paused_content_description" msgid="5149623040804051095">"Служебните ви приложения са изключени. Те не могат да ви изпращат известия, да използват батерията или да осъществяват достъп до местоположението ви"</string>
- <string name="work_apps_paused_edu_banner" msgid="8872412121608402058">"Служебните приложения са означени със значка и са видими за системния администратор"</string>
- <string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"Разбрах"</string>
- <string name="work_apps_pause_btn_text" msgid="1921059713673767460">"Изключване на служебните приложения"</string>
- <string name="work_apps_enable_btn_text" msgid="1156432622148413741">"Включване на служебните приложения"</string>
- <string name="developer_options_filter_hint" msgid="5896817443635989056">"Филтър"</string>
+ <string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"Тук можете да намерите служебните приложения"</string>
+ <string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"Всяко служебно приложение има значка и организацията ви се грижи за сигурността му. За по-лесен достъп преместете приложенията на началния си екран."</string>
+ <string name="work_mode_on_label" msgid="4781128097185272916">"Управлява се от организацията ви"</string>
+ <string name="work_mode_off_label" msgid="3194894777601421047">"Известията и приложенията са изключени"</string>
+ <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Затваряне"</string>
+ <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Затворено"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Неуспешно: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
</resources>
diff --git a/res/values-bn/strings.xml b/res/values-bn/strings.xml
index 299a0147d5..09608b5426 100644
--- a/res/values-bn/strings.xml
+++ b/res/values-bn/strings.xml
@@ -26,57 +26,32 @@
<string name="safemode_shortcut_error" msgid="9160126848219158407">"ডাউনলোড করা অ্যাপ্লিকেশান নিরাপদ মোডে অক্ষম রয়েছে"</string>
<string name="safemode_widget_error" msgid="4863470563535682004">"সুরক্ষিত মোডে উইজেট নিষ্ক্রিয় থাকে"</string>
<string name="shortcut_not_available" msgid="2536503539825726397">"শর্টকাটগুলি অনুপলব্ধ"</string>
- <string name="home_screen" msgid="5629429142036709174">"হোম"</string>
- <string name="recent_task_option_split_screen" msgid="6690461455618725183">"স্প্লিট স্ক্রিন"</string>
- <string name="split_screen_position_top" msgid="1504965011158689649">"স্ক্রিনের উপরের দিকে স্প্লিট করুন"</string>
- <string name="split_screen_position_left" msgid="7537793098851830883">"স্ক্রিনের বাঁদিকে স্প্লিট করুন"</string>
- <string name="split_screen_position_right" msgid="1569377524925193369">"স্ক্রিনের ডানদিকে স্প্লিট করুন"</string>
- <string name="split_app_info_accessibility" msgid="5475288491241414932">"%1$s-এর জন্য অ্যাপ সম্পর্কিত তথ্য"</string>
- <string name="long_press_widget_to_add" msgid="3587712543577675817">"কোনও উইজেট সরাতে সেটি টাচ করে ধরে রাখুন।"</string>
- <string name="long_accessible_way_to_add" msgid="2733588281439571974">"একটি উইজেট সরাতে বা কাস্টম অ্যাকশন ব্যবহার করতে ডবল ট্যাপ করে ধরে রাখুন।"</string>
+ <string name="home_screen" msgid="806512411299847073">"হোম স্ক্রিন"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"কাস্টম অ্যাকশন"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"একটি উইজেট তুলতে তা স্পর্শ করে ধরে রাখুন৷"</string>
+ <string name="long_accessible_way_to_add" msgid="4289502106628154155">"কোনো উইজেট বেছে নিতে দুবার-আলতো চেপে ধরে থাকুন অথবা কাস্টম ক্রিয়াগুলি ব্যবহার করুন৷"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%2$d উচ্চতা অনুযায়ী %1$d প্রস্থ"</string>
- <string name="widget_preview_context_description" msgid="9045841361655787574">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g>টি উইজেট"</string>
- <string name="add_item_request_drag_hint" msgid="5653291305078645405">"হোম স্ক্রিনের যেকোনও জায়গায় উইজেটটি নিয়ে যেতে, টাচ করে ধরে থাকুন"</string>
- <string name="add_to_home_screen" msgid="8631549138215492708">"হোম স্ক্রিনে যোগ করুন"</string>
- <string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g> উইজেট হোম স্ক্রিনে যোগ করা হয়েছে"</string>
- <string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{#টি উইজেট}one{#টি উইজেট}other{#টি উইজেট}}"</string>
- <string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{#টি শর্টকাট}one{#টি শর্টকাট}other{#টি শর্টকাট}}"</string>
- <string name="widgets_and_shortcuts_count" msgid="7209136747878365116">"<xliff:g id="WIDGETS_COUNT">%1$s</xliff:g>, <xliff:g id="SHORTCUTS_COUNT">%2$s</xliff:g>"</string>
- <string name="widget_button_text" msgid="2880537293434387943">"উইজেট"</string>
- <string name="widgets_full_sheet_search_bar_hint" msgid="8484659090860596457">"সার্চ করুন"</string>
- <string name="widgets_full_sheet_cancel_button_description" msgid="5766167035728653605">"সার্চ বক্স থেকে টেক্সট মুছুন"</string>
- <string name="no_widgets_available" msgid="4337693382501046170">"উইজেট এবং শর্টকার্ট উপলভ্য নেই"</string>
- <string name="no_search_results" msgid="3787956167293097509">"কোনও উইজেট বা শর্টকার্ট খুঁজে পাওয়া যায়নি"</string>
- <string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"ব্যক্তিগত"</string>
- <string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"অফিস"</string>
- <string name="widget_category_conversations" msgid="8894438636213590446">"কথোপকথন"</string>
- <string name="widget_education_header" msgid="4874760613775913787">"সহজেই দরকারি তথ্য পান"</string>
- <string name="widget_education_content" msgid="745542879510751525">"অ্যাপ না খুলে তথ্য পাওয়ার জন্য, আপনার হোম স্ক্রিনে উইজেট যোগ করতে পারেন"</string>
- <string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"উইজেট সেটিংস পরিবর্তন করতে ট্যাপ করুন"</string>
- <string name="widget_education_close_button" msgid="8676165703104836580">"বুঝেছি"</string>
- <string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"উইজেট সেটিংস পরিবর্তন করুন"</string>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"নিজে যোগ করতে টাচ করে ধরে রাখুন"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"স্বয়ংক্রিয়ভাবে যোগ করুন"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"অ্যাপ খুঁজুন"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"অ্যাপ লোড হচ্ছে…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" এর সাথে মেলে এমন কোনো অ্যাপ পাওয়া যায়নি"</string>
<string name="all_apps_search_market_message" msgid="1366263386197059176">"আরও অ্যাপ্লিকেশানের জন্য খুঁজুন"</string>
<string name="label_application" msgid="8531721983832654978">"অ্যাপ"</string>
- <string name="all_apps_label" msgid="5015784846527570951">"সব অ্যাপ"</string>
<string name="notifications_header" msgid="1404149926117359025">"বিজ্ঞপ্তি"</string>
- <string name="long_press_shortcut_to_add" msgid="5405328730817637737">"একটি শর্টকাট সরাতে টাচ করে ধরে রাখুন।"</string>
- <string name="long_accessible_way_to_add_shortcut" msgid="2199537273817090740">"একটি শর্টকাট সরাতে বা কাস্টম অ্যাকশন ব্যবহার করতে ডবল ট্যাপ করে ধরে রাখুন।"</string>
- <string name="out_of_space" msgid="6692471482459245734">"এই হোম স্ক্রিনে আর জায়গা খালি নেই"</string>
+ <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"কোনও শর্টকাট বেছে নিতে টাচ করে ধরে থাকুন।"</string>
+ <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"কোনও শর্টকাট বেছে নিতে ডবল ট্যাপ করে ধরে থাকুন অথবা কাস্টম অ্যাকশন ব্যবহার করুন।"</string>
+ <string name="out_of_space" msgid="4691004494942118364">"এই হোম স্ক্রীনে আর কোনো জায়গা নেই৷"</string>
<string name="hotseat_out_of_space" msgid="7448809638125333693">"পছন্দসই ট্রে-তে আর কোনো জায়গা নেই"</string>
<string name="all_apps_button_label" msgid="8130441508702294465">"অ্যাপ্লিকেশানগুলির তালিকা"</string>
- <string name="all_apps_search_results" msgid="5889367432531296759">"সার্চ ফলাফল"</string>
<string name="all_apps_button_personal_label" msgid="1315764287305224468">"ব্যক্তিগত অ্যাপের তালিকা"</string>
<string name="all_apps_button_work_label" msgid="7270707118948892488">"কাজের অ্যাপের তালিকা"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"হোম"</string>
<string name="remove_drop_target_label" msgid="7812859488053230776">"সরান"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"আনইনস্টল করুন"</string>
<string name="app_info_drop_target_label" msgid="692894985365717661">"অ্যাপের তথ্য"</string>
<string name="install_drop_target_label" msgid="2539096853673231757">"ইনস্টল করুন"</string>
- <string name="dismiss_prediction_label" msgid="3357562989568808658">"অ্যাপ সাজেস্ট করবেন না"</string>
- <string name="pin_prediction" msgid="4196423321649756498">"আপনার প্রয়োজন হতে পারে এমন অ্যাপ পিন করুন"</string>
<string name="permlab_install_shortcut" msgid="5632423390354674437">"শর্টকাটগুলি ইনস্টল করে"</string>
<string name="permdesc_install_shortcut" msgid="923466509822011139">"একটি অ্যাপ্লিকেশানকে ব্যবহারকারীর হস্তক্ষেপ ছাড়াই শর্টকাটগুলি যোগ করার অনুমতি দেয়৷"</string>
<string name="permlab_read_settings" msgid="1941457408239617576">"হোম সেটিংস এবং শর্টকাটগুলি পড়ে"</string>
@@ -84,13 +59,15 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"হোম সেটিংস এবং শর্টকাটগুলি লেখে"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"হোমে অ্যাপ্লিকেশানটিকে সেটিংস এবং শর্টকাটগুলি পরিবর্তন করতে দেয়৷"</string>
<string name="msg_no_phone_permission" msgid="9208659281529857371">"ফোন কলগুলি করার জন্য <xliff:g id="APP_NAME">%1$s</xliff:g> এর অনুমতি নেই"</string>
- <string name="gadget_error_text" msgid="740356548025791839">"উইজেট লোড করা যাচ্ছে না"</string>
- <string name="gadget_setup_text" msgid="8348374825537681407">"উইজেট সেটিংস"</string>
- <string name="gadget_complete_setup_text" msgid="309040266978007925">"সেটআপ সম্পূর্ণ করতে ট্যাপ করুন"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"উইজেট লোড হতে সমস্যা হয়েছে"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"সেটআপ"</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"এটি একটি সিস্টেম অ্যাপ্লিকেশান এবং আনইনস্টল করা যাবে না৷"</string>
- <string name="folder_hint_text" msgid="5174843001373488816">"নাম এডিট করুন"</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"নামবিহীন ফোল্ডার"</string>
<string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> অক্ষম করা হয়েছে"</string>
- <string name="dotted_app_label" msgid="1704091277755818896">"{count,plural,offset:1 =1{{app_name}-এর #টি বিজ্ঞপ্তি আছে}one{{app_name}-এর #টি বিজ্ঞপ্তি আছে}other{{app_name}-এর #টি বিজ্ঞপ্তি আছে}}"</string>
+ <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+ <item quantity="one"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g>টি বিজ্ঞপ্তি আছে</item>
+ <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g>টি বিজ্ঞপ্তি আছে</item>
+ </plurals>
<string name="default_scroll_format" msgid="7475544710230993317">"%2$dটির মধ্যে %1$dটি পৃষ্ঠা"</string>
<string name="workspace_scroll_format" msgid="8458889198184077399">"%2$dটির %1$d নম্বর হোম স্ক্রিন"</string>
<string name="workspace_new_page" msgid="257366611030256142">"নতুন হোম স্ক্রীনের পৃষ্ঠা"</string>
@@ -99,10 +76,10 @@
<string name="folder_tap_to_rename" msgid="4017685068016979677">"পুনঃনামকরণ সংরক্ষণ করতে আলতো চাপ দিন"</string>
<string name="folder_closed" msgid="4100806530910930934">"ফোল্ডার বন্ধ করা হয়েছে"</string>
<string name="folder_renamed" msgid="1794088362165669656">"ফোল্ডারের নাম পাল্টে <xliff:g id="NAME">%1$s</xliff:g> করা হয়েছে"</string>
- <string name="folder_name_format_exact" msgid="8626242716117004803">"ফোল্ডার: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g>টি আইটেম"</string>
- <string name="folder_name_format_overflow" msgid="4270108890534995199">"ফোল্ডার: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g>টি বা তার বেশি আইটেম"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"ফোল্ডার: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"উইজেট"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"ওয়ালপেপারগুলি"</string>
- <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"ওয়ালপেপার এবং স্টাইল"</string>
+ <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"স্টাইল এবং ওয়ালপেপার"</string>
<string name="settings_button_text" msgid="8873672322605444408">"হোম সেটিংস"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"আপনার প্রশাসক দ্বারা অক্ষম করা হয়েছে"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"হোম স্ক্রিন ঘোরানোর অনুমতি দিন"</string>
@@ -114,23 +91,23 @@
<string name="msg_missing_notification_access" msgid="281113995110910548">"বিজ্ঞপ্তির ডটগুলি দেখানোর জন্য, <xliff:g id="NAME">%1$s</xliff:g> এর অ্যাপ বিজ্ঞপ্তি চালু করুন"</string>
<string name="title_change_settings" msgid="1376365968844349552">"সেটিংস পরিবর্তন করুন"</string>
<string name="notification_dots_service_title" msgid="4284221181793592871">"বিজ্ঞপ্তির ডট দেখুন"</string>
- <string name="auto_add_shortcuts_label" msgid="3698776050751790653">"হোম স্ক্রিনে অ্যাপ আইকন যোগ করুন"</string>
- <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"নতুন অ্যাপের জন্য"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"হোম স্ক্রিনে আইকন যোগ করুন"</string>
+ <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"নতুন অ্যাপ্লিকেশানগুলির জন্যে"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"অজানা"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"সরান"</string>
<string name="abandoned_search" msgid="891119232568284442">"সার্চ"</string>
<string name="abandoned_promises_title" msgid="7096178467971716750">"এই অ্যাপ্লিকেশানটি ইন্সটল করা নাই"</string>
<string name="abandoned_promise_explanation" msgid="3990027586878167529">"এই আইকনের অ্যাপ্লিকেশানটি ইন্সটল করা নাই। আপনি এটি সরাতে পারেন বা অ্যাপ্লিকেশানটি সার্চ করে এটি নিজে ইন্সটল করতে পারেন।"</string>
- <string name="app_installing_title" msgid="5864044122733792085">"<xliff:g id="NAME">%1$s</xliff:g> ইনস্টল করা হচ্ছে, <xliff:g id="PROGRESS">%2$s</xliff:g> সম্পূর্ণ হয়েছে"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> ডাউনলোড হচ্ছে <xliff:g id="PROGRESS">%2$s</xliff:g> সম্পন্ন হয়েছে"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> ইনস্টলের অপেক্ষায় রয়েছে"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"<xliff:g id="NAME">%1$s</xliff:g> উইজেট"</string>
<string name="widgets_list" msgid="796804551140113767">"উইজেটের তালিকা"</string>
<string name="widgets_list_closed" msgid="6141506579418771922">"উইজেটের তালিকা বন্ধ করা হয়েছে"</string>
<string name="action_add_to_workspace" msgid="8902165848117513641">"হোম স্ক্রিনে যোগ করুন"</string>
<string name="action_move_here" msgid="2170188780612570250">"এখানে আইটেম সরান"</string>
<string name="item_added_to_workspace" msgid="4211073925752213539">"হোম স্ক্রীনে আইটেম যোগ করা হয়েছে"</string>
<string name="item_removed" msgid="851119963877842327">"আইটেম সরানো হয়েছে"</string>
- <string name="undo" msgid="4151576204245173321">"ফিরিয়ে আনুন"</string>
+ <string name="undo" msgid="4151576204245173321">"ফিরে যান"</string>
<string name="action_move" msgid="4339390619886385032">"আইটেম সরান"</string>
<string name="move_to_empty_cell" msgid="2833711483015685619">"সারি <xliff:g id="NUMBER_0">%1$s</xliff:g> কলাম <xliff:g id="NUMBER_1">%2$s</xliff:g> এ সরান"</string>
<string name="move_to_position" msgid="6750008980455459790">"অবস্থানে সরান <xliff:g id="NUMBER">%1$s</xliff:g>"</string>
@@ -151,20 +128,15 @@
<string name="action_deep_shortcut" msgid="2864038805849372848">"শর্টকাট"</string>
<string name="shortcuts_menu_with_notifications_description" msgid="2676582286544232849">"শর্টকাট এবং বিজ্ঞপ্তি"</string>
<string name="action_dismiss_notification" msgid="5909461085055959187">"খারিজ করুন"</string>
- <string name="accessibility_close" msgid="2277148124685870734">"বন্ধ করুন"</string>
<string name="notification_dismissed" msgid="6002233469409822874">"বিজ্ঞপ্তি খারিজ করা হয়েছে"</string>
<string name="all_apps_personal_tab" msgid="4190252696685155002">"ব্যক্তিগত"</string>
<string name="all_apps_work_tab" msgid="4884822796154055118">"অফিস"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"অফিসের প্রোফাইল"</string>
- <string name="work_profile_edu_work_apps" msgid="7895468576497746520">"অফিসের অ্যাপে ব্যাজ যোগ করা হয়েছে এবং আপনার আইটি অ্যাডমিন সেটি দেখতে পাবেন"</string>
- <string name="work_profile_edu_accept" msgid="6069788082535149071">"বুঝেছি"</string>
- <string name="work_apps_paused_title" msgid="3040901117349444598">"অফিস অ্যাপ বন্ধ করা আছে"</string>
- <string name="work_apps_paused_body" msgid="261634750995824906">"অফিসের অ্যাপ আপনাকে নোটিফিকেশন পাঠাতে পারবে না। এছাড়া, ব্যাটারি ব্যবহার করতে বা লোকেশন অ্যাক্সেস করতে পারবে না"</string>
- <string name="work_apps_paused_content_description" msgid="5149623040804051095">"অফিসের অ্যাপ বন্ধ আছে। আপনার অফিসের অ্যাপ আপনাকে বিজ্ঞপ্তি পাঠাতে, ব্যাটারি ব্যবহার করতে বা লোকেশন অ্যাক্সেস করতে পারবে না"</string>
- <string name="work_apps_paused_edu_banner" msgid="8872412121608402058">"অফিসের অ্যাপে ব্যাজ যোগ করা হয়েছে এবং আপনার আইটি অ্যাডমিন সেটি দেখতে পাবেন"</string>
- <string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"বুঝেছি"</string>
- <string name="work_apps_pause_btn_text" msgid="1921059713673767460">"অফিসের অ্যাপ বন্ধ করুন"</string>
- <string name="work_apps_enable_btn_text" msgid="1156432622148413741">"অফিস অ্যাপ চালু করুন"</string>
- <string name="developer_options_filter_hint" msgid="5896817443635989056">"ফিল্টার"</string>
+ <string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"এখানে কাজের অ্যাপ্সগুলি খুঁজুন"</string>
+ <string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"প্রতিটি কাজের অ্যাপে একটি করে ব্যাজ রয়েছে এবং অ্যাপগুলি আপনার প্রতিষ্ঠানের দ্বারা সুরক্ষিত। সহজে অ্যাক্সেস করার জন্য অ্যাপগুলি হোম স্ক্রিনে রাখুন।"</string>
+ <string name="work_mode_on_label" msgid="4781128097185272916">"আপনার প্রতিষ্ঠানের দ্বারা পরিচালিত"</string>
+ <string name="work_mode_off_label" msgid="3194894777601421047">"বিজ্ঞপ্তি এবং অ্যাপ বন্ধ আছে"</string>
+ <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"বন্ধ করুন"</string>
+ <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"বন্ধ"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"কাজটি করা যায়নি: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
</resources>
diff --git a/res/values-bs/strings.xml b/res/values-bs/strings.xml
index 50b2b3cc57..65ad91e9b0 100644
--- a/res/values-bs/strings.xml
+++ b/res/values-bs/strings.xml
@@ -26,57 +26,32 @@
<string name="safemode_shortcut_error" msgid="9160126848219158407">"Preuzeta aplikacija je onemogućena u sigurnom načinu rada"</string>
<string name="safemode_widget_error" msgid="4863470563535682004">"Vidžeti su onemogućeni u sigurnom načinu rada."</string>
<string name="shortcut_not_available" msgid="2536503539825726397">"Prečica nije dostupna"</string>
- <string name="home_screen" msgid="5629429142036709174">"Početni ekran"</string>
- <string name="recent_task_option_split_screen" msgid="6690461455618725183">"Podijeljeni ekran"</string>
- <string name="split_screen_position_top" msgid="1504965011158689649">"Podijeli nagore"</string>
- <string name="split_screen_position_left" msgid="7537793098851830883">"Podijeli ulijevo"</string>
- <string name="split_screen_position_right" msgid="1569377524925193369">"Podijeli udesno"</string>
- <string name="split_app_info_accessibility" msgid="5475288491241414932">"Informacije o aplikaciji %1$s"</string>
- <string name="long_press_widget_to_add" msgid="3587712543577675817">"Dodirnite i zadržite da pomjerite vidžet."</string>
- <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Dvaput dodirnite i zadržite da pomjerite vidžet ili da koristite prilagođene radnje."</string>
+ <string name="home_screen" msgid="806512411299847073">"Početni ekran"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"Prilagođene akcije"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"Dodirnite &amp; i držite da biste uzeli dodatak."</string>
+ <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Dodirnite dvaput &amp; i držite da biste uzeli vidžet ili koristite prilagođene radnje."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"Širina %1$d, visina %2$d"</string>
- <string name="widget_preview_context_description" msgid="9045841361655787574">"Vidžet <xliff:g id="WIDGET_NAME">%1$s</xliff:g>"</string>
- <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Dodirnite i držite vidžet da ga pomjerate po Početnom ekranu"</string>
- <string name="add_to_home_screen" msgid="8631549138215492708">"Dodaj na početni ekran"</string>
- <string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"Vidžet <xliff:g id="WIDGET_NAME">%1$s</xliff:g> je dodan na početni ekran"</string>
- <string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# vidžet}one{# vidžet}few{# vidžeta}other{# vidžeta}}"</string>
- <string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{# prečica}one{# prečica}few{# prečice}other{# prečica}}"</string>
- <string name="widgets_and_shortcuts_count" msgid="7209136747878365116">"<xliff:g id="WIDGETS_COUNT">%1$s</xliff:g>, <xliff:g id="SHORTCUTS_COUNT">%2$s</xliff:g>"</string>
- <string name="widget_button_text" msgid="2880537293434387943">"Vidžeti"</string>
- <string name="widgets_full_sheet_search_bar_hint" msgid="8484659090860596457">"Pretražite"</string>
- <string name="widgets_full_sheet_cancel_button_description" msgid="5766167035728653605">"Brisanje teksta iz okvira za pretraživanje"</string>
- <string name="no_widgets_available" msgid="4337693382501046170">"Vidžeti i prečice nisu dostupni"</string>
- <string name="no_search_results" msgid="3787956167293097509">"Nije pronađen nijedan vidžet ili prečica"</string>
- <string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Lično"</string>
- <string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Posao"</string>
- <string name="widget_category_conversations" msgid="8894438636213590446">"Razgovori"</string>
- <string name="widget_education_header" msgid="4874760613775913787">"Korisne informacije nadohvat ruke"</string>
- <string name="widget_education_content" msgid="745542879510751525">"Da dobijete informacije bez otvaranja aplikacija, možete dodati vidžete na početni ekran"</string>
- <string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Dodirnite da promijenite postavke vidžeta"</string>
- <string name="widget_education_close_button" msgid="8676165703104836580">"Razumijem"</string>
- <string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Promjena postavki vidžeta"</string>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Dodirnite i držite da postavite ručno"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"Dodaj automatski"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Pretražite aplikacije"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Aplikacije se učitavaju…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"Nije pronađena nijedna aplikacija za upit \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
<string name="all_apps_search_market_message" msgid="1366263386197059176">"Pretraži više aplikacija"</string>
<string name="label_application" msgid="8531721983832654978">"Aplikacija"</string>
- <string name="all_apps_label" msgid="5015784846527570951">"Sve aplikacije"</string>
<string name="notifications_header" msgid="1404149926117359025">"Obavještenja"</string>
- <string name="long_press_shortcut_to_add" msgid="5405328730817637737">"Dodirnite i zadržite da pomjerite prečicu."</string>
- <string name="long_accessible_way_to_add_shortcut" msgid="2199537273817090740">"Dvaput dodirnite i zadržite da pomjerite prečicu ili da koristite prilagođene radnje."</string>
- <string name="out_of_space" msgid="6692471482459245734">"Nema prostora na ovom početnom ekranu"</string>
+ <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"Dodirnite i držite da uzmete prečicu."</string>
+ <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"Dodirnite dvaput i držite da uzmete prečicu ili koristite prilagođene akcije."</string>
+ <string name="out_of_space" msgid="4691004494942118364">"Na ovom početnom ekranu nema više prostora."</string>
<string name="hotseat_out_of_space" msgid="7448809638125333693">"Nema više prostora u ladici Omiljeno"</string>
- <string name="all_apps_button_label" msgid="8130441508702294465">"Lista aplikacija"</string>
- <string name="all_apps_search_results" msgid="5889367432531296759">"Rezultati pretraživanja"</string>
+ <string name="all_apps_button_label" msgid="8130441508702294465">"Spisak aplikacija"</string>
<string name="all_apps_button_personal_label" msgid="1315764287305224468">"Lista ličnih aplikacija"</string>
<string name="all_apps_button_work_label" msgid="7270707118948892488">"Lista poslovnih aplikacija"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"Početna"</string>
<string name="remove_drop_target_label" msgid="7812859488053230776">"Ukloni"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"Deinstaliraj"</string>
- <string name="app_info_drop_target_label" msgid="692894985365717661">"Inform. o aplikaciji"</string>
+ <string name="app_info_drop_target_label" msgid="692894985365717661">"Informacije o aplikaciji"</string>
<string name="install_drop_target_label" msgid="2539096853673231757">"Instaliraj"</string>
- <string name="dismiss_prediction_label" msgid="3357562989568808658">"Ne predlaži aplikaciju"</string>
- <string name="pin_prediction" msgid="4196423321649756498">"Zakači predviđanje"</string>
<string name="permlab_install_shortcut" msgid="5632423390354674437">"instaliraj prečice"</string>
<string name="permdesc_install_shortcut" msgid="923466509822011139">"Dopušta aplikaciji dodavanje prečica bez posredovanja korisnika."</string>
<string name="permlab_read_settings" msgid="1941457408239617576">"čitaj postavke na početnom ekranu i prečice"</string>
@@ -84,13 +59,16 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"zapisuj postavke na početnom ekranu i prečice"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"Dopušta aplikaciji promjenu postavki i prečica na početnom ekranu."</string>
<string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> nema odobrenje da uspostavlja telefonske pozive"</string>
- <string name="gadget_error_text" msgid="740356548025791839">"Nije moguće učitati vidžet"</string>
- <string name="gadget_setup_text" msgid="8348374825537681407">"Postavke vidžeta"</string>
- <string name="gadget_complete_setup_text" msgid="309040266978007925">"Dodirnite da završite postavljanje"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"Problem pri učitavanju dodatka"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"Postavljanje"</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"Ovo je sistemska aplikacija i ne može se deinstalirati."</string>
- <string name="folder_hint_text" msgid="5174843001373488816">"Uređivanje naziva"</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"Neimenovani folder"</string>
<string name="disabled_app_label" msgid="6673129024321402780">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> je onemogućena"</string>
- <string name="dotted_app_label" msgid="1704091277755818896">"{count,plural,offset:1 =1{{app_name} ima # obavještenje}one{{app_name} ima # obavještenje}few{{app_name} ima # obavještenja}other{{app_name} ima # obavještenja}}"</string>
+ <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+ <item quantity="one">Aplikacija <xliff:g id="APP_NAME_2">%1$s</xliff:g> ima<xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> obavještenje​</item>
+ <item quantity="few">Aplikacija <xliff:g id="APP_NAME_2">%1$s</xliff:g> ima<xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> obavještenja​</item>
+ <item quantity="other">Aplikacija <xliff:g id="APP_NAME_2">%1$s</xliff:g> ima<xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> obavještenja​</item>
+ </plurals>
<string name="default_scroll_format" msgid="7475544710230993317">"Strana %1$d od %2$d"</string>
<string name="workspace_scroll_format" msgid="8458889198184077399">"Početni ekran %1$d od %2$d"</string>
<string name="workspace_new_page" msgid="257366611030256142">"Nova stranica početnog ekrana"</string>
@@ -99,10 +77,10 @@
<string name="folder_tap_to_rename" msgid="4017685068016979677">"Dodirnite da sačuvate promjenu naziva"</string>
<string name="folder_closed" msgid="4100806530910930934">"Folder je zatvoren"</string>
<string name="folder_renamed" msgid="1794088362165669656">"Ime foldera je promijenjeno u <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="folder_name_format_exact" msgid="8626242716117004803">"Folder: <xliff:g id="NAME">%1$s</xliff:g>, br. stavki: <xliff:g id="SIZE">%2$d</xliff:g>"</string>
- <string name="folder_name_format_overflow" msgid="4270108890534995199">"Folder: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> ili više stavki"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"Folder: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"Vidžeti"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Pozadinske slike"</string>
- <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Pozadinska slika i stil"</string>
+ <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Stilovi i pozadinske slike"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Postavke početnog ekrana"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Onemogućio vaš administrator"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Dozvoli rotiranje početnog ekrana"</string>
@@ -114,19 +92,19 @@
<string name="msg_missing_notification_access" msgid="281113995110910548">"Za prikaz tačaka za obavještenja, uključite obavještenja za aplikacije za aplikaciju <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="title_change_settings" msgid="1376365968844349552">"Promijeni postavke"</string>
<string name="notification_dots_service_title" msgid="4284221181793592871">"Prikaži tačke za obavještenja"</string>
- <string name="auto_add_shortcuts_label" msgid="3698776050751790653">"Dodaj ikone aplikacija na početni ekran"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Dodaj ikonu na početni ekran"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Za nove aplikacije"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"Nepoznato"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"Ukloni"</string>
<string name="abandoned_search" msgid="891119232568284442">"Pretraži"</string>
<string name="abandoned_promises_title" msgid="7096178467971716750">"Ova aplikacija nije instalirana"</string>
<string name="abandoned_promise_explanation" msgid="3990027586878167529">"Aplikacija za ovu ikonu nije instalirana. Možete je ukloniti ili potražiti aplikaciju i ručno je instalirati."</string>
- <string name="app_installing_title" msgid="5864044122733792085">"Instaliranje aplikacije <xliff:g id="NAME">%1$s</xliff:g>, završeno je <xliff:g id="PROGRESS">%2$s</xliff:g>"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> se preuzima, završeno <xliff:g id="PROGRESS">%2$s</xliff:g>"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> čeka da se instalira"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"Vidžeti za aplikaciju <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="widgets_list" msgid="796804551140113767">"Spisak vidžeta"</string>
<string name="widgets_list_closed" msgid="6141506579418771922">"Spisak vidžeta je zatvoren"</string>
- <string name="action_add_to_workspace" msgid="8902165848117513641">"Dodavanje na početni ekran"</string>
+ <string name="action_add_to_workspace" msgid="8902165848117513641">"Dodaj na početni ekran"</string>
<string name="action_move_here" msgid="2170188780612570250">"Premjesti stavku ovdje"</string>
<string name="item_added_to_workspace" msgid="4211073925752213539">"Stavka je dodana na Početni ekran."</string>
<string name="item_removed" msgid="851119963877842327">"Stavka je uklonjena"</string>
@@ -151,20 +129,15 @@
<string name="action_deep_shortcut" msgid="2864038805849372848">"Prečice"</string>
<string name="shortcuts_menu_with_notifications_description" msgid="2676582286544232849">"Prečice i obavještenja"</string>
<string name="action_dismiss_notification" msgid="5909461085055959187">"Odbaci"</string>
- <string name="accessibility_close" msgid="2277148124685870734">"Zatvaranje"</string>
<string name="notification_dismissed" msgid="6002233469409822874">"Obavještenje je odbačeno"</string>
<string name="all_apps_personal_tab" msgid="4190252696685155002">"Lične"</string>
<string name="all_apps_work_tab" msgid="4884822796154055118">"Poslovne"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"Radni profil"</string>
- <string name="work_profile_edu_work_apps" msgid="7895468576497746520">"Poslovne aplikacije su označene i vaš IT administrator ih može vidjeti"</string>
- <string name="work_profile_edu_accept" msgid="6069788082535149071">"Razumijem"</string>
- <string name="work_apps_paused_title" msgid="3040901117349444598">"Poslovne aplikacije su pauzirane"</string>
- <string name="work_apps_paused_body" msgid="261634750995824906">"Poslovne aplikacije vam ne mogu slati obavještenja, koristiti bateriju niti pristupiti vašoj lokaciji"</string>
- <string name="work_apps_paused_content_description" msgid="5149623040804051095">"Poslovne aplikacije su isključene. Poslovne aplikacije vam ne mogu slati obavještenja, koristiti bateriju ili pristupiti vašoj lokaciji"</string>
- <string name="work_apps_paused_edu_banner" msgid="8872412121608402058">"Poslovne aplikacije su označene i vaš IT administrator ih može vidjeti"</string>
- <string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"Razumijem"</string>
- <string name="work_apps_pause_btn_text" msgid="1921059713673767460">"Isključi poslovne aplikacije"</string>
- <string name="work_apps_enable_btn_text" msgid="1156432622148413741">"Uključi poslovne aplikacije"</string>
- <string name="developer_options_filter_hint" msgid="5896817443635989056">"Filtrirajte"</string>
+ <string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"Pronađite poslovne aplikacije ovdje"</string>
+ <string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"Svaka poslovna aplikacija ima značku i osigurava je vaša organizacija. Premjestite aplikacije na Početni ekran, radi lakšeg pristupa."</string>
+ <string name="work_mode_on_label" msgid="4781128097185272916">"Upravlja vaša organizacija"</string>
+ <string name="work_mode_off_label" msgid="3194894777601421047">"Notifikacije i aplikacije su isključene"</string>
+ <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Zatvori"</string>
+ <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Zatvoreno"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Nije uspjelo: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
</resources>
diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml
index a0f03c877d..4ef9ec3a2c 100644
--- a/res/values-ca/strings.xml
+++ b/res/values-ca/strings.xml
@@ -20,63 +20,38 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="649227358658669779">"Launcher3"</string>
- <string name="work_folder_name" msgid="3753320833950115786">"Treball"</string>
+ <string name="work_folder_name" msgid="3753320833950115786">"Feina"</string>
<string name="activity_not_found" msgid="8071924732094499514">"L\'aplicació no s\'ha instal·lat."</string>
<string name="activity_not_available" msgid="7456344436509528827">"L\'aplicació no està disponible."</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"L\'aplicació que has baixat està desactivada al mode segur."</string>
<string name="safemode_widget_error" msgid="4863470563535682004">"En Mode segur, els widgets estan desactivats."</string>
<string name="shortcut_not_available" msgid="2536503539825726397">"La drecera no està disponible"</string>
- <string name="home_screen" msgid="5629429142036709174">"Inici"</string>
- <string name="recent_task_option_split_screen" msgid="6690461455618725183">"Pantalla dividida"</string>
- <string name="split_screen_position_top" msgid="1504965011158689649">"Divideix a la part superior"</string>
- <string name="split_screen_position_left" msgid="7537793098851830883">"Divideix a l\'esquerra"</string>
- <string name="split_screen_position_right" msgid="1569377524925193369">"Divideix a la dreta"</string>
- <string name="split_app_info_accessibility" msgid="5475288491241414932">"Informació de l\'aplicació %1$s"</string>
- <string name="long_press_widget_to_add" msgid="3587712543577675817">"Fes doble toc i mantén premut per moure un widget."</string>
- <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Fes doble toc i mantén premut per moure un widget o per utilitzar accions personalitzades."</string>
+ <string name="home_screen" msgid="806512411299847073">"Pantalla d\'inici"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"Accions personalitzades"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"Mantén premut un widget per triar-lo."</string>
+ <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Fes doble toc i mantén premut per seleccionar un widget o per utilitzar les accions personalitzades."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d d\'amplada per %2$d d\'alçada"</string>
- <string name="widget_preview_context_description" msgid="9045841361655787574">"Widget de <xliff:g id="WIDGET_NAME">%1$s</xliff:g>"</string>
- <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Mantén premut el widget per moure\'l per la pantalla d\'inici"</string>
- <string name="add_to_home_screen" msgid="8631549138215492708">"Afegeix a la pantalla d\'inici"</string>
- <string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"El widget <xliff:g id="WIDGET_NAME">%1$s</xliff:g> s\'ha afegit a la pantalla d\'inici"</string>
- <string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# widget}other{# widgets}}"</string>
- <string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{# drecera}other{# dreceres}}"</string>
- <string name="widgets_and_shortcuts_count" msgid="7209136747878365116">"<xliff:g id="WIDGETS_COUNT">%1$s</xliff:g>, <xliff:g id="SHORTCUTS_COUNT">%2$s</xliff:g>"</string>
- <string name="widget_button_text" msgid="2880537293434387943">"Widgets"</string>
- <string name="widgets_full_sheet_search_bar_hint" msgid="8484659090860596457">"Cerca"</string>
- <string name="widgets_full_sheet_cancel_button_description" msgid="5766167035728653605">"Esborra el text del quadre de cerca"</string>
- <string name="no_widgets_available" msgid="4337693382501046170">"No hi ha widgets ni dreceres disponibles"</string>
- <string name="no_search_results" msgid="3787956167293097509">"No s\'ha trobat cap widget ni drecera"</string>
- <string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Personal"</string>
- <string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Treball"</string>
- <string name="widget_category_conversations" msgid="8894438636213590446">"Converses"</string>
- <string name="widget_education_header" msgid="4874760613775913787">"Informació útil a l\'abast de la mà"</string>
- <string name="widget_education_content" msgid="745542879510751525">"Per obtenir informació sense obrir les aplicacions, pots afegir widgets a la pantalla d\'inici"</string>
- <string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Toca per canviar la configuració del widget"</string>
- <string name="widget_education_close_button" msgid="8676165703104836580">"Entesos"</string>
- <string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Canvia la configuració del widget"</string>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Mantén premut l\'element per afegir-lo manualment"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"Afegeix automàticament"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Cerca aplicacions"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"S\'estan carregant les aplicacions…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"No s\'ha trobat cap aplicació que coincideixi amb \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
<string name="all_apps_search_market_message" msgid="1366263386197059176">"Cerca més aplicacions"</string>
<string name="label_application" msgid="8531721983832654978">"Aplicació"</string>
- <string name="all_apps_label" msgid="5015784846527570951">"Totes les aplicacions"</string>
<string name="notifications_header" msgid="1404149926117359025">"Notificacions"</string>
- <string name="long_press_shortcut_to_add" msgid="5405328730817637737">"Fes doble toc i mantén premut per moure una drecera."</string>
- <string name="long_accessible_way_to_add_shortcut" msgid="2199537273817090740">"Fes doble toc i mantén premut per moure una drecera o per utilitzar accions personalitzades."</string>
- <string name="out_of_space" msgid="6692471482459245734">"No queda espai en aquesta pantalla d\'inici"</string>
+ <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"Mantén premuda una drecera per seleccionar-la."</string>
+ <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"Fes doble toc i mantén premut per seleccionar una drecera o per utilitzar accions personalitzades."</string>
+ <string name="out_of_space" msgid="4691004494942118364">"Ja no queda espai en aquesta pantalla d\'inici."</string>
<string name="hotseat_out_of_space" msgid="7448809638125333693">"No hi ha més espai a la safata Preferits."</string>
<string name="all_apps_button_label" msgid="8130441508702294465">"Llista d\'aplicacions"</string>
- <string name="all_apps_search_results" msgid="5889367432531296759">"Resultats de la cerca"</string>
<string name="all_apps_button_personal_label" msgid="1315764287305224468">"Llista d\'aplicacions personals"</string>
- <string name="all_apps_button_work_label" msgid="7270707118948892488">"Llista d\'aplicacions de treball"</string>
+ <string name="all_apps_button_work_label" msgid="7270707118948892488">"Llista d\'aplicacions per a la feina"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"Inici"</string>
<string name="remove_drop_target_label" msgid="7812859488053230776">"Suprimeix"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"Desinstal·la"</string>
<string name="app_info_drop_target_label" msgid="692894985365717661">"Informació de l\'aplicació"</string>
<string name="install_drop_target_label" msgid="2539096853673231757">"Instal·la"</string>
- <string name="dismiss_prediction_label" msgid="3357562989568808658">"No suggereixis l\'aplicació"</string>
- <string name="pin_prediction" msgid="4196423321649756498">"Fixa la predicció"</string>
<string name="permlab_install_shortcut" msgid="5632423390354674437">"instal·la dreceres"</string>
<string name="permdesc_install_shortcut" msgid="923466509822011139">"Permet que una aplicació afegeixi dreceres sense la intervenció de l\'usuari."</string>
<string name="permlab_read_settings" msgid="1941457408239617576">"llegeix la configuració i les dreceres de la pantalla d\'inici"</string>
@@ -84,13 +59,15 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"escriu la configuració i les dreceres de la pantalla d\'inici"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"Permet que l\'aplicació canviï la configuració i les dreceres de la pantalla d\'inici."</string>
<string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> no té permís per fer trucades telefòniques"</string>
- <string name="gadget_error_text" msgid="740356548025791839">"No es pot carregar el widget"</string>
- <string name="gadget_setup_text" msgid="8348374825537681407">"Configuració del widget"</string>
- <string name="gadget_complete_setup_text" msgid="309040266978007925">"Toca per finalitzar la configuració"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"S\'ha produït un problema en carregar el widget"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"Configuració"</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"Aquesta aplicació és una aplicació del sistema i no es pot desinstal·lar."</string>
- <string name="folder_hint_text" msgid="5174843001373488816">"Edita el nom"</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"Carpeta sense nom"</string>
<string name="disabled_app_label" msgid="6673129024321402780">"S\'ha desactivat <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
- <string name="dotted_app_label" msgid="1704091277755818896">"{count,plural,offset:1 =1{{app_name} té # notificació}other{{app_name} té # notificacions}}"</string>
+ <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+ <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>​ té <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> notificacions</item>
+ <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g> té <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> notificació</item>
+ </plurals>
<string name="default_scroll_format" msgid="7475544710230993317">"Pàgina %1$d de %2$d"</string>
<string name="workspace_scroll_format" msgid="8458889198184077399">"Pantalla d\'inici %1$d de %2$d"</string>
<string name="workspace_new_page" msgid="257366611030256142">"Pàgina de la pantalla d\'inici nova"</string>
@@ -99,10 +76,10 @@
<string name="folder_tap_to_rename" msgid="4017685068016979677">"Toca per desar el nom nou"</string>
<string name="folder_closed" msgid="4100806530910930934">"Carpeta tancada"</string>
<string name="folder_renamed" msgid="1794088362165669656">"S\'ha canviat el nom de la carpeta a <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="folder_name_format_exact" msgid="8626242716117004803">"Carpeta: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> elements"</string>
- <string name="folder_name_format_overflow" msgid="4270108890534995199">"Carpeta: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> o més elements"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"Carpeta: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"Widgets"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Fons de pantalla"</string>
- <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Estil i fons de pantalla"</string>
+ <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Estils i fons de pantalla"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Config. pantalla d\'inici"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Desactivada per l\'administrador"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Permet la rotació de la pantalla d\'inici"</string>
@@ -114,16 +91,16 @@
<string name="msg_missing_notification_access" msgid="281113995110910548">"Per veure els punts de notificació, activa les notificacions de l\'aplicació <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="title_change_settings" msgid="1376365968844349552">"Canvia la configuració"</string>
<string name="notification_dots_service_title" msgid="4284221181793592871">"Mostra els punts de notificació"</string>
- <string name="auto_add_shortcuts_label" msgid="3698776050751790653">"Afegeix icones d\'aplicacions a la pantalla d\'inici"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Afegeix icona a la pantalla d\'inici"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Per a les aplicacions noves"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"Desconegut"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"Suprimeix"</string>
<string name="abandoned_search" msgid="891119232568284442">"Cerca"</string>
<string name="abandoned_promises_title" msgid="7096178467971716750">"Aquesta aplicació no està instal·lada"</string>
<string name="abandoned_promise_explanation" msgid="3990027586878167529">"L\'aplicació d\'aquesta icona no està instal·lada. Pots suprimir-la o cercar l\'aplicació i instal·lar-la manualment."</string>
- <string name="app_installing_title" msgid="5864044122733792085">"S\'està instal·lant <xliff:g id="NAME">%1$s</xliff:g>; s\'ha completat un <xliff:g id="PROGRESS">%2$s</xliff:g>"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"S\'està baixant <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="PROGRESS">%2$s</xliff:g> completat"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"S\'està esperant per instal·lar <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"Widgets de: <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="widgets_list" msgid="796804551140113767">"Llista de widgets"</string>
<string name="widgets_list_closed" msgid="6141506579418771922">"S\'ha tancat la llista de widgets"</string>
<string name="action_add_to_workspace" msgid="8902165848117513641">"Afegeix a la pantalla d\'inici"</string>
@@ -151,20 +128,15 @@
<string name="action_deep_shortcut" msgid="2864038805849372848">"Dreceres"</string>
<string name="shortcuts_menu_with_notifications_description" msgid="2676582286544232849">"Dreceres i notificacions"</string>
<string name="action_dismiss_notification" msgid="5909461085055959187">"Ignora"</string>
- <string name="accessibility_close" msgid="2277148124685870734">"Tanca"</string>
<string name="notification_dismissed" msgid="6002233469409822874">"S\'ha ignorat la notificació"</string>
<string name="all_apps_personal_tab" msgid="4190252696685155002">"Personal"</string>
- <string name="all_apps_work_tab" msgid="4884822796154055118">"Treball"</string>
- <string name="work_profile_toggle_label" msgid="3081029915775481146">"Perfil de treball"</string>
- <string name="work_profile_edu_work_apps" msgid="7895468576497746520">"Les aplicacions de treball tenen una insígnia i són visibles per al teu administrador de TI"</string>
- <string name="work_profile_edu_accept" msgid="6069788082535149071">"Entesos"</string>
- <string name="work_apps_paused_title" msgid="3040901117349444598">"Les aplicacions de treball estan en pausa"</string>
- <string name="work_apps_paused_body" msgid="261634750995824906">"Les aplicacions de treball no poden enviar-te notificacions, consumir bateria ni accedir a la teva ubicació"</string>
- <string name="work_apps_paused_content_description" msgid="5149623040804051095">"Les aplicacions de treball estan desactivades: no poden enviar-te notificacions, consumir bateria ni accedir a la teva ubicació"</string>
- <string name="work_apps_paused_edu_banner" msgid="8872412121608402058">"Les aplicacions de treball tenen una insígnia i són visibles per al teu administrador de TI"</string>
- <string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"Entesos"</string>
- <string name="work_apps_pause_btn_text" msgid="1921059713673767460">"Desactiva les aplicacions de treball"</string>
- <string name="work_apps_enable_btn_text" msgid="1156432622148413741">"Activa les aplicacions de treball"</string>
- <string name="developer_options_filter_hint" msgid="5896817443635989056">"Filtra"</string>
+ <string name="all_apps_work_tab" msgid="4884822796154055118">"Feina"</string>
+ <string name="work_profile_toggle_label" msgid="3081029915775481146">"Perfil professional"</string>
+ <string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"Cerca aplicacions per a la feina aquí"</string>
+ <string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"Totes les aplicacions per a la feina tenen una insígnia que indica que estan protegides per la teva organització. Mou les aplicacions a la pantalla d\'inici per poder-hi accedir més fàcilment."</string>
+ <string name="work_mode_on_label" msgid="4781128097185272916">"Gestionat per la teva organització"</string>
+ <string name="work_mode_off_label" msgid="3194894777601421047">"Les notificacions i les aplicacions estan desactivades"</string>
+ <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Tanca"</string>
+ <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"S\'ha tancat"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Error: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
</resources>
diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml
index a92e93661f..692b57d46e 100644
--- a/res/values-cs/strings.xml
+++ b/res/values-cs/strings.xml
@@ -20,63 +20,39 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="649227358658669779">"Launcher3"</string>
+ <string name="folder_name" msgid="7371454440695724752"></string>
<string name="work_folder_name" msgid="3753320833950115786">"Práce"</string>
<string name="activity_not_found" msgid="8071924732094499514">"Aplikace není nainstalována."</string>
<string name="activity_not_available" msgid="7456344436509528827">"Aplikace není k dispozici."</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"Stažená aplikace je v nouzovém režimu zakázána"</string>
<string name="safemode_widget_error" msgid="4863470563535682004">"V nouzovém režimu jsou widgety zakázány."</string>
<string name="shortcut_not_available" msgid="2536503539825726397">"Zkratka není k dispozici"</string>
- <string name="home_screen" msgid="5629429142036709174">"Domů"</string>
- <string name="recent_task_option_split_screen" msgid="6690461455618725183">"Rozdělená obrazovka"</string>
- <string name="split_screen_position_top" msgid="1504965011158689649">"Rozdělit nahoře"</string>
- <string name="split_screen_position_left" msgid="7537793098851830883">"Rozdělit vlevo"</string>
- <string name="split_screen_position_right" msgid="1569377524925193369">"Rozdělit vpravo"</string>
- <string name="split_app_info_accessibility" msgid="5475288491241414932">"Informace o aplikaci %1$s"</string>
- <string name="long_press_widget_to_add" msgid="3587712543577675817">"Klepnutím a podržením přesunete widget."</string>
- <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Dvojitým klepnutím a podržením přesunete widget, případně použijte vlastní akce."</string>
+ <string name="home_screen" msgid="806512411299847073">"Plocha"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"Vlastní akce"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"Widget vyberete dotykem a podržením."</string>
+ <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Dvojitým klepnutím a podržením vyberte widget, případně použijte vlastní akce."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"šířka %1$d, výška %2$d"</string>
- <string name="widget_preview_context_description" msgid="9045841361655787574">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g> widget"</string>
- <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Pokud chcete widgetem pohybovat po ploše, podržte ho"</string>
- <string name="add_to_home_screen" msgid="8631549138215492708">"Přidat na plochu"</string>
- <string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"Widget <xliff:g id="WIDGET_NAME">%1$s</xliff:g> byl přidán na plochu"</string>
- <string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{ # widget}few{# widgety}many{# widgetu}other{# widgetů}}"</string>
- <string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{# zkratka}few{# zkratky}many{# zkratky}other{# zkratek}}"</string>
- <string name="widgets_and_shortcuts_count" msgid="7209136747878365116">"<xliff:g id="WIDGETS_COUNT">%1$s</xliff:g>, <xliff:g id="SHORTCUTS_COUNT">%2$s</xliff:g>"</string>
- <string name="widget_button_text" msgid="2880537293434387943">"Widgety"</string>
- <string name="widgets_full_sheet_search_bar_hint" msgid="8484659090860596457">"Vyhledávání"</string>
- <string name="widgets_full_sheet_cancel_button_description" msgid="5766167035728653605">"Vymazat text z vyhledávacího pole"</string>
- <string name="no_widgets_available" msgid="4337693382501046170">"Widgety ani zkratky nejsou k dispozici"</string>
- <string name="no_search_results" msgid="3787956167293097509">"Nebyly nalezeny žádné widgety ani zkratky"</string>
- <string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Osobní"</string>
- <string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Práce"</string>
- <string name="widget_category_conversations" msgid="8894438636213590446">"Konverzace"</string>
- <string name="widget_education_header" msgid="4874760613775913787">"Užitečné informace na dosah"</string>
- <string name="widget_education_content" msgid="745542879510751525">"Pokud chcete mít informace k dispozici bez otevírání aplikací, můžete si na plochu přidat widgety"</string>
- <string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Klepnutím změníte nastavení widgetu"</string>
- <string name="widget_education_close_button" msgid="8676165703104836580">"Rozumím"</string>
- <string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Změnit nastavení widgetu"</string>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Chcete-li položku umístit ručně, klepněte na ni a podržte ji"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"Přidat automaticky"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Hledat v aplikacích"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Načítání aplikací…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"Dotazu „<xliff:g id="QUERY">%1$s</xliff:g>“ neodpovídají žádné aplikace"</string>
<string name="all_apps_search_market_message" msgid="1366263386197059176">"Vyhledat další aplikace"</string>
<string name="label_application" msgid="8531721983832654978">"Aplikace"</string>
- <string name="all_apps_label" msgid="5015784846527570951">"Všechny aplikace"</string>
<string name="notifications_header" msgid="1404149926117359025">"Oznámení"</string>
- <string name="long_press_shortcut_to_add" msgid="5405328730817637737">"Klepnutím a podržením přesunete zkratku."</string>
- <string name="long_accessible_way_to_add_shortcut" msgid="2199537273817090740">"Dvojitým klepnutím a podržením přesunete zkratku, případně použijte vlastní akce."</string>
- <string name="out_of_space" msgid="6692471482459245734">"Na této ploše není místo"</string>
+ <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"Zkratku vyberete podržením."</string>
+ <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"Dvojitým klepnutím a podržením vyberte zkratku, případně použijte vlastní akce."</string>
+ <string name="out_of_space" msgid="4691004494942118364">"Na této ploše již není místo."</string>
<string name="hotseat_out_of_space" msgid="7448809638125333693">"Na panelu Oblíbené položky již není místo."</string>
<string name="all_apps_button_label" msgid="8130441508702294465">"Seznam aplikací"</string>
- <string name="all_apps_search_results" msgid="5889367432531296759">"Výsledky vyhledávání"</string>
<string name="all_apps_button_personal_label" msgid="1315764287305224468">"Seznam osobních aplikací"</string>
<string name="all_apps_button_work_label" msgid="7270707118948892488">"Seznam pracovních aplikací"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"Plocha"</string>
<string name="remove_drop_target_label" msgid="7812859488053230776">"Odstranit"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"Odinstalovat"</string>
<string name="app_info_drop_target_label" msgid="692894985365717661">"O aplikaci"</string>
<string name="install_drop_target_label" msgid="2539096853673231757">"Nainstalovat"</string>
- <string name="dismiss_prediction_label" msgid="3357562989568808658">"Aplikaci nenavrhovat"</string>
- <string name="pin_prediction" msgid="4196423321649756498">"Připnout předpověď"</string>
<string name="permlab_install_shortcut" msgid="5632423390354674437">"instalace zástupce"</string>
<string name="permdesc_install_shortcut" msgid="923466509822011139">"Umožňuje aplikaci přidat zástupce bez zásahu uživatele."</string>
<string name="permlab_read_settings" msgid="1941457408239617576">"čtení nastavení a odkazů plochy"</string>
@@ -84,13 +60,17 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"zápis nastavení a odkazů plochy"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"Umožňuje aplikaci změnit nastavení a odkazy na ploše."</string>
<string name="msg_no_phone_permission" msgid="9208659281529857371">"Aplikace <xliff:g id="APP_NAME">%1$s</xliff:g> nemá oprávnění telefonovat"</string>
- <string name="gadget_error_text" msgid="740356548025791839">"Widget se nepodařilo načíst"</string>
- <string name="gadget_setup_text" msgid="8348374825537681407">"Nastavení widgetů"</string>
- <string name="gadget_complete_setup_text" msgid="309040266978007925">"Klepnutím dokončíte konfiguraci"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"Problém s načtením widgetu"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"Nastavení"</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"Toto je systémová aplikace a nelze ji odinstalovat."</string>
- <string name="folder_hint_text" msgid="5174843001373488816">"Upravit název"</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"Složka bez názvu"</string>
<string name="disabled_app_label" msgid="6673129024321402780">"Aplikace <xliff:g id="APP_NAME">%1$s</xliff:g> je zakázána"</string>
- <string name="dotted_app_label" msgid="1704091277755818896">"{count,plural,offset:1 =1{Aplikace {app_name} má # oznámení}few{Aplikace {app_name} má # oznámení}many{Aplikace {app_name} má # oznámení}other{Aplikace {app_name} má # oznámení}}"</string>
+ <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+ <item quantity="few">Aplikace <xliff:g id="APP_NAME_2">%1$s</xliff:g> má <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> oznámení</item>
+ <item quantity="many">Aplikace <xliff:g id="APP_NAME_2">%1$s</xliff:g> má <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> oznámení</item>
+ <item quantity="other">Aplikace <xliff:g id="APP_NAME_2">%1$s</xliff:g> má <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> oznámení</item>
+ <item quantity="one">Aplikace <xliff:g id="APP_NAME_0">%1$s</xliff:g> má <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> oznámení</item>
+ </plurals>
<string name="default_scroll_format" msgid="7475544710230993317">"Strana %1$d z %2$d"</string>
<string name="workspace_scroll_format" msgid="8458889198184077399">"Plocha %1$d z %2$d"</string>
<string name="workspace_new_page" msgid="257366611030256142">"Nová stránka plochy"</string>
@@ -99,10 +79,10 @@
<string name="folder_tap_to_rename" msgid="4017685068016979677">"Klepnutím změnu názvu uložíte"</string>
<string name="folder_closed" msgid="4100806530910930934">"Složka je uzavřena"</string>
<string name="folder_renamed" msgid="1794088362165669656">"Složka přejmenována na <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="folder_name_format_exact" msgid="8626242716117004803">"Složka: <xliff:g id="NAME">%1$s</xliff:g>, počet položek: <xliff:g id="SIZE">%2$d</xliff:g>"</string>
- <string name="folder_name_format_overflow" msgid="4270108890534995199">"Složka: <xliff:g id="NAME">%1$s</xliff:g>, počet položek: <xliff:g id="SIZE">%2$d</xliff:g> nebo více"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"Složka: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"Widgety"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Tapety"</string>
- <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Tapeta a styl"</string>
+ <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Styly a tapety"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Nastavení plochy"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Zakázáno administrátorem"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Povolit otáčení plochy"</string>
@@ -114,16 +94,16 @@
<string name="msg_missing_notification_access" msgid="281113995110910548">"Chcete-li zobrazovat puntíky s oznámením, zapněte oznámení z aplikace <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="title_change_settings" msgid="1376365968844349552">"Změnit nastavení"</string>
<string name="notification_dots_service_title" msgid="4284221181793592871">"Zobrazovat puntíky s oznámením"</string>
- <string name="auto_add_shortcuts_label" msgid="3698776050751790653">"Přidávat na plochu ikony aplikací"</string>
- <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"U nových aplikací"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Přidat ikonu na plochu"</string>
+ <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Pro nové aplikace"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"Neznámé"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"Odstranit"</string>
<string name="abandoned_search" msgid="891119232568284442">"Hledat"</string>
<string name="abandoned_promises_title" msgid="7096178467971716750">"Tato aplikace není nainstalována"</string>
<string name="abandoned_promise_explanation" msgid="3990027586878167529">"Aplikace pro tuto ikonu není nainstalována. Můžete ikonu odstranit nebo zkusit aplikaci vyhledat a nainstalovat ručně."</string>
- <string name="app_installing_title" msgid="5864044122733792085">"Instalace aplikace <xliff:g id="NAME">%1$s</xliff:g>, dokončeno <xliff:g id="PROGRESS">%2$s</xliff:g>"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"Stahování aplikace <xliff:g id="NAME">%1$s</xliff:g> (dokončeno <xliff:g id="PROGRESS">%2$s</xliff:g>)"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"Instalace aplikace <xliff:g id="NAME">%1$s</xliff:g> čeká na zahájení"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"Widgety <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="widgets_list" msgid="796804551140113767">"Seznam widgetů"</string>
<string name="widgets_list_closed" msgid="6141506579418771922">"Seznam widgetů zavřen"</string>
<string name="action_add_to_workspace" msgid="8902165848117513641">"Přidat na plochu"</string>
@@ -151,20 +131,15 @@
<string name="action_deep_shortcut" msgid="2864038805849372848">"Zkratky"</string>
<string name="shortcuts_menu_with_notifications_description" msgid="2676582286544232849">"Zkratky a oznámení"</string>
<string name="action_dismiss_notification" msgid="5909461085055959187">"Zavřít"</string>
- <string name="accessibility_close" msgid="2277148124685870734">"Zavřít"</string>
<string name="notification_dismissed" msgid="6002233469409822874">"Oznámení bylo zavřeno"</string>
<string name="all_apps_personal_tab" msgid="4190252696685155002">"Osobní"</string>
<string name="all_apps_work_tab" msgid="4884822796154055118">"Pracovní"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"Pracovní profil"</string>
- <string name="work_profile_edu_work_apps" msgid="7895468576497746520">"Pracovní aplikace jsou označené a viditelné vašemu administrátorovi IT"</string>
- <string name="work_profile_edu_accept" msgid="6069788082535149071">"Rozumím"</string>
- <string name="work_apps_paused_title" msgid="3040901117349444598">"Pracovní aplikace jsou pozastaveny"</string>
- <string name="work_apps_paused_body" msgid="261634750995824906">"Pracovní aplikace vám nemohou zasílat oznámení, používat vaši baterii ani získat přístup k vaší poloze"</string>
- <string name="work_apps_paused_content_description" msgid="5149623040804051095">"Pracovní aplikace jsou vypnuté. Nemohou vám zasílat oznámení, používat vaši baterii ani získat přístup k vaší poloze"</string>
- <string name="work_apps_paused_edu_banner" msgid="8872412121608402058">"Pracovní aplikace jsou označené a viditelné vašemu administrátorovi IT"</string>
- <string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"OK"</string>
- <string name="work_apps_pause_btn_text" msgid="1921059713673767460">"Vypnout pracovní aplikace"</string>
- <string name="work_apps_enable_btn_text" msgid="1156432622148413741">"Zapnout pracovní aplikace"</string>
- <string name="developer_options_filter_hint" msgid="5896817443635989056">"Filtr"</string>
+ <string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"Zde naleznete pracovní aplikace"</string>
+ <string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"Každá pracovní aplikace má odznak a je zabezpečena vaší organizací. Aplikace si můžete pro jednoduchost přesunout na plochu."</string>
+ <string name="work_mode_on_label" msgid="4781128097185272916">"Spravováno vaší organizací"</string>
+ <string name="work_mode_off_label" msgid="3194894777601421047">"Oznámení a aplikace jsou vypnuty"</string>
+ <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Zavřít"</string>
+ <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Zavřeno"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Selhalo: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
</resources>
diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml
index ee339c4669..dc17516bce 100644
--- a/res/values-da/strings.xml
+++ b/res/values-da/strings.xml
@@ -20,63 +20,39 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="649227358658669779">"Launcher3"</string>
+ <string name="folder_name" msgid="7371454440695724752"></string>
<string name="work_folder_name" msgid="3753320833950115786">"Arbejde"</string>
<string name="activity_not_found" msgid="8071924732094499514">"Appen er ikke installeret."</string>
<string name="activity_not_available" msgid="7456344436509528827">"Appen er ikke tilgængelig"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"Downloadet app er deaktiveret i sikker tilstand"</string>
<string name="safemode_widget_error" msgid="4863470563535682004">"Widgets er deaktiveret i Beskyttet tilstand"</string>
<string name="shortcut_not_available" msgid="2536503539825726397">"Genvejen er ikke tilgængelig"</string>
- <string name="home_screen" msgid="5629429142036709174">"Startskærm"</string>
- <string name="recent_task_option_split_screen" msgid="6690461455618725183">"Opdel skærm"</string>
- <string name="split_screen_position_top" msgid="1504965011158689649">"Vis øverst"</string>
- <string name="split_screen_position_left" msgid="7537793098851830883">"Vis i venstre side"</string>
- <string name="split_screen_position_right" msgid="1569377524925193369">"Vis i højre side"</string>
- <string name="split_app_info_accessibility" msgid="5475288491241414932">"Appinfo for %1$s"</string>
- <string name="long_press_widget_to_add" msgid="3587712543577675817">"Hold en widget nede for at flytte den."</string>
- <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Tryk to gange, og hold en widget nede for at flytte den eller bruge tilpassede handlinger."</string>
+ <string name="home_screen" msgid="806512411299847073">"Startskærm"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"Brugerdefinerede handlinger"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"Tryk på en widget, og hold den nede for at vælge."</string>
+ <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Tryk to gange, og hold fingeren nede for at vælge en widget eller bruge tilpassede handlinger."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d i bredden og %2$d i højden"</string>
- <string name="widget_preview_context_description" msgid="9045841361655787574">"Widgetten <xliff:g id="WIDGET_NAME">%1$s</xliff:g>"</string>
- <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Hold widgetten nede for at flytte den rundt på startskærmen"</string>
- <string name="add_to_home_screen" msgid="8631549138215492708">"Føj til startskærm"</string>
- <string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"Widgetten <xliff:g id="WIDGET_NAME">%1$s</xliff:g> blev føjet til startskærmen"</string>
- <string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# widget}one{# widget}other{# widgets}}"</string>
- <string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{# genvej}one{# genvej}other{# genveje}}"</string>
- <string name="widgets_and_shortcuts_count" msgid="7209136747878365116">"<xliff:g id="WIDGETS_COUNT">%1$s</xliff:g>, <xliff:g id="SHORTCUTS_COUNT">%2$s</xliff:g>"</string>
- <string name="widget_button_text" msgid="2880537293434387943">"Widgets"</string>
- <string name="widgets_full_sheet_search_bar_hint" msgid="8484659090860596457">"Søg"</string>
- <string name="widgets_full_sheet_cancel_button_description" msgid="5766167035728653605">"Ryd teksten i søgefeltet"</string>
- <string name="no_widgets_available" msgid="4337693382501046170">"Der er ingen tilgængelige widgets eller genveje"</string>
- <string name="no_search_results" msgid="3787956167293097509">"Der blev ikke fundet nogen widgets eller genveje"</string>
- <string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Personlige"</string>
- <string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Arbejde"</string>
- <string name="widget_category_conversations" msgid="8894438636213590446">"Samtaler"</string>
- <string name="widget_education_header" msgid="4874760613775913787">"Nyttige oplysninger lige ved hånden"</string>
- <string name="widget_education_content" msgid="745542879510751525">"Hvis du vil have oplysninger uden at åbne apps, kan du føje widgets til din startskærm"</string>
- <string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Tryk for at ændre widgetindstillinger"</string>
- <string name="widget_education_close_button" msgid="8676165703104836580">"OK"</string>
- <string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Skift widgetindstillinger"</string>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Tryk og hold for at placere manuelt"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"Tilføj automatisk"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Søg efter apps"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Indlæser apps…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"Der blev ikke fundet nogen apps, som matcher \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
<string name="all_apps_search_market_message" msgid="1366263386197059176">"Søg efter flere apps"</string>
<string name="label_application" msgid="8531721983832654978">"App"</string>
- <string name="all_apps_label" msgid="5015784846527570951">"Alle apps"</string>
<string name="notifications_header" msgid="1404149926117359025">"Notifikationer"</string>
- <string name="long_press_shortcut_to_add" msgid="5405328730817637737">"Hold en genvej nede for at flytte den."</string>
- <string name="long_accessible_way_to_add_shortcut" msgid="2199537273817090740">"Tryk to gange, og hold en genvej nede for at flytte den eller bruge tilpassede handlinger."</string>
- <string name="out_of_space" msgid="6692471482459245734">"Der er ikke ledig plads på startskærmen"</string>
+ <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"Hold en genvej nede for at samle den op."</string>
+ <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"Tryk to gange, og hold en genvej nede for at samle den op eller bruge tilpassede handlinger."</string>
+ <string name="out_of_space" msgid="4691004494942118364">"Der er ikke mere plads på denne startskærm."</string>
<string name="hotseat_out_of_space" msgid="7448809638125333693">"Der er ikke mere plads i bakken Favoritter"</string>
<string name="all_apps_button_label" msgid="8130441508702294465">"Liste med apps"</string>
- <string name="all_apps_search_results" msgid="5889367432531296759">"Søgeresultater"</string>
<string name="all_apps_button_personal_label" msgid="1315764287305224468">"Liste over personlige apps"</string>
<string name="all_apps_button_work_label" msgid="7270707118948892488">"Liste over apps til arbejdet"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"Hjem"</string>
<string name="remove_drop_target_label" msgid="7812859488053230776">"Fjern"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"Afinstaller"</string>
<string name="app_info_drop_target_label" msgid="692894985365717661">"Appinfo"</string>
<string name="install_drop_target_label" msgid="2539096853673231757">"Installer"</string>
- <string name="dismiss_prediction_label" msgid="3357562989568808658">"Foreslå ikke en app"</string>
- <string name="pin_prediction" msgid="4196423321649756498">"Fastgør forslaget"</string>
<string name="permlab_install_shortcut" msgid="5632423390354674437">"installere genveje"</string>
<string name="permdesc_install_shortcut" msgid="923466509822011139">"Tillader, at en app tilføjer genveje uden brugerens indgriben."</string>
<string name="permlab_read_settings" msgid="1941457408239617576">"læs indstillinger og genveje for startskærmen"</string>
@@ -84,13 +60,15 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"skrive indstillinger og genveje for startskærmen"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"Tillader, at appen ændrer indstillingerne og genvejene på startskærmen."</string>
<string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> har ikke tilladelse til at foretage telefonopkald"</string>
- <string name="gadget_error_text" msgid="740356548025791839">"Widgetten kan ikke indlæses"</string>
- <string name="gadget_setup_text" msgid="8348374825537681407">"Widget-indstillinger"</string>
- <string name="gadget_complete_setup_text" msgid="309040266978007925">"Tryk for at fuldføre konfigurationen"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"Der er problemer med indlæsning af widgetten"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"Konfigurer"</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"Dette er en systemapp, som ikke kan afinstalleres."</string>
- <string name="folder_hint_text" msgid="5174843001373488816">"Rediger navn"</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"Unavngiven mappe"</string>
<string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> er deaktiveret"</string>
- <string name="dotted_app_label" msgid="1704091277755818896">"{count,plural,offset:1 =1{{app_name} har # notifikation}one{{app_name} har # notifikation}other{{app_name} har # notifikationer}}"</string>
+ <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+ <item quantity="one"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, har <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> notifikation</item>
+ <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, har <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> notifikationer</item>
+ </plurals>
<string name="default_scroll_format" msgid="7475544710230993317">"Side %1$d ud af %2$d"</string>
<string name="workspace_scroll_format" msgid="8458889198184077399">"Startskærm %1$d ud af %2$d"</string>
<string name="workspace_new_page" msgid="257366611030256142">"Ny startskærm"</string>
@@ -99,31 +77,31 @@
<string name="folder_tap_to_rename" msgid="4017685068016979677">"Tryk for at gemme omdøbningen"</string>
<string name="folder_closed" msgid="4100806530910930934">"Mappen er lukket"</string>
<string name="folder_renamed" msgid="1794088362165669656">"Mappen er omdøbt til <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="folder_name_format_exact" msgid="8626242716117004803">"Mappe: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> elementer"</string>
- <string name="folder_name_format_overflow" msgid="4270108890534995199">"Mappe: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> eller flere elementer"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"Mappe: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"Widgets"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Baggrunde"</string>
- <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Baggrund og stil"</string>
- <string name="settings_button_text" msgid="8873672322605444408">"Indst. for startskærm"</string>
+ <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Stil og baggrunde"</string>
+ <string name="settings_button_text" msgid="8873672322605444408">"Startskærmindstillinger"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Deaktiveret af din administrator"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Tillad rotation af startskærmen"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Når telefonen roteres"</string>
- <string name="notification_dots_title" msgid="9062440428204120317">"Notifikationsprikker"</string>
+ <string name="notification_dots_title" msgid="9062440428204120317">"Notifikationscirkler"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"Til"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"Fra"</string>
<string name="title_missing_notification_access" msgid="7503287056163941064">"Kræver adgang til notifikationer"</string>
- <string name="msg_missing_notification_access" msgid="281113995110910548">"Hvis du vil se notifikationsprikker, skal du aktivere appnotifikationer for <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="msg_missing_notification_access" msgid="281113995110910548">"Hvis du vil se notifikationscirkler, skal du aktivere appnotifikationer for <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="title_change_settings" msgid="1376365968844349552">"Skift indstillinger"</string>
- <string name="notification_dots_service_title" msgid="4284221181793592871">"Vis notifikationsprikker"</string>
- <string name="auto_add_shortcuts_label" msgid="3698776050751790653">"Føj appikoner til startskærmen"</string>
+ <string name="notification_dots_service_title" msgid="4284221181793592871">"Vis notifikationscirkler"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Føj ikon til startskærmen"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"For nye apps"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"Ukendt"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"Fjern"</string>
<string name="abandoned_search" msgid="891119232568284442">"Søg"</string>
<string name="abandoned_promises_title" msgid="7096178467971716750">"Denne app er ikke installeret"</string>
<string name="abandoned_promise_explanation" msgid="3990027586878167529">"Appen, der hører til dette ikon, er ikke installeret. Du kan fjerne den eller prøve at søge efter appen og installere den manuelt."</string>
- <string name="app_installing_title" msgid="5864044122733792085">"<xliff:g id="NAME">%1$s</xliff:g> installeres. <xliff:g id="PROGRESS">%2$s</xliff:g> fuldført"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> downloades. <xliff:g id="PROGRESS">%2$s</xliff:g> er gennemført"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> venter på at installere"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"<xliff:g id="NAME">%1$s</xliff:g>-widgets"</string>
<string name="widgets_list" msgid="796804551140113767">"Liste med widgets"</string>
<string name="widgets_list_closed" msgid="6141506579418771922">"Listen med widgets blev lukket"</string>
<string name="action_add_to_workspace" msgid="8902165848117513641">"Føj til startskærm"</string>
@@ -151,20 +129,15 @@
<string name="action_deep_shortcut" msgid="2864038805849372848">"Genveje"</string>
<string name="shortcuts_menu_with_notifications_description" msgid="2676582286544232849">"Genveje og notifikationer"</string>
<string name="action_dismiss_notification" msgid="5909461085055959187">"Afvis"</string>
- <string name="accessibility_close" msgid="2277148124685870734">"Luk"</string>
<string name="notification_dismissed" msgid="6002233469409822874">"Notifikationen blev afvist"</string>
<string name="all_apps_personal_tab" msgid="4190252696685155002">"Personlige"</string>
<string name="all_apps_work_tab" msgid="4884822796154055118">"Arbejde"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"Arbejdsprofil"</string>
- <string name="work_profile_edu_work_apps" msgid="7895468576497746520">"Arbejdsapps har badges og kan ses af din it-administrator"</string>
- <string name="work_profile_edu_accept" msgid="6069788082535149071">"OK"</string>
- <string name="work_apps_paused_title" msgid="3040901117349444598">"Dine arbejdsapps er sat på pause"</string>
- <string name="work_apps_paused_body" msgid="261634750995824906">"Arbejdsapps kan ikke sende dig notifikationer, bruge dit batteri eller få adgang til din lokation"</string>
- <string name="work_apps_paused_content_description" msgid="5149623040804051095">"Arbejdsapps er deaktiveret. Dine arbejdsapps kan ikke sende dig notifikationer, bruge dit batteri eller få adgang til din lokation"</string>
- <string name="work_apps_paused_edu_banner" msgid="8872412121608402058">"Arbejdsapps har badges og kan ses af din it-administrator"</string>
- <string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"OK"</string>
- <string name="work_apps_pause_btn_text" msgid="1921059713673767460">"Deaktiver arbejdsapps"</string>
- <string name="work_apps_enable_btn_text" msgid="1156432622148413741">"Aktivér arbejdsapps"</string>
- <string name="developer_options_filter_hint" msgid="5896817443635989056">"Filter"</string>
+ <string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"Find arbejdsapps her"</string>
+ <string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"Alle arbejdsapps har et badge og beskyttes af din organisation. Flyt apps til din startskærm, så du nemmere kan få adgang til dem."</string>
+ <string name="work_mode_on_label" msgid="4781128097185272916">"Administreret af din organisation"</string>
+ <string name="work_mode_off_label" msgid="3194894777601421047">"Notifikationer og apps er slået fra"</string>
+ <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Luk"</string>
+ <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Lukket"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Mislykket: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
</resources>
diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml
index a0c784f1fb..a345babd5c 100644
--- a/res/values-de/strings.xml
+++ b/res/values-de/strings.xml
@@ -20,63 +20,39 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="649227358658669779">"Launcher3"</string>
+ <string name="folder_name" msgid="7371454440695724752"></string>
<string name="work_folder_name" msgid="3753320833950115786">"Arbeit"</string>
<string name="activity_not_found" msgid="8071924732094499514">"App ist nicht installiert."</string>
<string name="activity_not_available" msgid="7456344436509528827">"App nicht verfügbar"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"Heruntergeladene App im abgesicherten Modus deaktiviert"</string>
<string name="safemode_widget_error" msgid="4863470563535682004">"Widgets im abgesicherten Modus deaktiviert"</string>
<string name="shortcut_not_available" msgid="2536503539825726397">"Verknüpfung nicht verfügbar"</string>
- <string name="home_screen" msgid="5629429142036709174">"Startbildschirm"</string>
- <string name="recent_task_option_split_screen" msgid="6690461455618725183">"Splitscreen"</string>
- <string name="split_screen_position_top" msgid="1504965011158689649">"Oben teilen"</string>
- <string name="split_screen_position_left" msgid="7537793098851830883">"Links teilen"</string>
- <string name="split_screen_position_right" msgid="1569377524925193369">"Rechts teilen"</string>
- <string name="split_app_info_accessibility" msgid="5475288491241414932">"App-Info für %1$s"</string>
- <string name="long_press_widget_to_add" msgid="3587712543577675817">"Zum Verschieben des Widgets berühren und halten"</string>
- <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Doppeltippen und halten, um ein Widget zu bewegen oder benutzerdefinierte Aktionen zu nutzen."</string>
+ <string name="home_screen" msgid="806512411299847073">"Startbildschirm"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"Benutzerdefinierte Aktionen"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"Zum Hinzufügen Widget berühren und halten"</string>
+ <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Zum Hinzufügen auf Widget doppeltippen und gedrückt halten oder benutzerdefinierte Aktionen verwenden."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d breit und %2$d hoch"</string>
- <string name="widget_preview_context_description" msgid="9045841361655787574">"Widget „<xliff:g id="WIDGET_NAME">%1$s</xliff:g>“"</string>
- <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Wenn du das Widget auf dem Startbildschirm verschieben möchtest, halte es gedrückt"</string>
- <string name="add_to_home_screen" msgid="8631549138215492708">"Zum Startbildschirm hinzufügen"</string>
- <string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g>-Widget zum Startbildschirm hinzugefügt"</string>
- <string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# Widget}other{# Widgets}}"</string>
- <string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{# Verknüpfung}other{# Verknüpfungen}}"</string>
- <string name="widgets_and_shortcuts_count" msgid="7209136747878365116">"<xliff:g id="WIDGETS_COUNT">%1$s</xliff:g>, <xliff:g id="SHORTCUTS_COUNT">%2$s</xliff:g>"</string>
- <string name="widget_button_text" msgid="2880537293434387943">"Widgets"</string>
- <string name="widgets_full_sheet_search_bar_hint" msgid="8484659090860596457">"Suche"</string>
- <string name="widgets_full_sheet_cancel_button_description" msgid="5766167035728653605">"Text aus dem Suchfeld löschen"</string>
- <string name="no_widgets_available" msgid="4337693382501046170">"Widgets und Verknüpfungen nicht verfügbar"</string>
- <string name="no_search_results" msgid="3787956167293097509">"Keine Widgets oder Verknüpfungen gefunden"</string>
- <string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Privat"</string>
- <string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Geschäftlich"</string>
- <string name="widget_category_conversations" msgid="8894438636213590446">"Unterhaltungen"</string>
- <string name="widget_education_header" msgid="4874760613775913787">"Praktische Informationen – immer zur Hand"</string>
- <string name="widget_education_content" msgid="745542879510751525">"Wenn du Informationen erhalten möchtest, ohne Apps zu öffnen, kannst du deinem Startbildschirm Widgets hinzufügen"</string>
- <string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Tippen, um die Widget-Einstellungen zu ändern"</string>
- <string name="widget_education_close_button" msgid="8676165703104836580">"OK"</string>
- <string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Widget-Einstellungen ändern"</string>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Zum manuellen Hinzufügen gedrückt halten"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"Automatisch hinzufügen"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Apps finden"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Apps werden geladen…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"Keine Apps für \"<xliff:g id="QUERY">%1$s</xliff:g>\" gefunden"</string>
<string name="all_apps_search_market_message" msgid="1366263386197059176">"Weitere Apps suchen"</string>
<string name="label_application" msgid="8531721983832654978">"App"</string>
- <string name="all_apps_label" msgid="5015784846527570951">"Alle Apps"</string>
<string name="notifications_header" msgid="1404149926117359025">"Benachrichtigungen"</string>
- <string name="long_press_shortcut_to_add" msgid="5405328730817637737">"Zum Verschieben einer Verknüpfung berühren und halten"</string>
- <string name="long_accessible_way_to_add_shortcut" msgid="2199537273817090740">"Doppeltippen und halten, um eine Verknüpfung zu bewegen oder benutzerdefinierte Aktionen zu nutzen."</string>
- <string name="out_of_space" msgid="6692471482459245734">"Auf diesem Startbildschirm ist kein Platz mehr vorhanden"</string>
+ <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"Tippen und halten, um eine Verknüpfung auszuwählen."</string>
+ <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"Doppeltippen und halten, um eine Verknüpfung auszuwählen oder benutzerdefinierte Aktionen zu nutzen."</string>
+ <string name="out_of_space" msgid="4691004494942118364">"Auf diesem Startbildschirm ist kein Platz mehr vorhanden."</string>
<string name="hotseat_out_of_space" msgid="7448809638125333693">"Ablage \"Favoriten\" ist voll."</string>
<string name="all_apps_button_label" msgid="8130441508702294465">"Liste der Apps"</string>
- <string name="all_apps_search_results" msgid="5889367432531296759">"Suchergebnisse"</string>
<string name="all_apps_button_personal_label" msgid="1315764287305224468">"Liste der privaten Apps"</string>
<string name="all_apps_button_work_label" msgid="7270707118948892488">"Liste der geschäftlichen Apps"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"Startseite"</string>
<string name="remove_drop_target_label" msgid="7812859488053230776">"Entfernen"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"Deinstallieren"</string>
- <string name="app_info_drop_target_label" msgid="692894985365717661">"App-Info"</string>
+ <string name="app_info_drop_target_label" msgid="692894985365717661">"App-Details"</string>
<string name="install_drop_target_label" msgid="2539096853673231757">"Installieren"</string>
- <string name="dismiss_prediction_label" msgid="3357562989568808658">"App nicht vorschlagen"</string>
- <string name="pin_prediction" msgid="4196423321649756498">"Vorgeschlagene App fixieren"</string>
<string name="permlab_install_shortcut" msgid="5632423390354674437">"Verknüpfungen installieren"</string>
<string name="permdesc_install_shortcut" msgid="923466509822011139">"Ermöglicht einer App das Hinzufügen von Verknüpfungen ohne Eingreifen des Nutzers"</string>
<string name="permlab_read_settings" msgid="1941457408239617576">"Einstellungen und Verknüpfungen auf dem Startbildschirm lesen"</string>
@@ -84,13 +60,15 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"Einstellungen und Verknüpfungen für den Startbildschirm schreiben"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"Ermöglicht der App, die Einstellungen und Verknüpfungen auf dem Startbildschirm zu ändern"</string>
<string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> darf keine Telefonanrufe tätigen."</string>
- <string name="gadget_error_text" msgid="740356548025791839">"Widget kann nicht geladen werden"</string>
- <string name="gadget_setup_text" msgid="8348374825537681407">"Widget-Einstellungen"</string>
- <string name="gadget_complete_setup_text" msgid="309040266978007925">"Tippen, um Einrichtung abzuschließen"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"Problem beim Laden des Widgets"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"Einrichten"</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"Dies ist eine Systemanwendung, die nicht deinstalliert werden kann."</string>
- <string name="folder_hint_text" msgid="5174843001373488816">"Name bearbeiten"</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"Unbenannter Ordner"</string>
<string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> deaktiviert"</string>
- <string name="dotted_app_label" msgid="1704091277755818896">"{count,plural,offset:1 =1{{app_name} hat # Benachrichtigung}other{{app_name} hat # Benachrichtigungen}}"</string>
+ <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+ <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, hat <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> Benachrichtigungen</item>
+ <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g>, hat <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> Benachrichtigung</item>
+ </plurals>
<string name="default_scroll_format" msgid="7475544710230993317">"Seite %1$d von %2$d"</string>
<string name="workspace_scroll_format" msgid="8458889198184077399">"Startbildschirm %1$d von %2$d"</string>
<string name="workspace_new_page" msgid="257366611030256142">"Neue Startbildschirmseite"</string>
@@ -99,13 +77,13 @@
<string name="folder_tap_to_rename" msgid="4017685068016979677">"Neuen Namen zum Speichern antippen"</string>
<string name="folder_closed" msgid="4100806530910930934">"Ordner geschlossen"</string>
<string name="folder_renamed" msgid="1794088362165669656">"Ordner umbenannt in <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="folder_name_format_exact" msgid="8626242716117004803">"Ordner: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> Elemente"</string>
- <string name="folder_name_format_overflow" msgid="4270108890534995199">"Ordner: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> oder mehr Elemente"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"Ordner: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"Widgets"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Hintergründe"</string>
- <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Hintergrund &amp; Stil"</string>
+ <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Designs und Hintergründe"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Startbildschirm-Einstellungen"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Von deinem Administrator deaktiviert"</string>
- <string name="allow_rotation_title" msgid="7728578836261442095">"Drehen des Startbildschirms zulassen"</string>
+ <string name="allow_rotation_title" msgid="7728578836261442095">"Drehung des Startbildschirms zulassen"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Beim Drehen des Smartphones"</string>
<string name="notification_dots_title" msgid="9062440428204120317">"App-Benachrichtigungspunkte"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"An"</string>
@@ -114,16 +92,16 @@
<string name="msg_missing_notification_access" msgid="281113995110910548">"Um dir Benachrichtigungspunkte anzeigen zu lassen, aktiviere die Benachrichtigungen für die App \"<xliff:g id="NAME">%1$s</xliff:g>\""</string>
<string name="title_change_settings" msgid="1376365968844349552">"Einstellungen ändern"</string>
<string name="notification_dots_service_title" msgid="4284221181793592871">"App-Benachrichtigungspunkte anzeigen"</string>
- <string name="auto_add_shortcuts_label" msgid="3698776050751790653">"App-Symbole auf Startbildschirm setzen"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Symbol zum Startbildschirm hinzufügen"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Bei neuen Apps"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"Unbekannt"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"Entfernen"</string>
<string name="abandoned_search" msgid="891119232568284442">"Suchen"</string>
<string name="abandoned_promises_title" msgid="7096178467971716750">"Diese App ist nicht installiert"</string>
<string name="abandoned_promise_explanation" msgid="3990027586878167529">"Die App für dieses Symbol ist nicht installiert. Du kannst das Symbol entfernen oder die App lokalisieren und dann manuell installieren."</string>
- <string name="app_installing_title" msgid="5864044122733792085">"<xliff:g id="NAME">%1$s</xliff:g> wird installiert, <xliff:g id="PROGRESS">%2$s</xliff:g> abgeschlossen"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> wird heruntergeladen, <xliff:g id="PROGRESS">%2$s</xliff:g> abgeschlossen"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"Warten auf Installation von <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"<xliff:g id="NAME">%1$s</xliff:g>-Widgets"</string>
<string name="widgets_list" msgid="796804551140113767">"Widgetliste"</string>
<string name="widgets_list_closed" msgid="6141506579418771922">"Widgetliste geschlossen"</string>
<string name="action_add_to_workspace" msgid="8902165848117513641">"Zum Startbildschirm hinzufügen"</string>
@@ -151,20 +129,15 @@
<string name="action_deep_shortcut" msgid="2864038805849372848">"Verknüpfungen"</string>
<string name="shortcuts_menu_with_notifications_description" msgid="2676582286544232849">"Verknüpfungen und Benachrichtigungen"</string>
<string name="action_dismiss_notification" msgid="5909461085055959187">"Schließen"</string>
- <string name="accessibility_close" msgid="2277148124685870734">"Schließen"</string>
<string name="notification_dismissed" msgid="6002233469409822874">"Benachrichtigung geschlossen"</string>
<string name="all_apps_personal_tab" msgid="4190252696685155002">"Privat"</string>
<string name="all_apps_work_tab" msgid="4884822796154055118">"Geschäftlich"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"Arbeitsprofil"</string>
- <string name="work_profile_edu_work_apps" msgid="7895468576497746520">"Geschäftliche Apps sind gekennzeichnet und für deinen IT-Administrator sichtbar"</string>
- <string name="work_profile_edu_accept" msgid="6069788082535149071">"OK"</string>
- <string name="work_apps_paused_title" msgid="3040901117349444598">"Geschäftliche Apps sind pausiert"</string>
- <string name="work_apps_paused_body" msgid="261634750995824906">"Deine geschäftlichen Apps können dir keine Benachrichtigungen senden, deinen Akku nicht nutzen und nicht auf deinen Standort zugreifen"</string>
- <string name="work_apps_paused_content_description" msgid="5149623040804051095">"Geschäftliche Apps sind deaktiviert. Sie können dir keine Benachrichtigungen senden, deinen Akku nicht nutzen und nicht auf deinen Standort zugreifen."</string>
- <string name="work_apps_paused_edu_banner" msgid="8872412121608402058">"Geschäftliche Apps sind gekennzeichnet und für deinen IT-Administrator sichtbar"</string>
- <string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"OK"</string>
- <string name="work_apps_pause_btn_text" msgid="1921059713673767460">"Geschäftliche Apps deaktivieren"</string>
- <string name="work_apps_enable_btn_text" msgid="1156432622148413741">"Geschäftliche Apps aktivieren"</string>
- <string name="developer_options_filter_hint" msgid="5896817443635989056">"Filter"</string>
+ <string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"Hier findest du Apps für die Arbeit"</string>
+ <string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"Jede App für die Arbeit ist mit einem Logo gekennzeichnet. Deine Organisation kümmert sich um den entsprechenden Schutz. Damit du leichter auf Apps zugreifen kannst, verschiebe sie auf deinen Startbildschirm."</string>
+ <string name="work_mode_on_label" msgid="4781128097185272916">"Wird von deiner Organisation verwaltet"</string>
+ <string name="work_mode_off_label" msgid="3194894777601421047">"Benachrichtigungen und Apps sind deaktiviert"</string>
+ <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Schließen"</string>
+ <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Geschlossen"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Fehler: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
</resources>
diff --git a/res/values-el/strings.xml b/res/values-el/strings.xml
index b78db22b1f..d80e905d8c 100644
--- a/res/values-el/strings.xml
+++ b/res/values-el/strings.xml
@@ -26,57 +26,32 @@
<string name="safemode_shortcut_error" msgid="9160126848219158407">"Η λήψη εφαρμογών απενεργοποήθηκε στην Ασφαλή λειτουργία"</string>
<string name="safemode_widget_error" msgid="4863470563535682004">"Τα γραφικά στοιχεία απενεργοποιήθηκαν στην ασφαλή λειτουργία"</string>
<string name="shortcut_not_available" msgid="2536503539825726397">"Η συντόμευση δεν είναι διαθέσιμη"</string>
- <string name="home_screen" msgid="5629429142036709174">"Αρχική οθόνη"</string>
- <string name="recent_task_option_split_screen" msgid="6690461455618725183">"Διαχωρισμός οθόνης"</string>
- <string name="split_screen_position_top" msgid="1504965011158689649">"Διαχωρισμός επάνω"</string>
- <string name="split_screen_position_left" msgid="7537793098851830883">"Διαχωρισμός αριστερά"</string>
- <string name="split_screen_position_right" msgid="1569377524925193369">"Διαχωρισμός δεξιά"</string>
- <string name="split_app_info_accessibility" msgid="5475288491241414932">"Πληροφορίες εφαρμογής για %1$s"</string>
- <string name="long_press_widget_to_add" msgid="3587712543577675817">"Πατήστε παρατετ. για μετακίνηση γραφ. στοιχείου."</string>
- <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Πατήστε δύο φορές παρατεταμένα για μετακίνηση γραφικού στοιχείου ή χρήση προσαρμοσμένων ενεργειών."</string>
+ <string name="home_screen" msgid="806512411299847073">"Αρχική οθόνη"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"Προσαρμοσμένες ενέργειες"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"Αγγίξτε παρατεταμένα για να πάρετε ένα γραφ.στοιχ."</string>
+ <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Πατήστε δύο φορές παρατεταμένα για επιλογή γραφικού στοιχείου ή χρήση προσαρμοσμένων ενεργειών."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"Πλάτος %1$d επί ύψος %2$d"</string>
- <string name="widget_preview_context_description" msgid="9045841361655787574">"Γραφικό στοιχείο <xliff:g id="WIDGET_NAME">%1$s</xliff:g>"</string>
- <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Αγγίξτε παρατεταμένα το γραφικό στοιχείο για να το μετακινήσετε στην Αρχική οθόνη"</string>
- <string name="add_to_home_screen" msgid="8631549138215492708">"Προσθήκη στην Αρχική οθόνη"</string>
- <string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"Το γραφικό στοιχείο <xliff:g id="WIDGET_NAME">%1$s</xliff:g> προστέθηκε στην αρχική οθόνη."</string>
- <string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# γραφικό στοιχείο}other{# γραφικά στοιχεία}}"</string>
- <string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{# συντόμευση}other{# συντομεύσεις}}"</string>
- <string name="widgets_and_shortcuts_count" msgid="7209136747878365116">"<xliff:g id="WIDGETS_COUNT">%1$s</xliff:g>, <xliff:g id="SHORTCUTS_COUNT">%2$s</xliff:g>"</string>
- <string name="widget_button_text" msgid="2880537293434387943">"Γραφικά στοιχεία"</string>
- <string name="widgets_full_sheet_search_bar_hint" msgid="8484659090860596457">"Αναζήτηση"</string>
- <string name="widgets_full_sheet_cancel_button_description" msgid="5766167035728653605">"Διαγραφή κειμένου από το πλαίσιο αναζήτησης"</string>
- <string name="no_widgets_available" msgid="4337693382501046170">"Δεν υπάρχουν διαθέσιμα γραφικά στοιχεία και συντομεύσεις."</string>
- <string name="no_search_results" msgid="3787956167293097509">"Δεν βρέθηκαν γραφικά στοιχεία ή συντομεύσεις."</string>
- <string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Προσωπικά"</string>
- <string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Εργασίας"</string>
- <string name="widget_category_conversations" msgid="8894438636213590446">"Συζητήσεις"</string>
- <string name="widget_education_header" msgid="4874760613775913787">"Χρήσιμες πληροφορίες στη διάθεσή σας"</string>
- <string name="widget_education_content" msgid="745542879510751525">"Για να λάβετε πληροφορίες χωρίς να ανοίξετε εφαρμογές, μπορείτε να προσθέσετε γραφικά στοιχεία στην αρχική σας οθόνη."</string>
- <string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Πατήστε για αλλαγή των ρυθμίσεων του γραφικού στοιχείου"</string>
- <string name="widget_education_close_button" msgid="8676165703104836580">"Το κατάλαβα"</string>
- <string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Αλλαγή ρυθμίσεων γραφικού στοιχείου"</string>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Αγγίξτε παρατεταμένα για μη αυτόματη τοποθέτηση"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"Αυτόματη προσθήκη"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Αναζήτηση εφαρμογών"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Φόρτωση εφαρμογών…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"Δεν βρέθηκαν εφαρμογές αντιστοίχισης για \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
<string name="all_apps_search_market_message" msgid="1366263386197059176">"Αναζήτηση περισσότερων εφαρμογών"</string>
<string name="label_application" msgid="8531721983832654978">"Εφαρμογή"</string>
- <string name="all_apps_label" msgid="5015784846527570951">"Όλες οι εφαρμογές"</string>
<string name="notifications_header" msgid="1404149926117359025">"Ειδοποιήσεις"</string>
- <string name="long_press_shortcut_to_add" msgid="5405328730817637737">"Πατήστε παρατεταμένα για μετακίνηση συντόμευσης."</string>
- <string name="long_accessible_way_to_add_shortcut" msgid="2199537273817090740">"Πατήστε δύο φορές παρατεταμένα για μετακίνηση συντόμευσης ή χρήση προσαρμοσμένων ενεργειών."</string>
- <string name="out_of_space" msgid="6692471482459245734">"Δεν υπάρχει χώρος σε αυτήν την αρχική οθόνη"</string>
+ <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"Αγγίξτε παρατεταμένα για επιλογή συντόμευσης."</string>
+ <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"Πατήσετε δύο φορές παρατεταμένα για επιλογή συντόμευσης ή χρήση προσαρμοσμένων ενεργειών."</string>
+ <string name="out_of_space" msgid="4691004494942118364">"Δεν υπάρχει χώρος σε αυτήν την αρχική οθόνη."</string>
<string name="hotseat_out_of_space" msgid="7448809638125333693">"Δεν υπάρχει επιπλέον χώρος στην περιοχή Αγαπημένα"</string>
<string name="all_apps_button_label" msgid="8130441508702294465">"Λίστα εφαρμογών"</string>
- <string name="all_apps_search_results" msgid="5889367432531296759">"Αποτελέσματα αναζήτησης"</string>
<string name="all_apps_button_personal_label" msgid="1315764287305224468">"Λίστα προσωπικών εφαρμογών"</string>
<string name="all_apps_button_work_label" msgid="7270707118948892488">"Λίστα εφαρμογών εργασίας"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"Αρχική οθόνη"</string>
<string name="remove_drop_target_label" msgid="7812859488053230776">"Κατάργηση"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"Απεγκατάσταση"</string>
- <string name="app_info_drop_target_label" msgid="692894985365717661">"Πληροφ. εφαρμογής"</string>
+ <string name="app_info_drop_target_label" msgid="692894985365717661">"Πληροφορίες εφαρμογής"</string>
<string name="install_drop_target_label" msgid="2539096853673231757">"Εγκατάσταση"</string>
- <string name="dismiss_prediction_label" msgid="3357562989568808658">"Να μην προτείνεται η εφαρμογή"</string>
- <string name="pin_prediction" msgid="4196423321649756498">"Καρφίτσωμα πρόβλεψης"</string>
<string name="permlab_install_shortcut" msgid="5632423390354674437">"εγκατάσταση συντομεύσεων"</string>
<string name="permdesc_install_shortcut" msgid="923466509822011139">"Επιτρέπει σε μια εφαρμογή την προσθήκη συντομεύσεων χωρίς την παρέμβαση του χρήστη."</string>
<string name="permlab_read_settings" msgid="1941457408239617576">"ανάγνωση ρυθμίσεων και συντομεύσεων αρχικής οθόνης"</string>
@@ -84,13 +59,15 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"εγγραφή ρυθμίσεων και συντομεύσεων αρχικής οθόνης"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"Επιτρέπει στην εφαρμογή την αλλαγή των ρυθμίσεων και των συντομεύσεων στην Αρχική οθόνη."</string>
<string name="msg_no_phone_permission" msgid="9208659281529857371">"Η εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g> δεν επιτρέπεται να πραγματοποιεί τηλεφωνικές κλήσεις"</string>
- <string name="gadget_error_text" msgid="740356548025791839">"Δεν είναι δυνατή η φόρτωση του γραφικού στοιχείου"</string>
- <string name="gadget_setup_text" msgid="8348374825537681407">"Ρυθμίσεις γραφικών στοιχείων"</string>
- <string name="gadget_complete_setup_text" msgid="309040266978007925">"Πατήστε για να ολοκληρώσετε τη ρύθμιση"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"Παρουσιάστηκε πρόβλημα στη φόρτωση του γραφικού στοιχείου"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"Ρύθμιση"</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"Αυτή είναι μια εφαρμογή συστήματος και δεν είναι δυνατή η κατάργηση της εγκατάστασής της."</string>
- <string name="folder_hint_text" msgid="5174843001373488816">"Επεξεργασία ονόματος"</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"Φάκελος χωρίς όνομα"</string>
<string name="disabled_app_label" msgid="6673129024321402780">"Η εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g> είναι απενεργοποιημένη"</string>
- <string name="dotted_app_label" msgid="1704091277755818896">"{count,plural,offset:1 =1{Η εφαρμογή {app_name} έχει # ειδοποίηση}other{Η εφαρμογή {app_name} έχει # ειδοποιήσεις}}"</string>
+ <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+ <item quantity="other">Η εφαρμογή <xliff:g id="APP_NAME_2">%1$s</xliff:g>, έχει <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> ειδοποιήσεις</item>
+ <item quantity="one">Η εφαρμογή <xliff:g id="APP_NAME_0">%1$s</xliff:g>, έχει <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> ειδοποίηση</item>
+ </plurals>
<string name="default_scroll_format" msgid="7475544710230993317">"Σελίδα %1$d από %2$d"</string>
<string name="workspace_scroll_format" msgid="8458889198184077399">"Αρχική οθόνη %1$d από %2$d"</string>
<string name="workspace_new_page" msgid="257366611030256142">"Νέα σελίδα αρχικής οθόνης"</string>
@@ -99,10 +76,10 @@
<string name="folder_tap_to_rename" msgid="4017685068016979677">"Πατήστε για να αποθηκεύσετε τη νέα ονομασία"</string>
<string name="folder_closed" msgid="4100806530910930934">"Ο φάκελος έκλεισε"</string>
<string name="folder_renamed" msgid="1794088362165669656">"Ο φάκελος μετονομάστηκε σε <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="folder_name_format_exact" msgid="8626242716117004803">"Φάκελος: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> στοιχεία"</string>
- <string name="folder_name_format_overflow" msgid="4270108890534995199">"Φάκελος: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> ή περισσότερα στοιχεία"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"Φάκελος: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"Γραφικά στοιχεία"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Ταπετσαρίες"</string>
- <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Ταπετσαρία και στιλ"</string>
+ <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Στιλ και ταπετσαρίες"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Ρυθμίσεις Αρχ. Οθ."</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Απενεργοποιήθηκε από τον διαχειριστή σας"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Να επιτρέπεται η περιστροφή της αρχικής οθόνης"</string>
@@ -114,16 +91,16 @@
<string name="msg_missing_notification_access" msgid="281113995110910548">"Για να εμφανιστούν οι Κουκκίδες ειδοποίησης, ενεργοποιήστε τις κουκκίδες εφαρμογής για την εφαρμογή <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="title_change_settings" msgid="1376365968844349552">"Αλλαγή ρυθμίσεων"</string>
<string name="notification_dots_service_title" msgid="4284221181793592871">"Εμφάνιση κουκκίδων ειδοποιήσεων"</string>
- <string name="auto_add_shortcuts_label" msgid="3698776050751790653">"Προσθ. εικονιδίων εφαρμ. σε αρχική οθόνη"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Προσθήκη εικονιδίου στην Αρχική οθόνη"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Για νέες εφαρμογές"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"Άγνωστο"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"Κατάργηση"</string>
<string name="abandoned_search" msgid="891119232568284442">"Αναζήτηση"</string>
<string name="abandoned_promises_title" msgid="7096178467971716750">"Αυτή η εφαρμογή δεν είναι εγκατεστημένη"</string>
<string name="abandoned_promise_explanation" msgid="3990027586878167529">"Η εφαρμογή γι\' αυτό το εικονίδιο δεν είναι εγκατεστημένη. Μπορείτε να το καταργήσετε ή να αναζητήσετε την εφαρμογή και να την εγκαταστήσετε με μη αυτόματο τρόπο."</string>
- <string name="app_installing_title" msgid="5864044122733792085">"Έχει ολοκληρωθεί το <xliff:g id="PROGRESS">%2$s</xliff:g> της εγκατάστασης της εφαρμογής <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"Λήψη <xliff:g id="NAME">%1$s</xliff:g>, ολοκληρώθηκε <xliff:g id="PROGRESS">%2$s</xliff:g>"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> σε αναμονή για εγκατάσταση"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"Γραφικά στοιχεία <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="widgets_list" msgid="796804551140113767">"Λίστα γραφικών στοιχείων"</string>
<string name="widgets_list_closed" msgid="6141506579418771922">"Η λίστα γραφικών στοιχείων έκλεισε"</string>
<string name="action_add_to_workspace" msgid="8902165848117513641">"Προσθήκη στην αρχική οθόνη"</string>
@@ -151,20 +128,15 @@
<string name="action_deep_shortcut" msgid="2864038805849372848">"Συντομεύσεις"</string>
<string name="shortcuts_menu_with_notifications_description" msgid="2676582286544232849">"Συντομεύσεις και ειδοποιήσεις"</string>
<string name="action_dismiss_notification" msgid="5909461085055959187">"Παράβλεψη"</string>
- <string name="accessibility_close" msgid="2277148124685870734">"Κλείσιμο"</string>
<string name="notification_dismissed" msgid="6002233469409822874">"Η ειδοποίηση παραβλέφθηκε"</string>
<string name="all_apps_personal_tab" msgid="4190252696685155002">"Προσωπικές"</string>
<string name="all_apps_work_tab" msgid="4884822796154055118">"Εργασίας"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"Προφίλ εργασίας"</string>
- <string name="work_profile_edu_work_apps" msgid="7895468576497746520">"Οι εφαρμογές εργασιών φέρουν σήμα και είναι ορατές στον διαχειριστή IT σας"</string>
- <string name="work_profile_edu_accept" msgid="6069788082535149071">"Το κατάλαβα"</string>
- <string name="work_apps_paused_title" msgid="3040901117349444598">"Οι εφαρμογές εργασίας τέθηκαν σε παύση."</string>
- <string name="work_apps_paused_body" msgid="261634750995824906">"Οι εφαρμογές εργασίας δεν έχουν τη δυνατότητα αποστολής ειδοποιήσεων, χρήσης της μπαταρίας ή πρόσβασης στην τοποθεσία σας"</string>
- <string name="work_apps_paused_content_description" msgid="5149623040804051095">"Οι εφαρμογές εργασίας είναι απενεργοποιημένες. Οι εφαρμογές εργασίας δεν έχουν τη δυνατότητα αποστολής ειδοποιήσεων, χρήσης της μπαταρίας ή πρόσβασης στην τοποθεσία σας"</string>
- <string name="work_apps_paused_edu_banner" msgid="8872412121608402058">"Οι εφαρμογές εργασιών φέρουν σήμα και είναι ορατές στον διαχειριστή IT σας"</string>
- <string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"Το κατάλαβα"</string>
- <string name="work_apps_pause_btn_text" msgid="1921059713673767460">"Απενεργοποίηση εφαρμογών εργασιών"</string>
- <string name="work_apps_enable_btn_text" msgid="1156432622148413741">"Ενεργοποίηση εφαρμογών εργασίας"</string>
- <string name="developer_options_filter_hint" msgid="5896817443635989056">"Φίλτρο"</string>
+ <string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"Βρείτε όλες τις εφαρμογές εργασίας εδώ"</string>
+ <string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"Κάθε εφαρμογή εργασίας φέρει ένα σήμα και διατηρείται ασφαλής από τον οργανισμό σας. Μετακινήστε τις εφαρμογές εργασίας στην Αρχική οθόνη, για να έχετε πιο εύκολη πρόσβαση."</string>
+ <string name="work_mode_on_label" msgid="4781128097185272916">"Διαχειριζόμενο από τον οργανισμό σας"</string>
+ <string name="work_mode_off_label" msgid="3194894777601421047">"Οι ειδοποιήσεις και οι εφαρμογές είναι απενεργοποιημένες"</string>
+ <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Κλείσιμο"</string>
+ <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Κλειστή"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Αποτυχία: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
</resources>
diff --git a/res/values-en-rAU/strings.xml b/res/values-en-rAU/strings.xml
index 29a726c532..7adc2187ec 100644
--- a/res/values-en-rAU/strings.xml
+++ b/res/values-en-rAU/strings.xml
@@ -26,57 +26,32 @@
<string name="safemode_shortcut_error" msgid="9160126848219158407">"Downloaded app disabled in Safe mode"</string>
<string name="safemode_widget_error" msgid="4863470563535682004">"Widgets disabled in Safe mode"</string>
<string name="shortcut_not_available" msgid="2536503539825726397">"Shortcut isn\'t available"</string>
- <string name="home_screen" msgid="5629429142036709174">"Home"</string>
- <string name="recent_task_option_split_screen" msgid="6690461455618725183">"Split screen"</string>
- <string name="split_screen_position_top" msgid="1504965011158689649">"Split top"</string>
- <string name="split_screen_position_left" msgid="7537793098851830883">"Split left"</string>
- <string name="split_screen_position_right" msgid="1569377524925193369">"Split right"</string>
- <string name="split_app_info_accessibility" msgid="5475288491241414932">"App info for %1$s"</string>
- <string name="long_press_widget_to_add" msgid="3587712543577675817">"Touch and hold to move a widget."</string>
- <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Double-tap &amp; hold to move a widget or use custom actions."</string>
+ <string name="home_screen" msgid="806512411299847073">"Home screen"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"Customised actions"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"Touch &amp; hold to pick up a widget."</string>
+ <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Double-tap &amp; hold to pick up a widget or use customised actions."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d wide by %2$d high"</string>
- <string name="widget_preview_context_description" msgid="9045841361655787574">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g> widget"</string>
- <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Touch and hold the widget to move it around the home screen"</string>
- <string name="add_to_home_screen" msgid="8631549138215492708">"Add to home screen"</string>
- <string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g> widget added to home screen"</string>
- <string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# widget}other{# widgets}}"</string>
- <string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{# shortcut}other{# shortcuts}}"</string>
- <string name="widgets_and_shortcuts_count" msgid="7209136747878365116">"<xliff:g id="WIDGETS_COUNT">%1$s</xliff:g>, <xliff:g id="SHORTCUTS_COUNT">%2$s</xliff:g>"</string>
- <string name="widget_button_text" msgid="2880537293434387943">"Widgets"</string>
- <string name="widgets_full_sheet_search_bar_hint" msgid="8484659090860596457">"Search"</string>
- <string name="widgets_full_sheet_cancel_button_description" msgid="5766167035728653605">"Clear text from search box"</string>
- <string name="no_widgets_available" msgid="4337693382501046170">"Widgets and shortcuts aren\'t available"</string>
- <string name="no_search_results" msgid="3787956167293097509">"No widgets or shortcuts found"</string>
- <string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Personal"</string>
- <string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Work"</string>
- <string name="widget_category_conversations" msgid="8894438636213590446">"Conversations"</string>
- <string name="widget_education_header" msgid="4874760613775913787">"Useful info at your fingertips"</string>
- <string name="widget_education_content" msgid="745542879510751525">"To get info without opening apps, you can add widgets to your home screen"</string>
- <string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Tap to change widget settings"</string>
- <string name="widget_education_close_button" msgid="8676165703104836580">"OK"</string>
- <string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Change widget settings"</string>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Touch &amp; hold to place manually"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"Add automatically"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Search apps"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Loading apps…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"No apps found matching \'<xliff:g id="QUERY">%1$s</xliff:g>\'"</string>
<string name="all_apps_search_market_message" msgid="1366263386197059176">"Search for more apps"</string>
<string name="label_application" msgid="8531721983832654978">"App"</string>
- <string name="all_apps_label" msgid="5015784846527570951">"All apps"</string>
<string name="notifications_header" msgid="1404149926117359025">"Notifications"</string>
- <string name="long_press_shortcut_to_add" msgid="5405328730817637737">"Touch &amp; hold to move a shortcut."</string>
- <string name="long_accessible_way_to_add_shortcut" msgid="2199537273817090740">"Double-tap &amp; hold to move a shortcut or use custom actions."</string>
- <string name="out_of_space" msgid="6692471482459245734">"No room on this home screen"</string>
+ <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"Touch &amp; hold to pick up a shortcut."</string>
+ <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"Double-tap &amp; hold to pick up a shortcut or use custom actions."</string>
+ <string name="out_of_space" msgid="4691004494942118364">"No more room on this Home screen."</string>
<string name="hotseat_out_of_space" msgid="7448809638125333693">"No more room in the Favourites tray"</string>
<string name="all_apps_button_label" msgid="8130441508702294465">"Apps list"</string>
- <string name="all_apps_search_results" msgid="5889367432531296759">"Search results"</string>
<string name="all_apps_button_personal_label" msgid="1315764287305224468">"Personal apps list"</string>
<string name="all_apps_button_work_label" msgid="7270707118948892488">"Work apps list"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"Home"</string>
<string name="remove_drop_target_label" msgid="7812859488053230776">"Remove"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"Uninstall"</string>
<string name="app_info_drop_target_label" msgid="692894985365717661">"App info"</string>
<string name="install_drop_target_label" msgid="2539096853673231757">"Install"</string>
- <string name="dismiss_prediction_label" msgid="3357562989568808658">"Don\'t suggest app"</string>
- <string name="pin_prediction" msgid="4196423321649756498">"Pin prediction"</string>
<string name="permlab_install_shortcut" msgid="5632423390354674437">"install shortcuts"</string>
<string name="permdesc_install_shortcut" msgid="923466509822011139">"Allows an app to add shortcuts without user intervention."</string>
<string name="permlab_read_settings" msgid="1941457408239617576">"read Home settings and shortcuts"</string>
@@ -84,13 +59,15 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"write Home settings and shortcuts"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"Allows the app to change the settings and shortcuts in Home."</string>
<string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> is not allowed to make phone calls"</string>
- <string name="gadget_error_text" msgid="740356548025791839">"Can\'t load widget"</string>
- <string name="gadget_setup_text" msgid="8348374825537681407">"Widget settings"</string>
- <string name="gadget_complete_setup_text" msgid="309040266978007925">"Tap to finish setup"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"Problem loading widget"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"Setup"</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"This is a system app and can\'t be uninstalled."</string>
- <string name="folder_hint_text" msgid="5174843001373488816">"Edit Name"</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"Unnamed Folder"</string>
<string name="disabled_app_label" msgid="6673129024321402780">"Disabled <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
- <string name="dotted_app_label" msgid="1704091277755818896">"{count,plural,offset:1 =1{{app_name} has # notification}other{{app_name} has # notifications}}"</string>
+ <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+ <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, has <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> notifications</item>
+ <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g>, has <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> notification</item>
+ </plurals>
<string name="default_scroll_format" msgid="7475544710230993317">"Page %1$d of %2$d"</string>
<string name="workspace_scroll_format" msgid="8458889198184077399">"Home screen %1$d of %2$d"</string>
<string name="workspace_new_page" msgid="257366611030256142">"New home screen page"</string>
@@ -99,10 +76,10 @@
<string name="folder_tap_to_rename" msgid="4017685068016979677">"Tap to save rename"</string>
<string name="folder_closed" msgid="4100806530910930934">"Folder closed"</string>
<string name="folder_renamed" msgid="1794088362165669656">"Folder renamed to <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="folder_name_format_exact" msgid="8626242716117004803">"Folder: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> items"</string>
- <string name="folder_name_format_overflow" msgid="4270108890534995199">"Folder: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> or more items"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"Folder: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"Widgets"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Wallpapers"</string>
- <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Wallpaper &amp; style"</string>
+ <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Styles &amp; wallpapers"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Home settings"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Disabled by your admin"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Allow Home screen rotation"</string>
@@ -114,16 +91,16 @@
<string name="msg_missing_notification_access" msgid="281113995110910548">"To show Notification Dots, turn on app notifications for <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="title_change_settings" msgid="1376365968844349552">"Change settings"</string>
<string name="notification_dots_service_title" msgid="4284221181793592871">"Show notification dots"</string>
- <string name="auto_add_shortcuts_label" msgid="3698776050751790653">"Add app icons to the home screen"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Add icon to Home screen"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"For new apps"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"Unknown"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"Remove"</string>
<string name="abandoned_search" msgid="891119232568284442">"Search"</string>
<string name="abandoned_promises_title" msgid="7096178467971716750">"This app is not installed"</string>
<string name="abandoned_promise_explanation" msgid="3990027586878167529">"The app for this icon isn\'t installed. You can remove it, or search for the app and install it manually."</string>
- <string name="app_installing_title" msgid="5864044122733792085">"<xliff:g id="NAME">%1$s</xliff:g> installing, <xliff:g id="PROGRESS">%2$s</xliff:g> complete"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> downloading, <xliff:g id="PROGRESS">%2$s</xliff:g> complete"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> waiting to install"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"<xliff:g id="NAME">%1$s</xliff:g> widgets"</string>
<string name="widgets_list" msgid="796804551140113767">"Widgets list"</string>
<string name="widgets_list_closed" msgid="6141506579418771922">"Widgets list closed"</string>
<string name="action_add_to_workspace" msgid="8902165848117513641">"Add to Home screen"</string>
@@ -151,20 +128,15 @@
<string name="action_deep_shortcut" msgid="2864038805849372848">"Short cuts"</string>
<string name="shortcuts_menu_with_notifications_description" msgid="2676582286544232849">"Shortcuts and notifications"</string>
<string name="action_dismiss_notification" msgid="5909461085055959187">"Dismiss"</string>
- <string name="accessibility_close" msgid="2277148124685870734">"Close"</string>
<string name="notification_dismissed" msgid="6002233469409822874">"Notification dismissed"</string>
<string name="all_apps_personal_tab" msgid="4190252696685155002">"Personal"</string>
<string name="all_apps_work_tab" msgid="4884822796154055118">"Work"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"Work profile"</string>
- <string name="work_profile_edu_work_apps" msgid="7895468576497746520">"Work apps are badged and visible to your IT admin"</string>
- <string name="work_profile_edu_accept" msgid="6069788082535149071">"OK"</string>
- <string name="work_apps_paused_title" msgid="3040901117349444598">"Work apps are paused"</string>
- <string name="work_apps_paused_body" msgid="261634750995824906">"Your work apps can’t send you notifications, use your battery or access your location"</string>
- <string name="work_apps_paused_content_description" msgid="5149623040804051095">"Work apps are off. Your work apps can’t send you notifications, use your battery or access your location"</string>
- <string name="work_apps_paused_edu_banner" msgid="8872412121608402058">"Work apps are badged and visible to your IT admin"</string>
- <string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"OK"</string>
- <string name="work_apps_pause_btn_text" msgid="1921059713673767460">"Turn off work apps"</string>
- <string name="work_apps_enable_btn_text" msgid="1156432622148413741">"Turn on work apps"</string>
- <string name="developer_options_filter_hint" msgid="5896817443635989056">"Filter"</string>
+ <string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"Find work apps here"</string>
+ <string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"Each work app has a badge and is kept secure by your organisation. Move apps to your Home screen for easier access."</string>
+ <string name="work_mode_on_label" msgid="4781128097185272916">"Managed by your organisation"</string>
+ <string name="work_mode_off_label" msgid="3194894777601421047">"Notifications and apps are off"</string>
+ <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Close"</string>
+ <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Closed"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Failed: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
</resources>
diff --git a/res/values-en-rCA/strings.xml b/res/values-en-rCA/strings.xml
deleted file mode 100644
index 29a726c532..0000000000
--- a/res/values-en-rCA/strings.xml
+++ /dev/null
@@ -1,170 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2008 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.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="649227358658669779">"Launcher3"</string>
- <string name="work_folder_name" msgid="3753320833950115786">"Work"</string>
- <string name="activity_not_found" msgid="8071924732094499514">"App isn\'t installed."</string>
- <string name="activity_not_available" msgid="7456344436509528827">"App isn\'t available"</string>
- <string name="safemode_shortcut_error" msgid="9160126848219158407">"Downloaded app disabled in Safe mode"</string>
- <string name="safemode_widget_error" msgid="4863470563535682004">"Widgets disabled in Safe mode"</string>
- <string name="shortcut_not_available" msgid="2536503539825726397">"Shortcut isn\'t available"</string>
- <string name="home_screen" msgid="5629429142036709174">"Home"</string>
- <string name="recent_task_option_split_screen" msgid="6690461455618725183">"Split screen"</string>
- <string name="split_screen_position_top" msgid="1504965011158689649">"Split top"</string>
- <string name="split_screen_position_left" msgid="7537793098851830883">"Split left"</string>
- <string name="split_screen_position_right" msgid="1569377524925193369">"Split right"</string>
- <string name="split_app_info_accessibility" msgid="5475288491241414932">"App info for %1$s"</string>
- <string name="long_press_widget_to_add" msgid="3587712543577675817">"Touch and hold to move a widget."</string>
- <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Double-tap &amp; hold to move a widget or use custom actions."</string>
- <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
- <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d wide by %2$d high"</string>
- <string name="widget_preview_context_description" msgid="9045841361655787574">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g> widget"</string>
- <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Touch and hold the widget to move it around the home screen"</string>
- <string name="add_to_home_screen" msgid="8631549138215492708">"Add to home screen"</string>
- <string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g> widget added to home screen"</string>
- <string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# widget}other{# widgets}}"</string>
- <string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{# shortcut}other{# shortcuts}}"</string>
- <string name="widgets_and_shortcuts_count" msgid="7209136747878365116">"<xliff:g id="WIDGETS_COUNT">%1$s</xliff:g>, <xliff:g id="SHORTCUTS_COUNT">%2$s</xliff:g>"</string>
- <string name="widget_button_text" msgid="2880537293434387943">"Widgets"</string>
- <string name="widgets_full_sheet_search_bar_hint" msgid="8484659090860596457">"Search"</string>
- <string name="widgets_full_sheet_cancel_button_description" msgid="5766167035728653605">"Clear text from search box"</string>
- <string name="no_widgets_available" msgid="4337693382501046170">"Widgets and shortcuts aren\'t available"</string>
- <string name="no_search_results" msgid="3787956167293097509">"No widgets or shortcuts found"</string>
- <string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Personal"</string>
- <string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Work"</string>
- <string name="widget_category_conversations" msgid="8894438636213590446">"Conversations"</string>
- <string name="widget_education_header" msgid="4874760613775913787">"Useful info at your fingertips"</string>
- <string name="widget_education_content" msgid="745542879510751525">"To get info without opening apps, you can add widgets to your home screen"</string>
- <string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Tap to change widget settings"</string>
- <string name="widget_education_close_button" msgid="8676165703104836580">"OK"</string>
- <string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Change widget settings"</string>
- <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Search apps"</string>
- <string name="all_apps_loading_message" msgid="5813968043155271636">"Loading apps…"</string>
- <string name="all_apps_no_search_results" msgid="3200346862396363786">"No apps found matching \'<xliff:g id="QUERY">%1$s</xliff:g>\'"</string>
- <string name="all_apps_search_market_message" msgid="1366263386197059176">"Search for more apps"</string>
- <string name="label_application" msgid="8531721983832654978">"App"</string>
- <string name="all_apps_label" msgid="5015784846527570951">"All apps"</string>
- <string name="notifications_header" msgid="1404149926117359025">"Notifications"</string>
- <string name="long_press_shortcut_to_add" msgid="5405328730817637737">"Touch &amp; hold to move a shortcut."</string>
- <string name="long_accessible_way_to_add_shortcut" msgid="2199537273817090740">"Double-tap &amp; hold to move a shortcut or use custom actions."</string>
- <string name="out_of_space" msgid="6692471482459245734">"No room on this home screen"</string>
- <string name="hotseat_out_of_space" msgid="7448809638125333693">"No more room in the Favourites tray"</string>
- <string name="all_apps_button_label" msgid="8130441508702294465">"Apps list"</string>
- <string name="all_apps_search_results" msgid="5889367432531296759">"Search results"</string>
- <string name="all_apps_button_personal_label" msgid="1315764287305224468">"Personal apps list"</string>
- <string name="all_apps_button_work_label" msgid="7270707118948892488">"Work apps list"</string>
- <string name="remove_drop_target_label" msgid="7812859488053230776">"Remove"</string>
- <string name="uninstall_drop_target_label" msgid="4722034217958379417">"Uninstall"</string>
- <string name="app_info_drop_target_label" msgid="692894985365717661">"App info"</string>
- <string name="install_drop_target_label" msgid="2539096853673231757">"Install"</string>
- <string name="dismiss_prediction_label" msgid="3357562989568808658">"Don\'t suggest app"</string>
- <string name="pin_prediction" msgid="4196423321649756498">"Pin prediction"</string>
- <string name="permlab_install_shortcut" msgid="5632423390354674437">"install shortcuts"</string>
- <string name="permdesc_install_shortcut" msgid="923466509822011139">"Allows an app to add shortcuts without user intervention."</string>
- <string name="permlab_read_settings" msgid="1941457408239617576">"read Home settings and shortcuts"</string>
- <string name="permdesc_read_settings" msgid="5833423719057558387">"Allows the app to read the settings and shortcuts in Home."</string>
- <string name="permlab_write_settings" msgid="3574213698004620587">"write Home settings and shortcuts"</string>
- <string name="permdesc_write_settings" msgid="5440712911516509985">"Allows the app to change the settings and shortcuts in Home."</string>
- <string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> is not allowed to make phone calls"</string>
- <string name="gadget_error_text" msgid="740356548025791839">"Can\'t load widget"</string>
- <string name="gadget_setup_text" msgid="8348374825537681407">"Widget settings"</string>
- <string name="gadget_complete_setup_text" msgid="309040266978007925">"Tap to finish setup"</string>
- <string name="uninstall_system_app_text" msgid="4172046090762920660">"This is a system app and can\'t be uninstalled."</string>
- <string name="folder_hint_text" msgid="5174843001373488816">"Edit Name"</string>
- <string name="disabled_app_label" msgid="6673129024321402780">"Disabled <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
- <string name="dotted_app_label" msgid="1704091277755818896">"{count,plural,offset:1 =1{{app_name} has # notification}other{{app_name} has # notifications}}"</string>
- <string name="default_scroll_format" msgid="7475544710230993317">"Page %1$d of %2$d"</string>
- <string name="workspace_scroll_format" msgid="8458889198184077399">"Home screen %1$d of %2$d"</string>
- <string name="workspace_new_page" msgid="257366611030256142">"New home screen page"</string>
- <string name="folder_opened" msgid="94695026776264709">"Folder opened, <xliff:g id="WIDTH">%1$d</xliff:g> by <xliff:g id="HEIGHT">%2$d</xliff:g>"</string>
- <string name="folder_tap_to_close" msgid="4625795376335528256">"Tap to close folder"</string>
- <string name="folder_tap_to_rename" msgid="4017685068016979677">"Tap to save rename"</string>
- <string name="folder_closed" msgid="4100806530910930934">"Folder closed"</string>
- <string name="folder_renamed" msgid="1794088362165669656">"Folder renamed to <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="folder_name_format_exact" msgid="8626242716117004803">"Folder: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> items"</string>
- <string name="folder_name_format_overflow" msgid="4270108890534995199">"Folder: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> or more items"</string>
- <string name="wallpaper_button_text" msgid="8404103075899945851">"Wallpapers"</string>
- <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Wallpaper &amp; style"</string>
- <string name="settings_button_text" msgid="8873672322605444408">"Home settings"</string>
- <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Disabled by your admin"</string>
- <string name="allow_rotation_title" msgid="7728578836261442095">"Allow Home screen rotation"</string>
- <string name="allow_rotation_desc" msgid="8662546029078692509">"When phone is rotated"</string>
- <string name="notification_dots_title" msgid="9062440428204120317">"Notification dots"</string>
- <string name="notification_dots_desc_on" msgid="1679848116452218908">"On"</string>
- <string name="notification_dots_desc_off" msgid="1760796511504341095">"Off"</string>
- <string name="title_missing_notification_access" msgid="7503287056163941064">"Notification access needed"</string>
- <string name="msg_missing_notification_access" msgid="281113995110910548">"To show Notification Dots, turn on app notifications for <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="title_change_settings" msgid="1376365968844349552">"Change settings"</string>
- <string name="notification_dots_service_title" msgid="4284221181793592871">"Show notification dots"</string>
- <string name="auto_add_shortcuts_label" msgid="3698776050751790653">"Add app icons to the home screen"</string>
- <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"For new apps"</string>
- <string name="package_state_unknown" msgid="7592128424511031410">"Unknown"</string>
- <string name="abandoned_clean_this" msgid="7610119707847920412">"Remove"</string>
- <string name="abandoned_search" msgid="891119232568284442">"Search"</string>
- <string name="abandoned_promises_title" msgid="7096178467971716750">"This app is not installed"</string>
- <string name="abandoned_promise_explanation" msgid="3990027586878167529">"The app for this icon isn\'t installed. You can remove it, or search for the app and install it manually."</string>
- <string name="app_installing_title" msgid="5864044122733792085">"<xliff:g id="NAME">%1$s</xliff:g> installing, <xliff:g id="PROGRESS">%2$s</xliff:g> complete"</string>
- <string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> downloading, <xliff:g id="PROGRESS">%2$s</xliff:g> complete"</string>
- <string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> waiting to install"</string>
- <string name="widgets_list" msgid="796804551140113767">"Widgets list"</string>
- <string name="widgets_list_closed" msgid="6141506579418771922">"Widgets list closed"</string>
- <string name="action_add_to_workspace" msgid="8902165848117513641">"Add to Home screen"</string>
- <string name="action_move_here" msgid="2170188780612570250">"Move item here"</string>
- <string name="item_added_to_workspace" msgid="4211073925752213539">"Item added to home screen"</string>
- <string name="item_removed" msgid="851119963877842327">"Item removed"</string>
- <string name="undo" msgid="4151576204245173321">"Undo"</string>
- <string name="action_move" msgid="4339390619886385032">"Move item"</string>
- <string name="move_to_empty_cell" msgid="2833711483015685619">"Move to row <xliff:g id="NUMBER_0">%1$s</xliff:g> column <xliff:g id="NUMBER_1">%2$s</xliff:g>"</string>
- <string name="move_to_position" msgid="6750008980455459790">"Move to position <xliff:g id="NUMBER">%1$s</xliff:g>"</string>
- <string name="move_to_hotseat_position" msgid="6295412897075147808">"Move to favourites position <xliff:g id="NUMBER">%1$s</xliff:g>"</string>
- <string name="item_moved" msgid="4606538322571412879">"Item moved"</string>
- <string name="add_to_folder" msgid="9040534766770853243">"Add to folder: <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="add_to_folder_with_app" msgid="4534929978967147231">"Add to folder with <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="added_to_folder" msgid="4793259502305558003">"Item added to folder"</string>
- <string name="create_folder_with" msgid="4050141361160214248">"Create folder with: <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="folder_created" msgid="6409794597405184510">"Folder created"</string>
- <string name="action_move_to_workspace" msgid="1603837886334246317">"Move to Home screen"</string>
- <string name="action_resize" msgid="1802976324781771067">"Re-size"</string>
- <string name="action_increase_width" msgid="8773715375078513326">"Increase width"</string>
- <string name="action_increase_height" msgid="459390020612501122">"Increase height"</string>
- <string name="action_decrease_width" msgid="1374549771083094654">"Decrease width"</string>
- <string name="action_decrease_height" msgid="282377193880900022">"Decrease height"</string>
- <string name="widget_resized" msgid="9130327887929620">"Widget re-sized to width <xliff:g id="NUMBER_0">%1$s</xliff:g> height <xliff:g id="NUMBER_1">%2$s</xliff:g>"</string>
- <string name="action_deep_shortcut" msgid="2864038805849372848">"Short cuts"</string>
- <string name="shortcuts_menu_with_notifications_description" msgid="2676582286544232849">"Shortcuts and notifications"</string>
- <string name="action_dismiss_notification" msgid="5909461085055959187">"Dismiss"</string>
- <string name="accessibility_close" msgid="2277148124685870734">"Close"</string>
- <string name="notification_dismissed" msgid="6002233469409822874">"Notification dismissed"</string>
- <string name="all_apps_personal_tab" msgid="4190252696685155002">"Personal"</string>
- <string name="all_apps_work_tab" msgid="4884822796154055118">"Work"</string>
- <string name="work_profile_toggle_label" msgid="3081029915775481146">"Work profile"</string>
- <string name="work_profile_edu_work_apps" msgid="7895468576497746520">"Work apps are badged and visible to your IT admin"</string>
- <string name="work_profile_edu_accept" msgid="6069788082535149071">"OK"</string>
- <string name="work_apps_paused_title" msgid="3040901117349444598">"Work apps are paused"</string>
- <string name="work_apps_paused_body" msgid="261634750995824906">"Your work apps can’t send you notifications, use your battery or access your location"</string>
- <string name="work_apps_paused_content_description" msgid="5149623040804051095">"Work apps are off. Your work apps can’t send you notifications, use your battery or access your location"</string>
- <string name="work_apps_paused_edu_banner" msgid="8872412121608402058">"Work apps are badged and visible to your IT admin"</string>
- <string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"OK"</string>
- <string name="work_apps_pause_btn_text" msgid="1921059713673767460">"Turn off work apps"</string>
- <string name="work_apps_enable_btn_text" msgid="1156432622148413741">"Turn on work apps"</string>
- <string name="developer_options_filter_hint" msgid="5896817443635989056">"Filter"</string>
- <string name="remote_action_failed" msgid="1383965239183576790">"Failed: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
-</resources>
diff --git a/res/values-en-rGB/strings.xml b/res/values-en-rGB/strings.xml
index 29a726c532..7adc2187ec 100644
--- a/res/values-en-rGB/strings.xml
+++ b/res/values-en-rGB/strings.xml
@@ -26,57 +26,32 @@
<string name="safemode_shortcut_error" msgid="9160126848219158407">"Downloaded app disabled in Safe mode"</string>
<string name="safemode_widget_error" msgid="4863470563535682004">"Widgets disabled in Safe mode"</string>
<string name="shortcut_not_available" msgid="2536503539825726397">"Shortcut isn\'t available"</string>
- <string name="home_screen" msgid="5629429142036709174">"Home"</string>
- <string name="recent_task_option_split_screen" msgid="6690461455618725183">"Split screen"</string>
- <string name="split_screen_position_top" msgid="1504965011158689649">"Split top"</string>
- <string name="split_screen_position_left" msgid="7537793098851830883">"Split left"</string>
- <string name="split_screen_position_right" msgid="1569377524925193369">"Split right"</string>
- <string name="split_app_info_accessibility" msgid="5475288491241414932">"App info for %1$s"</string>
- <string name="long_press_widget_to_add" msgid="3587712543577675817">"Touch and hold to move a widget."</string>
- <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Double-tap &amp; hold to move a widget or use custom actions."</string>
+ <string name="home_screen" msgid="806512411299847073">"Home screen"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"Customised actions"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"Touch &amp; hold to pick up a widget."</string>
+ <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Double-tap &amp; hold to pick up a widget or use customised actions."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d wide by %2$d high"</string>
- <string name="widget_preview_context_description" msgid="9045841361655787574">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g> widget"</string>
- <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Touch and hold the widget to move it around the home screen"</string>
- <string name="add_to_home_screen" msgid="8631549138215492708">"Add to home screen"</string>
- <string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g> widget added to home screen"</string>
- <string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# widget}other{# widgets}}"</string>
- <string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{# shortcut}other{# shortcuts}}"</string>
- <string name="widgets_and_shortcuts_count" msgid="7209136747878365116">"<xliff:g id="WIDGETS_COUNT">%1$s</xliff:g>, <xliff:g id="SHORTCUTS_COUNT">%2$s</xliff:g>"</string>
- <string name="widget_button_text" msgid="2880537293434387943">"Widgets"</string>
- <string name="widgets_full_sheet_search_bar_hint" msgid="8484659090860596457">"Search"</string>
- <string name="widgets_full_sheet_cancel_button_description" msgid="5766167035728653605">"Clear text from search box"</string>
- <string name="no_widgets_available" msgid="4337693382501046170">"Widgets and shortcuts aren\'t available"</string>
- <string name="no_search_results" msgid="3787956167293097509">"No widgets or shortcuts found"</string>
- <string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Personal"</string>
- <string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Work"</string>
- <string name="widget_category_conversations" msgid="8894438636213590446">"Conversations"</string>
- <string name="widget_education_header" msgid="4874760613775913787">"Useful info at your fingertips"</string>
- <string name="widget_education_content" msgid="745542879510751525">"To get info without opening apps, you can add widgets to your home screen"</string>
- <string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Tap to change widget settings"</string>
- <string name="widget_education_close_button" msgid="8676165703104836580">"OK"</string>
- <string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Change widget settings"</string>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Touch &amp; hold to place manually"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"Add automatically"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Search apps"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Loading apps…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"No apps found matching \'<xliff:g id="QUERY">%1$s</xliff:g>\'"</string>
<string name="all_apps_search_market_message" msgid="1366263386197059176">"Search for more apps"</string>
<string name="label_application" msgid="8531721983832654978">"App"</string>
- <string name="all_apps_label" msgid="5015784846527570951">"All apps"</string>
<string name="notifications_header" msgid="1404149926117359025">"Notifications"</string>
- <string name="long_press_shortcut_to_add" msgid="5405328730817637737">"Touch &amp; hold to move a shortcut."</string>
- <string name="long_accessible_way_to_add_shortcut" msgid="2199537273817090740">"Double-tap &amp; hold to move a shortcut or use custom actions."</string>
- <string name="out_of_space" msgid="6692471482459245734">"No room on this home screen"</string>
+ <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"Touch &amp; hold to pick up a shortcut."</string>
+ <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"Double-tap &amp; hold to pick up a shortcut or use custom actions."</string>
+ <string name="out_of_space" msgid="4691004494942118364">"No more room on this Home screen."</string>
<string name="hotseat_out_of_space" msgid="7448809638125333693">"No more room in the Favourites tray"</string>
<string name="all_apps_button_label" msgid="8130441508702294465">"Apps list"</string>
- <string name="all_apps_search_results" msgid="5889367432531296759">"Search results"</string>
<string name="all_apps_button_personal_label" msgid="1315764287305224468">"Personal apps list"</string>
<string name="all_apps_button_work_label" msgid="7270707118948892488">"Work apps list"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"Home"</string>
<string name="remove_drop_target_label" msgid="7812859488053230776">"Remove"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"Uninstall"</string>
<string name="app_info_drop_target_label" msgid="692894985365717661">"App info"</string>
<string name="install_drop_target_label" msgid="2539096853673231757">"Install"</string>
- <string name="dismiss_prediction_label" msgid="3357562989568808658">"Don\'t suggest app"</string>
- <string name="pin_prediction" msgid="4196423321649756498">"Pin prediction"</string>
<string name="permlab_install_shortcut" msgid="5632423390354674437">"install shortcuts"</string>
<string name="permdesc_install_shortcut" msgid="923466509822011139">"Allows an app to add shortcuts without user intervention."</string>
<string name="permlab_read_settings" msgid="1941457408239617576">"read Home settings and shortcuts"</string>
@@ -84,13 +59,15 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"write Home settings and shortcuts"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"Allows the app to change the settings and shortcuts in Home."</string>
<string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> is not allowed to make phone calls"</string>
- <string name="gadget_error_text" msgid="740356548025791839">"Can\'t load widget"</string>
- <string name="gadget_setup_text" msgid="8348374825537681407">"Widget settings"</string>
- <string name="gadget_complete_setup_text" msgid="309040266978007925">"Tap to finish setup"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"Problem loading widget"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"Setup"</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"This is a system app and can\'t be uninstalled."</string>
- <string name="folder_hint_text" msgid="5174843001373488816">"Edit Name"</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"Unnamed Folder"</string>
<string name="disabled_app_label" msgid="6673129024321402780">"Disabled <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
- <string name="dotted_app_label" msgid="1704091277755818896">"{count,plural,offset:1 =1{{app_name} has # notification}other{{app_name} has # notifications}}"</string>
+ <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+ <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, has <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> notifications</item>
+ <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g>, has <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> notification</item>
+ </plurals>
<string name="default_scroll_format" msgid="7475544710230993317">"Page %1$d of %2$d"</string>
<string name="workspace_scroll_format" msgid="8458889198184077399">"Home screen %1$d of %2$d"</string>
<string name="workspace_new_page" msgid="257366611030256142">"New home screen page"</string>
@@ -99,10 +76,10 @@
<string name="folder_tap_to_rename" msgid="4017685068016979677">"Tap to save rename"</string>
<string name="folder_closed" msgid="4100806530910930934">"Folder closed"</string>
<string name="folder_renamed" msgid="1794088362165669656">"Folder renamed to <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="folder_name_format_exact" msgid="8626242716117004803">"Folder: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> items"</string>
- <string name="folder_name_format_overflow" msgid="4270108890534995199">"Folder: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> or more items"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"Folder: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"Widgets"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Wallpapers"</string>
- <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Wallpaper &amp; style"</string>
+ <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Styles &amp; wallpapers"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Home settings"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Disabled by your admin"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Allow Home screen rotation"</string>
@@ -114,16 +91,16 @@
<string name="msg_missing_notification_access" msgid="281113995110910548">"To show Notification Dots, turn on app notifications for <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="title_change_settings" msgid="1376365968844349552">"Change settings"</string>
<string name="notification_dots_service_title" msgid="4284221181793592871">"Show notification dots"</string>
- <string name="auto_add_shortcuts_label" msgid="3698776050751790653">"Add app icons to the home screen"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Add icon to Home screen"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"For new apps"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"Unknown"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"Remove"</string>
<string name="abandoned_search" msgid="891119232568284442">"Search"</string>
<string name="abandoned_promises_title" msgid="7096178467971716750">"This app is not installed"</string>
<string name="abandoned_promise_explanation" msgid="3990027586878167529">"The app for this icon isn\'t installed. You can remove it, or search for the app and install it manually."</string>
- <string name="app_installing_title" msgid="5864044122733792085">"<xliff:g id="NAME">%1$s</xliff:g> installing, <xliff:g id="PROGRESS">%2$s</xliff:g> complete"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> downloading, <xliff:g id="PROGRESS">%2$s</xliff:g> complete"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> waiting to install"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"<xliff:g id="NAME">%1$s</xliff:g> widgets"</string>
<string name="widgets_list" msgid="796804551140113767">"Widgets list"</string>
<string name="widgets_list_closed" msgid="6141506579418771922">"Widgets list closed"</string>
<string name="action_add_to_workspace" msgid="8902165848117513641">"Add to Home screen"</string>
@@ -151,20 +128,15 @@
<string name="action_deep_shortcut" msgid="2864038805849372848">"Short cuts"</string>
<string name="shortcuts_menu_with_notifications_description" msgid="2676582286544232849">"Shortcuts and notifications"</string>
<string name="action_dismiss_notification" msgid="5909461085055959187">"Dismiss"</string>
- <string name="accessibility_close" msgid="2277148124685870734">"Close"</string>
<string name="notification_dismissed" msgid="6002233469409822874">"Notification dismissed"</string>
<string name="all_apps_personal_tab" msgid="4190252696685155002">"Personal"</string>
<string name="all_apps_work_tab" msgid="4884822796154055118">"Work"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"Work profile"</string>
- <string name="work_profile_edu_work_apps" msgid="7895468576497746520">"Work apps are badged and visible to your IT admin"</string>
- <string name="work_profile_edu_accept" msgid="6069788082535149071">"OK"</string>
- <string name="work_apps_paused_title" msgid="3040901117349444598">"Work apps are paused"</string>
- <string name="work_apps_paused_body" msgid="261634750995824906">"Your work apps can’t send you notifications, use your battery or access your location"</string>
- <string name="work_apps_paused_content_description" msgid="5149623040804051095">"Work apps are off. Your work apps can’t send you notifications, use your battery or access your location"</string>
- <string name="work_apps_paused_edu_banner" msgid="8872412121608402058">"Work apps are badged and visible to your IT admin"</string>
- <string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"OK"</string>
- <string name="work_apps_pause_btn_text" msgid="1921059713673767460">"Turn off work apps"</string>
- <string name="work_apps_enable_btn_text" msgid="1156432622148413741">"Turn on work apps"</string>
- <string name="developer_options_filter_hint" msgid="5896817443635989056">"Filter"</string>
+ <string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"Find work apps here"</string>
+ <string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"Each work app has a badge and is kept secure by your organisation. Move apps to your Home screen for easier access."</string>
+ <string name="work_mode_on_label" msgid="4781128097185272916">"Managed by your organisation"</string>
+ <string name="work_mode_off_label" msgid="3194894777601421047">"Notifications and apps are off"</string>
+ <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Close"</string>
+ <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Closed"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Failed: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
</resources>
diff --git a/res/values-en-rIN/strings.xml b/res/values-en-rIN/strings.xml
index 29a726c532..7adc2187ec 100644
--- a/res/values-en-rIN/strings.xml
+++ b/res/values-en-rIN/strings.xml
@@ -26,57 +26,32 @@
<string name="safemode_shortcut_error" msgid="9160126848219158407">"Downloaded app disabled in Safe mode"</string>
<string name="safemode_widget_error" msgid="4863470563535682004">"Widgets disabled in Safe mode"</string>
<string name="shortcut_not_available" msgid="2536503539825726397">"Shortcut isn\'t available"</string>
- <string name="home_screen" msgid="5629429142036709174">"Home"</string>
- <string name="recent_task_option_split_screen" msgid="6690461455618725183">"Split screen"</string>
- <string name="split_screen_position_top" msgid="1504965011158689649">"Split top"</string>
- <string name="split_screen_position_left" msgid="7537793098851830883">"Split left"</string>
- <string name="split_screen_position_right" msgid="1569377524925193369">"Split right"</string>
- <string name="split_app_info_accessibility" msgid="5475288491241414932">"App info for %1$s"</string>
- <string name="long_press_widget_to_add" msgid="3587712543577675817">"Touch and hold to move a widget."</string>
- <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Double-tap &amp; hold to move a widget or use custom actions."</string>
+ <string name="home_screen" msgid="806512411299847073">"Home screen"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"Customised actions"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"Touch &amp; hold to pick up a widget."</string>
+ <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Double-tap &amp; hold to pick up a widget or use customised actions."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d wide by %2$d high"</string>
- <string name="widget_preview_context_description" msgid="9045841361655787574">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g> widget"</string>
- <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Touch and hold the widget to move it around the home screen"</string>
- <string name="add_to_home_screen" msgid="8631549138215492708">"Add to home screen"</string>
- <string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g> widget added to home screen"</string>
- <string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# widget}other{# widgets}}"</string>
- <string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{# shortcut}other{# shortcuts}}"</string>
- <string name="widgets_and_shortcuts_count" msgid="7209136747878365116">"<xliff:g id="WIDGETS_COUNT">%1$s</xliff:g>, <xliff:g id="SHORTCUTS_COUNT">%2$s</xliff:g>"</string>
- <string name="widget_button_text" msgid="2880537293434387943">"Widgets"</string>
- <string name="widgets_full_sheet_search_bar_hint" msgid="8484659090860596457">"Search"</string>
- <string name="widgets_full_sheet_cancel_button_description" msgid="5766167035728653605">"Clear text from search box"</string>
- <string name="no_widgets_available" msgid="4337693382501046170">"Widgets and shortcuts aren\'t available"</string>
- <string name="no_search_results" msgid="3787956167293097509">"No widgets or shortcuts found"</string>
- <string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Personal"</string>
- <string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Work"</string>
- <string name="widget_category_conversations" msgid="8894438636213590446">"Conversations"</string>
- <string name="widget_education_header" msgid="4874760613775913787">"Useful info at your fingertips"</string>
- <string name="widget_education_content" msgid="745542879510751525">"To get info without opening apps, you can add widgets to your home screen"</string>
- <string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Tap to change widget settings"</string>
- <string name="widget_education_close_button" msgid="8676165703104836580">"OK"</string>
- <string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Change widget settings"</string>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Touch &amp; hold to place manually"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"Add automatically"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Search apps"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Loading apps…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"No apps found matching \'<xliff:g id="QUERY">%1$s</xliff:g>\'"</string>
<string name="all_apps_search_market_message" msgid="1366263386197059176">"Search for more apps"</string>
<string name="label_application" msgid="8531721983832654978">"App"</string>
- <string name="all_apps_label" msgid="5015784846527570951">"All apps"</string>
<string name="notifications_header" msgid="1404149926117359025">"Notifications"</string>
- <string name="long_press_shortcut_to_add" msgid="5405328730817637737">"Touch &amp; hold to move a shortcut."</string>
- <string name="long_accessible_way_to_add_shortcut" msgid="2199537273817090740">"Double-tap &amp; hold to move a shortcut or use custom actions."</string>
- <string name="out_of_space" msgid="6692471482459245734">"No room on this home screen"</string>
+ <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"Touch &amp; hold to pick up a shortcut."</string>
+ <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"Double-tap &amp; hold to pick up a shortcut or use custom actions."</string>
+ <string name="out_of_space" msgid="4691004494942118364">"No more room on this Home screen."</string>
<string name="hotseat_out_of_space" msgid="7448809638125333693">"No more room in the Favourites tray"</string>
<string name="all_apps_button_label" msgid="8130441508702294465">"Apps list"</string>
- <string name="all_apps_search_results" msgid="5889367432531296759">"Search results"</string>
<string name="all_apps_button_personal_label" msgid="1315764287305224468">"Personal apps list"</string>
<string name="all_apps_button_work_label" msgid="7270707118948892488">"Work apps list"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"Home"</string>
<string name="remove_drop_target_label" msgid="7812859488053230776">"Remove"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"Uninstall"</string>
<string name="app_info_drop_target_label" msgid="692894985365717661">"App info"</string>
<string name="install_drop_target_label" msgid="2539096853673231757">"Install"</string>
- <string name="dismiss_prediction_label" msgid="3357562989568808658">"Don\'t suggest app"</string>
- <string name="pin_prediction" msgid="4196423321649756498">"Pin prediction"</string>
<string name="permlab_install_shortcut" msgid="5632423390354674437">"install shortcuts"</string>
<string name="permdesc_install_shortcut" msgid="923466509822011139">"Allows an app to add shortcuts without user intervention."</string>
<string name="permlab_read_settings" msgid="1941457408239617576">"read Home settings and shortcuts"</string>
@@ -84,13 +59,15 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"write Home settings and shortcuts"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"Allows the app to change the settings and shortcuts in Home."</string>
<string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> is not allowed to make phone calls"</string>
- <string name="gadget_error_text" msgid="740356548025791839">"Can\'t load widget"</string>
- <string name="gadget_setup_text" msgid="8348374825537681407">"Widget settings"</string>
- <string name="gadget_complete_setup_text" msgid="309040266978007925">"Tap to finish setup"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"Problem loading widget"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"Setup"</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"This is a system app and can\'t be uninstalled."</string>
- <string name="folder_hint_text" msgid="5174843001373488816">"Edit Name"</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"Unnamed Folder"</string>
<string name="disabled_app_label" msgid="6673129024321402780">"Disabled <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
- <string name="dotted_app_label" msgid="1704091277755818896">"{count,plural,offset:1 =1{{app_name} has # notification}other{{app_name} has # notifications}}"</string>
+ <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+ <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, has <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> notifications</item>
+ <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g>, has <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> notification</item>
+ </plurals>
<string name="default_scroll_format" msgid="7475544710230993317">"Page %1$d of %2$d"</string>
<string name="workspace_scroll_format" msgid="8458889198184077399">"Home screen %1$d of %2$d"</string>
<string name="workspace_new_page" msgid="257366611030256142">"New home screen page"</string>
@@ -99,10 +76,10 @@
<string name="folder_tap_to_rename" msgid="4017685068016979677">"Tap to save rename"</string>
<string name="folder_closed" msgid="4100806530910930934">"Folder closed"</string>
<string name="folder_renamed" msgid="1794088362165669656">"Folder renamed to <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="folder_name_format_exact" msgid="8626242716117004803">"Folder: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> items"</string>
- <string name="folder_name_format_overflow" msgid="4270108890534995199">"Folder: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> or more items"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"Folder: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"Widgets"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Wallpapers"</string>
- <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Wallpaper &amp; style"</string>
+ <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Styles &amp; wallpapers"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Home settings"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Disabled by your admin"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Allow Home screen rotation"</string>
@@ -114,16 +91,16 @@
<string name="msg_missing_notification_access" msgid="281113995110910548">"To show Notification Dots, turn on app notifications for <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="title_change_settings" msgid="1376365968844349552">"Change settings"</string>
<string name="notification_dots_service_title" msgid="4284221181793592871">"Show notification dots"</string>
- <string name="auto_add_shortcuts_label" msgid="3698776050751790653">"Add app icons to the home screen"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Add icon to Home screen"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"For new apps"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"Unknown"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"Remove"</string>
<string name="abandoned_search" msgid="891119232568284442">"Search"</string>
<string name="abandoned_promises_title" msgid="7096178467971716750">"This app is not installed"</string>
<string name="abandoned_promise_explanation" msgid="3990027586878167529">"The app for this icon isn\'t installed. You can remove it, or search for the app and install it manually."</string>
- <string name="app_installing_title" msgid="5864044122733792085">"<xliff:g id="NAME">%1$s</xliff:g> installing, <xliff:g id="PROGRESS">%2$s</xliff:g> complete"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> downloading, <xliff:g id="PROGRESS">%2$s</xliff:g> complete"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> waiting to install"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"<xliff:g id="NAME">%1$s</xliff:g> widgets"</string>
<string name="widgets_list" msgid="796804551140113767">"Widgets list"</string>
<string name="widgets_list_closed" msgid="6141506579418771922">"Widgets list closed"</string>
<string name="action_add_to_workspace" msgid="8902165848117513641">"Add to Home screen"</string>
@@ -151,20 +128,15 @@
<string name="action_deep_shortcut" msgid="2864038805849372848">"Short cuts"</string>
<string name="shortcuts_menu_with_notifications_description" msgid="2676582286544232849">"Shortcuts and notifications"</string>
<string name="action_dismiss_notification" msgid="5909461085055959187">"Dismiss"</string>
- <string name="accessibility_close" msgid="2277148124685870734">"Close"</string>
<string name="notification_dismissed" msgid="6002233469409822874">"Notification dismissed"</string>
<string name="all_apps_personal_tab" msgid="4190252696685155002">"Personal"</string>
<string name="all_apps_work_tab" msgid="4884822796154055118">"Work"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"Work profile"</string>
- <string name="work_profile_edu_work_apps" msgid="7895468576497746520">"Work apps are badged and visible to your IT admin"</string>
- <string name="work_profile_edu_accept" msgid="6069788082535149071">"OK"</string>
- <string name="work_apps_paused_title" msgid="3040901117349444598">"Work apps are paused"</string>
- <string name="work_apps_paused_body" msgid="261634750995824906">"Your work apps can’t send you notifications, use your battery or access your location"</string>
- <string name="work_apps_paused_content_description" msgid="5149623040804051095">"Work apps are off. Your work apps can’t send you notifications, use your battery or access your location"</string>
- <string name="work_apps_paused_edu_banner" msgid="8872412121608402058">"Work apps are badged and visible to your IT admin"</string>
- <string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"OK"</string>
- <string name="work_apps_pause_btn_text" msgid="1921059713673767460">"Turn off work apps"</string>
- <string name="work_apps_enable_btn_text" msgid="1156432622148413741">"Turn on work apps"</string>
- <string name="developer_options_filter_hint" msgid="5896817443635989056">"Filter"</string>
+ <string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"Find work apps here"</string>
+ <string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"Each work app has a badge and is kept secure by your organisation. Move apps to your Home screen for easier access."</string>
+ <string name="work_mode_on_label" msgid="4781128097185272916">"Managed by your organisation"</string>
+ <string name="work_mode_off_label" msgid="3194894777601421047">"Notifications and apps are off"</string>
+ <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Close"</string>
+ <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Closed"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Failed: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
</resources>
diff --git a/res/values-en-rXC/strings.xml b/res/values-en-rXC/strings.xml
deleted file mode 100644
index f975d5c970..0000000000
--- a/res/values-en-rXC/strings.xml
+++ /dev/null
@@ -1,170 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-/*
-* Copyright (C) 2008 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.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="649227358658669779">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‎‎‏‎‎‏‎‎‎‎‎‎‏‎‏‎‎‎‎‏‎‎‏‏‎‏‎‏‏‏‏‏‎‎‏‎‏‏‎‏‎‏‎‎‎‎‏‎‏‎‏‏‎‎‏‏‎‏‎‎‏‏‎Launcher3‎‏‎‎‏‎"</string>
- <string name="work_folder_name" msgid="3753320833950115786">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‏‎‏‎‎‎‎‎‏‎‏‏‎‎‏‏‏‏‎‎‏‎‏‏‎‏‎‎‏‏‎‎‏‏‎‏‏‏‎‏‎‏‎‏‏‎‏‏‎‎‏‏‏‏‏‎‎‏‎‏‎‎Work‎‏‎‎‏‎"</string>
- <string name="activity_not_found" msgid="8071924732094499514">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‏‏‎‎‎‎‎‎‎‎‎‏‎‏‎‎‏‏‏‏‎‎‏‏‎‎‎‏‏‎‏‏‏‎‎‏‏‎‎‎‏‎‏‏‏‎‏‏‎‎‏‎‏‎‏‎‏‏‏‎‏‎‎App isn\'t installed.‎‏‎‎‏‎"</string>
- <string name="activity_not_available" msgid="7456344436509528827">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‏‎‎‏‏‏‎‏‏‏‏‎‏‎‎‏‎‎‎‎‎‏‏‏‎‎‎‎‏‎‎‏‏‏‎‏‎‏‎‎‎‏‏‏‎‎‎‏‎‏‎‎‏‎‏‏‏‏‏‎‏‏‎App isn\'t available‎‏‎‎‏‎"</string>
- <string name="safemode_shortcut_error" msgid="9160126848219158407">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‎‎‎‏‏‏‏‏‎‏‎‎‏‏‏‎‏‏‎‏‎‏‏‎‎‎‎‎‎‏‎‏‏‎‎‏‏‏‏‏‎‎‎‏‎‏‏‏‏‎‎‎‎‏‏‏‎Downloaded app disabled in Safe mode‎‏‎‎‏‎"</string>
- <string name="safemode_widget_error" msgid="4863470563535682004">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‎‎‎‎‏‏‎‏‏‏‏‏‏‎‏‎‎‎‎‏‎‎‏‎‏‏‎‏‎‏‏‎‏‏‎‎‏‏‎‎‎‏‏‏‎‎‏‏‏‏‏‎‎‏‏‏‎‏‎‏‎‎‎Widgets disabled in Safe mode‎‏‎‎‏‎"</string>
- <string name="shortcut_not_available" msgid="2536503539825726397">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‎‎‎‏‏‎‎‏‏‎‎‏‏‎‏‏‏‏‎‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‎‏‏‎‏‎‏‎‏‎‏‎‏‎‎‏‏‏‎‏‏‏‏‎‏‎Shortcut isn\'t available‎‏‎‎‏‎"</string>
- <string name="home_screen" msgid="5629429142036709174">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‎‎‏‏‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‏‏‎‏‎‏‎‎‎‏‎‏‏‎‏‎‏‎‏‎‎‎‏‏‏‏‏‏‏‎‎‏‏‎‏‏‎‎Home‎‏‎‎‏‎"</string>
- <string name="recent_task_option_split_screen" msgid="6690461455618725183">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‎‏‏‏‎‎‏‏‎‏‏‎‎‏‎‏‎‎‏‎‏‏‎‎‏‏‏‏‏‏‎‎‎‎‏‏‎‏‏‎‎‏‏‎‎‎‏‏‎‏‎‏‎‏‎‎‏‏‏‏‏‏‎Split screen‎‏‎‎‏‎"</string>
- <string name="split_screen_position_top" msgid="1504965011158689649">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‎‏‏‎‏‎‎‏‏‏‎‎‎‏‎‏‎‏‏‎‏‎‏‏‎‏‏‎‏‎‎‎‎‏‏‏‎‎‏‏‎‎‎‎‎‎‏‎‏‏‎‎‏‏‏‎‏‏‏‎‎‎‏‎Split top‎‏‎‎‏‎"</string>
- <string name="split_screen_position_left" msgid="7537793098851830883">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‏‎‏‎‎‎‏‎‎‏‏‎‏‏‏‎‎‏‏‏‏‎‏‏‏‎‎‎‏‎‏‏‏‎‏‏‏‏‎‏‏‏‎‏‎‎‎‏‎‎‏‏‎‎‎‏‏‎‎‎‏‏‎Split left‎‏‎‎‏‎"</string>
- <string name="split_screen_position_right" msgid="1569377524925193369">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‎‏‏‎‏‎‏‏‏‎‎‎‏‏‏‏‎‎‎‏‏‎‎‏‎‎‎‏‎‏‏‎‏‎‎‎‎‏‏‏‎‏‎‎‏‎‏‏‏‎‏‏‏‎‎‏‎‎‏‏‎‎‏‎Split right‎‏‎‎‏‎"</string>
- <string name="split_app_info_accessibility" msgid="5475288491241414932">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‎‎‏‎‏‏‏‏‏‏‏‏‎‎‎‎‏‎‎‎‎‏‏‏‎‏‏‏‏‏‏‎‎‏‏‎‏‏‎‎‏‏‏‎‏‎‏‎‏‎‎‎‎‏‎‎‎‏‎‏‎‎‎App info for %1$s‎‏‎‎‏‎"</string>
- <string name="long_press_widget_to_add" msgid="3587712543577675817">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‏‎‎‎‏‏‏‎‎‏‎‏‎‎‎‎‏‏‏‎‏‏‎‎‎‏‏‎‎‏‏‎‎‎‏‎‎‎‎‏‎‏‎‎‏‎‎‎‏‏‎‎‎‎‎‏‎‏‎‎‏‎Touch &amp; hold to move a widget.‎‏‎‎‏‎"</string>
- <string name="long_accessible_way_to_add" msgid="2733588281439571974">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‎‎‏‎‏‏‏‏‎‏‏‏‏‏‎‏‎‏‎‎‎‎‎‎‎‏‏‏‏‎‎‎‎‏‏‎‏‎‏‏‎‎‎‎‎‎‏‎‏‎‎‎‎‎‎‎‎‎‏‏‎‎Double-tap &amp; hold to move a widget or use custom actions.‎‏‎‎‏‎"</string>
- <string name="widget_dims_format" msgid="2370757736025621599">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‎‎‎‎‎‏‏‏‎‎‏‏‎‏‎‎‏‏‏‏‏‏‎‎‏‏‎‎‏‏‎‏‎‎‎‎‎‎‏‎‏‎‎‎‏‎‎‎‎‎‏‎‎‎‏‎‏‏‏‏‏‎%1$d × %2$d‎‏‎‎‏‎"</string>
- <string name="widget_accessible_dims_format" msgid="3640149169885301790">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‏‎‎‏‎‏‎‎‎‎‏‎‎‎‏‏‎‏‎‎‎‎‏‏‎‎‎‏‎‎‎‏‏‏‎‎‎‎‏‏‏‎‎‏‎‎‏‎‎‏‏‎‎‎‎‎‏‏‏‏‎‎%1$d wide by %2$d high‎‏‎‎‏‎"</string>
- <string name="widget_preview_context_description" msgid="9045841361655787574">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‏‏‏‏‎‏‏‎‎‎‏‎‎‏‎‏‎‎‏‎‎‎‏‏‎‎‏‎‏‎‏‎‏‎‎‎‎‎‎‎‎‎‎‏‏‏‎‏‏‏‎‎‎‎‎‎‏‏‎‏‏‎‎‎‏‎‎‏‏‎<xliff:g id="WIDGET_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ widget‎‏‎‎‏‎"</string>
- <string name="add_item_request_drag_hint" msgid="5653291305078645405">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‎‎‏‏‏‎‎‏‏‏‎‏‎‎‏‎‎‎‎‏‏‎‎‏‏‏‏‏‎‏‎‏‎‏‎‎‏‏‎‎‎‎‎‏‎‎‎‏‏‎‎‎‏‎‏‎‎‏‏‏‎‏‎Touch &amp; hold the widget to move it around the Home screen‎‏‎‎‏‎"</string>
- <string name="add_to_home_screen" msgid="8631549138215492708">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‏‏‎‏‏‏‏‏‎‎‏‎‎‏‎‏‏‎‏‏‎‎‎‎‏‏‎‏‎‏‏‎‎‏‎‏‎‎‏‎‏‎‏‎‎‏‏‏‎‏‏‏‎‎‎‏‏‎‎‏‎‎‎Add to Home screen‎‏‎‎‏‎"</string>
- <string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‏‏‏‎‏‏‏‎‎‎‏‏‏‎‎‎‏‎‎‎‏‎‏‎‎‏‎‎‏‏‏‎‏‎‎‏‎‏‏‏‏‏‎‎‏‏‎‏‎‎‎‎‎‏‎‏‏‏‏‏‏‎‎‏‎‎‏‏‎<xliff:g id="WIDGET_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ widget added to home screen‎‏‎‎‏‎"</string>
- <string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‎‏‏‎‎‏‏‏‎‎‎‎‏‎‎‎‎‎‏‏‎‏‎‎‏‎‎‏‏‏‎‎‎‏‎‏‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‏‏‎‎‏‎‎‎‎‎‎‎# widget‎‏‎‎‏‎}other{‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‎‏‏‎‎‏‏‏‎‎‎‎‏‎‎‎‎‎‏‏‎‏‎‎‏‎‎‏‏‏‎‎‎‏‎‏‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‏‏‎‎‏‎‎‎‎‎‎‎# widgets‎‏‎‎‏‎}}"</string>
- <string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‏‏‎‏‎‏‏‎‎‏‎‎‎‏‏‎‎‏‎‏‎‎‎‏‏‎‏‎‎‏‏‏‎‎‏‏‎‏‎‏‏‎‏‏‎‏‎‏‏‏‎‎‎‏‏‎‏‏‏‏‎‏‎# shortcut‎‏‎‎‏‎}other{‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‏‏‎‏‎‏‏‎‎‏‎‎‎‏‏‎‎‏‎‏‎‎‎‏‏‎‏‎‎‏‏‏‎‎‏‏‎‏‎‏‏‎‏‏‎‏‎‏‏‏‎‎‎‏‏‎‏‏‏‏‎‏‎# shortcuts‎‏‎‎‏‎}}"</string>
- <string name="widgets_and_shortcuts_count" msgid="7209136747878365116">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‏‎‎‏‎‎‎‎‎‎‏‎‏‏‏‏‏‏‏‏‏‏‏‎‏‎‏‏‎‏‎‎‏‏‎‎‏‎‏‎‎‎‎‎‎‏‎‎‏‏‎‏‏‏‏‎‏‏‏‏‎‎‎‎‏‎‎‏‏‎<xliff:g id="WIDGETS_COUNT">%1$s</xliff:g>‎‏‎‎‏‏‏‎, ‎‏‎‎‏‏‎<xliff:g id="SHORTCUTS_COUNT">%2$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
- <string name="widget_button_text" msgid="2880537293434387943">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‎‎‏‏‏‏‏‏‏‏‎‎‏‏‎‏‏‏‎‎‏‎‏‏‎‏‎‎‎‎‎‎‏‏‎‎‏‎‏‏‎‏‎‏‏‏‏‏‏‏‏‎‏‏‏‏‎‎‏‏‏‎Widgets‎‏‎‎‏‎"</string>
- <string name="widgets_full_sheet_search_bar_hint" msgid="8484659090860596457">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‏‏‎‏‎‏‏‎‏‏‏‏‏‏‏‎‎‏‎‎‎‎‎‏‏‏‏‏‎‏‎‏‎‎‏‏‏‏‎‎‎‎‏‎‎‎‏‏‎‏‏‏‎‎‏‏‏‎‏‎‎‏‎Search‎‏‎‎‏‎"</string>
- <string name="widgets_full_sheet_cancel_button_description" msgid="5766167035728653605">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‎‏‎‎‎‎‎‎‎‎‎‏‎‏‏‎‎‎‏‎‏‎‎‏‎‏‏‏‏‎‎‏‎‏‏‎‎‎‎‎‏‎‏‏‎‎‎‏‏‎‏‏‎‏‎‎‏‎‎‏‎‏‎Clear text from search box‎‏‎‎‏‎"</string>
- <string name="no_widgets_available" msgid="4337693382501046170">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‏‏‏‎‎‎‎‏‏‎‎‏‎‏‎‎‏‎‏‎‏‎‎‏‎‎‏‏‎‎‎‏‏‏‎‎‎‏‎‎‎‏‎‎‏‏‎‎‏‎‏‏‏‏‎‎‏‏‎‏‎‎Widgets and shortcuts aren\'t available‎‏‎‎‏‎"</string>
- <string name="no_search_results" msgid="3787956167293097509">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‏‎‏‎‎‏‎‎‏‎‎‎‏‏‎‎‎‎‏‏‎‎‎‎‏‎‎‎‎‏‎‎‏‎‎‎‎‎‏‎‎‎‎‎‏‎‏‎‏‎‏‏‎‎‎‏‎‎‏‎‏‎No widgets or shortcuts found‎‏‎‎‏‎"</string>
- <string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‎‎‏‏‎‎‎‎‏‎‎‏‏‎‎‎‎‎‎‏‏‎‎‏‏‎‎‎‎‏‎‏‎‏‏‎‏‏‏‎‎‎‎‎‎‎‎‎‎‎‏‎‏‎‎‏‏‎‏‏‎‎Personal‎‏‎‎‏‎"</string>
- <string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‏‎‏‎‎‎‏‎‎‎‏‏‏‏‎‎‏‏‎‏‎‏‏‏‏‏‏‎‏‏‎‎‎‏‏‎‏‏‎‎‎‏‎‎‎‎‏‎‏‎‎‎‏‎‎‏‎‎‏‎‏‎Work‎‏‎‎‏‎"</string>
- <string name="widget_category_conversations" msgid="8894438636213590446">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‏‏‏‎‏‏‎‏‏‎‏‏‏‏‎‏‏‎‎‏‎‎‏‏‎‏‎‎‎‎‏‎‎‏‏‏‎‎‎‎‎‎‎‏‎‏‎‏‎‏‏‎‎‏‏‎‏‎‏‏‏‎‎Conversations‎‏‎‎‏‎"</string>
- <string name="widget_education_header" msgid="4874760613775913787">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‎‎‎‎‏‏‏‎‏‎‎‏‏‎‏‎‏‎‎‎‎‎‏‏‏‏‎‎‏‏‎‏‎‏‏‏‎‏‎‎‏‎‏‏‎‏‏‎‏‏‎‎‏‏‎‎‏‏‏‎‏‏‎Useful info at your fingertips‎‏‎‎‏‎"</string>
- <string name="widget_education_content" msgid="745542879510751525">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‎‎‏‎‏‎‎‏‎‏‏‎‎‎‏‎‏‏‎‎‏‏‎‏‎‎‏‏‎‎‏‎‎‎‎‎‏‎‎‎‎‎‏‏‏‏‎‏‏‎‏‎‎‏‎‎‏‎‎‏‎‏‎To get info without opening apps, you can add widgets to your Home screen‎‏‎‎‏‎"</string>
- <string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‎‏‎‏‏‏‏‏‏‏‎‎‎‏‎‏‏‎‏‎‎‏‏‏‏‏‏‏‏‎‎‎‏‎‎‎‎‏‎‏‎‎‏‎‎‏‎‏‏‎‎‏‏‏‏‏‏‏‎‎‎‏‎Tap to change widget settings‎‏‎‎‏‎"</string>
- <string name="widget_education_close_button" msgid="8676165703104836580">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‏‏‏‎‎‎‎‏‏‎‎‏‏‏‏‏‏‎‏‏‏‎‏‎‏‏‏‏‎‏‎‎‎‏‏‎‎‏‏‏‏‏‏‏‎‏‏‎‏‏‎‎‏‏‏‏‏‎‎‏‎‎‎Got it‎‏‎‎‏‎"</string>
- <string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‏‏‏‎‏‎‎‏‎‎‏‎‎‎‏‎‏‎‎‎‏‏‏‏‎‎‎‎‎‏‎‏‎‏‏‏‏‏‏‏‎‎‎‏‏‎‎‎‎‎‏‎‏‎‎‎‎‎‎‎‏‎‎Change widget settings‎‏‎‎‏‎"</string>
- <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‎‏‏‎‎‏‏‎‏‎‎‏‏‎‎‎‎‏‏‏‏‎‎‏‎‏‏‎‏‎‏‎‎‏‏‏‏‎‎‏‎‎‎‏‏‎‎‏‏‏‎‏‎‎‎‎‏‎‎‏‏‏‎‎Search apps‎‏‎‎‏‎"</string>
- <string name="all_apps_loading_message" msgid="5813968043155271636">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‎‏‎‎‎‎‏‎‏‎‏‏‏‏‎‏‎‏‏‏‎‏‎‎‏‎‎‎‎‏‏‎‏‎‏‎‏‏‏‎‏‏‏‏‏‎‎‎‏‎‏‏‏‏‏‏‎‏‎‏‎‎‎Loading apps…‎‏‎‎‏‎"</string>
- <string name="all_apps_no_search_results" msgid="3200346862396363786">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‎‏‏‎‎‎‏‏‎‏‎‎‏‏‏‏‎‏‎‏‎‏‎‎‎‎‎‏‏‏‏‏‎‎‎‏‏‎‎‏‎‏‎‏‏‏‏‎‏‎‏‎‎‎‎‎‎‏‎‏‎‎No apps found matching \"‎‏‎‎‏‏‎<xliff:g id="QUERY">%1$s</xliff:g>‎‏‎‎‏‏‏‎\"‎‏‎‎‏‎"</string>
- <string name="all_apps_search_market_message" msgid="1366263386197059176">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‎‏‏‎‎‏‎‏‏‏‏‎‏‎‏‏‏‏‏‎‎‎‏‎‏‎‎‏‏‏‏‏‎‎‏‏‎‏‏‏‏‏‎‎‏‎‏‏‏‏‎‎‏‏‎‎‏‏‎‏‎‎‎‎Search for more apps‎‏‎‎‏‎"</string>
- <string name="label_application" msgid="8531721983832654978">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‏‏‎‏‏‎‎‏‏‎‎‏‏‎‏‏‎‎‎‎‏‏‏‏‏‏‎‎‎‎‏‏‏‏‏‎‎‎‏‎‏‏‏‏‎‎‏‎‎‎‎‏‎‎‏‎‎‎‎‎‏‎‎App‎‏‎‎‏‎"</string>
- <string name="all_apps_label" msgid="5015784846527570951">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‎‎‎‏‎‏‏‎‎‏‏‎‏‏‏‎‏‎‎‏‎‏‏‎‏‏‏‏‏‎‎‎‏‏‏‏‏‏‎‎‎‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‎‎‎‏‏‏‎All apps‎‏‎‎‏‎"</string>
- <string name="notifications_header" msgid="1404149926117359025">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‎‏‏‎‎‏‏‎‏‏‏‏‏‎‎‏‎‎‎‏‎‏‎‏‏‏‎‏‎‏‏‎‎‎‏‎‏‎‏‏‎‎‏‏‏‎‏‏‎‏‏‏‏‎‏‏‎‏‏‎‎‎‏‎Notifications‎‏‎‎‏‎"</string>
- <string name="long_press_shortcut_to_add" msgid="5405328730817637737">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‎‎‏‎‏‏‎‎‎‎‎‎‏‏‏‎‎‏‎‏‎‏‏‏‎‏‎‏‏‏‏‎‎‎‏‏‏‎‏‎‎‏‏‎‎‏‎‎‏‎‏‏‎‏‎‏‏‎‏‎‎‏‎Touch &amp; hold to move a shortcut.‎‏‎‎‏‎"</string>
- <string name="long_accessible_way_to_add_shortcut" msgid="2199537273817090740">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‎‏‏‏‏‏‎‏‎‎‎‎‏‏‎‎‏‎‏‎‎‏‏‎‏‏‏‏‏‏‏‎‎‏‏‎‏‎‎‎‎‎‏‏‎‎‏‎‏‎‎‏‎‏‎‏‎‏‏‎‏‎‎‎Double-tap &amp; hold to move a shortcut or use custom actions.‎‏‎‎‏‎"</string>
- <string name="out_of_space" msgid="6692471482459245734">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‎‏‏‏‎‎‏‏‏‎‎‎‎‎‎‏‏‎‏‏‏‏‎‏‎‏‏‎‏‎‏‏‏‎‎‏‎‏‎‏‏‎‏‎‏‎‎‏‎‎‏‏‎‎‏‎‏‎‎‏‏‎‎No room on this Home screen‎‏‎‎‏‎"</string>
- <string name="hotseat_out_of_space" msgid="7448809638125333693">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‏‎‎‏‏‏‎‏‎‏‏‏‏‏‎‏‏‏‏‏‎‎‏‏‏‎‎‏‏‎‎‏‏‏‏‏‏‏‏‏‏‏‎‏‏‏‎‏‏‎‏‏‎‎‏‎‏‏‏‏‎‏‎No more room in the Favorites tray‎‏‎‎‏‎"</string>
- <string name="all_apps_button_label" msgid="8130441508702294465">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‏‏‎‎‎‎‏‏‎‏‎‏‎‏‎‎‏‎‎‎‎‏‎‏‏‏‏‎‎‏‏‎‏‎‏‎‎‏‎‏‎‎‏‎‏‎‏‎‎‏‎‎‎‏‏‏‎‎‎‎‎‏‎Apps list‎‏‎‎‏‎"</string>
- <string name="all_apps_search_results" msgid="5889367432531296759">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‎‏‎‎‎‏‏‎‏‏‏‎‏‏‎‎‏‏‏‏‎‎‎‏‏‏‏‎‏‎‎‎‎‎‎‏‏‏‏‏‎‎‏‎‎‎‎‏‎‎‎‎‎‏‏‏‏‏‎‏‏‏‎Search results‎‏‎‎‏‎"</string>
- <string name="all_apps_button_personal_label" msgid="1315764287305224468">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‎‏‏‎‎‏‎‎‏‎‎‎‎‏‎‏‎‎‎‏‎‎‎‏‎‏‎‎‏‎‏‏‏‏‎‏‎‎‎‏‏‏‏‏‎‎‏‎‎‎‏‎‎‎‏‎‎‎‏‎‏‎‎‎Personal apps list‎‏‎‎‏‎"</string>
- <string name="all_apps_button_work_label" msgid="7270707118948892488">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‏‎‎‏‎‎‏‏‏‎‎‏‏‎‏‎‏‏‏‏‎‏‏‎‎‏‏‎‏‎‎‏‎‏‎‎‏‎‏‏‎‏‏‎‏‎‎‎‏‏‏‏‏‏‎‏‎‎‏‎‎‎‎Work apps list‎‏‎‎‏‎"</string>
- <string name="remove_drop_target_label" msgid="7812859488053230776">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‏‎‏‏‎‎‎‏‏‎‏‏‎‎‏‏‎‏‏‎‏‎‎‏‎‎‏‏‏‏‎‏‏‎‎‎‎‏‎‏‏‏‎‎‏‏‏‏‏‏‏‏‎‎‏‎‏‏‏‎‎‎‎Remove‎‏‎‎‏‎"</string>
- <string name="uninstall_drop_target_label" msgid="4722034217958379417">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‎‎‎‎‎‏‏‎‎‎‏‎‎‎‎‎‎‎‏‎‎‏‎‎‎‏‏‎‏‎‎‏‎‏‎‎‏‎‏‎‏‎‎‏‏‎‎‎‎‎‏‏‏‏‏‎‎‏‏‎‎‏‎Uninstall‎‏‎‎‏‎"</string>
- <string name="app_info_drop_target_label" msgid="692894985365717661">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‎‎‏‎‎‏‏‎‎‏‏‏‎‏‏‎‏‎‏‎‎‎‎‏‎‏‎‎‎‏‎‏‏‎‏‏‎‏‎‏‎‏‏‏‏‏‏‎‎‎‎‎‏‎‏‎‎‏‏‏‎‏‎App info‎‏‎‎‏‎"</string>
- <string name="install_drop_target_label" msgid="2539096853673231757">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‎‎‎‏‏‎‎‏‏‏‏‎‎‏‎‏‎‏‏‏‏‎‎‏‎‎‎‏‎‏‎‏‏‏‏‎‏‏‎‎‎‎‎‎‏‎‏‎‎‎‏‎‏‏‎‎‎‏‏‎‏‎Install‎‏‎‎‏‎"</string>
- <string name="dismiss_prediction_label" msgid="3357562989568808658">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‎‏‏‏‎‏‎‎‏‏‎‎‎‎‏‏‏‎‏‎‏‏‎‏‏‏‏‏‏‏‏‏‏‏‎‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‏‎‏‏‎‏‎‎‏‎‎Don\'t suggest app‎‏‎‎‏‎"</string>
- <string name="pin_prediction" msgid="4196423321649756498">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‏‏‎‏‎‎‎‏‏‏‏‎‎‏‎‏‏‎‎‎‎‏‏‎‎‎‏‏‏‎‎‎‎‎‏‏‎‎‎‎‏‏‎‎‏‎‎‏‏‏‎‎‏‎‏‎‏‎‎‏‎‎Pin Prediction‎‏‎‎‏‎"</string>
- <string name="permlab_install_shortcut" msgid="5632423390354674437">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‎‎‏‏‏‎‎‎‏‎‏‎‏‎‎‏‏‎‎‎‏‏‎‎‏‏‏‎‏‏‎‏‎‎‏‏‏‎‏‎‏‏‎‎‎‏‎‎‎‏‎‎‏‏‎‎‎‎‎‏‎‏‎install shortcuts‎‏‎‎‏‎"</string>
- <string name="permdesc_install_shortcut" msgid="923466509822011139">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‎‎‏‏‎‎‏‏‎‏‎‎‎‎‏‏‎‎‏‏‏‏‏‏‏‎‎‏‎‏‏‏‎‏‏‏‏‏‏‏‏‎‏‎‎‏‎‎‏‎‎‏‏‏‎‎‎‎‎‎‏‏‎Allows an app to add shortcuts without user intervention.‎‏‎‎‏‎"</string>
- <string name="permlab_read_settings" msgid="1941457408239617576">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‎‏‏‏‎‏‎‏‏‏‏‎‎‎‏‎‏‏‏‎‎‎‏‎‎‏‏‏‎‎‏‏‏‏‏‏‏‎‎‏‎‏‎‏‏‎‎‎‏‎‎‎‏‏‎‎‎‏‎‏‎‎‎‎read Home settings and shortcuts‎‏‎‎‏‎"</string>
- <string name="permdesc_read_settings" msgid="5833423719057558387">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‎‏‎‎‎‎‏‏‏‏‎‏‎‎‎‏‏‏‏‎‏‏‏‏‏‏‎‏‏‏‎‎‏‏‎‏‏‎‏‏‎‎‎‎‏‏‏‎‎‎‏‎‏‏‎‏‏‏‎‎‏‏‎Allows the app to read the settings and shortcuts in Home.‎‏‎‎‏‎"</string>
- <string name="permlab_write_settings" msgid="3574213698004620587">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‏‎‎‎‏‏‎‎‏‏‎‏‎‎‎‏‎‏‎‎‎‎‏‏‎‏‎‏‏‏‏‎‏‏‏‎‎‏‏‏‎‎‏‏‎‏‎‎‏‎‏‎‏‎‎‏‎‏‎‏‏‎write Home settings and shortcuts‎‏‎‎‏‎"</string>
- <string name="permdesc_write_settings" msgid="5440712911516509985">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‏‎‎‏‎‏‏‏‎‎‏‎‎‎‏‎‎‎‏‏‏‏‏‏‏‎‏‎‎‏‎‏‎‏‎‎‏‏‏‎‎‏‎‎‎‎‏‎Allows the app to change the settings and shortcuts in Home.‎‏‎‎‏‎"</string>
- <string name="msg_no_phone_permission" msgid="9208659281529857371">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‎‎‏‎‏‏‏‎‏‏‏‎‏‎‏‏‎‏‎‎‏‏‏‎‏‏‎‏‎‏‎‎‏‏‎‎‎‎‏‏‏‎‎‏‎‏‎‏‎‏‏‎‏‏‎‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ is not allowed to make phone calls‎‏‎‎‏‎"</string>
- <string name="gadget_error_text" msgid="740356548025791839">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‎‎‏‎‏‎‎‏‎‎‎‏‏‎‎‏‎‎‎‏‏‎‎‏‎‏‏‎‏‏‏‎‎‏‏‏‎‎‎‎‏‏‎‏‏‎‎‎‏‏‎‏‎‏‎‏‎‏‏‏‏‏‎Can\'t load widget‎‏‎‎‏‎"</string>
- <string name="gadget_setup_text" msgid="8348374825537681407">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‏‏‎‎‏‏‏‏‎‏‏‎‏‏‎‏‏‎‎‎‏‎‏‎‏‎‏‏‎‎‎‎‎‏‎‏‏‏‏‏‏‏‏‏‎‎‏‎‏‏‎‏‏‏‏‏‏‏‏‏‏‏‎Widget settings‎‏‎‎‏‎"</string>
- <string name="gadget_complete_setup_text" msgid="309040266978007925">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‎‏‏‏‎‎‎‏‎‎‏‎‎‏‏‏‏‎‏‏‏‎‎‏‏‏‏‏‎‎‎‏‎‎‎‏‏‎‏‎‎‎‎‏‎‎‎‎‎‏‏‎‏‏‎‏‏‏‎‏‎‏‎Tap to finish setup‎‏‎‎‏‎"</string>
- <string name="uninstall_system_app_text" msgid="4172046090762920660">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‏‏‎‎‏‏‏‏‎‎‏‏‎‎‎‎‏‎‏‎‏‏‏‎‏‎‎‎‎‏‎‏‎‏‎‏‎‎‏‏‏‏‎‏‏‎‎‏‎‎‎‏‎‏‏‎‏‎‏‎‎‎This is a system app and can\'t be uninstalled.‎‏‎‎‏‎"</string>
- <string name="folder_hint_text" msgid="5174843001373488816">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‎‎‎‏‏‏‏‏‎‏‎‎‎‎‏‎‏‏‏‏‎‎‎‏‎‎‏‎‏‎‏‏‎‏‎‎‎‏‎‏‎‎‏‎‎‎‎‏‏‏‎‏‏‎‏‎‏‏‎‎‎‎‎Edit Name‎‏‎‎‏‎"</string>
- <string name="disabled_app_label" msgid="6673129024321402780">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‎‏‏‏‎‎‏‎‎‏‏‎‏‏‏‎‏‏‎‏‏‏‎‏‏‏‏‏‎‏‏‏‏‎‏‎‏‏‎‎‎‎‎‏‏‎‏‎‏‏‎‏‏‏‏‎‎‏‏‏‎‎‎Disabled ‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
- <string name="dotted_app_label" msgid="1704091277755818896">"{count,plural,offset:1 =1{‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‎‏‏‎‏‏‏‏‎‏‎‎‏‏‎‎‎‏‎‎‏‎‏‏‏‏‏‏‏‎‏‎‎‎‎‏‎‏‏‎‏‏‏‏‎‏‎‎‎‏‎‎‎‏‏‏‎‎‏‎‎‎‎‎‎‏‎‎‏‏‎{app_name}‎‏‎‎‏‏‏‎ has # notification‎‏‎‎‏‎}other{‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‎‏‏‎‏‏‏‏‎‏‎‎‏‏‎‎‎‏‎‎‏‎‏‏‏‏‏‏‏‎‏‎‎‎‎‏‎‏‏‎‏‏‏‏‎‏‎‎‎‏‎‎‎‏‏‏‎‎‏‎‎‎‎‎‎‏‎‎‏‏‎{app_name}‎‏‎‎‏‏‏‎ has # notifications‎‏‎‎‏‎}}"</string>
- <string name="default_scroll_format" msgid="7475544710230993317">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‏‎‎‏‏‏‏‎‏‏‏‏‏‎‎‏‏‏‏‎‎‎‎‏‎‎‏‏‏‎‏‎‎‎‏‎‏‏‏‏‎‏‏‏‏‎‎‏‏‎‏‎‎‏‏‎‏‎‎‏‎‏‎Page %1$d of %2$d‎‏‎‎‏‎"</string>
- <string name="workspace_scroll_format" msgid="8458889198184077399">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‏‏‎‏‎‏‎‏‏‎‎‏‎‎‎‎‎‎‎‎‏‎‏‏‏‎‏‎‎‎‏‎‎‏‏‏‎‎‎‎‏‎‎‏‏‎‏‎‎‏‏‎‎‎‎‏‎‏‎‏‏‏‎Home screen %1$d of %2$d‎‏‎‎‏‎"</string>
- <string name="workspace_new_page" msgid="257366611030256142">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‎‏‎‏‏‏‎‎‏‎‎‏‎‎‏‎‏‏‎‎‏‏‎‎‏‎‎‎‏‏‎‏‏‎‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‏‎‏‎‎‎‎‎‏‏‏‎‎New home screen page‎‏‎‎‏‎"</string>
- <string name="folder_opened" msgid="94695026776264709">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‎‎‏‏‎‏‎‏‎‎‎‎‎‏‏‎‏‏‎‎‏‎‏‎‎‎‎‎‎‎‎‎‏‎‎‎‏‏‏‏‏‏‏‎‏‏‎‏‎‎‎‎‎‎‎‎‎‏‎‏‎Folder opened, ‎‏‎‎‏‏‎<xliff:g id="WIDTH">%1$d</xliff:g>‎‏‎‎‏‏‏‎ by ‎‏‎‎‏‏‎<xliff:g id="HEIGHT">%2$d</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
- <string name="folder_tap_to_close" msgid="4625795376335528256">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‎‎‎‎‎‎‎‎‏‏‎‎‏‎‎‎‏‎‎‎‎‎‎‏‏‎‎‎‏‎‏‏‏‎‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‏‎‏‎‎‎‎‎‎‎Tap to close folder‎‏‎‎‏‎"</string>
- <string name="folder_tap_to_rename" msgid="4017685068016979677">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‏‎‏‏‏‏‏‎‎‎‎‎‏‏‎‏‎‏‏‏‏‎‏‎‎‏‎‎‎‎‏‏‎‎‎‏‎‏‎‎‎‏‎‏‏‎‎‎‎‏‏‏‎‏‏‎‏‏‏‎‏‎Tap to save rename‎‏‎‎‏‎"</string>
- <string name="folder_closed" msgid="4100806530910930934">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‏‏‎‎‎‏‏‏‎‏‎‎‎‏‏‏‏‏‏‎‏‏‏‎‏‎‎‎‎‎‎‎‏‎‏‏‏‏‎‎‎‏‏‎‎‎‏‎‎‎‏‏‏‏‏‏‏‎‏‏‎‎Folder closed‎‏‎‎‏‎"</string>
- <string name="folder_renamed" msgid="1794088362165669656">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‎‏‏‏‎‎‎‏‏‏‎‎‏‎‏‏‏‏‎‎‎‎‏‏‏‎‏‏‏‎‎‎‎‏‎‎‎‏‎‏‎‎‎‏‏‎‎‎‎‎‎‏‏‏‏‎‎‎‏‏‎‎‎‎Folder renamed to ‎‏‎‎‏‏‎<xliff:g id="NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
- <string name="folder_name_format_exact" msgid="8626242716117004803">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‏‏‎‏‏‏‏‎‏‏‎‏‏‎‏‎‎‏‎‎‏‎‎‎‎‎‏‎‏‏‏‏‏‎‏‎‎‎‎‏‏‏‎‏‎‎‎‏‏‏‎‎‏‎‎‎‎‎‎‎‏‏‎Folder: ‎‏‎‎‏‏‎<xliff:g id="NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎, ‎‏‎‎‏‏‎<xliff:g id="SIZE">%2$d</xliff:g>‎‏‎‎‏‏‏‎ items‎‏‎‎‏‎"</string>
- <string name="folder_name_format_overflow" msgid="4270108890534995199">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‏‏‎‏‏‎‏‎‎‎‎‏‎‎‏‏‏‏‎‎‏‎‏‏‎‏‎‎‏‎‏‏‏‎‏‎‎‏‎‎‏‎‎‏‏‎‏‏‎‎‏‎‎‏‏‏‏‏‏‏‏‎Folder: ‎‏‎‎‏‏‎<xliff:g id="NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎, ‎‏‎‎‏‏‎<xliff:g id="SIZE">%2$d</xliff:g>‎‏‎‎‏‏‏‎ or more items‎‏‎‎‏‎"</string>
- <string name="wallpaper_button_text" msgid="8404103075899945851">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‏‏‎‏‎‎‏‎‏‎‎‎‎‏‎‏‎‏‏‏‏‏‎‎‏‏‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‏‎‎‎‏‎‏‏‎‎‏‏‎‏‏‏‏‎‏‏‎Wallpapers‎‏‎‎‏‎"</string>
- <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‏‏‎‎‏‎‎‎‎‎‏‎‎‎‏‎‎‎‎‎‏‎‏‏‎‏‎‎‎‏‎‎‏‏‏‎‏‏‎‎‏‎‎‎‎‎‏‎‎‏‎‏‎‏‎‎‏‏‏‎‏‎‎Wallpaper &amp; style‎‏‎‎‏‎"</string>
- <string name="settings_button_text" msgid="8873672322605444408">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‏‏‏‎‏‏‎‎‏‎‎‏‎‏‏‎‎‏‏‏‎‏‏‏‏‏‎‏‏‎‎‏‏‏‎‎‏‎‎‎‎‏‏‏‎‎‏‏‏‎‏‏‎‏‎‎‏‏‏‎‎‎‎Home settings‎‏‎‎‏‎"</string>
- <string name="msg_disabled_by_admin" msgid="6898038085516271325">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‎‏‏‏‏‏‏‎‏‏‏‎‏‎‏‏‎‎‎‎‎‏‎‎‎‏‎‏‏‏‎‏‏‎‎‏‏‎‎‏‎‏‎‎‎‎‎‎‎‏‏‏‏‎‏‏‎‏‏‏‎‏‎Disabled by your admin‎‏‎‎‏‎"</string>
- <string name="allow_rotation_title" msgid="7728578836261442095">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‏‎‏‎‏‏‎‏‎‎‎‎‎‏‎‏‏‎‏‏‎‏‏‎‎‎‎‎‎‎‏‏‏‏‏‎‎‏‏‏‏‏‎‏‏‏‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‎Allow Home screen rotation‎‏‎‎‏‎"</string>
- <string name="allow_rotation_desc" msgid="8662546029078692509">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‏‏‏‎‎‎‎‎‏‏‎‏‏‏‏‎‎‎‏‎‏‏‏‎‏‏‎‏‏‏‏‎‏‎‎‎‎‏‏‎‏‏‎‏‎‎‏‏‎‎‎‎‏‎‏‎‎‏‏‏‎‏‎When phone is rotated‎‏‎‎‏‎"</string>
- <string name="notification_dots_title" msgid="9062440428204120317">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‏‏‏‏‎‏‏‏‎‎‎‏‎‎‎‏‎‎‎‎‎‏‏‎‎‎‏‏‎‏‏‏‏‏‏‎‎‏‎‎‏‏‏‏‏‎‏‏‎‏‏‎‎‎‏‏‏‏‏‏‎‏‎Notification dots‎‏‎‎‏‎"</string>
- <string name="notification_dots_desc_on" msgid="1679848116452218908">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‎‏‏‎‏‏‏‎‏‎‏‎‎‎‎‎‎‎‎‎‏‎‎‏‏‏‏‎‏‏‎‎‎‏‏‎‎‎‏‏‎‏‏‏‏‏‎‎‏‎‏‏‎‎‎‎‎‎‏‏‏‎‎‎On‎‏‎‎‏‎"</string>
- <string name="notification_dots_desc_off" msgid="1760796511504341095">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‎‏‏‏‎‎‎‎‏‏‎‏‏‏‏‏‎‎‏‏‎‏‏‎‎‎‏‏‎‎‏‎‎‎‏‏‏‎‏‏‏‏‏‎‏‏‎‏‎‎‏‏‎‎‎‎‏‏‎‎‏‏‏‎Off‎‏‎‎‏‎"</string>
- <string name="title_missing_notification_access" msgid="7503287056163941064">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‏‎‏‎‎‎‎‎‏‎‎‎‎‏‎‎‎‎‎‏‏‏‏‏‎‏‎‎‏‎‏‏‎‎‏‏‏‎‎‏‏‏‎‎‎‎‎‎‏‎‏‎‏‎‏‏‎‎‏‎‎‎‎Notification access needed‎‏‎‎‏‎"</string>
- <string name="msg_missing_notification_access" msgid="281113995110910548">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‎‏‎‏‏‏‏‏‎‎‏‏‎‏‎‏‏‎‏‏‏‏‎‏‏‎‎‎‎‎‏‏‎‏‎‏‏‏‏‏‏‏‎‏‎‎‎‎‎‏‎‏‎‎‏‎‏‎‏‎‎‎To show Notification Dots, turn on app notifications for ‎‏‎‎‏‏‎<xliff:g id="NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
- <string name="title_change_settings" msgid="1376365968844349552">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‎‏‏‎‎‏‏‎‎‎‏‏‎‎‏‏‏‎‏‎‏‎‏‏‎‎‎‏‏‏‎‎‏‏‎‏‏‎‏‏‏‏‎‎‏‏‏‎‏‏‎‎‎‎‎‎‏‏‏‎‎‎‎‎Change settings‎‏‎‎‏‎"</string>
- <string name="notification_dots_service_title" msgid="4284221181793592871">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‏‏‎‏‏‎‏‏‏‎‏‎‎‏‎‎‏‏‏‎‎‎‏‏‏‎‏‏‏‎‏‎‏‎‎‎‎‎‎‎‎‎‎‏‎‏‏‏‎‎‏‏‎‎‎‏‎‎‏‏‏‎Show notification dots‎‏‎‎‏‎"</string>
- <string name="auto_add_shortcuts_label" msgid="3698776050751790653">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‏‎‎‏‏‎‏‎‏‎‏‎‎‏‎‏‏‎‎‎‏‎‎‏‏‏‎‎‎‏‎‏‎‎‎‎‎‏‏‎‎‏‎‎‎‎‏‎‏‏‏‏‎‎‎‏‏‏‏‎‏‎Add app icons to Home screen‎‏‎‎‏‎"</string>
- <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‏‎‎‎‏‎‏‏‎‎‎‏‎‏‏‎‎‎‏‏‏‎‎‎‏‏‏‎‏‎‎‎‎‎‏‎‏‎‏‎‏‎‏‎‎‎‎‎‏‎‏‏‏‏‏‎‏‎‏‎‏‎‎For new apps‎‏‎‎‏‎"</string>
- <string name="package_state_unknown" msgid="7592128424511031410">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‏‎‏‎‎‏‎‏‎‏‏‏‎‎‏‎‏‎‏‎‎‎‏‎‎‏‎‎‏‏‏‏‎‎‏‎‎‎‎‎‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‎‎‏‎‎Unknown‎‏‎‎‏‎"</string>
- <string name="abandoned_clean_this" msgid="7610119707847920412">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‏‎‏‎‎‏‏‎‎‏‏‏‎‎‏‎‎‏‎‎‏‏‏‎‎‎‏‏‎‏‏‏‎‏‏‏‎‎‎‏‏‏‏‎‎‏‏‎‎‎‏‎‏‏‎‎‎‏‏‏‎‎‎Remove‎‏‎‎‏‎"</string>
- <string name="abandoned_search" msgid="891119232568284442">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‎‎‏‏‎‎‎‏‎‏‏‏‎‏‏‏‏‎‎‏‎‎‎‎‏‏‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‎‎‎‎‎‎‏‎‏‎‏‎‏‎‎‎‏‏‎‏‎‎Search‎‏‎‎‏‎"</string>
- <string name="abandoned_promises_title" msgid="7096178467971716750">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‏‎‎‎‏‎‎‏‏‏‏‎‏‎‏‎‏‏‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‏‏‏‎‎‎‏‏‏‎‏‎‏‏‎‏‎‏‏‎‏‎‎‎‏‏‏‎‎This app is not installed‎‏‎‎‏‎"</string>
- <string name="abandoned_promise_explanation" msgid="3990027586878167529">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‏‎‏‏‏‎‏‎‏‏‏‏‏‎‏‏‎‏‏‎‎‏‏‏‏‎‎‏‏‎‎‏‏‏‏‏‏‏‏‏‎‎‎‎‏‏‏‎‏‏‎‎‏‏‏‏‎‏‎‎‏‎The app for this icon isn\'t installed. You can remove it, or search for the app and install it manually.‎‏‎‎‏‎"</string>
- <string name="app_installing_title" msgid="5864044122733792085">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‎‏‎‎‎‏‎‏‏‎‎‎‎‏‎‏‎‎‎‏‎‏‎‎‎‎‏‏‏‏‏‎‎‎‎‎‏‎‏‏‎‎‎‎‏‏‏‏‎‎‏‎‏‏‎‏‎‏‎‏‎‏‎‎‏‎‎‏‏‎<xliff:g id="NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ installing, ‎‏‎‎‏‏‎<xliff:g id="PROGRESS">%2$s</xliff:g>‎‏‎‎‏‏‏‎ complete‎‏‎‎‏‎"</string>
- <string name="app_downloading_title" msgid="8336702962104482644">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‏‏‎‎‏‏‏‎‏‏‎‎‎‏‏‏‏‎‏‎‏‏‎‎‏‎‏‏‎‎‏‎‎‏‏‏‏‎‎‎‏‎‏‏‏‏‎‎‏‏‏‎‏‏‎‏‎‏‎‏‎‎‎‎‏‎‎‏‏‎<xliff:g id="NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ downloading, ‎‏‎‎‏‏‎<xliff:g id="PROGRESS">%2$s</xliff:g>‎‏‎‎‏‏‏‎ complete‎‏‎‎‏‎"</string>
- <string name="app_waiting_download_title" msgid="7053938513995617849">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‏‎‎‎‎‏‏‏‏‎‎‏‎‎‏‎‎‏‏‏‏‏‏‎‏‏‎‏‎‎‏‎‎‎‎‎‏‎‎‎‏‎‎‏‏‏‏‏‎‏‎‏‏‎‎‎‏‏‏‎‎‏‎‎‏‎‎‏‏‎<xliff:g id="NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ waiting to install‎‏‎‎‏‎"</string>
- <string name="widgets_list" msgid="796804551140113767">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‎‎‏‎‏‏‎‎‎‎‏‏‏‎‏‏‎‏‎‎‎‏‏‎‎‎‎‏‎‎‏‎‎‎‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‏‏‏‎‏‎‏‏‎‎‏‏‏‎Widgets list‎‏‎‎‏‎"</string>
- <string name="widgets_list_closed" msgid="6141506579418771922">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‎‏‎‏‎‏‎‎‏‏‏‎‏‏‎‎‎‎‎‎‏‏‏‎‏‏‎‎‎‏‏‏‏‎‎‎‏‏‏‏‏‏‏‎‏‎‏‏‏‏‎‎‎‏‏‏‎‏‎‎‏‎‎Widgets list closed‎‏‎‎‏‎"</string>
- <string name="action_add_to_workspace" msgid="8902165848117513641">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‏‏‏‎‏‏‏‎‎‎‏‎‏‎‏‏‎‏‏‎‎‎‏‎‏‎‏‏‎‎‎‏‎‏‎‏‎‎‏‎‏‎‏‎‎‎‏‎‎‎‏‏‎‏‏‎‏‎‏‎‎‏‎Add to Home screen‎‏‎‎‏‎"</string>
- <string name="action_move_here" msgid="2170188780612570250">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‎‏‏‏‏‏‎‎‎‎‏‏‏‏‎‎‎‎‎‏‏‏‏‎‎‏‏‎‎‏‎‏‎‏‎‎‎‏‏‏‏‏‏‎‎‏‏‎‏‎‎‏‏‎‎‏‎‎‎‏‎‏‎‎Move item here‎‏‎‎‏‎"</string>
- <string name="item_added_to_workspace" msgid="4211073925752213539">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‏‏‎‏‎‎‏‏‏‎‎‎‎‏‎‏‏‏‏‎‏‎‏‏‎‏‏‎‎‏‎‎‏‏‎‏‏‎‏‎‏‏‏‏‎‏‏‎‏‎‎‎‎‎‎‏‎‎‎‏‏‎Item added to home screen‎‏‎‎‏‎"</string>
- <string name="item_removed" msgid="851119963877842327">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‎‎‏‎‏‏‏‏‎‎‏‏‏‏‏‏‎‎‏‎‎‏‎‎‎‏‏‎‎‏‎‎‎‎‎‏‎‎‎‎‏‎‏‏‏‎‏‎‎‏‏‏‎‏‏‎‎‏‎‏‏‏‎Item removed‎‏‎‎‏‎"</string>
- <string name="undo" msgid="4151576204245173321">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‏‏‎‎‏‏‎‎‏‏‏‎‏‎‏‎‏‏‏‎‎‏‎‎‎‏‏‏‏‏‏‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‎‎‎‎‏‎‎‎‏‎‎‏‎‎‏‎Undo‎‏‎‎‏‎"</string>
- <string name="action_move" msgid="4339390619886385032">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‏‏‏‎‎‎‎‏‏‏‎‎‎‏‎‎‏‏‏‎‎‏‏‎‎‎‏‏‏‎‎‎‏‎‏‏‏‏‏‏‏‏‏‎‏‎‏‏‏‎‏‏‏‏‎‎‎‏‎‎‎‎Move item‎‏‎‎‏‎"</string>
- <string name="move_to_empty_cell" msgid="2833711483015685619">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‎‎‏‏‏‎‏‎‏‎‎‏‏‎‏‎‏‏‏‎‏‏‎‎‏‎‏‎‎‏‎‎‎‎‏‎‏‎‎‎‏‏‎‎‎‎‏‏‎‎‏‎‏‏‏‏‏‎‎‏‏‎Move to row ‎‏‎‎‏‏‎<xliff:g id="NUMBER_0">%1$s</xliff:g>‎‏‎‎‏‏‏‎ column ‎‏‎‎‏‏‎<xliff:g id="NUMBER_1">%2$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
- <string name="move_to_position" msgid="6750008980455459790">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‎‏‏‏‎‏‏‎‏‎‏‏‎‎‏‏‎‏‏‎‎‏‎‏‏‎‎‏‏‏‏‎‎‏‎‏‏‎‏‎‏‏‏‏‏‎‏‎‎‎‏‎‏‏‏‏‎‎‏‏‏‎‎Move to position ‎‏‎‎‏‏‎<xliff:g id="NUMBER">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
- <string name="move_to_hotseat_position" msgid="6295412897075147808">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‎‏‎‏‏‏‎‏‎‏‏‏‎‏‏‏‎‎‏‏‎‎‏‎‏‎‏‏‎‎‏‏‏‎‎‏‎‎‏‎‎‏‎‎‏‏‏‎‏‏‎‏‎‎‎‎‏‎‎‎‎‎‎Move to favorites position ‎‏‎‎‏‏‎<xliff:g id="NUMBER">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
- <string name="item_moved" msgid="4606538322571412879">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‎‏‏‎‏‏‎‏‏‎‏‏‎‎‎‏‏‎‎‏‎‏‎‏‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‎‎‏‎‏‏‎‎‎‏‏‏‏‎Item moved‎‏‎‎‏‎"</string>
- <string name="add_to_folder" msgid="9040534766770853243">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‏‏‏‏‎‏‎‏‏‏‎‏‏‎‎‏‏‎‏‏‏‎‎‏‏‏‏‎‎‎‏‎‏‏‏‎‎‎‏‏‏‏‎‎‏‎‎‎‎‏‎‏‎‏‎‏‏‏‏‎‏‏‎Add to folder: ‎‏‎‎‏‏‎<xliff:g id="NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
- <string name="add_to_folder_with_app" msgid="4534929978967147231">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‏‏‏‏‎‏‏‏‎‏‏‏‏‎‏‎‎‏‏‏‎‏‏‎‎‏‎‎‏‏‏‏‎‏‏‎‏‏‎‎‏‏‎‏‏‎‏‎‎‎‎‏‎‏‏‎‏‏‏‏‏‎Add to folder with ‎‏‎‎‏‏‎<xliff:g id="NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
- <string name="added_to_folder" msgid="4793259502305558003">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‎‎‎‎‏‎‏‎‎‎‎‏‎‏‎‎‎‏‎‏‎‎‎‎‎‏‏‏‏‏‎‎‎‏‏‏‏‏‎‎‏‏‎‎‎‎‎‎‏‏‏‏‎‏‏‏‏‏‎‎‏‏‎Item added to folder‎‏‎‎‏‎"</string>
- <string name="create_folder_with" msgid="4050141361160214248">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‏‏‎‎‎‎‎‏‏‎‏‎‎‏‏‏‏‏‏‏‎‎‎‎‏‏‏‎‎‎‎‎‎‎‎‏‎‎‎‎‏‎‎‏‎‎‏‎‏‎‏‏‎‏‏‏‎‏‎‎‎‎Create folder with: ‎‏‎‎‏‏‎<xliff:g id="NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
- <string name="folder_created" msgid="6409794597405184510">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‎‏‏‎‎‎‏‏‏‏‎‏‎‎‎‎‏‎‏‎‏‎‎‎‏‏‏‎‎‏‏‏‎‎‏‏‎‏‏‎‎‎‏‏‎‏‏‏‎‏‎‎‎‏‏‏‏‏‏‏‏‎‎Folder created‎‏‎‎‏‎"</string>
- <string name="action_move_to_workspace" msgid="1603837886334246317">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‎‏‏‎‏‏‎‎‏‎‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‎‏‏‏‏‎‏‏‎‎‏‎‎‎‏‎‎‎‏‎‎‎‎‎‏‏‏‎‏‏‎‏‎‏‏‎‏‎Move to Home screen‎‏‎‎‏‎"</string>
- <string name="action_resize" msgid="1802976324781771067">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‎‏‏‏‎‎‏‎‎‎‎‎‏‎‏‎‏‏‏‎‏‎‏‎‏‏‎‏‎‏‎‎‎‏‏‎‎‎‏‎‎‎‎‏‏‏‎‏‎‎‎‏‎‎‏‎‎‏‏‏‎‏‏‎Resize‎‏‎‎‏‎"</string>
- <string name="action_increase_width" msgid="8773715375078513326">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‏‏‏‎‎‏‏‏‎‎‎‎‏‎‎‏‏‏‏‏‏‏‏‎‏‎‎‏‏‎‎‎‎‎‎‎‏‏‏‏‏‏‎‎‎‎‎‎‎‏‏‎‏‎‏‎‏‎‏‏‏‎‎Increase width‎‏‎‎‏‎"</string>
- <string name="action_increase_height" msgid="459390020612501122">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‎‏‏‏‏‎‎‏‏‎‎‎‎‎‎‎‎‏‎‏‎‎‏‏‎‎‏‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‎‏‏‏‏‎‏‎‏‏‏‎‏‎‎‎‎‎‏‎‎Increase height‎‏‎‎‏‎"</string>
- <string name="action_decrease_width" msgid="1374549771083094654">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‎‏‏‎‎‏‏‎‎‎‏‎‎‏‏‎‏‏‎‎‎‎‏‏‎‏‏‏‎‏‏‏‏‏‎‏‏‏‏‏‎‎‎‎‎‎‎‏‎‎‏‏‎‏‎‎‏‏‏‏‏‏‎‎Decrease width‎‏‎‎‏‎"</string>
- <string name="action_decrease_height" msgid="282377193880900022">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‎‏‎‏‏‏‏‏‎‏‎‏‏‎‎‏‏‎‏‎‎‏‎‎‎‏‏‏‏‏‏‎‎‏‏‎‏‏‏‏‏‎‎‎‏‎‏‎‏‎‎‎‏‏‎‏‏‎‏‏‎‎Decrease height‎‏‎‎‏‎"</string>
- <string name="widget_resized" msgid="9130327887929620">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‎‏‏‎‏‎‎‎‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‏‎‎‎‎‎‏‏‏‏‎‎‏‏‏‎‎‎‏‎‏‏‎‎‎‎‏‎‎‎‏‎‏‎‎‎Widget resized to width ‎‏‎‎‏‏‎<xliff:g id="NUMBER_0">%1$s</xliff:g>‎‏‎‎‏‏‏‎ height ‎‏‎‎‏‏‎<xliff:g id="NUMBER_1">%2$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
- <string name="action_deep_shortcut" msgid="2864038805849372848">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‎‎‏‏‏‏‎‏‏‏‏‏‏‎‎‎‏‏‏‎‎‎‎‎‏‏‏‏‎‏‎‎‏‏‏‎‏‏‎‎‏‎‏‎‏‏‏‏‏‏‎‎‎‏‎‏‏‎‎‎‎‎Shortcuts‎‏‎‎‏‎"</string>
- <string name="shortcuts_menu_with_notifications_description" msgid="2676582286544232849">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‎‎‏‎‏‎‎‏‎‎‏‎‏‎‎‏‎‎‎‎‏‎‏‏‎‏‎‎‎‏‎‎‏‎‎‎‏‏‎‎‏‎‎‏‎‎‏‏‎‎‎‎‏‏‎‎‏‎‎‎‏‎Shortcuts and notifications‎‏‎‎‏‎"</string>
- <string name="action_dismiss_notification" msgid="5909461085055959187">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‎‏‎‎‏‎‎‎‎‎‎‎‏‎‏‎‎‏‏‏‏‏‏‎‎‎‏‏‎‎‎‎‎‏‎‏‎‎‏‏‎‎‎‎‎‏‎‏‎‎‎‎‎‎‏‎‎‏‎‎‏‏‎Dismiss‎‏‎‎‏‎"</string>
- <string name="accessibility_close" msgid="2277148124685870734">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‎‎‏‏‎‏‎‎‎‎‎‏‏‏‎‎‎‏‎‎‏‏‏‏‎‎‏‎‎‎‎‏‏‎‏‏‎‎‏‎‎‏‎‎‏‏‎‏‎‎‎‏‏‏‎‎Close‎‏‎‎‏‎"</string>
- <string name="notification_dismissed" msgid="6002233469409822874">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‎‏‎‎‏‏‎‏‎‎‏‏‎‎‎‎‏‏‎‏‏‏‏‎‎‎‏‎‏‎‎‎‎‎‏‎‏‏‎‎‏‎‎‎‏‎‎‎‎‎‏‎‎‎‏‎‎‏‏‎‏‎‎Notification dismissed‎‏‎‎‏‎"</string>
- <string name="all_apps_personal_tab" msgid="4190252696685155002">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‏‏‎‏‎‎‎‏‎‎‏‏‎‏‏‎‎‎‏‎‎‏‎‏‎‎‎‎‎‎‏‏‏‎‎‎‏‎‎‎‎‏‎‏‎‏‎‎‏‎‎‏‎‏‎‏‏‏‎‏‎‎Personal‎‏‎‎‏‎"</string>
- <string name="all_apps_work_tab" msgid="4884822796154055118">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‎‎‎‎‏‏‏‏‎‎‏‎‏‎‎‏‏‎‎‎‎‎‎‏‏‏‎‎‏‏‏‏‎‎‎‎‏‏‎‏‏‏‏‏‏‎‎‎‏‎‏‎‎‏‏‏‎‎‏‏‏‎‎Work‎‏‎‎‏‎"</string>
- <string name="work_profile_toggle_label" msgid="3081029915775481146">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‎‏‎‏‎‏‏‎‎‎‎‏‎‎‎‎‎‎‏‎‎‎‏‏‎‎‎‏‎‎‏‏‎‏‎‎‎‎‎‏‎‎‏‏‎‎‎‏‏‎‏‎‏‎‎‏‏‏‎‏‎‎Work profile‎‏‎‎‏‎"</string>
- <string name="work_profile_edu_work_apps" msgid="7895468576497746520">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‏‎‏‏‎‏‏‎‎‏‎‎‏‎‎‏‎‏‎‏‏‎‏‏‎‏‎‏‏‎‏‎‎‏‏‏‎‏‎‏‏‎‏‎‎‎‎‏‎‎‎‎‏‎‎‏‎‏‏‎‎‎‎Work apps are badged and visible to your IT admin‎‏‎‎‏‎"</string>
- <string name="work_profile_edu_accept" msgid="6069788082535149071">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‎‏‎‏‎‎‎‎‏‏‏‏‎‎‎‎‏‏‏‎‎‎‎‎‎‏‏‎‏‎‎‎‎‏‏‎‎‏‎‏‏‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‏‏‏‎Got it‎‏‎‎‏‎"</string>
- <string name="work_apps_paused_title" msgid="3040901117349444598">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‎‏‎‏‎‎‎‏‏‎‎‏‏‎‏‏‏‎‎‏‏‎‏‏‏‎‏‎‎‎‏‏‏‎‎‎‎‏‎‏‏‎‎‏‏‏‎‏‏‏‎‏‏‏‏‏‏‎‏‏‎‎Work apps are paused‎‏‎‎‏‎"</string>
- <string name="work_apps_paused_body" msgid="261634750995824906">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‎‏‎‏‏‏‎‏‎‎‎‎‏‏‎‎‎‎‎‏‏‎‏‏‎‏‎‏‏‎‏‏‏‏‎‏‎‎‎‎‎‎‎‎‏‎‎‎‎‎‎‎‏‎‎‎‎‏‎‏‎‎Your work apps can’t send you notifications, use your battery, or access your location‎‏‎‎‏‎"</string>
- <string name="work_apps_paused_content_description" msgid="5149623040804051095">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‎‎‎‏‏‏‎‏‏‏‎‏‏‏‎‎‏‎‎‎‏‎‏‏‎‏‏‏‏‏‎‎‏‎‏‎‏‎‎‏‎‎‏‎‏‎‏‏‎‏‏‎‎‎‏‎‎‏‎‏‏‏‎Work apps are off. Your work apps can’t send you notifications, use your battery, or access your location‎‏‎‎‏‎"</string>
- <string name="work_apps_paused_edu_banner" msgid="8872412121608402058">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‏‏‏‎‏‏‎‎‏‎‎‎‎‏‎‎‏‎‎‎‏‏‏‏‎‏‎‎‎‏‎‎‎‎‏‎‎‏‎‏‎‏‎‏‏‎‏‎‏‏‎‏‎‎‏‎‎‎‏‎‏‎‎Work apps are badged and visible to your IT admin‎‏‎‎‏‎"</string>
- <string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‎‏‏‎‎‎‏‎‎‎‎‎‎‏‎‏‎‏‏‎‎‏‎‏‏‎‎‎‎‏‏‏‏‎‎‏‏‏‎‎‎‏‏‎‏‎‏‎‏‎‏‏‏‏‏‎‎‎‎‏‎‎‎Got it‎‏‎‎‏‎"</string>
- <string name="work_apps_pause_btn_text" msgid="1921059713673767460">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‎‏‏‏‎‏‎‏‎‏‎‏‎‎‎‏‏‏‏‏‎‎‏‏‎‏‎‎‎‎‏‏‎‏‎‎‎‎‏‏‏‎‏‎‏‏‎‏‎‏‎‏‎‏‎‎‎‏‎‎‏‎‎‎Turn off work apps‎‏‎‎‏‎"</string>
- <string name="work_apps_enable_btn_text" msgid="1156432622148413741">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‎‏‏‎‎‎‎‎‎‎‎‏‏‎‎‎‏‏‏‏‎‎‏‎‏‎‏‎‏‏‏‏‏‎‎‎‎‎‏‏‏‎‏‎‏‎‎‎‏‏‎‏‎‎‏‎‎‏‎‏‏‎‏‎Turn on work apps‎‏‎‎‏‎"</string>
- <string name="developer_options_filter_hint" msgid="5896817443635989056">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‎‏‎‎‎‏‏‏‎‏‎‏‎‏‏‎‏‏‎‏‎‎‎‎‏‏‏‎‎‎‏‏‏‎‏‎‎‏‎‏‎‎‎‎‎‎‎‎‎‎‏‎‏‎‎‏‎‎‎‎‎‎‎Filter‎‏‎‎‏‎"</string>
- <string name="remote_action_failed" msgid="1383965239183576790">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‎‏‏‎‎‏‏‎‎‏‏‎‏‎‎‏‏‎‏‎‏‎‏‎‎‎‎‏‏‎‏‎‏‏‎‏‏‏‏‎‎‎‎‎‏‏‎‏‎‎‎‏‏‏‎‏‏‎‏‎‏‏‎‎Failed: ‎‏‎‎‏‏‎<xliff:g id="WHAT">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
-</resources>
diff --git a/res/values-es-rUS/strings.xml b/res/values-es-rUS/strings.xml
index 314a3af814..d10c84b9ca 100644
--- a/res/values-es-rUS/strings.xml
+++ b/res/values-es-rUS/strings.xml
@@ -20,63 +20,39 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="649227358658669779">"Launcher3"</string>
+ <string name="folder_name" msgid="7371454440695724752"></string>
<string name="work_folder_name" msgid="3753320833950115786">"Trabajo"</string>
<string name="activity_not_found" msgid="8071924732094499514">"No se instaló la aplicación."</string>
<string name="activity_not_available" msgid="7456344436509528827">"La aplicación no está disponible."</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"Aplicación descargada inhabilitada en modo seguro"</string>
<string name="safemode_widget_error" msgid="4863470563535682004">"Widgets inhabilitados en modo seguro"</string>
<string name="shortcut_not_available" msgid="2536503539825726397">"El acceso directo no está disponible"</string>
- <string name="home_screen" msgid="5629429142036709174">"Pantalla principal"</string>
- <string name="recent_task_option_split_screen" msgid="6690461455618725183">"Pantalla dividida"</string>
- <string name="split_screen_position_top" msgid="1504965011158689649">"Dividir en la parte superior"</string>
- <string name="split_screen_position_left" msgid="7537793098851830883">"Dividir a la izquierda"</string>
- <string name="split_screen_position_right" msgid="1569377524925193369">"Dividir a la derecha"</string>
- <string name="split_app_info_accessibility" msgid="5475288491241414932">"Información de la app de %1$s"</string>
- <string name="long_press_widget_to_add" msgid="3587712543577675817">"Mantén presionado para mover un widget."</string>
- <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Presiona dos veces y mantén presionado para mover un widget o usar acciones personalizadas."</string>
+ <string name="home_screen" msgid="806512411299847073">"Pantalla principal"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"Acciones personalizadas"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"Mantén presionado el widget que desees elegir."</string>
+ <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Presiona dos veces y mantén presionado para elegir un widget o usa una acción personalizada."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d de ancho por %2$d de alto"</string>
- <string name="widget_preview_context_description" msgid="9045841361655787574">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g> widget"</string>
- <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Mantén presionado el widget para moverlo por la pantalla principal"</string>
- <string name="add_to_home_screen" msgid="8631549138215492708">"Agregar a pantalla principal"</string>
- <string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"Se agregó el widget de <xliff:g id="WIDGET_NAME">%1$s</xliff:g> a la pantalla principal"</string>
- <string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# widget}other{# widgets}}"</string>
- <string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{# acceso directo}other{# accesos directos}}"</string>
- <string name="widgets_and_shortcuts_count" msgid="7209136747878365116">"<xliff:g id="WIDGETS_COUNT">%1$s</xliff:g>, <xliff:g id="SHORTCUTS_COUNT">%2$s</xliff:g>"</string>
- <string name="widget_button_text" msgid="2880537293434387943">"Widgets"</string>
- <string name="widgets_full_sheet_search_bar_hint" msgid="8484659090860596457">"Buscar"</string>
- <string name="widgets_full_sheet_cancel_button_description" msgid="5766167035728653605">"Borra el texto del cuadro de búsqueda"</string>
- <string name="no_widgets_available" msgid="4337693382501046170">"Los widgets y accesos directos no están disponibles"</string>
- <string name="no_search_results" msgid="3787956167293097509">"No se encontraron widgets ni accesos directos"</string>
- <string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Personales"</string>
- <string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Trabajo"</string>
- <string name="widget_category_conversations" msgid="8894438636213590446">"Conversaciones"</string>
- <string name="widget_education_header" msgid="4874760613775913787">"Información útil a tu alcance"</string>
- <string name="widget_education_content" msgid="745542879510751525">"Para recibir información de apps sin abrirlas, puedes agregar widgets a la pantalla principal"</string>
- <string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Presiona para cambiar la configuración del widget"</string>
- <string name="widget_education_close_button" msgid="8676165703104836580">"Entendido"</string>
- <string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Cambiar la configuración del widget"</string>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Mantén presionado para ubicarlo manualmente"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"Agregar automáticamente"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Buscar apps"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Cargando apps…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"No hay apps que coincidan con \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
<string name="all_apps_search_market_message" msgid="1366263386197059176">"Buscar más apps"</string>
<string name="label_application" msgid="8531721983832654978">"App"</string>
- <string name="all_apps_label" msgid="5015784846527570951">"Todas las apps"</string>
<string name="notifications_header" msgid="1404149926117359025">"Notificaciones"</string>
- <string name="long_press_shortcut_to_add" msgid="5405328730817637737">"Mantén presionado para mover un acceso directo."</string>
- <string name="long_accessible_way_to_add_shortcut" msgid="2199537273817090740">"Presiona dos veces y mantén presionado para mover un acceso directo o usar acciones personalizadas."</string>
- <string name="out_of_space" msgid="6692471482459245734">"No hay más espacio en esta pantalla principal"</string>
+ <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"Mantén presionado para elegir un acceso directo."</string>
+ <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"Presiona dos veces y mantén presionado para elegir un acceso directo o usar acciones personalizadas."</string>
+ <string name="out_of_space" msgid="4691004494942118364">"No hay más espacio en esta pantalla principal."</string>
<string name="hotseat_out_of_space" msgid="7448809638125333693">"La bandeja de favoritos está llena."</string>
<string name="all_apps_button_label" msgid="8130441508702294465">"Lista de apps"</string>
- <string name="all_apps_search_results" msgid="5889367432531296759">"Resultados de la búsqueda"</string>
<string name="all_apps_button_personal_label" msgid="1315764287305224468">"Lista de apps personales"</string>
<string name="all_apps_button_work_label" msgid="7270707118948892488">"Lista de apps del trabajo"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"Pantalla principal"</string>
<string name="remove_drop_target_label" msgid="7812859488053230776">"Quitar"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"Desinstalar"</string>
<string name="app_info_drop_target_label" msgid="692894985365717661">"Información de app"</string>
<string name="install_drop_target_label" msgid="2539096853673231757">"Instalar"</string>
- <string name="dismiss_prediction_label" msgid="3357562989568808658">"No sugerir app"</string>
- <string name="pin_prediction" msgid="4196423321649756498">"Fijar predicción"</string>
<string name="permlab_install_shortcut" msgid="5632423390354674437">"instalar accesos directos"</string>
<string name="permdesc_install_shortcut" msgid="923466509822011139">"Permite que una aplicación agregue accesos directos sin que el usuario intervenga."</string>
<string name="permlab_read_settings" msgid="1941457408239617576">"leer configuración y accesos directos de la pantalla principal"</string>
@@ -84,13 +60,15 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"escribir configuración y accesos directos de la pantalla principal"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"Permite que la aplicación cambie la configuración y los accesos directos de la pantalla principal."</string>
<string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> no puede realizar llamadas telefónicas"</string>
- <string name="gadget_error_text" msgid="740356548025791839">"No se puede cargar el widget"</string>
- <string name="gadget_setup_text" msgid="8348374825537681407">"Configuración del widget"</string>
- <string name="gadget_complete_setup_text" msgid="309040266978007925">"Presiona para finalizar la configuración"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"Problema al cargar el widget"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"Configuración"</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"Esta es una aplicación del sistema y no se puede desinstalar."</string>
- <string name="folder_hint_text" msgid="5174843001373488816">"Editar nombre"</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"Carpeta sin nombre"</string>
<string name="disabled_app_label" msgid="6673129024321402780">"Se inhabilitó <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
- <string name="dotted_app_label" msgid="1704091277755818896">"{count,plural,offset:1 =1{{app_name} tiene # notificación}other{{app_name} tiene # notificaciones}}"</string>
+ <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+ <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g> tiene <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> notificaciones</item>
+ <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g> tiene <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> notificación</item>
+ </plurals>
<string name="default_scroll_format" msgid="7475544710230993317">"Página %1$d de %2$d"</string>
<string name="workspace_scroll_format" msgid="8458889198184077399">"Pantalla principal %1$d de %2$d"</string>
<string name="workspace_new_page" msgid="257366611030256142">"Nueva página en la pantalla principal"</string>
@@ -99,11 +77,11 @@
<string name="folder_tap_to_rename" msgid="4017685068016979677">"Presiona para guardar el cambio de nombre"</string>
<string name="folder_closed" msgid="4100806530910930934">"Carpeta cerrada"</string>
<string name="folder_renamed" msgid="1794088362165669656">"El nombre de la carpeta se cambió a <xliff:g id="NAME">%1$s</xliff:g>."</string>
- <string name="folder_name_format_exact" msgid="8626242716117004803">"Carpeta: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> elementos"</string>
- <string name="folder_name_format_overflow" msgid="4270108890534995199">"Carpeta: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> o más elementos"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"Carpeta: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"Widgets"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Fondos de pantalla"</string>
- <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Fondo de pantalla y estilo"</string>
- <string name="settings_button_text" msgid="8873672322605444408">"Configuración de pantalla principal"</string>
+ <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Estilos y fondos de pantalla"</string>
+ <string name="settings_button_text" msgid="8873672322605444408">"Configuración de página principal"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"El administrador inhabilitó esta función"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Permitir la rotación de la pantalla principal"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Al girar el teléfono"</string>
@@ -114,16 +92,16 @@
<string name="msg_missing_notification_access" msgid="281113995110910548">"Para mostrar los puntos de notificación, activa las notificaciones de la app para <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="title_change_settings" msgid="1376365968844349552">"Cambiar la configuración"</string>
<string name="notification_dots_service_title" msgid="4284221181793592871">"Mostrar puntos de notificación"</string>
- <string name="auto_add_shortcuts_label" msgid="3698776050751790653">"Agrega íconos de apps a pantalla principal"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Agregar ícono a la pantalla principal"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Para nuevas apps"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"Desconocido"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"Eliminar"</string>
<string name="abandoned_search" msgid="891119232568284442">"Buscar"</string>
<string name="abandoned_promises_title" msgid="7096178467971716750">"Esta aplicación no está instalada"</string>
<string name="abandoned_promise_explanation" msgid="3990027586878167529">"La aplicación para este ícono no está instalada. Puedes eliminar el ícono o buscar la aplicación e instarla manualmente."</string>
- <string name="app_installing_title" msgid="5864044122733792085">"Se está instalando <xliff:g id="NAME">%1$s</xliff:g>; <xliff:g id="PROGRESS">%2$s</xliff:g> completado"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"Se completó el <xliff:g id="PROGRESS">%2$s</xliff:g> de la descarga de <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"Instalación de <xliff:g id="NAME">%1$s</xliff:g> en espera"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"Widgets de <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="widgets_list" msgid="796804551140113767">"Lista de widgets"</string>
<string name="widgets_list_closed" msgid="6141506579418771922">"Se cerró la lista de widgets"</string>
<string name="action_add_to_workspace" msgid="8902165848117513641">"Agregar a la pantalla principal"</string>
@@ -151,20 +129,15 @@
<string name="action_deep_shortcut" msgid="2864038805849372848">"Accesos directos"</string>
<string name="shortcuts_menu_with_notifications_description" msgid="2676582286544232849">"Accesos directos y notificaciones"</string>
<string name="action_dismiss_notification" msgid="5909461085055959187">"Descartar"</string>
- <string name="accessibility_close" msgid="2277148124685870734">"Cerrar"</string>
<string name="notification_dismissed" msgid="6002233469409822874">"Se descartó la notificación"</string>
<string name="all_apps_personal_tab" msgid="4190252696685155002">"Personales"</string>
- <string name="all_apps_work_tab" msgid="4884822796154055118">"De trabajo"</string>
+ <string name="all_apps_work_tab" msgid="4884822796154055118">"Laborales"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"Perfil de trabajo"</string>
- <string name="work_profile_edu_work_apps" msgid="7895468576497746520">"Las apps de trabajo tienen una insignia y el administrador de TI las puede ver"</string>
- <string name="work_profile_edu_accept" msgid="6069788082535149071">"Entendido"</string>
- <string name="work_apps_paused_title" msgid="3040901117349444598">"Las apps de trabajo están detenidas"</string>
- <string name="work_apps_paused_body" msgid="261634750995824906">"Las apps de trabajo no pueden enviarte notificaciones, usar la batería ni acceder a tu ubicación"</string>
- <string name="work_apps_paused_content_description" msgid="5149623040804051095">"Las apps de trabajo están desactivadas y, por ende, no pueden enviarte notificaciones, usar la batería ni acceder a tu ubicación"</string>
- <string name="work_apps_paused_edu_banner" msgid="8872412121608402058">"Las apps de trabajo tienen una insignia y el administrador de TI las puede ver"</string>
- <string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"Entendido"</string>
- <string name="work_apps_pause_btn_text" msgid="1921059713673767460">"Desactivar las apps de trabajo"</string>
- <string name="work_apps_enable_btn_text" msgid="1156432622148413741">"Activar las apps de trabajo"</string>
- <string name="developer_options_filter_hint" msgid="5896817443635989056">"Filtro"</string>
+ <string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"Apps de trabajo"</string>
+ <string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"Cada app de trabajo tiene una insignia y está protegida por tu organización. Transfiere las apps a la pantalla principal para acceder a ellas con mayor facilidad."</string>
+ <string name="work_mode_on_label" msgid="4781128097185272916">"Administrado por tu organización"</string>
+ <string name="work_mode_off_label" msgid="3194894777601421047">"Las notificaciones y las apps están desactivadas"</string>
+ <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Cerrar"</string>
+ <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Cerrado"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Error: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
</resources>
diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml
index 24010548fd..09b1239972 100644
--- a/res/values-es/strings.xml
+++ b/res/values-es/strings.xml
@@ -20,63 +20,39 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="649227358658669779">"Launcher3"</string>
+ <string name="folder_name" msgid="7371454440695724752"></string>
<string name="work_folder_name" msgid="3753320833950115786">"Trabajo"</string>
<string name="activity_not_found" msgid="8071924732094499514">"La aplicación no está instalada."</string>
<string name="activity_not_available" msgid="7456344436509528827">"La aplicación no está disponible"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"Aplicación descargada inhabilitada en modo seguro"</string>
<string name="safemode_widget_error" msgid="4863470563535682004">"Widgets inhabilitados en modo seguro"</string>
<string name="shortcut_not_available" msgid="2536503539825726397">"Acceso directo no disponible"</string>
- <string name="home_screen" msgid="5629429142036709174">"Inicio"</string>
- <string name="recent_task_option_split_screen" msgid="6690461455618725183">"Pantalla dividida"</string>
- <string name="split_screen_position_top" msgid="1504965011158689649">"Dividir parte superior"</string>
- <string name="split_screen_position_left" msgid="7537793098851830883">"Dividir parte izquierda"</string>
- <string name="split_screen_position_right" msgid="1569377524925193369">"Dividir parte derecha"</string>
- <string name="split_app_info_accessibility" msgid="5475288491241414932">"Información de la aplicación %1$s"</string>
- <string name="long_press_widget_to_add" msgid="3587712543577675817">"Mantén pulsado un widget para moverlo."</string>
- <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Toca dos veces y mantén pulsado un widget para moverlo o usar acciones personalizadas."</string>
+ <string name="home_screen" msgid="806512411299847073">"Pantalla de inicio"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"Acciones personalizadas"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"Mantén pulsado el widget que quieras seleccionar."</string>
+ <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Toca dos veces y mantén pulsado el widget que quieras seleccionar o utiliza acciones personalizadas."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d de ancho por %2$d de alto"</string>
- <string name="widget_preview_context_description" msgid="9045841361655787574">"Widget de <xliff:g id="WIDGET_NAME">%1$s</xliff:g>"</string>
- <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Mantén pulsado el widget para moverlo por la pantalla de inicio"</string>
- <string name="add_to_home_screen" msgid="8631549138215492708">"Añadir a la pantalla de inicio"</string>
- <string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"Widget <xliff:g id="WIDGET_NAME">%1$s</xliff:g> añadido a la pantalla de inicio"</string>
- <string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# widget}other{# widgets}}"</string>
- <string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{# combinación de teclas}other{# combinaciones de teclas}}"</string>
- <string name="widgets_and_shortcuts_count" msgid="7209136747878365116">"<xliff:g id="WIDGETS_COUNT">%1$s</xliff:g>, <xliff:g id="SHORTCUTS_COUNT">%2$s</xliff:g>"</string>
- <string name="widget_button_text" msgid="2880537293434387943">"Widgets"</string>
- <string name="widgets_full_sheet_search_bar_hint" msgid="8484659090860596457">"Buscar"</string>
- <string name="widgets_full_sheet_cancel_button_description" msgid="5766167035728653605">"Borrar texto del cuadro de búsqueda"</string>
- <string name="no_widgets_available" msgid="4337693382501046170">"Los widgets y los accesos directos no están disponibles"</string>
- <string name="no_search_results" msgid="3787956167293097509">"No se han encontrado widgets ni accesos directos"</string>
- <string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Personales"</string>
- <string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Trabajo"</string>
- <string name="widget_category_conversations" msgid="8894438636213590446">"Conversaciones"</string>
- <string name="widget_education_header" msgid="4874760613775913787">"Información útil al alcance de la mano"</string>
- <string name="widget_education_content" msgid="745542879510751525">"Para recibir información sin abrir aplicaciones, puedes añadir widgets a la pantalla de inicio."</string>
- <string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Toca para cambiar los ajustes del widget"</string>
- <string name="widget_education_close_button" msgid="8676165703104836580">"Entendido"</string>
- <string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Cambiar ajustes del widget"</string>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Mantenlo pulsado para añadirlo manualmente"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"Añadir automáticamente"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Buscar aplicaciones"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Cargando aplicaciones…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"No se han encontrado aplicaciones que contengan \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
<string name="all_apps_search_market_message" msgid="1366263386197059176">"Buscar más aplicaciones"</string>
<string name="label_application" msgid="8531721983832654978">"Aplicación"</string>
- <string name="all_apps_label" msgid="5015784846527570951">"Todas las aplicaciones"</string>
<string name="notifications_header" msgid="1404149926117359025">"Notificaciones"</string>
- <string name="long_press_shortcut_to_add" msgid="5405328730817637737">"Mantén pulsado un acceso directo para moverlo."</string>
- <string name="long_accessible_way_to_add_shortcut" msgid="2199537273817090740">"Toca dos veces y mantén pulsado un acceso directo para moverlo o usar acciones personalizadas."</string>
- <string name="out_of_space" msgid="6692471482459245734">"No queda espacio en la pantalla de inicio"</string>
+ <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"Mantén pulsado para elegir un acceso directo."</string>
+ <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"Toca dos veces y mantén pulsado para elegir un acceso directo o utilizar acciones personalizadas."</string>
+ <string name="out_of_space" msgid="4691004494942118364">"No queda espacio en la pantalla de inicio."</string>
<string name="hotseat_out_of_space" msgid="7448809638125333693">"La bandeja de favoritos está completa"</string>
<string name="all_apps_button_label" msgid="8130441508702294465">"Lista de aplicaciones"</string>
- <string name="all_apps_search_results" msgid="5889367432531296759">"Resultados de búsqueda"</string>
<string name="all_apps_button_personal_label" msgid="1315764287305224468">"Lista de aplicaciones personales"</string>
<string name="all_apps_button_work_label" msgid="7270707118948892488">"Lista de aplicaciones del trabajo"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"Inicio"</string>
<string name="remove_drop_target_label" msgid="7812859488053230776">"Quitar"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"Desinstalar"</string>
<string name="app_info_drop_target_label" msgid="692894985365717661">"Información de la aplicación"</string>
<string name="install_drop_target_label" msgid="2539096853673231757">"Instalar"</string>
- <string name="dismiss_prediction_label" msgid="3357562989568808658">"No sugerir aplicación"</string>
- <string name="pin_prediction" msgid="4196423321649756498">"Fijar predicción"</string>
<string name="permlab_install_shortcut" msgid="5632423390354674437">"instalar accesos directos"</string>
<string name="permdesc_install_shortcut" msgid="923466509822011139">"Permite que una aplicación añada accesos directos sin intervención del usuario."</string>
<string name="permlab_read_settings" msgid="1941457408239617576">"leer información de accesos directos y de ajustes de la pantalla de inicio"</string>
@@ -84,13 +60,15 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"escribir información de accesos directos y de ajustes de la pantalla de inicio"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"Permite que las aplicaciones cambien los ajustes y los accesos directos de la pantalla de inicio."</string>
<string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> no puede hacer llamadas"</string>
- <string name="gadget_error_text" msgid="740356548025791839">"No se puede cargar el widget"</string>
- <string name="gadget_setup_text" msgid="8348374825537681407">"Ajustes de widget"</string>
- <string name="gadget_complete_setup_text" msgid="309040266978007925">"Toca para finalizar la configuración"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"Problema al cargar el widget"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"Configuración"</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"Esta aplicación es del sistema y no se puede desinstalar."</string>
- <string name="folder_hint_text" msgid="5174843001373488816">"Editar nombre"</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"Carpeta sin nombre"</string>
<string name="disabled_app_label" msgid="6673129024321402780">"Se ha inhabilitado <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
- <string name="dotted_app_label" msgid="1704091277755818896">"{count,plural,offset:1 =1{{app_name} tiene # notificación}other{{app_name} tiene # notificaciones}}"</string>
+ <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+ <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g> tiene <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> notificaciones</item>
+ <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g> tiene <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> notificación</item>
+ </plurals>
<string name="default_scroll_format" msgid="7475544710230993317">"Página %1$d de %2$d"</string>
<string name="workspace_scroll_format" msgid="8458889198184077399">"Pantalla de inicio %1$d de %2$d"</string>
<string name="workspace_new_page" msgid="257366611030256142">"Nueva página de pantalla de inicio"</string>
@@ -99,37 +77,37 @@
<string name="folder_tap_to_rename" msgid="4017685068016979677">"Toca para guardar el nuevo nombre"</string>
<string name="folder_closed" msgid="4100806530910930934">"Carpeta cerrada"</string>
<string name="folder_renamed" msgid="1794088362165669656">"Se ha cambiado el nombre de la carpeta a <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="folder_name_format_exact" msgid="8626242716117004803">"Carpeta: <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SIZE">%2$d</xliff:g> elementos)"</string>
- <string name="folder_name_format_overflow" msgid="4270108890534995199">"Carpeta: <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SIZE">%2$d</xliff:g> o más elementos)"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"Carpeta: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"Widgets"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Fondos de pantalla"</string>
- <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Fondo de pantalla y estilo"</string>
+ <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Estilos y fondos de pantalla"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Ajustes de la pantalla de inicio"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Inhabilitado por el administrador"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Permitir rotación de la pantalla de inicio"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Al girar el teléfono"</string>
<string name="notification_dots_title" msgid="9062440428204120317">"Puntos de notificación"</string>
- <string name="notification_dots_desc_on" msgid="1679848116452218908">"Activado"</string>
+ <string name="notification_dots_desc_on" msgid="1679848116452218908">"Activados"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"Desactivadas"</string>
<string name="title_missing_notification_access" msgid="7503287056163941064">"Se necesita acceso a las notificaciones"</string>
<string name="msg_missing_notification_access" msgid="281113995110910548">"Para mostrar puntos de notificación, activa las notificaciones de <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="title_change_settings" msgid="1376365968844349552">"Cambiar ajustes"</string>
<string name="notification_dots_service_title" msgid="4284221181793592871">"Mostrar puntos de notificación"</string>
- <string name="auto_add_shortcuts_label" msgid="3698776050751790653">"Añadir aplicaciones a la pantalla de inicio"</string>
- <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Añade el icono de una aplicación nueva instalada a la pantalla de inicio"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Añadir icono a la pantalla de inicio"</string>
+ <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Para aplicaciones nuevas"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"Desconocido"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"Quitar"</string>
<string name="abandoned_search" msgid="891119232568284442">"Buscar"</string>
<string name="abandoned_promises_title" msgid="7096178467971716750">"Esta aplicación no está instalada"</string>
<string name="abandoned_promise_explanation" msgid="3990027586878167529">"La aplicación de este icono no está instalada. Puedes quitar el icono o buscar la aplicación e instalarla manualmente."</string>
- <string name="app_installing_title" msgid="5864044122733792085">"Instalando <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="PROGRESS">%2$s</xliff:g> completado"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"Descargando <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="PROGRESS">%2$s</xliff:g> completado)"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"Esperando para instalar <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"Widgets de <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="widgets_list" msgid="796804551140113767">"Lista de widgets"</string>
<string name="widgets_list_closed" msgid="6141506579418771922">"Lista de widgets cerrada"</string>
<string name="action_add_to_workspace" msgid="8902165848117513641">"Añadir a la pantalla de inicio"</string>
<string name="action_move_here" msgid="2170188780612570250">"Mover elemento aquí"</string>
<string name="item_added_to_workspace" msgid="4211073925752213539">"Elemento añadido a la pantalla de inicio"</string>
- <string name="item_removed" msgid="851119963877842327">"Elemento quitado"</string>
+ <string name="item_removed" msgid="851119963877842327">"Elemento eliminado"</string>
<string name="undo" msgid="4151576204245173321">"Deshacer"</string>
<string name="action_move" msgid="4339390619886385032">"Mover elemento"</string>
<string name="move_to_empty_cell" msgid="2833711483015685619">"Mover a la fila <xliff:g id="NUMBER_0">%1$s</xliff:g>, columna <xliff:g id="NUMBER_1">%2$s</xliff:g>"</string>
@@ -151,20 +129,15 @@
<string name="action_deep_shortcut" msgid="2864038805849372848">"Accesos directos"</string>
<string name="shortcuts_menu_with_notifications_description" msgid="2676582286544232849">"Accesos directos y notificaciones"</string>
<string name="action_dismiss_notification" msgid="5909461085055959187">"Cerrar"</string>
- <string name="accessibility_close" msgid="2277148124685870734">"Cerrar"</string>
<string name="notification_dismissed" msgid="6002233469409822874">"Notificación ignorada"</string>
<string name="all_apps_personal_tab" msgid="4190252696685155002">"Personal"</string>
<string name="all_apps_work_tab" msgid="4884822796154055118">"Trabajo"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"Perfil de trabajo"</string>
- <string name="work_profile_edu_work_apps" msgid="7895468576497746520">"Las aplicaciones de trabajo tienen una insignia, y tu administrador de TI las puede ver"</string>
- <string name="work_profile_edu_accept" msgid="6069788082535149071">"Entendido"</string>
- <string name="work_apps_paused_title" msgid="3040901117349444598">"Las aplicaciones de trabajo están en pausa"</string>
- <string name="work_apps_paused_body" msgid="261634750995824906">"Tus aplicaciones de trabajo no pueden enviarte notificaciones, usar batería ni acceder a tu ubicación"</string>
- <string name="work_apps_paused_content_description" msgid="5149623040804051095">"Las aplicaciones de trabajo están desactivadas, por lo que no pueden enviarte notificaciones, consumir batería ni acceder a tu ubicación"</string>
- <string name="work_apps_paused_edu_banner" msgid="8872412121608402058">"Las aplicaciones de trabajo tienen una insignia y tu administrador de TI las puede ver"</string>
- <string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"Entendido"</string>
- <string name="work_apps_pause_btn_text" msgid="1921059713673767460">"Desactivar aplicaciones de trabajo"</string>
- <string name="work_apps_enable_btn_text" msgid="1156432622148413741">"Activar aplicaciones de trabajo"</string>
- <string name="developer_options_filter_hint" msgid="5896817443635989056">"Filtro"</string>
+ <string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"Aplicaciones de trabajo"</string>
+ <string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"Cada aplicación de trabajo tiene una insignia y está protegida por tu organización. Mueve las aplicaciones a la pantalla de inicio para acceder a ellas más fácilmente."</string>
+ <string name="work_mode_on_label" msgid="4781128097185272916">"Administrada por tu organización"</string>
+ <string name="work_mode_off_label" msgid="3194894777601421047">"Las notificaciones y las aplicaciones están desactivadas"</string>
+ <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Cerrar"</string>
+ <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Cerrada"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Se ha producido un error: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
</resources>
diff --git a/res/values-et/strings.xml b/res/values-et/strings.xml
index e4830415e6..1e470e15a7 100644
--- a/res/values-et/strings.xml
+++ b/res/values-et/strings.xml
@@ -20,63 +20,39 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="649227358658669779">"Launcher3"</string>
+ <string name="folder_name" msgid="7371454440695724752"></string>
<string name="work_folder_name" msgid="3753320833950115786">"Töö"</string>
<string name="activity_not_found" msgid="8071924732094499514">"Rakendus pole installitud."</string>
<string name="activity_not_available" msgid="7456344436509528827">"Rakendus ei ole saadaval"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"Allalaetud rakendus on turvarežiimis keelatud"</string>
<string name="safemode_widget_error" msgid="4863470563535682004">"Turvarežiimis on vidinad keelatud"</string>
<string name="shortcut_not_available" msgid="2536503539825726397">"Otsetee pole saadaval"</string>
- <string name="home_screen" msgid="5629429142036709174">"Avakuva"</string>
- <string name="recent_task_option_split_screen" msgid="6690461455618725183">"Jagatud ekraanikuva"</string>
- <string name="split_screen_position_top" msgid="1504965011158689649">"Jaga üles"</string>
- <string name="split_screen_position_left" msgid="7537793098851830883">"Jaga vasakule"</string>
- <string name="split_screen_position_right" msgid="1569377524925193369">"Jaga paremale"</string>
- <string name="split_app_info_accessibility" msgid="5475288491241414932">"Rakenduse teave: %1$s"</string>
- <string name="long_press_widget_to_add" msgid="3587712543577675817">"Vidina teisaldamiseks puudutage ja hoidke all."</string>
- <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Vidina teisaldamiseks või kohandatud toimingute kasutamiseks topeltpuudutage ja hoidke all."</string>
+ <string name="home_screen" msgid="806512411299847073">"Avakuva"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"Kohandatud toimingud"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"Vidina valimiseks vajutage ja hoidke seda all."</string>
+ <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Topeltpuudutage ja hoidke vidina valimiseks või kohandatud toimingute kasutamiseks."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d lai ja %2$d kõrge"</string>
- <string name="widget_preview_context_description" msgid="9045841361655787574">"Vidin <xliff:g id="WIDGET_NAME">%1$s</xliff:g>"</string>
- <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Vidina teisaldamiseks avakuval puudutage vidinat ja hoidke seda all"</string>
- <string name="add_to_home_screen" msgid="8631549138215492708">"Lisa avakuvale"</string>
- <string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"Vidin <xliff:g id="WIDGET_NAME">%1$s</xliff:g> lisati avakuvale"</string>
- <string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# vidin}other{# vidinat}}"</string>
- <string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{# otsetee}other{# otseteed}}"</string>
- <string name="widgets_and_shortcuts_count" msgid="7209136747878365116">"<xliff:g id="WIDGETS_COUNT">%1$s</xliff:g>, <xliff:g id="SHORTCUTS_COUNT">%2$s</xliff:g>"</string>
- <string name="widget_button_text" msgid="2880537293434387943">"Vidinad"</string>
- <string name="widgets_full_sheet_search_bar_hint" msgid="8484659090860596457">"Otsing"</string>
- <string name="widgets_full_sheet_cancel_button_description" msgid="5766167035728653605">"Kustuta otsingukastis olev tekst"</string>
- <string name="no_widgets_available" msgid="4337693382501046170">"Vidinad ja otseteed pole saadaval"</string>
- <string name="no_search_results" msgid="3787956167293097509">"Ei leitud ühtegi vidinat ega otseteed"</string>
- <string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Isiklikud"</string>
- <string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Töö"</string>
- <string name="widget_category_conversations" msgid="8894438636213590446">"Vestlused"</string>
- <string name="widget_education_header" msgid="4874760613775913787">"Kasulik teave on teie käeulatuses"</string>
- <string name="widget_education_content" msgid="745542879510751525">"Teabe saamiseks rakendusi avamata võite oma avakuvale lisada vidinaid"</string>
- <string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Puudutage vidina seadete muutmiseks"</string>
- <string name="widget_education_close_button" msgid="8676165703104836580">"Selge"</string>
- <string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Vidina seadete muutmine"</string>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Puudutage pikalt, et käsitsi asetada"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"Lisa automaatselt"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Otsige rakendusi"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Rakenduste laadimine …"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"Päringule „<xliff:g id="QUERY">%1$s</xliff:g>” ei vastanud ükski rakendus"</string>
<string name="all_apps_search_market_message" msgid="1366263386197059176">"Otsi rohkem rakendusi"</string>
<string name="label_application" msgid="8531721983832654978">"Rakendus"</string>
- <string name="all_apps_label" msgid="5015784846527570951">"Kõik rakendused"</string>
<string name="notifications_header" msgid="1404149926117359025">"Märguanded"</string>
- <string name="long_press_shortcut_to_add" msgid="5405328730817637737">"Otsetee teisaldamiseks puudutage ja hoidke all."</string>
- <string name="long_accessible_way_to_add_shortcut" msgid="2199537273817090740">"Otsetee teisaldamiseks või kohandatud toimingute kasutamiseks topeltpuudutage ja hoidke all."</string>
- <string name="out_of_space" msgid="6692471482459245734">"Sellel avakuval pole ruumi"</string>
+ <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"Otsetee valimiseks puudutage seda pikalt."</string>
+ <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"Topeltpuudutage ja hoidke otsetee valimiseks või kohandatud toimingute kasutamiseks."</string>
+ <string name="out_of_space" msgid="4691004494942118364">"Sellel avaekraanil pole enam ruumi."</string>
<string name="hotseat_out_of_space" msgid="7448809638125333693">"Salves Lemmikud pole rohkem ruumi"</string>
<string name="all_apps_button_label" msgid="8130441508702294465">"Rakenduste loend"</string>
- <string name="all_apps_search_results" msgid="5889367432531296759">"Otsingutulemused"</string>
<string name="all_apps_button_personal_label" msgid="1315764287305224468">"Isiklike rakenduste loend"</string>
<string name="all_apps_button_work_label" msgid="7270707118948892488">"Töörakenduste loend"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"Avakuva"</string>
<string name="remove_drop_target_label" msgid="7812859488053230776">"Eemalda"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"Desinstalli"</string>
- <string name="app_info_drop_target_label" msgid="692894985365717661">"Rakenduste teave"</string>
+ <string name="app_info_drop_target_label" msgid="692894985365717661">"Rakenduse teave"</string>
<string name="install_drop_target_label" msgid="2539096853673231757">"Installimine"</string>
- <string name="dismiss_prediction_label" msgid="3357562989568808658">"Ära soovita rakendust"</string>
- <string name="pin_prediction" msgid="4196423321649756498">"Kinnita ennustus"</string>
<string name="permlab_install_shortcut" msgid="5632423390354674437">"installi otseteed"</string>
<string name="permdesc_install_shortcut" msgid="923466509822011139">"Võimaldab rakendusel lisada otseteid kasutaja sekkumiseta."</string>
<string name="permlab_read_settings" msgid="1941457408239617576">"avakuva seadete ja otseteede lugemine"</string>
@@ -84,13 +60,15 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"avakuva seadete ja otseteede kirjutamine"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"Võimaldab rakendusel muuta avaekraanil seadeid ja otseteid."</string>
<string name="msg_no_phone_permission" msgid="9208659281529857371">"Rakendusel <xliff:g id="APP_NAME">%1$s</xliff:g> pole lubatud helistada"</string>
- <string name="gadget_error_text" msgid="740356548025791839">"Vidinat ei saa laadida"</string>
- <string name="gadget_setup_text" msgid="8348374825537681407">"Vidina seaded"</string>
- <string name="gadget_complete_setup_text" msgid="309040266978007925">"Puudutage seadistuse lõpuleviimiseks"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"Probleem vidina laadimisel"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"Seadistamine"</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"See on süsteemirakendus ja seda ei saa desinstallida."</string>
- <string name="folder_hint_text" msgid="5174843001373488816">"Muuda nime"</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"Nimetu kaust"</string>
<string name="disabled_app_label" msgid="6673129024321402780">"Rakendus <xliff:g id="APP_NAME">%1$s</xliff:g> on keelatud"</string>
- <string name="dotted_app_label" msgid="1704091277755818896">"{count,plural,offset:1 =1{Rakenduses {app_name} on # märguanne}other{Rakenduses {app_name} on # märguannet}}"</string>
+ <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+ <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> märguannet</item>
+ <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g>, <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> märguanne</item>
+ </plurals>
<string name="default_scroll_format" msgid="7475544710230993317">"Leht %1$d/%2$d"</string>
<string name="workspace_scroll_format" msgid="8458889198184077399">"Avakuva %1$d/%2$d"</string>
<string name="workspace_new_page" msgid="257366611030256142">"Uus avakuva leht"</string>
@@ -99,10 +77,10 @@
<string name="folder_tap_to_rename" msgid="4017685068016979677">"Puudutage ümbernimetamise salvestamiseks"</string>
<string name="folder_closed" msgid="4100806530910930934">"Kaust on suletud"</string>
<string name="folder_renamed" msgid="1794088362165669656">"Kausta uus nimi: <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="folder_name_format_exact" msgid="8626242716117004803">"Kaust: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> üksust"</string>
- <string name="folder_name_format_overflow" msgid="4270108890534995199">"Kaust: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> või rohkem üksust"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"Kaust: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"Vidinad"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Taustapildid"</string>
- <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Taustapilt ja stiil"</string>
+ <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Stiilid ja taustapildid"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Avakuva seaded"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Keelas administraator"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Luba avakuva pööramine"</string>
@@ -114,16 +92,16 @@
<string name="msg_missing_notification_access" msgid="281113995110910548">"Märguandetäppide kuvamiseks lülitage sisse rakenduse <xliff:g id="NAME">%1$s</xliff:g> märguanded"</string>
<string name="title_change_settings" msgid="1376365968844349552">"Seadete muutmine"</string>
<string name="notification_dots_service_title" msgid="4284221181793592871">"Kuva märguandetäpid"</string>
- <string name="auto_add_shortcuts_label" msgid="3698776050751790653">"Lisa rakenduste ikoonid avakuvale"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Lisa ikoon avakuvasse"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Uute rakenduste puhul"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"Teadmata"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"Eemalda"</string>
<string name="abandoned_search" msgid="891119232568284442">"Otsing"</string>
<string name="abandoned_promises_title" msgid="7096178467971716750">"See rakendus ei ole installitud"</string>
<string name="abandoned_promise_explanation" msgid="3990027586878167529">"Selle ikooni rakendust pole installitud. Saate selle eemaldada või rakendust otsida ja käsitsi installida."</string>
- <string name="app_installing_title" msgid="5864044122733792085">"Üksust <xliff:g id="NAME">%1$s</xliff:g> installitakse, <xliff:g id="PROGRESS">%2$s</xliff:g> on valmis"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"Rakenduse <xliff:g id="NAME">%1$s</xliff:g> allalaadimine, <xliff:g id="PROGRESS">%2$s</xliff:g> on valmis"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> on installimise ootel"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"Teenuse <xliff:g id="NAME">%1$s</xliff:g> vidinad"</string>
<string name="widgets_list" msgid="796804551140113767">"Vidinate loend"</string>
<string name="widgets_list_closed" msgid="6141506579418771922">"Vidinate loend on suletud"</string>
<string name="action_add_to_workspace" msgid="8902165848117513641">"Lisa avakuvasse"</string>
@@ -151,20 +129,15 @@
<string name="action_deep_shortcut" msgid="2864038805849372848">"Otseteed"</string>
<string name="shortcuts_menu_with_notifications_description" msgid="2676582286544232849">"Otseteed ja märguanded"</string>
<string name="action_dismiss_notification" msgid="5909461085055959187">"Loobu"</string>
- <string name="accessibility_close" msgid="2277148124685870734">"Sule"</string>
<string name="notification_dismissed" msgid="6002233469409822874">"Märguandest loobuti"</string>
<string name="all_apps_personal_tab" msgid="4190252696685155002">"Isiklik"</string>
<string name="all_apps_work_tab" msgid="4884822796154055118">"Töö"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"Tööprofiil"</string>
- <string name="work_profile_edu_work_apps" msgid="7895468576497746520">"Töörakendustel on märk ja need on teie IT-administraatorile nähtavad"</string>
- <string name="work_profile_edu_accept" msgid="6069788082535149071">"Selge"</string>
- <string name="work_apps_paused_title" msgid="3040901117349444598">"Töörakendused on peatatud"</string>
- <string name="work_apps_paused_body" msgid="261634750995824906">"Töörakendused ei saa teile märguandeid saata, akut kasutada ega teie asukohale juurde pääseda"</string>
- <string name="work_apps_paused_content_description" msgid="5149623040804051095">"Töörakendused on välja lülitatud. Töörakendused ei saa teile märguandeid saata, akut kasutada ega teie asukohale juurde pääseda."</string>
- <string name="work_apps_paused_edu_banner" msgid="8872412121608402058">"Töörakendustel on märk ja need on teie IT-administraatorile nähtavad"</string>
- <string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"Selge"</string>
- <string name="work_apps_pause_btn_text" msgid="1921059713673767460">"Lülita töörakendused välja"</string>
- <string name="work_apps_enable_btn_text" msgid="1156432622148413741">"Lülita töörakendused sisse"</string>
- <string name="developer_options_filter_hint" msgid="5896817443635989056">"Filter"</string>
+ <string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"Töörakendused leiate siit"</string>
+ <string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"Igal töörakendusel on märk ja teie organisatsioon tagab selle turvalisuse. Teisaldage rakendused avaekraanile, et neile oleks lihtsam juurde pääseda."</string>
+ <string name="work_mode_on_label" msgid="4781128097185272916">"Haldab teie organisatsioon"</string>
+ <string name="work_mode_off_label" msgid="3194894777601421047">"Märguanded ja rakendused on välja lülitatud"</string>
+ <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Sule"</string>
+ <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Suletud"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Nurjus: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
</resources>
diff --git a/res/values-eu/strings.xml b/res/values-eu/strings.xml
index f1cc45eae7..10aebe7ad6 100644
--- a/res/values-eu/strings.xml
+++ b/res/values-eu/strings.xml
@@ -26,57 +26,32 @@
<string name="safemode_shortcut_error" msgid="9160126848219158407">"Deskargatutako aplikazioa modu seguruan desgaitu da"</string>
<string name="safemode_widget_error" msgid="4863470563535682004">"Widgetak desgaitu egin dira modu seguruan"</string>
<string name="shortcut_not_available" msgid="2536503539825726397">"Lasterbideak ez daude erabilgarri"</string>
- <string name="home_screen" msgid="5629429142036709174">"Hasierako pantaila"</string>
- <string name="recent_task_option_split_screen" msgid="6690461455618725183">"Zatitu pantaila"</string>
- <string name="split_screen_position_top" msgid="1504965011158689649">"Zatitu goialdean"</string>
- <string name="split_screen_position_left" msgid="7537793098851830883">"Zatitu ezkerraldean"</string>
- <string name="split_screen_position_right" msgid="1569377524925193369">"Zatitu eskuinaldean"</string>
- <string name="split_app_info_accessibility" msgid="5475288491241414932">"%1$s aplikazioari buruzko informazioa"</string>
- <string name="long_press_widget_to_add" msgid="3587712543577675817">"Eduki sakatuta widget bat mugitzeko."</string>
- <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Sakatu birritan eta eduki sakatuta widget bat mugitzeko edo ekintza pertsonalizatuak erabiltzeko."</string>
+ <string name="home_screen" msgid="806512411299847073">"Hasierako pantaila"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"Ekintza pertsonalizatuak"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"Eduki sakatuta widgeta aukeratzeko."</string>
+ <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Sakatu birritan eta eduki sakatuta widgeta aukeratzeko edo ekintza pertsonalizatuak erabiltzeko."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d zabal eta %2$d luze"</string>
- <string name="widget_preview_context_description" msgid="9045841361655787574">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g> widgeta"</string>
- <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Eduki sakatuta widgeta hasierako pantailan zehar mugitzeko"</string>
- <string name="add_to_home_screen" msgid="8631549138215492708">"Gehitu hasierako pantailan"</string>
- <string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g> widgeta hasierako pantailan gehitu da"</string>
- <string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# widget}other{# widget}}"</string>
- <string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{# lasterbide}other{# lasterbide}}"</string>
- <string name="widgets_and_shortcuts_count" msgid="7209136747878365116">"<xliff:g id="WIDGETS_COUNT">%1$s</xliff:g>, <xliff:g id="SHORTCUTS_COUNT">%2$s</xliff:g>"</string>
- <string name="widget_button_text" msgid="2880537293434387943">"Widgetak"</string>
- <string name="widgets_full_sheet_search_bar_hint" msgid="8484659090860596457">"Bilatu"</string>
- <string name="widgets_full_sheet_cancel_button_description" msgid="5766167035728653605">"Garbitu bilaketa-koadroko testua"</string>
- <string name="no_widgets_available" msgid="4337693382501046170">"Widgetak eta lasterbideak erabilgarri daude"</string>
- <string name="no_search_results" msgid="3787956167293097509">"Ez da aurkitu widgetik edo lasterbiderik"</string>
- <string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Pertsonalak"</string>
- <string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Lanekoak"</string>
- <string name="widget_category_conversations" msgid="8894438636213590446">"Elkarrizketak"</string>
- <string name="widget_education_header" msgid="4874760613775913787">"Informazio erabilgarria beti eskura"</string>
- <string name="widget_education_content" msgid="745542879510751525">"Aplikaziorik ireki beharrik gabe informazioa zuzenean jasotzeko, gehitu widgetak hasierako pantailan"</string>
- <string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Sakatu hau widgeten ezarpenak aldatzeko"</string>
- <string name="widget_education_close_button" msgid="8676165703104836580">"Ados"</string>
- <string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Aldatu widgeten ezarpenak"</string>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Eduki sakatuta eskuz gehitzeko"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"Gehitu automatikoki"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Bilatu aplikazioetan"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Aplikazioak kargatzen…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"Ez da aurkitu \"<xliff:g id="QUERY">%1$s</xliff:g>\" bilaketaren emaitzarik"</string>
<string name="all_apps_search_market_message" msgid="1366263386197059176">"Bilatu aplikazio gehiago"</string>
<string name="label_application" msgid="8531721983832654978">"Aplikazioa"</string>
- <string name="all_apps_label" msgid="5015784846527570951">"Aplikazio guztiak"</string>
<string name="notifications_header" msgid="1404149926117359025">"Jakinarazpenak"</string>
- <string name="long_press_shortcut_to_add" msgid="5405328730817637737">"Eduki sakatuta lasterbide bat mugitzeko."</string>
- <string name="long_accessible_way_to_add_shortcut" msgid="2199537273817090740">"Sakatu birritan eta eduki sakatuta lasterbide bat mugitzeko edo ekintza pertsonalizatuak erabiltzeko."</string>
- <string name="out_of_space" msgid="6692471482459245734">"Ez dago tokirik hasierako pantailan"</string>
+ <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"Eduki sakatuta lasterbide bat aukeratzeko."</string>
+ <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"Sakatu birritan eta eduki sakatuta lasterbide bat aukeratzeko edo ekintza pertsonalizatuak erabiltzeko."</string>
+ <string name="out_of_space" msgid="4691004494942118364">"Hasierako pantaila honetan ez dago toki gehiago."</string>
<string name="hotseat_out_of_space" msgid="7448809638125333693">"Ez dago toki gehiago Gogokoak erretiluan"</string>
<string name="all_apps_button_label" msgid="8130441508702294465">"Aplikazioen zerrenda"</string>
- <string name="all_apps_search_results" msgid="5889367432531296759">"Bilaketa-emaitzak"</string>
<string name="all_apps_button_personal_label" msgid="1315764287305224468">"Aplikazio pertsonalen zerrenda"</string>
<string name="all_apps_button_work_label" msgid="7270707118948892488">"Laneko aplikazioen zerrenda"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"Hasiera"</string>
<string name="remove_drop_target_label" msgid="7812859488053230776">"Kendu"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"Desinstalatu"</string>
- <string name="app_info_drop_target_label" msgid="692894985365717661">"Aplikazioaren informazioa"</string>
+ <string name="app_info_drop_target_label" msgid="692894985365717661">"Aplikazioaren datuak"</string>
<string name="install_drop_target_label" msgid="2539096853673231757">"Instalatu"</string>
- <string name="dismiss_prediction_label" msgid="3357562989568808658">"Ez iradoki aplikazioa"</string>
- <string name="pin_prediction" msgid="4196423321649756498">"Ainguratu iragarpena"</string>
<string name="permlab_install_shortcut" msgid="5632423390354674437">"Instalatu lasterbideak"</string>
<string name="permdesc_install_shortcut" msgid="923466509822011139">"Erabiltzaileak ezer egin gabe lasterbideak gehitzeko baimena ematen die aplikazioei."</string>
<string name="permlab_read_settings" msgid="1941457408239617576">"Irakurri hasierako ezarpenak eta lasterbideak"</string>
@@ -84,29 +59,31 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"Idatzi hasierako ezarpenak eta lasterbideak"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"Hasierako pantailako ezarpenak eta lasterbideak aldatzeko baimena ematen die aplikazioei."</string>
<string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> aplikazioak ez du telefono-deiak egiteko baimenik"</string>
- <string name="gadget_error_text" msgid="740356548025791839">"Ezin da kargatu widgeta"</string>
- <string name="gadget_setup_text" msgid="8348374825537681407">"Widgetaren ezarpenak"</string>
- <string name="gadget_complete_setup_text" msgid="309040266978007925">"Sakatu konfiguratzen amaitzeko"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"Arazo bat izan da widgeta kargatzean"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"Konfigurazioa"</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"Sistema-aplikazioa da hau eta ezin da desinstalatu."</string>
- <string name="folder_hint_text" msgid="5174843001373488816">"Editatu izena"</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"Izenik gabeko karpeta"</string>
<string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> desgaituta dago"</string>
- <string name="dotted_app_label" msgid="1704091277755818896">"{count,plural,offset:1 =1{{app_name} aplikazioak # jakinarazpen dauka}other{{app_name} aplikazioak # jakinarazpen dauzka}}"</string>
+ <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+ <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g> aplikazioak <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> jakinarazpen ditu</item>
+ <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g> aplikazioak <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> jakinarazpen du</item>
+ </plurals>
<string name="default_scroll_format" msgid="7475544710230993317">"%1$d/%2$d orria"</string>
<string name="workspace_scroll_format" msgid="8458889198184077399">"%1$d/%2$d hasierako pantaila"</string>
<string name="workspace_new_page" msgid="257366611030256142">"Hasierako pantailaren orri berria"</string>
- <string name="folder_opened" msgid="94695026776264709">"Karpeta ireki da: <xliff:g id="WIDTH">%1$d</xliff:g> × <xliff:g id="HEIGHT">%2$d</xliff:g>"</string>
+ <string name="folder_opened" msgid="94695026776264709">"Karpeta ireki da: <xliff:g id="WIDTH">%1$d</xliff:g> x <xliff:g id="HEIGHT">%2$d</xliff:g>"</string>
<string name="folder_tap_to_close" msgid="4625795376335528256">"Karpeta ixteko, sakatu hau"</string>
<string name="folder_tap_to_rename" msgid="4017685068016979677">"Izen berria gordetzeko, sakatu hau"</string>
<string name="folder_closed" msgid="4100806530910930934">"Karpeta itxi da"</string>
<string name="folder_renamed" msgid="1794088362165669656">"Karpetari <xliff:g id="NAME">%1$s</xliff:g> izena eman zaio"</string>
- <string name="folder_name_format_exact" msgid="8626242716117004803">"<xliff:g id="NAME">%1$s</xliff:g> karpeta (<xliff:g id="SIZE">%2$d</xliff:g> elementu)"</string>
- <string name="folder_name_format_overflow" msgid="4270108890534995199">"<xliff:g id="NAME">%1$s</xliff:g> karpeta (<xliff:g id="SIZE">%2$d</xliff:g> elementu edo gehiago)"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"Karpeta: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"Widgetak"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Horma-paperak"</string>
- <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Horma-papera eta estiloa"</string>
+ <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Estiloak eta horma-paperak"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Hasierako pantailaren ezarpenak"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Administratzaileak desgaitu du"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Eman hasierako pantaila biratzeko baimena"</string>
- <string name="allow_rotation_desc" msgid="8662546029078692509">"Telefonoa biratzean"</string>
+ <string name="allow_rotation_desc" msgid="8662546029078692509">"Telefonoa biratzen denean"</string>
<string name="notification_dots_title" msgid="9062440428204120317">"Jakinarazpen-biribiltxoak"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"Aktibatuta"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"Desaktibatuta"</string>
@@ -114,16 +91,16 @@
<string name="msg_missing_notification_access" msgid="281113995110910548">"Jakinarazpen-biribiltxoak ikusteko, aktibatu <xliff:g id="NAME">%1$s</xliff:g> aplikazioaren jakinarazpenak"</string>
<string name="title_change_settings" msgid="1376365968844349552">"Aldatu ezarpenak"</string>
<string name="notification_dots_service_title" msgid="4284221181793592871">"Erakutsi jakinarazpen-biribiltxoak"</string>
- <string name="auto_add_shortcuts_label" msgid="3698776050751790653">"Gehitu aplikazioen ikonoak hasierako pantailan"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Gehitu ikonoa hasierako pantailan"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Aplikazio berrien kasuan"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"Ezezaguna"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"Kendu"</string>
<string name="abandoned_search" msgid="891119232568284442">"Bilatu"</string>
<string name="abandoned_promises_title" msgid="7096178467971716750">"Aplikazio hau ez dago instalatuta"</string>
<string name="abandoned_promise_explanation" msgid="3990027586878167529">"Ikono honen aplikazioa ez dago instalatuta. Ikonoa ken dezakezu, edo aplikazioa bilatu eta eskuz instalatu."</string>
- <string name="app_installing_title" msgid="5864044122733792085">"<xliff:g id="NAME">%1$s</xliff:g> instalatzen, <xliff:g id="PROGRESS">%2$s</xliff:g> osatuta"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> deskargatzen, <xliff:g id="PROGRESS">%2$s</xliff:g> osatuta"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> instalatzeko zain"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"<xliff:g id="NAME">%1$s</xliff:g> widgetak"</string>
<string name="widgets_list" msgid="796804551140113767">"Widget-zerrenda"</string>
<string name="widgets_list_closed" msgid="6141506579418771922">"Itxi da widget-zerrenda"</string>
<string name="action_add_to_workspace" msgid="8902165848117513641">"Gehitu hasierako pantailan"</string>
@@ -151,20 +128,15 @@
<string name="action_deep_shortcut" msgid="2864038805849372848">"Lasterbideak"</string>
<string name="shortcuts_menu_with_notifications_description" msgid="2676582286544232849">"Lasterbideak eta jakinarazpenak"</string>
<string name="action_dismiss_notification" msgid="5909461085055959187">"Baztertu"</string>
- <string name="accessibility_close" msgid="2277148124685870734">"Itxi"</string>
<string name="notification_dismissed" msgid="6002233469409822874">"Baztertu egin da jakinarazpena"</string>
<string name="all_apps_personal_tab" msgid="4190252696685155002">"Pertsonalak"</string>
<string name="all_apps_work_tab" msgid="4884822796154055118">"Lanekoak"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"Laneko profila"</string>
- <string name="work_profile_edu_work_apps" msgid="7895468576497746520">"Laneko aplikazioek bereizgarriak dituzte, eta IKT saileko administratzaileak ikus ditzake"</string>
- <string name="work_profile_edu_accept" msgid="6069788082535149071">"Ados"</string>
- <string name="work_apps_paused_title" msgid="3040901117349444598">"Pausatu egin dira laneko aplikazioak"</string>
- <string name="work_apps_paused_body" msgid="261634750995824906">"Laneko aplikazioek ezin dute jakinarazpenik bidali, bateria erabili edo kokapena atzitu"</string>
- <string name="work_apps_paused_content_description" msgid="5149623040804051095">"Laneko aplikazioak desaktibatuta daude. Hori dela eta, ezin dute jakinarazpenik bidali, bateria erabili edo kokapena atzitu."</string>
- <string name="work_apps_paused_edu_banner" msgid="8872412121608402058">"Laneko aplikazioek bereizgarriak dituzte, eta IKT saileko administratzaileak ikus ditzake"</string>
- <string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"Ados"</string>
- <string name="work_apps_pause_btn_text" msgid="1921059713673767460">"Desaktibatu laneko aplikazioak"</string>
- <string name="work_apps_enable_btn_text" msgid="1156432622148413741">"Aktibatu laneko aplikazioak"</string>
- <string name="developer_options_filter_hint" msgid="5896817443635989056">"Iragazi"</string>
+ <string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"Hemen dituzu laneko aplikazioak"</string>
+ <string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"Laneko aplikazio bakoitzak bereizgarri bat dauka eta erakundeak babesten du. Aplikazioak errazago atzitzeko, eraman itzazu hasierako pantailara."</string>
+ <string name="work_mode_on_label" msgid="4781128097185272916">"Erakundeak kudeatzen du"</string>
+ <string name="work_mode_off_label" msgid="3194894777601421047">"Jakinarazpenak eta aplikazioak desaktibatuta daude"</string>
+ <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Itxi"</string>
+ <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Itxita"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Huts egin du: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
</resources>
diff --git a/res/values-fa/strings.xml b/res/values-fa/strings.xml
index a7b10208b1..926cdb9b1c 100644
--- a/res/values-fa/strings.xml
+++ b/res/values-fa/strings.xml
@@ -20,63 +20,39 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="649227358658669779">"Launcher3"</string>
+ <string name="folder_name" msgid="7371454440695724752"></string>
<string name="work_folder_name" msgid="3753320833950115786">"کاری"</string>
<string name="activity_not_found" msgid="8071924732094499514">"برنامه نصب نشده است."</string>
<string name="activity_not_available" msgid="7456344436509528827">"برنامه در دسترس نیست"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"برنامه بارگیری شده در حالت ایمن غیرفعال شد"</string>
<string name="safemode_widget_error" msgid="4863470563535682004">"ابزارک‌ها در حالت ایمن غیرفعال هستند"</string>
<string name="shortcut_not_available" msgid="2536503539825726397">"میان‌بر دردسترس نیست"</string>
- <string name="home_screen" msgid="5629429142036709174">"صفحه اصلی"</string>
- <string name="recent_task_option_split_screen" msgid="6690461455618725183">"صفحهٔ دونیمه"</string>
- <string name="split_screen_position_top" msgid="1504965011158689649">"تقسیم از بالا"</string>
- <string name="split_screen_position_left" msgid="7537793098851830883">"تقسیم از چپ"</string>
- <string name="split_screen_position_right" msgid="1569377524925193369">"تقسیم از راست"</string>
- <string name="split_app_info_accessibility" msgid="5475288491241414932">"‏اطلاعات برنامه %1$s"</string>
- <string name="long_press_widget_to_add" msgid="3587712543577675817">"برای جابه‌جا کردن ابزارک، لمس کنید و نگه دارید."</string>
- <string name="long_accessible_way_to_add" msgid="2733588281439571974">"برای جابه‌جا کردن ابزارک یا استفاده از کنش‌های سفارشی، دوضربه بزنید و نگه دارید."</string>
+ <string name="home_screen" msgid="806512411299847073">"صفحه اصلی"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"کنش‌های سفارشی"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"برای انتخاب ابزارک لمس کنید و نگه دارید."</string>
+ <string name="long_accessible_way_to_add" msgid="4289502106628154155">"برای انتخاب یک ابزارک، دو ضربه سریع بزنید و نگه‌دارید یا از کنش‌های سفارشی استفاده کنید."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"‏%1$d عرض در %2$d طول"</string>
- <string name="widget_preview_context_description" msgid="9045841361655787574">"ابزارک <xliff:g id="WIDGET_NAME">%1$s</xliff:g>"</string>
- <string name="add_item_request_drag_hint" msgid="5653291305078645405">"ابزارک را لمس کنید و نگه دارید تا آن را در صفحه اصلی حرکت دهید"</string>
- <string name="add_to_home_screen" msgid="8631549138215492708">"افزودن به صفحه اصلی"</string>
- <string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"ابزارک <xliff:g id="WIDGET_NAME">%1$s</xliff:g> به صفحه اصلی اضافه شد"</string>
- <string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{‏# ابزارک}one{‏# ابزارک}other{‏# ابزارک}}"</string>
- <string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{‏# میان‌بر}one{‏# میان‌بر}other{‏# میان‌بر}}"</string>
- <string name="widgets_and_shortcuts_count" msgid="7209136747878365116">"<xliff:g id="WIDGETS_COUNT">%1$s</xliff:g>،<xliff:g id="SHORTCUTS_COUNT">%2$s</xliff:g>"</string>
- <string name="widget_button_text" msgid="2880537293434387943">"ابزارک‌ها"</string>
- <string name="widgets_full_sheet_search_bar_hint" msgid="8484659090860596457">"جستجو"</string>
- <string name="widgets_full_sheet_cancel_button_description" msgid="5766167035728653605">"پاک کردن نوشتار از چارگوش جستجو"</string>
- <string name="no_widgets_available" msgid="4337693382501046170">"ابزارک و میان‌بری دردسترس نیست"</string>
- <string name="no_search_results" msgid="3787956167293097509">"هیچ ابزارک یا میان‌بری پیدا نشد"</string>
- <string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"ابزارک‌های شخصی"</string>
- <string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"کار"</string>
- <string name="widget_category_conversations" msgid="8894438636213590446">"مکالمه‌ها"</string>
- <string name="widget_education_header" msgid="4874760613775913787">"دسترسی آسان به اطلاعات سودمند"</string>
- <string name="widget_education_content" msgid="745542879510751525">"با افزودن ابزارک‌ها به «صفحه اصلی» می‌توانید اطلاعات را بدون باز کردن برنامه‌ها دریافت کنید"</string>
- <string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"برای تغییر تنظیمات ابزارک، ضربه بزنید"</string>
- <string name="widget_education_close_button" msgid="8676165703104836580">"متوجه‌ام"</string>
- <string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"تغییر تنظیمات ابزارک"</string>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"آن را لمس کنید و بکشید تا به‌صورت دستی اضافه شود"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"افزودن خودکار"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"جستجوی برنامه‌ها"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"درحال بارگیری برنامه‌‌ها…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"هیچ برنامه‌ای در مطابقت با «<xliff:g id="QUERY">%1$s</xliff:g>» پیدا نشد"</string>
<string name="all_apps_search_market_message" msgid="1366263386197059176">"جستجوی برنامه‌های بیشتر"</string>
<string name="label_application" msgid="8531721983832654978">"برنامه"</string>
- <string name="all_apps_label" msgid="5015784846527570951">"همه برنامه‌ها"</string>
<string name="notifications_header" msgid="1404149926117359025">"اعلان‌ها"</string>
- <string name="long_press_shortcut_to_add" msgid="5405328730817637737">"برای جابه‌جا کردن میان‌بر، لمس کنید و نگه دارید."</string>
- <string name="long_accessible_way_to_add_shortcut" msgid="2199537273817090740">"برای جابه‌جا کردن میان‌بر یا استفاده از کنش‌های سفارشی، دوضربه بزنید و نگه دارید."</string>
- <string name="out_of_space" msgid="6692471482459245734">"فضای خالی در این صفحه اصلی وجود ندارد"</string>
+ <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"برای انتخاب میان‌بر، لمس کنید و نگه‌دارید."</string>
+ <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"برای انتخاب میان‌بر، دو ضربه سریع بزنید و نگه‌دارید یا از کنش‌های سفارشی استفاده کنید."</string>
+ <string name="out_of_space" msgid="4691004494942118364">"فضای بیشتری در این صفحه اصلی موجود نیست."</string>
<string name="hotseat_out_of_space" msgid="7448809638125333693">"فضای بیشتری در سینی موارد دلخواه وجود ندارد"</string>
<string name="all_apps_button_label" msgid="8130441508702294465">"فهرست برنامه‌ها"</string>
- <string name="all_apps_search_results" msgid="5889367432531296759">"نتایج جستجو"</string>
<string name="all_apps_button_personal_label" msgid="1315764287305224468">"فهرست برنامه‌های شخصی"</string>
<string name="all_apps_button_work_label" msgid="7270707118948892488">"فهرست برنامه‌های کاری"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"صفحه اصلی"</string>
<string name="remove_drop_target_label" msgid="7812859488053230776">"برداشتن"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"حذف نصب"</string>
<string name="app_info_drop_target_label" msgid="692894985365717661">"اطلاعات برنامه"</string>
<string name="install_drop_target_label" msgid="2539096853673231757">"نصب"</string>
- <string name="dismiss_prediction_label" msgid="3357562989568808658">"برنامه پیشنهاد داده نشود"</string>
- <string name="pin_prediction" msgid="4196423321649756498">"سنجاق کردن پیشنهاد"</string>
<string name="permlab_install_shortcut" msgid="5632423390354674437">"نصب میان‌برها"</string>
<string name="permdesc_install_shortcut" msgid="923466509822011139">"به برنامه اجازه می‌دهد میان‌برها را بدون دخالت کاربر اضافه کند."</string>
<string name="permlab_read_settings" msgid="1941457408239617576">"خواندن تنظیمات و میان‌برهای صفحه اصلی"</string>
@@ -84,13 +60,15 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"نوشتن تنظیمات و میان‌برهای صفحه اصلی"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"به برنامه اجازه می‌دهد تنظیمات و میان‌برها را در صفحه اصلی تغییر دهد."</string>
<string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> مجاز نیست تماس تلفنی برقرار کند"</string>
- <string name="gadget_error_text" msgid="740356548025791839">"ابزارک را نمی‌توان بار کرد"</string>
- <string name="gadget_setup_text" msgid="8348374825537681407">"تنظیمات ابزارک"</string>
- <string name="gadget_complete_setup_text" msgid="309040266978007925">"برای تکمیل راه‌اندازی ضربه بزنید"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"مشکل در بارگیری ابزارک"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"تنظیم"</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"این برنامه سیستمی است و حذف نصب نمی‌شود."</string>
- <string name="folder_hint_text" msgid="5174843001373488816">"ویرایش نام"</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"پوشه بی‌نام"</string>
<string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> غیرفعال شد"</string>
- <string name="dotted_app_label" msgid="1704091277755818896">"{count,plural,offset:1 =1{{app_name} ‏# اعلان دارد}one{{app_name} ‏# اعلان دارد}other{{app_name} ‏# اعلان دارد}}"</string>
+ <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+ <item quantity="one"><xliff:g id="APP_NAME_2">%1$s</xliff:g>، <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> اعلان دارد</item>
+ <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>، <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> اعلان دارد</item>
+ </plurals>
<string name="default_scroll_format" msgid="7475544710230993317">"‏صفحه %1$d از %2$d"</string>
<string name="workspace_scroll_format" msgid="8458889198184077399">"‏صفحه اصلی %1$d از %2$d"</string>
<string name="workspace_new_page" msgid="257366611030256142">"صفحه اصلی جدید"</string>
@@ -99,13 +77,13 @@
<string name="folder_tap_to_rename" msgid="4017685068016979677">"برای ذخیره تغییر نام، ضربه بزنید"</string>
<string name="folder_closed" msgid="4100806530910930934">"پوشه بسته شد"</string>
<string name="folder_renamed" msgid="1794088362165669656">"نام پوشه به <xliff:g id="NAME">%1$s</xliff:g> تغییر کرد"</string>
- <string name="folder_name_format_exact" msgid="8626242716117004803">"پوشه: <xliff:g id="NAME">%1$s</xliff:g>، <xliff:g id="SIZE">%2$d</xliff:g> مورد"</string>
- <string name="folder_name_format_overflow" msgid="4270108890534995199">"پوشه: <xliff:g id="NAME">%1$s</xliff:g>، <xliff:g id="SIZE">%2$d</xliff:g> مورد یا بیشتر"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"پوشه: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"ابزارک‌ها"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"کاغذدیواری‌ها"</string>
- <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"کاغذدیواری و سبک"</string>
+ <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"سبک و کاغذدیواری"</string>
<string name="settings_button_text" msgid="8873672322605444408">"تنظیمات صفحه اصلی"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"توسط سرپرست سیستم غیرفعال شده است"</string>
- <string name="allow_rotation_title" msgid="7728578836261442095">"قابل‌چرخش بودن صفحه اصلی"</string>
+ <string name="allow_rotation_title" msgid="7728578836261442095">"امکان دادن به چرخش صفحه اصلی"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"وقتی تلفن چرخانده می‌شود"</string>
<string name="notification_dots_title" msgid="9062440428204120317">"نقطه‌های اعلان"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"روشن"</string>
@@ -114,16 +92,16 @@
<string name="msg_missing_notification_access" msgid="281113995110910548">"برای نمایش «نقطه‌های اعلان»، اعلان‌های برنامه را برای <xliff:g id="NAME">%1$s</xliff:g> روشن کنید"</string>
<string name="title_change_settings" msgid="1376365968844349552">"تغییر تنظیمات"</string>
<string name="notification_dots_service_title" msgid="4284221181793592871">"نمایش نقطه‌های اعلان"</string>
- <string name="auto_add_shortcuts_label" msgid="3698776050751790653">"افزودن نماد برنامه‌ها به صفحه اصلی"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"افزودن نماد به صفحه اصلی"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"برای برنامه‌های جدید"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"نامشخص"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"حذف"</string>
<string name="abandoned_search" msgid="891119232568284442">"جستجو"</string>
<string name="abandoned_promises_title" msgid="7096178467971716750">"این برنامه نصب نشده است."</string>
<string name="abandoned_promise_explanation" msgid="3990027586878167529">"برنامه برای این نماد نصب نشده است. می‌توانید آن را حذف کنید یا سعی کنید برنامه را جستجو کنید و آن را به صورت دستی نصب کنید."</string>
- <string name="app_installing_title" msgid="5864044122733792085">"<xliff:g id="NAME">%1$s</xliff:g> درحال نصب است، <xliff:g id="PROGRESS">%2$s</xliff:g> تکمیل شده است"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"درحال بارگیری <xliff:g id="NAME">%1$s</xliff:g>، <xliff:g id="PROGRESS">%2$s</xliff:g> کامل شد"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> درانتظار نصب"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"ابزارک‌های <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="widgets_list" msgid="796804551140113767">"فهرست ابزارک‌ها"</string>
<string name="widgets_list_closed" msgid="6141506579418771922">"فهرست ابزارک‌ها بسته شد"</string>
<string name="action_add_to_workspace" msgid="8902165848117513641">"افزودن به صفحه اصلی"</string>
@@ -151,20 +129,15 @@
<string name="action_deep_shortcut" msgid="2864038805849372848">"میان‌برها"</string>
<string name="shortcuts_menu_with_notifications_description" msgid="2676582286544232849">"میان‌برها و اعلان‌ها"</string>
<string name="action_dismiss_notification" msgid="5909461085055959187">"رد کردن"</string>
- <string name="accessibility_close" msgid="2277148124685870734">"بستن"</string>
<string name="notification_dismissed" msgid="6002233469409822874">"اعلان رد شد"</string>
<string name="all_apps_personal_tab" msgid="4190252696685155002">"شخصی"</string>
- <string name="all_apps_work_tab" msgid="4884822796154055118">"کاری"</string>
+ <string name="all_apps_work_tab" msgid="4884822796154055118">"محل کار"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"نمایه کاری"</string>
- <string name="work_profile_edu_work_apps" msgid="7895468576497746520">"برنامه‌های کاری دارای نشان هستند و سرپرست سیستم می‌تواند آن‌ها را ببیند"</string>
- <string name="work_profile_edu_accept" msgid="6069788082535149071">"متوجه‌ام"</string>
- <string name="work_apps_paused_title" msgid="3040901117349444598">"برنامه‌های کاری موقتاً متوقف شده‌اند."</string>
- <string name="work_apps_paused_body" msgid="261634750995824906">"برنامه‌های کاری نمی‌توانند برای شما اعلان ارسال کنند، از باتری استفاده کنند، یا به مکانتان دسترسی داشته باشند"</string>
- <string name="work_apps_paused_content_description" msgid="5149623040804051095">"برنامه‌های کاری خاموش است. برنامه‌های کاری نمی‌توانند برای شما اعلان ارسال کنند، از باتری استفاده کنند، یا به مکانتان دسترسی داشته باشند"</string>
- <string name="work_apps_paused_edu_banner" msgid="8872412121608402058">"برنامه‌های کاری دارای نشان هستند و سرپرست سیستم می‌تواند آن‌ها را ببیند."</string>
- <string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"متوجه‌ام"</string>
- <string name="work_apps_pause_btn_text" msgid="1921059713673767460">"خاموش کردن برنامه‌های کاری"</string>
- <string name="work_apps_enable_btn_text" msgid="1156432622148413741">"روشن کردن برنامه‌های کاری"</string>
- <string name="developer_options_filter_hint" msgid="5896817443635989056">"فیلتر"</string>
+ <string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"اینجا برنامه‌های کاری را پیدا کنید"</string>
+ <string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"همه برنامه‌های کاری نشانی دارند و توسط سازمانتان ایمن نگه داشته می‌شوند. برنامه‌های کاری را برای دسترسی آسان‌تر به صفحه اصلی انتقال دهید."</string>
+ <string name="work_mode_on_label" msgid="4781128097185272916">"توسط سازمانتان مدیریت می‌شود"</string>
+ <string name="work_mode_off_label" msgid="3194894777601421047">"اعلان‌ها و برنامه‌ها خاموش هستند"</string>
+ <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"بستن"</string>
+ <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"بسته‌شده"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"ناموفق بود: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
</resources>
diff --git a/res/values-fi/strings.xml b/res/values-fi/strings.xml
index 874c85d265..f87441ff3d 100644
--- a/res/values-fi/strings.xml
+++ b/res/values-fi/strings.xml
@@ -20,63 +20,39 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="649227358658669779">"Launcher3"</string>
+ <string name="folder_name" msgid="7371454440695724752"></string>
<string name="work_folder_name" msgid="3753320833950115786">"Työ"</string>
<string name="activity_not_found" msgid="8071924732094499514">"Sovellusta ei ole asennettu."</string>
<string name="activity_not_available" msgid="7456344436509528827">"Sovellus ei ole käytettävissä"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"Ladattu sovellus poistettiin käytöstä suojatussa tilassa"</string>
<string name="safemode_widget_error" msgid="4863470563535682004">"Widgetit poistettu käytöstä vikasietotilassa"</string>
<string name="shortcut_not_available" msgid="2536503539825726397">"Pikakuvake ei ole käytettävissä."</string>
- <string name="home_screen" msgid="5629429142036709174">"Etusivu"</string>
- <string name="recent_task_option_split_screen" msgid="6690461455618725183">"Jaettu näyttö"</string>
- <string name="split_screen_position_top" msgid="1504965011158689649">"Ylhäällä"</string>
- <string name="split_screen_position_left" msgid="7537793098851830883">"Vasemmalla"</string>
- <string name="split_screen_position_right" msgid="1569377524925193369">"Oikealla"</string>
- <string name="split_app_info_accessibility" msgid="5475288491241414932">"Sovellustiedot: %1$s"</string>
- <string name="long_press_widget_to_add" msgid="3587712543577675817">"Kosketa pitkään, niin voit siirtää widgetiä."</string>
- <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Kaksoisnapauta ja paina pitkään, niin voit siirtää widgetiä tai käyttää muokattuja toimintoja."</string>
+ <string name="home_screen" msgid="806512411299847073">"Aloitusnäyttö"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"Muokatut toiminnot"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"Valitse widget painamalla sitä pitkään."</string>
+ <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Valitse widget tai käytä muokattuja toimintoja kaksoisnapauttamalla ja painamalla kohdetta pitkään."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"Leveys: %1$d, korkeus: %2$d"</string>
- <string name="widget_preview_context_description" msgid="9045841361655787574">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g> widget"</string>
- <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Voit siirtää widgetiä aloitusnäytöllä koskettamalla sitä pitkään"</string>
- <string name="add_to_home_screen" msgid="8631549138215492708">"Lisää aloitusnäytölle"</string>
- <string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"Widget lisätty aloitusnäytölle: <xliff:g id="WIDGET_NAME">%1$s</xliff:g>"</string>
- <string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# widget}other{# widgetiä}}"</string>
- <string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{# pikakuvake}other{# pikakuvaketta}}"</string>
- <string name="widgets_and_shortcuts_count" msgid="7209136747878365116">"<xliff:g id="WIDGETS_COUNT">%1$s</xliff:g>, <xliff:g id="SHORTCUTS_COUNT">%2$s</xliff:g>"</string>
- <string name="widget_button_text" msgid="2880537293434387943">"Widgetit"</string>
- <string name="widgets_full_sheet_search_bar_hint" msgid="8484659090860596457">"Haku"</string>
- <string name="widgets_full_sheet_cancel_button_description" msgid="5766167035728653605">"Tyhjennä teksti hakukentästä"</string>
- <string name="no_widgets_available" msgid="4337693382501046170">"Widgetit ja pikanäppäimet eivät ole saatavilla"</string>
- <string name="no_search_results" msgid="3787956167293097509">"Widgetejä tai pikakuvakkeita ei löytynyt"</string>
- <string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Henkilökohtaiset"</string>
- <string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Työ"</string>
- <string name="widget_category_conversations" msgid="8894438636213590446">"Keskustelut"</string>
- <string name="widget_education_header" msgid="4874760613775913787">"Hyödyllisiä tietoja käden ulottuvilla"</string>
- <string name="widget_education_content" msgid="745542879510751525">"Jos haluat nähdä tietoja avaamatta sovelluksia, voit lisätä aloitusnäytölle widgetejä"</string>
- <string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Napauta, niin voit muuttaa widgetin asetuksia"</string>
- <string name="widget_education_close_button" msgid="8676165703104836580">"OK"</string>
- <string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Muuta widgetin asetuksia"</string>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Sijoita manuaalisesti koskettamalla pitkään"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"Lisää automaattisesti"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Hae sovelluksia"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Ladataan sovelluksia…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"<xliff:g id="QUERY">%1$s</xliff:g> ei palauttanut sovelluksia."</string>
<string name="all_apps_search_market_message" msgid="1366263386197059176">"Hae lisää sovelluksia"</string>
<string name="label_application" msgid="8531721983832654978">"Sovellus"</string>
- <string name="all_apps_label" msgid="5015784846527570951">"Kaikki sovellukset"</string>
<string name="notifications_header" msgid="1404149926117359025">"Ilmoitukset"</string>
- <string name="long_press_shortcut_to_add" msgid="5405328730817637737">"Kosketa pitkään, niin voit siirtää pikakuvaketta."</string>
- <string name="long_accessible_way_to_add_shortcut" msgid="2199537273817090740">"Kaksoisnapauta ja paina pitkään, niin voit siirtää pikakuvaketta tai käyttää muokattuja toimintoja."</string>
- <string name="out_of_space" msgid="6692471482459245734">"Tällä aloitusnäytöllä ei ole tilaa"</string>
+ <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"Valitse pikakuvake painamalla sitä pitkään."</string>
+ <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"Valitse pikakuvake tai käytä muokattuja toimintoja kaksoisnapauttamalla ja painamalla pitkään."</string>
+ <string name="out_of_space" msgid="4691004494942118364">"Tässä aloitusruudussa ei ole enää tilaa."</string>
<string name="hotseat_out_of_space" msgid="7448809638125333693">"Suosikit-valikossa ei ole enää tilaa"</string>
<string name="all_apps_button_label" msgid="8130441508702294465">"Sovellusluettelo"</string>
- <string name="all_apps_search_results" msgid="5889367432531296759">"Hakutulokset"</string>
<string name="all_apps_button_personal_label" msgid="1315764287305224468">"Omat sovellukset ‑luettelo"</string>
<string name="all_apps_button_work_label" msgid="7270707118948892488">"Työsovellusluettelo"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"Aloitusruutu"</string>
<string name="remove_drop_target_label" msgid="7812859488053230776">"Poista"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"Poista asennus"</string>
<string name="app_info_drop_target_label" msgid="692894985365717661">"Sovelluksen tiedot"</string>
<string name="install_drop_target_label" msgid="2539096853673231757">"Asenna"</string>
- <string name="dismiss_prediction_label" msgid="3357562989568808658">"Älä ehdota sovellusta"</string>
- <string name="pin_prediction" msgid="4196423321649756498">"Kiinnitä sovellus"</string>
<string name="permlab_install_shortcut" msgid="5632423390354674437">"asenna pikakuvakkeita"</string>
<string name="permdesc_install_shortcut" msgid="923466509822011139">"Antaa sovelluksen lisätä pikakuvakkeita itsenäisesti ilman käyttäjän valintaa."</string>
<string name="permlab_read_settings" msgid="1941457408239617576">"lue aloitusruudun asetuksia ja pikakuvakkeita"</string>
@@ -84,13 +60,15 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"kirjoita aloitusruudun asetuksia ja pikakuvakkeita"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"Antaa sovelluksen muuttaa aloitusruudun asetuksia ja pikakuvakkeita."</string>
<string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> ei saa soittaa puheluita."</string>
- <string name="gadget_error_text" msgid="740356548025791839">"Widgetiä ei voi ladata"</string>
- <string name="gadget_setup_text" msgid="8348374825537681407">"Widgetin asetukset"</string>
- <string name="gadget_complete_setup_text" msgid="309040266978007925">"Viimeistele asennus napauttamalla"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"Ongelma ladattaessa widgetiä"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"Asetus"</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"Tämä on järjestelmäsovellus, eikä sitä voi poistaa."</string>
- <string name="folder_hint_text" msgid="5174843001373488816">"Muokkaa nimeä"</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"Nimetön kansio"</string>
<string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> poistettiin käytöstä"</string>
- <string name="dotted_app_label" msgid="1704091277755818896">"{count,plural,offset:1 =1{{app_name}: # ilmoitus}other{{app_name}: # ilmoitusta}}"</string>
+ <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+ <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>: <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> ilmoitusta</item>
+ <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g>: <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> ilmoitus</item>
+ </plurals>
<string name="default_scroll_format" msgid="7475544710230993317">"Sivu %1$d / %2$d"</string>
<string name="workspace_scroll_format" msgid="8458889198184077399">"Aloitusruutu %1$d/%2$d"</string>
<string name="workspace_new_page" msgid="257366611030256142">"Uusi aloitusnäytön sivu"</string>
@@ -99,37 +77,37 @@
<string name="folder_tap_to_rename" msgid="4017685068016979677">"Tallenna uusi nimi koskettamalla."</string>
<string name="folder_closed" msgid="4100806530910930934">"Kansio on suljettu"</string>
<string name="folder_renamed" msgid="1794088362165669656">"Kansion nimeksi vaihdettiin <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="folder_name_format_exact" msgid="8626242716117004803">"Kansio: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> kohdetta"</string>
- <string name="folder_name_format_overflow" msgid="4270108890534995199">"Kansio: <xliff:g id="NAME">%1$s</xliff:g>, ainakin <xliff:g id="SIZE">%2$d</xliff:g> kohdetta"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"Kansio: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"Widgetit"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Taustakuvat"</string>
- <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Taustakuva ja tyyli"</string>
- <string name="settings_button_text" msgid="8873672322605444408">"Aloitusnäyttö"</string>
+ <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Tyylit ja taustakuvat"</string>
+ <string name="settings_button_text" msgid="8873672322605444408">"Kotiasetukset"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Järjestelmänvalvoja on poistanut toiminnon käytöstä."</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Salli aloitusnäytön kiertäminen"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Kun puhelinta kierretään"</string>
<string name="notification_dots_title" msgid="9062440428204120317">"Pistemerkit"</string>
- <string name="notification_dots_desc_on" msgid="1679848116452218908">"Päällä"</string>
- <string name="notification_dots_desc_off" msgid="1760796511504341095">"Ei päällä"</string>
+ <string name="notification_dots_desc_on" msgid="1679848116452218908">"Käytössä"</string>
+ <string name="notification_dots_desc_off" msgid="1760796511504341095">"Ei käytössä"</string>
<string name="title_missing_notification_access" msgid="7503287056163941064">"Ilmoituksien käyttöoikeus tarvitaan"</string>
<string name="msg_missing_notification_access" msgid="281113995110910548">"<xliff:g id="NAME">%1$s</xliff:g> tarvitsee ilmoitusten käyttöoikeuden, jotta pistemerkkejä voidaan näyttää."</string>
<string name="title_change_settings" msgid="1376365968844349552">"Muuta asetuksia"</string>
<string name="notification_dots_service_title" msgid="4284221181793592871">"Näytä ilmoituksista kertovat pistemerkit"</string>
- <string name="auto_add_shortcuts_label" msgid="3698776050751790653">"Lisää sovelluskuvakkeet aloitusnäytölle"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Lisää kuvake aloitusruutuun"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Uusille sovelluksille"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"Tuntematon"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"Poista"</string>
<string name="abandoned_search" msgid="891119232568284442">"Haku"</string>
<string name="abandoned_promises_title" msgid="7096178467971716750">"Sovellusta ei ole asennettu"</string>
<string name="abandoned_promise_explanation" msgid="3990027586878167529">"Kuvakkeen sovellusta ei ole asennettu. Voit poistaa kuvakkeen tai etsiä sovelluksen ja asentaa sen manuaalisesti."</string>
- <string name="app_installing_title" msgid="5864044122733792085">"<xliff:g id="NAME">%1$s</xliff:g> asennetaan, <xliff:g id="PROGRESS">%2$s</xliff:g> valmis"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> latautuu, valmiina <xliff:g id="PROGRESS">%2$s</xliff:g>"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> odottaa asennusta"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"Widgetit: <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="widgets_list" msgid="796804551140113767">"Widget-luettelo"</string>
<string name="widgets_list_closed" msgid="6141506579418771922">"Widget-luettelo suljettu"</string>
<string name="action_add_to_workspace" msgid="8902165848117513641">"Lisää aloitusnäytölle"</string>
<string name="action_move_here" msgid="2170188780612570250">"Siirrä kohde tänne"</string>
<string name="item_added_to_workspace" msgid="4211073925752213539">"Kohde lisättiin aloitusnäytölle."</string>
- <string name="item_removed" msgid="851119963877842327">"Kohde poistettiin"</string>
+ <string name="item_removed" msgid="851119963877842327">"Kohde poistettiin."</string>
<string name="undo" msgid="4151576204245173321">"Kumoa"</string>
<string name="action_move" msgid="4339390619886385032">"Siirrä kohde"</string>
<string name="move_to_empty_cell" msgid="2833711483015685619">"Siirrä rivin <xliff:g id="NUMBER_0">%1$s</xliff:g> sarakkeeseen <xliff:g id="NUMBER_1">%2$s</xliff:g>."</string>
@@ -151,20 +129,15 @@
<string name="action_deep_shortcut" msgid="2864038805849372848">"Pikakuvakkeet"</string>
<string name="shortcuts_menu_with_notifications_description" msgid="2676582286544232849">"Pikakuvakkeet ja ilmoitukset"</string>
<string name="action_dismiss_notification" msgid="5909461085055959187">"Hylkää"</string>
- <string name="accessibility_close" msgid="2277148124685870734">"Sulje"</string>
<string name="notification_dismissed" msgid="6002233469409822874">"Ilmoitus hylätty"</string>
<string name="all_apps_personal_tab" msgid="4190252696685155002">"Henkilökohtaiset"</string>
<string name="all_apps_work_tab" msgid="4884822796154055118">"Työsovellukset"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"Työprofiili"</string>
- <string name="work_profile_edu_work_apps" msgid="7895468576497746520">"Työsovellukset on merkitty sellaisiksi ja näkyvät IT-järjestelmänvalvojille"</string>
- <string name="work_profile_edu_accept" msgid="6069788082535149071">"Selvä"</string>
- <string name="work_apps_paused_title" msgid="3040901117349444598">"Työsovellukset on keskeytetty"</string>
- <string name="work_apps_paused_body" msgid="261634750995824906">"Työsovellukset eivät voi lähettää sinulle ilmoituksia eivätkä käyttää akkuasi tai paikantaa sijaintiasi"</string>
- <string name="work_apps_paused_content_description" msgid="5149623040804051095">"Työsovellukset ovat pois päältä. Ne eivät voi lähettää sinulle ilmoituksia eivätkä käyttää akkuasi tai sijaintiasi"</string>
- <string name="work_apps_paused_edu_banner" msgid="8872412121608402058">"Työsovellukset on merkitty sellaisiksi ja näkyvät IT-järjestelmänvalvojille"</string>
- <string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"OK"</string>
- <string name="work_apps_pause_btn_text" msgid="1921059713673767460">"Laita työsovellukset pois päältä"</string>
- <string name="work_apps_enable_btn_text" msgid="1156432622148413741">"Laita työsovellukset päälle"</string>
- <string name="developer_options_filter_hint" msgid="5896817443635989056">"Suodatin"</string>
+ <string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"Etsi työsovelluksia tästä"</string>
+ <string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"Kaikki työsovellukset on merkitty, ja organisaatiosi vastaa niiden suojaamisesta. Voit siirtää työsovelluksia aloitusnäytölle käytön helpottamiseksi."</string>
+ <string name="work_mode_on_label" msgid="4781128097185272916">"Organisaatiosi hallinnoima"</string>
+ <string name="work_mode_off_label" msgid="3194894777601421047">"Ilmoitukset ja sovellukset ovat poissa käytöstä"</string>
+ <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Sulje"</string>
+ <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Suljettu"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Epäonnistui: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
</resources>
diff --git a/res/values-fr-rCA/strings.xml b/res/values-fr-rCA/strings.xml
index 9a77c87e32..5ac514d448 100644
--- a/res/values-fr-rCA/strings.xml
+++ b/res/values-fr-rCA/strings.xml
@@ -20,63 +20,39 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="649227358658669779">"Lanceur3"</string>
+ <string name="folder_name" msgid="7371454440695724752"></string>
<string name="work_folder_name" msgid="3753320833950115786">"Travail"</string>
<string name="activity_not_found" msgid="8071924732094499514">"L\'application n\'est pas installée."</string>
<string name="activity_not_available" msgid="7456344436509528827">"Application indisponible"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"L\'application téléchargée est désactivée en mode sans échec."</string>
<string name="safemode_widget_error" msgid="4863470563535682004">"Widgets désactivés en mode sans échec"</string>
<string name="shortcut_not_available" msgid="2536503539825726397">"Le raccourci n\'est pas disponible"</string>
- <string name="home_screen" msgid="5629429142036709174">"Accueil"</string>
- <string name="recent_task_option_split_screen" msgid="6690461455618725183">"Écran partagé"</string>
- <string name="split_screen_position_top" msgid="1504965011158689649">"Diviser dans la partie supérieure"</string>
- <string name="split_screen_position_left" msgid="7537793098851830883">"Diviser à gauche"</string>
- <string name="split_screen_position_right" msgid="1569377524925193369">"Diviser à droite"</string>
- <string name="split_app_info_accessibility" msgid="5475288491241414932">"Renseignements sur l\'appli pour %1$s"</string>
- <string name="long_press_widget_to_add" msgid="3587712543577675817">"Maintenez le doigt sur un widget pour le déplacer."</string>
- <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Touchez 2x un widget et maintenez le doigt dessus pour le déplacer ou utiliser des actions personnalisées."</string>
+ <string name="home_screen" msgid="806512411299847073">"Écran d\'accueil"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"Actions personnalisées"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"Maintenez un doigt sur le widget pour l\'ajouter."</string>
+ <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Touchez 2x un widget et maintenez doigt dessus pour l’ajouter ou utiliser des actions personnalisées"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d de largeur sur %2$d de hauteur"</string>
- <string name="widget_preview_context_description" msgid="9045841361655787574">"Widget <xliff:g id="WIDGET_NAME">%1$s</xliff:g>"</string>
- <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Maintenez le doigt sur le widget pour le déplacer sur l\'écran d\'accueil"</string>
- <string name="add_to_home_screen" msgid="8631549138215492708">"Ajouter à l\'écran d\'accueil"</string>
- <string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"Le widget <xliff:g id="WIDGET_NAME">%1$s</xliff:g> a été ajouté à l\'écran d\'accueil"</string>
- <string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# widget}one{# widget}other{# widgets}}"</string>
- <string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{# raccourci}one{# raccourci}other{# raccourcis}}"</string>
- <string name="widgets_and_shortcuts_count" msgid="7209136747878365116">"<xliff:g id="WIDGETS_COUNT">%1$s</xliff:g>, <xliff:g id="SHORTCUTS_COUNT">%2$s</xliff:g>"</string>
- <string name="widget_button_text" msgid="2880537293434387943">"Widgets"</string>
- <string name="widgets_full_sheet_search_bar_hint" msgid="8484659090860596457">"Rechercher"</string>
- <string name="widgets_full_sheet_cancel_button_description" msgid="5766167035728653605">"Effacer le texte dans le champ de recherche"</string>
- <string name="no_widgets_available" msgid="4337693382501046170">"Aucun widget ou raccourci proposé"</string>
- <string name="no_search_results" msgid="3787956167293097509">"Aucun widget ni raccourci trouvé"</string>
- <string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Personnels"</string>
- <string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Professionnels"</string>
- <string name="widget_category_conversations" msgid="8894438636213590446">"Conversations"</string>
- <string name="widget_education_header" msgid="4874760613775913787">"Renseignements utiles à portée de main"</string>
- <string name="widget_education_content" msgid="745542879510751525">"Pour obtenir des renseignements sans ouvrir d\'application, vous pouvez ajouter des widgets à votre écran d\'accueil"</string>
- <string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Touchez pour modifier les paramètres du widget"</string>
- <string name="widget_education_close_button" msgid="8676165703104836580">"OK"</string>
- <string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Modifier les paramètres du widget"</string>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Maintenez le doigt sur l\'élément pour le placer manuellement"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"Ajouter automatiquement"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Rechercher dans les applications"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Chargement des applications en cours…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"Aucune application trouvée correspondant à « <xliff:g id="QUERY">%1$s</xliff:g> »"</string>
<string name="all_apps_search_market_message" msgid="1366263386197059176">"Rechercher plus d\'applications"</string>
<string name="label_application" msgid="8531721983832654978">"Application"</string>
- <string name="all_apps_label" msgid="5015784846527570951">"Toutes les applications"</string>
<string name="notifications_header" msgid="1404149926117359025">"Notifications"</string>
- <string name="long_press_shortcut_to_add" msgid="5405328730817637737">"Maintenez le doigt sur un raccourci pour le déplacer."</string>
- <string name="long_accessible_way_to_add_shortcut" msgid="2199537273817090740">"Touchez deux fois un raccourci et maintenez le doigt dessus pour le déplacer ou utiliser des actions personnalisées."</string>
- <string name="out_of_space" msgid="6692471482459245734">"Pas d\'espace libre sur cet écran d\'accueil"</string>
+ <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"Maintenez un doigt sur le raccourci pour l\'ajouter"</string>
+ <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"Touchez 2x un raccourci et maintenez doigt dessus pour l’aj. ou utiliser des actions personnalisées."</string>
+ <string name="out_of_space" msgid="4691004494942118364">"Pas d\'espace libre sur l\'écran d\'accueil."</string>
<string name="hotseat_out_of_space" msgid="7448809638125333693">"Il n\'y a plus d\'espace dans la zone des favoris"</string>
<string name="all_apps_button_label" msgid="8130441508702294465">"Liste des applications"</string>
- <string name="all_apps_search_results" msgid="5889367432531296759">"Résultats de recherche"</string>
<string name="all_apps_button_personal_label" msgid="1315764287305224468">"Liste des applications personnelles"</string>
<string name="all_apps_button_work_label" msgid="7270707118948892488">"Liste des applications professionnelles"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"Accueil"</string>
<string name="remove_drop_target_label" msgid="7812859488053230776">"Supprimer"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"Désinstaller"</string>
- <string name="app_info_drop_target_label" msgid="692894985365717661">"Détails de l\'appli"</string>
+ <string name="app_info_drop_target_label" msgid="692894985365717661">"Détails de l\'application"</string>
<string name="install_drop_target_label" msgid="2539096853673231757">"Installer"</string>
- <string name="dismiss_prediction_label" msgid="3357562989568808658">"Ne pas suggérer d\'application"</string>
- <string name="pin_prediction" msgid="4196423321649756498">"Épingler la prédiction"</string>
<string name="permlab_install_shortcut" msgid="5632423390354674437">"installer des raccourcis"</string>
<string name="permdesc_install_shortcut" msgid="923466509822011139">"Permet à une application d\'ajouter des raccourcis sans l\'intervention de l\'utilisateur."</string>
<string name="permlab_read_settings" msgid="1941457408239617576">"lire les paramètres et les raccourcis de la page d\'accueil"</string>
@@ -84,13 +60,15 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"enregistrer les paramètres de la page d\'accueil et des raccourcis"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"Permet à l\'application de modifier les paramètres et les raccourcis de l\'écran d\'accueil."</string>
<string name="msg_no_phone_permission" msgid="9208659281529857371">"L\'application <xliff:g id="APP_NAME">%1$s</xliff:g> n\'est pas autorisée à faire des appels téléphoniques"</string>
- <string name="gadget_error_text" msgid="740356548025791839">"Impossible de charger le widget"</string>
- <string name="gadget_setup_text" msgid="8348374825537681407">"Paramètres du widget"</string>
- <string name="gadget_complete_setup_text" msgid="309040266978007925">"Touchez pour terminer la configuration"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"Problème lors du chargement du widget"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"Configuration"</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"Impossible de désinstaller cette application, car il s\'agit d\'une application système."</string>
- <string name="folder_hint_text" msgid="5174843001373488816">"Modifier le nom"</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"Dossier sans nom"</string>
<string name="disabled_app_label" msgid="6673129024321402780">"L\'application <xliff:g id="APP_NAME">%1$s</xliff:g> est désactivée"</string>
- <string name="dotted_app_label" msgid="1704091277755818896">"{count,plural,offset:1 =1{{app_name} a # notification}one{{app_name} a # notification}other{{app_name} a # notifications}}"</string>
+ <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+ <item quantity="one"><xliff:g id="APP_NAME_2">%1$s</xliff:g> a <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> notification</item>
+ <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g> a <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> notificatio​ns</item>
+ </plurals>
<string name="default_scroll_format" msgid="7475544710230993317">"Page %1$d sur %2$d"</string>
<string name="workspace_scroll_format" msgid="8458889198184077399">"Écran d\'accueil %1$d sur %2$d"</string>
<string name="workspace_new_page" msgid="257366611030256142">"Nouvelle page d\'écran d\'accueil"</string>
@@ -99,10 +77,10 @@
<string name="folder_tap_to_rename" msgid="4017685068016979677">"Touchez pour enregistrer le nouveau nom"</string>
<string name="folder_closed" msgid="4100806530910930934">"Dossier fermé"</string>
<string name="folder_renamed" msgid="1794088362165669656">"Nouveau nom du dossier : <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="folder_name_format_exact" msgid="8626242716117004803">"Dossier : <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> élément(s)"</string>
- <string name="folder_name_format_overflow" msgid="4270108890534995199">"Dossier : <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> éléments ou plus"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"Dossier : <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"Widgets"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Fonds d\'écran"</string>
- <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Fond d\'écran et style"</string>
+ <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Styles et fonds d\'écran"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Paramètres d\'accueil"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Cette fonction est désactivée par votre administrateur"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Autoriser la rotation de l\'écran d\'accueil"</string>
@@ -114,22 +92,22 @@
<string name="msg_missing_notification_access" msgid="281113995110910548">"Pour afficher les points de notification, activez les notifications d\'application pour <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="title_change_settings" msgid="1376365968844349552">"Modifier les paramètres"</string>
<string name="notification_dots_service_title" msgid="4284221181793592871">"Afficher les points de notification"</string>
- <string name="auto_add_shortcuts_label" msgid="3698776050751790653">"Ajouter icônes d\'applis à l\'écran d\'accueil"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Ajouter l\'icône à l\'écran d\'accueil"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Pour les nouvelles applications"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"Inconnu"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"Supprimer"</string>
<string name="abandoned_search" msgid="891119232568284442">"Rechercher"</string>
<string name="abandoned_promises_title" msgid="7096178467971716750">"Cette application n\'est pas installée"</string>
<string name="abandoned_promise_explanation" msgid="3990027586878167529">"L\'application liée à cette icône n\'est pas installée. Vous pouvez la supprimer ou rechercher l\'application et l\'installer manuellement."</string>
- <string name="app_installing_title" msgid="5864044122733792085">"Installation de l\'application <xliff:g id="NAME">%1$s</xliff:g> en cours, <xliff:g id="PROGRESS">%2$s</xliff:g> terminée"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"Téléchargement de <xliff:g id="NAME">%1$s</xliff:g> : <xliff:g id="PROGRESS">%2$s</xliff:g>"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> en attente d\'installation"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"Widgets pour <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="widgets_list" msgid="796804551140113767">"Liste des widgets"</string>
<string name="widgets_list_closed" msgid="6141506579418771922">"Liste des widgets fermée"</string>
<string name="action_add_to_workspace" msgid="8902165848117513641">"Ajouter à l\'écran d\'accueil"</string>
<string name="action_move_here" msgid="2170188780612570250">"Déplacer l\'élément ici"</string>
<string name="item_added_to_workspace" msgid="4211073925752213539">"Élément ajouté à l\'écran d\'accueil"</string>
- <string name="item_removed" msgid="851119963877842327">"Élément retiré"</string>
+ <string name="item_removed" msgid="851119963877842327">"Élément supprimé"</string>
<string name="undo" msgid="4151576204245173321">"Annuler"</string>
<string name="action_move" msgid="4339390619886385032">"Déplacer l\'élément"</string>
<string name="move_to_empty_cell" msgid="2833711483015685619">"Déplacer vers rangée <xliff:g id="NUMBER_0">%1$s</xliff:g> colonne <xliff:g id="NUMBER_1">%2$s</xliff:g>"</string>
@@ -151,20 +129,15 @@
<string name="action_deep_shortcut" msgid="2864038805849372848">"Raccourcis"</string>
<string name="shortcuts_menu_with_notifications_description" msgid="2676582286544232849">"Raccourcis et notifications"</string>
<string name="action_dismiss_notification" msgid="5909461085055959187">"Ignorer"</string>
- <string name="accessibility_close" msgid="2277148124685870734">"Fermer"</string>
<string name="notification_dismissed" msgid="6002233469409822874">"Notification ignorée"</string>
<string name="all_apps_personal_tab" msgid="4190252696685155002">"Personnel"</string>
<string name="all_apps_work_tab" msgid="4884822796154055118">"Travail"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"Profil professionnel"</string>
- <string name="work_profile_edu_work_apps" msgid="7895468576497746520">"Les applications professionnelles sont indiquées par un badge et elles sont visibles pour votre administrateur informatique"</string>
- <string name="work_profile_edu_accept" msgid="6069788082535149071">"OK"</string>
- <string name="work_apps_paused_title" msgid="3040901117349444598">"Les applications professionnelles sont interrompues"</string>
- <string name="work_apps_paused_body" msgid="261634750995824906">"Les applications professionnelles ne peuvent ni vous envoyer de notifications, ni utiliser la pile, ni accéder à votre position"</string>
- <string name="work_apps_paused_content_description" msgid="5149623040804051095">"Les applications professionnelles sont désactivées. Vos applications professionnelles ne peuvent ni vous envoyer de notifications, ni utiliser la pile, ni accéder à votre position"</string>
- <string name="work_apps_paused_edu_banner" msgid="8872412121608402058">"Les applications professionnelles sont indiquées par un badge et sont visibles pour votre administrateur informatique"</string>
- <string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"OK"</string>
- <string name="work_apps_pause_btn_text" msgid="1921059713673767460">"Désactiver les applications professionnelles"</string>
- <string name="work_apps_enable_btn_text" msgid="1156432622148413741">"Activer les applications professionnelles"</string>
- <string name="developer_options_filter_hint" msgid="5896817443635989056">"Filtrer"</string>
+ <string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"Trouvez ici des applications professionnelles"</string>
+ <string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"Chaque application professionnelle comporte un badge, ce qui signifie qu\'elle est sécurisée par votre organisation. Vous pouvez déplacer vos applications vers l\'écran d\'accueil afin d\'y accéder plus facilement."</string>
+ <string name="work_mode_on_label" msgid="4781128097185272916">"Géré par votre organisation"</string>
+ <string name="work_mode_off_label" msgid="3194894777601421047">"Les notifications et les applications sont désactivées"</string>
+ <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Fermer"</string>
+ <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Fermé"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Échec : <xliff:g id="WHAT">%1$s</xliff:g>"</string>
</resources>
diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml
index f071db9a32..65db47e8a7 100644
--- a/res/values-fr/strings.xml
+++ b/res/values-fr/strings.xml
@@ -20,63 +20,38 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="649227358658669779">"Launcher3"</string>
- <string name="work_folder_name" msgid="3753320833950115786">"Pro"</string>
+ <string name="work_folder_name" msgid="3753320833950115786">"Android Work"</string>
<string name="activity_not_found" msgid="8071924732094499514">"L\'application n\'est pas installée."</string>
<string name="activity_not_available" msgid="7456344436509528827">"Application indisponible"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"L\'application téléchargée est désactivée en mode sécurisé."</string>
<string name="safemode_widget_error" msgid="4863470563535682004">"Les widgets sont désactivés en mode sécurisé."</string>
<string name="shortcut_not_available" msgid="2536503539825726397">"Raccourci non disponible"</string>
- <string name="home_screen" msgid="5629429142036709174">"Accueil"</string>
- <string name="recent_task_option_split_screen" msgid="6690461455618725183">"Écran partagé"</string>
- <string name="split_screen_position_top" msgid="1504965011158689649">"Affichée en haut"</string>
- <string name="split_screen_position_left" msgid="7537793098851830883">"Affichée à gauche"</string>
- <string name="split_screen_position_right" msgid="1569377524925193369">"Affichée à droite"</string>
- <string name="split_app_info_accessibility" msgid="5475288491241414932">"Infos sur l\'appli pour %1$s"</string>
- <string name="long_press_widget_to_add" msgid="3587712543577675817">"Appuyez de manière prolongée sur un widget pour le déplacer."</string>
- <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Appuyez deux fois et maintenez la pression pour déplacer widget ou utiliser actions personnalisées."</string>
+ <string name="home_screen" msgid="806512411299847073">"Écran d\'accueil"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"Actions personnalisées"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"App. de manière prolongée pour sélectionner widget."</string>
+ <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Appuyez 2 fois et maintenez la pression pour sélectionner widget ou utilisez actions personnalisées."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d x %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d de largeur et %2$d de hauteur"</string>
- <string name="widget_preview_context_description" msgid="9045841361655787574">"Widget <xliff:g id="WIDGET_NAME">%1$s</xliff:g>"</string>
- <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Appuyez de manière prolongée sur le widget pour le déplacer sur l\'écran d\'accueil"</string>
- <string name="add_to_home_screen" msgid="8631549138215492708">"Ajouter à l\'écran d\'accueil"</string>
- <string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"Widget <xliff:g id="WIDGET_NAME">%1$s</xliff:g> ajouté à l\'écran d\'accueil"</string>
- <string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# widget}one{# widget}other{# widgets}}"</string>
- <string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{# raccourci}one{# raccourci}other{# raccourcis}}"</string>
- <string name="widgets_and_shortcuts_count" msgid="7209136747878365116">"<xliff:g id="WIDGETS_COUNT">%1$s</xliff:g>, <xliff:g id="SHORTCUTS_COUNT">%2$s</xliff:g>"</string>
- <string name="widget_button_text" msgid="2880537293434387943">"Widgets"</string>
- <string name="widgets_full_sheet_search_bar_hint" msgid="8484659090860596457">"Rechercher"</string>
- <string name="widgets_full_sheet_cancel_button_description" msgid="5766167035728653605">"Effacer le texte du champ de recherche"</string>
- <string name="no_widgets_available" msgid="4337693382501046170">"Les widgets et les raccourcis ne sont pas disponibles"</string>
- <string name="no_search_results" msgid="3787956167293097509">"Aucun widget ni raccourci trouvé"</string>
- <string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Personnels"</string>
- <string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Professionnels"</string>
- <string name="widget_category_conversations" msgid="8894438636213590446">"Conversations"</string>
- <string name="widget_education_header" msgid="4874760613775913787">"Infos utiles à portée de main"</string>
- <string name="widget_education_content" msgid="745542879510751525">"Pour obtenir des infos sans ouvrir d\'applis, vous pouvez ajouter des widgets à votre écran d\'accueil"</string>
- <string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Appuyez pour modifier les paramètres du widget"</string>
- <string name="widget_education_close_button" msgid="8676165703104836580">"OK"</string>
- <string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Modifier les paramètres du widget"</string>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Appuyez de manière prolongée pour placer l\'élément manuellement."</string>
+ <string name="place_automatically" msgid="8064208734425456485">"Ajouter automatiquement"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Rechercher dans les applications"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Chargement des applications…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"Aucune application ne correspond à la requête \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
<string name="all_apps_search_market_message" msgid="1366263386197059176">"Rechercher plus d\'applications"</string>
<string name="label_application" msgid="8531721983832654978">"Application"</string>
- <string name="all_apps_label" msgid="5015784846527570951">"Toutes les applis"</string>
<string name="notifications_header" msgid="1404149926117359025">"Notifications"</string>
- <string name="long_press_shortcut_to_add" msgid="5405328730817637737">"Appuyez de manière prolongée pour déplacer un raccourci."</string>
- <string name="long_accessible_way_to_add_shortcut" msgid="2199537273817090740">"Appuyez deux fois et maintenez la pression pour déplacer un raccourci ou utiliser les actions personnalisées."</string>
- <string name="out_of_space" msgid="6692471482459245734">"Espace insuffisant sur cet écran d\'accueil"</string>
+ <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"Appui prolongé pour sélectionner un raccourci."</string>
+ <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"Appuyez 2X et maintenez la pression pour choisir un raccourci ou utilisez les actions personnalisées"</string>
+ <string name="out_of_space" msgid="4691004494942118364">"Pas d\'espace libre sur cet écran d\'accueil."</string>
<string name="hotseat_out_of_space" msgid="7448809638125333693">"Plus d\'espace disponible dans la zone de favoris."</string>
<string name="all_apps_button_label" msgid="8130441508702294465">"Liste d\'applications"</string>
- <string name="all_apps_search_results" msgid="5889367432531296759">"Résultats de recherche"</string>
<string name="all_apps_button_personal_label" msgid="1315764287305224468">"Liste des applications personnelles"</string>
<string name="all_apps_button_work_label" msgid="7270707118948892488">"Liste des applications professionnelles"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"Accueil"</string>
<string name="remove_drop_target_label" msgid="7812859488053230776">"Supprimer"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"Désinstaller"</string>
<string name="app_info_drop_target_label" msgid="692894985365717661">"Infos sur l\'appli"</string>
<string name="install_drop_target_label" msgid="2539096853673231757">"Installer"</string>
- <string name="dismiss_prediction_label" msgid="3357562989568808658">"Ne pas suggérer d\'application"</string>
- <string name="pin_prediction" msgid="4196423321649756498">"Épingler la prédiction"</string>
<string name="permlab_install_shortcut" msgid="5632423390354674437">"installer des raccourcis"</string>
<string name="permdesc_install_shortcut" msgid="923466509822011139">"Permettre à une application d\'ajouter des raccourcis sans l\'intervention de l\'utilisateur"</string>
<string name="permlab_read_settings" msgid="1941457408239617576">"lire les paramètres et les raccourcis de l\'écran d\'accueil"</string>
@@ -84,13 +59,15 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"modifier les paramètres et les raccourcis de l\'écran d\'accueil"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"Permettre à l\'application de modifier les paramètres et les raccourcis de l\'écran d\'accueil"</string>
<string name="msg_no_phone_permission" msgid="9208659281529857371">"L\'application <xliff:g id="APP_NAME">%1$s</xliff:g> n\'est pas autorisée à passer des appels téléphoniques."</string>
- <string name="gadget_error_text" msgid="740356548025791839">"Impossible de charger le widget"</string>
- <string name="gadget_setup_text" msgid="8348374825537681407">"Paramètres du widget"</string>
- <string name="gadget_complete_setup_text" msgid="309040266978007925">"Appuyez pour terminer la configuration"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"Problème lors du chargement du widget."</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"Configuration"</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"Impossible de désinstaller cette application, car il s\'agit d\'une application système."</string>
- <string name="folder_hint_text" msgid="5174843001373488816">"Modifier le nom"</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"Dossier sans nom"</string>
<string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> est désactivé."</string>
- <string name="dotted_app_label" msgid="1704091277755818896">"{count,plural,offset:1 =1{{app_name} a # notification}one{{app_name} a # notification}other{{app_name} a # notifications}}"</string>
+ <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+ <item quantity="one"><xliff:g id="APP_NAME_2">%1$s</xliff:g> comporte <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> notification</item>
+ <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g> comporte <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> notifications</item>
+ </plurals>
<string name="default_scroll_format" msgid="7475544710230993317">"Page %1$d sur %2$d"</string>
<string name="workspace_scroll_format" msgid="8458889198184077399">"Écran d\'accueil %1$d sur %2$d"</string>
<string name="workspace_new_page" msgid="257366611030256142">"Nouvelle page d\'écran d\'accueil"</string>
@@ -99,11 +76,11 @@
<string name="folder_tap_to_rename" msgid="4017685068016979677">"Appuyez pour enregistrer le nouveau nom du dossier."</string>
<string name="folder_closed" msgid="4100806530910930934">"Dossier fermé"</string>
<string name="folder_renamed" msgid="1794088362165669656">"Nouveau nom du dossier : <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="folder_name_format_exact" msgid="8626242716117004803">"Dossier : <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> éléments"</string>
- <string name="folder_name_format_overflow" msgid="4270108890534995199">"Dossier : <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> éléments ou plus"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"Dossier \"<xliff:g id="NAME">%1$s</xliff:g>\""</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"Widgets"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Fonds d\'écran"</string>
- <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Fond d\'écran et style"</string>
- <string name="settings_button_text" msgid="8873672322605444408">"Paramètres de l\'accueil"</string>
+ <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Styles et fonds d\'écran"</string>
+ <string name="settings_button_text" msgid="8873672322605444408">"Paramètres d\'écran d\'accueil"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Désactivé par votre administrateur"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Autoriser la rotation de l\'écran d\'accueil"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Lorsque vous faites pivoter le téléphone"</string>
@@ -114,16 +91,16 @@
<string name="msg_missing_notification_access" msgid="281113995110910548">"Pour afficher les pastilles de notification, activez les notifications de l\'application <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="title_change_settings" msgid="1376365968844349552">"Modifier les paramètres"</string>
<string name="notification_dots_service_title" msgid="4284221181793592871">"Afficher les pastilles de notification"</string>
- <string name="auto_add_shortcuts_label" msgid="3698776050751790653">"Ajouter les icônes des applis à l\'écran d\'accueil"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Ajouter l\'icône à l\'écran d\'accueil"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Pour les nouvelles applications"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"Inconnu"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"Supprimer"</string>
<string name="abandoned_search" msgid="891119232568284442">"Rechercher"</string>
<string name="abandoned_promises_title" msgid="7096178467971716750">"Cette application n\'est pas installée"</string>
<string name="abandoned_promise_explanation" msgid="3990027586878167529">"L\'application correspondant à cette icône n\'est pas installée. Vous pouvez supprimer cette dernière, ou essayer de rechercher l\'application et de l\'installer manuellement."</string>
- <string name="app_installing_title" msgid="5864044122733792085">"Installation de <xliff:g id="NAME">%1$s</xliff:g>… (<xliff:g id="PROGRESS">%2$s</xliff:g> terminés)"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> en cours de téléchargement, <xliff:g id="PROGRESS">%2$s</xliff:g> effectué(s)"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> en attente d\'installation"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"Widgets <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="widgets_list" msgid="796804551140113767">"Liste des widgets"</string>
<string name="widgets_list_closed" msgid="6141506579418771922">"La liste des widgets est fermée"</string>
<string name="action_add_to_workspace" msgid="8902165848117513641">"Ajouter à l\'écran d\'accueil"</string>
@@ -151,20 +128,15 @@
<string name="action_deep_shortcut" msgid="2864038805849372848">"Raccourcis"</string>
<string name="shortcuts_menu_with_notifications_description" msgid="2676582286544232849">"Raccourcis et notifications"</string>
<string name="action_dismiss_notification" msgid="5909461085055959187">"Ignorer"</string>
- <string name="accessibility_close" msgid="2277148124685870734">"Fermer"</string>
<string name="notification_dismissed" msgid="6002233469409822874">"Notification ignorée"</string>
<string name="all_apps_personal_tab" msgid="4190252696685155002">"Personnelles"</string>
<string name="all_apps_work_tab" msgid="4884822796154055118">"Professionnelles"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"Profil professionnel"</string>
- <string name="work_profile_edu_work_apps" msgid="7895468576497746520">"Les applis professionnelles sont identifiées par un badge et votre administrateur informatique peut les voir"</string>
- <string name="work_profile_edu_accept" msgid="6069788082535149071">"OK"</string>
- <string name="work_apps_paused_title" msgid="3040901117349444598">"Applications professionnelles en veille"</string>
- <string name="work_apps_paused_body" msgid="261634750995824906">"Vos applis professionnelles ne peuvent pas vous envoyer de notifications, utiliser votre batterie ni accéder à votre position"</string>
- <string name="work_apps_paused_content_description" msgid="5149623040804051095">"Vos applis professionnelles sont désactivées. Elles ne peuvent pas vous envoyer de notifications, utiliser votre batterie ni accéder à votre position."</string>
- <string name="work_apps_paused_edu_banner" msgid="8872412121608402058">"Les applis professionnelles sont identifiées par un badge et votre administrateur informatique peut les voir"</string>
- <string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"OK"</string>
- <string name="work_apps_pause_btn_text" msgid="1921059713673767460">"Désactiver les applis professionnelles"</string>
- <string name="work_apps_enable_btn_text" msgid="1156432622148413741">"Activer les applications professionnelles"</string>
- <string name="developer_options_filter_hint" msgid="5896817443635989056">"Filtre"</string>
+ <string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"Retrouvez ici vos applications professionnelles"</string>
+ <string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"Les applications professionnelles sont accompagnées d\'un badge et sont sécurisées par votre organisation. Vous pouvez les déplacer vers votre écran d\'accueil pour y accéder plus facilement."</string>
+ <string name="work_mode_on_label" msgid="4781128097185272916">"Géré par votre organisation"</string>
+ <string name="work_mode_off_label" msgid="3194894777601421047">"Notifications et applications désactivées"</string>
+ <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Fermer"</string>
+ <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Fermé"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Échec : <xliff:g id="WHAT">%1$s</xliff:g>"</string>
</resources>
diff --git a/res/values-gl/strings.xml b/res/values-gl/strings.xml
index 3986aa4da6..ca5ba3c5e4 100644
--- a/res/values-gl/strings.xml
+++ b/res/values-gl/strings.xml
@@ -26,57 +26,32 @@
<string name="safemode_shortcut_error" msgid="9160126848219158407">"A aplicación que descargaches está desactivada no modo seguro"</string>
<string name="safemode_widget_error" msgid="4863470563535682004">"Os widgets están desactivados no modo seguro"</string>
<string name="shortcut_not_available" msgid="2536503539825726397">"O atallo non está dispoñible"</string>
- <string name="home_screen" msgid="5629429142036709174">"Inicio"</string>
- <string name="recent_task_option_split_screen" msgid="6690461455618725183">"Pantalla dividida"</string>
- <string name="split_screen_position_top" msgid="1504965011158689649">"Dividir (arriba)"</string>
- <string name="split_screen_position_left" msgid="7537793098851830883">"Dividir (esquerda)"</string>
- <string name="split_screen_position_right" msgid="1569377524925193369">"Dividir (dereita)"</string>
- <string name="split_app_info_accessibility" msgid="5475288491241414932">"Información da aplicación para %1$s"</string>
- <string name="long_press_widget_to_add" msgid="3587712543577675817">"Mantén premido un widget para movelo."</string>
- <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Toca dúas veces un widget e manteno premido para movelo ou utiliza accións personalizadas."</string>
+ <string name="home_screen" msgid="806512411299847073">"Pantalla de inicio"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"Accións personalizadas"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"Mantén premido un widget para seleccionalo."</string>
+ <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Toca dúas veces e mantén premido para seleccionar un widget ou utiliza accións personalizadas."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d de largo por %2$d de alto"</string>
- <string name="widget_preview_context_description" msgid="9045841361655787574">"Widget <xliff:g id="WIDGET_NAME">%1$s</xliff:g>"</string>
- <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Mantén premido o widget para movelo pola pantalla de inicio"</string>
- <string name="add_to_home_screen" msgid="8631549138215492708">"Engadir á pantalla de inicio"</string>
- <string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"Engadiuse o widget <xliff:g id="WIDGET_NAME">%1$s</xliff:g> á pantalla de inicio"</string>
- <string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# widget}other{# widgets}}"</string>
- <string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{# atallo}other{# atallos}}"</string>
- <string name="widgets_and_shortcuts_count" msgid="7209136747878365116">"<xliff:g id="WIDGETS_COUNT">%1$s</xliff:g>, <xliff:g id="SHORTCUTS_COUNT">%2$s</xliff:g>"</string>
- <string name="widget_button_text" msgid="2880537293434387943">"Widgets"</string>
- <string name="widgets_full_sheet_search_bar_hint" msgid="8484659090860596457">"Busca Widgets"</string>
- <string name="widgets_full_sheet_cancel_button_description" msgid="5766167035728653605">"Borrar texto da caixa de busca"</string>
- <string name="no_widgets_available" msgid="4337693382501046170">"Non hai widgets nin atallos dispoñibles"</string>
- <string name="no_search_results" msgid="3787956167293097509">"Non se atoparon widgets nin atallos"</string>
- <string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Widgets persoais"</string>
- <string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Widgets do traballo"</string>
- <string name="widget_category_conversations" msgid="8894438636213590446">"Conversas"</string>
- <string name="widget_education_header" msgid="4874760613775913787">"Información útil ao teu alcance"</string>
- <string name="widget_education_content" msgid="745542879510751525">"Se queres obter información sen abrir as aplicacións, podes engadir widgets á pantalla de inicio"</string>
- <string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Toca para cambiar a configuración do widget"</string>
- <string name="widget_education_close_button" msgid="8676165703104836580">"Entendido"</string>
- <string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Cambiar configuración do widget"</string>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Mantén premido o elemento para colocalo manualmente"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"Engadir automaticamente"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Buscar aplicacións"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Cargando aplicacións…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"Non se atoparon aplicacións que coincidan con \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
<string name="all_apps_search_market_message" msgid="1366263386197059176">"Buscar máis aplicacións"</string>
<string name="label_application" msgid="8531721983832654978">"Aplicación"</string>
- <string name="all_apps_label" msgid="5015784846527570951">"Todas as aplicacións"</string>
<string name="notifications_header" msgid="1404149926117359025">"Notificacións"</string>
- <string name="long_press_shortcut_to_add" msgid="5405328730817637737">"Mantén premido un atallo para movelo."</string>
- <string name="long_accessible_way_to_add_shortcut" msgid="2199537273817090740">"Toca dúas veces un atallo e manteno premido para movelo ou utiliza accións personalizadas."</string>
- <string name="out_of_space" msgid="6692471482459245734">"Non queda espazo nesta pantalla de inicio"</string>
+ <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"Mantén premido un atallo para seleccionalo."</string>
+ <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"Toca dúas veces e mantén premido para seleccionar un atallo ou utiliza accións personalizadas."</string>
+ <string name="out_of_space" msgid="4691004494942118364">"Non hai máis espazo nesta pantalla de inicio."</string>
<string name="hotseat_out_of_space" msgid="7448809638125333693">"Non hai máis espazo na bandexa de favoritos"</string>
<string name="all_apps_button_label" msgid="8130441508702294465">"Lista de aplicacións"</string>
- <string name="all_apps_search_results" msgid="5889367432531296759">"Resultados da busca"</string>
<string name="all_apps_button_personal_label" msgid="1315764287305224468">"Lista de aplicacións persoais"</string>
<string name="all_apps_button_work_label" msgid="7270707118948892488">"Lista de aplicacións de traballo"</string>
- <string name="remove_drop_target_label" msgid="7812859488053230776">"Quitar"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"Inicio"</string>
+ <string name="remove_drop_target_label" msgid="7812859488053230776">"Eliminar"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"Desinstalar"</string>
<string name="app_info_drop_target_label" msgid="692894985365717661">"Info. da aplicación"</string>
<string name="install_drop_target_label" msgid="2539096853673231757">"Instalar"</string>
- <string name="dismiss_prediction_label" msgid="3357562989568808658">"Non suxerir aplicación"</string>
- <string name="pin_prediction" msgid="4196423321649756498">"Fixar predición"</string>
<string name="permlab_install_shortcut" msgid="5632423390354674437">"instalar atallos"</string>
<string name="permdesc_install_shortcut" msgid="923466509822011139">"Permite a unha aplicación engadir atallos sen intervención do usuario."</string>
<string name="permlab_read_settings" msgid="1941457408239617576">"ler a configuración e os atallos da pantalla de inicio"</string>
@@ -84,13 +59,15 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"modificar a configuración e os atallos da pantalla de inicio"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"Permite a unha aplicación cambiar a configuración e os atallos da pantalla de inicio."</string>
<string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> non ten permiso para facer chamadas telefónicas"</string>
- <string name="gadget_error_text" msgid="740356548025791839">"Non se puido cargar o widget"</string>
- <string name="gadget_setup_text" msgid="8348374825537681407">"Configuración do widget"</string>
- <string name="gadget_complete_setup_text" msgid="309040266978007925">"Toca para rematar a configuración"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"Produciuse un problema ao cargar o widget"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"Configuración"</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"Esta aplicación é do sistema e non se pode desinstalar."</string>
- <string name="folder_hint_text" msgid="5174843001373488816">"Edita o nome"</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"Cartafol sen nome"</string>
<string name="disabled_app_label" msgid="6673129024321402780">"Desactivouse <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
- <string name="dotted_app_label" msgid="1704091277755818896">"{count,plural,offset:1 =1{{app_name} ten # notificación}other{{app_name} ten # notificacións}}"</string>
+ <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+ <item quantity="other">A aplicación <xliff:g id="APP_NAME_2">%1$s</xliff:g> ten <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> notificacións</item>
+ <item quantity="one">A aplicación <xliff:g id="APP_NAME_0">%1$s</xliff:g> ten <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> notificación</item>
+ </plurals>
<string name="default_scroll_format" msgid="7475544710230993317">"Páxina %1$d de %2$d"</string>
<string name="workspace_scroll_format" msgid="8458889198184077399">"Pantalla de inicio %1$d de %2$d"</string>
<string name="workspace_new_page" msgid="257366611030256142">"Nova páxina da pantalla de inicio"</string>
@@ -99,10 +76,10 @@
<string name="folder_tap_to_rename" msgid="4017685068016979677">"Toca fóra para cambiar o nome do cartafol"</string>
<string name="folder_closed" msgid="4100806530910930934">"Pechouse o cartafol"</string>
<string name="folder_renamed" msgid="1794088362165669656">"O cartafol cambiou o nome a <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="folder_name_format_exact" msgid="8626242716117004803">"Cartafol: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> elementos"</string>
- <string name="folder_name_format_overflow" msgid="4270108890534995199">"Cartafol: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> elementos ou máis"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"Cartafol: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"Widgets"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Fondos de pantalla"</string>
- <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Estilo e fondo de pantalla"</string>
+ <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Estilos/fondos de pantalla"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Axustes de Inicio"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Función desactivada polo administrador"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Permitir xirar a pantalla de inicio"</string>
@@ -113,23 +90,23 @@
<string name="title_missing_notification_access" msgid="7503287056163941064">"Necesítase acceso ás notificacións"</string>
<string name="msg_missing_notification_access" msgid="281113995110910548">"Para que se mostren os puntos de notificacións, activa as notificacións da aplicación <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="title_change_settings" msgid="1376365968844349552">"Cambiar configuración"</string>
- <string name="notification_dots_service_title" msgid="4284221181793592871">"Mostra puntos de notificacións"</string>
- <string name="auto_add_shortcuts_label" msgid="3698776050751790653">"Engadir iconas de aplicacións á pantalla de inicio"</string>
+ <string name="notification_dots_service_title" msgid="4284221181793592871">"Mostrar puntos de notificacións"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Engadir icona á pantalla de inicio"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Para novas aplicacións"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"Descoñecido"</string>
- <string name="abandoned_clean_this" msgid="7610119707847920412">"Quitar"</string>
+ <string name="abandoned_clean_this" msgid="7610119707847920412">"Eliminar"</string>
<string name="abandoned_search" msgid="891119232568284442">"Buscar"</string>
<string name="abandoned_promises_title" msgid="7096178467971716750">"Esta aplicación non está instalada"</string>
- <string name="abandoned_promise_explanation" msgid="3990027586878167529">"A aplicación para esta icona non está instalada. Podes quitala ou buscar a aplicación e instalala manualmente."</string>
- <string name="app_installing_title" msgid="5864044122733792085">"Instalando <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="PROGRESS">%2$s</xliff:g> completado"</string>
+ <string name="abandoned_promise_explanation" msgid="3990027586878167529">"A aplicación para esta icona non está instalada. Podes eliminala ou buscar a aplicación e instalala manualmente."</string>
<string name="app_downloading_title" msgid="8336702962104482644">"Descargando <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="PROGRESS">%2$s</xliff:g> completado)"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"Esperando para instalar <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"Widgets de: <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="widgets_list" msgid="796804551140113767">"Lista de widgets"</string>
<string name="widgets_list_closed" msgid="6141506579418771922">"Pechouse a lista de widgets"</string>
<string name="action_add_to_workspace" msgid="8902165848117513641">"Engadir á pantalla de inicio"</string>
<string name="action_move_here" msgid="2170188780612570250">"Mover elemento aquí"</string>
<string name="item_added_to_workspace" msgid="4211073925752213539">"Engadiuse o elemento á pantalla de inicio"</string>
- <string name="item_removed" msgid="851119963877842327">"Quitouse o elemento"</string>
+ <string name="item_removed" msgid="851119963877842327">"Eliminouse o elemento"</string>
<string name="undo" msgid="4151576204245173321">"Desfacer"</string>
<string name="action_move" msgid="4339390619886385032">"Mover elemento"</string>
<string name="move_to_empty_cell" msgid="2833711483015685619">"Mover á fila <xliff:g id="NUMBER_0">%1$s</xliff:g> columna <xliff:g id="NUMBER_1">%2$s</xliff:g>"</string>
@@ -151,20 +128,15 @@
<string name="action_deep_shortcut" msgid="2864038805849372848">"Atallos"</string>
<string name="shortcuts_menu_with_notifications_description" msgid="2676582286544232849">"Atallos e notificacións"</string>
<string name="action_dismiss_notification" msgid="5909461085055959187">"Ignorar"</string>
- <string name="accessibility_close" msgid="2277148124685870734">"Pechar"</string>
<string name="notification_dismissed" msgid="6002233469409822874">"Ignorouse a notificación"</string>
<string name="all_apps_personal_tab" msgid="4190252696685155002">"Persoal"</string>
<string name="all_apps_work_tab" msgid="4884822796154055118">"Traballo"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"Perfil de traballo"</string>
- <string name="work_profile_edu_work_apps" msgid="7895468576497746520">"O administrador de TI pode ver as aplicacións do traballo e engadirlles indicadores"</string>
- <string name="work_profile_edu_accept" msgid="6069788082535149071">"Entendido"</string>
- <string name="work_apps_paused_title" msgid="3040901117349444598">"Puxéronse en pausa as aplicacións do traballo"</string>
- <string name="work_apps_paused_body" msgid="261634750995824906">"As aplicacións do traballo non poden enviarche notificacións, utilizar a batería nin acceder á túa localización"</string>
- <string name="work_apps_paused_content_description" msgid="5149623040804051095">"As aplicacións do traballo están desactivadas e non poden enviarche notificacións, utilizar a batería nin acceder á túa localización"</string>
- <string name="work_apps_paused_edu_banner" msgid="8872412121608402058">"O administrador de TI pode ver as aplicacións do traballo e engadirlles indicadores"</string>
- <string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"Entendido"</string>
- <string name="work_apps_pause_btn_text" msgid="1921059713673767460">"Desactivar aplicacións do traballo"</string>
- <string name="work_apps_enable_btn_text" msgid="1156432622148413741">"Activar aplicacións do traballo"</string>
- <string name="developer_options_filter_hint" msgid="5896817443635989056">"Filtra"</string>
+ <string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"Buscar aplicacións do traballo aquí"</string>
+ <string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"As aplicacións do traballo teñen unha insignia e están protexidas pola túa organización. Traslada as aplicacións á pantalla de inicio para acceder a elas de forma máis fácil."</string>
+ <string name="work_mode_on_label" msgid="4781128097185272916">"Perfil xestionado pola túa organización"</string>
+ <string name="work_mode_off_label" msgid="3194894777601421047">"As notificacións e as aplicacións están desactivadas"</string>
+ <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Pechar"</string>
+ <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Pechada"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Erro: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
</resources>
diff --git a/res/values-gu/strings.xml b/res/values-gu/strings.xml
index fae3773756..3228dea004 100644
--- a/res/values-gu/strings.xml
+++ b/res/values-gu/strings.xml
@@ -20,77 +20,54 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="649227358658669779">"Launcher3"</string>
- <string name="work_folder_name" msgid="3753320833950115786">"ઑફિસ"</string>
+ <string name="work_folder_name" msgid="3753320833950115786">"કાર્યાલય"</string>
<string name="activity_not_found" msgid="8071924732094499514">"ઍપ્લિકેશન ઇન્સ્ટોલ થઈ નથી."</string>
<string name="activity_not_available" msgid="7456344436509528827">"ઍપ્લિકેશન ઉપલબ્ધ નથી"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"સુરક્ષિત મોડમાં ડાઉનલોડ કરેલ ઍપ્લિકેશન અક્ષમ કરી"</string>
<string name="safemode_widget_error" msgid="4863470563535682004">"સુરક્ષિત મોડમાં વિજેટ્સ અક્ષમ કર્યા"</string>
<string name="shortcut_not_available" msgid="2536503539825726397">"શૉર્ટકટ ઉપલબ્ધ નથી"</string>
- <string name="home_screen" msgid="5629429142036709174">"હોમ સ્ક્રીન"</string>
- <string name="recent_task_option_split_screen" msgid="6690461455618725183">"સ્ક્રીનને વિભાજિત કરો"</string>
- <string name="split_screen_position_top" msgid="1504965011158689649">"ઉપર વિભાજિત કરો"</string>
- <string name="split_screen_position_left" msgid="7537793098851830883">"ડાબે વિભાજિત કરો"</string>
- <string name="split_screen_position_right" msgid="1569377524925193369">"જમણે વિભાજિત કરો"</string>
- <string name="split_app_info_accessibility" msgid="5475288491241414932">"%1$s માટે ઍપ માહિતી"</string>
- <string name="long_press_widget_to_add" msgid="3587712543577675817">"વિજેટ ખસેડવા ટચ કરીને થોડી વાર દબાવી રાખો."</string>
- <string name="long_accessible_way_to_add" msgid="2733588281439571974">"વિજેટ ખસેડવા બે વાર ટૅપ કરીને દબાવી રાખો અથવા કસ્ટમ ક્રિયાઓનો ઉપયોગ કરો."</string>
+ <string name="home_screen" msgid="806512411299847073">"હોમ સ્ક્રીન"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"કસ્ટમ ક્રિયાઓ"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"વિજેટ ચૂંટવા માટે સ્પર્શ કરો અને પકડી રાખો."</string>
+ <string name="long_accessible_way_to_add" msgid="4289502106628154155">"વિજેટ ચૂંટવા અથવા કસ્ટમ ક્રિયાઓનો ઉપયોગ કરવા માટે બે વાર ટેપ કરો અને પકડી રાખો."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d પહોળાઈ X %2$d ઊંચાઈ"</string>
- <string name="widget_preview_context_description" msgid="9045841361655787574">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g> વિજેટ"</string>
- <string name="add_item_request_drag_hint" msgid="5653291305078645405">"વિજેટને હોમ સ્ક્રીનની આજુબાજુ ખસેડવા માટે, તેને ટચ કરીને થોડીવાર દબાવી રાખો"</string>
- <string name="add_to_home_screen" msgid="8631549138215492708">"હોમ સ્ક્રીન પર ઉમેરો"</string>
- <string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"હોમ સ્ક્રીન પર <xliff:g id="WIDGET_NAME">%1$s</xliff:g> વિજેટ ઉમેર્યુ"</string>
- <string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# વિજેટ}one{# વિજેટ}other{# વિજેટ}}"</string>
- <string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{# શૉર્ટકટ}one{# શૉર્ટકટ}other{# શૉર્ટકટ}}"</string>
- <string name="widgets_and_shortcuts_count" msgid="7209136747878365116">"<xliff:g id="WIDGETS_COUNT">%1$s</xliff:g>, <xliff:g id="SHORTCUTS_COUNT">%2$s</xliff:g>"</string>
- <string name="widget_button_text" msgid="2880537293434387943">"વિજેટ"</string>
- <string name="widgets_full_sheet_search_bar_hint" msgid="8484659090860596457">"શોધ"</string>
- <string name="widgets_full_sheet_cancel_button_description" msgid="5766167035728653605">"શોધ બૉક્સમાંથી ટેક્સ્ટ સાફ કરો"</string>
- <string name="no_widgets_available" msgid="4337693382501046170">"વિજેટ અને શૉર્ટકટ ઉપલબ્ધ નથી"</string>
- <string name="no_search_results" msgid="3787956167293097509">"કોઈ વિજેટ અથવા શૉર્ટકટ મળ્યા નથી"</string>
- <string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"વ્યક્તિગત"</string>
- <string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"ઑફિસ"</string>
- <string name="widget_category_conversations" msgid="8894438636213590446">"વાતચીતો"</string>
- <string name="widget_education_header" msgid="4874760613775913787">"ઉપયોગી માહિતી તમારી આંગળીના ટેરવે"</string>
- <string name="widget_education_content" msgid="745542879510751525">"ઍપને ખોલ્યા વિના માહિતી મેળવવા માટે, તમે તમારી હોમ સ્ક્રીન પર વિજેટ ઉમેરી શકો છો"</string>
- <string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"વિજેટના સેટિંગ બદલવા માટે ટૅપ કરો"</string>
- <string name="widget_education_close_button" msgid="8676165703104836580">"સમજાઈ ગયું"</string>
- <string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"વિજેટના સેટિંગ બદલો"</string>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"મેન્યુઅલી મૂકવા માટે ટચ કરી દબાવી રાખો"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"આપમેળે ઉમેરો"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"શોધ ઍપ્લિકેશનો"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"ઍપ્લિકેશનો લોડ કરી રહ્યું છે…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\"થી મેળ ખાતી કોઈ ઍપ્લિકેશનો મળી નથી"</string>
<string name="all_apps_search_market_message" msgid="1366263386197059176">"વધુ ઍપ્લિકેશનો શોધો"</string>
<string name="label_application" msgid="8531721983832654978">"ઍપ"</string>
- <string name="all_apps_label" msgid="5015784846527570951">"બધી ઍપ"</string>
- <string name="notifications_header" msgid="1404149926117359025">"નોટિફિકેશન"</string>
- <string name="long_press_shortcut_to_add" msgid="5405328730817637737">"શૉર્ટકટ ખસેડવા ટચ કરીને થોડી વાર દબાવી રાખો."</string>
- <string name="long_accessible_way_to_add_shortcut" msgid="2199537273817090740">"શૉર્ટકટ ખસેડવા બે વાર ટૅપ કરીને દબાવી રાખો અથવા કસ્ટમ ક્રિયાઓનો ઉપયોગ કરો."</string>
- <string name="out_of_space" msgid="6692471482459245734">"આ હોમ સ્ક્રીન પર વધુ જગ્યા નથી"</string>
+ <string name="notifications_header" msgid="1404149926117359025">"નોટિફિકેશનો"</string>
+ <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"એક શૉર્ટકટ ચૂંટવા માટે સ્પર્શ કરી રાખો."</string>
+ <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"એક શૉર્ટકટ ચૂંટવા અથવા કોઈ કસ્ટમ ક્રિયાઓનો ઉપયોગ કરવા માટે બે વાર ટૅપ કરીને દબાવી રાખો."</string>
+ <string name="out_of_space" msgid="4691004494942118364">"આ હોમ સ્ક્રીન પર વધુ જગ્યા નથી."</string>
<string name="hotseat_out_of_space" msgid="7448809638125333693">"મનપસંદ ટ્રે પર વધુ જગ્યા નથી"</string>
<string name="all_apps_button_label" msgid="8130441508702294465">"ઍપ્લિકેશનોની સૂચિ"</string>
- <string name="all_apps_search_results" msgid="5889367432531296759">"શોધ પરિણામો"</string>
<string name="all_apps_button_personal_label" msgid="1315764287305224468">"વ્યક્તિગત ઍપની સૂચિ"</string>
<string name="all_apps_button_work_label" msgid="7270707118948892488">"કાર્યસ્થળની ઍપની સૂચિ"</string>
- <string name="remove_drop_target_label" msgid="7812859488053230776">"કાઢી નાખો"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"હોમ"</string>
+ <string name="remove_drop_target_label" msgid="7812859488053230776">"દૂર કરો"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"અનઇન્સ્ટોલ કરો"</string>
- <string name="app_info_drop_target_label" msgid="692894985365717661">"ઍપની માહિતી"</string>
+ <string name="app_info_drop_target_label" msgid="692894985365717661">"ઍપ્લિકેશન માહિતી"</string>
<string name="install_drop_target_label" msgid="2539096853673231757">"ઇન્સ્ટૉલ કરો"</string>
- <string name="dismiss_prediction_label" msgid="3357562989568808658">"ઍપ સૂચવશો નહીં"</string>
- <string name="pin_prediction" msgid="4196423321649756498">"પૂર્વાનુમાનને પિન કરો"</string>
- <string name="permlab_install_shortcut" msgid="5632423390354674437">"શૉર્ટકટ ઇન્સ્ટૉલ કરો"</string>
+ <string name="permlab_install_shortcut" msgid="5632423390354674437">"શોર્ટકટ્સ ઇન્સ્ટોલ કરો"</string>
<string name="permdesc_install_shortcut" msgid="923466509822011139">"એપ્લિકેશનને વપરાશકર્તા હસ્તક્ષેપ વગર શોર્ટકટ્સ ઉમેરવાની મંજૂરી આપે છે."</string>
- <string name="permlab_read_settings" msgid="1941457408239617576">"હોમ સેટિંગ અને શૉર્ટકટ વાંચો"</string>
- <string name="permdesc_read_settings" msgid="5833423719057558387">"ઍપને હોમમાં સેટિંગ અને શૉર્ટકટ વાંચવાની મંજૂરી આપે છે."</string>
- <string name="permlab_write_settings" msgid="3574213698004620587">"હોમ સેટિંગ અને શૉર્ટકટ લખો"</string>
- <string name="permdesc_write_settings" msgid="5440712911516509985">"ઍપને હોમમાં સેટિંગ અને શૉર્ટકટ બદલવાની મંજૂરી આપે છે."</string>
+ <string name="permlab_read_settings" msgid="1941457408239617576">"હોમ સેટિંગ્સ અને શોર્ટકટ્સ વાંચો"</string>
+ <string name="permdesc_read_settings" msgid="5833423719057558387">"એપ્લિકેશનને હોમમાં સેટિંગ્સ અને શોર્ટકટ્સ વાંચવાની મંજૂરી આપે છે."</string>
+ <string name="permlab_write_settings" msgid="3574213698004620587">"હોમ સેટિંગ્સ અને શોર્ટકટ્સ લખો"</string>
+ <string name="permdesc_write_settings" msgid="5440712911516509985">"એપ્લિકેશનને હોમમાં સેટિંગ્સ અને શોર્ટકટ્સ બદલવાની મંજૂરી આપે છે."</string>
<string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> ને ફોન કૉલ્સ કરવાની મંજૂરી નથી"</string>
- <string name="gadget_error_text" msgid="740356548025791839">"વિજેટ લોડ કરી શકાતું નથી"</string>
- <string name="gadget_setup_text" msgid="8348374825537681407">"વિજેટ સેટિંગ"</string>
- <string name="gadget_complete_setup_text" msgid="309040266978007925">"સેટઅપ પૂર્ણ કરવા માટે ટૅપ કરો"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"વિજેટ લોડ કરવામાં સમસ્યા"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"સેટઅપ"</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"આ એક સિસ્ટમ ઍપ્લિકેશન છે અને અનઇન્સ્ટોલ કરી શકાતી નથી."</string>
- <string name="folder_hint_text" msgid="5174843001373488816">"નામમાં ફેરફાર કરો"</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"અનામી ફોલ્ડર"</string>
<string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> અક્ષમ કરી"</string>
- <string name="dotted_app_label" msgid="1704091277755818896">"{count,plural,offset:1 =1{{app_name}ના # નોટિફિકેશન છે}one{{app_name}ના # નોટિફિકેશન છે}other{{app_name}ના # નોટિફિકેશન છે}}"</string>
+ <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+ <item quantity="one"><xliff:g id="APP_NAME_2">%1$s</xliff:g>ના <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> નોટિફિકેશન છે</item>
+ <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>ના <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> નોટિફિકેશન છે</item>
+ </plurals>
<string name="default_scroll_format" msgid="7475544710230993317">"%2$d માંથી %1$d પૃષ્ઠ"</string>
<string name="workspace_scroll_format" msgid="8458889198184077399">"%2$d માંથી %1$d હોમ સ્ક્રીન"</string>
<string name="workspace_new_page" msgid="257366611030256142">"નવું હોમ સ્ક્રીન પૃષ્ઠ"</string>
@@ -99,11 +76,11 @@
<string name="folder_tap_to_rename" msgid="4017685068016979677">"નામ બદલવાનું સાચવવા માટે ટૅપ કરો"</string>
<string name="folder_closed" msgid="4100806530910930934">"ફોલ્ડર બંધ કર્યું"</string>
<string name="folder_renamed" msgid="1794088362165669656">"ફોલ્ડરનું નામ બદલીને <xliff:g id="NAME">%1$s</xliff:g> કર્યું"</string>
- <string name="folder_name_format_exact" msgid="8626242716117004803">"ફોલ્ડર: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> આઇટમ"</string>
- <string name="folder_name_format_overflow" msgid="4270108890534995199">"ફોલ્ડર: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> કે વધુ આઇટમ"</string>
- <string name="wallpaper_button_text" msgid="8404103075899945851">"વૉલપેપર"</string>
- <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"વૉલપેપર અને શૈલી"</string>
- <string name="settings_button_text" msgid="8873672322605444408">"હોમ સેટિંગ"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"ફોલ્ડર: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"વિજેટ્સ"</string>
+ <string name="wallpaper_button_text" msgid="8404103075899945851">"વૉલપેપર્સ"</string>
+ <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"શૈલીઓ અને વૉલપેપર"</string>
+ <string name="settings_button_text" msgid="8873672322605444408">"હોમ સેટિંગ્સ"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"તમારા વ્યવસ્થાપક દ્વારા અક્ષમ કરેલ"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"હોમ સ્ક્રીનને ફેરવવાની મંજૂરી આપો"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"જ્યારે ફોન ફેરવવામાં આવે ત્યારે"</string>
@@ -112,18 +89,18 @@
<string name="notification_dots_desc_off" msgid="1760796511504341095">"બંધ છે"</string>
<string name="title_missing_notification_access" msgid="7503287056163941064">"નોટિફિકેશનનો ઍક્સેસની જરૂરી છે"</string>
<string name="msg_missing_notification_access" msgid="281113995110910548">"નોટિફિકેશન માટેનું ચિહ્ન બતાવવા હેતુ, <xliff:g id="NAME">%1$s</xliff:g> માટેની ઍપ્લિકેશન નોટિફિકેશન ચાલુ કરો"</string>
- <string name="title_change_settings" msgid="1376365968844349552">"સેટિંગ બદલો"</string>
+ <string name="title_change_settings" msgid="1376365968844349552">"સેટિંગ્સ બદલો"</string>
<string name="notification_dots_service_title" msgid="4284221181793592871">"નોટિફિકેશન માટેના ચિહ્ન બતાવો"</string>
- <string name="auto_add_shortcuts_label" msgid="3698776050751790653">"ઍપના આઇકન હોમ સ્ક્રીન પર ઉમેરો"</string>
- <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"નવી ઍપ માટે"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"હોમ સ્ક્રીન પર આઇકન ઉમેરો"</string>
+ <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"નવી ઍપ્લિકેશનો માટે"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"અજાણ્યો"</string>
- <string name="abandoned_clean_this" msgid="7610119707847920412">"કાઢી નાખો"</string>
+ <string name="abandoned_clean_this" msgid="7610119707847920412">"દૂર કરો"</string>
<string name="abandoned_search" msgid="891119232568284442">"શોધો"</string>
<string name="abandoned_promises_title" msgid="7096178467971716750">"આ ઍપ્લિકેશન ઇન્સ્ટોલ થયેલ નથી"</string>
<string name="abandoned_promise_explanation" msgid="3990027586878167529">"આ આયકન માટેની ઍપ્લિકેશન ઇન્સ્ટોલ થયેલ નથી. તમે તેને દૂર કરી શકો છો અથવા ઍપ્લિકેશન માટે શોધ કરી અને તેને મેન્યુઅલી ઇન્સ્ટોલ કરી શકો છો."</string>
- <string name="app_installing_title" msgid="5864044122733792085">"<xliff:g id="NAME">%1$s</xliff:g> ઇન્સ્ટૉલ કરી રહ્યાં છીએ, <xliff:g id="PROGRESS">%2$s</xliff:g> પૂર્ણ થયું"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> ડાઉનલોડ કરી રહ્યાં છે, <xliff:g id="PROGRESS">%2$s</xliff:g> પૂર્ણ"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g>, ઇન્સ્ટૉલ થવાની રાહ જોઈ રહ્યું છે"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"<xliff:g id="NAME">%1$s</xliff:g> વિજેટ"</string>
<string name="widgets_list" msgid="796804551140113767">"વિજેટની સૂચિ"</string>
<string name="widgets_list_closed" msgid="6141506579418771922">"વિજેટની સૂચિ બંધ કરવામાં આવી છે"</string>
<string name="action_add_to_workspace" msgid="8902165848117513641">"હોમ સ્ક્રીન પર ઉમેરો"</string>
@@ -151,20 +128,15 @@
<string name="action_deep_shortcut" msgid="2864038805849372848">"શૉર્ટકટ્સ"</string>
<string name="shortcuts_menu_with_notifications_description" msgid="2676582286544232849">"શૉર્ટકટ અને નોટિફિકેશનો"</string>
<string name="action_dismiss_notification" msgid="5909461085055959187">"છોડી દો"</string>
- <string name="accessibility_close" msgid="2277148124685870734">"બંધ કરો"</string>
<string name="notification_dismissed" msgid="6002233469409822874">"સૂચના છોડી દીધી"</string>
<string name="all_apps_personal_tab" msgid="4190252696685155002">"મનગમતી ઍપ"</string>
- <string name="all_apps_work_tab" msgid="4884822796154055118">"ઑફિસની ઍપ"</string>
- <string name="work_profile_toggle_label" msgid="3081029915775481146">"ઑફિસની પ્રોફાઇલ"</string>
- <string name="work_profile_edu_work_apps" msgid="7895468576497746520">"ઑફિસની ઍપને બૅજ આપેલા હોય છે અને તમારા IT વ્યવસ્થાપક તેમને જોઈ શકે છે"</string>
- <string name="work_profile_edu_accept" msgid="6069788082535149071">"સમજાઈ ગયું"</string>
- <string name="work_apps_paused_title" msgid="3040901117349444598">"ઑફિસ માટેની ઍપ થોભાવવામાં આવેલ છે"</string>
- <string name="work_apps_paused_body" msgid="261634750995824906">"ઑફિસ માટેની તમારી ઍપ તમને નોટિફિકેશન મોકલી શકતી નથી, તમારી બૅટરી વાપરી શકતી નથી કે તમારું સ્થાન ઍક્સેસ કરી શકતી નથી"</string>
- <string name="work_apps_paused_content_description" msgid="5149623040804051095">"ઑફિસ માટેની ઍપ બંધ છે. ઑફિસ માટેની તમારી ઍપ તમને નોટિફિકેશન મોકલી શકતી નથી, તમારી બૅટરી વાપરી શકતી નથી કે તમારું સ્થાન ઍક્સેસ કરી શકતી નથી"</string>
- <string name="work_apps_paused_edu_banner" msgid="8872412121608402058">"ઑફિસની ઍપને બૅજ આપેલા હોય છે અને તમારા IT વ્યવસ્થાપક તેમને જોઈ શકે છે"</string>
- <string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"સમજાઈ ગયું"</string>
- <string name="work_apps_pause_btn_text" msgid="1921059713673767460">"ઑફિસ માટેની ઍપ બંધ કરો"</string>
- <string name="work_apps_enable_btn_text" msgid="1156432622148413741">"ઑફિસ માટેની ઍપ ચાલુ કરો"</string>
- <string name="developer_options_filter_hint" msgid="5896817443635989056">"ફિલ્ટર કરો"</string>
+ <string name="all_apps_work_tab" msgid="4884822796154055118">"કાર્યાલયની ઍપ"</string>
+ <string name="work_profile_toggle_label" msgid="3081029915775481146">"કાર્યાલયની પ્રોફાઇલ"</string>
+ <string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"કાર્ય ઍપને અહીંથી મેળવો"</string>
+ <string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"દરેક કાર્ય ઍપ પાસે એક બૅજ હોય છે અને તમારી સંસ્થા દ્વારા તેને સુરક્ષિત રાખવામાં આવે છે. વધુ સરળ ઍક્સેસ માટે ઍપને તમારી હોમ સ્ક્રીન પર ખસેડો."</string>
+ <string name="work_mode_on_label" msgid="4781128097185272916">"તમારી સંસ્થા દ્વારા મેનેજ કરેલ"</string>
+ <string name="work_mode_off_label" msgid="3194894777601421047">"નોટિફિકેશન અને ઍપ બંધ છે"</string>
+ <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"બંધ કરો"</string>
+ <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"બંધ"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"નિષ્ફળ: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
</resources>
diff --git a/res/values-hi/strings.xml b/res/values-hi/strings.xml
index 6290cd171f..8fa02c0165 100644
--- a/res/values-hi/strings.xml
+++ b/res/values-hi/strings.xml
@@ -20,63 +20,38 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="649227358658669779">"Launcher3"</string>
- <string name="work_folder_name" msgid="3753320833950115786">"दफ़्तर"</string>
+ <string name="work_folder_name" msgid="3753320833950115786">"कार्यस्‍थल"</string>
<string name="activity_not_found" msgid="8071924732094499514">"ऐप्‍लिकेशन इंस्‍टॉल नहीं है."</string>
<string name="activity_not_available" msgid="7456344436509528827">"ऐप्लिकेशन उपलब्ध नहीं है"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"डाउनलोड किए गए ऐप्लिकेशन सुरक्षित मोड में अक्षम है"</string>
<string name="safemode_widget_error" msgid="4863470563535682004">"विजेट सुरक्षित मोड में अक्षम हैं"</string>
<string name="shortcut_not_available" msgid="2536503539825726397">"शॉर्टकट उपलब्ध नहीं है"</string>
- <string name="home_screen" msgid="5629429142036709174">"होम स्क्रीन"</string>
- <string name="recent_task_option_split_screen" msgid="6690461455618725183">"स्प्लिट स्क्रीन"</string>
- <string name="split_screen_position_top" msgid="1504965011158689649">"स्क्रीन को ऊपर के हिस्से में स्प्लिट करें"</string>
- <string name="split_screen_position_left" msgid="7537793098851830883">"स्क्रीन को बाएं हिस्से में स्प्लिट करें"</string>
- <string name="split_screen_position_right" msgid="1569377524925193369">"स्क्रीन को दाएं हिस्से में स्प्लिट करें"</string>
- <string name="split_app_info_accessibility" msgid="5475288491241414932">"%1$s के लिए ऐप्लिकेशन की जानकारी"</string>
- <string name="long_press_widget_to_add" msgid="3587712543577675817">"किसी विजेट को एक से दूसरी जगह ले जाने के लिए, उसे दबाकर रखें."</string>
- <string name="long_accessible_way_to_add" msgid="2733588281439571974">"किसी विजेट को एक से दूसरी जगह ले जाने के लिए, उस पर दो बार टैप करके दबाकर रखें या पसंद के मुताबिक कार्रवाइयां इस्तेमाल करें."</string>
+ <string name="home_screen" msgid="806512411299847073">"होम स्क्रीन"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"कस्टम कार्रवाइयां"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"विजेट को चुनने के लिए दबाकर रखें"</string>
+ <string name="long_accessible_way_to_add" msgid="4289502106628154155">"कोई विजेट चुनने के लिए दो बार छूएं और दबाये रखें या अपने मुताबिक कार्रवाइयां चुनें."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d चौड़ाई गुणा %2$d ऊंचाई"</string>
- <string name="widget_preview_context_description" msgid="9045841361655787574">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g> विजेट"</string>
- <string name="add_item_request_drag_hint" msgid="5653291305078645405">"होम स्क्रीन पर यहां-वहां ले जाने के लिए विजेट को दबाकर रखें"</string>
- <string name="add_to_home_screen" msgid="8631549138215492708">"होम स्क्रीन पर जोड़ें"</string>
- <string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g> विजेट को होम स्क्रीन पर जोड़ा गया"</string>
- <string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# विजेट}one{# विजेट}other{# विजेट}}"</string>
- <string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{# शॉर्टकट}one{# शॉर्टकट}other{# शॉर्टकट}}"</string>
- <string name="widgets_and_shortcuts_count" msgid="7209136747878365116">"<xliff:g id="WIDGETS_COUNT">%1$s</xliff:g>, <xliff:g id="SHORTCUTS_COUNT">%2$s</xliff:g>"</string>
- <string name="widget_button_text" msgid="2880537293434387943">"विजेट"</string>
- <string name="widgets_full_sheet_search_bar_hint" msgid="8484659090860596457">"खोजें"</string>
- <string name="widgets_full_sheet_cancel_button_description" msgid="5766167035728653605">"खोज बॉक्स से टेक्स्ट हटाएं"</string>
- <string name="no_widgets_available" msgid="4337693382501046170">"विजेट और शॉर्टकट उपलब्ध नहीं हैं"</string>
- <string name="no_search_results" msgid="3787956167293097509">"कोई विजेट या शॉर्टकट नहीं मिला"</string>
- <string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"निजी विजेट"</string>
- <string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"ऑफ़िस"</string>
- <string name="widget_category_conversations" msgid="8894438636213590446">"बातचीत"</string>
- <string name="widget_education_header" msgid="4874760613775913787">"काम की जानकारी आसानी से पाएं"</string>
- <string name="widget_education_content" msgid="745542879510751525">"ऐप्लिकेशन को खोले बिना उनकी जानकारी पाने के लिए, आप होम स्क्रीन पर विजेट जोड़ सकते हैं"</string>
- <string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"विजेट की सेटिंग में बदलाव करने के लिए टैप करें"</string>
- <string name="widget_education_close_button" msgid="8676165703104836580">"ठीक है"</string>
- <string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"विजेट की सेटिंग में बदलाव करें"</string>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"खुद जोड़ने के लिए दबाकर रखें"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"अपने आप जोड़ें"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"ऐप सर्च करें"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"ऐप्लिकेशन लोड हो रहे हैं…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" से मिलता-जुलता कोई ऐप्लिकेशन नहीं मिला"</string>
<string name="all_apps_search_market_message" msgid="1366263386197059176">"और ऐप सर्च करें"</string>
<string name="label_application" msgid="8531721983832654978">"ऐप्लिकेशन"</string>
- <string name="all_apps_label" msgid="5015784846527570951">"सभी ऐप्लिकेशन"</string>
<string name="notifications_header" msgid="1404149926117359025">"सूचनाएं"</string>
- <string name="long_press_shortcut_to_add" msgid="5405328730817637737">"किसी शॉर्टकट को एक से दूसरी जगह ले जाने के लिए, उसे दबाकर रखें."</string>
- <string name="long_accessible_way_to_add_shortcut" msgid="2199537273817090740">"किसी शॉर्टकट को एक से दूसरी जगह ले जाने के लिए, उस पर दो बार टैप करके दबाकर रखें या पसंद के मुताबिक कार्रवाइयां इस्तेमाल करें."</string>
- <string name="out_of_space" msgid="6692471482459245734">"इस होम स्क्रीन पर जगह खाली नहीं है"</string>
+ <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"शॉर्टकट चुनने के लिए दबाकर रखें."</string>
+ <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"शॉर्टकट चुनने या पसंद के मुताबिक कार्रवाई करने के लिए दो बार टैप करें और कुछ देर दबाए रखें."</string>
+ <string name="out_of_space" msgid="4691004494942118364">"इस होम स्‍क्रीन पर जगह नहीं बची है"</string>
<string name="hotseat_out_of_space" msgid="7448809638125333693">"पसंदीदा ट्रे में और जगह नहीं है"</string>
<string name="all_apps_button_label" msgid="8130441508702294465">"ऐप्लिकेशन सूची"</string>
- <string name="all_apps_search_results" msgid="5889367432531296759">"खोज के नतीजे"</string>
<string name="all_apps_button_personal_label" msgid="1315764287305224468">"निजी ऐप्लिकेशन की सूची"</string>
<string name="all_apps_button_work_label" msgid="7270707118948892488">"काम से जुड़े ऐप्लिकेशन की सूची"</string>
- <string name="remove_drop_target_label" msgid="7812859488053230776">"हटाएं"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"होम पेज"</string>
+ <string name="remove_drop_target_label" msgid="7812859488053230776">"निकालें"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"अनइंस्टॉल करें"</string>
<string name="app_info_drop_target_label" msgid="692894985365717661">"ऐप्लिकेशन की जानकारी"</string>
<string name="install_drop_target_label" msgid="2539096853673231757">"इंस्‍टॉल करें"</string>
- <string name="dismiss_prediction_label" msgid="3357562989568808658">"ऐप्लिकेशन का सुझाव न दें"</string>
- <string name="pin_prediction" msgid="4196423321649756498">"सुझाए गए ऐप्लिकेशन को पिन करें"</string>
<string name="permlab_install_shortcut" msgid="5632423390354674437">"शॉर्टकट इंस्‍टॉल करें"</string>
<string name="permdesc_install_shortcut" msgid="923466509822011139">"ऐप को उपयोगकर्ता के हस्‍तक्षेप के बिना शॉर्टकट जोड़ने देती है."</string>
<string name="permlab_read_settings" msgid="1941457408239617576">"होम पेज की सेटिंग और शॉर्टकट पढ़ें"</string>
@@ -84,13 +59,15 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"होम पेज की सेटिंग और शॉर्टकट लिखें"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"ऐप्लिकेशन को होम पेज में सेटिंग और शॉर्टकट बदलने देती है."</string>
<string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> को फ़ोन कॉल करने की अनुमति नहीं है"</string>
- <string name="gadget_error_text" msgid="740356548025791839">"विजेट को लोड नहीं किया जा सका"</string>
- <string name="gadget_setup_text" msgid="8348374825537681407">"विजेट की सेटिंग"</string>
- <string name="gadget_complete_setup_text" msgid="309040266978007925">"सेट अप पूरा करने के लिए टैप करें"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"विजेट लोड करने में समस्‍या"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"सेटअप"</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"यह एक सिस्टम ऐप्लिकेशन है और इसे अनइंस्टॉल नहीं किया जा सकता."</string>
- <string name="folder_hint_text" msgid="5174843001373488816">"नाम में बदलाव करें"</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"अनामित फ़ोल्डर"</string>
<string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> अक्षम है"</string>
- <string name="dotted_app_label" msgid="1704091277755818896">"{count,plural,offset:1 =1{{app_name} से जुड़ी # सूचना है}one{{app_name} से जुड़ी # सूचना है}other{{app_name} से जुड़ी # सूचनाएं हैं}}"</string>
+ <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+ <item quantity="one"><xliff:g id="APP_NAME_2">%1$s</xliff:g> की <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> सूचना है</item>
+ <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g> की <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> सूचनाएं हैं</item>
+ </plurals>
<string name="default_scroll_format" msgid="7475544710230993317">"पेज %2$d में से %1$d"</string>
<string name="workspace_scroll_format" msgid="8458889198184077399">"होम स्क्रीन %2$d में से %1$d"</string>
<string name="workspace_new_page" msgid="257366611030256142">"नया होम स्‍क्रीन पेज"</string>
@@ -99,10 +76,10 @@
<string name="folder_tap_to_rename" msgid="4017685068016979677">"नाम बदलना सहेजने के लिए टैप करें"</string>
<string name="folder_closed" msgid="4100806530910930934">"फ़ोल्डर बंद किया गया"</string>
<string name="folder_renamed" msgid="1794088362165669656">"फ़ोल्डर का नाम बदलकर <xliff:g id="NAME">%1$s</xliff:g> किया गया"</string>
- <string name="folder_name_format_exact" msgid="8626242716117004803">"फ़ोल्डर: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> आइटम"</string>
- <string name="folder_name_format_overflow" msgid="4270108890534995199">"फ़ोल्डर: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> या इससे ज़्यादा आइटम"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"फ़ोल्डर: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"विजेट"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"वॉलपेपर"</string>
- <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"वॉलपेपर और स्टाइल"</string>
+ <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"स्टाइल और वॉलपेपर"</string>
<string name="settings_button_text" msgid="8873672322605444408">"होम पेज की सेटिंग"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"आपके एडमिन ने बंद किया हुआ है"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"होमस्क्रीन घुमाने की अनुमति दें"</string>
@@ -114,22 +91,22 @@
<string name="msg_missing_notification_access" msgid="281113995110910548">"सूचना बिंदु दिखाने के लिए, <xliff:g id="NAME">%1$s</xliff:g> के ऐप्लिकेशन सूचना चालू करें"</string>
<string name="title_change_settings" msgid="1376365968844349552">"सेटिंग बदलें"</string>
<string name="notification_dots_service_title" msgid="4284221181793592871">"नई सूचनाएं बताने वाला गोल निशान दिखाएं"</string>
- <string name="auto_add_shortcuts_label" msgid="3698776050751790653">"होम स्क्रीन पर ऐप्लिकेशन के आइकॉन जोड़ें"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"होम स्क्रीन में आइकॉन जोड़ें"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"नए ऐप्लिकेशन के लिए"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"अज्ञात"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"निकालें"</string>
- <string name="abandoned_search" msgid="891119232568284442">"खोजें"</string>
+ <string name="abandoned_search" msgid="891119232568284442">"सर्च करें"</string>
<string name="abandoned_promises_title" msgid="7096178467971716750">"यह ऐप्लिकेशन इंस्टॉल नहीं है"</string>
<string name="abandoned_promise_explanation" msgid="3990027586878167529">"इस आइकॉन का ऐप इंस्टॉल नहीं है. आप उसे निकाल सकते हैं या ऐप को खोज कर उसे मैन्युअल रूप से इंस्टॉल कर सकते हैं."</string>
- <string name="app_installing_title" msgid="5864044122733792085">"<xliff:g id="NAME">%1$s</xliff:g> इंस्टॉल किया जा रहा है, <xliff:g id="PROGRESS">%2$s</xliff:g> पूरा हो गया"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> डाउनलोड हो रहा है, <xliff:g id="PROGRESS">%2$s</xliff:g> पूरी हुई"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> के इंस्टॉल होने की प्रतीक्षा की जा रही है"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"<xliff:g id="NAME">%1$s</xliff:g> विजेट"</string>
<string name="widgets_list" msgid="796804551140113767">"विजेट की सूची"</string>
<string name="widgets_list_closed" msgid="6141506579418771922">"विजेट की सूची बंद हो गई है"</string>
<string name="action_add_to_workspace" msgid="8902165848117513641">"होम स्‍क्रीन में जोड़ें"</string>
<string name="action_move_here" msgid="2170188780612570250">"आइटम यहां ले जाएं"</string>
<string name="item_added_to_workspace" msgid="4211073925752213539">"होम स्क्रीन में आइटम जोड़ा गया"</string>
- <string name="item_removed" msgid="851119963877842327">"आइटम हटाया गया"</string>
+ <string name="item_removed" msgid="851119963877842327">"आइटम निकाला गया"</string>
<string name="undo" msgid="4151576204245173321">"पहले जैसा करें"</string>
<string name="action_move" msgid="4339390619886385032">"आइटम ले जाएं"</string>
<string name="move_to_empty_cell" msgid="2833711483015685619">"पंक्ति <xliff:g id="NUMBER_0">%1$s</xliff:g> स्तंभ <xliff:g id="NUMBER_1">%2$s</xliff:g> पर ले जाएं"</string>
@@ -151,20 +128,15 @@
<string name="action_deep_shortcut" msgid="2864038805849372848">"शॉर्टकट"</string>
<string name="shortcuts_menu_with_notifications_description" msgid="2676582286544232849">"शॉर्टकट और सूचनाएं"</string>
<string name="action_dismiss_notification" msgid="5909461085055959187">"खारिज करें"</string>
- <string name="accessibility_close" msgid="2277148124685870734">"बंद करें"</string>
<string name="notification_dismissed" msgid="6002233469409822874">"सूचना को खारिज किया गया"</string>
<string name="all_apps_personal_tab" msgid="4190252696685155002">"निजी ऐप"</string>
<string name="all_apps_work_tab" msgid="4884822796154055118">"काम से जुड़े ऐप"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"वर्क प्रोफ़ाइल"</string>
- <string name="work_profile_edu_work_apps" msgid="7895468576497746520">"ऑफ़िस के काम से जुड़े ऐप्लिकेशन बैज किए गए हैं और आईटी एडमिन को दिख रहे हैं"</string>
- <string name="work_profile_edu_accept" msgid="6069788082535149071">"ठीक है"</string>
- <string name="work_apps_paused_title" msgid="3040901117349444598">"ऑफ़िस के काम से जुड़े ऐप्लिकेशन रोके गए"</string>
- <string name="work_apps_paused_body" msgid="261634750995824906">"ऑफ़िस के काम से जुड़े आपके ऐप्लिकेशन, आपको सूचनाएं नहीं भेज सकते. साथ ही, आपकी बैटरी का इस्तेमाल या आपकी जगह की जानकारी को ऐक्सेस भी नहीं कर सकते"</string>
- <string name="work_apps_paused_content_description" msgid="5149623040804051095">"ऑफ़िस के काम से जुड़े ऐप्लिकेशन बंद हैं. ये ऐप्लिकेशन, आपको सूचनाएं नहीं भेज सकते. साथ ही, आपकी बैटरी का इस्तेमाल या आपकी जगह की जानकारी को ऐक्सेस भी नहीं कर सकते"</string>
- <string name="work_apps_paused_edu_banner" msgid="8872412121608402058">"ऑफ़िस के काम से जुड़े ऐप्लिकेशन बैज किए गए हैं और आईटी एडमिन को दिख रहे हैं"</string>
- <string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"ठीक है"</string>
- <string name="work_apps_pause_btn_text" msgid="1921059713673767460">"ऑफ़िस के काम से जुड़े ऐप्लिकेशन बंद करें"</string>
- <string name="work_apps_enable_btn_text" msgid="1156432622148413741">"ऑफ़िस के काम से जुड़े ऐप्लिकेशन चालू करें"</string>
- <string name="developer_options_filter_hint" msgid="5896817443635989056">"फ़िल्टर"</string>
+ <string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"काम से जुड़े सभी ऐप्लिकेशन यहां पाएं"</string>
+ <string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"काम से जुड़े हर ऐप्लिकेशन पर एक बैज (निशान) होता है और इन ऐप्लिकेशन की सुरक्षा आपका संगठन करता है. आसानी से इस्तेमाल करने के लिए ऐप्लिकेशन को अपनी होम स्क्रीन पर ले जाएं."</string>
+ <string name="work_mode_on_label" msgid="4781128097185272916">"आपका संगठन प्रबंधित कर रहा है"</string>
+ <string name="work_mode_off_label" msgid="3194894777601421047">"सूचनाएं और ऐप्लिकेशन बंद हैं"</string>
+ <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"बंद करें"</string>
+ <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"बंद कर दिया गया"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"पूरा नहीं हुआ: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
</resources>
diff --git a/res/values-hr/strings.xml b/res/values-hr/strings.xml
index 75e47a1fe9..b738bc0739 100644
--- a/res/values-hr/strings.xml
+++ b/res/values-hr/strings.xml
@@ -26,57 +26,32 @@
<string name="safemode_shortcut_error" msgid="9160126848219158407">"Preuzeta aplikacija onemogućena je u Sigurnom načinu rada"</string>
<string name="safemode_widget_error" msgid="4863470563535682004">"Widgeti su onemogućeni u Sigurnom načinu rada"</string>
<string name="shortcut_not_available" msgid="2536503539825726397">"Prečac nije dostupan"</string>
- <string name="home_screen" msgid="5629429142036709174">"Početni zaslon"</string>
- <string name="recent_task_option_split_screen" msgid="6690461455618725183">"Podijeljeni zaslon"</string>
- <string name="split_screen_position_top" msgid="1504965011158689649">"Podijeli gore"</string>
- <string name="split_screen_position_left" msgid="7537793098851830883">"Podijeli lijevo"</string>
- <string name="split_screen_position_right" msgid="1569377524925193369">"Podijeli desno"</string>
- <string name="split_app_info_accessibility" msgid="5475288491241414932">"Informacije o aplikaciji %1$s"</string>
- <string name="long_press_widget_to_add" msgid="3587712543577675817">"Dodirnite i zadržite da biste premjestili widget."</string>
- <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Dvaput dodirnite i zadržite pritisak da biste premjestili widget ili upotrijebite prilagođene radnje"</string>
+ <string name="home_screen" msgid="806512411299847073">"Početni zaslon"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"Prilagođene radnje"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"Dodirnite i držite kako biste podigli widget."</string>
+ <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Dodirnite dvaput i držite kako biste podigli widget ili pokušajte prilagođenim radnjama."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d širine i %2$d visine"</string>
- <string name="widget_preview_context_description" msgid="9045841361655787574">"Widget <xliff:g id="WIDGET_NAME">%1$s</xliff:g>"</string>
- <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Dodirnite i zadržite widget da biste ga pomicali po početnom zaslonu"</string>
- <string name="add_to_home_screen" msgid="8631549138215492708">"Dodaj na početni zaslon"</string>
- <string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"Widget <xliff:g id="WIDGET_NAME">%1$s</xliff:g> dodan je na početni zaslon"</string>
- <string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# widget}one{# widget}few{# widgeta}other{# widgeta}}"</string>
- <string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{# prečac}one{# prečac}few{# prečaca}other{# prečaca}}"</string>
- <string name="widgets_and_shortcuts_count" msgid="7209136747878365116">"<xliff:g id="WIDGETS_COUNT">%1$s</xliff:g>, <xliff:g id="SHORTCUTS_COUNT">%2$s</xliff:g>"</string>
- <string name="widget_button_text" msgid="2880537293434387943">"Widgeti"</string>
- <string name="widgets_full_sheet_search_bar_hint" msgid="8484659090860596457">"Pretražite"</string>
- <string name="widgets_full_sheet_cancel_button_description" msgid="5766167035728653605">"Izbrišite tekst iz okvira za pretraživanje"</string>
- <string name="no_widgets_available" msgid="4337693382501046170">"Widgeti i prečaci nisu dostupni"</string>
- <string name="no_search_results" msgid="3787956167293097509">"Nema widgeta ili prečaca"</string>
- <string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Osobni"</string>
- <string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Posao"</string>
- <string name="widget_category_conversations" msgid="8894438636213590446">"Razgovori"</string>
- <string name="widget_education_header" msgid="4874760613775913787">"Korisne informacije nadohvat ruke"</string>
- <string name="widget_education_content" msgid="745542879510751525">"Da biste dobili informacije bez otvaranja aplikacija, možete dodati widgete na početni zaslon"</string>
- <string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Dodirnite da biste promijenili postavke widgeta"</string>
- <string name="widget_education_close_button" msgid="8676165703104836580">"Shvaćam"</string>
- <string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Promijenite postavke widgeta"</string>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Dodirnite i zadržite stavku da biste je postavili ručno"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"Dodaj automatski"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Pretraži aplikacije"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Učitavanje aplikacija…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"Nema aplikacija podudarnih s upitom \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
<string name="all_apps_search_market_message" msgid="1366263386197059176">"Traži više aplikacija"</string>
<string name="label_application" msgid="8531721983832654978">"Aplikacija"</string>
- <string name="all_apps_label" msgid="5015784846527570951">"Sve aplikacije"</string>
<string name="notifications_header" msgid="1404149926117359025">"Obavijesti"</string>
- <string name="long_press_shortcut_to_add" msgid="5405328730817637737">"Dodirnite i zadržite da biste premjestili prečac."</string>
- <string name="long_accessible_way_to_add_shortcut" msgid="2199537273817090740">"Dvaput dodirnite i zadržite pritisak da biste premjestili prečac ili upotrijebite prilagođene radnje."</string>
- <string name="out_of_space" msgid="6692471482459245734">"Na ovom početnom zaslonu više nema mjesta"</string>
+ <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"Dodirnite i zadržite kako biste podigli prečac."</string>
+ <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"Dvaput dodirnite i zadržite pritisak kako biste podigli prečac ili pokušajte prilagođenim radnjama."</string>
+ <string name="out_of_space" msgid="4691004494942118364">"Na ovom početnom zaslonu više nema mjesta."</string>
<string name="hotseat_out_of_space" msgid="7448809638125333693">"Nema više prostora na traci Favoriti"</string>
<string name="all_apps_button_label" msgid="8130441508702294465">"Popis aplikacija"</string>
- <string name="all_apps_search_results" msgid="5889367432531296759">"Rezultati pretraživanja"</string>
<string name="all_apps_button_personal_label" msgid="1315764287305224468">"Popis osobnih aplikacija"</string>
<string name="all_apps_button_work_label" msgid="7270707118948892488">"Popis radnih aplikacija"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"Početna"</string>
<string name="remove_drop_target_label" msgid="7812859488053230776">"Ukloni"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"Deinstaliraj"</string>
- <string name="app_info_drop_target_label" msgid="692894985365717661">"Podaci o aplikaciji"</string>
+ <string name="app_info_drop_target_label" msgid="692894985365717661">"Info o aplikaciji"</string>
<string name="install_drop_target_label" msgid="2539096853673231757">"Instaliraj"</string>
- <string name="dismiss_prediction_label" msgid="3357562989568808658">"Ne predlaži aplikaciju"</string>
- <string name="pin_prediction" msgid="4196423321649756498">"Prikvači predviđenu apl."</string>
<string name="permlab_install_shortcut" msgid="5632423390354674437">"instaliranje prečaca"</string>
<string name="permdesc_install_shortcut" msgid="923466509822011139">"Aplikaciji omogućuje dodavanje prečaca bez intervencije korisnika."</string>
<string name="permlab_read_settings" msgid="1941457408239617576">"čitanje postavki početnog zaslona i prečaca"</string>
@@ -84,13 +59,16 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"pisanje postavki početnog zaslona i prečaca"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"Aplikaciji omogućuje promjenu postavki i prečaca na početnom zaslonu."</string>
<string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> nema dopuštenje za telefonske pozive"</string>
- <string name="gadget_error_text" msgid="740356548025791839">"Widget se ne može učitati"</string>
- <string name="gadget_setup_text" msgid="8348374825537681407">"Postavke widgeta"</string>
- <string name="gadget_complete_setup_text" msgid="309040266978007925">"Dodirnite da biste dovršili postavljanje"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"Problem pri učitavanju widgeta"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"Postavljanje"</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"Ovo je aplikacija sustava i ne može se ukloniti."</string>
- <string name="folder_hint_text" msgid="5174843001373488816">"Uređivanje naziva"</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"Neimenovana mapa"</string>
<string name="disabled_app_label" msgid="6673129024321402780">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> onemogućena"</string>
- <string name="dotted_app_label" msgid="1704091277755818896">"{count,plural,offset:1 =1{Aplikacija {app_name} ima # obavijest}one{Aplikacija {app_name} ima # obavijest}few{Aplikacija {app_name} ima # obavijesti}other{Aplikacija {app_name} ima # obavijesti}}"</string>
+ <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+ <item quantity="one"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, ima <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> obavijest</item>
+ <item quantity="few"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, ima <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> obavijesti</item>
+ <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, ima <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> obavijesti</item>
+ </plurals>
<string name="default_scroll_format" msgid="7475544710230993317">"Stranica %1$d od %2$d"</string>
<string name="workspace_scroll_format" msgid="8458889198184077399">"Početni zaslon %1$d od %2$d"</string>
<string name="workspace_new_page" msgid="257366611030256142">"Nova stranica početnog zaslona"</string>
@@ -99,10 +77,10 @@
<string name="folder_tap_to_rename" msgid="4017685068016979677">"Dodirnite da biste spremili promijenjeni naziv"</string>
<string name="folder_closed" msgid="4100806530910930934">"Mapa je zatvorena"</string>
<string name="folder_renamed" msgid="1794088362165669656">"Mapa je preimenovana u <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="folder_name_format_exact" msgid="8626242716117004803">"Mapa: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> stavke"</string>
- <string name="folder_name_format_overflow" msgid="4270108890534995199">"Mapa: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> ili više stavki"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"Mapa: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"Widgeti"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Pozadine"</string>
- <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Pozadina i stil"</string>
+ <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Stilovi i pozadine"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Postavke početnog zaslona"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Onemogućio administrator"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Dopusti zakretanje početnog zaslona"</string>
@@ -114,16 +92,16 @@
<string name="msg_missing_notification_access" msgid="281113995110910548">"Za prikaz točaka obavijesti uključite obavijesti aplikacije <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="title_change_settings" msgid="1376365968844349552">"Promjena postavki"</string>
<string name="notification_dots_service_title" msgid="4284221181793592871">"Prikaži točke obavijesti"</string>
- <string name="auto_add_shortcuts_label" msgid="3698776050751790653">"Dodaj ikone aplikacija na početni zaslon"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Dodaj ikonu na početni zaslon"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Za nove aplikacije"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"Nepoznato"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"Ukloni"</string>
<string name="abandoned_search" msgid="891119232568284442">"Traži"</string>
<string name="abandoned_promises_title" msgid="7096178467971716750">"Ta aplikacija nije instalirana"</string>
<string name="abandoned_promise_explanation" msgid="3990027586878167529">"Aplikacija ove ikone nije instalirana. Možete je ukloniti ili potražiti aplikaciju i instalirati je ručno."</string>
- <string name="app_installing_title" msgid="5864044122733792085">"Instaliranje aplikacije <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="PROGRESS">%2$s</xliff:g> dovršeno"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"Preuzimanje aplikacije <xliff:g id="NAME">%1$s</xliff:g>, dovršeno <xliff:g id="PROGRESS">%2$s</xliff:g>"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"Čekanje na instaliranje aplikacije <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"<xliff:g id="NAME">%1$s</xliff:g> widgeti"</string>
<string name="widgets_list" msgid="796804551140113767">"Popis widgeta"</string>
<string name="widgets_list_closed" msgid="6141506579418771922">"Popis widgeta zatvoren"</string>
<string name="action_add_to_workspace" msgid="8902165848117513641">"Dodavanje na početni zaslon"</string>
@@ -151,20 +129,15 @@
<string name="action_deep_shortcut" msgid="2864038805849372848">"Prečaci"</string>
<string name="shortcuts_menu_with_notifications_description" msgid="2676582286544232849">"Prečaci i obavijesti"</string>
<string name="action_dismiss_notification" msgid="5909461085055959187">"Odbaci"</string>
- <string name="accessibility_close" msgid="2277148124685870734">"Zatvori"</string>
<string name="notification_dismissed" msgid="6002233469409822874">"Obavijest je odbačena"</string>
<string name="all_apps_personal_tab" msgid="4190252696685155002">"Osobno"</string>
<string name="all_apps_work_tab" msgid="4884822796154055118">"Posao"</string>
- <string name="work_profile_toggle_label" msgid="3081029915775481146">"Poslovni profil"</string>
- <string name="work_profile_edu_work_apps" msgid="7895468576497746520">"Poslovne su aplikacije označene i vidljive vašem IT administratoru"</string>
- <string name="work_profile_edu_accept" msgid="6069788082535149071">"Shvaćam"</string>
- <string name="work_apps_paused_title" msgid="3040901117349444598">"Poslovne aplikacije su pauzirane"</string>
- <string name="work_apps_paused_body" msgid="261634750995824906">"Poslovne aplikacije ne mogu vam slati obavijesti, trošiti bateriju ili pristupati vašoj lokaciji"</string>
- <string name="work_apps_paused_content_description" msgid="5149623040804051095">"Poslovne aplikacije su isključene. Ne mogu vam slati obavijesti, trošiti bateriju ili pristupati vašoj lokaciji"</string>
- <string name="work_apps_paused_edu_banner" msgid="8872412121608402058">"Poslovne su aplikacije označene i vidljive vašem IT administratoru"</string>
- <string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"Shvaćam"</string>
- <string name="work_apps_pause_btn_text" msgid="1921059713673767460">"Isključite poslovne aplikacije"</string>
- <string name="work_apps_enable_btn_text" msgid="1156432622148413741">"Uključite poslovne aplikacije"</string>
- <string name="developer_options_filter_hint" msgid="5896817443635989056">"Filtrirajte"</string>
+ <string name="work_profile_toggle_label" msgid="3081029915775481146">"Radni profil"</string>
+ <string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"Ovdje možete pronaći radne aplikacije"</string>
+ <string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"Svaka radna aplikacija ima značku i štiti je vaša organizacija. Premjestite aplikacije na početni zaslon radi lakšeg pristupa."</string>
+ <string name="work_mode_on_label" msgid="4781128097185272916">"Pod upravljanjem vaše organizacije"</string>
+ <string name="work_mode_off_label" msgid="3194894777601421047">"Obavijesti i aplikacije isključeni su"</string>
+ <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Zatvori"</string>
+ <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Zatvoreno"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Nije uspjelo: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
</resources>
diff --git a/res/values-hu/strings.xml b/res/values-hu/strings.xml
index 71a8d69887..3327590a45 100644
--- a/res/values-hu/strings.xml
+++ b/res/values-hu/strings.xml
@@ -20,63 +20,39 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="649227358658669779">"Launcher3"</string>
+ <string name="folder_name" msgid="7371454440695724752"></string>
<string name="work_folder_name" msgid="3753320833950115786">"Munka"</string>
<string name="activity_not_found" msgid="8071924732094499514">"Az alkalmazás nincs telepítve."</string>
<string name="activity_not_available" msgid="7456344436509528827">"Az alkalmazás nem érhető el"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"A letöltött alkalmazás Csökkentett módban ki van kapcsolva"</string>
<string name="safemode_widget_error" msgid="4863470563535682004">"A modulok ki vannak kapcsolva Csökkentett módban"</string>
<string name="shortcut_not_available" msgid="2536503539825726397">"A gyorsparancs nem áll rendelkezésre"</string>
- <string name="home_screen" msgid="5629429142036709174">"Kezdőképernyő"</string>
- <string name="recent_task_option_split_screen" msgid="6690461455618725183">"Osztott képernyő"</string>
- <string name="split_screen_position_top" msgid="1504965011158689649">"Osztás a képernyő tetején"</string>
- <string name="split_screen_position_left" msgid="7537793098851830883">"Osztás a képernyő bal oldalán"</string>
- <string name="split_screen_position_right" msgid="1569377524925193369">"Osztás a képernyő jobb oldalán"</string>
- <string name="split_app_info_accessibility" msgid="5475288491241414932">"Alkalmazásinformáció a következőhöz: %1$s"</string>
- <string name="long_press_widget_to_add" msgid="3587712543577675817">"Tartsa lenyomva a modult az áthelyezéshez."</string>
- <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Modul áthelyezéséhez koppintson duplán, tartsa nyomva az ujját, vagy használjon egyéni műveleteket."</string>
+ <string name="home_screen" msgid="806512411299847073">"Kezdőképernyő"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"Egyéni műveletek"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"Modul felvételéhez érintse meg, és tartsa lenyomva"</string>
+ <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Modul mozgatásához koppintson rá duplán és tartsa lenyomva, vagy használjon egyéni műveleteket."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d széles és %2$d magas"</string>
- <string name="widget_preview_context_description" msgid="9045841361655787574">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g> modul"</string>
- <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Tartsa lenyomva a modult a kezdőképernyőn való mozgatáshoz"</string>
- <string name="add_to_home_screen" msgid="8631549138215492708">"Hozzáadás a kezdőképernyőhöz"</string>
- <string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g> modul hozzáadva a kezdőképernyőhöz"</string>
- <string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# modul}other{# modul}}"</string>
- <string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{# gyorsparancs}other{# gyorsparancs}}"</string>
- <string name="widgets_and_shortcuts_count" msgid="7209136747878365116">"<xliff:g id="WIDGETS_COUNT">%1$s</xliff:g>, <xliff:g id="SHORTCUTS_COUNT">%2$s</xliff:g>"</string>
- <string name="widget_button_text" msgid="2880537293434387943">"Modulok"</string>
- <string name="widgets_full_sheet_search_bar_hint" msgid="8484659090860596457">"Keresés"</string>
- <string name="widgets_full_sheet_cancel_button_description" msgid="5766167035728653605">"Keresőmezőben lévő szöveg törlése"</string>
- <string name="no_widgets_available" msgid="4337693382501046170">"A modulok és parancsikonok nem állnak rendelkezésre"</string>
- <string name="no_search_results" msgid="3787956167293097509">"Nem található modul vagy parancsikon"</string>
- <string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Személyes"</string>
- <string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Munka"</string>
- <string name="widget_category_conversations" msgid="8894438636213590446">"Beszélgetések"</string>
- <string name="widget_education_header" msgid="4874760613775913787">"Hasznos információk egy koppintásnyira"</string>
- <string name="widget_education_content" msgid="745542879510751525">"Ha az alkalmazások megnyitása nélkül szeretne információhoz jutni, felvehet modulokat a kezdőképernyőre."</string>
- <string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Ide koppintva módosíthatja a modulbeállításokat"</string>
- <string name="widget_education_close_button" msgid="8676165703104836580">"Értem"</string>
- <string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"A modulbeállítások módosítása"</string>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Tartsa lenyomva a manuális hozzáadáshoz"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"Automatikus hozzáadás"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Alkalmazások keresése"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Alkalmazások betöltése…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"Nem található alkalmazás a(z) „<xliff:g id="QUERY">%1$s</xliff:g>” lekérdezésre"</string>
<string name="all_apps_search_market_message" msgid="1366263386197059176">"További alkalmazások keresése"</string>
<string name="label_application" msgid="8531721983832654978">"Alkalmazás"</string>
- <string name="all_apps_label" msgid="5015784846527570951">"Összes alkalmazás"</string>
<string name="notifications_header" msgid="1404149926117359025">"Értesítések"</string>
- <string name="long_press_shortcut_to_add" msgid="5405328730817637737">"Tartsa lenyomva a parancsikont az áthelyezéshez."</string>
- <string name="long_accessible_way_to_add_shortcut" msgid="2199537273817090740">"Parancsikon áthelyezéséhez koppintson duplán, és tartsa nyomva az ujját, vagy használjon egyéni műveleteket."</string>
- <string name="out_of_space" msgid="6692471482459245734">"Nincs több hely ezen a kezdőképernyőn"</string>
+ <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"Felvételhez tartsa nyomva a parancsikont."</string>
+ <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"Parancsikon felvételéhez koppintson rá duplán és tartsa nyomva, vagy használjon egyéni műveleteket."</string>
+ <string name="out_of_space" msgid="4691004494942118364">"Nincs több hely ezen a kezdőképernyőn."</string>
<string name="hotseat_out_of_space" msgid="7448809638125333693">"Nincs több hely a Kedvencek tálcán"</string>
<string name="all_apps_button_label" msgid="8130441508702294465">"Alkalmazások listája"</string>
- <string name="all_apps_search_results" msgid="5889367432531296759">"Keresési találatok"</string>
<string name="all_apps_button_personal_label" msgid="1315764287305224468">"Személyes alkalmazások listája"</string>
<string name="all_apps_button_work_label" msgid="7270707118948892488">"Munkahelyi alkalmazások listája"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"Főoldal"</string>
<string name="remove_drop_target_label" msgid="7812859488053230776">"Törlés"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"Eltávolítás"</string>
- <string name="app_info_drop_target_label" msgid="692894985365717661">"Alkalmazásinfó"</string>
+ <string name="app_info_drop_target_label" msgid="692894985365717661">"Alkalmazásinformáció"</string>
<string name="install_drop_target_label" msgid="2539096853673231757">"Telepítés"</string>
- <string name="dismiss_prediction_label" msgid="3357562989568808658">"Ne javasoljon alkalmazást"</string>
- <string name="pin_prediction" msgid="4196423321649756498">"Várható kitűzése"</string>
<string name="permlab_install_shortcut" msgid="5632423390354674437">"parancsikonok telepítése"</string>
<string name="permdesc_install_shortcut" msgid="923466509822011139">"Lehetővé teszi egy alkalmazás számára, hogy felhasználói beavatkozás nélkül adjon hozzá parancsikonokat."</string>
<string name="permlab_read_settings" msgid="1941457408239617576">"Főoldal beállításainak és parancsikonjainak beolvasása"</string>
@@ -84,13 +60,15 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"Főoldal beállításainak és parancsikonjainak írása"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"Lehetővé teszi az alkalmazás számára, hogy módosítsa a kezdőképernyő beállításait és parancsikonjait."</string>
<string name="msg_no_phone_permission" msgid="9208659281529857371">"A(z) <xliff:g id="APP_NAME">%1$s</xliff:g> nem kezdeményezhet telefonhívásokat"</string>
- <string name="gadget_error_text" msgid="740356548025791839">"Nem tölthető le a modul"</string>
- <string name="gadget_setup_text" msgid="8348374825537681407">"Modulbeállítások"</string>
- <string name="gadget_complete_setup_text" msgid="309040266978007925">"Koppintson a beállítás befejezéséhez"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"Probléma történt a modul betöltésekor"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"Beállítás"</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"Ez egy rendszeralkalmazás, és nem lehet eltávolítani."</string>
- <string name="folder_hint_text" msgid="5174843001373488816">"Név módosítása"</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"Névtelen mappa"</string>
<string name="disabled_app_label" msgid="6673129024321402780">"A(z) <xliff:g id="APP_NAME">%1$s</xliff:g> letiltva"</string>
- <string name="dotted_app_label" msgid="1704091277755818896">"{count,plural,offset:1 =1{A(z) {app_name} # értesítéssel rendelkezik}other{A(z) {app_name} # értesítéssel rendelkezik}}"</string>
+ <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+ <item quantity="other">A(z) <xliff:g id="APP_NAME_2">%1$s</xliff:g> <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> értesítéssel rendelkezik</item>
+ <item quantity="one">A(z) <xliff:g id="APP_NAME_0">%1$s</xliff:g> <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> értesítéssel rendelkezik</item>
+ </plurals>
<string name="default_scroll_format" msgid="7475544710230993317">"%2$d/%1$d. oldal"</string>
<string name="workspace_scroll_format" msgid="8458889198184077399">"%2$d/%1$d. kezdőképernyő"</string>
<string name="workspace_new_page" msgid="257366611030256142">"Új kezdőképernyő oldal"</string>
@@ -99,11 +77,11 @@
<string name="folder_tap_to_rename" msgid="4017685068016979677">"Koppintson ide az átnevezés mentéséhez"</string>
<string name="folder_closed" msgid="4100806530910930934">"Mappa lezárva"</string>
<string name="folder_renamed" msgid="1794088362165669656">"A mappa új neve: <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="folder_name_format_exact" msgid="8626242716117004803">"Mappa: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> elem"</string>
- <string name="folder_name_format_overflow" msgid="4270108890534995199">"Mappa: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> vagy több elem"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"Mappa: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"Modulok"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Háttérképek"</string>
- <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Háttérkép és stílus"</string>
- <string name="settings_button_text" msgid="8873672322605444408">"Kezdőképernyő beállításai"</string>
+ <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Stílusok és háttérképek"</string>
+ <string name="settings_button_text" msgid="8873672322605444408">"Kezdőoldal beállításai"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"A rendszergazda letiltotta"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"A kezdőképernyő elforgatásának engedélyezése"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"A telefon elforgatásakor"</string>
@@ -114,16 +92,16 @@
<string name="msg_missing_notification_access" msgid="281113995110910548">"Az értesítési pöttyök megjelenítéséhez kapcsolja be a(z) <xliff:g id="NAME">%1$s</xliff:g> alkalmazás értesítéseit"</string>
<string name="title_change_settings" msgid="1376365968844349552">"Beállítások módosítása"</string>
<string name="notification_dots_service_title" msgid="4284221181793592871">"Értesítési pöttyök megjelenítése"</string>
- <string name="auto_add_shortcuts_label" msgid="3698776050751790653">"Appikonok hozzáadása a kezdőképernyőhöz"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Ikon hozzáadása a kezdőképernyőhöz"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Új alkalmazásoknál"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"Ismeretlen"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"Törlés"</string>
<string name="abandoned_search" msgid="891119232568284442">"Keresés"</string>
<string name="abandoned_promises_title" msgid="7096178467971716750">"Az alkalmazás nincs telepítve"</string>
<string name="abandoned_promise_explanation" msgid="3990027586878167529">"Az ikonhoz tartozó alkalmazás nincs telepítve. Törölheti az ikont, vagy az alkalmazás megkeresése után manuálisan telepítheti azt."</string>
- <string name="app_installing_title" msgid="5864044122733792085">"Folyamatban van a(z) <xliff:g id="NAME">%1$s</xliff:g> telepítése, <xliff:g id="PROGRESS">%2$s</xliff:g> kész"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"A(z) <xliff:g id="NAME">%1$s</xliff:g> letöltése, <xliff:g id="PROGRESS">%2$s</xliff:g> kész"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"A(z) <xliff:g id="NAME">%1$s</xliff:g> telepítésre vár"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"<xliff:g id="NAME">%1$s</xliff:g>-modulok"</string>
<string name="widgets_list" msgid="796804551140113767">"Widgetlista"</string>
<string name="widgets_list_closed" msgid="6141506579418771922">"Widgetlista bezárva"</string>
<string name="action_add_to_workspace" msgid="8902165848117513641">"Hozzáadás a kezdőképernyőhöz"</string>
@@ -151,20 +129,15 @@
<string name="action_deep_shortcut" msgid="2864038805849372848">"Gyorsparancsok"</string>
<string name="shortcuts_menu_with_notifications_description" msgid="2676582286544232849">"Parancsikonok és értesítések"</string>
<string name="action_dismiss_notification" msgid="5909461085055959187">"Elvetés"</string>
- <string name="accessibility_close" msgid="2277148124685870734">"Bezárás"</string>
<string name="notification_dismissed" msgid="6002233469409822874">"Értesítés elvetve"</string>
<string name="all_apps_personal_tab" msgid="4190252696685155002">"Személyes"</string>
<string name="all_apps_work_tab" msgid="4884822796154055118">"Munkahelyi"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"Munkaprofil"</string>
- <string name="work_profile_edu_work_apps" msgid="7895468576497746520">"A munkahelyi alkalmazások jelvénnyel vannak megjelölve, és láthatók a rendszergazda számára"</string>
- <string name="work_profile_edu_accept" msgid="6069788082535149071">"Értem"</string>
- <string name="work_apps_paused_title" msgid="3040901117349444598">"A munkahelyi alkalmazások szüneteltetve vannak"</string>
- <string name="work_apps_paused_body" msgid="261634750995824906">"A munkahelyi alkalmazások nem küldhetnek Önnek értesítéseket, nem használhatják az akkumulátorát, és nem férhetnek hozzá a tartózkodási helyéhez."</string>
- <string name="work_apps_paused_content_description" msgid="5149623040804051095">"A munkahelyi alkalmazások nem küldhetnek Önnek értesítéseket, nem használhatják az akkumulátorát, és nem férhetnek hozzá a tartózkodási helyéhez"</string>
- <string name="work_apps_paused_edu_banner" msgid="8872412121608402058">"A munkahelyi alkalmazások jelvénnyel vannak megjelölve, és láthatók a rendszergazda számára"</string>
- <string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"Értem"</string>
- <string name="work_apps_pause_btn_text" msgid="1921059713673767460">"Kapcsolja ki a munkahelyi alkalmazásokat"</string>
- <string name="work_apps_enable_btn_text" msgid="1156432622148413741">"Munkahelyi alkalmazások bekapcsolása"</string>
- <string name="developer_options_filter_hint" msgid="5896817443635989056">"Szűrő"</string>
+ <string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"Itt kereshet munkahelyi alkalmazásokat"</string>
+ <string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"A munkahelyi alkalmazásoknál jelvény található, és biztonságukról az Ön szervezete gondoskodik. A könnyebb hozzáférés érdekében helyezze át az alkalmazásokat a kezdőképernyőre."</string>
+ <string name="work_mode_on_label" msgid="4781128097185272916">"Az Ön szervezete kezeli"</string>
+ <string name="work_mode_off_label" msgid="3194894777601421047">"Az értesítések és az alkalmazások ki vannak kapcsolva"</string>
+ <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Bezárás"</string>
+ <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Bezárva"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Sikertelen: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
</resources>
diff --git a/res/values-hy/strings.xml b/res/values-hy/strings.xml
index 3d65a3ed07..93404e6f5f 100644
--- a/res/values-hy/strings.xml
+++ b/res/values-hy/strings.xml
@@ -26,71 +26,48 @@
<string name="safemode_shortcut_error" msgid="9160126848219158407">"Ներբեռնված ծրագիրն անջատված է Անվտանգ ռեժիմում"</string>
<string name="safemode_widget_error" msgid="4863470563535682004">"Վիջեթներն անջատված են անվտանգ ռեժիմում"</string>
<string name="shortcut_not_available" msgid="2536503539825726397">"Դյուրանցումն անհասանելի է"</string>
- <string name="home_screen" msgid="5629429142036709174">"Հիմնական էկրան"</string>
- <string name="recent_task_option_split_screen" msgid="6690461455618725183">"Տրոհել էկրանը"</string>
- <string name="split_screen_position_top" msgid="1504965011158689649">"Հավելվածը վերևում"</string>
- <string name="split_screen_position_left" msgid="7537793098851830883">"Հավելվածը ձախ կողմում"</string>
- <string name="split_screen_position_right" msgid="1569377524925193369">"Հավելվածը աջ կողմում"</string>
- <string name="split_app_info_accessibility" msgid="5475288491241414932">"Տեղեկություններ %1$s հավելվածի մասին"</string>
- <string name="long_press_widget_to_add" msgid="3587712543577675817">"Հպեք և պահեք՝ վիջեթ տեղափոխելու համար։"</string>
- <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Կրկնակի հպեք և պահեք՝ վիջեթ տեղափոխելու համար, կամ օգտվեք հատուկ գործողություններից։"</string>
+ <string name="home_screen" msgid="806512411299847073">"Հիմնական էկրան"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"Հատուկ գործողություններ"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"Հպեք և պահեք՝ վիջեթն ընտրելու համար:"</string>
+ <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Կրկնակի հպեք և պահեք՝ վիջեթ ավելացնելու համար կամ օգտվեք հարմարեցրած գործողություններից:"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"Լայնությունը՝ %1$d, բարձրությունը՝ %2$d"</string>
- <string name="widget_preview_context_description" msgid="9045841361655787574">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g> վիջեթ"</string>
- <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Հպեք վիջեթին և պահեք տեղափոխելու համար"</string>
- <string name="add_to_home_screen" msgid="8631549138215492708">"Ավելացնել հիմնական էկրանին"</string>
- <string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g> վիջեթն ավելացվել է հիմնական էկրանին"</string>
- <string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# վիջեթ}one{# վիջեթ}other{# վիջեթ}}"</string>
- <string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{# դյուրանցում}one{# դյուրանցում}other{# դյուրանցում}}"</string>
- <string name="widgets_and_shortcuts_count" msgid="7209136747878365116">"<xliff:g id="WIDGETS_COUNT">%1$s</xliff:g>, <xliff:g id="SHORTCUTS_COUNT">%2$s</xliff:g>"</string>
- <string name="widget_button_text" msgid="2880537293434387943">"Վիջեթներ"</string>
- <string name="widgets_full_sheet_search_bar_hint" msgid="8484659090860596457">"Որոնեք"</string>
- <string name="widgets_full_sheet_cancel_button_description" msgid="5766167035728653605">"Մաքրել որոնման դաշտի տեքստը"</string>
- <string name="no_widgets_available" msgid="4337693382501046170">"Հասանելի վիջեթներ և դյուրանցումներ չկան"</string>
- <string name="no_search_results" msgid="3787956167293097509">"Ոչ մի վիջեթ կամ դյուրանցում չի գտնվել"</string>
- <string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Անձնական"</string>
- <string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Աշխատանքային"</string>
- <string name="widget_category_conversations" msgid="8894438636213590446">"Զրույցներ"</string>
- <string name="widget_education_header" msgid="4874760613775913787">"Բոլոր կարևոր տեղեկությունները՝ ձեռքի տակ"</string>
- <string name="widget_education_content" msgid="745542879510751525">"Առանց հավելվածները բացելու տեղեկություններ ստանալու համար ձեր հիմնական էկրանին ավելացրեք վիջեթներ։"</string>
- <string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Հպեք՝ վիջեթի կարգավորումները փոփոխելու համար"</string>
- <string name="widget_education_close_button" msgid="8676165703104836580">"Եղավ"</string>
- <string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Փոխել վիջեթի կարգավորումները"</string>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Հպեք և պահեք՝ ձեռքով տեղադրելու համար"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"Ավելացնել ավտոմատ կերպով"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Որոնել հավելվածներ"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Հավելվածների բեռնում…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"«<xliff:g id="QUERY">%1$s</xliff:g>» հարցմանը համապատասխանող հավելվածներ չեն գտնվել"</string>
<string name="all_apps_search_market_message" msgid="1366263386197059176">"Որոնել այլ հավելվածներ"</string>
<string name="label_application" msgid="8531721983832654978">"Հավելված"</string>
- <string name="all_apps_label" msgid="5015784846527570951">"Բոլոր հավելվածները"</string>
<string name="notifications_header" msgid="1404149926117359025">"Ծանուցումներ"</string>
- <string name="long_press_shortcut_to_add" msgid="5405328730817637737">"Հպեք և պահեք՝ դյուրանցում տեղափոխելու համար։"</string>
- <string name="long_accessible_way_to_add_shortcut" msgid="2199537273817090740">"Կրկնակի հպեք և պահեք՝ դյուրանցում տեղափոխելու համար, կամ օգտվեք հատուկ գործողություններից։"</string>
- <string name="out_of_space" msgid="6692471482459245734">"Հիմնական էկրանին ազատ տեղ չկա"</string>
+ <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"Կրկնակի հպեք և պահեք՝ դյուրանցում ընտրելու համար։"</string>
+ <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"Կրկնակի հպեք և պահեք՝ դյուրանցում ընտրելու համար կամ օգտվեք հարմարեցրած գործողություններից:"</string>
+ <string name="out_of_space" msgid="4691004494942118364">"Այլևս տեղ չկա այս հիմնական էկրանին:"</string>
<string name="hotseat_out_of_space" msgid="7448809638125333693">"Ընտրյալների ցուցակում այլևս ազատ տեղ չկա"</string>
<string name="all_apps_button_label" msgid="8130441508702294465">"Հավելվածների ցանկ"</string>
- <string name="all_apps_search_results" msgid="5889367432531296759">"Որոնման արդյունքներ"</string>
<string name="all_apps_button_personal_label" msgid="1315764287305224468">"Անձնական հավելվածների ցանկ"</string>
<string name="all_apps_button_work_label" msgid="7270707118948892488">"Աշխատանքային հավելվածների ցանկ"</string>
- <string name="remove_drop_target_label" msgid="7812859488053230776">"Հեռացնել"</string>
- <string name="uninstall_drop_target_label" msgid="4722034217958379417">"Ապատեղադրել"</string>
- <string name="app_info_drop_target_label" msgid="692894985365717661">"Հավելվածի մասին"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"Հիմնական"</string>
+ <string name="remove_drop_target_label" msgid="7812859488053230776">"Ապատեղադրել"</string>
+ <string name="uninstall_drop_target_label" msgid="4722034217958379417">"Հեռացնել"</string>
+ <string name="app_info_drop_target_label" msgid="692894985365717661">"Հավելվածի տվյալներ"</string>
<string name="install_drop_target_label" msgid="2539096853673231757">"Տեղադրել"</string>
- <string name="dismiss_prediction_label" msgid="3357562989568808658">"Թաքցնել առաջարկը"</string>
- <string name="pin_prediction" msgid="4196423321649756498">"Ամրացնել առաջարկվող հավելվածը"</string>
- <string name="permlab_install_shortcut" msgid="5632423390354674437">"Դյուրանցումների տեղադրում"</string>
+ <string name="permlab_install_shortcut" msgid="5632423390354674437">"տեղադրել դյուրանցումներ"</string>
<string name="permdesc_install_shortcut" msgid="923466509822011139">"Ծրագրին թույլ է տալիս ավելացնել դյուրանցումներ՝ առանց օգտագործողի միջամտության:"</string>
<string name="permlab_read_settings" msgid="1941457408239617576">"կարդալ հիմնաէջի կարգավորումներն ու դյուրանցումները"</string>
<string name="permdesc_read_settings" msgid="5833423719057558387">"Ծրագրին թույլ է տալիս կարդալ հիմնաէջի կարգավորումներն ու դյուրանցումները:"</string>
<string name="permlab_write_settings" msgid="3574213698004620587">"ստեղծել հիմնաէջի կարգավորումներ ու դյուրանցումներ"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"Ծրագրին թույլ է տալիս փոփոխել հիմնաէջի կարգավորումներն ու դյուրանցումները:"</string>
<string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> հավելվածին չի թույլատրվում հեռախոսազանգեր կատարել"</string>
- <string name="gadget_error_text" msgid="740356548025791839">"Չհաջողվեց բեռնել վիջեթը"</string>
- <string name="gadget_setup_text" msgid="8348374825537681407">"Վիջեթի կարգավորումներ"</string>
- <string name="gadget_complete_setup_text" msgid="309040266978007925">"Հպեք՝ կարգավորումն ավարտելու համար"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"Վիջեթի բեռնման խնդիր կա"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"Կարգավորում"</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"Սա համակարգային ծրագիր է և չի կարող ապատեղադրվել:"</string>
- <string name="folder_hint_text" msgid="5174843001373488816">"Փոխել անունը"</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"Անանուն պանակ"</string>
<string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> հավելվածն անջատված է"</string>
- <string name="dotted_app_label" msgid="1704091277755818896">"{count,plural,offset:1 =1{«{app_name}» հավելվածն ունի # ծանուցում}one{«{app_name}» հավելվածն ունի # ծանուցում}other{«{app_name}» հավելվածն ունի # ծանուցում}}"</string>
+ <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+ <item quantity="one"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, ունի <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> ծանուցում</item>
+ <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, ունի <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> ծանուցում</item>
+ </plurals>
<string name="default_scroll_format" msgid="7475544710230993317">"Էջ %1$d՝ %2$d-ից"</string>
<string name="workspace_scroll_format" msgid="8458889198184077399">"Հիմնական էկրան %1$d` %2$d-ից"</string>
<string name="workspace_new_page" msgid="257366611030256142">"Հիմնական էկրանի նոր էջ"</string>
@@ -99,11 +76,11 @@
<string name="folder_tap_to_rename" msgid="4017685068016979677">"Հպեք՝ նոր անվանումը պահելու համար"</string>
<string name="folder_closed" msgid="4100806530910930934">"Պանակը փակ է"</string>
<string name="folder_renamed" msgid="1794088362165669656">"Պանակը վերանվանվեց <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="folder_name_format_exact" msgid="8626242716117004803">"Պանակ՝ <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> տարր"</string>
- <string name="folder_name_format_overflow" msgid="4270108890534995199">"Պանակ՝ <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> կամ ավելի տարրեր"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"Պանակ՝ <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"Վիջեթներ"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Պաստառներ"</string>
- <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Պաստառ և ոճ"</string>
- <string name="settings_button_text" msgid="8873672322605444408">"Գլխավոր էկրանի կարգավորումներ"</string>
+ <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Ոճեր և պաստառներ"</string>
+ <string name="settings_button_text" msgid="8873672322605444408">"Գլխավոր էջի կարգավորումներ"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Անջատվել է ձեր ադմինիստրատորի կողմից"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Թույլ տալ հիմնական էկրանի պտտումը"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Հեռախոսը պտտելու դեպքում"</string>
@@ -114,16 +91,16 @@
<string name="msg_missing_notification_access" msgid="281113995110910548">"Ծանուցումների կետիկները ցուցադրելու համար միացրեք ծանուցումները <xliff:g id="NAME">%1$s</xliff:g>-ի համար"</string>
<string name="title_change_settings" msgid="1376365968844349552">"Փոխել կարգավորումները"</string>
<string name="notification_dots_service_title" msgid="4284221181793592871">"Ցուցադրել ծանուցումների կետիկները"</string>
- <string name="auto_add_shortcuts_label" msgid="3698776050751790653">"Ավելացնել պատկերակները հիմնական էկրանին"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Ավելացնել պատկերակը Հիմնական էկրանին"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Նոր հավելվածների համար"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"Անհայտ է"</string>
- <string name="abandoned_clean_this" msgid="7610119707847920412">"Հեռացնել"</string>
+ <string name="abandoned_clean_this" msgid="7610119707847920412">"Ապատեղադրել"</string>
<string name="abandoned_search" msgid="891119232568284442">"Գտնել"</string>
<string name="abandoned_promises_title" msgid="7096178467971716750">"Այս ծրագիրը տեղադրված չէ:"</string>
<string name="abandoned_promise_explanation" msgid="3990027586878167529">"Այս պատկերակի ծրագիրը տեղադրված չէ: Դուք կարող եք հեռացնել այն կամ գտնել ծրագիրը և տեղադրել այն ձեռքով:"</string>
- <string name="app_installing_title" msgid="5864044122733792085">"<xliff:g id="NAME">%1$s</xliff:g> հավելվածը տեղադրվում է, կատարված է <xliff:g id="PROGRESS">%2$s</xliff:g>-ը"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g>–ի ներբեռնում (<xliff:g id="PROGRESS">%2$s</xliff:g>)"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g>-ի տեղադրման սպասում"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"<xliff:g id="NAME">%1$s</xliff:g> վիջեթներ"</string>
<string name="widgets_list" msgid="796804551140113767">"Վիջեթների ցանկ"</string>
<string name="widgets_list_closed" msgid="6141506579418771922">"Վիջեթների ցանկը փակվեց"</string>
<string name="action_add_to_workspace" msgid="8902165848117513641">"Ավելացնել Հիմնական էկրանին"</string>
@@ -151,20 +128,15 @@
<string name="action_deep_shortcut" msgid="2864038805849372848">"Դյուրանցումներ"</string>
<string name="shortcuts_menu_with_notifications_description" msgid="2676582286544232849">"Դյուրանցումներ և ծանուցումներ"</string>
<string name="action_dismiss_notification" msgid="5909461085055959187">"Անտեսել"</string>
- <string name="accessibility_close" msgid="2277148124685870734">"Փակել"</string>
<string name="notification_dismissed" msgid="6002233469409822874">"Ծանուցումը մերժված է"</string>
<string name="all_apps_personal_tab" msgid="4190252696685155002">"Անձնական"</string>
<string name="all_apps_work_tab" msgid="4884822796154055118">"Աշխատանքային"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"Աշխատանքային պրոֆիլ"</string>
- <string name="work_profile_edu_work_apps" msgid="7895468576497746520">"Աշխատանքային հավելվածները հատուկ նշանակ ունեն և տեսանելի են ՏՏ ադմինիստրատորին"</string>
- <string name="work_profile_edu_accept" msgid="6069788082535149071">"Եղավ"</string>
- <string name="work_apps_paused_title" msgid="3040901117349444598">"Աշխատանքային հավելվածները դադարեցված են"</string>
- <string name="work_apps_paused_body" msgid="261634750995824906">"Աշխատանքային հավելվածները չեն կարող ծանուցումներ ուղարկել ձեզ, օգտագործել մարտկոցը և ձեր տեղադրության մասին տվյալներ ստանալ։"</string>
- <string name="work_apps_paused_content_description" msgid="5149623040804051095">"Աշխատանքային հավելվածներն անջատված են։ Դրանք չեն կարող ծանուցումներ ուղարկել ձեզ, օգտագործել մարտկոցը և ձեր տեղադրության մասին տվյալներ ստանալ։"</string>
- <string name="work_apps_paused_edu_banner" msgid="8872412121608402058">"Աշխատանքային հավելվածները հատուկ նշանակ ունեն և տեսանելի են ՏՏ ադմինիստրատորին"</string>
- <string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"Եղավ"</string>
- <string name="work_apps_pause_btn_text" msgid="1921059713673767460">"Անջատել աշխատանքային հավելվածները"</string>
- <string name="work_apps_enable_btn_text" msgid="1156432622148413741">"Միացնել աշխատանքային հավելվածները"</string>
- <string name="developer_options_filter_hint" msgid="5896817443635989056">"Զտեք"</string>
+ <string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"Գտեք աշխատանքային հավելվածներ այստեղ"</string>
+ <string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"Աշխատանքային հավելվածները նշված են հատուկ նշանով: Նման հավելվածների անվտանգությունը ապահովում է ձեր կազմակերպությունը։ Հարմարության համար աշխատանքային հավելվածները կարող եք տեղափոխել հիմնական էկրան։"</string>
+ <string name="work_mode_on_label" msgid="4781128097185272916">"Կառավարվում է ձեր կազմակերպության կողմից"</string>
+ <string name="work_mode_off_label" msgid="3194894777601421047">"Ծանուցումներն ու հավելվածներն անջատված են"</string>
+ <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Փակել"</string>
+ <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Փակվեց"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Չհաջողվեց կատարել գործողությունը (<xliff:g id="WHAT">%1$s</xliff:g>)"</string>
</resources>
diff --git a/res/values-in/strings.xml b/res/values-in/strings.xml
index f1067740d8..92c7accaa8 100644
--- a/res/values-in/strings.xml
+++ b/res/values-in/strings.xml
@@ -20,63 +20,38 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="649227358658669779">"Launcher3"</string>
- <string name="work_folder_name" msgid="3753320833950115786">"Kerja"</string>
+ <string name="work_folder_name" msgid="3753320833950115786">"Kantor"</string>
<string name="activity_not_found" msgid="8071924732094499514">"Aplikasi tidak dipasang."</string>
<string name="activity_not_available" msgid="7456344436509528827">"Aplikasi tidak tersedia"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"Aplikasi yang didownload dinonaktifkan dalam mode Aman"</string>
<string name="safemode_widget_error" msgid="4863470563535682004">"Widget dinonaktifkan dalam mode Aman"</string>
<string name="shortcut_not_available" msgid="2536503539825726397">"Pintasan tidak tersedia"</string>
- <string name="home_screen" msgid="5629429142036709174">"Layar utama"</string>
- <string name="recent_task_option_split_screen" msgid="6690461455618725183">"Layar terpisah"</string>
- <string name="split_screen_position_top" msgid="1504965011158689649">"Pisahkan ke atas"</string>
- <string name="split_screen_position_left" msgid="7537793098851830883">"Pisahkan ke kiri"</string>
- <string name="split_screen_position_right" msgid="1569377524925193369">"Pisahkan ke kanan"</string>
- <string name="split_app_info_accessibility" msgid="5475288491241414932">"Info aplikasi untuk %1$s"</string>
- <string name="long_press_widget_to_add" msgid="3587712543577675817">"Sentuh lama untuk memindahkan widget."</string>
- <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Ketuk dua kali &amp; tahan untuk memindahkan widget atau gunakan tindakan khusus."</string>
+ <string name="home_screen" msgid="806512411299847073">"Layar utama"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"Tindakan khusus"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"Sentuh lama untuk memilih widget."</string>
+ <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Ketuk dua kali &amp; tahan untuk mengambil widget atau menggunakan tindakan khusus."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"lebar %1$d x tinggi %2$d"</string>
- <string name="widget_preview_context_description" msgid="9045841361655787574">"Widget <xliff:g id="WIDGET_NAME">%1$s</xliff:g>"</string>
- <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Sentuh lama widget untuk memindahkannya di sekitar Layar utama"</string>
- <string name="add_to_home_screen" msgid="8631549138215492708">"Tambahkan ke Layar utama"</string>
- <string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"Widget <xliff:g id="WIDGET_NAME">%1$s</xliff:g> ditambahkan ke layar utama"</string>
- <string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# widget}other{# widget}}"</string>
- <string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{# pintasan}other{# pintasan}}"</string>
- <string name="widgets_and_shortcuts_count" msgid="7209136747878365116">"<xliff:g id="WIDGETS_COUNT">%1$s</xliff:g>, <xliff:g id="SHORTCUTS_COUNT">%2$s</xliff:g>"</string>
- <string name="widget_button_text" msgid="2880537293434387943">"Widget"</string>
- <string name="widgets_full_sheet_search_bar_hint" msgid="8484659090860596457">"Telusuri"</string>
- <string name="widgets_full_sheet_cancel_button_description" msgid="5766167035728653605">"Hapus teks dari kotak penelusuran"</string>
- <string name="no_widgets_available" msgid="4337693382501046170">"Widget dan pintasan tidak tersedia"</string>
- <string name="no_search_results" msgid="3787956167293097509">"Tidak ada widget atau pintasan yang ditemukan"</string>
- <string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Pribadi"</string>
- <string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Kerja"</string>
- <string name="widget_category_conversations" msgid="8894438636213590446">"Percakapan"</string>
- <string name="widget_education_header" msgid="4874760613775913787">"Info bermanfaat mudah dilihat"</string>
- <string name="widget_education_content" msgid="745542879510751525">"Untuk mendapatkan info tanpa membuka aplikasi, Anda dapat menambahkan widget ke Layar utama"</string>
- <string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Ketuk untuk mengubah setelan widget"</string>
- <string name="widget_education_close_button" msgid="8676165703104836580">"Oke"</string>
- <string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Ubah setelan widget"</string>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Sentuh lama untuk menempatkan secara manual"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"Tambahkan otomatis"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Telusuri aplikasi"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Memuat aplikasi…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"Tidak ditemukan aplikasi yang cocok dengan \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
<string name="all_apps_search_market_message" msgid="1366263386197059176">"Telusuri aplikasi lainnya"</string>
<string name="label_application" msgid="8531721983832654978">"Aplikasi"</string>
- <string name="all_apps_label" msgid="5015784846527570951">"Semua aplikasi"</string>
<string name="notifications_header" msgid="1404149926117359025">"Notifikasi"</string>
- <string name="long_press_shortcut_to_add" msgid="5405328730817637737">"Sentuh lama untuk memindahkan pintasan."</string>
- <string name="long_accessible_way_to_add_shortcut" msgid="2199537273817090740">"Ketuk dua kali &amp; tahan untuk memindahkan pintasan atau gunakan tindakan khusus."</string>
- <string name="out_of_space" msgid="6692471482459245734">"Tidak ada ruang di Layar utama ini"</string>
+ <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"Sentuh lama untuk memilih pintasan."</string>
+ <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"Ketuk dua kali &amp; tahan untuk memilih pintasan atau menggunakan tindakan khusus."</string>
+ <string name="out_of_space" msgid="4691004494942118364">"Tidak ada ruang lagi pada layar Utama ini."</string>
<string name="hotseat_out_of_space" msgid="7448809638125333693">"Tidak ada ruang tersisa di baki Favorit"</string>
<string name="all_apps_button_label" msgid="8130441508702294465">"Daftar aplikasi"</string>
- <string name="all_apps_search_results" msgid="5889367432531296759">"Hasil penelusuran"</string>
<string name="all_apps_button_personal_label" msgid="1315764287305224468">"Daftar aplikasi pribadi"</string>
<string name="all_apps_button_work_label" msgid="7270707118948892488">"Daftar aplikasi kantor"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"Layar Utama"</string>
<string name="remove_drop_target_label" msgid="7812859488053230776">"Hapus"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"Uninstal"</string>
<string name="app_info_drop_target_label" msgid="692894985365717661">"Info aplikasi"</string>
<string name="install_drop_target_label" msgid="2539096853673231757">"Instal"</string>
- <string name="dismiss_prediction_label" msgid="3357562989568808658">"Jangan sarankan aplikasi"</string>
- <string name="pin_prediction" msgid="4196423321649756498">"Pin Prediksi"</string>
<string name="permlab_install_shortcut" msgid="5632423390354674437">"memasang pintasan"</string>
<string name="permdesc_install_shortcut" msgid="923466509822011139">"Mengizinkan aplikasi menambahkan pintasan tanpa campur tangan pengguna."</string>
<string name="permlab_read_settings" msgid="1941457408239617576">"membaca setelan dan pintasan layar Utama"</string>
@@ -84,13 +59,15 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"menulis setelan dan pintasan layar Utama"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"Mengizinkan aplikasi mengubah setelan dan pintasan di layar Utama."</string>
<string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> tidak diizinkan untuk melakukan panggilan telepon"</string>
- <string name="gadget_error_text" msgid="740356548025791839">"Tidak dapat memuat widget"</string>
- <string name="gadget_setup_text" msgid="8348374825537681407">"Setelan widget"</string>
- <string name="gadget_complete_setup_text" msgid="309040266978007925">"Ketuk untuk menyelesaikan penyiapan"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"Masalah memuat widget"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"Siapkan"</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"Ini adalah aplikasi sistem dan tidak dapat dicopot pemasangannya."</string>
- <string name="folder_hint_text" msgid="5174843001373488816">"Sunting Nama"</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"Folder Tanpa Nama"</string>
<string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> dinonaktifkan"</string>
- <string name="dotted_app_label" msgid="1704091277755818896">"{count,plural,offset:1 =1{{app_name} memiliki # notifikasi}other{{app_name} memiliki # notifikasi}}"</string>
+ <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+ <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, memiliki <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> notifikasi</item>
+ <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g>, memiliki <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> notifikasi</item>
+ </plurals>
<string name="default_scroll_format" msgid="7475544710230993317">"Halaman %1$d dari %2$d"</string>
<string name="workspace_scroll_format" msgid="8458889198184077399">"Layar utama %1$d dari %2$d"</string>
<string name="workspace_new_page" msgid="257366611030256142">"Halaman layar utama baru"</string>
@@ -99,11 +76,11 @@
<string name="folder_tap_to_rename" msgid="4017685068016979677">"Ketuk untuk menyimpan ganti nama"</string>
<string name="folder_closed" msgid="4100806530910930934">"Folder ditutup"</string>
<string name="folder_renamed" msgid="1794088362165669656">"Folder diganti namanya menjadi <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="folder_name_format_exact" msgid="8626242716117004803">"Folder: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> item"</string>
- <string name="folder_name_format_overflow" msgid="4270108890534995199">"Folder: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> item atau lebih"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"Folder: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"Widget"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Wallpaper"</string>
- <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Wallpaper &amp; gaya"</string>
- <string name="settings_button_text" msgid="8873672322605444408">"Setelan Layar utama"</string>
+ <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Gaya &amp; wallpaper"</string>
+ <string name="settings_button_text" msgid="8873672322605444408">"Setelan layar utama"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Dinonaktifkan oleh admin"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Izinkan Layar utama diputar"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Saat ponsel diputar"</string>
@@ -114,16 +91,16 @@
<string name="msg_missing_notification_access" msgid="281113995110910548">"Guna menampilkan Titik Notifikasi, aktifkan notifikasi aplikasi untuk <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="title_change_settings" msgid="1376365968844349552">"Ubah setelan"</string>
<string name="notification_dots_service_title" msgid="4284221181793592871">"Tampilkan titik notifikasi"</string>
- <string name="auto_add_shortcuts_label" msgid="3698776050751790653">"Tambahkan ikon aplikasi ke Layar utama"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Tambahkan ikon ke Layar utama"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Untuk aplikasi baru"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"Tidak dikenal"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"Buang"</string>
<string name="abandoned_search" msgid="891119232568284442">"Telusuri"</string>
<string name="abandoned_promises_title" msgid="7096178467971716750">"Aplikasi ini belum terpasang"</string>
<string name="abandoned_promise_explanation" msgid="3990027586878167529">"Aplikasi untuk ikon ini belum dipasang. Anda dapat membuangnya, atau menelusuri aplikasi dan memasangnya secara manual."</string>
- <string name="app_installing_title" msgid="5864044122733792085">"<xliff:g id="NAME">%1$s</xliff:g> sedang diinstal, <xliff:g id="PROGRESS">%2$s</xliff:g> selesai"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> sedang didownload, <xliff:g id="PROGRESS">%2$s</xliff:g> selesai"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> menunggu dipasang"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"Widget <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="widgets_list" msgid="796804551140113767">"Daftar widget"</string>
<string name="widgets_list_closed" msgid="6141506579418771922">"Daftar widget ditutup"</string>
<string name="action_add_to_workspace" msgid="8902165848117513641">"Tambahkan ke Layar Utama"</string>
@@ -151,20 +128,15 @@
<string name="action_deep_shortcut" msgid="2864038805849372848">"Pintasan"</string>
<string name="shortcuts_menu_with_notifications_description" msgid="2676582286544232849">"Pintasan dan notifikasi"</string>
<string name="action_dismiss_notification" msgid="5909461085055959187">"Tutup"</string>
- <string name="accessibility_close" msgid="2277148124685870734">"Tutup"</string>
<string name="notification_dismissed" msgid="6002233469409822874">"Notifikasi ditutup"</string>
<string name="all_apps_personal_tab" msgid="4190252696685155002">"Pribadi"</string>
- <string name="all_apps_work_tab" msgid="4884822796154055118">"Kerja"</string>
+ <string name="all_apps_work_tab" msgid="4884822796154055118">"Kantor"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"Profil kerja"</string>
- <string name="work_profile_edu_work_apps" msgid="7895468576497746520">"Aplikasi kerja diberi badge dan terlihat oleh admin IT"</string>
- <string name="work_profile_edu_accept" msgid="6069788082535149071">"Oke"</string>
- <string name="work_apps_paused_title" msgid="3040901117349444598">"Aplikasi kerja dijeda"</string>
- <string name="work_apps_paused_body" msgid="261634750995824906">"Aplikasi kerja tidak dapat mengirimkan notifikasi, menggunakan baterai, atau mengakses lokasi Anda"</string>
- <string name="work_apps_paused_content_description" msgid="5149623040804051095">"Aplikasi kerja dinonaktifkan. Aplikasi kerja tidak dapat mengirimkan notifikasi, menggunakan baterai, atau mengakses lokasi Anda"</string>
- <string name="work_apps_paused_edu_banner" msgid="8872412121608402058">"Aplikasi kerja diberi badge dan terlihat oleh admin IT"</string>
- <string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"Oke"</string>
- <string name="work_apps_pause_btn_text" msgid="1921059713673767460">"Nonaktifkan aplikasi kerja"</string>
- <string name="work_apps_enable_btn_text" msgid="1156432622148413741">"Aktifkan aplikasi kerja"</string>
- <string name="developer_options_filter_hint" msgid="5896817443635989056">"Filter"</string>
+ <string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"Temukan aplikasi kerja di sini"</string>
+ <string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"Setiap aplikasi kerja memiliki badge dan dibuat tetap aman oleh organisasi. Pindahkan aplikasi ke Layar utama untuk memudahkan akses."</string>
+ <string name="work_mode_on_label" msgid="4781128097185272916">"Dikelola oleh organisasi"</string>
+ <string name="work_mode_off_label" msgid="3194894777601421047">"Notifikasi dan aplikasi nonaktif"</string>
+ <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Tutup"</string>
+ <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Ditutup"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Gagal: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
</resources>
diff --git a/res/values-is/strings.xml b/res/values-is/strings.xml
index 1397b88ee7..d66ca3243a 100644
--- a/res/values-is/strings.xml
+++ b/res/values-is/strings.xml
@@ -20,63 +20,39 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="649227358658669779">"Launcher3"</string>
+ <string name="folder_name" msgid="7371454440695724752"></string>
<string name="work_folder_name" msgid="3753320833950115786">"Vinna"</string>
<string name="activity_not_found" msgid="8071924732094499514">"Forritið er ekki uppsett."</string>
<string name="activity_not_available" msgid="7456344436509528827">"Forritið er ekki í boði"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"Sótt forrit er óvirkt í öryggisstillingu"</string>
<string name="safemode_widget_error" msgid="4863470563535682004">"Græjur eru óvirkar í öruggri stillingu"</string>
<string name="shortcut_not_available" msgid="2536503539825726397">"Flýtileið er ekki tiltæk"</string>
- <string name="home_screen" msgid="5629429142036709174">"Heim"</string>
- <string name="recent_task_option_split_screen" msgid="6690461455618725183">"Skipta skjá"</string>
- <string name="split_screen_position_top" msgid="1504965011158689649">"Skipta efst"</string>
- <string name="split_screen_position_left" msgid="7537793098851830883">"Skipta vinstra megin"</string>
- <string name="split_screen_position_right" msgid="1569377524925193369">"Skipta hægra megin"</string>
- <string name="split_app_info_accessibility" msgid="5475288491241414932">"Upplýsingar um forrit fyrir %1$s"</string>
- <string name="long_press_widget_to_add" msgid="3587712543577675817">"Haltu fingri á græju til að færa hana."</string>
- <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Ýttu tvisvar og haltu fingri á græju til að færa hana eða notaðu sérsniðnar aðgerðir."</string>
+ <string name="home_screen" msgid="806512411299847073">"Heimaskjár"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"Sérsniðnar aðgerðir"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"Haltu fingri á græju til að grípa hana."</string>
+ <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Ýttu tvisvar og haltu fingri á græju til að grípa hana eða notaðu sérsniðnar aðgerðir."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d á breidd og %2$d á hæð"</string>
- <string name="widget_preview_context_description" msgid="9045841361655787574">"Græjan <xliff:g id="WIDGET_NAME">%1$s</xliff:g>"</string>
- <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Haltu fingri á græjunni til að hreyfa hana um heimaskjáinn"</string>
- <string name="add_to_home_screen" msgid="8631549138215492708">"Bæta á heimaskjá"</string>
- <string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g> græju bætt við heimaskjá"</string>
- <string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# græja}one{# græja}other{# græjur}}"</string>
- <string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{# flýtileið}one{# flýtileið}other{# flýtileiðir}}"</string>
- <string name="widgets_and_shortcuts_count" msgid="7209136747878365116">"<xliff:g id="WIDGETS_COUNT">%1$s</xliff:g>, <xliff:g id="SHORTCUTS_COUNT">%2$s</xliff:g>"</string>
- <string name="widget_button_text" msgid="2880537293434387943">"Græjur"</string>
- <string name="widgets_full_sheet_search_bar_hint" msgid="8484659090860596457">"Leit"</string>
- <string name="widgets_full_sheet_cancel_button_description" msgid="5766167035728653605">"Hreinsa texta úr leitarreit"</string>
- <string name="no_widgets_available" msgid="4337693382501046170">"Græjur og flýtileiðir eru ekki í boði"</string>
- <string name="no_search_results" msgid="3787956167293097509">"Engar græjur eða flýtileiðir fundust"</string>
- <string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Persónulegt"</string>
- <string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Vinna"</string>
- <string name="widget_category_conversations" msgid="8894438636213590446">"Samtöl"</string>
- <string name="widget_education_header" msgid="4874760613775913787">"Gagnlegar upplýsingar innan seilingar"</string>
- <string name="widget_education_content" msgid="745542879510751525">"Þú getur bætt við græjum á heimaskjáinn til að fá upplýsingar án þess að opna forrit"</string>
- <string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Ýttu til að breyta græjustillingum"</string>
- <string name="widget_education_close_button" msgid="8676165703104836580">"Ég skil"</string>
- <string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Breyta græjustillingum"</string>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Haltu inni til að staðsetja handvirkt"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"Bæta sjálfkrafa við"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Leita í forritum"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Hleður forrit…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"Ekki fundust forrit sem samsvara „<xliff:g id="QUERY">%1$s</xliff:g>“"</string>
<string name="all_apps_search_market_message" msgid="1366263386197059176">"Leita að fleiri forritum"</string>
<string name="label_application" msgid="8531721983832654978">"Forrit"</string>
- <string name="all_apps_label" msgid="5015784846527570951">"Öll forrit"</string>
<string name="notifications_header" msgid="1404149926117359025">"Tilkynningar"</string>
- <string name="long_press_shortcut_to_add" msgid="5405328730817637737">"Haltu fingri á flýtileið til að færa hana."</string>
- <string name="long_accessible_way_to_add_shortcut" msgid="2199537273817090740">"Ýttu tvisvar og haltu fingri á flýtileið til að færa hana eða notaðu sérsniðnar aðgerðir."</string>
- <string name="out_of_space" msgid="6692471482459245734">"Ekkert pláss á þessum heimaskjá"</string>
+ <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"Haltu fingri á flýtileið til að grípa hana."</string>
+ <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"Ýttu tvisvar og haltu fingri á flýtileið til að grípa hana eða notaðu sérsniðnar aðgerðir."</string>
+ <string name="out_of_space" msgid="4691004494942118364">"Ekki meira pláss á þessum heimaskjá."</string>
<string name="hotseat_out_of_space" msgid="7448809638125333693">"Ekki meira pláss í bakka fyrir uppáhald"</string>
<string name="all_apps_button_label" msgid="8130441508702294465">"Forritalisti"</string>
- <string name="all_apps_search_results" msgid="5889367432531296759">"Leitarniðurstöður"</string>
<string name="all_apps_button_personal_label" msgid="1315764287305224468">"Listi yfir eigin forrit"</string>
<string name="all_apps_button_work_label" msgid="7270707118948892488">"Listi yfir vinnuforrit"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"Heim"</string>
<string name="remove_drop_target_label" msgid="7812859488053230776">"Taka niður"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"Fjarlægja"</string>
<string name="app_info_drop_target_label" msgid="692894985365717661">"Forritsupplýsingar"</string>
<string name="install_drop_target_label" msgid="2539096853673231757">"Setja upp"</string>
- <string name="dismiss_prediction_label" msgid="3357562989568808658">"Ekki fá tillögu að forriti"</string>
- <string name="pin_prediction" msgid="4196423321649756498">"Festa tillögu"</string>
<string name="permlab_install_shortcut" msgid="5632423390354674437">"setja upp flýtileiðir"</string>
<string name="permdesc_install_shortcut" msgid="923466509822011139">"Leyfir forriti að bæta við flýtileiðum án íhlutunar notanda."</string>
<string name="permlab_read_settings" msgid="1941457408239617576">"lesa stillingar og flýtileiðir heimaskjás"</string>
@@ -84,13 +60,15 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"skrifa stillingar og flýtileiðir heimaskjás"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"Leyfir forriti að breyta stillingum og flýtileiðum heimaskjás."</string>
<string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> hefur ekki leyfi til að hringja símtöl"</string>
- <string name="gadget_error_text" msgid="740356548025791839">"Ekki hægt að hlaða græju"</string>
- <string name="gadget_setup_text" msgid="8348374825537681407">"Græjustillingar"</string>
- <string name="gadget_complete_setup_text" msgid="309040266978007925">"Ýttu til að ljúka við uppsetningu"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"Vandamál við að hlaða græju"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"Uppsetning"</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"Þetta er kerfisforrit sem ekki er hægt að fjarlægja."</string>
- <string name="folder_hint_text" msgid="5174843001373488816">"Breyta nafni"</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"Ónefnd mappa"</string>
<string name="disabled_app_label" msgid="6673129024321402780">"Óvirkt <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
- <string name="dotted_app_label" msgid="1704091277755818896">"{count,plural,offset:1 =1{{app_name} er með # tilkynningu}one{{app_name} er með # tilkynningu}other{{app_name} er með # tilkynningar}}"</string>
+ <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+ <item quantity="one"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, er með <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> tilkynningu</item>
+ <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, er með <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> tilkynningar</item>
+ </plurals>
<string name="default_scroll_format" msgid="7475544710230993317">"Síða %1$d af %2$d"</string>
<string name="workspace_scroll_format" msgid="8458889198184077399">"Heimaskjár %1$d af %2$d"</string>
<string name="workspace_new_page" msgid="257366611030256142">"Ný síða á heimaskjá"</string>
@@ -99,13 +77,13 @@
<string name="folder_tap_to_rename" msgid="4017685068016979677">"Ýttu til að vista breytt heiti"</string>
<string name="folder_closed" msgid="4100806530910930934">"Möppu lokað"</string>
<string name="folder_renamed" msgid="1794088362165669656">"Heiti möppu breytt í <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="folder_name_format_exact" msgid="8626242716117004803">"Mappa: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> atriði"</string>
- <string name="folder_name_format_overflow" msgid="4270108890534995199">"Mappa: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> eða fleiri atriði"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"Mappa: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"Græjur"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Veggfóður"</string>
- <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Veggfóður og stíll"</string>
+ <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Stílar og veggfóður"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Heimastillingar"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Gert óvirkt af kerfisstjóra"</string>
- <string name="allow_rotation_title" msgid="7728578836261442095">"Leyfa snúning á heimaskjá"</string>
+ <string name="allow_rotation_title" msgid="7728578836261442095">"Leyfa snúning fyrir heimaskjá"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Þegar símanum er snúið"</string>
<string name="notification_dots_title" msgid="9062440428204120317">"Tilkynningapunktar"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"Kveikt"</string>
@@ -114,16 +92,16 @@
<string name="msg_missing_notification_access" msgid="281113995110910548">"Til að sýna tilkynningarpunkta skaltu kveikja á forritstilkynningum fyrir <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="title_change_settings" msgid="1376365968844349552">"Breyta stillingum"</string>
<string name="notification_dots_service_title" msgid="4284221181793592871">"Sýna tilkynningapunkta"</string>
- <string name="auto_add_shortcuts_label" msgid="3698776050751790653">"Bæta forritatáknum við heimaskjáinn"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Bæta tákni á heimaskjáinn"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Fyrir ný forrit"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"Óþekkt"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"Taka niður"</string>
<string name="abandoned_search" msgid="891119232568284442">"Leita"</string>
<string name="abandoned_promises_title" msgid="7096178467971716750">"Þetta forrit er ekki uppsett"</string>
<string name="abandoned_promise_explanation" msgid="3990027586878167529">"Forritið fyrir þetta tákn er ekki uppsett. Þú getur fjarlægt það eða leitað að forritinu og sett það upp handvirkt."</string>
- <string name="app_installing_title" msgid="5864044122733792085">"Setur upp <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="PROGRESS">%2$s</xliff:g> lokið"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> í niðurhali, <xliff:g id="PROGRESS">%2$s</xliff:g> lokið"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> bíður uppsetningar"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"<xliff:g id="NAME">%1$s</xliff:g>-græjur"</string>
<string name="widgets_list" msgid="796804551140113767">"Græjulisti"</string>
<string name="widgets_list_closed" msgid="6141506579418771922">"Græjulista lokað"</string>
<string name="action_add_to_workspace" msgid="8902165848117513641">"Bæta á heimaskjá"</string>
@@ -151,20 +129,15 @@
<string name="action_deep_shortcut" msgid="2864038805849372848">"Flýtileiðir"</string>
<string name="shortcuts_menu_with_notifications_description" msgid="2676582286544232849">"Flýtileiðir og tilkynningar"</string>
<string name="action_dismiss_notification" msgid="5909461085055959187">"Hunsa"</string>
- <string name="accessibility_close" msgid="2277148124685870734">"Loka"</string>
<string name="notification_dismissed" msgid="6002233469409822874">"Tilkynningu lokað"</string>
<string name="all_apps_personal_tab" msgid="4190252696685155002">"Persónulegt"</string>
<string name="all_apps_work_tab" msgid="4884822796154055118">"Vinna"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"Vinnusnið"</string>
- <string name="work_profile_edu_work_apps" msgid="7895468576497746520">"Vinnuforrit eru merkt og kerfisstjórinn getur séð þau"</string>
- <string name="work_profile_edu_accept" msgid="6069788082535149071">"Ég skil"</string>
- <string name="work_apps_paused_title" msgid="3040901117349444598">"Hlé gert á vinnuforritum"</string>
- <string name="work_apps_paused_body" msgid="261634750995824906">"Vinnuforrit geta ekki sent þér tilkynningar, notað rafhlöðuorku eða fengið aðgang að staðsetningu þinni"</string>
- <string name="work_apps_paused_content_description" msgid="5149623040804051095">"Slökkt er á vinnuforritum. Vinnuforrit geta ekki sent þér tilkynningar, notað rafhlöðuorku eða fengið aðgang að staðsetningu þinni"</string>
- <string name="work_apps_paused_edu_banner" msgid="8872412121608402058">"Vinnuforrit eru merkt og kerfisstjórinn getur séð þau"</string>
- <string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"Ég skil"</string>
- <string name="work_apps_pause_btn_text" msgid="1921059713673767460">"Slökkva á vinnuforritum"</string>
- <string name="work_apps_enable_btn_text" msgid="1156432622148413741">"Kveikja á vinnuforritum"</string>
- <string name="developer_options_filter_hint" msgid="5896817443635989056">"Sía"</string>
+ <string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"Hér finnurðu vinnuforrit"</string>
+ <string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"Öll vinnuforrit eru með merki og fyrirtækið þitt tryggir öryggi þeirra. Færðu forrit yfir á heimaskjáinn til að fá auðveldari aðgang að þeim."</string>
+ <string name="work_mode_on_label" msgid="4781128097185272916">"Stjórnað af fyrirtækinu þínu"</string>
+ <string name="work_mode_off_label" msgid="3194894777601421047">"Slökkt er á tilkynningum og forritum"</string>
+ <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Loka"</string>
+ <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Lokað"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Mistókst: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
</resources>
diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml
index ff0b6c03ee..8c4e3c5281 100644
--- a/res/values-it/strings.xml
+++ b/res/values-it/strings.xml
@@ -20,63 +20,39 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="649227358658669779">"Launcher3"</string>
+ <string name="folder_name" msgid="7371454440695724752"></string>
<string name="work_folder_name" msgid="3753320833950115786">"Lavoro"</string>
<string name="activity_not_found" msgid="8071924732094499514">"App non installata."</string>
<string name="activity_not_available" msgid="7456344436509528827">"App non disponibile"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"L\'app scaricata è stata disattivata in modalità provvisoria"</string>
<string name="safemode_widget_error" msgid="4863470563535682004">"Widget disabilitati in modalità provvisoria"</string>
<string name="shortcut_not_available" msgid="2536503539825726397">"La scorciatoia non è disponibile"</string>
- <string name="home_screen" msgid="5629429142036709174">"Home"</string>
- <string name="recent_task_option_split_screen" msgid="6690461455618725183">"Schermo diviso"</string>
- <string name="split_screen_position_top" msgid="1504965011158689649">"Dividi in alto"</string>
- <string name="split_screen_position_left" msgid="7537793098851830883">"Dividi a sinistra"</string>
- <string name="split_screen_position_right" msgid="1569377524925193369">"Dividi a destra"</string>
- <string name="split_app_info_accessibility" msgid="5475288491241414932">"Informazioni sull\'app %1$s"</string>
- <string name="long_press_widget_to_add" msgid="3587712543577675817">"Tocca e tieni premuto per spostare un widget."</string>
- <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Tocca due volte e tieni premuto per spostare un widget o per usare le azioni personalizzate."</string>
+ <string name="home_screen" msgid="806512411299847073">"Schermata Home"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"Azioni personalizzate"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"Tocca e tieni premuto per scegliere un widget."</string>
+ <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Tocca due volte e tieni premuto per scegliere un widget o per utilizzare azioni personalizzate."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d di larghezza per %2$d di altezza"</string>
- <string name="widget_preview_context_description" msgid="9045841361655787574">"Widget <xliff:g id="WIDGET_NAME">%1$s</xliff:g>"</string>
- <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Tocca e tieni premuto il widget per spostarlo nella schermata Home"</string>
- <string name="add_to_home_screen" msgid="8631549138215492708">"Aggiungi a schermata Home"</string>
- <string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"Widget <xliff:g id="WIDGET_NAME">%1$s</xliff:g> aggiunto alla schermata Home"</string>
- <string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# widget}one{# widget}other{# widget}}"</string>
- <string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{# scorciatoia}one{# scorciatoia}other{# scorciatoie}}"</string>
- <string name="widgets_and_shortcuts_count" msgid="7209136747878365116">"<xliff:g id="WIDGETS_COUNT">%1$s</xliff:g>, <xliff:g id="SHORTCUTS_COUNT">%2$s</xliff:g>"</string>
- <string name="widget_button_text" msgid="2880537293434387943">"Widget"</string>
- <string name="widgets_full_sheet_search_bar_hint" msgid="8484659090860596457">"Cerca"</string>
- <string name="widgets_full_sheet_cancel_button_description" msgid="5766167035728653605">"Cancella il testo nella casella di ricerca"</string>
- <string name="no_widgets_available" msgid="4337693382501046170">"Widget e scorciatoie non disponibili"</string>
- <string name="no_search_results" msgid="3787956167293097509">"Impossibile trovare widget o scorciatoie"</string>
- <string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Personali"</string>
- <string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Lavoro"</string>
- <string name="widget_category_conversations" msgid="8894438636213590446">"Conversazioni"</string>
- <string name="widget_education_header" msgid="4874760613775913787">"Informazioni utili a portata di mano"</string>
- <string name="widget_education_content" msgid="745542879510751525">"Per ricevere informazioni senza aprire app, puoi aggiungere widget alla schermata Home"</string>
- <string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Tocca per modificare le impostazioni del widget"</string>
- <string name="widget_education_close_button" msgid="8676165703104836580">"OK"</string>
- <string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Modifica le impostazioni del widget"</string>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Tieni premuto per posizionare l\'elemento manualmente"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"Aggiungi automaticamente"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Cerca nelle app"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Caricamento delle app…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"Nessuna app trovata corrispondente a \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
<string name="all_apps_search_market_message" msgid="1366263386197059176">"Cerca altre app"</string>
<string name="label_application" msgid="8531721983832654978">"App"</string>
- <string name="all_apps_label" msgid="5015784846527570951">"Tutte le app"</string>
<string name="notifications_header" msgid="1404149926117359025">"Notifiche"</string>
- <string name="long_press_shortcut_to_add" msgid="5405328730817637737">"Tocca e tieni premuto per spostare una scorciatoia."</string>
- <string name="long_accessible_way_to_add_shortcut" msgid="2199537273817090740">"Tocca due volte e tieni premuto per spostare una scorciatoia o per usare le azioni personalizzate."</string>
- <string name="out_of_space" msgid="6692471482459245734">"Non c\'è più spazio nella schermata Home"</string>
+ <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"Tocca e tieni premuto per scegliere la scorciatoia"</string>
+ <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"Tocca due volte e tieni premuto per scegliere una scorciatoia o per usare azioni personalizzate."</string>
+ <string name="out_of_space" msgid="4691004494942118364">"Spazio nella schermata Home esaurito."</string>
<string name="hotseat_out_of_space" msgid="7448809638125333693">"Spazio esaurito nella barra dei Preferiti"</string>
<string name="all_apps_button_label" msgid="8130441508702294465">"Elenco di app"</string>
- <string name="all_apps_search_results" msgid="5889367432531296759">"Risultati di ricerca"</string>
<string name="all_apps_button_personal_label" msgid="1315764287305224468">"Elenco di app personali"</string>
<string name="all_apps_button_work_label" msgid="7270707118948892488">"Elenco di app di lavoro"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"Home page"</string>
<string name="remove_drop_target_label" msgid="7812859488053230776">"Rimuovi"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"Disinstalla"</string>
<string name="app_info_drop_target_label" msgid="692894985365717661">"Informazioni app"</string>
<string name="install_drop_target_label" msgid="2539096853673231757">"Installa"</string>
- <string name="dismiss_prediction_label" msgid="3357562989568808658">"Non suggerire app"</string>
- <string name="pin_prediction" msgid="4196423321649756498">"Blocca previsione"</string>
<string name="permlab_install_shortcut" msgid="5632423390354674437">"aggiunta di scorciatoie"</string>
<string name="permdesc_install_shortcut" msgid="923466509822011139">"Consente a un\'app di aggiungere scorciatoie automaticamente."</string>
<string name="permlab_read_settings" msgid="1941457408239617576">"lettura di impostazioni e scorciatoie in Home"</string>
@@ -84,13 +60,15 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"creazione di impostazioni e scorciatoie in Home"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"Consente all\'app di modificare le impostazioni e le scorciatoie in Home."</string>
<string name="msg_no_phone_permission" msgid="9208659281529857371">"L\'app <xliff:g id="APP_NAME">%1$s</xliff:g> non è autorizzata a effettuare telefonate"</string>
- <string name="gadget_error_text" msgid="740356548025791839">"Impossibile caricare il widget"</string>
- <string name="gadget_setup_text" msgid="8348374825537681407">"Impostazioni widget"</string>
- <string name="gadget_complete_setup_text" msgid="309040266978007925">"Tocca per completare la configurazione"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"Errore durante il caricamento del widget"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"Configurazione"</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"Questa è un\'app di sistema e non può essere disinstallata."</string>
- <string name="folder_hint_text" msgid="5174843001373488816">"Modifica nome"</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"Cartella senza nome"</string>
<string name="disabled_app_label" msgid="6673129024321402780">"App <xliff:g id="APP_NAME">%1$s</xliff:g> disattivata"</string>
- <string name="dotted_app_label" msgid="1704091277755818896">"{count,plural,offset:1 =1{{app_name} ha # notifica}one{{app_name} ha # notifica}other{{app_name} ha # notifiche}}"</string>
+ <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+ <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, ha <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> notifiche</item>
+ <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g>, ha <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> notifica</item>
+ </plurals>
<string name="default_scroll_format" msgid="7475544710230993317">"Pagina %1$d di %2$d"</string>
<string name="workspace_scroll_format" msgid="8458889198184077399">"Schermata Home %1$d di %2$d"</string>
<string name="workspace_new_page" msgid="257366611030256142">"Nuova pagina Schermata Home"</string>
@@ -99,11 +77,11 @@
<string name="folder_tap_to_rename" msgid="4017685068016979677">"Tocca per salvare il nuovo nome"</string>
<string name="folder_closed" msgid="4100806530910930934">"Cartella chiusa"</string>
<string name="folder_renamed" msgid="1794088362165669656">"Nome della cartella sostituito con <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="folder_name_format_exact" msgid="8626242716117004803">"Cartella: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> elementi"</string>
- <string name="folder_name_format_overflow" msgid="4270108890534995199">"Cartella: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> o più elementi"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"Cartella: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"Widget"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Sfondi"</string>
- <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Sfondo e stile"</string>
- <string name="settings_button_text" msgid="8873672322605444408">"Impostazioni schermata Home"</string>
+ <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Stili e sfondi"</string>
+ <string name="settings_button_text" msgid="8873672322605444408">"Impostazioni Home"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Disattivata dall\'amministratore"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Consenti rotazione della schermata Home"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Con il telefono ruotato"</string>
@@ -114,16 +92,16 @@
<string name="msg_missing_notification_access" msgid="281113995110910548">"Per mostrare gli indicatori di notifica, attiva le notifiche per l\'app <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="title_change_settings" msgid="1376365968844349552">"Modifica impostazioni"</string>
<string name="notification_dots_service_title" msgid="4284221181793592871">"Mostra indicatori di notifica"</string>
- <string name="auto_add_shortcuts_label" msgid="3698776050751790653">"Aggiungi icone delle app alla schermata Home"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Aggiungi icone alla schermata Home"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Per le nuove app"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"Sconosciuto"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"Rimuovi"</string>
<string name="abandoned_search" msgid="891119232568284442">"Cerca"</string>
<string name="abandoned_promises_title" msgid="7096178467971716750">"L\'app non è installata"</string>
<string name="abandoned_promise_explanation" msgid="3990027586878167529">"L\'app per questa icona non è installata. Puoi rimuoverla o cercare l\'app e installarla manualmente."</string>
- <string name="app_installing_title" msgid="5864044122733792085">"Installazione di <xliff:g id="NAME">%1$s</xliff:g>, completamento: <xliff:g id="PROGRESS">%2$s</xliff:g>"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"Download di <xliff:g id="NAME">%1$s</xliff:g> in corso, <xliff:g id="PROGRESS">%2$s</xliff:g> completato"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> in attesa di installazione"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"Widget di <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="widgets_list" msgid="796804551140113767">"Elenco di widget"</string>
<string name="widgets_list_closed" msgid="6141506579418771922">"Elenco di widget chiuso"</string>
<string name="action_add_to_workspace" msgid="8902165848117513641">"Aggiungi a schermata Home"</string>
@@ -151,20 +129,15 @@
<string name="action_deep_shortcut" msgid="2864038805849372848">"Scorciatoie"</string>
<string name="shortcuts_menu_with_notifications_description" msgid="2676582286544232849">"Scorciatoie e notifiche"</string>
<string name="action_dismiss_notification" msgid="5909461085055959187">"Ignora"</string>
- <string name="accessibility_close" msgid="2277148124685870734">"Esci"</string>
<string name="notification_dismissed" msgid="6002233469409822874">"Notifica ignorata"</string>
<string name="all_apps_personal_tab" msgid="4190252696685155002">"Personali"</string>
<string name="all_apps_work_tab" msgid="4884822796154055118">"Lavoro"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"Profilo di lavoro"</string>
- <string name="work_profile_edu_work_apps" msgid="7895468576497746520">"Le app di lavoro sono contrassegnate con un badge e visibili all\'amministratore IT"</string>
- <string name="work_profile_edu_accept" msgid="6069788082535149071">"OK"</string>
- <string name="work_apps_paused_title" msgid="3040901117349444598">"Le app di lavoro sono in pausa"</string>
- <string name="work_apps_paused_body" msgid="261634750995824906">"Le app di lavoro non possono inviarti notifiche, usare la batteria o accedere alla tua posizione"</string>
- <string name="work_apps_paused_content_description" msgid="5149623040804051095">"Le app di lavoro non sono attive e non possono inviarti notifiche, usare la batteria o accedere alla tua posizione"</string>
- <string name="work_apps_paused_edu_banner" msgid="8872412121608402058">"Le app di lavoro sono contrassegnate con un badge e sono visibili dal tuo amministratore IT"</string>
- <string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"OK"</string>
- <string name="work_apps_pause_btn_text" msgid="1921059713673767460">"Disattiva app di lavoro"</string>
- <string name="work_apps_enable_btn_text" msgid="1156432622148413741">"Attiva app di lavoro"</string>
- <string name="developer_options_filter_hint" msgid="5896817443635989056">"Filtra"</string>
+ <string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"Qui puoi trovare le tue app di lavoro"</string>
+ <string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"Ogni app di lavoro è contrassegnata da un badge e viene tenuta al sicuro dalla tua organizzazione. Sposta le app nella schermata Home per accedervi più facilmente."</string>
+ <string name="work_mode_on_label" msgid="4781128097185272916">"Gestito dalla tua organizzazione"</string>
+ <string name="work_mode_off_label" msgid="3194894777601421047">"Le notifiche e le app non sono attive"</string>
+ <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Chiudi"</string>
+ <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Chiusa"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Operazione non riuscita: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
</resources>
diff --git a/res/values-iw/strings.xml b/res/values-iw/strings.xml
index 3d0774f10a..c25e8795f7 100644
--- a/res/values-iw/strings.xml
+++ b/res/values-iw/strings.xml
@@ -20,151 +20,126 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="649227358658669779">"Launcher3"</string>
+ <string name="folder_name" msgid="7371454440695724752"></string>
<string name="work_folder_name" msgid="3753320833950115786">"עבודה"</string>
<string name="activity_not_found" msgid="8071924732094499514">"האפליקציה לא מותקנת."</string>
<string name="activity_not_available" msgid="7456344436509528827">"האפליקציה אינה זמינה"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"אפליקציה שהורדת הושבתה במצב בטוח"</string>
<string name="safemode_widget_error" msgid="4863470563535682004">"ווידג\'טים מושבתים במצב בטוח"</string>
<string name="shortcut_not_available" msgid="2536503539825726397">"קיצור הדרך אינו זמין"</string>
- <string name="home_screen" msgid="5629429142036709174">"בית"</string>
- <string name="recent_task_option_split_screen" msgid="6690461455618725183">"מסך מפוצל"</string>
- <string name="split_screen_position_top" msgid="1504965011158689649">"פיצול למעלה"</string>
- <string name="split_screen_position_left" msgid="7537793098851830883">"פיצול שמאלה"</string>
- <string name="split_screen_position_right" msgid="1569377524925193369">"פיצול ימינה"</string>
- <string name="split_app_info_accessibility" msgid="5475288491241414932">"‏פרטים על האפליקציה %1$s"</string>
- <string name="long_press_widget_to_add" msgid="3587712543577675817">"כדי להעביר ווידג\'ט למקום אחר יש לגעת ולא להרפות."</string>
- <string name="long_accessible_way_to_add" msgid="2733588281439571974">"כדי להעביר ווידג\'ט למקום אחר או להשתמש בפעולות מותאמות אישית, יש ללחוץ פעמיים ולא להרפות."</string>
+ <string name="home_screen" msgid="806512411299847073">"מסך דף הבית"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"פעולות מותאמות אישית"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"אפשר לבחור את הווידג\'ט אם נוגעים בו נגיעה רציפה."</string>
+ <string name="long_accessible_way_to_add" msgid="4289502106628154155">"הקש פעמיים וגע נגיעה רציפה בווידג\'ט כדי לבחור בו, או השתמש בפעולות מותאמות אישית."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"‏רוחב %1$d על גובה %2$d"</string>
- <string name="widget_preview_context_description" msgid="9045841361655787574">"ווידג\'ט <xliff:g id="WIDGET_NAME">%1$s</xliff:g>"</string>
- <string name="add_item_request_drag_hint" msgid="5653291305078645405">"יש ללחוץ לחיצה ארוכה על הווידג\'ט כדי להזיז אותו ברחבי מסך הבית"</string>
- <string name="add_to_home_screen" msgid="8631549138215492708">"הוספה למסך הבית"</string>
- <string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"הווידג\'ט <xliff:g id="WIDGET_NAME">%1$s</xliff:g> נוסף למסך הבית"</string>
- <string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{ווידג\'ט אחד}two{# ווידג\'טים}many{# ווידג\'טים}other{# ווידג\'טים}}"</string>
- <string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{קיצור דרך אחד}two{# קיצורי דרך}many{# קיצורי דרך}other{# קיצורי דרך}}"</string>
- <string name="widgets_and_shortcuts_count" msgid="7209136747878365116">"<xliff:g id="WIDGETS_COUNT">%1$s</xliff:g>, <xliff:g id="SHORTCUTS_COUNT">%2$s</xliff:g>"</string>
- <string name="widget_button_text" msgid="2880537293434387943">"ווידג\'טים"</string>
- <string name="widgets_full_sheet_search_bar_hint" msgid="8484659090860596457">"חיפוש"</string>
- <string name="widgets_full_sheet_cancel_button_description" msgid="5766167035728653605">"מחיקת טקסט מתיבת החיפוש"</string>
- <string name="no_widgets_available" msgid="4337693382501046170">"אין ווידג\'טים או קיצורי דרך"</string>
- <string name="no_search_results" msgid="3787956167293097509">"לא נמצאו ווידג\'טים או קיצורי דרך"</string>
- <string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"ווידג\'טים אישיים"</string>
- <string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"עבודה"</string>
- <string name="widget_category_conversations" msgid="8894438636213590446">"שיחות"</string>
- <string name="widget_education_header" msgid="4874760613775913787">"קבלת מידע שימושי בהקשה"</string>
- <string name="widget_education_content" msgid="745542879510751525">"רוצה לקבל מידע בלי לפתוח אפליקציות? אפשר להוסיף ווידג\'טים למסך הבית"</string>
- <string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"אפשר לשנות את הגדרות הווידג\'ט בהקשה"</string>
- <string name="widget_education_close_button" msgid="8676165703104836580">"הבנתי"</string>
- <string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"שינוי הגדרות הווידג\'ט"</string>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"יש ללחוץ לחיצה ארוכה כדי להוסיף ידנית"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"הוסף באופן אוטומטי"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"חיפוש אפליקציות"</string>
- <string name="all_apps_loading_message" msgid="5813968043155271636">"טעינת אפליקציות מתבצעת…"</string>
+ <string name="all_apps_loading_message" msgid="5813968043155271636">"טוען אפליקציות…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"לא נמצאו אפליקציות התואמות ל-\"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
- <string name="all_apps_search_market_message" msgid="1366263386197059176">"חיפוש אפליקציות נוספות"</string>
+ <string name="all_apps_search_market_message" msgid="1366263386197059176">"חפש אפליקציות נוספות"</string>
<string name="label_application" msgid="8531721983832654978">"אפליקציה"</string>
- <string name="all_apps_label" msgid="5015784846527570951">"כל האפליקציות"</string>
<string name="notifications_header" msgid="1404149926117359025">"התראות"</string>
- <string name="long_press_shortcut_to_add" msgid="5405328730817637737">"כדי להעביר קיצור דרך למקום אחר יש לגעת ולא להרפות."</string>
- <string name="long_accessible_way_to_add_shortcut" msgid="2199537273817090740">"כדי להעביר קיצור דרך למקום אחר או להשתמש בפעולות מותאמות אישית\' יש ללחוץ פעמיים ולא להרפות."</string>
- <string name="out_of_space" msgid="6692471482459245734">"אין מקום במסך הבית הזה"</string>
+ <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"כדי להוסיף קיצור דרך, יש לגעת בו ולהחזיק אותו."</string>
+ <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"כדי להוסיף קיצור דרך או להשתמש בפעולות מותאמות אישית, יש להקיש על קיצור הדרך פעמיים ולהחזיק אותו."</string>
+ <string name="out_of_space" msgid="4691004494942118364">"אין עוד מקום במסך דף הבית הזה."</string>
<string name="hotseat_out_of_space" msgid="7448809638125333693">"אין עוד מקום במגש המועדפים"</string>
<string name="all_apps_button_label" msgid="8130441508702294465">"רשימת אפליקציות"</string>
- <string name="all_apps_search_results" msgid="5889367432531296759">"תוצאות חיפוש"</string>
<string name="all_apps_button_personal_label" msgid="1315764287305224468">"רשימת אפליקציות אישיות"</string>
<string name="all_apps_button_work_label" msgid="7270707118948892488">"רשימת אפליקציות עבודה"</string>
- <string name="remove_drop_target_label" msgid="7812859488053230776">"הסרה"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"דף הבית"</string>
+ <string name="remove_drop_target_label" msgid="7812859488053230776">"הסר"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"להסרת התקנה"</string>
<string name="app_info_drop_target_label" msgid="692894985365717661">"פרטי אפליקציה"</string>
<string name="install_drop_target_label" msgid="2539096853673231757">"התקנה"</string>
- <string name="dismiss_prediction_label" msgid="3357562989568808658">"בלי להציע את האפליקציה"</string>
- <string name="pin_prediction" msgid="4196423321649756498">"הצמדת החיזוי"</string>
- <string name="permlab_install_shortcut" msgid="5632423390354674437">"התקנת קיצורי דרך"</string>
+ <string name="permlab_install_shortcut" msgid="5632423390354674437">"התקן קיצורי דרך"</string>
<string name="permdesc_install_shortcut" msgid="923466509822011139">"מאפשר לאפליקציה להוסיף קיצורי דרך ללא התערבות המשתמש."</string>
- <string name="permlab_read_settings" msgid="1941457408239617576">"קריאת הגדרות וקיצורי דרך של דף הבית"</string>
+ <string name="permlab_read_settings" msgid="1941457408239617576">"קרא הגדרות וקיצורי דרך של דף הבית"</string>
<string name="permdesc_read_settings" msgid="5833423719057558387">"מאפשר לאפליקציה לקרוא את ההגדרות וקיצורי הדרך בדף הבית."</string>
- <string name="permlab_write_settings" msgid="3574213698004620587">"כתיבת הגדרות וקיצורי דרך של דף הבית"</string>
+ <string name="permlab_write_settings" msgid="3574213698004620587">"כתוב הגדרות וקיצורי דרך של דף הבית"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"מאפשר לאפליקציה לשנות את ההגדרות וקיצורי הדרך בדף הבית."</string>
<string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> אינו רשאי להתקשר"</string>
- <string name="gadget_error_text" msgid="740356548025791839">"לא ניתן לטעון את הווידג\'ט"</string>
- <string name="gadget_setup_text" msgid="8348374825537681407">"הגדרות הווידג\'ט"</string>
- <string name="gadget_complete_setup_text" msgid="309040266978007925">"צריך להקיש כדי לסיים את תהליך ההגדרה"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"בעיה בטעינת ווידג\'ט"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"הגדרה"</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"זוהי אפליקציית מערכת ולא ניתן להסיר את התקנתה."</string>
- <string name="folder_hint_text" msgid="5174843001373488816">"עריכת השם"</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"תיקיה ללא שם"</string>
<string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> מושבתת"</string>
- <string name="dotted_app_label" msgid="1704091277755818896">"{count,plural,offset:1 =1{לאפליקציה {app_name} יש התראה אחת}two{לאפליקציה {app_name} יש # התראות}many{לאפליקציה {app_name} יש # התראות}other{לאפליקציה {app_name} יש # התראות}}"</string>
+ <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+ <item quantity="two">לאפליקציה <xliff:g id="APP_NAME_2">%1$s</xliff:g> יש <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> התראות</item>
+ <item quantity="many">לאפליקציה <xliff:g id="APP_NAME_2">%1$s</xliff:g> יש <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> התראות</item>
+ <item quantity="other">לאפליקציה <xliff:g id="APP_NAME_2">%1$s</xliff:g> יש <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> התראות</item>
+ <item quantity="one">לאפליקציה <xliff:g id="APP_NAME_0">%1$s</xliff:g> יש התראה אחת (<xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g>)</item>
+ </plurals>
<string name="default_scroll_format" msgid="7475544710230993317">"‏דף %1$d מתוך %2$d"</string>
<string name="workspace_scroll_format" msgid="8458889198184077399">"‏מסך דף הבית %1$d מתוך %2$d"</string>
<string name="workspace_new_page" msgid="257366611030256142">"מסך דף הבית חדש"</string>
- <string name="folder_opened" msgid="94695026776264709">"תיקייה פתוחה, <xliff:g id="WIDTH">%1$d</xliff:g> על <xliff:g id="HEIGHT">%2$d</xliff:g>"</string>
- <string name="folder_tap_to_close" msgid="4625795376335528256">"יש להקיש כדי לסגור את התיקייה"</string>
- <string name="folder_tap_to_rename" msgid="4017685068016979677">"יש להקיש כדי לשמור שינוי שם"</string>
- <string name="folder_closed" msgid="4100806530910930934">"התיקייה נסגרה"</string>
- <string name="folder_renamed" msgid="1794088362165669656">"שם התיקייה שונה ל-<xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="folder_name_format_exact" msgid="8626242716117004803">"תיקייה: <xliff:g id="NAME">%1$s</xliff:g>, מספר הפריטים: <xliff:g id="SIZE">%2$d</xliff:g>"</string>
- <string name="folder_name_format_overflow" msgid="4270108890534995199">"תיקייה: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> פריטים או יותר"</string>
+ <string name="folder_opened" msgid="94695026776264709">"תיקיה פתוחה, <xliff:g id="WIDTH">%1$d</xliff:g> על <xliff:g id="HEIGHT">%2$d</xliff:g>"</string>
+ <string name="folder_tap_to_close" msgid="4625795376335528256">"הקש כדי לסגור את התיקייה"</string>
+ <string name="folder_tap_to_rename" msgid="4017685068016979677">"הקש כדי לשמור שינוי שם"</string>
+ <string name="folder_closed" msgid="4100806530910930934">"התיקיה נסגרה"</string>
+ <string name="folder_renamed" msgid="1794088362165669656">"שם התיקיה שונה ל-<xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"תיקיה: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"רכיבי ווידג\'ט"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"טפטים"</string>
- <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"טפט וסגנון"</string>
- <string name="settings_button_text" msgid="8873672322605444408">"הגדרות של מסך הבית"</string>
+ <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"סגנונות וטפטים"</string>
+ <string name="settings_button_text" msgid="8873672322605444408">"הגדרות דף הבית"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"הושבת על ידי מנהל המערכת שלך"</string>
- <string name="allow_rotation_title" msgid="7728578836261442095">"סיבוב של מסך הבית"</string>
+ <string name="allow_rotation_title" msgid="7728578836261442095">"אפשרות סיבוב של מסך דף הבית"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"כאשר הטלפון מסובב"</string>
<string name="notification_dots_title" msgid="9062440428204120317">"סימני ההתראות"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"מופעל"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"כבוי"</string>
<string name="title_missing_notification_access" msgid="7503287056163941064">"נדרשת גישה להתראות"</string>
<string name="msg_missing_notification_access" msgid="281113995110910548">"כדי להציג את סימני ההתראות,יש להפעיל התראות מהאפליקציה <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="title_change_settings" msgid="1376365968844349552">"שינוי ההגדרות"</string>
+ <string name="title_change_settings" msgid="1376365968844349552">"שנה את ההגדרות"</string>
<string name="notification_dots_service_title" msgid="4284221181793592871">"הצגת סימני ההתראות"</string>
- <string name="auto_add_shortcuts_label" msgid="3698776050751790653">"הוספת סמלי אפליקציות למסך הבית"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"הוספת סמל במסך דף הבית"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"לאפליקציות חדשות"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"לא ידוע"</string>
- <string name="abandoned_clean_this" msgid="7610119707847920412">"הסרה"</string>
+ <string name="abandoned_clean_this" msgid="7610119707847920412">"הסר"</string>
<string name="abandoned_search" msgid="891119232568284442">"חיפוש"</string>
<string name="abandoned_promises_title" msgid="7096178467971716750">"אפליקציה זו אינה מותקנת"</string>
<string name="abandoned_promise_explanation" msgid="3990027586878167529">"האפליקציה של סמל זה אינה מותקנת. ניתן להסיר אותו, או לחפש את האפליקציה ולהתקין אותה ידנית."</string>
- <string name="app_installing_title" msgid="5864044122733792085">"<xliff:g id="NAME">%1$s</xliff:g> בתהליך התקנה, <xliff:g id="PROGRESS">%2$s</xliff:g> הושלמו"</string>
- <string name="app_downloading_title" msgid="8336702962104482644">"הורדת <xliff:g id="NAME">%1$s</xliff:g> מתבצעת, <xliff:g id="PROGRESS">%2$s</xliff:g> הושלמו"</string>
+ <string name="app_downloading_title" msgid="8336702962104482644">"מוריד את <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="PROGRESS">%2$s</xliff:g> הושלמו"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"מחכה להתקנה של <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"ווידג\'טים של <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="widgets_list" msgid="796804551140113767">"רשימת ווידג\'טים"</string>
<string name="widgets_list_closed" msgid="6141506579418771922">"רשימת הווידג\'טים נסגרה"</string>
- <string name="action_add_to_workspace" msgid="8902165848117513641">"הוספה למסך דף הבית"</string>
- <string name="action_move_here" msgid="2170188780612570250">"העברת הפריט לכאן"</string>
+ <string name="action_add_to_workspace" msgid="8902165848117513641">"הוסף למסך דף הבית"</string>
+ <string name="action_move_here" msgid="2170188780612570250">"העבר את הפריט לכאן"</string>
<string name="item_added_to_workspace" msgid="4211073925752213539">"הפריט הועבר אל מסך דף הבית"</string>
<string name="item_removed" msgid="851119963877842327">"הפריט הוסר"</string>
<string name="undo" msgid="4151576204245173321">"ביטול"</string>
- <string name="action_move" msgid="4339390619886385032">"העברת הפריט"</string>
- <string name="move_to_empty_cell" msgid="2833711483015685619">"העברה אל שורה <xliff:g id="NUMBER_0">%1$s</xliff:g> עמודה <xliff:g id="NUMBER_1">%2$s</xliff:g>"</string>
- <string name="move_to_position" msgid="6750008980455459790">"העברה אל מיקום <xliff:g id="NUMBER">%1$s</xliff:g>"</string>
- <string name="move_to_hotseat_position" msgid="6295412897075147808">"העברה אל מיקום <xliff:g id="NUMBER">%1$s</xliff:g> במועדפים"</string>
+ <string name="action_move" msgid="4339390619886385032">"העבר את הפריט"</string>
+ <string name="move_to_empty_cell" msgid="2833711483015685619">"העבר אל שורה <xliff:g id="NUMBER_0">%1$s</xliff:g> עמודה <xliff:g id="NUMBER_1">%2$s</xliff:g>"</string>
+ <string name="move_to_position" msgid="6750008980455459790">"העבר אל מיקום <xliff:g id="NUMBER">%1$s</xliff:g>"</string>
+ <string name="move_to_hotseat_position" msgid="6295412897075147808">"העבר אל מיקום <xliff:g id="NUMBER">%1$s</xliff:g> במועדפים"</string>
<string name="item_moved" msgid="4606538322571412879">"הפריט הועבר"</string>
- <string name="add_to_folder" msgid="9040534766770853243">"הוספה לתיקייה: <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="add_to_folder_with_app" msgid="4534929978967147231">"הוספה לתיקייה עם <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="add_to_folder" msgid="9040534766770853243">"הוסף לתיקייה: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="add_to_folder_with_app" msgid="4534929978967147231">"העבר אל התיקייה עם <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="added_to_folder" msgid="4793259502305558003">"הפריט נוסף לתיקייה"</string>
- <string name="create_folder_with" msgid="4050141361160214248">"יצירת תיקייה עם: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="create_folder_with" msgid="4050141361160214248">"צור תיקייה עם: <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="folder_created" msgid="6409794597405184510">"התיקייה נוצרה"</string>
<string name="action_move_to_workspace" msgid="1603837886334246317">"העבר אל מסך דף הבית"</string>
- <string name="action_resize" msgid="1802976324781771067">"שינוי גודל"</string>
- <string name="action_increase_width" msgid="8773715375078513326">"הגדלת רוחב"</string>
- <string name="action_increase_height" msgid="459390020612501122">"הגדלת גובה"</string>
- <string name="action_decrease_width" msgid="1374549771083094654">"הקטנת רוחב"</string>
- <string name="action_decrease_height" msgid="282377193880900022">"הקטנת גובה"</string>
+ <string name="action_resize" msgid="1802976324781771067">"שנה גודל"</string>
+ <string name="action_increase_width" msgid="8773715375078513326">"הגדל רוחב"</string>
+ <string name="action_increase_height" msgid="459390020612501122">"הגדל גובה"</string>
+ <string name="action_decrease_width" msgid="1374549771083094654">"הקטן רוחב"</string>
+ <string name="action_decrease_height" msgid="282377193880900022">"הקטן גובה"</string>
<string name="widget_resized" msgid="9130327887929620">"גודל הווידג\'ט שונה - רוחב <xliff:g id="NUMBER_0">%1$s</xliff:g> גובה <xliff:g id="NUMBER_1">%2$s</xliff:g>"</string>
<string name="action_deep_shortcut" msgid="2864038805849372848">"קיצורי דרך"</string>
<string name="shortcuts_menu_with_notifications_description" msgid="2676582286544232849">"קיצורי דרך והתראות"</string>
- <string name="action_dismiss_notification" msgid="5909461085055959187">"סגירה"</string>
- <string name="accessibility_close" msgid="2277148124685870734">"סגירה"</string>
+ <string name="action_dismiss_notification" msgid="5909461085055959187">"סגור"</string>
<string name="notification_dismissed" msgid="6002233469409822874">"ההתראה נסגרה"</string>
<string name="all_apps_personal_tab" msgid="4190252696685155002">"אישיות"</string>
<string name="all_apps_work_tab" msgid="4884822796154055118">"עבודה"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"פרופיל עבודה"</string>
- <string name="work_profile_edu_work_apps" msgid="7895468576497746520">"‏האפליקציות לעבודה מתויגות ומוצגות למנהל ה-IT"</string>
- <string name="work_profile_edu_accept" msgid="6069788082535149071">"הבנתי"</string>
- <string name="work_apps_paused_title" msgid="3040901117349444598">"האפליקציות לעבודה מושהות"</string>
- <string name="work_apps_paused_body" msgid="261634750995824906">"האפליקציות לעבודה לא יכולות לשלוח לך התראות, להשתמש בסוללה או לגשת למיקום שלך"</string>
- <string name="work_apps_paused_content_description" msgid="5149623040804051095">"האפליקציות לעבודה מושבתות. האפליקציות לא יכולות לשלוח לך התראות, להשתמש בסוללה או לגשת למיקום שלך"</string>
- <string name="work_apps_paused_edu_banner" msgid="8872412121608402058">"‏האפליקציות לעבודה מתויגות ומוצגות למנהל ה-IT"</string>
- <string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"הבנתי"</string>
- <string name="work_apps_pause_btn_text" msgid="1921059713673767460">"כיבוי של אפליקציות לעבודה"</string>
- <string name="work_apps_enable_btn_text" msgid="1156432622148413741">"הפעלה של אפליקציות לעבודה"</string>
- <string name="developer_options_filter_hint" msgid="5896817443635989056">"סינון"</string>
+ <string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"ניתן למצוא כאן את אפליקציות העבודה"</string>
+ <string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"לכל אפליקציית עבודה יש תג ואבטחתה מטופלת בידי הארגון. אפשר להעביר אפליקציות אל מסך דף הבית כדי להקל את הגישה אליהן."</string>
+ <string name="work_mode_on_label" msgid="4781128097185272916">"מנוהל בידי הארגון"</string>
+ <string name="work_mode_off_label" msgid="3194894777601421047">"התראות ואפליקציות כבויות"</string>
+ <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"סגירה"</string>
+ <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"סגור"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"הפעולה נכשלה: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
</resources>
diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml
index f1db158098..354f02032e 100644
--- a/res/values-ja/strings.xml
+++ b/res/values-ja/strings.xml
@@ -20,63 +20,39 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="649227358658669779">"Launcher3"</string>
+ <string name="folder_name" msgid="7371454440695724752"></string>
<string name="work_folder_name" msgid="3753320833950115786">"仕事用"</string>
<string name="activity_not_found" msgid="8071924732094499514">"このアプリはインストールされていません。"</string>
<string name="activity_not_available" msgid="7456344436509528827">"このアプリは使用できません"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"ダウンロードしたアプリは、セーフモードでは無効です"</string>
<string name="safemode_widget_error" msgid="4863470563535682004">"セーフモードではウィジェットは無効です"</string>
<string name="shortcut_not_available" msgid="2536503539825726397">"ショートカットは使用できません"</string>
- <string name="home_screen" msgid="5629429142036709174">"ホーム"</string>
- <string name="recent_task_option_split_screen" msgid="6690461455618725183">"分割画面"</string>
- <string name="split_screen_position_top" msgid="1504965011158689649">"上に分割"</string>
- <string name="split_screen_position_left" msgid="7537793098851830883">"左に分割"</string>
- <string name="split_screen_position_right" msgid="1569377524925193369">"右に分割"</string>
- <string name="split_app_info_accessibility" msgid="5475288491241414932">"%1$s のアプリ情報"</string>
- <string name="long_press_widget_to_add" msgid="3587712543577675817">"長押ししてウィジェットを移動してください。"</string>
- <string name="long_accessible_way_to_add" msgid="2733588281439571974">"ウィジェットをダブルタップして長押ししながら移動するか、カスタム操作を使用してください。"</string>
+ <string name="home_screen" msgid="806512411299847073">"ホーム画面"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"カスタム操作"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"ウィジェットを追加するには押し続けます。"</string>
+ <string name="long_accessible_way_to_add" msgid="4289502106628154155">"ダブルタップ後に押し続けてウィジェットを選択するか、カスタム操作を使用してください。"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$dx%2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"幅 %1$d、高さ %2$d"</string>
- <string name="widget_preview_context_description" msgid="9045841361655787574">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g> ウィジェット"</string>
- <string name="add_item_request_drag_hint" msgid="5653291305078645405">"ウィジェットを押し続けると、ホーム画面上に移動できます。"</string>
- <string name="add_to_home_screen" msgid="8631549138215492708">"ホーム画面に追加"</string>
- <string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"「<xliff:g id="WIDGET_NAME">%1$s</xliff:g>」ウィジェットをホーム画面に追加しました"</string>
- <string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# 件のウィジェット}other{# 件のウィジェット}}"</string>
- <string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{# 件のショートカット}other{# 件のショートカット}}"</string>
- <string name="widgets_and_shortcuts_count" msgid="7209136747878365116">"<xliff:g id="WIDGETS_COUNT">%1$s</xliff:g>、<xliff:g id="SHORTCUTS_COUNT">%2$s</xliff:g>"</string>
- <string name="widget_button_text" msgid="2880537293434387943">"ウィジェット"</string>
- <string name="widgets_full_sheet_search_bar_hint" msgid="8484659090860596457">"検索"</string>
- <string name="widgets_full_sheet_cancel_button_description" msgid="5766167035728653605">"検索ボックスからテキストを消去します"</string>
- <string name="no_widgets_available" msgid="4337693382501046170">"ウィジェットもショートカットも利用できません"</string>
- <string name="no_search_results" msgid="3787956167293097509">"ウィジェットやショートカットは見つかりませんでした"</string>
- <string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"個人用"</string>
- <string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"仕事用"</string>
- <string name="widget_category_conversations" msgid="8894438636213590446">"会話"</string>
- <string name="widget_education_header" msgid="4874760613775913787">"ウィジェットで情報を得る"</string>
- <string name="widget_education_content" msgid="745542879510751525">"ホーム画面にウィジェットを追加すると、アプリを開かずに情報を入手できます"</string>
- <string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"タップしてウィジェットの設定を変更する"</string>
- <string name="widget_education_close_button" msgid="8676165703104836580">"OK"</string>
- <string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"ウィジェットの設定を変更します"</string>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"長押しすると、手動で追加できます"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"自動的に追加"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"アプリを検索"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"アプリを読み込んでいます…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"「<xliff:g id="QUERY">%1$s</xliff:g>」に一致するアプリは見つかりませんでした"</string>
<string name="all_apps_search_market_message" msgid="1366263386197059176">"他のアプリを検索"</string>
<string name="label_application" msgid="8531721983832654978">"アプリ"</string>
- <string name="all_apps_label" msgid="5015784846527570951">"すべてのアプリ"</string>
<string name="notifications_header" msgid="1404149926117359025">"通知"</string>
- <string name="long_press_shortcut_to_add" msgid="5405328730817637737">"長押ししてショートカットを移動してください。"</string>
- <string name="long_accessible_way_to_add_shortcut" msgid="2199537273817090740">"ショートカットをダブルタップして長押ししながら移動するか、カスタム操作を使用してください。"</string>
- <string name="out_of_space" msgid="6692471482459245734">"このホーム画面には空きスペースがありません"</string>
+ <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"ショートカットを追加するには押し続けます。"</string>
+ <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"ダブルタップ後に押し続けてショートカットを選択するか、カスタム操作を使用してください。"</string>
+ <string name="out_of_space" msgid="4691004494942118364">"このホーム画面に空きスペースがありません。"</string>
<string name="hotseat_out_of_space" msgid="7448809638125333693">"お気に入りトレイに空きスペースがありません"</string>
<string name="all_apps_button_label" msgid="8130441508702294465">"アプリのリスト"</string>
- <string name="all_apps_search_results" msgid="5889367432531296759">"検索結果"</string>
<string name="all_apps_button_personal_label" msgid="1315764287305224468">"個人用アプリのリスト"</string>
<string name="all_apps_button_work_label" msgid="7270707118948892488">"仕事用アプリのリスト"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"ホーム"</string>
<string name="remove_drop_target_label" msgid="7812859488053230776">"削除"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"アンインストール"</string>
<string name="app_info_drop_target_label" msgid="692894985365717661">"アプリ情報"</string>
<string name="install_drop_target_label" msgid="2539096853673231757">"インストール"</string>
- <string name="dismiss_prediction_label" msgid="3357562989568808658">"アプリの候補を表示しない"</string>
- <string name="pin_prediction" msgid="4196423321649756498">"アプリの候補を固定"</string>
<string name="permlab_install_shortcut" msgid="5632423390354674437">"ショートカットのインストール"</string>
<string name="permdesc_install_shortcut" msgid="923466509822011139">"ユーザー操作なしでショートカットを追加することをアプリに許可します。"</string>
<string name="permlab_read_settings" msgid="1941457408239617576">"ホームの設定とショートカットの読み取り"</string>
@@ -84,13 +60,15 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"ホームの設定とショートカットの書き込み"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"ホームの設定とショートカットの変更をアプリに許可します。"</string>
<string name="msg_no_phone_permission" msgid="9208659281529857371">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」から電話をかけることはできません"</string>
- <string name="gadget_error_text" msgid="740356548025791839">"ウィジェットを読み込めません"</string>
- <string name="gadget_setup_text" msgid="8348374825537681407">"ウィジェットの設定"</string>
- <string name="gadget_complete_setup_text" msgid="309040266978007925">"タップして設定を完了してください"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"ウィジェットを表示できません"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"セットアップ"</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"このシステムアプリはアンインストールできません。"</string>
- <string name="folder_hint_text" msgid="5174843001373488816">"名前の編集"</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"名前のないフォルダ"</string>
<string name="disabled_app_label" msgid="6673129024321402780">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」は無効です"</string>
- <string name="dotted_app_label" msgid="1704091277755818896">"{count,plural,offset:1 =1{{app_name} の通知が # 件あります}other{{app_name} の通知が # 件あります}}"</string>
+ <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+ <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g> の通知が <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> 件あります</item>
+ <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g> の通知が <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> 件あります</item>
+ </plurals>
<string name="default_scroll_format" msgid="7475544710230993317">"%1$d/%2$dページ"</string>
<string name="workspace_scroll_format" msgid="8458889198184077399">"ホーム画面: %1$d/%2$d"</string>
<string name="workspace_new_page" msgid="257366611030256142">"新しいホーム画面ページ"</string>
@@ -99,14 +77,14 @@
<string name="folder_tap_to_rename" msgid="4017685068016979677">"タップして変更後の名前を保存します"</string>
<string name="folder_closed" msgid="4100806530910930934">"フォルダは閉じています"</string>
<string name="folder_renamed" msgid="1794088362165669656">"フォルダの名前を「<xliff:g id="NAME">%1$s</xliff:g>」に変更しました"</string>
- <string name="folder_name_format_exact" msgid="8626242716117004803">"フォルダ: <xliff:g id="NAME">%1$s</xliff:g>、<xliff:g id="SIZE">%2$d</xliff:g> 件のアイテム"</string>
- <string name="folder_name_format_overflow" msgid="4270108890534995199">"フォルダ: <xliff:g id="NAME">%1$s</xliff:g>、<xliff:g id="SIZE">%2$d</xliff:g> 件以上のアイテム"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"フォルダ: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"ウィジェット"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"壁紙"</string>
- <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"壁紙とスタイル"</string>
+ <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"スタイルと壁紙"</string>
<string name="settings_button_text" msgid="8873672322605444408">"ホームの設定"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"管理者により無効にされています"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"ホーム画面の回転を許可"</string>
- <string name="allow_rotation_desc" msgid="8662546029078692509">"スマートフォンの向きに合わせます"</string>
+ <string name="allow_rotation_desc" msgid="8662546029078692509">"スマートフォンが回転したとき"</string>
<string name="notification_dots_title" msgid="9062440428204120317">"通知ドット"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"ON"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"OFF"</string>
@@ -114,16 +92,16 @@
<string name="msg_missing_notification_access" msgid="281113995110910548">"通知ドットを表示するには、「<xliff:g id="NAME">%1$s</xliff:g>」のアプリ通知を ON にしてください"</string>
<string name="title_change_settings" msgid="1376365968844349552">"設定を変更"</string>
<string name="notification_dots_service_title" msgid="4284221181793592871">"通知ドットの表示"</string>
- <string name="auto_add_shortcuts_label" msgid="3698776050751790653">"ホーム画面にアプリのアイコンを追加"</string>
- <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"新しいアプリをダウンロードしたときに自動で追加します"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"ホーム画面にアイコンを追加"</string>
+ <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"新しいアプリをダウンロードしたとき"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"不明"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"削除"</string>
<string name="abandoned_search" msgid="891119232568284442">"検索"</string>
<string name="abandoned_promises_title" msgid="7096178467971716750">"このアプリはインストールされていません"</string>
<string name="abandoned_promise_explanation" msgid="3990027586878167529">"このアイコンのアプリはインストールされていません。このアイコンは削除できます。または、手動でアプリを検索してインストールしください。"</string>
- <string name="app_installing_title" msgid="5864044122733792085">"<xliff:g id="NAME">%1$s</xliff:g> をインストールしています: <xliff:g id="PROGRESS">%2$s</xliff:g> 完了"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g>をダウンロード中、<xliff:g id="PROGRESS">%2$s</xliff:g>完了"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g>のインストール待ち"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"<xliff:g id="NAME">%1$s</xliff:g>のウィジェット"</string>
<string name="widgets_list" msgid="796804551140113767">"ウィジェット リスト"</string>
<string name="widgets_list_closed" msgid="6141506579418771922">"ウィジェット リストを閉じました"</string>
<string name="action_add_to_workspace" msgid="8902165848117513641">"ホーム画面に追加"</string>
@@ -151,20 +129,15 @@
<string name="action_deep_shortcut" msgid="2864038805849372848">"ショートカット"</string>
<string name="shortcuts_menu_with_notifications_description" msgid="2676582286544232849">"ショートカットと通知"</string>
<string name="action_dismiss_notification" msgid="5909461085055959187">"表示しない"</string>
- <string name="accessibility_close" msgid="2277148124685870734">"閉じる"</string>
<string name="notification_dismissed" msgid="6002233469409822874">"通知を非表示にしました"</string>
<string name="all_apps_personal_tab" msgid="4190252696685155002">"個人用"</string>
<string name="all_apps_work_tab" msgid="4884822796154055118">"仕事用"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"仕事用プロファイル"</string>
- <string name="work_profile_edu_work_apps" msgid="7895468576497746520">"仕事用アプリはバッジ付きで表示され、IT 管理者に公開されます"</string>
- <string name="work_profile_edu_accept" msgid="6069788082535149071">"OK"</string>
- <string name="work_apps_paused_title" msgid="3040901117349444598">"仕事用アプリの一時停止"</string>
- <string name="work_apps_paused_body" msgid="261634750995824906">"仕事用アプリでは、通知の送信、バッテリーの使用、位置情報の取得が無効になっています"</string>
- <string name="work_apps_paused_content_description" msgid="5149623040804051095">"仕事用アプリは OFF になっています。仕事用アプリでは、通知の送信、バッテリーの使用、位置情報の取得が無効になっています"</string>
- <string name="work_apps_paused_edu_banner" msgid="8872412121608402058">"仕事用アプリはバッジが付き、IT 管理者に公開されます"</string>
- <string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"OK"</string>
- <string name="work_apps_pause_btn_text" msgid="1921059713673767460">"仕事用アプリを OFF にする"</string>
- <string name="work_apps_enable_btn_text" msgid="1156432622148413741">"仕事用アプリを ON にする"</string>
- <string name="developer_options_filter_hint" msgid="5896817443635989056">"フィルタ"</string>
+ <string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"ここには仕事用アプリが表示されます"</string>
+ <string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"仕事用アプリにはバッジが表示され、組織によって安全に保護されています。仕事用アプリをホーム画面に移動すると、簡単にアクセスできます。"</string>
+ <string name="work_mode_on_label" msgid="4781128097185272916">"組織によって管理されています"</string>
+ <string name="work_mode_off_label" msgid="3194894777601421047">"通知とアプリは OFF です"</string>
+ <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"閉じる"</string>
+ <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"終了"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"失敗: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
</resources>
diff --git a/res/values-ka/strings.xml b/res/values-ka/strings.xml
index a0cbbc7dc8..e9afef9077 100644
--- a/res/values-ka/strings.xml
+++ b/res/values-ka/strings.xml
@@ -20,63 +20,39 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="649227358658669779">"Launcher3"</string>
+ <string name="folder_name" msgid="7371454440695724752"></string>
<string name="work_folder_name" msgid="3753320833950115786">"სამუშაო"</string>
<string name="activity_not_found" msgid="8071924732094499514">"აპი არ არის დაყენებული."</string>
<string name="activity_not_available" msgid="7456344436509528827">"აპი მიუწვდომელია"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"უსაფრთხო რეჟიმში ჩამოტვირთული აპი გაუქმებულია"</string>
<string name="safemode_widget_error" msgid="4863470563535682004">"უსაფრთხო რეჟიმში ვიჯეტი გამორთულია"</string>
<string name="shortcut_not_available" msgid="2536503539825726397">"მალსახმობი მიუწვდომელია"</string>
- <string name="home_screen" msgid="5629429142036709174">"მთავარი გვერდი"</string>
- <string name="recent_task_option_split_screen" msgid="6690461455618725183">"ეკრანის გაყოფა"</string>
- <string name="split_screen_position_top" msgid="1504965011158689649">"გაყოფილი ზემოთ"</string>
- <string name="split_screen_position_left" msgid="7537793098851830883">"გაყოფილი მარცხნივ"</string>
- <string name="split_screen_position_right" msgid="1569377524925193369">"გაყოფილი მარჯვნივ"</string>
- <string name="split_app_info_accessibility" msgid="5475288491241414932">"%1$s-ის აპის ინფო"</string>
- <string name="long_press_widget_to_add" msgid="3587712543577675817">"შეხებით აირჩიეთ და გეჭიროთ ვიჯეტის გადასაადგილებლად."</string>
- <string name="long_accessible_way_to_add" msgid="2733588281439571974">"ორმაგი შეხებით აირჩიეთ და გეჭიროთ ვიჯეტის გადასაადგილებლად ან მორგებული მოქმედებების გამოსაყენებლად."</string>
+ <string name="home_screen" msgid="806512411299847073">"მთავარი ეკრანი"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"მორგებული ქმედებები"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"შეეხეთ და დააყოვნეთ ვიჯეტის ასარჩევად."</string>
+ <string name="long_accessible_way_to_add" msgid="4289502106628154155">"ორმაგად შეეხეთ და გეჭიროთ ვიჯეტის ასარჩევად ან მორგებული მოქმედებების გამოსაყენებლად."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"სიგრძე: %1$d, სიგანე: %2$d"</string>
- <string name="widget_preview_context_description" msgid="9045841361655787574">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g> ვიჯეტი"</string>
- <string name="add_item_request_drag_hint" msgid="5653291305078645405">"ხანგრძლივად შეეხეთ ვიჯეტს მთავარ ეკრანზე მის გადასაადგილებლად"</string>
- <string name="add_to_home_screen" msgid="8631549138215492708">"მთავარ ეკრანზე დამატება"</string>
- <string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g> ვიჯეტი დამატებულია მთავარ ეკრანზე"</string>
- <string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# ვიჯეტი}other{# ვიჯეტი}}"</string>
- <string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{# მალსახმობი}other{# მალსახმობი}}"</string>
- <string name="widgets_and_shortcuts_count" msgid="7209136747878365116">"<xliff:g id="WIDGETS_COUNT">%1$s</xliff:g>, <xliff:g id="SHORTCUTS_COUNT">%2$s</xliff:g>"</string>
- <string name="widget_button_text" msgid="2880537293434387943">"ვიჯეტები"</string>
- <string name="widgets_full_sheet_search_bar_hint" msgid="8484659090860596457">"ძიება"</string>
- <string name="widgets_full_sheet_cancel_button_description" msgid="5766167035728653605">"ტექსტის გასუფთავება საძიებო ველიდან"</string>
- <string name="no_widgets_available" msgid="4337693382501046170">"ვიჯეტები და მალსახმობები ხელმისაწვდომი არ არის"</string>
- <string name="no_search_results" msgid="3787956167293097509">"ვიჯეტები ან მალსახმობები ვერ მოიძებნა"</string>
- <string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"პირადი"</string>
- <string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"სამსახური"</string>
- <string name="widget_category_conversations" msgid="8894438636213590446">"მიმოწერები"</string>
- <string name="widget_education_header" msgid="4874760613775913787">"ადვილად მისაწვდომი სასარგებლო ინფორმაცია"</string>
- <string name="widget_education_content" msgid="745542879510751525">"იმისთვის, რომ ინფორმაცია აპების გაუხსნელად მიიღოთ, შეგიძლიათ, მთავარ ეკრანზე ვიჯეტები დაამატოთ"</string>
- <string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"შეეხეთ ვიჯეტის პარამეტრების შესაცვლელად"</string>
- <string name="widget_education_close_button" msgid="8676165703104836580">"გასაგებია"</string>
- <string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"ვიჯეტის პარამეტრების შეცვლა"</string>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"ხანგრძლივად შეეხეთ ხელით განსათავსებლად"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"ავტომატურად დამატება"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"აპების ძიება"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"აპები იტვირთება…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"„<xliff:g id="QUERY">%1$s</xliff:g>“-ის თანხვედრი აპები არ მოიძებნა"</string>
<string name="all_apps_search_market_message" msgid="1366263386197059176">"მეტი აპის პოვნა"</string>
<string name="label_application" msgid="8531721983832654978">"აპი"</string>
- <string name="all_apps_label" msgid="5015784846527570951">"ყველა აპი"</string>
<string name="notifications_header" msgid="1404149926117359025">"შეტყობინებები"</string>
- <string name="long_press_shortcut_to_add" msgid="5405328730817637737">"შეხებით აირჩიეთ და გეჭიროთ მალსახმობის გადასაადგილებლად."</string>
- <string name="long_accessible_way_to_add_shortcut" msgid="2199537273817090740">"ორმაგი შეხებით აირჩიეთ და გეჭიროთ მალსახმობის გადასაადგილებლად ან მორგებული მოქმედებების გამოსაყენებლად."</string>
- <string name="out_of_space" msgid="6692471482459245734">"ამ მთავარ ეკრანზე ადგილი არ არის"</string>
+ <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"შეეხეთ და დააყოვნეთ მალსახმობის ასარჩევად."</string>
+ <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"ორმაგად შეეხეთ და გეჭიროთ მალსახმობის ასარჩევად ან მორგებული მოქმედებების გამოსაყენებლად."</string>
+ <string name="out_of_space" msgid="4691004494942118364">"ამ მთავარ ეკრანზე ადგილი აღარ არის."</string>
<string name="hotseat_out_of_space" msgid="7448809638125333693">"რჩეულების თაროზე ადგილი არ არის"</string>
<string name="all_apps_button_label" msgid="8130441508702294465">"აპების სია"</string>
- <string name="all_apps_search_results" msgid="5889367432531296759">"ძიების შედეგები"</string>
<string name="all_apps_button_personal_label" msgid="1315764287305224468">"პერსონალური აპების სია"</string>
<string name="all_apps_button_work_label" msgid="7270707118948892488">"სამსახურის აპების სია"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"მთავარი"</string>
<string name="remove_drop_target_label" msgid="7812859488053230776">"ამოშლა"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"დეინსტალაცია"</string>
<string name="app_info_drop_target_label" msgid="692894985365717661">"აპის შესახებ"</string>
<string name="install_drop_target_label" msgid="2539096853673231757">"ინსტალაცია"</string>
- <string name="dismiss_prediction_label" msgid="3357562989568808658">"არ შემომთავაზო აპი"</string>
- <string name="pin_prediction" msgid="4196423321649756498">"ჩამაგრების პროგნოზირება"</string>
<string name="permlab_install_shortcut" msgid="5632423390354674437">"მალსახმობების დაყენება"</string>
<string name="permdesc_install_shortcut" msgid="923466509822011139">"აპისთვის მალსახმობების დამოუკიდებლად დამატების უფლების მიცემა."</string>
<string name="permlab_read_settings" msgid="1941457408239617576">"მთავარი ეკრანის პარამეტრებისა და მალსახმობების წაკითხვა"</string>
@@ -84,13 +60,15 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"მთავარი ეკრანის პარამეტრებისა და მალსახმობების ჩაწერა"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"აპისთვის მთავარი ეკრანის პარამეტრებისა და მალსახმობების შეცვლის უფლების მიცემა."</string>
<string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g>-ს არ აქვს სატელეფონო ზარების განხორციელების უფლება"</string>
- <string name="gadget_error_text" msgid="740356548025791839">"ვიჯეტის ჩატვირთვა ვერ ხერხდება"</string>
- <string name="gadget_setup_text" msgid="8348374825537681407">"ვიჯეტის პარამეტრები"</string>
- <string name="gadget_complete_setup_text" msgid="309040266978007925">"შეეხეთ დაყენების დასასრულებლად"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"პრობლემა ვიჯეტის ჩატვირთვისას"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"დაყენება"</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"ეს სისტემური აპია და მისი წაშლა შეუძლებელია."</string>
- <string name="folder_hint_text" msgid="5174843001373488816">"სახელის რედაქტირება"</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"უსახელო საქაღალდე"</string>
<string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> გაითიშა"</string>
- <string name="dotted_app_label" msgid="1704091277755818896">"{count,plural,offset:1 =1{{app_name}-ში # შეტყობინებაა}other{{app_name}-ში # შეტყობინებაა}}"</string>
+ <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+ <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>-ში არის <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> შეტყობინება</item>
+ <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g>-ში არის <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> შეტყობინება</item>
+ </plurals>
<string name="default_scroll_format" msgid="7475544710230993317">"გვერდი %1$d %2$d-დან"</string>
<string name="workspace_scroll_format" msgid="8458889198184077399">"მთავარი ეკრანი %1$d, %2$d-დან"</string>
<string name="workspace_new_page" msgid="257366611030256142">"მთავარი ეკრანის ახალი გვერდი"</string>
@@ -99,10 +77,10 @@
<string name="folder_tap_to_rename" msgid="4017685068016979677">"შეეხეთ გადარქმეული სახელის შესანახად"</string>
<string name="folder_closed" msgid="4100806530910930934">"საქაღალდე დაიხურა"</string>
<string name="folder_renamed" msgid="1794088362165669656">"საქაღალდეს შეეცვალა სახელი „<xliff:g id="NAME">%1$s</xliff:g>“-ად"</string>
- <string name="folder_name_format_exact" msgid="8626242716117004803">"საქაღალდე: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> ერთეული"</string>
- <string name="folder_name_format_overflow" msgid="4270108890534995199">"საქაღალდე: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> ან მეტი ერთეული"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"საქაღალდე: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"ვიჯეტები"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"ფონები"</string>
- <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"ფონი და სტილი"</string>
+ <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"სტილები და ფონები"</string>
<string name="settings_button_text" msgid="8873672322605444408">"მთავარი გვერდის პარამეტრები"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"გათიშულია თქვენი ადმინისტრატორის მიერ"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"მთავარი ეკრანის შეტრიალების დაშვება"</string>
@@ -114,16 +92,16 @@
<string name="msg_missing_notification_access" msgid="281113995110910548">"შეტყობინებათა ნიშნულების საჩვენებლად, ჩართეთ აპის შეტყობინებები <xliff:g id="NAME">%1$s</xliff:g>-ისთვის"</string>
<string name="title_change_settings" msgid="1376365968844349552">"პარამეტრების შეცვლა"</string>
<string name="notification_dots_service_title" msgid="4284221181793592871">"შეტყობინების ნიშნულების ჩვენება"</string>
- <string name="auto_add_shortcuts_label" msgid="3698776050751790653">"აპის ხატულების მთავარ ეკრანზე დამატება"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"ხატულას მთავარ ეკრანზე დამატება"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"ახალი აპებისთვის"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"უცნობი"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"ამოშლა"</string>
<string name="abandoned_search" msgid="891119232568284442">"ძიება"</string>
<string name="abandoned_promises_title" msgid="7096178467971716750">"ეს აპი დაყენებული არ არის"</string>
<string name="abandoned_promise_explanation" msgid="3990027586878167529">"ამ ხატულის აპი დაყენებული არ არის. შეგიძლიათ ამოშალოთ, ან მოიძიოთ აპი და ხელით მოახდინოთ მისი ინსტალაცია."</string>
- <string name="app_installing_title" msgid="5864044122733792085">"ინსტალირდება <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="PROGRESS">%2$s</xliff:g> დასრულებულია"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"მიმდინარეობს <xliff:g id="NAME">%1$s</xliff:g>-ის ჩამოტვირთვა, <xliff:g id="PROGRESS">%2$s</xliff:g> დასრულდა"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> ელოდება ინსტალაციას"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"<xliff:g id="NAME">%1$s</xliff:g>-ის ვიჯეტები"</string>
<string name="widgets_list" msgid="796804551140113767">"ვიჯეტების სია"</string>
<string name="widgets_list_closed" msgid="6141506579418771922">"ვიჯეტების სია დაიხურა"</string>
<string name="action_add_to_workspace" msgid="8902165848117513641">"მთავარ ეკრანზე დამატება"</string>
@@ -151,20 +129,15 @@
<string name="action_deep_shortcut" msgid="2864038805849372848">"მალსახმობები"</string>
<string name="shortcuts_menu_with_notifications_description" msgid="2676582286544232849">"მალსახმობები და შეტყობინებები"</string>
<string name="action_dismiss_notification" msgid="5909461085055959187">"დახურვა"</string>
- <string name="accessibility_close" msgid="2277148124685870734">"დახურვა"</string>
<string name="notification_dismissed" msgid="6002233469409822874">"შეტყობინება დაიხურა"</string>
<string name="all_apps_personal_tab" msgid="4190252696685155002">"პირადი"</string>
<string name="all_apps_work_tab" msgid="4884822796154055118">"სამსახური"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"სამსახურის პროფილი"</string>
- <string name="work_profile_edu_work_apps" msgid="7895468576497746520">"სამსახურის აპები ბეჯით არის მონიშნული და ხილულია IT ადმინისტრატორისთვის"</string>
- <string name="work_profile_edu_accept" msgid="6069788082535149071">"გასაგებია"</string>
- <string name="work_apps_paused_title" msgid="3040901117349444598">"სამსახურის აპები დაპაუზებულია"</string>
- <string name="work_apps_paused_body" msgid="261634750995824906">"თქვენს სამსახურის აპებს არ შეუძლია თქვენთვის შეტყობინებების გამოგზავნა, თქვენი ბატარეის გამოყენება, ან თქვენს მდებარეობაზე წვდომა"</string>
- <string name="work_apps_paused_content_description" msgid="5149623040804051095">"სამსახურის აპები გამორთულია. თქვენს სამსახურის აპებს არ შეუძლია თქვენთვის შეტყობინებების გამოგზავნა, თქვენი ბატარეის გამოყენება, ან თქვენს მდებარეობაზე წვდომა"</string>
- <string name="work_apps_paused_edu_banner" msgid="8872412121608402058">"სამსახურის აპები ბეჯით არის მონიშნული და ხილულია IT ადმინისტრატორისთვის"</string>
- <string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"გასაგებია"</string>
- <string name="work_apps_pause_btn_text" msgid="1921059713673767460">"სამსახურის აპების გამორთვა"</string>
- <string name="work_apps_enable_btn_text" msgid="1156432622148413741">"სამსახურის აპების ჩართვა"</string>
- <string name="developer_options_filter_hint" msgid="5896817443635989056">"ფილტრი"</string>
+ <string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"აქ თავმოყრილია სამსახურის აპები"</string>
+ <string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"სამსახურის თითოეულ აპს აქვს ბეჯი, რაც ნიშნავს, რომ მათ უსაფრთხოებას თქვენი ორგანიზაცია უზრუნველყოფს. მარტივი წვდომისთვის, შეგიძლიათ სამსახურის აპები მთავარი ეკრანზე გადაიტანოთ."</string>
+ <string name="work_mode_on_label" msgid="4781128097185272916">"იმართება თქვენი ორგანიზაციის მიერ"</string>
+ <string name="work_mode_off_label" msgid="3194894777601421047">"შეტყობინებები და აპები გამორთულია"</string>
+ <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"დახურვა"</string>
+ <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"დახურული"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"ვერ მოხერხდა: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
</resources>
diff --git a/res/values-kk/strings.xml b/res/values-kk/strings.xml
index 529a00f550..1cd9045b76 100644
--- a/res/values-kk/strings.xml
+++ b/res/values-kk/strings.xml
@@ -20,77 +20,55 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="649227358658669779">"Launcher3"</string>
+ <string name="folder_name" msgid="7371454440695724752"></string>
<string name="work_folder_name" msgid="3753320833950115786">"Жұмыс"</string>
<string name="activity_not_found" msgid="8071924732094499514">"Қолданба орнатылмаған."</string>
<string name="activity_not_available" msgid="7456344436509528827">"Қолданба қол жетімді емес"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"Жүктелген қолданба қауіпсіз режимде өшірілген"</string>
<string name="safemode_widget_error" msgid="4863470563535682004">"Қауіпсіз режимде виджеттер өшіріледі"</string>
<string name="shortcut_not_available" msgid="2536503539825726397">"Таңбаша қолжетімді емес"</string>
- <string name="home_screen" msgid="5629429142036709174">"Негізгі экран"</string>
- <string name="recent_task_option_split_screen" msgid="6690461455618725183">"Экранды бөлу"</string>
- <string name="split_screen_position_top" msgid="1504965011158689649">"Жоғарыдан шығару"</string>
- <string name="split_screen_position_left" msgid="7537793098851830883">"Сол жақтан шығару"</string>
- <string name="split_screen_position_right" msgid="1569377524925193369">"Оң жақтан шығару"</string>
- <string name="split_app_info_accessibility" msgid="5475288491241414932">"%1$s қолданбасы туралы ақпарат"</string>
- <string name="long_press_widget_to_add" msgid="3587712543577675817">"Виджетті жылжыту үшін басып тұрыңыз."</string>
- <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Виджетті жылжыту үшін екі рет түртіңіз де, ұстап тұрыңыз немесе арнаулы әрекеттерді пайдаланыңыз."</string>
+ <string name="home_screen" msgid="806512411299847073">"Негізгі экран"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"Арнаулы әрекеттер"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"Виджетті таңдау үшін түртіп, мықтап ұстаңыз."</string>
+ <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Виджетті таңдау немесе арнаулы әрекеттерді таңдау үшін екі рет түртіп, ұстап тұрыңыз."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"Ені: %1$d, биіктігі: %2$d"</string>
- <string name="widget_preview_context_description" msgid="9045841361655787574">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g> виджеті"</string>
- <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Негізгі экранда қозғалту үшін виджетті басып тұрыңыз."</string>
- <string name="add_to_home_screen" msgid="8631549138215492708">"Негізгі экранға қосу"</string>
- <string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g> виджеті негізгі экранға енгізілді."</string>
- <string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# виджет}other{# виджет}}"</string>
- <string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{# таңбаша}other{# таңбаша}}"</string>
- <string name="widgets_and_shortcuts_count" msgid="7209136747878365116">"<xliff:g id="WIDGETS_COUNT">%1$s</xliff:g>, <xliff:g id="SHORTCUTS_COUNT">%2$s</xliff:g>"</string>
- <string name="widget_button_text" msgid="2880537293434387943">"Виджеттер"</string>
- <string name="widgets_full_sheet_search_bar_hint" msgid="8484659090860596457">"Іздеу"</string>
- <string name="widgets_full_sheet_cancel_button_description" msgid="5766167035728653605">"Мәтінді іздеу өрісінен өшіру"</string>
- <string name="no_widgets_available" msgid="4337693382501046170">"Виджеттер мен таңбашалар қолжетімді емес."</string>
- <string name="no_search_results" msgid="3787956167293097509">"Ешқандай виджет немесе таңбаша табылмады."</string>
- <string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Жеке виджеттер"</string>
- <string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Жұмыс виджеттері"</string>
- <string name="widget_category_conversations" msgid="8894438636213590446">"Әңгімелер"</string>
- <string name="widget_education_header" msgid="4874760613775913787">"Саусақпен түртсеңіз болғаны – пайдалы ақпарат көз алдыңызда"</string>
- <string name="widget_education_content" msgid="745542879510751525">"Қолданбаларды ашпай-ақ ақпарат алу үшін негізгі экранға тиісті виджеттерді қосыңыз."</string>
- <string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Виджет параметрлерін өзгерту үшін түртіңіз."</string>
- <string name="widget_education_close_button" msgid="8676165703104836580">"Түсінікті"</string>
- <string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Виджет параметрлерін өзгерту"</string>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Қолмен қою үшін басып тұрыңыз"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"Автоматты қосу"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Қолданбаларды іздеу"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Қолданбалар жүктелуде…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" сұрауына сәйкес келетін қолданбалар жоқ"</string>
<string name="all_apps_search_market_message" msgid="1366263386197059176">"Қосымша қолданбалар іздеу"</string>
<string name="label_application" msgid="8531721983832654978">"Қолданба"</string>
- <string name="all_apps_label" msgid="5015784846527570951">"Барлық қолданба"</string>
<string name="notifications_header" msgid="1404149926117359025">"Хабарландырулар"</string>
- <string name="long_press_shortcut_to_add" msgid="5405328730817637737">"Таңбашаны жылжыту үшін басып тұрыңыз."</string>
- <string name="long_accessible_way_to_add_shortcut" msgid="2199537273817090740">"Таңбашаны жылжыту үшін екі рет түртіңіз де, ұстап тұрыңыз немесе арнаулы әрекеттерді пайдаланыңыз."</string>
- <string name="out_of_space" msgid="6692471482459245734">"Негізгі экранда бос орын қалмады."</string>
+ <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"Таңбашаны таңдау үшін оны басып, ұстап тұрыңыз."</string>
+ <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"Екі рет басып, ұстап тұрып, таңбашаны таңдаңыз немесе арнаулы әрекеттерді пайдаланыңыз."</string>
+ <string name="out_of_space" msgid="4691004494942118364">"Бұл Негізгі экранда орын қалмады."</string>
<string name="hotseat_out_of_space" msgid="7448809638125333693">"Қалаулылар науасында орын қалмады"</string>
<string name="all_apps_button_label" msgid="8130441508702294465">"Қолданбалар тізімі"</string>
- <string name="all_apps_search_results" msgid="5889367432531296759">"Іздеу нәтижелері"</string>
<string name="all_apps_button_personal_label" msgid="1315764287305224468">"Жеке қолданбалар тізімі"</string>
<string name="all_apps_button_work_label" msgid="7270707118948892488">"Жұмыс қолданбаларының тізімі"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"Негізгі"</string>
<string name="remove_drop_target_label" msgid="7812859488053230776">"Алып тастау"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"Жою"</string>
<string name="app_info_drop_target_label" msgid="692894985365717661">"Қолданба ақпараты"</string>
<string name="install_drop_target_label" msgid="2539096853673231757">"Орнату"</string>
- <string name="dismiss_prediction_label" msgid="3357562989568808658">"Қолданбаны ұсынбау"</string>
- <string name="pin_prediction" msgid="4196423321649756498">"Болжанған қолданбаны бекіту"</string>
- <string name="permlab_install_shortcut" msgid="5632423390354674437">"таңбаша орнату"</string>
+ <string name="permlab_install_shortcut" msgid="5632423390354674437">"төте пернелерді орнату"</string>
<string name="permdesc_install_shortcut" msgid="923466509822011139">"Қолданбаға пайдаланушының қатысуынсыз төте пернелерді қосу мүмкіндігін береді."</string>
<string name="permlab_read_settings" msgid="1941457408239617576">"Негізгі экрандағы параметрлер мен төте пернелерді оқу"</string>
<string name="permdesc_read_settings" msgid="5833423719057558387">"Қолданбаға Негізгі экрандағы параметрлер мен төте пернелерді оқу мүмкіндігін береді."</string>
<string name="permlab_write_settings" msgid="3574213698004620587">"Негізгі экран параметрлері мен төте пернелерін жазу"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"Қолданбаға Негізгі экрандағы параметрлер мен төте пернелерді өзгерту мүмкіндігін береді."</string>
<string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> арқылы телефон қоңырауларын соғуға рұқсат етілмеген"</string>
- <string name="gadget_error_text" msgid="740356548025791839">"Виджетті жүктеу мүмкін емес."</string>
- <string name="gadget_setup_text" msgid="8348374825537681407">"Виджет параметрлері"</string>
- <string name="gadget_complete_setup_text" msgid="309040266978007925">"Реттеуді аяқтау үшін түртіңіз."</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"Виджетті жүктеу барысында мәселе орын алды"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"Орнату"</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"Бұл жүйе қолданбасы, сондықтан оны алу мүмкін емес."</string>
- <string name="folder_hint_text" msgid="5174843001373488816">"Атын өңдеу"</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"Атауы жоқ қалта"</string>
<string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> өшірілді"</string>
- <string name="dotted_app_label" msgid="1704091277755818896">"{count,plural,offset:1 =1{{app_name} қолданбасында # хабарландыру бар}other{{app_name} қолданбасында # хабарландыру бар}}"</string>
+ <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+ <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g> қолданбасында <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> хабарландыру бар</item>
+ <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g> қолданбасында <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> хабарландыру бар</item>
+ </plurals>
<string name="default_scroll_format" msgid="7475544710230993317">"%1$d бет, барлығы %2$d"</string>
<string name="workspace_scroll_format" msgid="8458889198184077399">"%1$d негізгі экран, барлығы %2$d"</string>
<string name="workspace_new_page" msgid="257366611030256142">"Жаңа негізгі экран беті"</string>
@@ -99,10 +77,10 @@
<string name="folder_tap_to_rename" msgid="4017685068016979677">"Қайта атауды сақтау үшін түртіңіз"</string>
<string name="folder_closed" msgid="4100806530910930934">"Қалта жабылды"</string>
<string name="folder_renamed" msgid="1794088362165669656">"Қалта атауы <xliff:g id="NAME">%1$s</xliff:g> болып өзгертілді"</string>
- <string name="folder_name_format_exact" msgid="8626242716117004803">"Қалта: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> элемент бар"</string>
- <string name="folder_name_format_overflow" msgid="4270108890534995199">"Қалта: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> не одан көп элемент бар"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"Қалта: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"Виджеттер"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Тұсқағаздар"</string>
- <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Тұсқағаз және стиль"</string>
+ <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Стильдер мен тұсқағаздар"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Негізгі экран параметрлері"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Әкімші өшірді"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Негізгі экранның бұрылуына рұқсат ету"</string>
@@ -114,16 +92,16 @@
<string name="msg_missing_notification_access" msgid="281113995110910548">"Хабарландыру белгілерін көрсету үшін <xliff:g id="NAME">%1$s</xliff:g> қолданбасының қолданба хабарландыруларын қосыңыз"</string>
<string name="title_change_settings" msgid="1376365968844349552">"Параметрлерді өзгерту"</string>
<string name="notification_dots_service_title" msgid="4284221181793592871">"Хабарландыру белгілерін көрсету"</string>
- <string name="auto_add_shortcuts_label" msgid="3698776050751790653">"Қолданба белгішесін негізгі экранға қосу"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Негізгі экранға белгіше енгізу"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Жаңа қолданбаларға арналған"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"Белгісіз"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"Алып тастау"</string>
<string name="abandoned_search" msgid="891119232568284442">"Іздеу"</string>
<string name="abandoned_promises_title" msgid="7096178467971716750">"Бұл қолданба орнатылмаған"</string>
<string name="abandoned_promise_explanation" msgid="3990027586878167529">"Осы белгіше үшін қолданба орнатылмаған. Оны жоюға болады немесе қолданбаны іздеп, қолмен орнатуға болады."</string>
- <string name="app_installing_title" msgid="5864044122733792085">"<xliff:g id="NAME">%1$s</xliff:g> орнатылуда, <xliff:g id="PROGRESS">%2$s</xliff:g> аяқталды"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> жүктелуде, <xliff:g id="PROGRESS">%2$s</xliff:g> аяқталды"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> орнату күтілуде"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"<xliff:g id="NAME">%1$s</xliff:g> виджеті"</string>
<string name="widgets_list" msgid="796804551140113767">"Виджеттер тізімі"</string>
<string name="widgets_list_closed" msgid="6141506579418771922">"Видджеттер тізімі жабылды"</string>
<string name="action_add_to_workspace" msgid="8902165848117513641">"Негізгі экранға қосу"</string>
@@ -151,20 +129,15 @@
<string name="action_deep_shortcut" msgid="2864038805849372848">"Таңбашалар"</string>
<string name="shortcuts_menu_with_notifications_description" msgid="2676582286544232849">"Таңбашалар мен хабарландырулар"</string>
<string name="action_dismiss_notification" msgid="5909461085055959187">"Бас тарту"</string>
- <string name="accessibility_close" msgid="2277148124685870734">"Жабу"</string>
<string name="notification_dismissed" msgid="6002233469409822874">"Хабарландырудан бас тартылды"</string>
<string name="all_apps_personal_tab" msgid="4190252696685155002">"Жеке"</string>
<string name="all_apps_work_tab" msgid="4884822796154055118">"Жұмыс"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"Жұмыс профилі"</string>
- <string name="work_profile_edu_work_apps" msgid="7895468576497746520">"Жұмыс қолданбаларының танымбелгілері бар және олар әкімшіңізге көрінеді."</string>
- <string name="work_profile_edu_accept" msgid="6069788082535149071">"Түсінікті"</string>
- <string name="work_apps_paused_title" msgid="3040901117349444598">"Жұмыс қолданбалары кідіртілді"</string>
- <string name="work_apps_paused_body" msgid="261634750995824906">"Жұмыс қолданбалары сізге хабарландырулар жібере, батареяңызды немесе локацияңызды пайдалана алмайды."</string>
- <string name="work_apps_paused_content_description" msgid="5149623040804051095">"Жұмыс қолданбалары өшірулі. Олар сізге хабарландырулар жібере, батареяңызды немесе локацияңызды пайдалана алмайды."</string>
- <string name="work_apps_paused_edu_banner" msgid="8872412121608402058">"Жұмыс қолданбаларының танымбелгілері бар және олар әкімшіңізге көрінеді."</string>
- <string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"Түсінікті"</string>
- <string name="work_apps_pause_btn_text" msgid="1921059713673767460">"Жұмыс қолданбаларын өшіру"</string>
- <string name="work_apps_enable_btn_text" msgid="1156432622148413741">"Жұмыс қолданбаларын қосу"</string>
- <string name="developer_options_filter_hint" msgid="5896817443635989056">"Сүзгі"</string>
+ <string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"Жұмыс қолданбалары осы жерде берілген"</string>
+ <string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"Әрбір жұмыс қолданбасында танымбелгі бар. Ол оның қауіпсіздігі ұйым арқылы қамтамасыз етілетінін білдіреді. Жұмыс қолданбаларына оңай кіру үшін, оларды Негізгі экранға жылжытуға болады."</string>
+ <string name="work_mode_on_label" msgid="4781128097185272916">"Ұйым арқылы басқарылады"</string>
+ <string name="work_mode_off_label" msgid="3194894777601421047">"Хабарландырулар мен қолданбалар өшірулі"</string>
+ <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Жабу"</string>
+ <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Жабық"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Қате шықты: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
</resources>
diff --git a/res/values-km/strings.xml b/res/values-km/strings.xml
index f8560aae61..973804200a 100644
--- a/res/values-km/strings.xml
+++ b/res/values-km/strings.xml
@@ -26,57 +26,32 @@
<string name="safemode_shortcut_error" msgid="9160126848219158407">"បាន​បិទ​កម្មវិធី​ដែល​បាន​ទាញ​យក​ក្នុង​របៀប​សុវត្ថិភាព"</string>
<string name="safemode_widget_error" msgid="4863470563535682004">"បាន​បិទ​ធាតុ​ក្រាហ្វិក​ក្នុង​របៀប​សុវត្ថិភាព"</string>
<string name="shortcut_not_available" msgid="2536503539825726397">"ផ្លូវកាត់មិនអាចប្រើបានទេ"</string>
- <string name="home_screen" msgid="5629429142036709174">"អេក្រង់ដើម"</string>
- <string name="recent_task_option_split_screen" msgid="6690461455618725183">"មុខងារ​បំបែកអេក្រង់"</string>
- <string name="split_screen_position_top" msgid="1504965011158689649">"បំបែក​ខាងលើ"</string>
- <string name="split_screen_position_left" msgid="7537793098851830883">"បំបែក​ខាងឆ្វេង"</string>
- <string name="split_screen_position_right" msgid="1569377524925193369">"បំបែក​ខាងស្ដាំ"</string>
- <string name="split_app_info_accessibility" msgid="5475288491241414932">"ព័ត៌មានកម្មវិធី​សម្រាប់ %1$s"</string>
- <string name="long_press_widget_to_add" msgid="3587712543577675817">"ចុចឱ្យជាប់​ដើម្បីផ្លាស់ទី​ធាតុក្រាហ្វិក​។"</string>
- <string name="long_accessible_way_to_add" msgid="2733588281439571974">"ចុចពីរដង រួចសង្កត់ឱ្យជាប់ ដើម្បីផ្លាស់ទី​ធាតុក្រាហ្វិក ឬប្រើ​សកម្មភាព​តាមបំណង​។"</string>
+ <string name="home_screen" msgid="806512411299847073">"អេក្រង់ដើម"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"សកម្មភាព​ផ្ទាល់ខ្លួន"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"ប៉ះ &amp; សង្កត់ ដើម្បី​ជ្រើស​ធាតុ​ក្រាហ្វិក។"</string>
+ <string name="long_accessible_way_to_add" msgid="4289502106628154155">"ប៉ះពីរដង ហើយចុចឲ្យជាប់ដើម្បីជ្រើសយកធាតុក្រាហ្វិក ឬប្រើសកម្មភាពផ្ទាល់ខ្លួន។"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"ទទឺង %1$d គុណនឹងកម្ពស់ %2$d"</string>
- <string name="widget_preview_context_description" msgid="9045841361655787574">"ធាតុ​ក្រាហ្វិក <xliff:g id="WIDGET_NAME">%1$s</xliff:g>"</string>
- <string name="add_item_request_drag_hint" msgid="5653291305078645405">"ចុចធាតុក្រាហ្វិក​ឱ្យជាប់ ដើម្បីផ្លាស់ទីវា​ជុំវិញអេក្រង់ដើម"</string>
- <string name="add_to_home_screen" msgid="8631549138215492708">"បញ្ចូល​ទៅអេក្រង់ដើម"</string>
- <string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"បានបញ្ចូល​ធាតុក្រាហ្វិក <xliff:g id="WIDGET_NAME">%1$s</xliff:g> ទៅ​អេក្រង់ដើម"</string>
- <string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{ធាតុ​ក្រាហ្វិក #}other{ធាតុ​ក្រាហ្វិក #}}"</string>
- <string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{ផ្លូវកាត់ #}other{ផ្លូវកាត់ #}}"</string>
- <string name="widgets_and_shortcuts_count" msgid="7209136747878365116">"<xliff:g id="WIDGETS_COUNT">%1$s</xliff:g>, <xliff:g id="SHORTCUTS_COUNT">%2$s</xliff:g>"</string>
- <string name="widget_button_text" msgid="2880537293434387943">"ធាតុ​ក្រាហ្វិក"</string>
- <string name="widgets_full_sheet_search_bar_hint" msgid="8484659090860596457">"ស្វែងរក"</string>
- <string name="widgets_full_sheet_cancel_button_description" msgid="5766167035728653605">"សម្អាត​ពាក្យឬឃ្លា​ចេញពី​ប្រអប់ស្វែងរក"</string>
- <string name="no_widgets_available" msgid="4337693382501046170">"មិនមាន​ធាតុក្រាហ្វិក និងផ្លូវកាត់​បានទេ"</string>
- <string name="no_search_results" msgid="3787956167293097509">"រកមិនឃើញ​ធាតុក្រាហ្វិក ឬផ្លូវកាត់​ទេ"</string>
- <string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"ផ្ទាល់ខ្លួន"</string>
- <string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"ការងារ"</string>
- <string name="widget_category_conversations" msgid="8894438636213590446">"ការសន្ទនា"</string>
- <string name="widget_education_header" msgid="4874760613775913787">"ទទួលបាន​ព័ត៌មានដែលមានប្រយោជន៍​យ៉ាងងាយស្រួល"</string>
- <string name="widget_education_content" msgid="745542879510751525">"ដើម្បីទទួលបាន​ព័ត៌មាន​ដោយមិនចាំបាច់​បើកកម្មវិធី អ្នកអាចបញ្ចូលធាតុ​ក្រាហ្វិកទៅក្នុង​អេក្រង់ដើម​របស់អ្នក"</string>
- <string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"ចុចដើម្បីប្ដូរការកំណត់ធាតុ​ក្រាហ្វិក"</string>
- <string name="widget_education_close_button" msgid="8676165703104836580">"យល់ហើយ"</string>
- <string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"ប្ដូរការកំណត់ធាតុ​ក្រាហ្វិក"</string>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"ចុច​ឲ្យជាប់​ដើម្បី​បញ្ចូលវា​ដោយផ្ទាល់"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"បញ្ចូល​ដោយ​ស្វ័យ​ប្រវត្តិ"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"ស្វែងរក​កម្មវិធី"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"កំពុងផ្ទុកកម្មវិធី…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"រកមិនឃើញកម្មវិធី​ដែលត្រូវគ្នាជាមួយ \"<xliff:g id="QUERY">%1$s</xliff:g>\" ទេ"</string>
<string name="all_apps_search_market_message" msgid="1366263386197059176">"ស្វែងរកកម្មវិធីច្រើនទៀត"</string>
<string name="label_application" msgid="8531721983832654978">"កម្មវិធី"</string>
- <string name="all_apps_label" msgid="5015784846527570951">"កម្មវិធី​ទាំងអស់"</string>
<string name="notifications_header" msgid="1404149926117359025">"ការ​ជូនដំណឹង"</string>
- <string name="long_press_shortcut_to_add" msgid="5405328730817637737">"ចុចឱ្យជាប់​ដើម្បីផ្លាស់ទី​ផ្លូវកាត់​។"</string>
- <string name="long_accessible_way_to_add_shortcut" msgid="2199537273817090740">"ចុចពីរដង រួចសង្កត់ឱ្យជាប់ ដើម្បីផ្លាស់ទី​ផ្លូវកាត់ ឬប្រើ​សកម្មភាព​តាមបំណង​។"</string>
- <string name="out_of_space" msgid="6692471482459245734">"គ្មានកន្លែង​នៅលើ​អេក្រង់ដើមនេះទេ"</string>
+ <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"ចុច​ឱ្យ​ជាប់​ដើម្បី​ជ្រើស​រើស​ផ្លូវកាត់​មួយ។"</string>
+ <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"ចុច​ពីរ​ដង ហើយ​ចុច​ឱ្យ​ជាប់​ដើម្បី​ជ្រើសរើស​ផ្លូវកាត់​មួយ ឬ​ប្រើ​សកម្មភាព​ផ្ទាល់ខ្លួន។"</string>
+ <string name="out_of_space" msgid="4691004494942118364">"គ្មាន​បន្ទប់​នៅ​លើ​អេក្រង់​ដើម​នេះ​ទៀត​ទេ។"</string>
<string name="hotseat_out_of_space" msgid="7448809638125333693">"គ្មាន​បន្ទប់​​ក្នុង​ថាស​និយម​ប្រើ"</string>
<string name="all_apps_button_label" msgid="8130441508702294465">"បញ្ជីកម្មវិធី"</string>
- <string name="all_apps_search_results" msgid="5889367432531296759">"លទ្ធផលស្វែងរក"</string>
<string name="all_apps_button_personal_label" msgid="1315764287305224468">"បញ្ជី​កម្មវិធី​ផ្ទាល់ខ្លួន"</string>
<string name="all_apps_button_work_label" msgid="7270707118948892488">"បញ្ជី​កម្មវិធី​ការងារ"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"ដើម"</string>
<string name="remove_drop_target_label" msgid="7812859488053230776">"យកចេញ"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"លុបការដំឡើង"</string>
<string name="app_info_drop_target_label" msgid="692894985365717661">"ព័ត៌មាន​កម្មវិធី"</string>
<string name="install_drop_target_label" msgid="2539096853673231757">"ដំឡើង"</string>
- <string name="dismiss_prediction_label" msgid="3357562989568808658">"កុំណែនាំកម្មវិធី"</string>
- <string name="pin_prediction" msgid="4196423321649756498">"ខ្ទាស់ការ​ព្យាករ"</string>
<string name="permlab_install_shortcut" msgid="5632423390354674437">"ដំឡើង​ផ្លូវកាត់"</string>
<string name="permdesc_install_shortcut" msgid="923466509822011139">"អនុញ្ញាត​ឲ្យ​កម្មវិធី​បន្ថែម​ផ្លូវកាត់​ ដោយ​មិន​ចាំបាច់​​អំពើ​ពី​អ្នក​ប្រើ។"</string>
<string name="permlab_read_settings" msgid="1941457408239617576">"អាន​ការ​កំណត់​ និង​ផ្លូវកាត់​​អេក្រង់​ដើម"</string>
@@ -84,13 +59,15 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"សរសេរ​ការ​កំណត់ ​និង​ផ្លូវកាត់​​លើ​អេក្រង់​ដើម"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"អនុញ្ញាត​ឲ្យ​កម្មវិធី​ប្ដូរ​ការ​កំណត់ និង​ផ្លូវ​កាត់​ក្នុង​អេក្រង់​ដើម។"</string>
<string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> មិនត្រូវបានអនុញ្ញាតឲ្យធ្វើការហៅទូរស័ព្ទទេ"</string>
- <string name="gadget_error_text" msgid="740356548025791839">"មិនអាចផ្ទុក​ធាតុក្រាហ្វិក​បានទេ"</string>
- <string name="gadget_setup_text" msgid="8348374825537681407">"ការកំណត់​ធាតុក្រាហ្វិក"</string>
- <string name="gadget_complete_setup_text" msgid="309040266978007925">"ចុច​ដើម្បី​បញ្ចប់​ការរៀបចំ"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"បញ្ហា​ក្នុង​ការ​ផ្ទុក​ធាតុ​​ក្រាហ្វិក"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"រៀបចំ"</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"នេះ​​​ជា​កម្មវិធី​ប្រព័ន្ធ មិន​អាច​លុប​បាន​ទេ។"</string>
- <string name="folder_hint_text" msgid="5174843001373488816">"កែ​ឈ្មោះ"</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"ថត​គ្មាន​ឈ្មោះ"</string>
<string name="disabled_app_label" msgid="6673129024321402780">"បានបិទដំណើរការ <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
- <string name="dotted_app_label" msgid="1704091277755818896">"{count,plural,offset:1 =1{{app_name} មានការជូនដំណឹង #}other{{app_name} មានការជូនដំណឹង #}}"</string>
+ <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+ <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, មាន​ការជូនដំណឹង <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g></item>
+ <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g>, មាន​ការជូនដំណឺង <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g></item>
+ </plurals>
<string name="default_scroll_format" msgid="7475544710230993317">"ទំព័រ %1$d នៃ %2$d"</string>
<string name="workspace_scroll_format" msgid="8458889198184077399">"អេក្រង់​ដើម %1$d នៃ %2$d"</string>
<string name="workspace_new_page" msgid="257366611030256142">"ទំព័រអេក្រង់ដើមថ្មី"</string>
@@ -99,10 +76,10 @@
<string name="folder_tap_to_rename" msgid="4017685068016979677">"ប៉ះដើម្បីរក្សាទុកឈ្មោះដែលបានប្តូរ"</string>
<string name="folder_closed" msgid="4100806530910930934">"បាន​បិទ​ថត"</string>
<string name="folder_renamed" msgid="1794088362165669656">"បាន​ប្ដូរ​ឈ្មោះ​ថត​ជា <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="folder_name_format_exact" msgid="8626242716117004803">"ថត៖ <xliff:g id="NAME">%1$s</xliff:g>, ធាតុ <xliff:g id="SIZE">%2$d</xliff:g>"</string>
- <string name="folder_name_format_overflow" msgid="4270108890534995199">"ថត៖ <xliff:g id="NAME">%1$s</xliff:g>, ធាតុ <xliff:g id="SIZE">%2$d</xliff:g> ឬច្រើនជាងនេះ"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"ថត៖ <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"ធាតុ​ក្រាហ្វិក"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"ផ្ទាំង​រូបភាព"</string>
- <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"ផ្ទាំងរូបភាព និងរចនាប័ទ្ម"</string>
+ <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"រចនាប័ទ្ម និង​ផ្ទាំង​រូបភាព"</string>
<string name="settings_button_text" msgid="8873672322605444408">"ការកំណត់​ទំព័រដើម"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"បានបិទដំណើរការដោយអ្នកគ្រប់គ្រងរបស់អ្នក"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"អនុញ្ញាតការបងិ្វលអេក្រង់ដើម"</string>
@@ -114,22 +91,22 @@
<string name="msg_missing_notification_access" msgid="281113995110910548">"ដើម្បីបង្ហាញស្លាកជូនដំណឹង សូមបើកការជូនដំណឹងកម្មវិធីសម្រាប់ <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="title_change_settings" msgid="1376365968844349552">"ប្ដូរ​ការកំណត់"</string>
<string name="notification_dots_service_title" msgid="4284221181793592871">"បង្ហាញ​ស្លាក​ជូនដំណឹង"</string>
- <string name="auto_add_shortcuts_label" msgid="3698776050751790653">"បញ្ចូល​រូបកម្មវិធី​ទៅក្នុង​អេក្រង់ដើម"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"បញ្ចូល​រូបតំណាង​ទៅ​អេក្រង់​ដើម"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"សម្រាប់កម្មវិធីថ្មី"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"មិន​ស្គាល់"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"លុបចេញ"</string>
<string name="abandoned_search" msgid="891119232568284442">"ស្វែងរក"</string>
<string name="abandoned_promises_title" msgid="7096178467971716750">"មិន​បាន​ដំឡើង​កម្មវិធី​នេះ"</string>
<string name="abandoned_promise_explanation" msgid="3990027586878167529">"មិន​បាន​ដំឡើង​កម្មវិធី​សម្រាប់​រូបតំណាង​នេះ។ អ្នក​អាច​លុប​វា ឬ​ស្វែងរក​កម្មវិធី និង​ដំឡើង​វា​ដោយ​ដៃ។"</string>
- <string name="app_installing_title" msgid="5864044122733792085">"កំពុង​ដំឡើង <xliff:g id="NAME">%1$s</xliff:g>, បាន​បញ្ចប់ <xliff:g id="PROGRESS">%2$s</xliff:g>"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"កំពុងដោនឡូត <xliff:g id="NAME">%1$s</xliff:g> បានបញ្ចប់ <xliff:g id="PROGRESS">%2$s</xliff:g>"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> កំពុងរង់ចាំការដំឡើង"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"ធាតុ​ក្រាហ្វិក <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="widgets_list" msgid="796804551140113767">"បញ្ជីធាតុ​ក្រាហ្វិក"</string>
<string name="widgets_list_closed" msgid="6141506579418771922">"បាន​បិទ​បញ្ជីធាតុ​ក្រាហ្វិក"</string>
<string name="action_add_to_workspace" msgid="8902165848117513641">"បញ្ចូលទៅអេក្រង់ដើម"</string>
<string name="action_move_here" msgid="2170188780612570250">"ផ្លាស់ធាតុមកទីនេះ"</string>
<string name="item_added_to_workspace" msgid="4211073925752213539">"ធាតុដែលត្រូវបានបន្ថែមទៅអេក្រង់ដើម"</string>
- <string name="item_removed" msgid="851119963877842327">"បានដកធាតុចេញ"</string>
+ <string name="item_removed" msgid="851119963877842327">"ធាតុដែលបានដកចេញ"</string>
<string name="undo" msgid="4151576204245173321">"ត្រឡប់វិញ"</string>
<string name="action_move" msgid="4339390619886385032">"ផ្លាស់ទីធាតុ"</string>
<string name="move_to_empty_cell" msgid="2833711483015685619">"ផ្លាស់ទីទៅជួរដេកទី <xliff:g id="NUMBER_0">%1$s</xliff:g> ជួរឈរទី <xliff:g id="NUMBER_1">%2$s</xliff:g>"</string>
@@ -150,21 +127,16 @@
<string name="widget_resized" msgid="9130327887929620">"ធាតុក្រាហ្វិកដែលបានប្តូរទំហំទៅទទឹងប្រវែង <xliff:g id="NUMBER_0">%1$s</xliff:g> កម្ពស់ប្រវែង <xliff:g id="NUMBER_1">%2$s</xliff:g>"</string>
<string name="action_deep_shortcut" msgid="2864038805849372848">"ផ្លូវកាត់"</string>
<string name="shortcuts_menu_with_notifications_description" msgid="2676582286544232849">"ផ្លូវកាត់ និង​ការជូនដំណឹង"</string>
- <string name="action_dismiss_notification" msgid="5909461085055959187">"ច្រានចោល"</string>
- <string name="accessibility_close" msgid="2277148124685870734">"បិទ"</string>
+ <string name="action_dismiss_notification" msgid="5909461085055959187">"បដិសេធ"</string>
<string name="notification_dismissed" msgid="6002233469409822874">"បាន​បដិសេធ​ការជូនដំណឹង"</string>
<string name="all_apps_personal_tab" msgid="4190252696685155002">"ផ្ទាល់ខ្លួន"</string>
<string name="all_apps_work_tab" msgid="4884822796154055118">"ការងារ"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"កម្រងព័ត៌មានការងារ"</string>
- <string name="work_profile_edu_work_apps" msgid="7895468576497746520">"កម្មវិធីការងារ​ត្រូវបានដាក់​គ្រឿងសម្គាល់ ហើយ​អ្នកគ្រប់គ្រង​ផ្នែកព័ត៌មានវិទ្យា​របស់អ្នក​អាចមើលឃើញ"</string>
- <string name="work_profile_edu_accept" msgid="6069788082535149071">"យល់ហើយ"</string>
- <string name="work_apps_paused_title" msgid="3040901117349444598">"កម្មវិធី​ការងារ​ត្រូវបានផ្អាក"</string>
- <string name="work_apps_paused_body" msgid="261634750995824906">"កម្មវិធី​ការងារ​របស់អ្នក​មិនអាចផ្ញើ​ការជូនដំណឹង​ទៅអ្នក ប្រើប្រាស់ថ្ម​របស់អ្នក ឬ​ចូលប្រើ​ទីតាំង​របស់អ្នក​បានទេ"</string>
- <string name="work_apps_paused_content_description" msgid="5149623040804051095">"កម្មវិធីការងារ​ត្រូវបានបិទ។ កម្មវិធីការងារ​របស់អ្នកមិនអាចផ្ញើ​ការជូនដំណឹង​ទៅអ្នក ប្រើប្រាស់ថ្ម​របស់អ្នក ឬ​ចូលប្រើ​ទីតាំង​របស់អ្នក​បានទេ"</string>
- <string name="work_apps_paused_edu_banner" msgid="8872412121608402058">"កម្មវិធីការងារ​ត្រូវបានដាក់​គ្រឿងសម្គាល់ ហើយ​អ្នកគ្រប់គ្រង​ផ្នែកព័ត៌មានវិទ្យា​របស់អ្នក​អាចមើលឃើញ"</string>
- <string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"យល់ហើយ"</string>
- <string name="work_apps_pause_btn_text" msgid="1921059713673767460">"បិទ​កម្មវិធីការងារ"</string>
- <string name="work_apps_enable_btn_text" msgid="1156432622148413741">"បើក​កម្មវិធី​ការងារ"</string>
- <string name="developer_options_filter_hint" msgid="5896817443635989056">"តម្រង"</string>
+ <string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"ស្វែង​រក​កម្មវិធី​ការងារ​នៅទីនេះ"</string>
+ <string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"កម្មវិធី​ការងារ​នីមួយៗ​មាន​ស្លាកមួយ និងត្រូវ​បានរក្សាទុក​យ៉ាងមានសុវត្ថិភាព​ដោយស្ថាប័ន​របស់អ្នក។ សូម​ផ្លាស់ទី​កម្មវិធី​ទៅកាន់​អេក្រង់​ដើម​របស់អ្នក​ ដើម្បី​ងាយស្រួល​ចូលប្រើជាងមុន។"</string>
+ <string name="work_mode_on_label" msgid="4781128097185272916">"គ្រប់គ្រងដោយ​ស្ថាប័ន​របស់អ្នក"</string>
+ <string name="work_mode_off_label" msgid="3194894777601421047">"ការជូនដំណឹង​ និងកម្មវិធី​ត្រូវបានបិទ"</string>
+ <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"បិទ"</string>
+ <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"បានបិទ"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"បានបរាជ័យ៖ <xliff:g id="WHAT">%1$s</xliff:g>"</string>
</resources>
diff --git a/res/values-kn/strings.xml b/res/values-kn/strings.xml
index 9eda419086..67ea6a830a 100644
--- a/res/values-kn/strings.xml
+++ b/res/values-kn/strings.xml
@@ -26,57 +26,32 @@
<string name="safemode_shortcut_error" msgid="9160126848219158407">"ಡೌನ್‌ಲೋಡ್ ಮಾಡಲಾದ ಅಪ್ಲಿಕೇಶನ್ ಅನ್ನು ಸುರಕ್ಷಿತ ಮೋಡ್‌ನಲ್ಲಿ ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ"</string>
<string name="safemode_widget_error" msgid="4863470563535682004">"ಸುರಕ್ಷಿತ ಮೋಡ್‌ನಲ್ಲಿ ವಿಜೆಟ್‌ಗಳನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ"</string>
<string name="shortcut_not_available" msgid="2536503539825726397">"ಶಾರ್ಟ್‌ಕಟ್ ಲಭ್ಯವಿಲ್ಲ"</string>
- <string name="home_screen" msgid="5629429142036709174">"ಹೋಮ್"</string>
- <string name="recent_task_option_split_screen" msgid="6690461455618725183">"ಸ್ಪ್ಲಿಟ್ ಸ್ಕ್ರೀನ್"</string>
- <string name="split_screen_position_top" msgid="1504965011158689649">"ಮೇಲಕ್ಕೆ ವಿಭಜಿಸಿ"</string>
- <string name="split_screen_position_left" msgid="7537793098851830883">"ಎಡಕ್ಕೆ ವಿಭಜಿಸಿ"</string>
- <string name="split_screen_position_right" msgid="1569377524925193369">"ಬಲಕ್ಕೆ ವಿಭಜಿಸಿ"</string>
- <string name="split_app_info_accessibility" msgid="5475288491241414932">"%1$s ಗಾಗಿ ಆ್ಯಪ್ ಮಾಹಿತಿ"</string>
- <string name="long_press_widget_to_add" msgid="3587712543577675817">"ವಿಜೆಟ್ ಸರಿಸಲು ಸ್ಪರ್ಶಿಸಿ ಮತ್ತು ಹಿಡಿದುಕೊಳ್ಳಿ."</string>
- <string name="long_accessible_way_to_add" msgid="2733588281439571974">"ವಿಜೆಟ್ ಸರಿಸಲು ಅಥವಾ ಕಸ್ಟಮ್ ಕ್ರಿಯೆಗಳನ್ನು ಬಳಸಲು ಡಬಲ್-ಟ್ಯಾಪ್ ಮಾಡಿ ಮತ್ತು ಹಿಡಿದುಕೊಳ್ಳಿ."</string>
+ <string name="home_screen" msgid="806512411299847073">"ಮುಖಪುಟದ ಪರದೆ"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"ಕಸ್ಟಮ್ ಕ್ರಿಯೆಗಳು"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"ವಿಜೆಟ್ ಅನ್ನು ಆರಿಸಿಕೊಳ್ಳಲು ಸ್ಪರ್ಶಿಸಿ &amp; ಹಿಡಿದುಕೊಳ್ಳಿ."</string>
+ <string name="long_accessible_way_to_add" msgid="4289502106628154155">"ಡಬಲ್ ಟ್ಯಾಪ್ ಮಾಡಿ ಮತ್ತು ವಿಜೆಟ್ ಆರಿಸಿಕೊಳ್ಳಲು ಹೋಲ್ಡ್ ಮಾಡಿ ಅಥವಾ ಕಸ್ಟಮ್ ಕ್ರಿಯೆಗಳನ್ನು ಬಳಸಿ"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d ಅಗಲ ಮತ್ತು %2$d ಎತ್ತರ"</string>
- <string name="widget_preview_context_description" msgid="9045841361655787574">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g> ವಿಜೆಟ್"</string>
- <string name="add_item_request_drag_hint" msgid="5653291305078645405">"ಮುಖಪುಟದ ಪರದೆ ಸುತ್ತ ವಿಜೆಟ್ ಅನ್ನು ಸರಿಸಲು, ಸ್ಪರ್ಶಿಸಿ ಮತ್ತು ಒತ್ತಿ ಹಿಡಿದುಕೊಳ್ಳಿ"</string>
- <string name="add_to_home_screen" msgid="8631549138215492708">"ಮುಖಪುಟಕ್ಕೆ ಸೇರಿಸಿ"</string>
- <string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"ಹೋಮ್‌ಸ್ಕ್ರೀನ್‌ಗೆ <xliff:g id="WIDGET_NAME">%1$s</xliff:g> ವಿಜೆಟ್ ಅನ್ನು ಸೇರಿಸಲಾಗಿದೆ"</string>
- <string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# ವಿಜೆಟ್}one{# ವಿಜೆಟ್‌ಗಳು}other{# ವಿಜೆಟ್‌ಗಳು}}"</string>
- <string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{# ಶಾರ್ಟ್‌ಕಟ್}one{# ಶಾರ್ಟ್‌ಕಟ್‌ಗಳು}other{# ಶಾರ್ಟ್‌ಕಟ್‌ಗಳು}}"</string>
- <string name="widgets_and_shortcuts_count" msgid="7209136747878365116">"<xliff:g id="WIDGETS_COUNT">%1$s</xliff:g>, <xliff:g id="SHORTCUTS_COUNT">%2$s</xliff:g>"</string>
- <string name="widget_button_text" msgid="2880537293434387943">"ವಿಜೆಟ್‌ಗಳು"</string>
- <string name="widgets_full_sheet_search_bar_hint" msgid="8484659090860596457">"ಹುಡುಕಿ"</string>
- <string name="widgets_full_sheet_cancel_button_description" msgid="5766167035728653605">"ಹುಡುಕಾಟ ಪೆಟ್ಟಿಗೆಯಿಂದ ಪಠ್ಯವನ್ನು ತೆರವುಗೊಳಿಸಿ"</string>
- <string name="no_widgets_available" msgid="4337693382501046170">"ವಿಜೆಟ್‌ಗಳು ಮತ್ತು ಶಾರ್ಟ್‌ಕಟ್‌ಗಳು ಲಭ್ಯವಿಲ್ಲ"</string>
- <string name="no_search_results" msgid="3787956167293097509">"ಯಾವುದೇ ವಿಜೆಟ್‌ಗಳು ಅಥವಾ ಶಾರ್ಟ್‌ಕಟ್‌ಗಳು ಕಂಡುಬಂದಿಲ್ಲ"</string>
- <string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"ವೈಯಕ್ತಿಕ"</string>
- <string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"ಕೆಲಸ"</string>
- <string name="widget_category_conversations" msgid="8894438636213590446">"ಸಂವಾದಗಳು"</string>
- <string name="widget_education_header" msgid="4874760613775913787">"ನಿಮ್ಮ ಬೆರಳ ತುದಿಯಲ್ಲಿ ಉಪಯುಕ್ತ ಮಾಹಿತಿ"</string>
- <string name="widget_education_content" msgid="745542879510751525">"ಆ್ಯಪ್‌ಗಳನ್ನು ತೆರೆಯದೆಯೇ ಮಾಹಿತಿಯನ್ನು ಪಡೆಯಲು, ನಿಮ್ಮ ಹೋಮ್ ಸ್ಕ್ರೀನ್‌ನಲ್ಲಿ ನೀವು ವಿಜೆಟ್‌ಗಳನ್ನು ಸೇರಿಸಬಹುದು"</string>
- <string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"ವಿಜೆಟ್ ಸೆಟ್ಟಿಂಗ್‌ಗಳನ್ನು ಬದಲಾಯಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
- <string name="widget_education_close_button" msgid="8676165703104836580">"ಅರ್ಥವಾಯಿತು"</string>
- <string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"ವಿಜೆಟ್ ಸೆಟ್ಟಿಂಗ್‌ಗಳನ್ನು ಬದಲಾಯಿಸಿ"</string>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"ಹಸ್ತಚಾಲಿತವಾಗಿ ಸೇರಿಸಲು ಸ್ಪರ್ಶಿಸಿ ಮತ್ತು ಹೋಲ್ಡ್ ಮಾಡಿ"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"ಸ್ವಯಂಚಾಲಿತವಾಗಿ ಸೇರಿಸಿ"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"ಅಪ್ಲಿಕೇಶನ್‌ಗಳನ್ನು ಹುಡುಕಿ"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"ಅಪ್ಲಿಕೇಶನ್‌ಗಳನ್ನು ಲೋಡ್ ಮಾಡಲಾಗುತ್ತಿದೆ..."</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" ಹೊಂದಿಕೆಯ ಯಾವುದೇ ಅಪ್ಲಿಕೇಶನ್‌ಗಳು ಕಂಡುಬಂದಿಲ್ಲ"</string>
<string name="all_apps_search_market_message" msgid="1366263386197059176">"ಮತ್ತಷ್ಟು ಅಪ್ಲಿಕೇಶನ್‌ಗಳನ್ನು ಹುಡುಕಿ"</string>
<string name="label_application" msgid="8531721983832654978">"ಆ್ಯಪ್"</string>
- <string name="all_apps_label" msgid="5015784846527570951">"ಎಲ್ಲಾ ಆ್ಯಪ್‌ಗಳು"</string>
<string name="notifications_header" msgid="1404149926117359025">"ಅಧಿಸೂಚನೆಗಳು"</string>
- <string name="long_press_shortcut_to_add" msgid="5405328730817637737">"ಶಾರ್ಟ್‌ಕಟ್ ಸರಿಸಲು ಸ್ಪರ್ಶಿಸಿ ಮತ್ತು ಹಿಡಿದುಕೊಳ್ಳಿ."</string>
- <string name="long_accessible_way_to_add_shortcut" msgid="2199537273817090740">"ಶಾರ್ಟ್‌ಕಟ್ ಸರಿಸಲು ಅಥವಾ ಕಸ್ಟಮ್ ಕ್ರಿಯೆಗಳನ್ನು ಬಳಸಲು ಡಬಲ್-ಟ್ಯಾಪ್ ಮಾಡಿ ಮತ್ತು ಹಿಡಿದುಕೊಳ್ಳಿ."</string>
- <string name="out_of_space" msgid="6692471482459245734">"ಈ ಹೋಮ್ ಸ್ಕ್ರೀನ್‌ನಲ್ಲಿ ಸ್ಥಳಾವಕಾಶವಿಲ್ಲ"</string>
+ <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"ಸ್ಪರ್ಶಿಸಿ ಮತ್ತು ಶಾರ್ಟ್‌ಕಟ್ ಆರಿಸಲು ಹೋಲ್ಡ್ ಮಾಡಿ."</string>
+ <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"ಡಬಲ್ ಟ್ಯಾಪ್ ಮಾಡಿ ಮತ್ತು ಶಾರ್ಟ್‌ಕಟ್ ಆರಿಸಿಕೊಳ್ಳಲು ಹೋಲ್ಡ್ ಮಾಡಿ ಅಥವಾ ಕಸ್ಟಮ್ ಕ್ರಿಯೆಗಳನ್ನು ಬಳಸಿ."</string>
+ <string name="out_of_space" msgid="4691004494942118364">"ಈ ಮುಖಪುಟದ ಪರದೆಯಲ್ಲಿ ಹೆಚ್ಚು ಸ್ಥಳಾವಕಾಶವಿಲ್ಲ."</string>
<string name="hotseat_out_of_space" msgid="7448809638125333693">"ಮೆಚ್ಚಿನವುಗಳ ಟ್ರೇನಲ್ಲಿ ಹೆಚ್ಚಿನ ಸ್ಥಳಾವಕಾಶವಿಲ್ಲ"</string>
<string name="all_apps_button_label" msgid="8130441508702294465">"ಅಪ್ಲಿಕೇಶನ್‌ಗಳ ಪಟ್ಟಿ"</string>
- <string name="all_apps_search_results" msgid="5889367432531296759">"ಹುಡುಕಾಟ ಫಲಿತಾಂಶಗಳು"</string>
<string name="all_apps_button_personal_label" msgid="1315764287305224468">"ವೈಯಕ್ತಿಕ ಅಪ್ಲಿಕೇಶನ್‌ಗಳ ಪಟ್ಟಿ"</string>
<string name="all_apps_button_work_label" msgid="7270707118948892488">"ಕೆಲಸದ ಅಪ್ಲಿಕೇಶನ್‌ಗಳ ಪಟ್ಟಿ"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"ಮುಖಪುಟ"</string>
<string name="remove_drop_target_label" msgid="7812859488053230776">"ತೆಗೆದುಹಾಕಿ"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"ಅನ್‌ಇನ್‌ಸ್ಟಾಲ್"</string>
<string name="app_info_drop_target_label" msgid="692894985365717661">"ಅಪ್ಲಿಕೇಶನ್ ಮಾಹಿತಿ"</string>
<string name="install_drop_target_label" msgid="2539096853673231757">"ಸ್ಥಾಪಿಸಿ"</string>
- <string name="dismiss_prediction_label" msgid="3357562989568808658">"ಆ್ಯಪ್ ಅನ್ನು ಸೂಚಿಸಬೇಡಿ"</string>
- <string name="pin_prediction" msgid="4196423321649756498">"ಮುನ್ನೋಟ ಪಿನ್ ಮಾಡಿ"</string>
<string name="permlab_install_shortcut" msgid="5632423390354674437">"ಶಾರ್ಟ್‌ಕಟ್‌ಗಳನ್ನು ಸ್ಥಾಪಿಸಿ"</string>
<string name="permdesc_install_shortcut" msgid="923466509822011139">"ಬಳಕೆದಾರರ ಹಸ್ತಕ್ಷೇಪವಿಲ್ಲದೆ ಶಾರ್ಟ್‌ಕಟ್‌ಗಳನ್ನು ಸೇರಿಸಲು ಅಪ್ಲಿಕೇಶನ್‌ಗೆ ಅನುಮತಿಸುತ್ತದೆ."</string>
<string name="permlab_read_settings" msgid="1941457408239617576">"ಮುಖಪುಟದ ಸೆಟ್ಟಿಂಗ್‌ಗಳು ಮತ್ತು ಶಾರ್ಟ್‌ಕಟ್‌ಗಳನ್ನು ಓದಿ"</string>
@@ -84,13 +59,15 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"ಮುಖಪುಟದ ಸೆಟ್ಟಿಂಗ್‌ಗಳು ಮತ್ತು ಶಾರ್ಟ್‌ಕಟ್‌ಗಳನ್ನು ಬರೆಯಿರಿ"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"ಮುಖಪುಟದಲ್ಲಿ ಸೆಟ್ಟಿಂಗ್‌ಗಳು ಮತ್ತು ಶಾರ್ಟ್‌ಕಟ್‌ಗಳನ್ನು ಬದಲಾಯಿಸಲು ಅಪ್ಲಿಕೇಶನ್‌ಗೆ ಅನುಮತಿ ನೀಡುತ್ತದೆ."</string>
<string name="msg_no_phone_permission" msgid="9208659281529857371">"ಫೋನ್ ಕರೆಗಳನ್ನು ಮಾಡಲು <xliff:g id="APP_NAME">%1$s</xliff:g> ಅಪ್ಲಿಕೇಶನ್‌‌ಗೆ ಅನುಮತಿಸಲಾಗುವುದಿಲ್ಲ"</string>
- <string name="gadget_error_text" msgid="740356548025791839">"ವಿಜೆಟ್ ಅನ್ನು ಲೋಡ್ ಮಾಡಲು ಸಾಧ್ಯವಿಲ್ಲ"</string>
- <string name="gadget_setup_text" msgid="8348374825537681407">"ವಿಜೆಟ್ ಸೆಟ್ಟಿಂಗ್‌ಗಳು"</string>
- <string name="gadget_complete_setup_text" msgid="309040266978007925">"ಸೆಟಪ್ ಪೂರ್ಣಗೊಳಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"ವಿಜೆಟ್ ಲೋಡ್‌ ಮಾಡುವಲ್ಲಿ ಸಮಸ್ಯೆ"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"ಸೆಟಪ್"</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"ಇದೊಂದು ಅಪ್ಲಿಕೇಶನ್ ಆಗಿದೆ ಮತ್ತು ಅಸ್ಥಾಪಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ."</string>
- <string name="folder_hint_text" msgid="5174843001373488816">"ಹೆಸರನ್ನು ಎಡಿಟ್ ಮಾಡಿ"</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"ಹೆಸರಿಲ್ಲದ ಫೋಲ್ಡರ್"</string>
<string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ"</string>
- <string name="dotted_app_label" msgid="1704091277755818896">"{count,plural,offset:1 =1{{app_name} ಆ್ಯಪ್‌ # ಅಧಿಸೂಚನೆಯನ್ನು ಹೊಂದಿದೆ}one{{app_name} ಆ್ಯಪ್‌ # ಅಧಿಸೂಚನೆಗಳನ್ನು ಹೊಂದಿದೆ}other{{app_name} ಆ್ಯಪ್‌ # ಅಧಿಸೂಚನೆಗಳನ್ನು ಹೊಂದಿದೆ}}"</string>
+ <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+ <item quantity="one"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> ಅಧಿಸೂಚನೆಗಳನ್ನು ಹೊಂದಿದೆ</item>
+ <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> ಅಧಿಸೂಚನೆಗಳನ್ನು ಹೊಂದಿದೆ</item>
+ </plurals>
<string name="default_scroll_format" msgid="7475544710230993317">"%2$d ರಲ್ಲಿ %1$d ಪುಟ"</string>
<string name="workspace_scroll_format" msgid="8458889198184077399">"%2$d ರಲ್ಲಿ %1$d ಮುಖಪುಟದ ಪರದೆ"</string>
<string name="workspace_new_page" msgid="257366611030256142">"ಹೊಸ ಮುಖಪುಟ ಪರದೆ"</string>
@@ -99,10 +76,10 @@
<string name="folder_tap_to_rename" msgid="4017685068016979677">"ಮರುಹೆಸರನ್ನು ಉಳಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
<string name="folder_closed" msgid="4100806530910930934">"ಫೋಲ್ಡರ್ ಮುಚ್ಚಿದೆ"</string>
<string name="folder_renamed" msgid="1794088362165669656">"ಫೋಲ್ಡರ್‌ ಅನ್ನು <xliff:g id="NAME">%1$s</xliff:g> ಗೆ ಮರುಹೆಸರಿಸಲಾಗಿದೆ"</string>
- <string name="folder_name_format_exact" msgid="8626242716117004803">"ಫೋಲ್ಡರ್: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> ಐಟಂಗಳು"</string>
- <string name="folder_name_format_overflow" msgid="4270108890534995199">"ಫೋಲ್ಡರ್: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> ಅಥವಾ ಹೆಚ್ಚಿನ ಐಟಂಗಳು"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"ಫೋಲ್ಡರ್: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"ವಿಜೆಟ್‌ಗಳು"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"ವಾಲ್‌ಪೇಪರ್‌ಗಳು"</string>
- <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"ವಾಲ್‌ಪೇಪರ್ ಮತ್ತು ಶೈಲಿ"</string>
+ <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"ಶೈಲಿಗಳು &amp; ವಾಲ್‌ಪೇಪರ್‌ಗಳು"</string>
<string name="settings_button_text" msgid="8873672322605444408">"ಮುಖಪುಟ ಸೆಟ್ಟಿಂಗ್‌ಗಳು"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"ನಿಮ್ಮ ನಿರ್ವಾಹಕರು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿದ್ದಾರೆ"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"ಮುಖಪುಟ ತಿರುಗುವಿಕೆಯನ್ನು ಅನುಮತಿಸಿ"</string>
@@ -114,16 +91,16 @@
<string name="msg_missing_notification_access" msgid="281113995110910548">"ಅಧಿಸೂಚನೆ ಚುಕ್ಕೆಗಳನ್ನು ತೋರಿಸಲು, <xliff:g id="NAME">%1$s</xliff:g> ಗೆ ಅಪ್ಲಿಕೇಶನ್‌ ಅಧಿಸೂಚನೆಗಳನ್ನು ಆನ್‌ ಮಾಡಿ"</string>
<string name="title_change_settings" msgid="1376365968844349552">"ಸೆಟ್ಟಿಂಗ್‌‌ಗಳನ್ನು ಬದಲಾಯಿಸಿ"</string>
<string name="notification_dots_service_title" msgid="4284221181793592871">"ಅಧಿಸೂಚನೆ ಡಾಟ್‌ಗಳನ್ನು ತೋರಿಸಿ"</string>
- <string name="auto_add_shortcuts_label" msgid="3698776050751790653">"ಹೋಮ್ ಸ್ಕ್ರೀನ್‌ಗೆ ಆ್ಯಪ್ ಐಕಾನ್‌ಗಳು ಸೇರಿಸಿ"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"ಮುಖಪುಟದ ಪರದೆಗೆ ಐಕಾನ್ ಸೇರಿಸಿ"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"ಹೊಸ ಅಪ್ಲಿಕೇಶನ್‌ಗಳಿಗೆ"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"ಅಪರಿಚಿತ"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"ತೆಗೆದುಹಾಕಿ"</string>
<string name="abandoned_search" msgid="891119232568284442">"ಹುಡುಕಿ"</string>
<string name="abandoned_promises_title" msgid="7096178467971716750">"ಈ ಅಪ್ಲಿಕೇಶನ್ ಸ್ಥಾಪನೆಗೊಂಡಿಲ್ಲ"</string>
<string name="abandoned_promise_explanation" msgid="3990027586878167529">"ಈ ಐಕಾನ್ ಅಪ್ಲಿಕೇಶನ್ ಸ್ಥಾಪನೆಗೊಂಡಿಲ್ಲ. ನೀವು ಅದನ್ನು ತೆಗೆದುಹಾಕಬಹುದು ಅಥವಾ ಅಪ್ಲಿಕೇಶನ್ ಹುಡುಕಬಹುದು ಮತ್ತು ಹಸ್ತಚಾಲಿತವಾಗಿ ಅದನ್ನು ಸ್ಥಾಪಿಸಬಹುದು."</string>
- <string name="app_installing_title" msgid="5864044122733792085">"<xliff:g id="NAME">%1$s</xliff:g> ಇನ್‌ಸ್ಟಾಲ್ ಮಾಡಲಾಗುತ್ತಿದೆ, <xliff:g id="PROGRESS">%2$s</xliff:g> ಪೂರ್ಣಗೊಂಡಿದೆ"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> ಡೌನ್‌ಲೋಡ್‌ ಮಾಡಲಾಗುತ್ತಿದೆ, <xliff:g id="PROGRESS">%2$s</xliff:g> ಪೂರ್ಣಗೊಂಡಿದೆ"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> ಸ್ಥಾಪಿಸಲು ಕಾಯಲಾಗುತ್ತಿದೆ"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"<xliff:g id="NAME">%1$s</xliff:g> ವಿಜೆಟ್‌ಗಳು"</string>
<string name="widgets_list" msgid="796804551140113767">"ವಿಜೆಟ್ ಪಟ್ಟಿ"</string>
<string name="widgets_list_closed" msgid="6141506579418771922">"ವಿಜೆಟ್ ಪಟ್ಟಿಯನ್ನು ಮುಚ್ಚಲಾಗಿದೆ"</string>
<string name="action_add_to_workspace" msgid="8902165848117513641">"ಮುಖಪುಟಕ್ಕೆ ಸೇರಿಸಿ"</string>
@@ -151,20 +128,15 @@
<string name="action_deep_shortcut" msgid="2864038805849372848">"ಶಾರ್ಟ್‌ಕಟ್‌ಗಳು"</string>
<string name="shortcuts_menu_with_notifications_description" msgid="2676582286544232849">"ಶಾರ್ಟ್‌ಕಟ್‌ಗಳು ಮತ್ತು ಅಧಿಸೂಚನೆಗಳು"</string>
<string name="action_dismiss_notification" msgid="5909461085055959187">"ವಜಾಗೊಳಿಸಿ"</string>
- <string name="accessibility_close" msgid="2277148124685870734">"ಮುಚ್ಚಿರಿ"</string>
<string name="notification_dismissed" msgid="6002233469409822874">"ಅಧಿಸೂಚನೆಯನ್ನು ವಜಾಗೊಳಿಸಲಾಗಿದೆ"</string>
<string name="all_apps_personal_tab" msgid="4190252696685155002">"ವೈಯಕ್ತಿಕ"</string>
<string name="all_apps_work_tab" msgid="4884822796154055118">"ಕೆಲಸ"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"ಕೆಲಸದ ಪ್ರೊಫೈಲ್"</string>
- <string name="work_profile_edu_work_apps" msgid="7895468576497746520">"ಕೆಲಸಕ್ಕೆ ಸಂಬಂಧಿಸಿದ ಆ್ಯಪ್‌ಗಳನ್ನು ಬ್ಯಾಡ್ಜ್ ಮಾಡಲಾಗಿದೆ ಮತ್ತು ಅವುಗಳು ನಿಮ್ಮ IT ನಿರ್ವಾಹಕರಿಗೆ ಗೋಚರಿಸುತ್ತವೆ"</string>
- <string name="work_profile_edu_accept" msgid="6069788082535149071">"ಸರಿ"</string>
- <string name="work_apps_paused_title" msgid="3040901117349444598">"ಕೆಲಸಕ್ಕೆ ಸಂಬಂಧಿಸಿದ ಆ್ಯಪ್‌ಗಳನ್ನು ವಿರಾಮಗೊಳಿಸಲಾಗಿದೆ"</string>
- <string name="work_apps_paused_body" msgid="261634750995824906">"ನಿಮ್ಮ ಕೆಲಸಕ್ಕೆ ಸಂಬಂಧಿಸಿದ ಆ್ಯಪ್‌ಗಳಿಗೆ ನಿಮಗೆ ಅಧಿಸೂಚನೆಗಳನ್ನು ಕಳುಹಿಸಲು, ನಿಮ್ಮ ಬ್ಯಾಟರಿಯನ್ನು ಬಳಸಲು ಅಥವಾ ನಿಮ್ಮ ಸ್ಥಳವನ್ನು ಪ್ರವೇಶಿಸಲು ಸಾಧ್ಯವಾಗದು"</string>
- <string name="work_apps_paused_content_description" msgid="5149623040804051095">"ಕೆಲಸಕ್ಕೆ ಸಂಬಂಧಿಸಿದ ಆ್ಯಪ್‌ಗಳು ಆಫ್ ಆಗಿವೆ. ನಿಮ್ಮ ಕೆಲಸಕ್ಕೆ ಸಂಬಂಧಿಸಿದ ಆ್ಯಪ್‌ಗಳು ನಿಮಗೆ ಅಧಿಸೂಚನೆಗಳನ್ನು ಕಳುಹಿಸಲು, ನಿಮ್ಮ ಬ್ಯಾಟರಿಯನ್ನು ಬಳಸಲು ಅಥವಾ ನಿಮ್ಮ ಸ್ಥಳವನ್ನು ಪ್ರವೇಶಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ"</string>
- <string name="work_apps_paused_edu_banner" msgid="8872412121608402058">"ಕೆಲಸಕ್ಕೆ ಸಂಬಂಧಿಸಿದ ಆ್ಯಪ್‌ಗಳು ಬ್ಯಾಡ್ಜ್ ಮಾಡಲಾಗಿದೆ ಮತ್ತು ನಿಮ್ಮ IT ನಿರ್ವಾಹಕರಿಗೆ ಗೋಚರಿಸುತ್ತದೆ"</string>
- <string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"ಅರ್ಥವಾಯಿತು"</string>
- <string name="work_apps_pause_btn_text" msgid="1921059713673767460">"ಕೆಲಸಕ್ಕೆ ಸಂಬಂಧಿಸಿದ ಆ್ಯಪ್‌ಗಳನ್ನು ಆಫ್ ಮಾಡಿ"</string>
- <string name="work_apps_enable_btn_text" msgid="1156432622148413741">"ಕೆಲಸಕ್ಕೆ ಸಂಬಂಧಿಸಿದ ಆ್ಯಪ್‌ಗಳನ್ನು ಆನ್ ಮಾಡಿ"</string>
- <string name="developer_options_filter_hint" msgid="5896817443635989056">"ಫಿಲ್ಟರ್‌"</string>
+ <string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"ಕೆಲಸದ ಅಪ್ಲಿಕೇಶನ್‌ಗಳನ್ನು ಇಲ್ಲಿ ಹುಡುಕಿ"</string>
+ <string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"ಕೆಲಸದ ಪ್ರತಿ ಅಪ್ಲಿಕೇಶನ್ ಬ್ಯಾಡ್ಜ್ ಹೊಂದಿದೆ ಮತ್ತು ನಿಮ್ಮ ಸಂಸ್ಥೆಯಿಂದ ಸುರಕ್ಷಿತವಾಗಿ ಇರಿಸಲಾಗುತ್ತದೆ. ಸುಲಭ ಪ್ರವೇಶಕ್ಕಾಗಿ ನಿಮ್ಮ ಹೋಮ್ ಸ್ಕ್ರೀನ್‌ಗೆ ಅಪ್ಲಿಕೇಶನ್‌ಗಳನ್ನು ಸರಿಸಿ."</string>
+ <string name="work_mode_on_label" msgid="4781128097185272916">"ನಿಮ್ಮ ಸಂಸ್ಥೆಯ ಮೂಲಕ ನಿರ್ವಹಿಸಲಾಗಿದೆ"</string>
+ <string name="work_mode_off_label" msgid="3194894777601421047">"ಅಧಿಸೂಚನೆಗಳು ಮತ್ತು ಅಪ್ಲಿಕೇಶನ್‌ಗಳು ಆಫ್ ಆಗಿವೆ"</string>
+ <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"ಮುಚ್ಚಿ"</string>
+ <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"ಮುಚ್ಚಲಾಗಿದೆ"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"ವಿಫಲವಾಗಿದೆ: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
</resources>
diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml
index 98597520be..58b65da032 100644
--- a/res/values-ko/strings.xml
+++ b/res/values-ko/strings.xml
@@ -20,63 +20,39 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="649227358658669779">"Launcher3"</string>
+ <string name="folder_name" msgid="7371454440695724752"></string>
<string name="work_folder_name" msgid="3753320833950115786">"업무"</string>
<string name="activity_not_found" msgid="8071924732094499514">"앱이 설치되지 않았습니다."</string>
<string name="activity_not_available" msgid="7456344436509528827">"앱을 사용할 수 없음"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"다운로드한 앱은 안전 모드에서 사용할 수 없습니다."</string>
<string name="safemode_widget_error" msgid="4863470563535682004">"안전 모드에서 위젯 사용 중지됨"</string>
<string name="shortcut_not_available" msgid="2536503539825726397">"바로가기를 사용할 수 없음"</string>
- <string name="home_screen" msgid="5629429142036709174">"홈"</string>
- <string name="recent_task_option_split_screen" msgid="6690461455618725183">"화면 분할"</string>
- <string name="split_screen_position_top" msgid="1504965011158689649">"위쪽으로 분할"</string>
- <string name="split_screen_position_left" msgid="7537793098851830883">"왼쪽으로 분할"</string>
- <string name="split_screen_position_right" msgid="1569377524925193369">"오른쪽으로 분할"</string>
- <string name="split_app_info_accessibility" msgid="5475288491241414932">"%1$s 앱 정보"</string>
- <string name="long_press_widget_to_add" msgid="3587712543577675817">"길게 터치하여 위젯을 이동하세요."</string>
- <string name="long_accessible_way_to_add" msgid="2733588281439571974">"두 번 탭한 다음 길게 터치하여 위젯을 이동하거나 맞춤 작업을 사용하세요."</string>
+ <string name="home_screen" msgid="806512411299847073">"홈 화면"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"맞춤 작업"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"위젯을 선택하려면 길게 터치하세요."</string>
+ <string name="long_accessible_way_to_add" msgid="4289502106628154155">"위젯을 선택하려면 두 번 탭한 다음 길게 터치하거나 맞춤 액션을 사용합니다."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d×%2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"너비 %1$d, 높이 %2$d"</string>
- <string name="widget_preview_context_description" msgid="9045841361655787574">"위젯 <xliff:g id="WIDGET_NAME">%1$s</xliff:g>개"</string>
- <string name="add_item_request_drag_hint" msgid="5653291305078645405">"홈 화면에서 위젯을 이동하려면 길게 터치하세요."</string>
- <string name="add_to_home_screen" msgid="8631549138215492708">"홈 화면에 추가"</string>
- <string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g> 위젯이 홈 화면에 추가됨"</string>
- <string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{위젯 #개}other{위젯 #개}}"</string>
- <string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{바로가기 #개}other{바로가기 #개}}"</string>
- <string name="widgets_and_shortcuts_count" msgid="7209136747878365116">"<xliff:g id="WIDGETS_COUNT">%1$s</xliff:g>, <xliff:g id="SHORTCUTS_COUNT">%2$s</xliff:g>"</string>
- <string name="widget_button_text" msgid="2880537293434387943">"위젯"</string>
- <string name="widgets_full_sheet_search_bar_hint" msgid="8484659090860596457">"검색"</string>
- <string name="widgets_full_sheet_cancel_button_description" msgid="5766167035728653605">"검색창에서 텍스트 지우기"</string>
- <string name="no_widgets_available" msgid="4337693382501046170">"위젯이나 바로가기를 사용할 수 없습니다."</string>
- <string name="no_search_results" msgid="3787956167293097509">"위젯이나 바로가기가 없습니다."</string>
- <string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"개인 위젯"</string>
- <string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"직장 위젯"</string>
- <string name="widget_category_conversations" msgid="8894438636213590446">"대화"</string>
- <string name="widget_education_header" msgid="4874760613775913787">"빠르게 유용한 정보 확인"</string>
- <string name="widget_education_content" msgid="745542879510751525">"앱을 열지 않고 정보를 확인하려면​ 홈 화면에 위젯을 추가하세요."</string>
- <string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"탭하여 위젯 설정 변경"</string>
- <string name="widget_education_close_button" msgid="8676165703104836580">"확인"</string>
- <string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"위젯 설정 변경"</string>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"길게 터치하여 직접 추가"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"자동으로 추가"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"앱 검색"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"앱 로드 중…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"\'<xliff:g id="QUERY">%1$s</xliff:g>\'과(와) 일치하는 앱이 없습니다."</string>
<string name="all_apps_search_market_message" msgid="1366263386197059176">"더 많은 앱 검색"</string>
<string name="label_application" msgid="8531721983832654978">"앱"</string>
- <string name="all_apps_label" msgid="5015784846527570951">"모든 앱"</string>
<string name="notifications_header" msgid="1404149926117359025">"알림"</string>
- <string name="long_press_shortcut_to_add" msgid="5405328730817637737">"길게 터치하여 바로가기를 이동하세요."</string>
- <string name="long_accessible_way_to_add_shortcut" msgid="2199537273817090740">"두 번 탭한 다음 길게 터치하여 바로가기를 이동하거나 맞춤 작업을 사용하세요."</string>
- <string name="out_of_space" msgid="6692471482459245734">"홈 화면에 더 이상 공간이 없습니다."</string>
+ <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"바로가기를 선택하려면 길게 터치하세요."</string>
+ <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"바로가기를 선택하려면 두 번 탭한 다음 길게 터치하거나 맞춤 동작을 사용하세요."</string>
+ <string name="out_of_space" msgid="4691004494942118364">"홈 화면에 더 이상 공간이 없습니다."</string>
<string name="hotseat_out_of_space" msgid="7448809638125333693">"즐겨찾기 트레이에 더 이상 공간이 없습니다."</string>
<string name="all_apps_button_label" msgid="8130441508702294465">"앱 목록"</string>
- <string name="all_apps_search_results" msgid="5889367432531296759">"검색결과"</string>
<string name="all_apps_button_personal_label" msgid="1315764287305224468">"개인 앱 목록"</string>
<string name="all_apps_button_work_label" msgid="7270707118948892488">"업무용 앱 목록"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"홈"</string>
<string name="remove_drop_target_label" msgid="7812859488053230776">"삭제"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"제거"</string>
<string name="app_info_drop_target_label" msgid="692894985365717661">"앱 정보"</string>
<string name="install_drop_target_label" msgid="2539096853673231757">"설치"</string>
- <string name="dismiss_prediction_label" msgid="3357562989568808658">"앱 제안 받지 않음"</string>
- <string name="pin_prediction" msgid="4196423321649756498">"예상 앱 고정"</string>
<string name="permlab_install_shortcut" msgid="5632423390354674437">"바로가기 설치"</string>
<string name="permdesc_install_shortcut" msgid="923466509822011139">"앱이 사용자의 작업 없이 바로가기를 추가할 수 있도록 합니다."</string>
<string name="permlab_read_settings" msgid="1941457408239617576">"홈 설정 및 바로가기 읽기"</string>
@@ -84,13 +60,15 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"홈 설정 및 바로가기 쓰기"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"앱이 홈에 있는 설정 및 바로가기를 변경할 수 있도록 합니다."</string>
<string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g>에서 전화를 걸 수 없습니다."</string>
- <string name="gadget_error_text" msgid="740356548025791839">"위젯을 로드할 수 없습니다."</string>
- <string name="gadget_setup_text" msgid="8348374825537681407">"위젯 설정"</string>
- <string name="gadget_complete_setup_text" msgid="309040266978007925">"탭하여 설정을 완료하세요."</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"위젯을 로드하는 중 문제가 발생했습니다."</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"설정"</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"시스템 앱은 제거할 수 없습니다."</string>
- <string name="folder_hint_text" msgid="5174843001373488816">"이름 수정"</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"이름이 없는 폴더"</string>
<string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> 사용 안함"</string>
- <string name="dotted_app_label" msgid="1704091277755818896">"{count,plural,offset:1 =1{{app_name} 알림 #개}other{{app_name}알림 #개}}"</string>
+ <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+ <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>에 <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g>개의 알림이 있음</item>
+ <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g>에 <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g>개의 알림이 있음</item>
+ </plurals>
<string name="default_scroll_format" msgid="7475544710230993317">"페이지 %1$d/%2$d"</string>
<string name="workspace_scroll_format" msgid="8458889198184077399">"홈 화면 %1$d/%2$d"</string>
<string name="workspace_new_page" msgid="257366611030256142">"새로운 홈 화면 페이지"</string>
@@ -99,10 +77,10 @@
<string name="folder_tap_to_rename" msgid="4017685068016979677">"탭하여 변경된 이름 저장"</string>
<string name="folder_closed" msgid="4100806530910930934">"폴더 닫음"</string>
<string name="folder_renamed" msgid="1794088362165669656">"폴더 이름 변경: <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="folder_name_format_exact" msgid="8626242716117004803">"폴더: <xliff:g id="NAME">%1$s</xliff:g>, 항목 <xliff:g id="SIZE">%2$d</xliff:g>개"</string>
- <string name="folder_name_format_overflow" msgid="4270108890534995199">"폴더: <xliff:g id="NAME">%1$s</xliff:g>, 항목 <xliff:g id="SIZE">%2$d</xliff:g>개 이상"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"폴더: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"위젯"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"배경화면"</string>
- <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"배경화면 및 스타일"</string>
+ <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"스타일 및 배경화면"</string>
<string name="settings_button_text" msgid="8873672322605444408">"홈 설정"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"관리자가 사용 중지함"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"홈 화면 회전 허용"</string>
@@ -114,16 +92,16 @@
<string name="msg_missing_notification_access" msgid="281113995110910548">"알림 표시점을 표시하려면 <xliff:g id="NAME">%1$s</xliff:g>의 앱 알림을 사용 설정하세요."</string>
<string name="title_change_settings" msgid="1376365968844349552">"설정 변경"</string>
<string name="notification_dots_service_title" msgid="4284221181793592871">"알림 표시 점 보기"</string>
- <string name="auto_add_shortcuts_label" msgid="3698776050751790653">"홈 화면에 앱 아이콘 추가"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"홈 화면에 아이콘 추가"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"새로 설치한 앱에 적용"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"알 수 없음"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"삭제"</string>
<string name="abandoned_search" msgid="891119232568284442">"검색"</string>
<string name="abandoned_promises_title" msgid="7096178467971716750">"이 앱이 설치되어 있지 않음"</string>
<string name="abandoned_promise_explanation" msgid="3990027586878167529">"이 아이콘의 앱이 설치되어 있지 않습니다. 아이콘을 삭제하거나 앱을 검색하여 수동으로 설치하세요."</string>
- <string name="app_installing_title" msgid="5864044122733792085">"<xliff:g id="NAME">%1$s</xliff:g> 설치 중, <xliff:g id="PROGRESS">%2$s</xliff:g> 완료"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> 다운로드 중, <xliff:g id="PROGRESS">%2$s</xliff:g> 완료"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> 설치 대기 중"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"<xliff:g id="NAME">%1$s</xliff:g> 위젯"</string>
<string name="widgets_list" msgid="796804551140113767">"위젯 목록"</string>
<string name="widgets_list_closed" msgid="6141506579418771922">"위젯 목록 닫힘"</string>
<string name="action_add_to_workspace" msgid="8902165848117513641">"홈 화면에 추가"</string>
@@ -151,20 +129,15 @@
<string name="action_deep_shortcut" msgid="2864038805849372848">"바로가기"</string>
<string name="shortcuts_menu_with_notifications_description" msgid="2676582286544232849">"바로가기 및 알림"</string>
<string name="action_dismiss_notification" msgid="5909461085055959187">"닫기"</string>
- <string name="accessibility_close" msgid="2277148124685870734">"닫기"</string>
<string name="notification_dismissed" msgid="6002233469409822874">"알림이 해제되었습니다."</string>
<string name="all_apps_personal_tab" msgid="4190252696685155002">"개인"</string>
<string name="all_apps_work_tab" msgid="4884822796154055118">"직장"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"직장 프로필"</string>
- <string name="work_profile_edu_work_apps" msgid="7895468576497746520">"직장 앱에는 배지가 있으며, IT 관리자는 직장 앱을 확인할 수 있습니다"</string>
- <string name="work_profile_edu_accept" msgid="6069788082535149071">"확인"</string>
- <string name="work_apps_paused_title" msgid="3040901117349444598">"직장 앱이 일시중지됨"</string>
- <string name="work_apps_paused_body" msgid="261634750995824906">"직장 앱에서 알림을 보내거나 배터리를 사용하거나 위치 정보에 액세스할 수 없습니다."</string>
- <string name="work_apps_paused_content_description" msgid="5149623040804051095">"직장 앱이 꺼져 있습니다. 직장 앱에서 알림을 보내거나 배터리를 사용하거나 위치 정보에 액세스할 수 없습니다."</string>
- <string name="work_apps_paused_edu_banner" msgid="8872412121608402058">"직장 앱에는 배지가 있으며, IT 관리자는 직장 앱을 확인할 수 있습니다."</string>
- <string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"확인"</string>
- <string name="work_apps_pause_btn_text" msgid="1921059713673767460">"직장 앱 사용 중지"</string>
- <string name="work_apps_enable_btn_text" msgid="1156432622148413741">"직장 앱 사용 설정"</string>
- <string name="developer_options_filter_hint" msgid="5896817443635989056">"필터"</string>
+ <string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"여기에서 업무용 앱 찾기"</string>
+ <string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"각 업무용 앱에는 배지가 있으며 업무용 앱은 조직에서 안전하게 보호됩니다. 앱을 홈 화면으로 이동하여 더 간편하게 사용하세요."</string>
+ <string name="work_mode_on_label" msgid="4781128097185272916">"조직에서 관리"</string>
+ <string name="work_mode_off_label" msgid="3194894777601421047">"알림 및 앱 사용 중지됨"</string>
+ <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"닫기"</string>
+ <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"종료됨"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"실패: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
</resources>
diff --git a/res/values-ky/strings.xml b/res/values-ky/strings.xml
index 5378ca509b..d52446c83c 100644
--- a/res/values-ky/strings.xml
+++ b/res/values-ky/strings.xml
@@ -26,57 +26,32 @@
<string name="safemode_shortcut_error" msgid="9160126848219158407">"Жүктөп алынган колдонмо Коопсуз режиминде иштен чыгарылды"</string>
<string name="safemode_widget_error" msgid="4863470563535682004">"Виджеттер Коопсуз режимде өчүрүлгөн"</string>
<string name="shortcut_not_available" msgid="2536503539825726397">"Кыска жол жок"</string>
- <string name="home_screen" msgid="5629429142036709174">"Башкы экран"</string>
- <string name="recent_task_option_split_screen" msgid="6690461455618725183">"Экранды бөлүү"</string>
- <string name="split_screen_position_top" msgid="1504965011158689649">"Өйдө бөлүү"</string>
- <string name="split_screen_position_left" msgid="7537793098851830883">"Солго бөлүү"</string>
- <string name="split_screen_position_right" msgid="1569377524925193369">"Оңго бөлүү"</string>
- <string name="split_app_info_accessibility" msgid="5475288491241414932">"%1$s колдонмосу жөнүндө маалымат"</string>
- <string name="long_press_widget_to_add" msgid="3587712543577675817">"Виджетти кое бербей басып туруп жылдырыңыз."</string>
- <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Виджетти жылдыруу үчүн эки жолу таптап, кармап туруңуз же ыңгайлаштырылган аракеттерди колдонуңуз."</string>
+ <string name="home_screen" msgid="806512411299847073">"Башкы экран"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"Ыңгайлаштырылган аракеттер"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"Виджетти тандаш үчүн, басып туруңуз"</string>
+ <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Виджет тандоо үчүн эки жолу таптап, кармап туруңуз же ыңгайлаштырылган аракеттерди колдонуңуз."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"Туурасы: %1$d, бийиктиги: %2$d"</string>
- <string name="widget_preview_context_description" msgid="9045841361655787574">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g> виджети"</string>
- <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Башкы экранга жылдыруу үчүн виджетти коё бербей басып туруңуз"</string>
- <string name="add_to_home_screen" msgid="8631549138215492708">"Башкы экранга кошуу"</string>
- <string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g> виджети башкы экранга кошулду"</string>
- <string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# виджет}other{# виджет}}"</string>
- <string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{# ыкчам баскыч}other{# ыкчам баскыч}}"</string>
- <string name="widgets_and_shortcuts_count" msgid="7209136747878365116">"<xliff:g id="WIDGETS_COUNT">%1$s</xliff:g>, <xliff:g id="SHORTCUTS_COUNT">%2$s</xliff:g>"</string>
- <string name="widget_button_text" msgid="2880537293434387943">"Виджеттер"</string>
- <string name="widgets_full_sheet_search_bar_hint" msgid="8484659090860596457">"Издөө"</string>
- <string name="widgets_full_sheet_cancel_button_description" msgid="5766167035728653605">"Текстти издөө кутучасынан тазалоо"</string>
- <string name="no_widgets_available" msgid="4337693382501046170">"Виджеттер менен ыкчам баскычтар жеткиликсиз"</string>
- <string name="no_search_results" msgid="3787956167293097509">"Виджеттер менен ыкчам баскычтар табылган жок"</string>
- <string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Жеке виджеттер"</string>
- <string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Жумуш"</string>
- <string name="widget_category_conversations" msgid="8894438636213590446">"Сүйлөшүүлөр"</string>
- <string name="widget_education_header" msgid="4874760613775913787">"Керектүү маалымат манжаңыздын учунда"</string>
- <string name="widget_education_content" msgid="745542879510751525">"Колдонмолорду ачпастан керектүү маалыматты алуу үчүн башкы экранга виджеттерди кошуңуз"</string>
- <string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Виджеттин жөндөөлөрүн өзгөртүү үчүн таптап коюңуз"</string>
- <string name="widget_education_close_button" msgid="8676165703104836580">"Түшүндүм"</string>
- <string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Виджеттин жөндөөлөрүн өзгөртүү"</string>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Кол менен кошуу үчүн кое бербей басып туруңуз"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"Автоматтык түрдө кошуу"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Колдонмолорду издөө"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Колдонмолор жүктөлүүдө…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" сурамына дал келген колдонмолор табылган жок"</string>
<string name="all_apps_search_market_message" msgid="1366263386197059176">"Көбүрөөк колдонмолорду издөө"</string>
<string name="label_application" msgid="8531721983832654978">"Колдонмо"</string>
- <string name="all_apps_label" msgid="5015784846527570951">"Бардык колдонмолор"</string>
<string name="notifications_header" msgid="1404149926117359025">"Билдирмелер"</string>
- <string name="long_press_shortcut_to_add" msgid="5405328730817637737">"Ыкчам баскычты жылдыруу үчүн коё бербей басып туруңуз."</string>
- <string name="long_accessible_way_to_add_shortcut" msgid="2199537273817090740">"Ыкчам баскычты жылдыруу үчүн эки жолу таптап, кармап туруңуз же ыңгайлаштырылган аракеттерди колдонуңуз."</string>
- <string name="out_of_space" msgid="6692471482459245734">"Башкы экранда бош орун жок"</string>
+ <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"Кыска жолду тандоо үчүн басып туруңуз."</string>
+ <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"Кыска жолду тандоо үчүн эки жолу таптап, кармап туруңуз же ыңгайлаштырылган аракеттерди колдонуңуз."</string>
+ <string name="out_of_space" msgid="4691004494942118364">"Бул Үй экранында бош орун жок."</string>
<string name="hotseat_out_of_space" msgid="7448809638125333693">"Тандамалдар тайпасында орун калган жок"</string>
<string name="all_apps_button_label" msgid="8130441508702294465">"Колдонмолор тизмеси"</string>
- <string name="all_apps_search_results" msgid="5889367432531296759">"Табылган нерселер"</string>
<string name="all_apps_button_personal_label" msgid="1315764287305224468">"Жеке колдономолордун тизмеси"</string>
<string name="all_apps_button_work_label" msgid="7270707118948892488">"Жумуш колдонмолорунун тизмеси"</string>
- <string name="remove_drop_target_label" msgid="7812859488053230776">"Өчүрүү"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"Үйгө"</string>
+ <string name="remove_drop_target_label" msgid="7812859488053230776">"Алып салуу"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"Чыгарып салуу"</string>
<string name="app_info_drop_target_label" msgid="692894985365717661">"Колдонмо тууралуу"</string>
<string name="install_drop_target_label" msgid="2539096853673231757">"Орнотуу"</string>
- <string name="dismiss_prediction_label" msgid="3357562989568808658">"Колдонмо сунушталбасын"</string>
- <string name="pin_prediction" msgid="4196423321649756498">"Божомолдонгон колдонмону кадап коюу"</string>
<string name="permlab_install_shortcut" msgid="5632423390354674437">"тез чакырмаларды орнотуу"</string>
<string name="permdesc_install_shortcut" msgid="923466509822011139">"Колдонмого колдонуучуга кайрылбастан тез чакырма кошууга уруксат берет."</string>
<string name="permlab_read_settings" msgid="1941457408239617576">"Үйдүн тууралоолорун жана тез чакырмаларын окуу"</string>
@@ -84,13 +59,15 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"Үйдүн тууралоолорун жана тез чакырмаларын жазуу"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"Колдонмого Үйдүн тууралоолорун жана тез чакырмаларын өзгөртүүгө уруксат берет."</string>
<string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> телефон чалууларды аткарууга уруксаты жок"</string>
- <string name="gadget_error_text" msgid="740356548025791839">"Виджет жүктөлбөй жатат"</string>
- <string name="gadget_setup_text" msgid="8348374825537681407">"Виджеттин жөндөөлөрү"</string>
- <string name="gadget_complete_setup_text" msgid="309040266978007925">"Жөндөп бүтүү үчүн таптап коюңуз"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"Виджетти жүктөөдө маселе бар"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"Орнотуу"</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"Бул системдик колдонмо жана аны чечкенге болбойт."</string>
- <string name="folder_hint_text" msgid="5174843001373488816">"Аталышын түзөтүү"</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"Аты жок фолдер"</string>
<string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> өчүрүлгөн"</string>
- <string name="dotted_app_label" msgid="1704091277755818896">"{count,plural,offset:1 =1{{app_name}, # билдирмеси бар}other{{app_name}, # билдирмеси бар}}"</string>
+ <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+ <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> билдирмеси бар</item>
+ <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g>, <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> билдирмеси бар</item>
+ </plurals>
<string name="default_scroll_format" msgid="7475544710230993317">"%2$d ичинен %1$d барак"</string>
<string name="workspace_scroll_format" msgid="8458889198184077399">"Үй экраны %2$d ичинен %1$d"</string>
<string name="workspace_new_page" msgid="257366611030256142">"Жаңы башкы экран барагы"</string>
@@ -99,31 +76,31 @@
<string name="folder_tap_to_rename" msgid="4017685068016979677">"Өзгөртүлгөн аталышын сактоо үчүн таптаңыз"</string>
<string name="folder_closed" msgid="4100806530910930934">"Фолдер жабык"</string>
<string name="folder_renamed" msgid="1794088362165669656">"Фолдердин аты <xliff:g id="NAME">%1$s</xliff:g> деп өзгөртүлдү"</string>
- <string name="folder_name_format_exact" msgid="8626242716117004803">"<xliff:g id="NAME">%1$s</xliff:g> папкасындагы объекттер: <xliff:g id="SIZE">%2$d</xliff:g>"</string>
- <string name="folder_name_format_overflow" msgid="4270108890534995199">"<xliff:g id="NAME">%1$s</xliff:g> папкасындагы объекттер: <xliff:g id="SIZE">%2$d</xliff:g> же андан көбүрөөк"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"Фолдер: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"Виджеттер"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Тушкагаздар"</string>
- <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Тушкагаз жана стиль"</string>
+ <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Стилдер жана тушкагаздар"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Башкы бет жөндөөлөрү"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Администраторуңуз өчүрүп койгон"</string>
- <string name="allow_rotation_title" msgid="7728578836261442095">"Башкы экранды бурууга уруксат берүү"</string>
- <string name="allow_rotation_desc" msgid="8662546029078692509">"Телефон бурулганда"</string>
+ <string name="allow_rotation_title" msgid="7728578836261442095">"Башкы экранды айлантууга уруксат берүү"</string>
+ <string name="allow_rotation_desc" msgid="8662546029078692509">"Телефон айланганда"</string>
<string name="notification_dots_title" msgid="9062440428204120317">"Билдирмелер белгилери"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"Күйүк"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"Өчүк"</string>
<string name="title_missing_notification_access" msgid="7503287056163941064">"Эскертмелерге уруксат берилиши керек"</string>
- <string name="msg_missing_notification_access" msgid="281113995110910548">"Эскертме белгилерин көрсөтүү максатында, <xliff:g id="NAME">%1$s</xliff:g> үчүн колдонмонун билдирмелерин күйгүзүү керек"</string>
- <string name="title_change_settings" msgid="1376365968844349552">"Параметрлерди өзгөртүү"</string>
+ <string name="msg_missing_notification_access" msgid="281113995110910548">"Эскертме белгилерин көрсөтүү максатында, <xliff:g id="NAME">%1$s</xliff:g> үчүн колдонмонун эскертмелерин күйгүзүү керек"</string>
+ <string name="title_change_settings" msgid="1376365968844349552">"Жөндөөлөрдү өзгөртүү"</string>
<string name="notification_dots_service_title" msgid="4284221181793592871">"Билдирмелер белгилерин көрсөтүү"</string>
- <string name="auto_add_shortcuts_label" msgid="3698776050751790653">"Колдонмонун сүрөтчөсүн Башкы экранга кошуу"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Башкы экранга сүрөтчө кошуу"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Жаңы колдонмолор үчүн"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"Белгисиз"</string>
- <string name="abandoned_clean_this" msgid="7610119707847920412">"Өчүрүү"</string>
+ <string name="abandoned_clean_this" msgid="7610119707847920412">"Алып салуу"</string>
<string name="abandoned_search" msgid="891119232568284442">"Издөө"</string>
<string name="abandoned_promises_title" msgid="7096178467971716750">"Бул колдонмо орнотулган эмес"</string>
<string name="abandoned_promise_explanation" msgid="3990027586878167529">"Бул сүрөтчөнүн колдонмосу орнотулган эмес. Аны алып салсаңыз же колдонмону издеп, кол менен орнотсоңуз болот."</string>
- <string name="app_installing_title" msgid="5864044122733792085">"<xliff:g id="NAME">%1$s</xliff:g> орнотулууда, <xliff:g id="PROGRESS">%2$s</xliff:g> аткарылды"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> жүктөлүп алынууда, <xliff:g id="PROGRESS">%2$s</xliff:g> аяктады"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> орнотулушу күтүлүүдө"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"<xliff:g id="NAME">%1$s</xliff:g> виджеттери"</string>
<string name="widgets_list" msgid="796804551140113767">"Виджеттердин тизмеси"</string>
<string name="widgets_list_closed" msgid="6141506579418771922">"Виджеттердин тизмеси жабык"</string>
<string name="action_add_to_workspace" msgid="8902165848117513641">"Башкы экранга кошуу"</string>
@@ -134,7 +111,7 @@
<string name="action_move" msgid="4339390619886385032">"Муну жылдыруу"</string>
<string name="move_to_empty_cell" msgid="2833711483015685619">"<xliff:g id="NUMBER_0">%1$s</xliff:g> катарга <xliff:g id="NUMBER_1">%2$s</xliff:g> тилкеге жылдыруу"</string>
<string name="move_to_position" msgid="6750008980455459790">"<xliff:g id="NUMBER">%1$s</xliff:g> орунга жылдыруу"</string>
- <string name="move_to_hotseat_position" msgid="6295412897075147808">"Тандалмаларга <xliff:g id="NUMBER">%1$s</xliff:g> жылдыруу"</string>
+ <string name="move_to_hotseat_position" msgid="6295412897075147808">"Сүйүктүүлөргө <xliff:g id="NUMBER">%1$s</xliff:g> жылдыруу"</string>
<string name="item_moved" msgid="4606538322571412879">"Нерсе жылдырылды"</string>
<string name="add_to_folder" msgid="9040534766770853243">"Куржунга кошуу: <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="add_to_folder_with_app" msgid="4534929978967147231">"<xliff:g id="NAME">%1$s</xliff:g> куржунуна кошуу"</string>
@@ -151,20 +128,15 @@
<string name="action_deep_shortcut" msgid="2864038805849372848">"Кыска жолдор"</string>
<string name="shortcuts_menu_with_notifications_description" msgid="2676582286544232849">"Кыска жолдор жана билдирмелер"</string>
<string name="action_dismiss_notification" msgid="5909461085055959187">"Этибарга албоо"</string>
- <string name="accessibility_close" msgid="2277148124685870734">"Жабуу"</string>
- <string name="notification_dismissed" msgid="6002233469409822874">"Билдирме жабылды"</string>
+ <string name="notification_dismissed" msgid="6002233469409822874">"Эскертме көз жаздымда калтырылды"</string>
<string name="all_apps_personal_tab" msgid="4190252696685155002">"Жеке колдонмолор"</string>
<string name="all_apps_work_tab" msgid="4884822796154055118">"Жумуш колдонмолору"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"Жумуш профили"</string>
- <string name="work_profile_edu_work_apps" msgid="7895468576497746520">"Жумуш колдонмолору белгиленип, аларды IT администраторлору көрөт"</string>
- <string name="work_profile_edu_accept" msgid="6069788082535149071">"Түшүндүм"</string>
- <string name="work_apps_paused_title" msgid="3040901117349444598">"Жумуш колдонмолору тындырылды"</string>
- <string name="work_apps_paused_body" msgid="261634750995824906">"Жумуш колдонмолору билдирмелерди жөнөтүп, түзмөгүңүздүн батареясын керектеп же кайда жүргөнүңүздү көрө албайт"</string>
- <string name="work_apps_paused_content_description" msgid="5149623040804051095">"Жумуш колдонмолору өчүк жана билдирмелерди жөнөтүп, түзмөгүңүздүн батареясын керектеп же кайда жүргөнүңүздү көрө албайт"</string>
- <string name="work_apps_paused_edu_banner" msgid="8872412121608402058">"Жумуш колдонмолору белгиленип, аларды IT администраторлору көрөт"</string>
- <string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"Түшүндүм"</string>
- <string name="work_apps_pause_btn_text" msgid="1921059713673767460">"Жумуш колдонмолорун өчүрүү"</string>
- <string name="work_apps_enable_btn_text" msgid="1156432622148413741">"Жумуш колдонмолорун күйгүзүү"</string>
- <string name="developer_options_filter_hint" msgid="5896817443635989056">"Чыпкалоо"</string>
+ <string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"Жумуш колдонмолорун бул жерден таап алыңыз"</string>
+ <string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"Ар бир жумуш колдонмосунун бейджиги бар жана ал уюмуңуз тарабынан коопсуз сакталат. Колдонмолорго тез өтүү үчүн аларды Башкы экранга кошуп алыңыз."</string>
+ <string name="work_mode_on_label" msgid="4781128097185272916">"Уюмуңуз тарабынан башкарылат"</string>
+ <string name="work_mode_off_label" msgid="3194894777601421047">"Билдирүүлөр жана колдонмолор өчүрүлгөн"</string>
+ <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Жабуу"</string>
+ <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Жабык"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Аткарылган жок: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
</resources>
diff --git a/res/values-land/dimens.xml b/res/values-land/dimens.xml
index 422240c939..662b86ebbe 100644
--- a/res/values-land/dimens.xml
+++ b/res/values-land/dimens.xml
@@ -22,22 +22,8 @@
<dimen name="fastscroll_popup_text_size">24dp</dimen>
<!-- Dynamic grid -->
- <dimen name="dynamic_grid_edge_margin">15.28dp</dimen>
<dimen name="dynamic_grid_icon_drawable_padding">4dp</dimen>
- <dimen name="dynamic_grid_drop_target_size">36dp</dimen>
- <dimen name="cell_layout_padding">20dp</dimen>
<!-- Hotseat -->
<dimen name="dynamic_grid_hotseat_side_padding">16dp</dimen>
- <dimen name="spring_loaded_hotseat_top_margin">45dp</dimen>
-
- <!-- Dragging -->
- <dimen name="drop_target_button_gap">28dp</dimen>
- <dimen name="drop_target_button_drawable_horizontal_padding">16dp</dimen>
- <dimen name="drop_target_button_drawable_vertical_padding">2dp</dimen>
- <dimen name="drop_target_top_margin">6dp</dimen>
- <dimen name="drop_target_bottom_margin">6dp</dimen>
-
- <!-- Workspace grid visualization parameters -->
- <dimen name="grid_visualization_horizontal_cell_spacing">24dp</dimen>
</resources>
diff --git a/res/values-lo/strings.xml b/res/values-lo/strings.xml
index e47fefdda2..afe7664d51 100644
--- a/res/values-lo/strings.xml
+++ b/res/values-lo/strings.xml
@@ -20,63 +20,39 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="649227358658669779">"Launcher3"</string>
+ <string name="folder_name" msgid="7371454440695724752"></string>
<string name="work_folder_name" msgid="3753320833950115786">"ວຽກ"</string>
<string name="activity_not_found" msgid="8071924732094499514">"ແອັບຯບໍ່ໄດ້ຖືກຕິດຕັ້ງ."</string>
<string name="activity_not_available" msgid="7456344436509528827">"ແອັບຯ​ໃຊ້​ບໍ່​ໄດ້"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"ແອັບຯ​ທີ່​ດາວ​ໂຫລດ​ແລ້ວ​ຖືກ​ປິດ​ການ​ນຳ​ໃຊ້​ໃນ Safe mode"</string>
<string name="safemode_widget_error" msgid="4863470563535682004">"​ວິດ​ເຈັດ​ຖືກ​ປິດ​ໃນ Safe mode"</string>
<string name="shortcut_not_available" msgid="2536503539825726397">"ບໍ່ສາມາດໃຊ້ທາງລັດໄດ້"</string>
- <string name="home_screen" msgid="5629429142036709174">"ໂຮມສະກຣີນ"</string>
- <string name="recent_task_option_split_screen" msgid="6690461455618725183">"ແບ່ງໜ້າຈໍ"</string>
- <string name="split_screen_position_top" msgid="1504965011158689649">"ແບ່ງເທິງ"</string>
- <string name="split_screen_position_left" msgid="7537793098851830883">"ແບ່ງຊ້າຍ"</string>
- <string name="split_screen_position_right" msgid="1569377524925193369">"ແບ່ງຂວາ"</string>
- <string name="split_app_info_accessibility" msgid="5475288491241414932">"ຂໍ້ມູນແອັບສຳລັບ %1$s"</string>
- <string name="long_press_widget_to_add" msgid="3587712543577675817">"ແຕະຄ້າງໄວ້ເພື່ອຍ້າຍວິດເຈັດ."</string>
- <string name="long_accessible_way_to_add" msgid="2733588281439571974">"ແຕະສອງເທື່ອຄ້າງໄວ້ເພື່ອຍ້າຍວິດເຈັດ ຫຼື ໃຊ້ຄຳສັ່ງກຳນົດເອງ."</string>
+ <string name="home_screen" msgid="806512411299847073">"ໜ້າຈໍຫຼັກ"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"ຄຳສັ່ງແບບກຳນົດເອງ"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"ສຳພັດຄ້າງໄວ້ ເພື່ອຈັບວິດເຈັດ."</string>
+ <string name="long_accessible_way_to_add" msgid="4289502106628154155">"ແຕະ​ຄ້າງ​ໄວ້ ເພື່ອ​ເລືອກວິດ​ເຈັດ ຫຼື ໃຊ້​ການ​ດຳ​ເນີນ​ການ​ກຳ​ນົດ​ເອງ."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"ກວ້າງ %1$d ຄູນສູງ %2$d"</string>
- <string name="widget_preview_context_description" msgid="9045841361655787574">"ວິດເຈັດ <xliff:g id="WIDGET_NAME">%1$s</xliff:g>"</string>
- <string name="add_item_request_drag_hint" msgid="5653291305078645405">"ແຕະວິດເຈັດຄ້າງໄວ້ເພື່ອຍ້າຍມັນໄປມາຢູ່ໂຮມສະກຣີນ"</string>
- <string name="add_to_home_screen" msgid="8631549138215492708">"ເພີ່ມໄປໃສ່ໂຮມສະກຣີນ"</string>
- <string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"ເພີ່ມວິດເຈັດ <xliff:g id="WIDGET_NAME">%1$s</xliff:g> ໃສ່ໂຮມສະກຣີນແລ້ວ"</string>
- <string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# ວິດເຈັດ}other{# ວິດເຈັດ}}"</string>
- <string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{# ທາງລັດ}other{# ທາງລັດ}}"</string>
- <string name="widgets_and_shortcuts_count" msgid="7209136747878365116">"<xliff:g id="WIDGETS_COUNT">%1$s</xliff:g>, <xliff:g id="SHORTCUTS_COUNT">%2$s</xliff:g>"</string>
- <string name="widget_button_text" msgid="2880537293434387943">"ວິດເຈັດ"</string>
- <string name="widgets_full_sheet_search_bar_hint" msgid="8484659090860596457">"ຊອກຫາ"</string>
- <string name="widgets_full_sheet_cancel_button_description" msgid="5766167035728653605">"ລຶບລ້າງຂໍ້ຄວາມຈາກກ່ອງຊອກຫາ"</string>
- <string name="no_widgets_available" msgid="4337693382501046170">"ບໍ່ສາມາດໃຊ້ວິດເຈັດ ຫຼື ທາງລັດໄດ້"</string>
- <string name="no_search_results" msgid="3787956167293097509">"ບໍ່ພົບວິດເຈັດ ຫຼື ທາງລັດ"</string>
- <string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"ສ່ວນຕົວ"</string>
- <string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"ວຽກ"</string>
- <string name="widget_category_conversations" msgid="8894438636213590446">"ການສົນທະນາ"</string>
- <string name="widget_education_header" msgid="4874760613775913787">"ຂໍ້ມູນທີ່ເປັນປະໂຫຍດຢູ່ປາຍນິ້ວຂອງທ່ານ"</string>
- <string name="widget_education_content" msgid="745542879510751525">"ເພື່ອຮັບຂໍ້ມູນໂດຍບໍ່ຕ້ອງເປີດແອັບ, ທ່ານສາມາດເພີ່ມວິດເຈັດໃສ່ໂຮມສະກຣີນຂອງທ່ານໄດ້"</string>
- <string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"ແຕະເພື່ອປ່ຽນການຕັ້ງຄ່າວິດເຈັດ"</string>
- <string name="widget_education_close_button" msgid="8676165703104836580">"ເຂົ້າໃຈແລ້ວ"</string>
- <string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"ປ່ຽນການຕັ້ງຄ່າວິດເຈັດ"</string>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"ແຕະຄ້າງໄວ້ເພື່ອວາງດ້ວຍຕົນເອງ"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"ເພີ່ມໂດຍອັດຕະໂນມັດ"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"ຊອກຫາແອັບ"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"ກໍາລັງໂຫຼດແອັບ…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"ບໍ່ພົບແອັບທີ່ກົງກັບ \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
<string name="all_apps_search_market_message" msgid="1366263386197059176">"ຊອກຫາແອັບເພີ່ມເຕີມ"</string>
<string name="label_application" msgid="8531721983832654978">"ແອັບ"</string>
- <string name="all_apps_label" msgid="5015784846527570951">"ແອັບທັງໝົດ"</string>
<string name="notifications_header" msgid="1404149926117359025">"ການແຈ້ງເຕືອນ"</string>
- <string name="long_press_shortcut_to_add" msgid="5405328730817637737">"ແຕະຄ້າງໄວ້ເພື່ອຍ້າຍທາງລັດ."</string>
- <string name="long_accessible_way_to_add_shortcut" msgid="2199537273817090740">"ແຕະສອງເທື່ອຄ້າງໄວ້ເພື່ອຍ້າຍທາງລັດ ຫຼື ໃຊ້ຄຳສັ່ງກຳນົດເອງ."</string>
- <string name="out_of_space" msgid="6692471482459245734">"ບໍ່ມີບ່ອນຫວ່າງໃນໜ້າໂຮມສະກຣີນນີ້"</string>
+ <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"ແຕະຄ້າງໄວ້ເພື່ອຮັບປຸ່ມລັດ."</string>
+ <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"ແຕະສອງເທື່ອຄ້າງໄວ້ເພື່ອຮັບປຸ່ມລັດ ຫຼື ໃຊ້ຄຳສັ່ງແບບກຳນົດເອງ."</string>
+ <string name="out_of_space" msgid="4691004494942118364">"ບໍ່ມີຫ້ອງເຫຼືອໃນໜ້າຈໍຫຼັກນີ້."</string>
<string name="hotseat_out_of_space" msgid="7448809638125333693">"ບໍ່ມີບ່ອນຫວ່າງໃນຖາດສຳລັບເກັບສິ່ງທີ່ໃຊ້ເປັນປະຈຳ"</string>
<string name="all_apps_button_label" msgid="8130441508702294465">"ລາຍຊື່ແອັບ"</string>
- <string name="all_apps_search_results" msgid="5889367432531296759">"ຜົນການຊອກຫາ"</string>
<string name="all_apps_button_personal_label" msgid="1315764287305224468">"ລາຍຊື່ແອັບສ່ວນຕົວ"</string>
<string name="all_apps_button_work_label" msgid="7270707118948892488">"ລາຍຊື່ແອັບເຮັດວຽກ"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"ໜ້າຫຼັກ"</string>
<string name="remove_drop_target_label" msgid="7812859488053230776">"ເອົາ​ອອກ"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"ຖອນ​ການ​ຕິດ​ຕັ້ງ"</string>
<string name="app_info_drop_target_label" msgid="692894985365717661">"ຂໍ້ມູນແອັບ"</string>
<string name="install_drop_target_label" msgid="2539096853673231757">"ຕິດຕັ້ງ"</string>
- <string name="dismiss_prediction_label" msgid="3357562989568808658">"ຢ່າແນະນຳແອັບ"</string>
- <string name="pin_prediction" msgid="4196423321649756498">"ປັກໝຸດການຄາດເດົາ"</string>
<string name="permlab_install_shortcut" msgid="5632423390354674437">"ຕິດຕັ້ງທາງລັດ"</string>
<string name="permdesc_install_shortcut" msgid="923466509822011139">"ອະນຸຍາດໃຫ້ແອັບຯ ເພີ່ມທາງລັດໂດຍບໍ່ຕ້ອງຮັບການຢືນຢັນຈາກຜູ່ໃຊ້."</string>
<string name="permlab_read_settings" msgid="1941457408239617576">"ອ່ານການຕັ້ງຄ່າໜ້າຫຼັກ ແລະທາງລັດ"</string>
@@ -84,13 +60,15 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"ຂຽນການຕັ້ງຄ່າໜ້າຫຼັກ ແລະທາງລັດ"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"ອະນຸຍາດໃຫ້ແອັບຯດັ່ງກ່າວ ປ່ຽນການຕັ້ງຄ່າ ແລະທາງລັດໃນໜ້າຫຼັກ."</string>
<string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> ບໍ່​ໄດ້​ຮັບ​ອະ​ນຸ​ຍາດ​ໃຫ້​ໂທ"</string>
- <string name="gadget_error_text" msgid="740356548025791839">"ບໍ່ສາມາດໂຫຼດວິດເຈັດໄດ້"</string>
- <string name="gadget_setup_text" msgid="8348374825537681407">"ການຕັ້ງຄ່າວິດເຈັດ"</string>
- <string name="gadget_complete_setup_text" msgid="309040266978007925">"ແຕະເພື່ອຕັ້ງຄ່າໃຫ້ແລ້ວ"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"ມີບັນຫາໃນການໂຫລດວິດເຈັດ"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"ຕິດຕັ້ງ"</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"ນີ້ແມ່ນແອັບຯຂອງລະບົບ ແລະບໍ່ສາມາດຖອນການຕິດຕັ້ງອອກໄດ້."</string>
- <string name="folder_hint_text" msgid="5174843001373488816">"ແກ້ໄຂຊື່"</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"ໂຟນເດີຍັງບໍ່ຖືກຕັ້ງຊື່"</string>
<string name="disabled_app_label" msgid="6673129024321402780">"ປິດການນຳໃຊ້ <xliff:g id="APP_NAME">%1$s</xliff:g> ແລ້ວ"</string>
- <string name="dotted_app_label" msgid="1704091277755818896">"{count,plural,offset:1 =1{{app_name} ມີ # ການແຈ້ງເຕືອນ}other{{app_name} ມີ # ການແຈ້ງເຕືອນ}}"</string>
+ <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+ <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, ມີ <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> ການແຈ້ງເຕືອນ</item>
+ <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g>, ມີ <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> ການແຈ້ງເຕືອນ</item>
+ </plurals>
<string name="default_scroll_format" msgid="7475544710230993317">"ໜ້າ %1$d ຈາກ %2$d"</string>
<string name="workspace_scroll_format" msgid="8458889198184077399">"ໜ້າຈໍຫຼັກ %1$d ໃນ %2$d"</string>
<string name="workspace_new_page" msgid="257366611030256142">"ໜ້າ​ຂອງ​ໜ້າ​ຈໍ​ຫຼັກ​ໃໝ່"</string>
@@ -99,13 +77,13 @@
<string name="folder_tap_to_rename" msgid="4017685068016979677">"ແຕະເພື່ອບັນທຶກການປ່ຽນຊື່"</string>
<string name="folder_closed" msgid="4100806530910930934">"ປິດໂຟນເດີແລ້ວ"</string>
<string name="folder_renamed" msgid="1794088362165669656">"ປ່ຽນຊື່ໂຟນເດີເປັນ <xliff:g id="NAME">%1$s</xliff:g> ແລ້ວ"</string>
- <string name="folder_name_format_exact" msgid="8626242716117004803">"ໂຟນເດີ: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> ລາຍການ"</string>
- <string name="folder_name_format_overflow" msgid="4270108890534995199">"ໂຟນເດີ: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> ຫຼື ລາຍການເພີ່ມເຕີມ"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"ໂຟນເດີ: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"ວິດເຈັດ"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"ພາບພື້ນຫຼັງ"</string>
- <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"ຮູບພື້ນຫຼັງ ແລະ ຮູບແບບ"</string>
- <string name="settings_button_text" msgid="8873672322605444408">"ການຕັ້ງຄ່າໜ້າຫຼັກ"</string>
+ <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"ຮູບແບບ ແລະ ຮູບພື້ນຫຼັງ"</string>
+ <string name="settings_button_text" msgid="8873672322605444408">"ການຕັ້ງຄ່າ Home"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"ຖືກປິດການນຳໃຊ້ໂດຍຜູ້ເບິ່ງແຍງລະບົບຂອງທ່ານ"</string>
- <string name="allow_rotation_title" msgid="7728578836261442095">"ອະນຸຍາດໃຫ້ໝຸນໜ້າຈໍຢູ່ໜ້າຫຼັກໄດ້"</string>
+ <string name="allow_rotation_title" msgid="7728578836261442095">"ອະນຸຍາດໃຫ້ໝຸນໜ້າຈໍທຳອິດໄດ້"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"ເມື່ອໝຸນໂທລະສັບ"</string>
<string name="notification_dots_title" msgid="9062440428204120317">"ຈຸດການແຈ້ງເຕືອນ"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"ເປີດ"</string>
@@ -114,16 +92,16 @@
<string name="msg_missing_notification_access" msgid="281113995110910548">"ເພື່ອສະແດງຈຸດການແຈ້ງເຕືອນ, ໃຫ້ເປີດການແຈ້ງເຕືອນສຳລັບ <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="title_change_settings" msgid="1376365968844349552">"ບັນທຶກການຕັ້ງຄ່າ"</string>
<string name="notification_dots_service_title" msgid="4284221181793592871">"ສະແດງຈຸດການແຈ້ງເຕືອນ"</string>
- <string name="auto_add_shortcuts_label" msgid="3698776050751790653">"ເພີ່ມໄອຄອນແອັບໄປໃສ່ໜ້າຈໍຫຼັກ"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"ເພີ່ມໄອຄອນໃສ່ໜ້າຈໍຫຼັກ"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"ສຳລັບແອັບໃໝ່"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"​ບໍ່​ຮູ້​ຈັກ"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"ລຶບ​"</string>
<string name="abandoned_search" msgid="891119232568284442">"ຊອກຫາ"</string>
<string name="abandoned_promises_title" msgid="7096178467971716750">"ແອັບຯ​ນີ້​ຍັງ​ບໍ່​ໄດ້​ຕິດ​ຕັ້ງ​ເທື່ອ"</string>
<string name="abandoned_promise_explanation" msgid="3990027586878167529">"​ແອັບຯ​ສຳ​ລັບ​ໄອ​ຄອນ​ນີ້​ຍັງ​ບໍ່ໄດ້​ຕິດ​ຕັ້ງ​ເທື່ອ. ທ່ານ​ສາ​ມາດ​ລຶບ​ມັນ​ອອກ ຫຼື​ຊອກ​ຫາ​ແອັບຯ ແລ້ວ​ຕິດ​ຕັ້ງ​ມັນ​ໄດ້​ດ້ວຍ​ຕົນ​ເອງ."</string>
- <string name="app_installing_title" msgid="5864044122733792085">"ກຳລັງຕິດຕັ້ງ <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="PROGRESS">%2$s</xliff:g> ສຳເລັດແລ້ວ"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> ກຳ​ລັງ​ດາວ​ໂຫຼດ, <xliff:g id="PROGRESS">%2$s</xliff:g> ສຳ​ເລັດ"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> ກຳ​ລັງ​ລໍ​ຖ້າ​ຕິດ​ຕັ້ງ"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"ວິດເຈັດ <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="widgets_list" msgid="796804551140113767">"ລາຍຊື່ວິດເຈັດ"</string>
<string name="widgets_list_closed" msgid="6141506579418771922">"ປິດລາຍຊື່ວິດເຈັດແລ້ວ"</string>
<string name="action_add_to_workspace" msgid="8902165848117513641">"ເພີ່ມໃສ່ໜ້າຈໍຫຼັກ"</string>
@@ -151,20 +129,15 @@
<string name="action_deep_shortcut" msgid="2864038805849372848">"ທາງລັດ"</string>
<string name="shortcuts_menu_with_notifications_description" msgid="2676582286544232849">"ປຸ່ມລັດ ແລະ ການແຈ້ງເຕືອນ"</string>
<string name="action_dismiss_notification" msgid="5909461085055959187">"ປິດໄວ້"</string>
- <string name="accessibility_close" msgid="2277148124685870734">"ປິດ"</string>
<string name="notification_dismissed" msgid="6002233469409822874">"ປິດການແຈ້ງເຕືອນແລ້ວ"</string>
<string name="all_apps_personal_tab" msgid="4190252696685155002">"ສ່ວນຕົວ"</string>
<string name="all_apps_work_tab" msgid="4884822796154055118">"ວຽກ"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"ໂປຣໄຟລ໌ບ່ອນເຮັດວຽກ"</string>
- <string name="work_profile_edu_work_apps" msgid="7895468576497746520">"ແອັບບ່ອນເຮັດວຽກແມ່ນຖືກຕິດປ້າຍ ແລະ ສະແດງໃຫ້ຜູ້ເບິ່ງແຍງໄອທີຂອງທ່ານເຫັນ"</string>
- <string name="work_profile_edu_accept" msgid="6069788082535149071">"ເຂົ້າໃຈແລ້ວ"</string>
- <string name="work_apps_paused_title" msgid="3040901117349444598">"ຢຸດແອັບວຽກໄວ້ຊົ່ວຄາວແລ້ວ"</string>
- <string name="work_apps_paused_body" msgid="261634750995824906">"ແອັບບ່ອນເຮັດວຽກຂອງທ່ານຈະບໍ່ສາມາດສົ່ງການແຈ້ງເຕືອນຫາທ່ານ, ໃຊ້ແບັດເຕີຣີຂອງທ່ານ ຫຼື ເຂົ້າເຖິງສະຖານທີ່ຂອງທ່ານໄດ້"</string>
- <string name="work_apps_paused_content_description" msgid="5149623040804051095">"ແອັບບ່ອນເຮັດວຽກຖືກປິດໄວ້ຢູ່. ແອັບບ່ອນເຮັດວຽກຂອງທ່ານຈະບໍ່ສາມາດສົ່ງການແຈ້ງເຕືອນໃຫ້ທ່ານ, ໃຊ້ແບັດເຕີຣີຂອງທ່ານ ຫຼື ເຂົ້າເຖິງສະຖານທີ່ຂອງທ່ານໄດ້"</string>
- <string name="work_apps_paused_edu_banner" msgid="8872412121608402058">"ແອັບບ່ອນເຮັດວຽກແມ່ນຖືກຕິດປ້າຍ ແລະ ສະແດງໃຫ້ຜູ້ເບິ່ງແຍງໄອທີຂອງທ່ານເຫັນ"</string>
- <string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"ເຂົ້າໃຈແລ້ວ"</string>
- <string name="work_apps_pause_btn_text" msgid="1921059713673767460">"ປິດການໃຊ້ແອັບບ່ອນເຮັດວຽກ"</string>
- <string name="work_apps_enable_btn_text" msgid="1156432622148413741">"ເປີດໃຊ້ແອັບບ່ອນເຮັດວຽກ"</string>
- <string name="developer_options_filter_hint" msgid="5896817443635989056">"ກັ່ນຕອງ"</string>
+ <string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"ຊອກຫາແອັບວຽກຢູ່ບ່ອນນີ້"</string>
+ <string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"ແຕ່ລະແອັບວຽກຈະມີປ້າຍ ແລະ ຖືກຈັດເກັບໄວ້ຢ່າງປອດໄພໂດຍອົງກອນຂອງທ່ານ. ທ່ານສາມາດຍ້າຍແອັບໄປໃສ່ໜ້າຈໍຫຼັກເພື່ອໃຫ້ເຂົ້າໃຊ້ງ່າຍຂຶ້ນໄດ້."</string>
+ <string name="work_mode_on_label" msgid="4781128097185272916">"ຈັດການໂດຍອົງກອນຂອງທ່ານ"</string>
+ <string name="work_mode_off_label" msgid="3194894777601421047">"ການແຈ້ງເຕືອນ ແລະ ແອັບຖືກປິດໄວ້"</string>
+ <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"ປິດ"</string>
+ <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"ປິດແລ້ວ"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"ບໍ່ສຳເລັດ: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
</resources>
diff --git a/res/values-lt/strings.xml b/res/values-lt/strings.xml
index e4fdfc613c..6571582cec 100644
--- a/res/values-lt/strings.xml
+++ b/res/values-lt/strings.xml
@@ -20,63 +20,39 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="649227358658669779">"Launcher3"</string>
+ <string name="folder_name" msgid="7371454440695724752"></string>
<string name="work_folder_name" msgid="3753320833950115786">"Darbas"</string>
<string name="activity_not_found" msgid="8071924732094499514">"Programa neįdiegta."</string>
<string name="activity_not_available" msgid="7456344436509528827">"Programa nepasiekiama"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"Atsisiųsta programa išjungta Saugos režimu"</string>
<string name="safemode_widget_error" msgid="4863470563535682004">"Valdikliai išjungti Saugiame režime"</string>
<string name="shortcut_not_available" msgid="2536503539825726397">"Sparčiojo klavišo negalima naudoti"</string>
- <string name="home_screen" msgid="5629429142036709174">"Pagrindinis"</string>
- <string name="recent_task_option_split_screen" msgid="6690461455618725183">"Išskaidyto ekrano režimas"</string>
- <string name="split_screen_position_top" msgid="1504965011158689649">"Išskaidyti viršun"</string>
- <string name="split_screen_position_left" msgid="7537793098851830883">"Išskaidyti kairėn"</string>
- <string name="split_screen_position_right" msgid="1569377524925193369">"Išskaidyti dešinėn"</string>
- <string name="split_app_info_accessibility" msgid="5475288491241414932">"Programos „%1$s“ informacija"</string>
- <string name="long_press_widget_to_add" msgid="3587712543577675817">"Dukart pal. ir palaik., kad perkeltumėte valdiklį."</string>
- <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Dukart palieskite ir palaikykite, kad perkeltumėte valdiklį ar naudotumėte tinkintus veiksmus."</string>
+ <string name="home_screen" msgid="806512411299847073">"Pagrindinis ekranas"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"Tinkinti veiksmai"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"Palieskite ir laikykite, kad pasirinkt. valdiklį."</string>
+ <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Dukart palieskite ir laikykite, kad pasirinktumėte valdiklį ar naudotumėte tinkintus veiksmus."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d plotis ir %2$d aukštis"</string>
- <string name="widget_preview_context_description" msgid="9045841361655787574">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g> valdiklis"</string>
- <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Paliesdami ir palaikydami valdiklį galite judėti pagrindiniame ekrane"</string>
- <string name="add_to_home_screen" msgid="8631549138215492708">"Pridėti prie pagrindinio ekrano"</string>
- <string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"Valdiklis „<xliff:g id="WIDGET_NAME">%1$s</xliff:g>“ pridėtas prie pagrindinio ekrano"</string>
- <string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# valdiklis}one{# valdiklis}few{# valdikliai}many{# valdiklio}other{# valdiklių}}"</string>
- <string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{# spartusis klavišas}one{# spartusis klavišas}few{# spartieji klavišai}many{# sparčiojo klavišo}other{# sparčiųjų klavišų}}"</string>
- <string name="widgets_and_shortcuts_count" msgid="7209136747878365116">"<xliff:g id="WIDGETS_COUNT">%1$s</xliff:g>, <xliff:g id="SHORTCUTS_COUNT">%2$s</xliff:g>"</string>
- <string name="widget_button_text" msgid="2880537293434387943">"Valdikliai"</string>
- <string name="widgets_full_sheet_search_bar_hint" msgid="8484659090860596457">"Paieška"</string>
- <string name="widgets_full_sheet_cancel_button_description" msgid="5766167035728653605">"Išvalyti tekstą iš paieškos laukelio"</string>
- <string name="no_widgets_available" msgid="4337693382501046170">"Valdikliai ir spartieji klavišai nepasiekiami"</string>
- <string name="no_search_results" msgid="3787956167293097509">"Neaptikta jokių valdiklių ar sparčiųjų klavišų"</string>
- <string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Asmeniniai"</string>
- <string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Darbas"</string>
- <string name="widget_category_conversations" msgid="8894438636213590446">"Pokalbiai"</string>
- <string name="widget_education_header" msgid="4874760613775913787">"Lengvai pasiekiama naudinga informacija"</string>
- <string name="widget_education_content" msgid="745542879510751525">"Jei norite gauti informacijos neatidarę programų, galite pridėti valdiklių pagrindiniame ekrane"</string>
- <string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Palieskite, kad pakeistumėte valdiklio nustatymus"</string>
- <string name="widget_education_close_button" msgid="8676165703104836580">"Supratau"</string>
- <string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Pakeisti valdiklio nustatymus"</string>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Palieskite ir palaikykite, kad padėtumėte patys"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"Pridėti automatiškai"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Paieškos programos"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Įkeliamos programos…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"Nerasta jokių užklausą „<xliff:g id="QUERY">%1$s</xliff:g>“ atitinkančių programų"</string>
<string name="all_apps_search_market_message" msgid="1366263386197059176">"Ieškoti daugiau programų"</string>
<string name="label_application" msgid="8531721983832654978">"Programa"</string>
- <string name="all_apps_label" msgid="5015784846527570951">"Visos programos"</string>
<string name="notifications_header" msgid="1404149926117359025">"Pranešimai"</string>
- <string name="long_press_shortcut_to_add" msgid="5405328730817637737">"Dukart pal. ir palaik., kad perk. spart. klavišą."</string>
- <string name="long_accessible_way_to_add_shortcut" msgid="2199537273817090740">"Dukart palieskite ir palaikykite, kad perkeltumėte spartųjį klavišą ar naudotumėte tinkintus veiksmus."</string>
- <string name="out_of_space" msgid="6692471482459245734">"Šiame pagrindiniame ekrane nebėra vietos"</string>
+ <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"Paliesk. ir palaikyk., kad pasirinkt. spart. klav."</string>
+ <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"Dukart palieskite ir palaikykite, kad pasirinkt. spartųjį klavišą ar naudotumėte tinkintus veiksmus."</string>
+ <string name="out_of_space" msgid="4691004494942118364">"Šiame pagrindiniame ekrane vietos nebėra."</string>
<string name="hotseat_out_of_space" msgid="7448809638125333693">"Mėgstamiausių dėkle nebėra vietos"</string>
<string name="all_apps_button_label" msgid="8130441508702294465">"Programų sąrašas"</string>
- <string name="all_apps_search_results" msgid="5889367432531296759">"Paieškos rezultatai"</string>
<string name="all_apps_button_personal_label" msgid="1315764287305224468">"Asmeninių programų sąrašas"</string>
<string name="all_apps_button_work_label" msgid="7270707118948892488">"Darbo programų sąrašas"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"Pagrindinis"</string>
<string name="remove_drop_target_label" msgid="7812859488053230776">"Ištrinti"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"Pašalinti"</string>
<string name="app_info_drop_target_label" msgid="692894985365717661">"Programos inform."</string>
<string name="install_drop_target_label" msgid="2539096853673231757">"Įdiegti"</string>
- <string name="dismiss_prediction_label" msgid="3357562989568808658">"Nesiūlyti programos"</string>
- <string name="pin_prediction" msgid="4196423321649756498">"Prisegti numatymą"</string>
<string name="permlab_install_shortcut" msgid="5632423390354674437">"įdiegti sparčiuosius klavišus"</string>
<string name="permdesc_install_shortcut" msgid="923466509822011139">"Programai leidžiama pridėti sparčiuosius klavišus be naudotojo įsikišimo."</string>
<string name="permlab_read_settings" msgid="1941457408239617576">"skaityti pagrindinio puslapio nustatymus ir sparčiuosius klavišus"</string>
@@ -84,13 +60,17 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"rašyti pagrindinio puslapio nustatymus ir sparčiuosius klavišus"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"Programai leidžiama keisti pagrindinio puslapio nustatymus ir sparčiuosius klavišus."</string>
<string name="msg_no_phone_permission" msgid="9208659281529857371">"„<xliff:g id="APP_NAME">%1$s</xliff:g>“ neleidžiama skambinti"</string>
- <string name="gadget_error_text" msgid="740356548025791839">"Nepavyko įkelti valdiklio"</string>
- <string name="gadget_setup_text" msgid="8348374825537681407">"Valdiklio nustatymai"</string>
- <string name="gadget_complete_setup_text" msgid="309040266978007925">"Palieskite, kad užbaigtumėte sąranką"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"Problema įkeliant valdiklį"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"Sąranka"</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"Tai sistemos programa ir jos negalima pašalinti."</string>
- <string name="folder_hint_text" msgid="5174843001373488816">"Pavadinimo redagavimas"</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"Aplankas be pavadinimo"</string>
<string name="disabled_app_label" msgid="6673129024321402780">"„<xliff:g id="APP_NAME">%1$s</xliff:g>“ išjungta"</string>
- <string name="dotted_app_label" msgid="1704091277755818896">"{count,plural,offset:1 =1{Programoje „{app_name}“ yra # pranešimas}one{Programoje „{app_name}“ yra # pranešimas}few{Programoje „{app_name}“ yra # pranešimai}many{Programoje „{app_name}“ yra # pranešimo}other{Programoje „{app_name}“ yra # pranešimų}}"</string>
+ <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+ <item quantity="one">Programoje „<xliff:g id="APP_NAME_2">%1$s</xliff:g>“ yra <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> pranešimas</item>
+ <item quantity="few">Programoje „<xliff:g id="APP_NAME_2">%1$s</xliff:g>“ yra <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> pranešimai</item>
+ <item quantity="many">Programoje „<xliff:g id="APP_NAME_2">%1$s</xliff:g>“ yra <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> pranešimo</item>
+ <item quantity="other">Programoje „<xliff:g id="APP_NAME_2">%1$s</xliff:g>“ yra <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> pranešimų</item>
+ </plurals>
<string name="default_scroll_format" msgid="7475544710230993317">"%1$d psl. iš %2$d"</string>
<string name="workspace_scroll_format" msgid="8458889198184077399">"%1$d pagrindinis ekranas iš %2$d"</string>
<string name="workspace_new_page" msgid="257366611030256142">"Naujas pagrindinio ekrano puslapis"</string>
@@ -99,10 +79,10 @@
<string name="folder_tap_to_rename" msgid="4017685068016979677">"Palieskite, kad išsaugotumėte pakeistą pavadinimą"</string>
<string name="folder_closed" msgid="4100806530910930934">"Aplankas uždarytas"</string>
<string name="folder_renamed" msgid="1794088362165669656">"Aplankas pervardytas kaip „<xliff:g id="NAME">%1$s</xliff:g>“"</string>
- <string name="folder_name_format_exact" msgid="8626242716117004803">"Aplankas: „<xliff:g id="NAME">%1$s</xliff:g>“, elementų: <xliff:g id="SIZE">%2$d</xliff:g>"</string>
- <string name="folder_name_format_overflow" msgid="4270108890534995199">"Aplankas: „<xliff:g id="NAME">%1$s</xliff:g>“, elementų: <xliff:g id="SIZE">%2$d</xliff:g> ar daugiau"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"Aplankas: „<xliff:g id="NAME">%1$s</xliff:g>“"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"Valdikliai"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Ekrano fonai"</string>
- <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Ekrano fonas ir stilius"</string>
+ <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Stiliai ir ekrano fonai"</string>
<string name="settings_button_text" msgid="8873672322605444408">"„Home“ nustatymai"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Išjungė administratorius"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Leisti pasukti pagrindinį ekraną"</string>
@@ -114,16 +94,16 @@
<string name="msg_missing_notification_access" msgid="281113995110910548">"Kad būtų rodomi pranešimų taškai, įjunkite programos „<xliff:g id="NAME">%1$s</xliff:g>“ pranešimus."</string>
<string name="title_change_settings" msgid="1376365968844349552">"Keisti nustatymus"</string>
<string name="notification_dots_service_title" msgid="4284221181793592871">"Rodyti pranešimų taškus"</string>
- <string name="auto_add_shortcuts_label" msgid="3698776050751790653">"Pridėti progr. piktogr. pagrind. ekrane"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Pridėti piktogr. prie pagrindinio ekrano"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Skirta naujoms programoms"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"Nežinoma"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"Panaikinti"</string>
<string name="abandoned_search" msgid="891119232568284442">"Ieškoti"</string>
<string name="abandoned_promises_title" msgid="7096178467971716750">"Ši programa neįdiegta"</string>
<string name="abandoned_promise_explanation" msgid="3990027586878167529">"Šios piktogramos programa neįdiegta. Galite ją pašalinti arba bandyti ieškoti programos ir ją įdiegti patys."</string>
- <string name="app_installing_title" msgid="5864044122733792085">"Įdiegiama: „<xliff:g id="NAME">%1$s</xliff:g>“; baigta: <xliff:g id="PROGRESS">%2$s</xliff:g>"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"Atsisiunčiama programa „<xliff:g id="NAME">%1$s</xliff:g>“, <xliff:g id="PROGRESS">%2$s</xliff:g> baigta"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"Laukiama, kol bus įdiegta programa „<xliff:g id="NAME">%1$s</xliff:g>“"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"„<xliff:g id="NAME">%1$s</xliff:g>“ valdikliai"</string>
<string name="widgets_list" msgid="796804551140113767">"Valdiklių sąrašas"</string>
<string name="widgets_list_closed" msgid="6141506579418771922">"Valdiklių sąrašas uždarytas"</string>
<string name="action_add_to_workspace" msgid="8902165848117513641">"Pridėti prie pagrind. ekrano"</string>
@@ -151,20 +131,15 @@
<string name="action_deep_shortcut" msgid="2864038805849372848">"Spartieji klavišai"</string>
<string name="shortcuts_menu_with_notifications_description" msgid="2676582286544232849">"Spartieji klavišai ir pranešimai"</string>
<string name="action_dismiss_notification" msgid="5909461085055959187">"Atsisakyti"</string>
- <string name="accessibility_close" msgid="2277148124685870734">"Uždaryti"</string>
<string name="notification_dismissed" msgid="6002233469409822874">"Pranešimo atsisakyta"</string>
<string name="all_apps_personal_tab" msgid="4190252696685155002">"Asmeninės"</string>
<string name="all_apps_work_tab" msgid="4884822796154055118">"Darbo"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"Darbo profilis"</string>
- <string name="work_profile_edu_work_apps" msgid="7895468576497746520">"Darbo programos yra pažymėtos ženkleliu ir matomos IT administratoriui"</string>
- <string name="work_profile_edu_accept" msgid="6069788082535149071">"Supratau"</string>
- <string name="work_apps_paused_title" msgid="3040901117349444598">"Darbo programos pristabdytos"</string>
- <string name="work_apps_paused_body" msgid="261634750995824906">"Darbo programos negali siųsti jums pranešimų, naudoti jūsų akumuliatoriaus ar pasiekti jūsų vietovės"</string>
- <string name="work_apps_paused_content_description" msgid="5149623040804051095">"Darbo programos išjungtos. Darbo programos negali siųsti jums pranešimų, naudoti jūsų akumuliatoriaus ar pasiekti jūsų vietovės"</string>
- <string name="work_apps_paused_edu_banner" msgid="8872412121608402058">"Darbo programos yra pažymėtos ženkleliu ir matomos IT administratoriui"</string>
- <string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"Supratau"</string>
- <string name="work_apps_pause_btn_text" msgid="1921059713673767460">"Išjungti darbo programas"</string>
- <string name="work_apps_enable_btn_text" msgid="1156432622148413741">"Įjungti darbo programas"</string>
- <string name="developer_options_filter_hint" msgid="5896817443635989056">"Filtruoti"</string>
+ <string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"Darbo programas rasite čia"</string>
+ <string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"Kiekvienai darbo programai priskirtas ženklelis, o tokių programų sauga rūpinasi jūsų organizacija. Perkelkite programas į pagrindinį ekraną, kad galėtumėte lengviau jas pasiekti."</string>
+ <string name="work_mode_on_label" msgid="4781128097185272916">"Tvarko jūsų organizacija"</string>
+ <string name="work_mode_off_label" msgid="3194894777601421047">"Programos ir pranešimai išjungti"</string>
+ <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Uždaryti"</string>
+ <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Uždaryta"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Nepavyko: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
</resources>
diff --git a/res/values-lv/strings.xml b/res/values-lv/strings.xml
index f02d4fba00..3da0fbb2e5 100644
--- a/res/values-lv/strings.xml
+++ b/res/values-lv/strings.xml
@@ -20,63 +20,39 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="649227358658669779">"Launcher3"</string>
+ <string name="folder_name" msgid="7371454440695724752"></string>
<string name="work_folder_name" msgid="3753320833950115786">"Darbs"</string>
<string name="activity_not_found" msgid="8071924732094499514">"Lietotne nav instalēta."</string>
<string name="activity_not_available" msgid="7456344436509528827">"Lietotne nav pieejama."</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"Lejupielādētā lietotne ir atspējota drošajā režīmā."</string>
<string name="safemode_widget_error" msgid="4863470563535682004">"Logrīki atspējoti drošajā režīmā"</string>
<string name="shortcut_not_available" msgid="2536503539825726397">"Saīsne nav pieejama."</string>
- <string name="home_screen" msgid="5629429142036709174">"Sākums"</string>
- <string name="recent_task_option_split_screen" msgid="6690461455618725183">"Sadalīt ekrānu"</string>
- <string name="split_screen_position_top" msgid="1504965011158689649">"Sadalījums augšdaļā"</string>
- <string name="split_screen_position_left" msgid="7537793098851830883">"Sadalījums pa kreisi"</string>
- <string name="split_screen_position_right" msgid="1569377524925193369">"Sadalījums pa labi"</string>
- <string name="split_app_info_accessibility" msgid="5475288491241414932">"%1$s: informācija par lietotni"</string>
- <string name="long_press_widget_to_add" msgid="3587712543577675817">"Lai pārvietotu logrīku, pieskarieties un turiet."</string>
- <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Lai pārvietotu logrīku, uz tā veiciet dubultskārienu un turiet. Varat arī veikt pielāgotas darbības."</string>
+ <string name="home_screen" msgid="806512411299847073">"Sākuma ekrāns"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"Pielāgotās darbības"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"Lai izvēlētos logrīku, pieskarieties un turiet to."</string>
+ <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Lai atlasītu logrīku, veiciet dubultskārienu uz tā un turiet to vai arī veiciet pielāgotas darbības."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d plats un %2$d augsts"</string>
- <string name="widget_preview_context_description" msgid="9045841361655787574">"Logrīks <xliff:g id="WIDGET_NAME">%1$s</xliff:g>"</string>
- <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Pieskarieties logrīkam un turiet to, lai to pārvietotu pa sākuma ekrānu."</string>
- <string name="add_to_home_screen" msgid="8631549138215492708">"Pievienot sākuma ekrānam"</string>
- <string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"Logrīks “<xliff:g id="WIDGET_NAME">%1$s</xliff:g>” ir pievienots sākuma ekrānam"</string>
- <string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# logrīks}zero{# logrīku}one{# logrīks}other{# logrīki}}"</string>
- <string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{# saīsne}zero{# saīšņu}one{# saīsne}other{# saīsnes}}"</string>
- <string name="widgets_and_shortcuts_count" msgid="7209136747878365116">"<xliff:g id="WIDGETS_COUNT">%1$s</xliff:g>, <xliff:g id="SHORTCUTS_COUNT">%2$s</xliff:g>"</string>
- <string name="widget_button_text" msgid="2880537293434387943">"Logrīki"</string>
- <string name="widgets_full_sheet_search_bar_hint" msgid="8484659090860596457">"Meklēt"</string>
- <string name="widgets_full_sheet_cancel_button_description" msgid="5766167035728653605">"Notīrīt tekstu no meklēšanas lodziņa"</string>
- <string name="no_widgets_available" msgid="4337693382501046170">"Logrīki un saīsnes nav pieejamas."</string>
- <string name="no_search_results" msgid="3787956167293097509">"Netika atrasts neviens logrīks vai saīsne."</string>
- <string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Personīgs"</string>
- <string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Darba"</string>
- <string name="widget_category_conversations" msgid="8894438636213590446">"Sarunas"</string>
- <string name="widget_education_header" msgid="4874760613775913787">"Ērta piekļuve noderīgai informācijai"</string>
- <string name="widget_education_content" msgid="745542879510751525">"Lai iegūtu informāciju, neatverot lietotnes, varat pievienot logrīkus sākuma ekrānā."</string>
- <string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Pieskarieties, lai mainītu logrīka iestatījumus."</string>
- <string name="widget_education_close_button" msgid="8676165703104836580">"Labi"</string>
- <string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Mainīt logrīka iestatījumus"</string>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Pieskarieties un turiet, lai manuāli pievienotu"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"Pievienot automātiski"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Meklēt lietotnes"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Notiek lietotņu ielāde…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"Vaicājumam “<xliff:g id="QUERY">%1$s</xliff:g>” neatbilda neviena lietotne"</string>
<string name="all_apps_search_market_message" msgid="1366263386197059176">"Meklēt citas lietotnes"</string>
<string name="label_application" msgid="8531721983832654978">"Lietotne"</string>
- <string name="all_apps_label" msgid="5015784846527570951">"Visas lietotnes"</string>
<string name="notifications_header" msgid="1404149926117359025">"Paziņojumi"</string>
- <string name="long_press_shortcut_to_add" msgid="5405328730817637737">"Lai pārvietotu saīsni, pieskarieties un turiet."</string>
- <string name="long_accessible_way_to_add_shortcut" msgid="2199537273817090740">"Lai pārvietotu saīsni, uz tās veiciet dubultskārienu un turiet. Varat arī veikt pielāgotas darbības."</string>
- <string name="out_of_space" msgid="6692471482459245734">"Šajā sākuma ekrānā nav vietas"</string>
+ <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"Lai atlasītu saīsni, pieskarieties un turiet to."</string>
+ <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"Lai atlasītu saīsni, veiciet dubultskārienu uz tās un turiet to. Varat arī veikt pielāgotas darbības."</string>
+ <string name="out_of_space" msgid="4691004494942118364">"Šajā sākuma ekrānā vairs nav vietas."</string>
<string name="hotseat_out_of_space" msgid="7448809638125333693">"Izlases joslā vairs nav vietas."</string>
<string name="all_apps_button_label" msgid="8130441508702294465">"Lietotņu saraksts"</string>
- <string name="all_apps_search_results" msgid="5889367432531296759">"Meklēšanas rezultāti"</string>
<string name="all_apps_button_personal_label" msgid="1315764287305224468">"Personīgo lietotņu saraksts"</string>
<string name="all_apps_button_work_label" msgid="7270707118948892488">"Darba lietotņu saraksts"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"Sākums"</string>
<string name="remove_drop_target_label" msgid="7812859488053230776">"Noņemt"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"Atinstalēt"</string>
<string name="app_info_drop_target_label" msgid="692894985365717661">"Par lietotni"</string>
<string name="install_drop_target_label" msgid="2539096853673231757">"Instalēt"</string>
- <string name="dismiss_prediction_label" msgid="3357562989568808658">"Neieteikt lietotni"</string>
- <string name="pin_prediction" msgid="4196423321649756498">"Piespraust prognozēto lietotni"</string>
<string name="permlab_install_shortcut" msgid="5632423390354674437">"instalēt saīsnes"</string>
<string name="permdesc_install_shortcut" msgid="923466509822011139">"Ļauj lietotnei pievienot saīsnes, nejautājot lietotājam."</string>
<string name="permlab_read_settings" msgid="1941457408239617576">"lasīt sākuma ekrāna iestatījumus un saīsnes"</string>
@@ -84,13 +60,16 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"rakstīt sākuma ekrāna iestatījumus un saīsnes"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"Ļauj lietotnei mainīt iestatījumus un saīsnes sākuma ekrānā."</string>
<string name="msg_no_phone_permission" msgid="9208659281529857371">"Lietotnei <xliff:g id="APP_NAME">%1$s</xliff:g> nav atļauts veikt tālruņa zvanus."</string>
- <string name="gadget_error_text" msgid="740356548025791839">"Nevar ielādēt logrīku."</string>
- <string name="gadget_setup_text" msgid="8348374825537681407">"Logrīka iestatījumi"</string>
- <string name="gadget_complete_setup_text" msgid="309040266978007925">"Pieskarieties, lai pabeigtu iestatīšanu"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"Ielādējot logrīku, radās problēma."</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"Notiek iestatīšana"</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"Šī ir sistēmas lietotne, un to nevar atinstalēt."</string>
- <string name="folder_hint_text" msgid="5174843001373488816">"Nosaukuma rediģēšana"</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"Mape bez nosaukuma"</string>
<string name="disabled_app_label" msgid="6673129024321402780">"Lietotne <xliff:g id="APP_NAME">%1$s</xliff:g> ir atspējota"</string>
- <string name="dotted_app_label" msgid="1704091277755818896">"{count,plural,offset:1 =1{Lietotnē {app_name} ir # paziņojums}zero{Lietotnē {app_name} ir # paziņojumi}one{Lietotnē {app_name} ir # paziņojums}other{Lietotnē {app_name} ir # paziņojumi}}"</string>
+ <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+ <item quantity="zero">Lietotnē <xliff:g id="APP_NAME_2">%1$s</xliff:g> ir <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> paziņojumi</item>
+ <item quantity="one">Lietotnē <xliff:g id="APP_NAME_2">%1$s</xliff:g> ir <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> paziņojums</item>
+ <item quantity="other">Lietotnē <xliff:g id="APP_NAME_2">%1$s</xliff:g> ir <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> paziņojumi</item>
+ </plurals>
<string name="default_scroll_format" msgid="7475544710230993317">"%1$d. lapa no %2$d"</string>
<string name="workspace_scroll_format" msgid="8458889198184077399">"Sākuma ekrāns: %1$d no %2$d"</string>
<string name="workspace_new_page" msgid="257366611030256142">"Jauna sākuma ekrāna lapa"</string>
@@ -99,10 +78,10 @@
<string name="folder_tap_to_rename" msgid="4017685068016979677">"Pieskarieties, lai saglabātu jauno nosaukumu."</string>
<string name="folder_closed" msgid="4100806530910930934">"Mape aizvērta"</string>
<string name="folder_renamed" msgid="1794088362165669656">"Mape pārdēvēta par: <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="folder_name_format_exact" msgid="8626242716117004803">"Mape <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> vienumi"</string>
- <string name="folder_name_format_overflow" msgid="4270108890534995199">"Mape <xliff:g id="NAME">%1$s</xliff:g>, vienumu skaits mapē: vismaz <xliff:g id="SIZE">%2$d</xliff:g>"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"Mape: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"Logrīki"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Fona tapetes"</string>
- <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Fona tapete un stils"</string>
+ <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Stili un fona tapetes"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Sākumlapas iestatījumi"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Atspējojis administrators"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Atļaut sākuma ekrāna pagriešanu"</string>
@@ -114,16 +93,16 @@
<string name="msg_missing_notification_access" msgid="281113995110910548">"Lai tiktu rādīti paziņojumu punkti, ieslēdziet paziņojumus lietotnei <xliff:g id="NAME">%1$s</xliff:g>."</string>
<string name="title_change_settings" msgid="1376365968844349552">"Mainīt iestatījumus"</string>
<string name="notification_dots_service_title" msgid="4284221181793592871">"Rādīt paziņojumu punktus"</string>
- <string name="auto_add_shortcuts_label" msgid="3698776050751790653">"Pievienot lietotņu ikonas sākuma ekrānam"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Pievienot ikonu sākuma ekrānā"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Jaunām lietotnēm"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"Nezināma"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"Noņemt"</string>
<string name="abandoned_search" msgid="891119232568284442">"Meklēt"</string>
<string name="abandoned_promises_title" msgid="7096178467971716750">"Šī lietotne nav instalēta"</string>
<string name="abandoned_promise_explanation" msgid="3990027586878167529">"Šai ikonai paredzētā lietotne nav instalēta. Varat noņemt ikonu vai meklēt lietotni un instalēt to manuāli."</string>
- <string name="app_installing_title" msgid="5864044122733792085">"Notiek lietotnes “<xliff:g id="NAME">%1$s</xliff:g>” instalēšana. Norise: <xliff:g id="PROGRESS">%2$s</xliff:g>."</string>
<string name="app_downloading_title" msgid="8336702962104482644">"Lietotnes <xliff:g id="NAME">%1$s</xliff:g> lejupielāde (<xliff:g id="PROGRESS">%2$s</xliff:g> pabeigti)"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"Notiek <xliff:g id="NAME">%1$s</xliff:g> instalēšana"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"<xliff:g id="NAME">%1$s</xliff:g> logrīki"</string>
<string name="widgets_list" msgid="796804551140113767">"Logrīku saraksts"</string>
<string name="widgets_list_closed" msgid="6141506579418771922">"Logrīku saraksts aizvērts"</string>
<string name="action_add_to_workspace" msgid="8902165848117513641">"Pievienot sākuma ekrānam"</string>
@@ -151,20 +130,15 @@
<string name="action_deep_shortcut" msgid="2864038805849372848">"Saīsnes"</string>
<string name="shortcuts_menu_with_notifications_description" msgid="2676582286544232849">"Saīsnes un paziņojumi"</string>
<string name="action_dismiss_notification" msgid="5909461085055959187">"Nerādīt"</string>
- <string name="accessibility_close" msgid="2277148124685870734">"Aizvērt"</string>
<string name="notification_dismissed" msgid="6002233469409822874">"Paziņojums netiek rādīts"</string>
<string name="all_apps_personal_tab" msgid="4190252696685155002">"Personīgās lietotnes"</string>
<string name="all_apps_work_tab" msgid="4884822796154055118">"Darba lietotnes"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"Darba profils"</string>
- <string name="work_profile_edu_work_apps" msgid="7895468576497746520">"Darba lietotnēm ir pievienota emblēma, un tās ir redzamas jūsu IT administratoram"</string>
- <string name="work_profile_edu_accept" msgid="6069788082535149071">"Labi"</string>
- <string name="work_apps_paused_title" msgid="3040901117349444598">"Darba lietotnes ir apturētas"</string>
- <string name="work_apps_paused_body" msgid="261634750995824906">"Jūsu darba lietotnes nevar sūtīt jums paziņojumus, izmantot akumulatoru un piekļūt jūsu atrašanās vietai."</string>
- <string name="work_apps_paused_content_description" msgid="5149623040804051095">"Darba lietotnes ir izslēgtas. Jūsu darba lietotnes nevar sūtīt jums paziņojumus, izmantot akumulatoru un piekļūt jūsu atrašanās vietai."</string>
- <string name="work_apps_paused_edu_banner" msgid="8872412121608402058">"Darba lietotnēm ir pievienota emblēma, un tās ir redzamas jūsu IT administratoram"</string>
- <string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"Labi"</string>
- <string name="work_apps_pause_btn_text" msgid="1921059713673767460">"Izslēgt darba lietotnes"</string>
- <string name="work_apps_enable_btn_text" msgid="1156432622148413741">"Ieslēgt darba lietotnes"</string>
- <string name="developer_options_filter_hint" msgid="5896817443635989056">"Filtrs"</string>
+ <string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"Meklējiet darba lietotnes šeit"</string>
+ <string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"Katrai darba lietotnei ir emblēma, un jūsu organizācija aizsargā šīs lietotnes. Lai varētu ērtāk piekļūt lietotnēm, pārvietojiet tās uz sākuma ekrānu."</string>
+ <string name="work_mode_on_label" msgid="4781128097185272916">"Pārvalda jūsu organizācija"</string>
+ <string name="work_mode_off_label" msgid="3194894777601421047">"Paziņojumi un lietotnes ir izslēgtas"</string>
+ <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Aizvērt"</string>
+ <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Aizvērta"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Neizdevās: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
</resources>
diff --git a/res/values-mk/strings.xml b/res/values-mk/strings.xml
index 0bc7043b68..ab14e8900b 100644
--- a/res/values-mk/strings.xml
+++ b/res/values-mk/strings.xml
@@ -26,57 +26,32 @@
<string name="safemode_shortcut_error" msgid="9160126848219158407">"Преземената апликација е оневозможена во безбеден режим"</string>
<string name="safemode_widget_error" msgid="4863470563535682004">"Додатоците се оневозможени во безбеден режим"</string>
<string name="shortcut_not_available" msgid="2536503539825726397">"Кратенката не е достапна"</string>
- <string name="home_screen" msgid="5629429142036709174">"Почетен екран"</string>
- <string name="recent_task_option_split_screen" msgid="6690461455618725183">"Поделен екран"</string>
- <string name="split_screen_position_top" msgid="1504965011158689649">"Подели нагоре"</string>
- <string name="split_screen_position_left" msgid="7537793098851830883">"Подели налево"</string>
- <string name="split_screen_position_right" msgid="1569377524925193369">"Подели надесно"</string>
- <string name="split_app_info_accessibility" msgid="5475288491241414932">"Податоци за апликација за %1$s"</string>
- <string name="long_press_widget_to_add" msgid="3587712543577675817">"Допрете и задржете за да преместите виџет."</string>
- <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Допрете двапати и задржете за да преместите виџет или користете приспособени дејства."</string>
+ <string name="home_screen" msgid="806512411299847073">"Почетен екран"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"Приспособени дејства"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"Допри и задржи за да се избере виџетот."</string>
+ <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Допрете двапати и задржете за да изберете додаток или да користите приспособени дејства."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d широк на %2$d висок"</string>
- <string name="widget_preview_context_description" msgid="9045841361655787574">"Виџет <xliff:g id="WIDGET_NAME">%1$s</xliff:g>"</string>
- <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Допрете го и задржете го виџетот за да го движите наоколу на почетниот екран"</string>
- <string name="add_to_home_screen" msgid="8631549138215492708">"Додај на почетниот екран"</string>
- <string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"Виџетот <xliff:g id="WIDGET_NAME">%1$s</xliff:g> е додаден на почетниот екран"</string>
- <string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# виџет}one{# виџет}other{# виџети}}"</string>
- <string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{# кратенка}one{# кратенка}other{# кратенки}}"</string>
- <string name="widgets_and_shortcuts_count" msgid="7209136747878365116">"<xliff:g id="WIDGETS_COUNT">%1$s</xliff:g>, <xliff:g id="SHORTCUTS_COUNT">%2$s</xliff:g>"</string>
- <string name="widget_button_text" msgid="2880537293434387943">"Виџети"</string>
- <string name="widgets_full_sheet_search_bar_hint" msgid="8484659090860596457">"Пребарувајте"</string>
- <string name="widgets_full_sheet_cancel_button_description" msgid="5766167035728653605">"Избриши го текстот од полето за пребарување"</string>
- <string name="no_widgets_available" msgid="4337693382501046170">"Виџетите и кратенките не се достапни"</string>
- <string name="no_search_results" msgid="3787956167293097509">"Не се најдени виџети или кратенки"</string>
- <string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Лични"</string>
- <string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Работни"</string>
- <string name="widget_category_conversations" msgid="8894438636213590446">"Разговори"</string>
- <string name="widget_education_header" msgid="4874760613775913787">"Корисни информации на дофат на прстите"</string>
- <string name="widget_education_content" msgid="745542879510751525">"За да добивате информации без да ги отворате апликациите, може да додадете виџети на почетниот екран"</string>
- <string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Допрете за да ги промените поставките за виџетот"</string>
- <string name="widget_education_close_button" msgid="8676165703104836580">"Сфатив"</string>
- <string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Промени ги поставките за виџетот"</string>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Допрете и задржете за рачно поставување"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"Додај автоматски"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Пребарувајте апликации"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Се вчитуваат апликации…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"Не се најдени апликации што одговараат на „<xliff:g id="QUERY">%1$s</xliff:g>“"</string>
<string name="all_apps_search_market_message" msgid="1366263386197059176">"Пребарај други апликации"</string>
<string name="label_application" msgid="8531721983832654978">"Апликација"</string>
- <string name="all_apps_label" msgid="5015784846527570951">"Сите апликации"</string>
<string name="notifications_header" msgid="1404149926117359025">"Известувања"</string>
- <string name="long_press_shortcut_to_add" msgid="5405328730817637737">"Допрете и задржете за да преместите кратенка."</string>
- <string name="long_accessible_way_to_add_shortcut" msgid="2199537273817090740">"Допрете двапати и задржете за да преместите кратенка или користете приспособени дејства."</string>
- <string name="out_of_space" msgid="6692471482459245734">"Нема простор на почетниов екран"</string>
+ <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"Допрете двапати и задржете за избор на кратенка."</string>
+ <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"Допрете двапати и задржете за избор на кратенка или користете приспособени дејства."</string>
+ <string name="out_of_space" msgid="4691004494942118364">"Нема повеќе простор на овој екран на почетната страница."</string>
<string name="hotseat_out_of_space" msgid="7448809638125333693">"Нема повеќе простор на лентата „Омилени“"</string>
<string name="all_apps_button_label" msgid="8130441508702294465">"Список со апликации"</string>
- <string name="all_apps_search_results" msgid="5889367432531296759">"Резултати од пребарување"</string>
<string name="all_apps_button_personal_label" msgid="1315764287305224468">"Список со лични апликации"</string>
<string name="all_apps_button_work_label" msgid="7270707118948892488">"Список со апликации за работа"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"Почетна страница"</string>
<string name="remove_drop_target_label" msgid="7812859488053230776">"Отстрани"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"Деинсталирај"</string>
<string name="app_info_drop_target_label" msgid="692894985365717661">"Инф. за апликација"</string>
<string name="install_drop_target_label" msgid="2539096853673231757">"Инсталирај"</string>
- <string name="dismiss_prediction_label" msgid="3357562989568808658">"Не предлагај апликација"</string>
- <string name="pin_prediction" msgid="4196423321649756498">"Закачи го предвидувањето"</string>
<string name="permlab_install_shortcut" msgid="5632423390354674437">"инсталирај кратенки"</string>
<string name="permdesc_install_shortcut" msgid="923466509822011139">"Овозможува апликацијата да додава кратенки без интервенција на корисникот."</string>
<string name="permlab_read_settings" msgid="1941457408239617576">"чита поставки и кратенки на почетна страница"</string>
@@ -84,13 +59,15 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"пишува поставки и кратенки на почетна страница"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"Овозможува апликацијата да ги менува подесувањата и кратенките на почетната страница."</string>
<string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> нема дозвола за телефонски повици"</string>
- <string name="gadget_error_text" msgid="740356548025791839">"Не може да се вчита виџетот"</string>
- <string name="gadget_setup_text" msgid="8348374825537681407">"Поставки за виџет"</string>
- <string name="gadget_complete_setup_text" msgid="309040266978007925">"Допрете за да го завршите поставувањето"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"Проблем при вчитувањето на виџетот"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"Поставување"</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"Ова е системска апликација и не може да се деинсталира."</string>
- <string name="folder_hint_text" msgid="5174843001373488816">"Изменете го името"</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"Неименувана папка"</string>
<string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> е оневозможена"</string>
- <string name="dotted_app_label" msgid="1704091277755818896">"{count,plural,offset:1 =1{{app_name} има # известување}one{{app_name} има # известување}other{{app_name} има # известувања}}"</string>
+ <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+ <item quantity="one"><xliff:g id="APP_NAME_2">%1$s</xliff:g> има <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> известување</item>
+ <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g> има <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> известувања</item>
+ </plurals>
<string name="default_scroll_format" msgid="7475544710230993317">"Страница %1$d од %2$d"</string>
<string name="workspace_scroll_format" msgid="8458889198184077399">"Екран на почетна страница %1$d од %2$d"</string>
<string name="workspace_new_page" msgid="257366611030256142">"Нова страница на почетен екран"</string>
@@ -99,13 +76,13 @@
<string name="folder_tap_to_rename" msgid="4017685068016979677">"Допрете за да го зачувате преименувањето"</string>
<string name="folder_closed" msgid="4100806530910930934">"Папката е затворена"</string>
<string name="folder_renamed" msgid="1794088362165669656">"Папката е преименувана во <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="folder_name_format_exact" msgid="8626242716117004803">"Папка: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> ставки"</string>
- <string name="folder_name_format_overflow" msgid="4270108890534995199">"Папка: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> или повеќе ставки"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"Папка: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"Виџети"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Тапети"</string>
- <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Тапет и стил"</string>
- <string name="settings_button_text" msgid="8873672322605444408">"Поставки за почетен екран"</string>
+ <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Стилови и тапети"</string>
+ <string name="settings_button_text" msgid="8873672322605444408">"Поставки за Home"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Оневозможено од администраторот"</string>
- <string name="allow_rotation_title" msgid="7728578836261442095">"Дозволи ротација на почетниот екран"</string>
+ <string name="allow_rotation_title" msgid="7728578836261442095">"Дозволете ротација на Почетниот екран"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Кога телефонот се ротира"</string>
<string name="notification_dots_title" msgid="9062440428204120317">"Точки за известување"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"Вклучено"</string>
@@ -114,19 +91,19 @@
<string name="msg_missing_notification_access" msgid="281113995110910548">"За да се прикажуваат „Точки за известување“, вклучете ги известувањата за апликацијата <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="title_change_settings" msgid="1376365968844349552">"Промени ги поставките"</string>
<string name="notification_dots_service_title" msgid="4284221181793592871">"Прикажувај точки за известување"</string>
- <string name="auto_add_shortcuts_label" msgid="3698776050751790653">"Додавај икони за апликации на почетниот екран"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Додај икона на почетниот екран"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"За нови апликации"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"Непознато"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"Отстрани"</string>
<string name="abandoned_search" msgid="891119232568284442">"Барај"</string>
<string name="abandoned_promises_title" msgid="7096178467971716750">"Апликацијата не е инсталирана"</string>
<string name="abandoned_promise_explanation" msgid="3990027586878167529">"Апликацијата за оваа икона не е инсталирана. Може да ја отстраните или да се обидете да ја најдете апликацијата и да ја инсталирате рачно."</string>
- <string name="app_installing_title" msgid="5864044122733792085">"<xliff:g id="NAME">%1$s</xliff:g> се инсталира, <xliff:g id="PROGRESS">%2$s</xliff:g> завршено"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"Се презема <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="PROGRESS">%2$s</xliff:g> завршено"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> чека да се инсталира"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"Виџети за <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="widgets_list" msgid="796804551140113767">"Список со виџети"</string>
<string name="widgets_list_closed" msgid="6141506579418771922">"Списокот со виџети е затворен"</string>
- <string name="action_add_to_workspace" msgid="8902165848117513641">"Додај на почетниот екран"</string>
+ <string name="action_add_to_workspace" msgid="8902165848117513641">"Додај на Почетен екран"</string>
<string name="action_move_here" msgid="2170188780612570250">"Премести ја ставката овде"</string>
<string name="item_added_to_workspace" msgid="4211073925752213539">"Ставката е додадена на почетниот екран"</string>
<string name="item_removed" msgid="851119963877842327">"Ставката е отстранета"</string>
@@ -151,20 +128,15 @@
<string name="action_deep_shortcut" msgid="2864038805849372848">"Кратенки"</string>
<string name="shortcuts_menu_with_notifications_description" msgid="2676582286544232849">"Кратенки и известувања"</string>
<string name="action_dismiss_notification" msgid="5909461085055959187">"Отфрли"</string>
- <string name="accessibility_close" msgid="2277148124685870734">"Затвори"</string>
<string name="notification_dismissed" msgid="6002233469409822874">"Известувањето е отфрлено"</string>
<string name="all_apps_personal_tab" msgid="4190252696685155002">"Лично"</string>
<string name="all_apps_work_tab" msgid="4884822796154055118">"За работа"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"Работен профил"</string>
- <string name="work_profile_edu_work_apps" msgid="7895468576497746520">"Работните апликации имаат значка и се видливи за IT-администраторот"</string>
- <string name="work_profile_edu_accept" msgid="6069788082535149071">"Сфатив"</string>
- <string name="work_apps_paused_title" msgid="3040901117349444598">"Работните апликации се паузирани"</string>
- <string name="work_apps_paused_body" msgid="261634750995824906">"Работните апликации не може да ви испраќаат известувања, да ја користат батеријата или да пристапуваат до вашата локација"</string>
- <string name="work_apps_paused_content_description" msgid="5149623040804051095">"Работните апликации се исклучени. Не може да ви испраќаат известувања, да ја користат батеријата или да пристапуваат до вашата локација"</string>
- <string name="work_apps_paused_edu_banner" msgid="8872412121608402058">"Работните апликации имаат значка и се видливи за IT-администраторот"</string>
- <string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"Сфатив"</string>
- <string name="work_apps_pause_btn_text" msgid="1921059713673767460">"Исклучете ги работните апликации"</string>
- <string name="work_apps_enable_btn_text" msgid="1156432622148413741">"Вклучете ги работните апликации"</string>
- <string name="developer_options_filter_hint" msgid="5896817443635989056">"Филтер"</string>
+ <string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"Најдете апликации за работа тука"</string>
+ <string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"Секоја апликација за работа има значка, а организацијата се грижи за нејзината безбедност. За полесен пристап, преместете ги апликациите на почетниот екран."</string>
+ <string name="work_mode_on_label" msgid="4781128097185272916">"Управувано од вашата организација"</string>
+ <string name="work_mode_off_label" msgid="3194894777601421047">"Известувањата и апликациите се исклучени"</string>
+ <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Затвори"</string>
+ <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Затворено"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Не успеа: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
</resources>
diff --git a/res/values-ml/strings.xml b/res/values-ml/strings.xml
index 5c626db7a3..4362e7cca5 100644
--- a/res/values-ml/strings.xml
+++ b/res/values-ml/strings.xml
@@ -20,63 +20,39 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="649227358658669779">"ലോഞ്ചർ3"</string>
+ <string name="folder_name" msgid="7371454440695724752"></string>
<string name="work_folder_name" msgid="3753320833950115786">"ഔദ്യോഗികം"</string>
<string name="activity_not_found" msgid="8071924732094499514">"അപ്ലിക്കേഷൻ ഇൻസ്‌റ്റാളുചെ‌യ്‌തിട്ടില്ല."</string>
<string name="activity_not_available" msgid="7456344436509528827">"അപ്ലിക്കേഷൻ ലഭ്യമല്ല"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"ഡൗൺലോഡുചെയ്‌ത അപ്ലിക്കേഷൻ സുരക്ഷാ മോഡിൽ പ്രവർത്തനരഹിതമാക്കി"</string>
<string name="safemode_widget_error" msgid="4863470563535682004">"സുരക്ഷിത മോഡിൽ വിജറ്റുകൾ പ്രവർത്തനരഹിതമാക്കി"</string>
<string name="shortcut_not_available" msgid="2536503539825726397">"കുറുക്കുവഴി ലഭ്യമല്ല"</string>
- <string name="home_screen" msgid="5629429142036709174">"ഹോം"</string>
- <string name="recent_task_option_split_screen" msgid="6690461455618725183">"സ്‌ക്രീൻ വിഭജന മോഡ്"</string>
- <string name="split_screen_position_top" msgid="1504965011158689649">"മുകളിലേക്ക് വിഭജിക്കുക"</string>
- <string name="split_screen_position_left" msgid="7537793098851830883">"ഇടതുഭാഗത്തേക്ക് വിഭജിക്കുക"</string>
- <string name="split_screen_position_right" msgid="1569377524925193369">"വലതുഭാഗത്തേക്ക് വിഭജിക്കുക"</string>
- <string name="split_app_info_accessibility" msgid="5475288491241414932">"%1$s എന്നതിന്റെ ആപ്പ് വിവരങ്ങൾ"</string>
- <string name="long_press_widget_to_add" msgid="3587712543577675817">"വിജറ്റ് നീക്കാൻ സ്‌പർശിച്ച് പിടിക്കുക."</string>
- <string name="long_accessible_way_to_add" msgid="2733588281439571974">"വിജറ്റ് നീക്കാൻ ഡബിൾ ടാപ്പ് ചെയ്യൂ, ഹോൾഡ് ചെയ്യൂ അല്ലെങ്കിൽ ഇഷ്‌ടാനുസൃത പ്രവർത്തനങ്ങൾ ഉപയോഗിക്കൂ."</string>
+ <string name="home_screen" msgid="806512411299847073">"ഹോം സ്‌ക്രീൻ"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"ഇഷ്‌ടാനുസൃത പ്രവർത്തനങ്ങൾ"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"ഒരു വിജറ്റ് ചേർക്കുന്നതിന് അത് സ്‌പർശിച്ച് പിടിക്കുക."</string>
+ <string name="long_accessible_way_to_add" msgid="4289502106628154155">"വിജറ്റ് തിരഞ്ഞെടുക്കാനോ ഇഷ്ടാനുസൃത പ്രവർത്തനങ്ങൾ ഉപയോഗിക്കാനോ രണ്ടുതവണ ടാപ്പുചെയ്ത് പിടിക്കുക."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d വീതിയും %2$d ഉയരവും"</string>
- <string name="widget_preview_context_description" msgid="9045841361655787574">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g> വിജറ്റ്"</string>
- <string name="add_item_request_drag_hint" msgid="5653291305078645405">"ഹോം സ്‌ക്രീനിന് ചുറ്റും വിജറ്റ് നീക്കാൻ അതിൽ സ്‌പർശിച്ച് പിടിക്കുക"</string>
- <string name="add_to_home_screen" msgid="8631549138215492708">"ഹോം സ്‌ക്രീനിലേക്ക് ചേർക്കുക"</string>
- <string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g> വിജറ്റ് ഹോം സ്‌ക്രീനിലേക്ക് ചേർത്തു"</string>
- <string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# വിജറ്റ്}other{# വിജറ്റുകൾ}}"</string>
- <string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{# കുറുക്കുവഴി}other{# കുറുക്കുവഴികൾ}}"</string>
- <string name="widgets_and_shortcuts_count" msgid="7209136747878365116">"<xliff:g id="WIDGETS_COUNT">%1$s</xliff:g>, <xliff:g id="SHORTCUTS_COUNT">%2$s</xliff:g>"</string>
- <string name="widget_button_text" msgid="2880537293434387943">"വിജറ്റുകൾ"</string>
- <string name="widgets_full_sheet_search_bar_hint" msgid="8484659090860596457">"തിരയുക"</string>
- <string name="widgets_full_sheet_cancel_button_description" msgid="5766167035728653605">"സെർച്ച് ബോക്‌സിൽ നിന്ന് ടെക്‌സ്‌റ്റ് മായ്‌ക്കുക"</string>
- <string name="no_widgets_available" msgid="4337693382501046170">"വിജറ്റുകളും കുറുക്കുവഴികളും ലഭ്യമല്ല"</string>
- <string name="no_search_results" msgid="3787956167293097509">"വിജറ്റുകളോ കുറുക്കുവഴികളോ കണ്ടെത്തിയില്ല"</string>
- <string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"വ്യക്തിപരം"</string>
- <string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"ജോലി"</string>
- <string name="widget_category_conversations" msgid="8894438636213590446">"സംഭാഷണങ്ങൾ"</string>
- <string name="widget_education_header" msgid="4874760613775913787">"ഉപകാരപ്രദമായ വിവരങ്ങൾ നിങ്ങളുടെ വിരൽത്തുമ്പിൽ"</string>
- <string name="widget_education_content" msgid="745542879510751525">"ആപ്പുകൾ തുറക്കാതെ വിവരങ്ങൾ ലഭിക്കാൻ, നിങ്ങൾക്ക് ഹോം സ്ക്രീനിലേക്ക് വിജറ്റുകൾ ചേർക്കാം"</string>
- <string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"വിജറ്റ് ക്രമീകരണം മാറ്റാൻ ടാപ്പ് ചെയ്യുക"</string>
- <string name="widget_education_close_button" msgid="8676165703104836580">"മനസ്സിലായി"</string>
- <string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"വിജറ്റ് ക്രമീകരണം മാറ്റുക"</string>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"നേരിട്ട് സ്ഥാപിക്കുന്നതിന് സ്‌പർശിച്ചുപിടിക്കുക"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"സ്വയമേവ ചേർക്കുക"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"ആപ്പുകൾ തിരയുക"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"ആപ്പുകൾ ലോഡുചെയ്യുന്നു..."</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" എന്നതുമായി പൊരുത്തപ്പെടുന്ന ആപ്പുകളൊന്നും കണ്ടെത്തിയില്ല"</string>
<string name="all_apps_search_market_message" msgid="1366263386197059176">"കൂടുതൽ ആപ്പുകൾക്ക് തിരയുക"</string>
<string name="label_application" msgid="8531721983832654978">"ആപ്പ്"</string>
- <string name="all_apps_label" msgid="5015784846527570951">"എല്ലാ ആപ്പുകളും"</string>
<string name="notifications_header" msgid="1404149926117359025">"അറിയിപ്പുകൾ"</string>
- <string name="long_press_shortcut_to_add" msgid="5405328730817637737">"കുറുക്കുവഴി നീക്കാൻ സ്‌പർശിച്ച് പിടിക്കുക."</string>
- <string name="long_accessible_way_to_add_shortcut" msgid="2199537273817090740">"കുറുക്കുവഴി നീക്കാൻ ഡബിൾ ടാപ്പ് ചെയ്യൂ, ഹോൾഡ് ചെയ്യൂ അല്ലെങ്കിൽ ഇഷ്‌ടാനുസൃത പ്രവർത്തനങ്ങൾ ഉപയോഗിക്കൂ."</string>
- <string name="out_of_space" msgid="6692471482459245734">"ഈ ഹോം സ്ക്രീനിലിൽ ഇടമില്ല"</string>
+ <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"തിരഞ്ഞെടുക്കുന്നതിന് കുറുക്കുവഴി സ്‌പർശിച്ച് പിടിക്കുക."</string>
+ <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"കുറുക്കുവഴി തിരഞ്ഞെടുക്കാനോ ഇഷ്‌ടാനുസൃത പ്രവർത്തനങ്ങൾ ഉപയോഗിക്കാനോ 2 തവണ ടാപ്പ് ചെയ്‌ത് പിടിക്കുക."</string>
+ <string name="out_of_space" msgid="4691004494942118364">"ഈ ഹോം സ്‌ക്രീനിൽ ഒഴിവൊന്നുമില്ല."</string>
<string name="hotseat_out_of_space" msgid="7448809638125333693">"പ്രിയപ്പെട്ടവയുടെ ട്രേയിൽ ഒഴിവൊന്നുമില്ല"</string>
<string name="all_apps_button_label" msgid="8130441508702294465">"അപ്ലിക്കേഷനുകളുടെ ലിസ്‌റ്റ്"</string>
- <string name="all_apps_search_results" msgid="5889367432531296759">"തിരയൽ ഫലങ്ങൾ"</string>
<string name="all_apps_button_personal_label" msgid="1315764287305224468">"വ്യക്തിഗത ആപ്പുകളുടെ ലിസ്റ്റ്"</string>
<string name="all_apps_button_work_label" msgid="7270707118948892488">"ഔദ്യോഗിക ആപ്പുകളുടെ ലിസ്റ്റ്"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"ഹോം"</string>
<string name="remove_drop_target_label" msgid="7812859488053230776">"നീക്കംചെയ്യുക"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"അൺഇൻസ്റ്റാളുചെയ്യുക"</string>
- <string name="app_info_drop_target_label" msgid="692894985365717661">"ആപ്പ് വിവരങ്ങൾ"</string>
+ <string name="app_info_drop_target_label" msgid="692894985365717661">"ആപ്പ് വിവരം"</string>
<string name="install_drop_target_label" msgid="2539096853673231757">"ഇൻസ്‌റ്റാൾ ചെയ്യുക"</string>
- <string name="dismiss_prediction_label" msgid="3357562989568808658">"ആപ്പ് നിർദ്ദേശിക്കരുത്"</string>
- <string name="pin_prediction" msgid="4196423321649756498">"പ്രവചനം പിൻ ചെയ്യുക"</string>
<string name="permlab_install_shortcut" msgid="5632423390354674437">"കുറുക്കുവഴികൾ ഇൻസ്റ്റാളുചെയ്യുക"</string>
<string name="permdesc_install_shortcut" msgid="923466509822011139">"ഉപയോക്തൃ ഇടപെടൽ ഇല്ലാതെ കുറുക്കുവഴികൾ ചേർക്കാൻ അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു."</string>
<string name="permlab_read_settings" msgid="1941457408239617576">"ഹോം ക്രമീകരണങ്ങളും കുറുക്കുവഴികളും റീഡുചെയ്യുക"</string>
@@ -84,13 +60,15 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"ഹോം ക്രമീകരണങ്ങളും കുറുക്കുവഴികളും റൈറ്റുചെയ്യുക"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"ഹോമിലെ ക്രമീകരണങ്ങളും കുറുക്കുവഴികളും മാറ്റാൻ അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു."</string>
<string name="msg_no_phone_permission" msgid="9208659281529857371">"ഫോൺ കോൾ ചെയ്യാൻ <xliff:g id="APP_NAME">%1$s</xliff:g> എന്നതിനെ അനുവദിച്ചിട്ടില്ല"</string>
- <string name="gadget_error_text" msgid="740356548025791839">"വിജറ്റ് ലോഡ് ചെയ്യാനാകുന്നില്ല"</string>
- <string name="gadget_setup_text" msgid="8348374825537681407">"വിജറ്റ് ക്രമീകരണം"</string>
- <string name="gadget_complete_setup_text" msgid="309040266978007925">"സജ്ജീകരണം പൂർത്തിയാക്കാൻ ടാപ്പ് ചെയ്യുക"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"വിജറ്റ് ലോഡുചെയ്യുന്നതിൽ പ്രശ്നമുണ്ട്"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"സജ്ജീകരിക്കുക"</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"ഇതൊരു സിസ്‌റ്റം അപ്ലിക്കേഷനായതിനാൽ അൺഇൻസ്‌റ്റാളുചെയ്യാനാവില്ല."</string>
- <string name="folder_hint_text" msgid="5174843001373488816">"പേര് എഡിറ്റ് ചെയ്യുക"</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"പേരുനൽകാത്ത ഫോൾഡർ"</string>
<string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> പ്രവർത്തനരഹിതമാക്കി"</string>
- <string name="dotted_app_label" msgid="1704091277755818896">"{count,plural,offset:1 =1{{app_name} ആപ്പിന് # അറിയിപ്പുണ്ട്}other{{app_name} ആപ്പിന് # അറിയിപ്പുകളുണ്ട്}}"</string>
+ <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+ <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g> എന്ന ആപ്പിന്, <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> അറിയിപ്പുകൾ ഉണ്ട്</item>
+ <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g> എന്ന ആപ്പിന്, <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> അറിയിപ്പുണ്ട്</item>
+ </plurals>
<string name="default_scroll_format" msgid="7475544710230993317">"പേജ് %1$d / %2$d"</string>
<string name="workspace_scroll_format" msgid="8458889198184077399">"ഹോം സ്‌ക്രീൻ %1$d / %2$d"</string>
<string name="workspace_new_page" msgid="257366611030256142">"പുതിയ ഹോം സ്ക്രീൻ പേജ്"</string>
@@ -99,10 +77,10 @@
<string name="folder_tap_to_rename" msgid="4017685068016979677">"പേരുമാറ്റം സംരക്ഷിക്കുന്നതിന് ടാപ്പുചെയ്യുക"</string>
<string name="folder_closed" msgid="4100806530910930934">"ഫോൾഡർ അടച്ചു"</string>
<string name="folder_renamed" msgid="1794088362165669656">"ഫോൾഡറിന്റെ പേര് <xliff:g id="NAME">%1$s</xliff:g> എന്നായി മാറ്റി"</string>
- <string name="folder_name_format_exact" msgid="8626242716117004803">"ഫോൾഡർ: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> ഇനങ്ങൾ"</string>
- <string name="folder_name_format_overflow" msgid="4270108890534995199">"ഫോൾഡർ: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> അല്ലെങ്കിൽ അതിലധികം ഇനങ്ങൾ"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"ഫോൾഡർ: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"വിഡ്ജെറ്റുകൾ"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"വാൾപേപ്പർ"</string>
- <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"വാൾപേപ്പറും സ്‌റ്റൈലും"</string>
+ <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"സ്‌റ്റൈലുകളും വാൾപേപ്പറുകളും"</string>
<string name="settings_button_text" msgid="8873672322605444408">"ഹോം ക്രമീകരണം"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"അഡ്മിൻ പ്രവർത്തനരഹിതമാക്കിയിരിക്കുന്നു"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"ഹോം സ്ക്രീൻ തിരിക്കൽ അനുവദിക്കുക"</string>
@@ -114,16 +92,16 @@
<string name="msg_missing_notification_access" msgid="281113995110910548">"അറിയിപ്പ് ഡോട്ടുകൾ കാണിക്കുന്നതിന്, <xliff:g id="NAME">%1$s</xliff:g> എന്നയാളിനായുള്ള ആപ്പ് അറിയിപ്പുകൾ ഓണാക്കുക"</string>
<string name="title_change_settings" msgid="1376365968844349552">"ക്രമീകരണം മാറ്റുക"</string>
<string name="notification_dots_service_title" msgid="4284221181793592871">"അറിയിപ്പ് ഡോട്ടുകൾ കാണിക്കുക"</string>
- <string name="auto_add_shortcuts_label" msgid="3698776050751790653">"ഹോം സ്‌ക്രീനിൽ ആപ്പ് ഐക്കണുകൾ ചേർക്കുക"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"ഹോം സ്ക്രീനിലേക്ക് ഐക്കൺ ചേർക്കുക"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"പുതിയ ആപ്പുകൾക്ക്"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"അജ്ഞാതം"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"നീക്കംചെയ്യുക"</string>
<string name="abandoned_search" msgid="891119232568284442">"തിരയുക"</string>
<string name="abandoned_promises_title" msgid="7096178467971716750">"ഈ അപ്ലിക്കേഷൻ ഇൻസ്റ്റാളുചെയ്‌തിട്ടില്ല"</string>
<string name="abandoned_promise_explanation" msgid="3990027586878167529">"ഈ ഐക്കണുവേണ്ടി അപ്ലിക്കേഷൻ ഇൻസ്റ്റാളുചെയ്‌തിട്ടില്ല. നിങ്ങൾക്കത് നീക്കംചെയ്യാനാകും അല്ലെങ്കിൽ അപ്ലിക്കേഷനുവേണ്ടി തിരഞ്ഞുകൊണ്ട് അത് സ്വമേധയാ ഇൻസ്റ്റാളുചെയ്യുക."</string>
- <string name="app_installing_title" msgid="5864044122733792085">"<xliff:g id="NAME">%1$s</xliff:g> ഇൻസ്‌റ്റാൾ ചെയ്യുന്നു, <xliff:g id="PROGRESS">%2$s</xliff:g> പൂർത്തിയായി"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> ഡൗൺലോഡ് ചെയ്യുന്നു, <xliff:g id="PROGRESS">%2$s</xliff:g> പൂർത്തിയായി"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"ഇൻസ്റ്റാൾ ചെയ്യാൻ <xliff:g id="NAME">%1$s</xliff:g> കാക്കുന്നു"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"<xliff:g id="NAME">%1$s</xliff:g> വിജറ്റുകൾ"</string>
<string name="widgets_list" msgid="796804551140113767">"വിജറ്റുകളുടെ ലിസ്‌റ്റ്"</string>
<string name="widgets_list_closed" msgid="6141506579418771922">"വിജറ്റുകളുടെ ലിസ്‌റ്റ് അവസാനിപ്പിച്ചു"</string>
<string name="action_add_to_workspace" msgid="8902165848117513641">"ഹോം സ്ക്രീനിൽ ചേർക്കുക"</string>
@@ -151,20 +129,15 @@
<string name="action_deep_shortcut" msgid="2864038805849372848">"കുറുക്കുവഴികൾ"</string>
<string name="shortcuts_menu_with_notifications_description" msgid="2676582286544232849">"കുറുക്കുവഴികളും അറിയിപ്പുകളും"</string>
<string name="action_dismiss_notification" msgid="5909461085055959187">"നിരസിക്കുക"</string>
- <string name="accessibility_close" msgid="2277148124685870734">"അടയ്ക്കൂ"</string>
<string name="notification_dismissed" msgid="6002233469409822874">"അറിയിപ്പ് നിരസിച്ചു"</string>
<string name="all_apps_personal_tab" msgid="4190252696685155002">"വ്യക്തിപരം"</string>
- <string name="all_apps_work_tab" msgid="4884822796154055118">"ഔദ്യോഗികം"</string>
+ <string name="all_apps_work_tab" msgid="4884822796154055118">"ജോലി"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"ഔദ്യോഗിക പ്രൊഫൈൽ"</string>
- <string name="work_profile_edu_work_apps" msgid="7895468576497746520">"ഔദ്യോഗിക ആപ്പുകൾക്ക് ബാഡ്‌ജ് നൽകിയിരിക്കുന്നു, അവ നിങ്ങളുടെ ഐടി അഡ്‌മിന് കാണാനുമാകും"</string>
- <string name="work_profile_edu_accept" msgid="6069788082535149071">"മനസ്സിലായി"</string>
- <string name="work_apps_paused_title" msgid="3040901117349444598">"ഔദ്യോഗിക ആപ്പുകൾ തൽക്കാലം നിർത്തിയിരിക്കുന്നു"</string>
- <string name="work_apps_paused_body" msgid="261634750995824906">"നിങ്ങൾക്ക് അറിയിപ്പുകൾ അയയ്ക്കാനോ ബാറ്ററി ഉപയോഗിക്കാനോ ലൊക്കേഷൻ ആക്‌സസ് ചെയ്യാനോ നിങ്ങളുടെ ഔദ്യോഗിക ആപ്പുകൾക്ക് കഴിയില്ല"</string>
- <string name="work_apps_paused_content_description" msgid="5149623040804051095">"ഔദ്യോഗിക ആപ്പുകൾ ഓഫാണ്. നിങ്ങൾക്ക് അറിയിപ്പുകൾ അയയ്ക്കാനോ ബാറ്ററി ഉപയോഗിക്കാനോ ലൊക്കേഷൻ ആക്‌സസ് ചെയ്യാനോ നിങ്ങളുടെ ഔദ്യോഗിക ആപ്പുകൾക്ക് കഴിയില്ല"</string>
- <string name="work_apps_paused_edu_banner" msgid="8872412121608402058">"ഔദ്യോഗിക ആപ്പുകൾക്ക് ബാഡ്‌ജ് നൽകിയിരിക്കുന്നു, അവ നിങ്ങളുടെ ഐടി അഡ്‌മിന് കാണാനും കഴിയും"</string>
- <string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"മനസ്സിലായി"</string>
- <string name="work_apps_pause_btn_text" msgid="1921059713673767460">"ഔദ്യോഗിക ആപ്പുകൾ ഓഫാക്കുക"</string>
- <string name="work_apps_enable_btn_text" msgid="1156432622148413741">"ഔദ്യോഗിക ആപ്പുകൾ ഓണാക്കുക"</string>
- <string name="developer_options_filter_hint" msgid="5896817443635989056">"ഫിൽട്ടർ ചെയ്യുക"</string>
+ <string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"ഔദ്യോഗിക ആപ്പുകൾ ഇവിടെ കണ്ടെത്തുക"</string>
+ <string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"എല്ലാ ഔദ്യോഗിക ആപ്പിനും ഒരു ബാഡ്‌ജ് ഉണ്ട്, നിങ്ങളുടെ സ്ഥാപനം അത് സുരക്ഷിതമായി സൂക്ഷിക്കുന്നു. എളുപ്പത്തിൽ ആക്സസ് ചെയ്യാൻ ആപ്പുകളെ ഹോം സ്‌ക്രീനിലേക്ക് നീക്കുക."</string>
+ <string name="work_mode_on_label" msgid="4781128097185272916">"നിങ്ങളുടെ സ്ഥാപനം നിയന്ത്രിക്കുന്നത്"</string>
+ <string name="work_mode_off_label" msgid="3194894777601421047">"അറിയിപ്പുകളും ആപ്പുകളും ഓഫാണ്"</string>
+ <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"അടയ്ക്കുക"</string>
+ <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"അടച്ചു"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"പരാജയപ്പെട്ടു: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
</resources>
diff --git a/res/values-mn/strings.xml b/res/values-mn/strings.xml
index e6fcefaedb..ab02ac655c 100644
--- a/res/values-mn/strings.xml
+++ b/res/values-mn/strings.xml
@@ -20,63 +20,39 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="649227358658669779">"Launcher3"</string>
+ <string name="folder_name" msgid="7371454440695724752"></string>
<string name="work_folder_name" msgid="3753320833950115786">"Ажил"</string>
<string name="activity_not_found" msgid="8071924732094499514">"Апп суугаагүй байна."</string>
<string name="activity_not_available" msgid="7456344436509528827">"Апп-г ашиглах боломжгүй"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"Татаж авсан апп-г Аюулгүй горим дотроос идэвхгүйжүүлсэн"</string>
<string name="safemode_widget_error" msgid="4863470563535682004">"Safe горимд виджетүүдийг идэвхгүйжүүлсэн"</string>
<string name="shortcut_not_available" msgid="2536503539825726397">"Товчлол алга"</string>
- <string name="home_screen" msgid="5629429142036709174">"Нүүр"</string>
- <string name="recent_task_option_split_screen" msgid="6690461455618725183">"Дэлгэцийг хуваах"</string>
- <string name="split_screen_position_top" msgid="1504965011158689649">"Дээш хуваах"</string>
- <string name="split_screen_position_left" msgid="7537793098851830883">"Зүүн тийш хуваах"</string>
- <string name="split_screen_position_right" msgid="1569377524925193369">"Баруун тийш хуваах"</string>
- <string name="split_app_info_accessibility" msgid="5475288491241414932">"%1$s-н аппын мэдээлэл"</string>
- <string name="long_press_widget_to_add" msgid="3587712543577675817">"Виджетийг зөөх бол хүрээд, удаан дарна уу."</string>
- <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Виджетийг зөөх эсвэл захиалгат үйлдлийг ашиглахын тулд хоёр товшоод, удаан дарна уу."</string>
+ <string name="home_screen" msgid="806512411299847073">"Үндсэн нүүр"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"Захиалгат үйлдэл"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"Виджетийг авах бол хүрээд барина уу."</string>
+ <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Жижиг хэрэгсэл авах болон тохируулсан үйлдлийг ашиглахын тулд 2 удаа товшоод барина уу."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d өргөн %2$d өндөр"</string>
- <string name="widget_preview_context_description" msgid="9045841361655787574">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g> жижиг хэрэгсэл"</string>
- <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Жижиг хэрэгслийг Үндсэн нүүрний эргэн тойронд зөөхийн тулд түүнд хүрээд, удаан дарна уу"</string>
- <string name="add_to_home_screen" msgid="8631549138215492708">"Үндсэн нүүрэнд нэмэх"</string>
- <string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g> виджетийг үндсэн нүүрэнд нэмсэн"</string>
- <string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# виджет}other{# виджет}}"</string>
- <string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{# товчлол}other{# товчлол}}"</string>
- <string name="widgets_and_shortcuts_count" msgid="7209136747878365116">"<xliff:g id="WIDGETS_COUNT">%1$s</xliff:g>, <xliff:g id="SHORTCUTS_COUNT">%2$s</xliff:g>"</string>
- <string name="widget_button_text" msgid="2880537293434387943">"Виджет"</string>
- <string name="widgets_full_sheet_search_bar_hint" msgid="8484659090860596457">"Хайх"</string>
- <string name="widgets_full_sheet_cancel_button_description" msgid="5766167035728653605">"Хайх хэсгээс текстийг арилгах"</string>
- <string name="no_widgets_available" msgid="4337693382501046170">"Жижиг хэрэгсэл болон товчлол боломжгүй байна"</string>
- <string name="no_search_results" msgid="3787956167293097509">"Виджет эсвэл товчлол олдсонгүй"</string>
- <string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Хувийн виджетүүд"</string>
- <string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Ажил"</string>
- <string name="widget_category_conversations" msgid="8894438636213590446">"Харилцан яриа"</string>
- <string name="widget_education_header" msgid="4874760613775913787">"Хэрэгтэй мэдээллээ хурууныхаа үзүүрээр аваарай"</string>
- <string name="widget_education_content" msgid="745542879510751525">"Аппуудыг нээлгүйгээр мэдээлэл авахын тулд та Үндсэн нүүрэндээ виджет нэмэх боломжтой"</string>
- <string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Жижиг хэрэгслийн тохиргоог өөрчлөхийн тулд товшино уу"</string>
- <string name="widget_education_close_button" msgid="8676165703104836580">"Ойлголоо"</string>
- <string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Жижиг хэрэгслийн тохиргоог өөрчлөх"</string>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Гараар байршуулахын тулд дараад хүлээнэ үү"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"Автоматаар нэмэх"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Апп хайх"</string>
- <string name="all_apps_loading_message" msgid="5813968043155271636">"Аппыг ачаалж байна..."</string>
+ <string name="all_apps_loading_message" msgid="5813968043155271636">"Аппыг ачааллаж байна..."</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\"-д тохирох апп олдсонгүй"</string>
<string name="all_apps_search_market_message" msgid="1366263386197059176">"Бусад апп-г хайх"</string>
<string name="label_application" msgid="8531721983832654978">"Апп"</string>
- <string name="all_apps_label" msgid="5015784846527570951">"Бүх апп"</string>
<string name="notifications_header" msgid="1404149926117359025">"Мэдэгдэл"</string>
- <string name="long_press_shortcut_to_add" msgid="5405328730817637737">"Товчлолыг зөөхийн тулд хүрээд, удаан дарна уу."</string>
- <string name="long_accessible_way_to_add_shortcut" msgid="2199537273817090740">"Товчлолыг зөөх эсвэл захиалгат үйлдлийг ашиглахын тулд хоёр товшоод, удаан дарна уу."</string>
- <string name="out_of_space" msgid="6692471482459245734">"Энэ үндсэн нүүрэнд зай байхгүй байна"</string>
+ <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"Товчлол авах бол удаан дарна уу."</string>
+ <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"Товчлол авах эсвэл тохируулсан үйлдлийг ашиглахын тулд давхар товшоод хүлээнэ үү."</string>
+ <string name="out_of_space" msgid="4691004494942118364">"Энэ Нүүр дэлгэц зайгүй."</string>
<string name="hotseat_out_of_space" msgid="7448809638125333693">"\"Дуртай\" трей дээр өөр зай байхгүй байна"</string>
<string name="all_apps_button_label" msgid="8130441508702294465">"Апп-н жагсаалт"</string>
- <string name="all_apps_search_results" msgid="5889367432531296759">"Хайлтын илэрц"</string>
<string name="all_apps_button_personal_label" msgid="1315764287305224468">"Хувийн аппын жагсаалт"</string>
<string name="all_apps_button_work_label" msgid="7270707118948892488">"Ажлын аппын жагсаалт"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"Нүүр"</string>
<string name="remove_drop_target_label" msgid="7812859488053230776">"Арилгах"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"Устгах"</string>
- <string name="app_info_drop_target_label" msgid="692894985365717661">"Аппын мэдээлэл"</string>
+ <string name="app_info_drop_target_label" msgid="692894985365717661">"Апп-н мэдээлэл"</string>
<string name="install_drop_target_label" msgid="2539096853673231757">"Суулгах"</string>
- <string name="dismiss_prediction_label" msgid="3357562989568808658">"Апп бүү санал болго"</string>
- <string name="pin_prediction" msgid="4196423321649756498">"Таамаглалыг бэхлэх"</string>
<string name="permlab_install_shortcut" msgid="5632423390354674437">"товчлол суулгах"</string>
<string name="permdesc_install_shortcut" msgid="923466509822011139">"Апп нь хэрэглэгчийн оролцоогүйгээр товчлолыг нэмэж чадна"</string>
<string name="permlab_read_settings" msgid="1941457408239617576">"Нүүрний тохиргоо болон товчлолыг унших"</string>
@@ -84,13 +60,15 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"Нүүрний тохиргоо болон товчлолыг бичих"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"Апп нь Нүүрэндэх товчлол болон тохиргоог өөрчилж чадна."</string>
<string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> утасны дуудлага хийх боломжгүй"</string>
- <string name="gadget_error_text" msgid="740356548025791839">"Жижиг хэрэгслийг ачаалах боломжгүй"</string>
- <string name="gadget_setup_text" msgid="8348374825537681407">"Виджетийн тохиргоо"</string>
- <string name="gadget_complete_setup_text" msgid="309040266978007925">"Тохируулгыг дуусгахын тулд товшино уу"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"Виджет ачаалахад асуудал гарав"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"Тохируулга"</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"Энэ апп нь системийн апп ба устгах боломжгүй."</string>
- <string name="folder_hint_text" msgid="5174843001373488816">"Нэр засах"</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"Нэргүй фолдер"</string>
<string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g>-г идэвхгүй болгосон"</string>
- <string name="dotted_app_label" msgid="1704091277755818896">"{count,plural,offset:1 =1{{app_name} дээр # мэдэгдэл байна}other{{app_name} дээр # мэдэгдэл байна}}"</string>
+ <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+ <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> мэдэгдэлтэй байна</item>
+ <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g>, <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> мэдэгдэлтэй байна</item>
+ </plurals>
<string name="default_scroll_format" msgid="7475544710230993317">"%2$d-н %1$d хуудас"</string>
<string name="workspace_scroll_format" msgid="8458889198184077399">"%2$d-н Нүүр дэлгэц %1$d"</string>
<string name="workspace_new_page" msgid="257366611030256142">"Шинэ үндсэн нүүр хуудас"</string>
@@ -99,10 +77,10 @@
<string name="folder_tap_to_rename" msgid="4017685068016979677">"Шинэ нэрийг хадгалахын тулд дарна уу."</string>
<string name="folder_closed" msgid="4100806530910930934">"Фолдер хаагдав"</string>
<string name="folder_renamed" msgid="1794088362165669656">"Фолдерын нэр <xliff:g id="NAME">%1$s</xliff:g> болов"</string>
- <string name="folder_name_format_exact" msgid="8626242716117004803">"Фолдер: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> зүйл"</string>
- <string name="folder_name_format_overflow" msgid="4270108890534995199">"Фолдер: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> эсвэл үүнээс олон зүйл"</string>
- <string name="wallpaper_button_text" msgid="8404103075899945851">"Дэлгэцийн зураг"</string>
- <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Дэлгэцийн зураг, загвар"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"Фолдер: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"Виджет"</string>
+ <string name="wallpaper_button_text" msgid="8404103075899945851">"Ханын зураг"</string>
+ <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Загвар ба ханын зураг"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Нүүр хуудасны тохиргоо"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Таны админ идэвхгүй болгосон"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Нүүр дэлгэцийг эргүүлэхийг зөвшөөрөх"</string>
@@ -114,22 +92,22 @@
<string name="msg_missing_notification_access" msgid="281113995110910548">"Мэдэгдлийн цэгийг харуулахын тулд <xliff:g id="NAME">%1$s</xliff:g>-д аппын мэдэгдлийг асаана уу"</string>
<string name="title_change_settings" msgid="1376365968844349552">"Тохиргоог өөрчлөх"</string>
<string name="notification_dots_service_title" msgid="4284221181793592871">"Мэдэгдлийн цэгийг харуулах"</string>
- <string name="auto_add_shortcuts_label" msgid="3698776050751790653">"Аппын дүрс тэмдгийг Үндсэн нүүрэнд нэмэх"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Нүүр хуудаст дүрс тэмдэг нэмэх"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Шинэ аппад зориулсан"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"Тодорхойгүй"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"Хасах"</string>
<string name="abandoned_search" msgid="891119232568284442">"Хайх"</string>
<string name="abandoned_promises_title" msgid="7096178467971716750">"Энэ апп-г суулгаагүй байна"</string>
<string name="abandoned_promise_explanation" msgid="3990027586878167529">"Энэ дүрсний апп-г суулгаагүй байна. Та үүнийг устгах буюу апп-г хайж суулгах боломжтой."</string>
- <string name="app_installing_title" msgid="5864044122733792085">"<xliff:g id="NAME">%1$s</xliff:g>-г суулгаж байна. <xliff:g id="PROGRESS">%2$s</xliff:g> дууссан"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g>-г татаж байна, <xliff:g id="PROGRESS">%2$s</xliff:g> татсан"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> нь суулгахыг хүлээж байна"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"<xliff:g id="NAME">%1$s</xliff:g> жижиг хэрэгсэл"</string>
<string name="widgets_list" msgid="796804551140113767">"Жижиг хэрэгслийн жагсаалт"</string>
<string name="widgets_list_closed" msgid="6141506579418771922">"Жижиг хэрэгслийн жагсаалтыг хаасан"</string>
<string name="action_add_to_workspace" msgid="8902165848117513641">"Нүүр дэлгэцэд нэмэх"</string>
<string name="action_move_here" msgid="2170188780612570250">"Энд байршуулах"</string>
<string name="item_added_to_workspace" msgid="4211073925752213539">"Нүүр дэлгэцэнд нэмсэн зүйл"</string>
- <string name="item_removed" msgid="851119963877842327">"Зүйлийг устгалаа"</string>
+ <string name="item_removed" msgid="851119963877842327">"Арилгасан зүйл"</string>
<string name="undo" msgid="4151576204245173321">"Болих"</string>
<string name="action_move" msgid="4339390619886385032">"Зөөх"</string>
<string name="move_to_empty_cell" msgid="2833711483015685619">"<xliff:g id="NUMBER_0">%1$s</xliff:g> мөр <xliff:g id="NUMBER_1">%2$s</xliff:g> баганад зөөх"</string>
@@ -151,20 +129,15 @@
<string name="action_deep_shortcut" msgid="2864038805849372848">"Товчлол"</string>
<string name="shortcuts_menu_with_notifications_description" msgid="2676582286544232849">"Товчлол болон мэдэгдэл"</string>
<string name="action_dismiss_notification" msgid="5909461085055959187">"Хаах"</string>
- <string name="accessibility_close" msgid="2277148124685870734">"Хаах"</string>
<string name="notification_dismissed" msgid="6002233469409822874">"Мэдэгдлийг хаасан"</string>
<string name="all_apps_personal_tab" msgid="4190252696685155002">"Хувийн"</string>
<string name="all_apps_work_tab" msgid="4884822796154055118">"Ажил"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"Ажлын профайл"</string>
- <string name="work_profile_edu_work_apps" msgid="7895468576497746520">"Ажлын аппуудыг тэмдэглэсэн бөгөөд танай IT админд харагдана"</string>
- <string name="work_profile_edu_accept" msgid="6069788082535149071">"Ойлголоо"</string>
- <string name="work_apps_paused_title" msgid="3040901117349444598">"Ажлын аппуудыг түр зогсоосон"</string>
- <string name="work_apps_paused_body" msgid="261634750995824906">"Таны ажлын аппууд танд мэдэгдэл илгээх, таны батарейг ашиглах эсвэл байршилд тань хандах боломжгүй"</string>
- <string name="work_apps_paused_content_description" msgid="5149623040804051095">"Ажлын аппууд унтраалттай байна. Таны ажлын аппууд танд мэдэгдэл илгээх, таны батарейг ашиглах эсвэл байршилд тань хандах боломжгүй"</string>
- <string name="work_apps_paused_edu_banner" msgid="8872412121608402058">"Ажлын аппуудыг тэмдэглэсэн бөгөөд танай IT админд харагдана"</string>
- <string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"Ойлголоо"</string>
- <string name="work_apps_pause_btn_text" msgid="1921059713673767460">"Ажлын аппуудыг унтраах"</string>
- <string name="work_apps_enable_btn_text" msgid="1156432622148413741">"Ажлын аппуудыг асаах"</string>
- <string name="developer_options_filter_hint" msgid="5896817443635989056">"Шүүлтүүр"</string>
+ <string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"Ажлын аппыг эндээс олно уу"</string>
+ <string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"Ажлын апп тус бүр тэмдэгтэй ба эдгээрийг танай байгууллагаас аюулгүй байлгадаг. Аппуудад хялбар хандахын тулд тэдгээрийг Үндсэн нүүр хэсэгт зөөнө үү."</string>
+ <string name="work_mode_on_label" msgid="4781128097185272916">"Танай байгууллагаас удирддаг"</string>
+ <string name="work_mode_off_label" msgid="3194894777601421047">"Мэдэгдэл, апп унтраалттай байна"</string>
+ <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Хаах"</string>
+ <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Хаасан"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Амжилтгүй болсон: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
</resources>
diff --git a/res/values-mr/strings.xml b/res/values-mr/strings.xml
index 34bdcd2ba8..49e38982cd 100644
--- a/res/values-mr/strings.xml
+++ b/res/values-mr/strings.xml
@@ -20,77 +20,55 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="649227358658669779">"Launcher3"</string>
+ <string name="folder_name" msgid="7371454440695724752"></string>
<string name="work_folder_name" msgid="3753320833950115786">"कार्य"</string>
<string name="activity_not_found" msgid="8071924732094499514">"अ‍ॅप इंस्टॉल केलेला नाही."</string>
<string name="activity_not_available" msgid="7456344436509528827">"अ‍ॅप उपलब्ध नाही"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"डाउनलोड केलेला अ‍ॅप सुरक्षित मोड मध्‍ये अक्षम केला"</string>
<string name="safemode_widget_error" msgid="4863470563535682004">"विजेट सुरक्षित मोडमध्ये अक्षम झाले"</string>
<string name="shortcut_not_available" msgid="2536503539825726397">"शॉर्टकट उपलब्ध नाही"</string>
- <string name="home_screen" msgid="5629429142036709174">"होम"</string>
- <string name="recent_task_option_split_screen" msgid="6690461455618725183">"स्प्लिट स्क्रीन"</string>
- <string name="split_screen_position_top" msgid="1504965011158689649">"सर्वात वरती स्प्लिट करा"</string>
- <string name="split_screen_position_left" msgid="7537793098851830883">"डावीकडे स्प्लिट करा"</string>
- <string name="split_screen_position_right" msgid="1569377524925193369">"उजवीकडे स्प्लिट करा"</string>
- <string name="split_app_info_accessibility" msgid="5475288491241414932">"%1$s साठी ॲपशी संबंधित माहिती"</string>
- <string name="long_press_widget_to_add" msgid="3587712543577675817">"विजेट हलवण्यासाठी स्पर्श करा आणि धरून ठेवा."</string>
- <string name="long_accessible_way_to_add" msgid="2733588281439571974">"विजेट हलवण्यासाठी किंवा कस्टम कृती वापरण्यासाठी दोनदा टॅप करा आणि धरून ठेवा."</string>
+ <string name="home_screen" msgid="806512411299847073">"होम स्क्रीन"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"कस्टम क्रिया"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"विजेट निवडण्यासाठी स्पर्श करा आणि धरून ठेवा."</string>
+ <string name="long_accessible_way_to_add" msgid="4289502106628154155">"एक विजेट निवडण्यासाठी दोनदा टॅप करा आणि धरून ठेवा किंवा कस्टम क्रिया वापरा."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d रूंद बाय %2$d उंच"</string>
- <string name="widget_preview_context_description" msgid="9045841361655787574">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g> विजेट"</string>
- <string name="add_item_request_drag_hint" msgid="5653291305078645405">"होम स्क्रीनवर ते हलवण्यासाठी विजेटला स्पर्श करा आणि धरून ठेवा"</string>
- <string name="add_to_home_screen" msgid="8631549138215492708">"होम स्‍क्रीनवर जोडा"</string>
- <string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g> हे विजेट तुमच्या होम स्क्रीनवर जोडले आहे"</string>
- <string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# विजेट}other{# विजेट}}"</string>
- <string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{# शॉर्टकट}other{# शॉर्टकट}}"</string>
- <string name="widgets_and_shortcuts_count" msgid="7209136747878365116">"<xliff:g id="WIDGETS_COUNT">%1$s</xliff:g>, <xliff:g id="SHORTCUTS_COUNT">%2$s</xliff:g>"</string>
- <string name="widget_button_text" msgid="2880537293434387943">"विजेट"</string>
- <string name="widgets_full_sheet_search_bar_hint" msgid="8484659090860596457">"शोधा"</string>
- <string name="widgets_full_sheet_cancel_button_description" msgid="5766167035728653605">"सर्च बॉक्समधून मजकूर साफ करा"</string>
- <string name="no_widgets_available" msgid="4337693382501046170">"विजेट आणि शॉर्टकट उपलब्ध नाहीत"</string>
- <string name="no_search_results" msgid="3787956167293097509">"कोणतीही विजेट किंवा शॉर्टकट आढळले नाहीत"</string>
- <string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"वैयक्तिक"</string>
- <string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"ऑफिस"</string>
- <string name="widget_category_conversations" msgid="8894438636213590446">"संभाषणे"</string>
- <string name="widget_education_header" msgid="4874760613775913787">"तुमच्यासाठी सहज उपलब्ध असलेली माहिती"</string>
- <string name="widget_education_content" msgid="745542879510751525">"ॲप्स न उघडता माहिती मिळवण्यासाठी, तुम्ही तुमच्या होम स्क्रीनवर विजेट जोडू शकता"</string>
- <string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"विजेट सेटिंग्ज बदलण्यासाठी टॅप करा"</string>
- <string name="widget_education_close_button" msgid="8676165703104836580">"समजले"</string>
- <string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"विजेट सेटिंग्ज बदला"</string>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"स्वतः ठेवण्यासाठी स्पर्श करा आणि धरून ठेवा"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"आपोआप जोडा"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"अ‍ॅप्स शोधा"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"अ‍ॅप्स लोड करत आहे…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" शी जुळणारे कोणतेही अ‍ॅप्स आढळले नाहीत"</string>
<string name="all_apps_search_market_message" msgid="1366263386197059176">"अधिक अ‍ॅप्स शोधा"</string>
<string name="label_application" msgid="8531721983832654978">"ॲप"</string>
- <string name="all_apps_label" msgid="5015784846527570951">"सर्व अ‍ॅप्स"</string>
<string name="notifications_header" msgid="1404149926117359025">"सूचना"</string>
- <string name="long_press_shortcut_to_add" msgid="5405328730817637737">"शॉर्टकट हलवण्यासाठी स्पर्श करा आणि धरून ठेवा."</string>
- <string name="long_accessible_way_to_add_shortcut" msgid="2199537273817090740">"शॉर्टकट हलवण्यासाठी किंवा कस्टम कृती वापरण्यासाठी दोनदा टॅप करा आणि धरून ठेवा."</string>
- <string name="out_of_space" msgid="6692471482459245734">"या होम स्क्रीनवर कोणतीही रूम नाही"</string>
+ <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"शॉर्टकट निवडण्यासाठी स्पर्श करा आणि धरून ठेवा."</string>
+ <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"शॉर्टकट निवडण्यासाठी किंवा कस्टम क्रिया वापरण्यासाठी दोनदा टॅप करा आणि धरून ठेवा."</string>
+ <string name="out_of_space" msgid="4691004494942118364">"या मुख्य स्क्रीनवर आणखी जागा नाही."</string>
<string name="hotseat_out_of_space" msgid="7448809638125333693">"आवडीच्या ट्रे मध्ये आणखी जागा नाही"</string>
<string name="all_apps_button_label" msgid="8130441508702294465">"अ‍ॅप्स सूची"</string>
- <string name="all_apps_search_results" msgid="5889367432531296759">"शोध परिणाम"</string>
<string name="all_apps_button_personal_label" msgid="1315764287305224468">"वैयक्तिक अ‍ॅप्स सूची"</string>
- <string name="all_apps_button_work_label" msgid="7270707118948892488">"कामाच्या ठिकाणी वापरली जाणाऱ्या ॲप्सची सूची"</string>
+ <string name="all_apps_button_work_label" msgid="7270707118948892488">"कामाच्या ठिकाणी वापरली जाणाऱ्या अॅप्सची सूची"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"होम"</string>
<string name="remove_drop_target_label" msgid="7812859488053230776">"काढा"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"अनइंस्टॉल करा"</string>
<string name="app_info_drop_target_label" msgid="692894985365717661">"अ‍ॅप माहिती"</string>
<string name="install_drop_target_label" msgid="2539096853673231757">"इंस्टॉल करा"</string>
- <string name="dismiss_prediction_label" msgid="3357562989568808658">"ॲप सुचवू नका"</string>
- <string name="pin_prediction" msgid="4196423321649756498">"पूर्वानुमान पिन करा"</string>
- <string name="permlab_install_shortcut" msgid="5632423390354674437">"शॉर्टकट इंस्टॉल करा"</string>
+ <string name="permlab_install_shortcut" msgid="5632423390354674437">"शॉर्टकट स्‍थापित करा"</string>
<string name="permdesc_install_shortcut" msgid="923466509822011139">"वापरकर्ता हस्तक्षेपाशिवाय शॉर्टकट जोडण्यास अ‍ॅप ला अनुमती देते."</string>
<string name="permlab_read_settings" msgid="1941457408239617576">"होम सेटिंग्ज आणि शॉर्टकट वाचा"</string>
<string name="permdesc_read_settings" msgid="5833423719057558387">"मुख्यपृष्ठातील सेटिंग्ज आणि शॉर्टकट वाचण्यास अ‍ॅप ला अनुमती देते."</string>
<string name="permlab_write_settings" msgid="3574213698004620587">"होम सेटिंग्ज आणि शॉर्टकट लिहा"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"मुख्यपृष्ठातील सेटिंग्ज आणि शॉर्टकट बदलण्यास अ‍ॅप ला अनुमती देते."</string>
<string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> ला फोन कॉल करण्याची अनुमती नाही"</string>
- <string name="gadget_error_text" msgid="740356548025791839">"विजेट लोड करू शकत नाही"</string>
- <string name="gadget_setup_text" msgid="8348374825537681407">"विजेटची सेटिंग्ज"</string>
- <string name="gadget_complete_setup_text" msgid="309040266978007925">"सेटअप पूर्ण करण्‍यासाठी टॅप करा"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"विजेट लोड करण्यात समस्या"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"सेटअप"</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"हा सिस्टम अ‍ॅप आहे आणि अनइंस्टॉल केला जाऊ शकत नाही."</string>
- <string name="folder_hint_text" msgid="5174843001373488816">"नाव संपादित करा"</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"अनामित फोल्डर"</string>
<string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> अक्षम केला आहे"</string>
- <string name="dotted_app_label" msgid="1704091277755818896">"{count,plural,offset:1 =1{{app_name} साठी # सूचना आहे}other{{app_name} साठी # सूचना आहेत}}"</string>
+ <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+ <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>साठी <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> सूचना आहेत</item>
+ <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g>साठी<xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g>सूचना आहे</item>
+ </plurals>
<string name="default_scroll_format" msgid="7475544710230993317">"%2$d पैकी %1$d पृष्ठ"</string>
<string name="workspace_scroll_format" msgid="8458889198184077399">"%2$d पैकी %1$d मुख्य स्क्रीन"</string>
<string name="workspace_new_page" msgid="257366611030256142">"नवीन मुख्य स्क्रीन पृष्ठ"</string>
@@ -99,31 +77,31 @@
<string name="folder_tap_to_rename" msgid="4017685068016979677">"पुनर्नामित करणे सेव्ह करण्यासाठी टॅप करा"</string>
<string name="folder_closed" msgid="4100806530910930934">"फोल्डर बंद"</string>
<string name="folder_renamed" msgid="1794088362165669656">"फोल्डरचे नाव बदलून <xliff:g id="NAME">%1$s</xliff:g> असे ठेवले"</string>
- <string name="folder_name_format_exact" msgid="8626242716117004803">"फोल्डर: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> आयटम"</string>
- <string name="folder_name_format_overflow" msgid="4270108890534995199">"फोल्डर: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> किंवा त्याहून अधिक आयटम"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"फोल्डर: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"विजेट"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"वॉलपेपर"</string>
- <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"वॉलपेपर आणि शैली"</string>
+ <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"शैली आणि वॉलपेपर"</string>
<string name="settings_button_text" msgid="8873672322605444408">"होम सेटिंग्‍ज"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"आपल्या प्रशासकाने अक्षम केले"</string>
- <string name="allow_rotation_title" msgid="7728578836261442095">"मुख्य स्क्रीन फिरविण्‍यास अनुमती द्या"</string>
+ <string name="allow_rotation_title" msgid="7728578836261442095">"मुख्यस्क्रीन फिरविण्‍यास अनुमती द्या"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"फोन फिरविला जातो तेव्हा"</string>
<string name="notification_dots_title" msgid="9062440428204120317">"सूचना बिंदू"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"सुरू"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"बंद"</string>
<string name="title_missing_notification_access" msgid="7503287056163941064">"सूचनांच्या अ‍ॅक्सेसची आवश्यकता आहे"</string>
- <string name="msg_missing_notification_access" msgid="281113995110910548">"सूचना बिंदू दाखवण्यासाठी, <xliff:g id="NAME">%1$s</xliff:g> साठी अ‍ॅप सूचना सुरू करा"</string>
+ <string name="msg_missing_notification_access" msgid="281113995110910548">"सूचना बिंदू दाखवण्यासाठी, <xliff:g id="NAME">%1$s</xliff:g> साठी अ‍ॅप सूचना चालू करा"</string>
<string name="title_change_settings" msgid="1376365968844349552">"सेटिंग्ज बदला"</string>
<string name="notification_dots_service_title" msgid="4284221181793592871">"सूचना बिंदू दाखवा"</string>
- <string name="auto_add_shortcuts_label" msgid="3698776050751790653">"होम स्क्रीनवर ॲप आयकन जोडा"</string>
- <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"नवीन अ‍ॅप्ससाठी"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"होम स्क्रीनवर आयकन जोडा"</string>
+ <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"नवीन अॅप्ससाठी"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"अज्ञात"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"काढा"</string>
<string name="abandoned_search" msgid="891119232568284442">"शोधा"</string>
<string name="abandoned_promises_title" msgid="7096178467971716750">"हा अ‍ॅप इंस्टॉल केलेला नाही"</string>
<string name="abandoned_promise_explanation" msgid="3990027586878167529">"या चिन्हासाठी अ‍ॅप इंस्टॉल केलेला नाही. तुम्ही ते काढू शकता किंवा अ‍ॅपचा शोध घेऊ शकता आणि त्यास व्यक्तिचलितपणे इंस्टॉल करू शकता."</string>
- <string name="app_installing_title" msgid="5864044122733792085">"<xliff:g id="NAME">%1$s</xliff:g> इंस्टॉल करत आहे, <xliff:g id="PROGRESS">%2$s</xliff:g> पूर्ण झाले"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> डाउनलोड होत आहे , <xliff:g id="PROGRESS">%2$s</xliff:g> पूर्ण झाले"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> इंस्टॉल करण्याची प्रतिक्षा करत आहे"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"<xliff:g id="NAME">%1$s</xliff:g> विजेट"</string>
<string name="widgets_list" msgid="796804551140113767">"विजेट सूची"</string>
<string name="widgets_list_closed" msgid="6141506579418771922">"विजेट सूची बंद केली"</string>
<string name="action_add_to_workspace" msgid="8902165848117513641">"होम स्क्रीनवर जोडा"</string>
@@ -151,20 +129,15 @@
<string name="action_deep_shortcut" msgid="2864038805849372848">"शॉर्टकट"</string>
<string name="shortcuts_menu_with_notifications_description" msgid="2676582286544232849">"शॉर्टकट आणि सूचना"</string>
<string name="action_dismiss_notification" msgid="5909461085055959187">"डिसमिस करा"</string>
- <string name="accessibility_close" msgid="2277148124685870734">"बंद करा"</string>
<string name="notification_dismissed" msgid="6002233469409822874">"सूचना डिसमिस केली"</string>
<string name="all_apps_personal_tab" msgid="4190252696685155002">"वैयक्तिक"</string>
- <string name="all_apps_work_tab" msgid="4884822796154055118">"कार्य"</string>
+ <string name="all_apps_work_tab" msgid="4884822796154055118">"कार्यालय"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"कार्य प्रोफाइल"</string>
- <string name="work_profile_edu_work_apps" msgid="7895468576497746520">"कामाशी संबंधित ॲप्स ही बॅज केलेली असून तुमच्या IT ॲडमिनला दृश्यमान आहेत"</string>
- <string name="work_profile_edu_accept" msgid="6069788082535149071">"समजले"</string>
- <string name="work_apps_paused_title" msgid="3040901117349444598">"कार्य ॲप्स थांबवली आहेत"</string>
- <string name="work_apps_paused_body" msgid="261634750995824906">"तुमची कार्य ॲप्स तुम्हाला सूचना पाठवू शकत नाहीत, तुमची बॅटरी वापरू शकत नाहीत किंवा तुमचे स्थान अ‍ॅक्सेस करू शकत नाहीत"</string>
- <string name="work_apps_paused_content_description" msgid="5149623040804051095">"कामाशी संबंधित ॲप्स बंद आहेत. तुमचे कामाशी संबंधित ॲप्स तुम्हाला सूचना पाठवू शकत नाहीत, तुमची बॅटरी वापरू शकत नाहीत किंवा तुमचे स्थान अ‍ॅक्सेस करू शकत नाहीत"</string>
- <string name="work_apps_paused_edu_banner" msgid="8872412121608402058">"Work apps ही बॅज केलेली असून तुमच्या IT ॲडमिनला दृश्यमान आहेत"</string>
- <string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"समजले"</string>
- <string name="work_apps_pause_btn_text" msgid="1921059713673767460">"कामाशी संबंधित ॲप्स बंद करा"</string>
- <string name="work_apps_enable_btn_text" msgid="1156432622148413741">"कार्य ॲप्स सुरू करा"</string>
- <string name="developer_options_filter_hint" msgid="5896817443635989056">"फिल्टर"</string>
+ <string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"कामाची अ‍ॅप्स येथे मिळवा"</string>
+ <string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"प्रत्येक कार्य अ‍ॅपला एक बॅज असतो आणि तो तुमच्या संस्थेकडून सुरक्षित ठेवला जातो. अधिक सहज अ‍ॅक्सेससाठी अ‍ॅप्स तुमच्या होम स्क्रीनवर हलवा."</string>
+ <string name="work_mode_on_label" msgid="4781128097185272916">"तुमच्या संस्थेकडून व्यवस्थापित"</string>
+ <string name="work_mode_off_label" msgid="3194894777601421047">"सूचना आणि अ‍ॅप्स बंद आहेत"</string>
+ <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"बंद करा"</string>
+ <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"बंद केले"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"हे करता आले नाही: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
</resources>
diff --git a/res/values-ms/strings.xml b/res/values-ms/strings.xml
index d39a213cf3..7d054124fb 100644
--- a/res/values-ms/strings.xml
+++ b/res/values-ms/strings.xml
@@ -20,63 +20,39 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="649227358658669779">"Launcher3"</string>
+ <string name="folder_name" msgid="7371454440695724752"></string>
<string name="work_folder_name" msgid="3753320833950115786">"Kerja"</string>
<string name="activity_not_found" msgid="8071924732094499514">"Apl tidak dipasang."</string>
<string name="activity_not_available" msgid="7456344436509528827">"Apl tidak tersedia"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"Apl yang dimuat turun dilumpuhkan dalam mod Selamat"</string>
<string name="safemode_widget_error" msgid="4863470563535682004">"Widget dilumpuhkan dalam mod Selamat"</string>
<string name="shortcut_not_available" msgid="2536503539825726397">"Pintasan tidak tersedia"</string>
- <string name="home_screen" msgid="5629429142036709174">"Rumah"</string>
- <string name="recent_task_option_split_screen" msgid="6690461455618725183">"Skrin pisah"</string>
- <string name="split_screen_position_top" msgid="1504965011158689649">"Pisah atas"</string>
- <string name="split_screen_position_left" msgid="7537793098851830883">"Pisah kiri"</string>
- <string name="split_screen_position_right" msgid="1569377524925193369">"Pisah kanan"</string>
- <string name="split_app_info_accessibility" msgid="5475288491241414932">"Maklumat apl untuk %1$s"</string>
- <string name="long_press_widget_to_add" msgid="3587712543577675817">"Sentuh &amp; tahan untuk menggerakkan widget."</string>
- <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Ketik dua kali &amp; tahan untuk menggerakkan widget atau menggunakan tindakan tersuai."</string>
+ <string name="home_screen" msgid="806512411299847073">"Skrin utama"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"Tindakan tersuai"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"Sentuh &amp; tahan untuk mengambil widget."</string>
+ <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Ketik dua kali &amp; tahan untuk mengambil widget atau menggunakan tindakan tersuai"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"Lebar %1$d kali tinggi %2$d"</string>
- <string name="widget_preview_context_description" msgid="9045841361655787574">"Widget <xliff:g id="WIDGET_NAME">%1$s</xliff:g>"</string>
- <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Sentuh &amp; tahan widget untuk menggerakkan widget di sekitar Skrin utama"</string>
- <string name="add_to_home_screen" msgid="8631549138215492708">"Tambahkan pada Skrin utama"</string>
- <string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"Widget <xliff:g id="WIDGET_NAME">%1$s</xliff:g> ditambahkan pada skrin utama"</string>
- <string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# widget}other{# widget}}"</string>
- <string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{# pintasan}other{# pintasan}}"</string>
- <string name="widgets_and_shortcuts_count" msgid="7209136747878365116">"<xliff:g id="WIDGETS_COUNT">%1$s</xliff:g>, <xliff:g id="SHORTCUTS_COUNT">%2$s</xliff:g>"</string>
- <string name="widget_button_text" msgid="2880537293434387943">"Widget"</string>
- <string name="widgets_full_sheet_search_bar_hint" msgid="8484659090860596457">"Cari"</string>
- <string name="widgets_full_sheet_cancel_button_description" msgid="5766167035728653605">"Kosongkan teks daripada kotak carian"</string>
- <string name="no_widgets_available" msgid="4337693382501046170">"Widget dan pintasan tidak tersedia"</string>
- <string name="no_search_results" msgid="3787956167293097509">"Tiada widget atau pintasan yang dijumpai"</string>
- <string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Peribadi"</string>
- <string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Tempat kerja"</string>
- <string name="widget_category_conversations" msgid="8894438636213590446">"Perbualan"</string>
- <string name="widget_education_header" msgid="4874760613775913787">"Maklumat berguna di hujung jari anda"</string>
- <string name="widget_education_content" msgid="745542879510751525">"Untuk mendapatkan maklumat tanpa membuka apl, anda boleh menambahkan widget pada skrin Utama anda"</string>
- <string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Ketik untuk menukar tetapan widget"</string>
- <string name="widget_education_close_button" msgid="8676165703104836580">"OK"</string>
- <string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Tukar tetapan widget"</string>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Sentuh &amp; tahan untuk meletakkan widget/ikon secara manual"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"Tambahkan secara automatik"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Cari apl"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Memuatkan apl…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"Tiada apl yang ditemui sepadan dengan \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
<string name="all_apps_search_market_message" msgid="1366263386197059176">"Cari lagi apl"</string>
<string name="label_application" msgid="8531721983832654978">"Apl"</string>
- <string name="all_apps_label" msgid="5015784846527570951">"Semua apl"</string>
<string name="notifications_header" msgid="1404149926117359025">"Pemberitahuan"</string>
- <string name="long_press_shortcut_to_add" msgid="5405328730817637737">"Sentuh &amp; tahan untuk menggerakkan pintasan."</string>
- <string name="long_accessible_way_to_add_shortcut" msgid="2199537273817090740">"Ketik dua kali &amp; tahan untuk menggerakkan pintasan atau menggunakan tindakan tersuai."</string>
- <string name="out_of_space" msgid="6692471482459245734">"Tiada ruang di skrin Utama ini"</string>
+ <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"Sentuh &amp; tahan untuk mengambil pintasan."</string>
+ <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"Ketik dua kali &amp; tahan untuk mengambil pintasan atau menggunakan tindakan tersuai."</string>
+ <string name="out_of_space" msgid="4691004494942118364">"Tiada lagi ruang pada skrin Laman Utama ini."</string>
<string name="hotseat_out_of_space" msgid="7448809638125333693">"Tiada ruang dalam dulang Kegemaran lagi"</string>
<string name="all_apps_button_label" msgid="8130441508702294465">"Senarai apl"</string>
- <string name="all_apps_search_results" msgid="5889367432531296759">"Hasil carian"</string>
<string name="all_apps_button_personal_label" msgid="1315764287305224468">"Senarai apl peribadi"</string>
<string name="all_apps_button_work_label" msgid="7270707118948892488">"Senarai apl kerja"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"Laman Utama"</string>
<string name="remove_drop_target_label" msgid="7812859488053230776">"Alih keluar"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"Nyahpasang"</string>
<string name="app_info_drop_target_label" msgid="692894985365717661">"Maklumat apl"</string>
<string name="install_drop_target_label" msgid="2539096853673231757">"Pasang"</string>
- <string name="dismiss_prediction_label" msgid="3357562989568808658">"Jangan cadangkan apl"</string>
- <string name="pin_prediction" msgid="4196423321649756498">"Sematkan Ramalan"</string>
<string name="permlab_install_shortcut" msgid="5632423390354674437">"pasang pintasan"</string>
<string name="permdesc_install_shortcut" msgid="923466509822011139">"Membenarkan apl menambah pintasan tanpa campur tangan pengguna."</string>
<string name="permlab_read_settings" msgid="1941457408239617576">"baca tetapan dan pintasan Laman Utama"</string>
@@ -84,13 +60,15 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"tulis tetapan dan pintasan Laman Utama"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"Membenarkan apl menukar tetapan dan pintasan di Laman Utama."</string>
<string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> tidak dibenarkan membuat panggilan telefon"</string>
- <string name="gadget_error_text" msgid="740356548025791839">"Tidak dapat memuatkan widget"</string>
- <string name="gadget_setup_text" msgid="8348374825537681407">"Tetapan widget"</string>
- <string name="gadget_complete_setup_text" msgid="309040266978007925">"Ketik untuk menyelesaikan persediaan"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"Masalah memuatkan widget"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"Persediaan"</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"Ini ialah apl sistem dan tidak boleh dinyahpasang."</string>
- <string name="folder_hint_text" msgid="5174843001373488816">"Edit Nama"</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"Folder Tanpa Nama"</string>
<string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> dilumpuhkan"</string>
- <string name="dotted_app_label" msgid="1704091277755818896">"{count,plural,offset:1 =1{{app_name} mempunyai # pemberitahuan}other{{app_name} mempunyai # pemberitahuan}}"</string>
+ <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+ <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, mempunyai <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> pemberitahuan</item>
+ <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g>, mempunyai <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> pemberitahuan</item>
+ </plurals>
<string name="default_scroll_format" msgid="7475544710230993317">"Halaman %1$d daripada %2$d"</string>
<string name="workspace_scroll_format" msgid="8458889198184077399">"Skrin Laman Utama %1$d daripada %2$d"</string>
<string name="workspace_new_page" msgid="257366611030256142">"Halaman skrin utama baharu"</string>
@@ -99,10 +77,10 @@
<string name="folder_tap_to_rename" msgid="4017685068016979677">"Ketik untuk menyimpan penamaan semula"</string>
<string name="folder_closed" msgid="4100806530910930934">"Folder ditutup"</string>
<string name="folder_renamed" msgid="1794088362165669656">"Folder dinamakan semula kepada <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="folder_name_format_exact" msgid="8626242716117004803">"Folder: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> item"</string>
- <string name="folder_name_format_overflow" msgid="4270108890534995199">"Folder: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> atau lebih banyak item"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"Folder: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"Widget"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Kertas dinding"</string>
- <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Kertas dinding &amp; gaya"</string>
+ <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Gaya &amp; kertas dinding"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Tetapan laman utama"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Dilumpuhkan oleh pentadbir anda"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Benarkan putaran Skrin Utama"</string>
@@ -114,16 +92,16 @@
<string name="msg_missing_notification_access" msgid="281113995110910548">"Untuk menunjukkan Titik Pemberitahuan, hidupkan pemberitahuan apl untuk <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="title_change_settings" msgid="1376365968844349552">"Tukar tetapan"</string>
<string name="notification_dots_service_title" msgid="4284221181793592871">"Tunjukkan titik pemberitahuan"</string>
- <string name="auto_add_shortcuts_label" msgid="3698776050751790653">"Tambahkan ikon apl pada Skrin utama"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Tambahkan ikon pada Skrin Utama"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Untuk apl baharu"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"Tidak diketahui"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"Alih keluar"</string>
<string name="abandoned_search" msgid="891119232568284442">"Carian"</string>
<string name="abandoned_promises_title" msgid="7096178467971716750">"Apl ini tidak dipasang"</string>
<string name="abandoned_promise_explanation" msgid="3990027586878167529">"Apl untuk ikon ini tidak dipasang. Anda boleh mengalih keluar atau mencari dan memasang apl itu secara manual."</string>
- <string name="app_installing_title" msgid="5864044122733792085">"<xliff:g id="NAME">%1$s</xliff:g> dipasang, <xliff:g id="PROGRESS">%2$s</xliff:g> selesai"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> memuat turun, <xliff:g id="PROGRESS">%2$s</xliff:g> selesai"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> menunggu untuk dipasang"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"Widget <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="widgets_list" msgid="796804551140113767">"Senarai widget"</string>
<string name="widgets_list_closed" msgid="6141506579418771922">"Senarai widget ditutup"</string>
<string name="action_add_to_workspace" msgid="8902165848117513641">"Tambahkan pada Skrin Utama"</string>
@@ -151,20 +129,15 @@
<string name="action_deep_shortcut" msgid="2864038805849372848">"Pintasan"</string>
<string name="shortcuts_menu_with_notifications_description" msgid="2676582286544232849">"Pintasan dan pemberitahuan"</string>
<string name="action_dismiss_notification" msgid="5909461085055959187">"Ketepikan"</string>
- <string name="accessibility_close" msgid="2277148124685870734">"Tutup"</string>
<string name="notification_dismissed" msgid="6002233469409822874">"Pemberitahuan diketepikan"</string>
<string name="all_apps_personal_tab" msgid="4190252696685155002">"Peribadi"</string>
<string name="all_apps_work_tab" msgid="4884822796154055118">"Kerja"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"Profil kerja"</string>
- <string name="work_profile_edu_work_apps" msgid="7895468576497746520">"Apl kerja mempunyai lencana dan kelihatan kepada pentadbir IT anda"</string>
- <string name="work_profile_edu_accept" msgid="6069788082535149071">"OK"</string>
- <string name="work_apps_paused_title" msgid="3040901117349444598">"Apl kerja dijeda"</string>
- <string name="work_apps_paused_body" msgid="261634750995824906">"Apl kerja anda tidak boleh menghantar pemberitahuan kepada anda, menggunakan bateri anda atau mengakses lokasi anda"</string>
- <string name="work_apps_paused_content_description" msgid="5149623040804051095">"Apl kerja dimatikan. Apl kerja anda tidak boleh menghantar pemberitahuan kepada anda, menggunakan bateri anda atau mengakses lokasi anda"</string>
- <string name="work_apps_paused_edu_banner" msgid="8872412121608402058">"Apl kerja mempunyai lencana dan kelihatan kepada pentadbir IT anda"</string>
- <string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"OK"</string>
- <string name="work_apps_pause_btn_text" msgid="1921059713673767460">"Matikan apl kerja"</string>
- <string name="work_apps_enable_btn_text" msgid="1156432622148413741">"Hidupkan apl kerja"</string>
- <string name="developer_options_filter_hint" msgid="5896817443635989056">"Tapis"</string>
+ <string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"Temui apl kerja di sini"</string>
+ <string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"Setiap apl kerja terdapat lencana dan dilindungi oleh organisasi anda. Alihkan apl ke Skrin Utama untuk akses yang lebih mudah."</string>
+ <string name="work_mode_on_label" msgid="4781128097185272916">"Diurus oleh organisasi anda"</string>
+ <string name="work_mode_off_label" msgid="3194894777601421047">"Pemberitahuan dan apl dimatikan"</string>
+ <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Tutup"</string>
+ <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Ditutup"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Gagal: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
</resources>
diff --git a/res/values-my/strings.xml b/res/values-my/strings.xml
index 0d4c8fa93d..78856f657d 100644
--- a/res/values-my/strings.xml
+++ b/res/values-my/strings.xml
@@ -26,71 +26,48 @@
<string name="safemode_shortcut_error" msgid="9160126848219158407">"ဒေါင်းလုဒ် အက်ပ်ကို လုံခြုံရေး မုဒ်ထဲမှာ ပိတ်ထား"</string>
<string name="safemode_widget_error" msgid="4863470563535682004">"လုံခြုံရေး မုဒ်ထဲမှာ ဝီဂျက်များကို ပိတ်ထား"</string>
<string name="shortcut_not_available" msgid="2536503539825726397">"ဖြတ်လမ်း မရနိုင်ပါ"</string>
- <string name="home_screen" msgid="5629429142036709174">"ပင်မစာမျက်နှာ"</string>
- <string name="recent_task_option_split_screen" msgid="6690461455618725183">"မျက်နှာပြင် ခွဲ၍ပြသခြင်း"</string>
- <string name="split_screen_position_top" msgid="1504965011158689649">"ထိပ်ပိုင်း အခွဲ"</string>
- <string name="split_screen_position_left" msgid="7537793098851830883">"ဘက်ဘက် အခွဲ"</string>
- <string name="split_screen_position_right" msgid="1569377524925193369">"ညာဘက် အခွဲ"</string>
- <string name="split_app_info_accessibility" msgid="5475288491241414932">"%1$s အတွက် အက်ပ်အချက်အလက်"</string>
- <string name="long_press_widget_to_add" msgid="3587712543577675817">"ဝိဂျက်ကို ရွှေ့ရန် တို့ပြီး ဖိထားပါ။"</string>
- <string name="long_accessible_way_to_add" msgid="2733588281439571974">"ဝိဂျက်ကို ရွှေ့ရန် (သို့) စိတ်ကြိုက်လုပ်ဆောင်ချက်များကို သုံးရန် နှစ်ချက်တို့ပြီး ဖိထားပါ။"</string>
+ <string name="home_screen" msgid="806512411299847073">"ပင်မစာမျက်နှာ"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"စိတ်ကြိုက် လုပ်ဆောင်ချက်များ"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"ဝဒ်ဂျက်တစ်ခုကို ကောက်ယူရန် ဖိနှိပ်ထားပါ"</string>
+ <string name="long_accessible_way_to_add" msgid="4289502106628154155">"ဝစ်ဂျက်တစ်ခုကိုရယူရန် သို့မဟုတ် စိတ်ကြိုက်လုပ်ဆောင်မှုများကို အသုံးပြုရန် နှစ်ချက်တို့ပြီး ကိုင်ထားပါ။"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"အလျား %1$d နှင့် အမြင့် %2$d"</string>
- <string name="widget_preview_context_description" msgid="9045841361655787574">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g> ဝိဂျက်"</string>
- <string name="add_item_request_drag_hint" msgid="5653291305078645405">"ပင်မစာမျက်နှာအနီးတွင် ဝိဂျက်ကိုရွှေ့ရန် ၎င်းကို တို့ထိ၍ဖိထားပါ"</string>
- <string name="add_to_home_screen" msgid="8631549138215492708">"ပင်မစာမျက်နှာသို့ ထည့်ရန်"</string>
- <string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g> ဝိဂျက်ကို ပင်မစာမျက်နှာတွင် ထည့်လိုက်ပြီ"</string>
- <string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{ဝိဂျက် # ခု}other{ဝိဂျက် # ခု}}"</string>
- <string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{ဖြတ်လမ်းလင့်ခ် # ခု}other{ဖြတ်လမ်းလင့်ခ် # ခု}}"</string>
- <string name="widgets_and_shortcuts_count" msgid="7209136747878365116">"<xliff:g id="WIDGETS_COUNT">%1$s</xliff:g>၊ <xliff:g id="SHORTCUTS_COUNT">%2$s</xliff:g>"</string>
- <string name="widget_button_text" msgid="2880537293434387943">"ဝိဂျက်များ"</string>
- <string name="widgets_full_sheet_search_bar_hint" msgid="8484659090860596457">"ရှာရန်"</string>
- <string name="widgets_full_sheet_cancel_button_description" msgid="5766167035728653605">"ရှာဖွေစာလုံးဖြည့်ကွက်လပ်မှ စာသားကို ရှင်းလင်းပါ"</string>
- <string name="no_widgets_available" msgid="4337693382501046170">"ဝိဂျက်နှင့် ဖြတ်လမ်းလင့်ခ်များ မရနိုင်ပါ"</string>
- <string name="no_search_results" msgid="3787956167293097509">"ဝိဂျက် (သို့) ဖြတ်လမ်းလင့်ခ်များ ရှာမတွေ့ပါ"</string>
- <string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"ကိုယ်ပိုင်"</string>
- <string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"အလုပ်"</string>
- <string name="widget_category_conversations" msgid="8894438636213590446">"စကားဝိုင်းများ"</string>
- <string name="widget_education_header" msgid="4874760613775913787">"အသုံးဝင်သော အချက်အလက်များကို အလွယ်တကူ ရယူလိုက်ပါ"</string>
- <string name="widget_education_content" msgid="745542879510751525">"အက်ပ်များကိုမဖွင့်ဘဲ အချက်အလက်များရယူရန် သင်၏ ပင်မစာမျက်နှာသို့ ဝိဂျက်များ ထည့်နိုင်သည်"</string>
- <string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"ဝိဂျက် ဆက်တင်များကို ပြောင်းရန် တို့ပါ"</string>
- <string name="widget_education_close_button" msgid="8676165703104836580">"ရပြီ"</string>
- <string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"ဝိဂျက် ဆက်တင်များကို ပြောင်းပါ"</string>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"ကိုယ်တိုင်ထည့်ရန် ထိထားပါ"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"အလိုအလျောက် ထည့်ရန်"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"ရှာဖွေမှု အက်ပ်များ"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"အက်ပ်များကို ဖွင့်နေသည်…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" နှင့်ကိုက်ညီသည့် အပ်ပ်များကို မတွေ့ပါ"</string>
<string name="all_apps_search_market_message" msgid="1366263386197059176">"နောက်ထပ် အက်ပ်များကို ရှာပါ"</string>
<string name="label_application" msgid="8531721983832654978">"အက်ပ်"</string>
- <string name="all_apps_label" msgid="5015784846527570951">"အက်ပ်အားလုံး"</string>
<string name="notifications_header" msgid="1404149926117359025">"အကြောင်းကြားချက်များ"</string>
- <string name="long_press_shortcut_to_add" msgid="5405328730817637737">"ဖြတ်လမ်းလင့်ခ်ကို ရွှေ့ရန် နှစ်ချက်တို့ပြီး ဖိထားပါ။"</string>
- <string name="long_accessible_way_to_add_shortcut" msgid="2199537273817090740">"ဖြတ်လမ်းလင့်ခ်ကို ရွှေ့ရန် (သို့) စိတ်ကြိုက်လုပ်ဆောင်ချက်များကို သုံးရန် နှစ်ချက်တို့ပြီး ဖိထားပါ။"</string>
- <string name="out_of_space" msgid="6692471482459245734">"ဤပင်မစာမျက်နှာတွင် နေရာလွတ် မရှိတော့ပါ"</string>
+ <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"ဖြတ်လမ်းလင့်ခ်တစ်ခုကို ရွေးရန် ထိပြီး ဖိထားပါ။"</string>
+ <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"ဖြတ်လမ်းလင့်ခ်ကို ရွေးရန် (သို့) စိတ်ကြိုက်လုပ်ဆောင်ချက်များကို သုံးရန် နှစ်ချက်တို့ပြီး ဖိထားပါ။"</string>
+ <string name="out_of_space" msgid="4691004494942118364">"ဤပင်မမျက်နှာစာတွင် နေရာလွတ် မကျန်တော့ပါ"</string>
<string name="hotseat_out_of_space" msgid="7448809638125333693">"အနှစ်သက်ဆုံးများ ထားရာတွင် နေရာလွတ် မကျန်တော့ပါ"</string>
<string name="all_apps_button_label" msgid="8130441508702294465">"အက်ပ်စာရင်း"</string>
- <string name="all_apps_search_results" msgid="5889367432531296759">"ရှာဖွေမှု ရလဒ်များ"</string>
<string name="all_apps_button_personal_label" msgid="1315764287305224468">"တစ်ကိုယ်ရေသုံး အက်ပ်စာရင်း"</string>
<string name="all_apps_button_work_label" msgid="7270707118948892488">"အလုပ်သုံး အက်ပ်စာရင်း"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"ပင်မစာမျက်နှာ"</string>
<string name="remove_drop_target_label" msgid="7812859488053230776">"ဖယ်ရှားမည်"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"ဖြုတ်ရန်"</string>
- <string name="app_info_drop_target_label" msgid="692894985365717661">"အက်ပ်အချက်အလက်"</string>
+ <string name="app_info_drop_target_label" msgid="692894985365717661">"အက်ပ်အချက်အလက်များ"</string>
<string name="install_drop_target_label" msgid="2539096853673231757">"ထည့်သွင်းရန်"</string>
- <string name="dismiss_prediction_label" msgid="3357562989568808658">"အက်ပ်ကို အကြံမပြုပါနှင့်"</string>
- <string name="pin_prediction" msgid="4196423321649756498">"ခန့်မှန်းချက်ကို ပင်ထိုးရန်"</string>
- <string name="permlab_install_shortcut" msgid="5632423390354674437">"ဖြတ်လမ်းလင့်ခ်များ ထည့်သွင်းခြင်း"</string>
+ <string name="permlab_install_shortcut" msgid="5632423390354674437">"အတိုကောက်မှတ်သားမှုများအား ထည့်သွင်းခြင်း"</string>
<string name="permdesc_install_shortcut" msgid="923466509822011139">"အသုံးပြုသူ လုပ်ဆောင်မှုမရှိပဲ အပ်ပလီကေးရှင်းကို အတိုကောက်မှတ်သားမှုများ ပြုလုပ်ခွင့် ပေးခြင်း"</string>
<string name="permlab_read_settings" msgid="1941457408239617576">"ပင်မမျက်နှာစာ အပြင်အဆင် နှင့် အတိုကောက်မှတ်သားမှုများအား ဖတ်ခြင်း"</string>
<string name="permdesc_read_settings" msgid="5833423719057558387">"ပင်မမျက်နှာစာတွင်ရှိသော အပြင်အဆင်နှင့် အတိုကောက်မှတ်သားမှုများကို အပ်ပလီကေးရှင်းအား ဖတ်ခွင့်ပြုခြင်း"</string>
<string name="permlab_write_settings" msgid="3574213698004620587">"ပင်မမျက်နှာစာ အပြင်အဆင် နှင့် အတိုကောက်မှတ်သားမှုများအား ရေးသားခြင်း"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"ပင်မမျက်နှာစာတွင် ရှိသော အပြင်အဆင် နှင့် အတိုကောက်မှတ်သားမှုများ ကို အပ်ပလီကေးရှင်းအား ပြောင်းခွင့်ပြုခြင်း"</string>
<string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g>သည် ဖုန်းခေါ်ဆိုခွင့် မရှိပါ"</string>
- <string name="gadget_error_text" msgid="740356548025791839">"ဝိဂျက်ကို ဖွင့်၍မရပါ"</string>
- <string name="gadget_setup_text" msgid="8348374825537681407">"ဝိဂျက်ဆက်တင်များ"</string>
- <string name="gadget_complete_setup_text" msgid="309040266978007925">"စနစ်ထည့်သွင်းခြင်း အပြီးသတ်ရန် တို့ပါ"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"ဝဒ်ဂျက် တင်ရာတွင် ပြသနာ ရှိပါသည်"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"စဖွင့်သတ်မှတ်ရန်"</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"ဤအပ်ပလီကေးရှင်းမှာ စစ်စတန်ပိုင်းဆိုင်ရာ အပ်ပလီကေးရှင်းဖြစ်ပါသည်။ ထုတ်ပစ်၍ မရပါ"</string>
- <string name="folder_hint_text" msgid="5174843001373488816">"အမည်ကို တည်းဖြတ်ပါ"</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"အမည်မရှိအကန့်"</string>
<string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> ကို ပိတ်ထားသည်"</string>
- <string name="dotted_app_label" msgid="1704091277755818896">"{count,plural,offset:1 =1{{app_name} တွင် အကြောင်းကြားချက် # ခု ရှိသည်}other{{app_name} တွင် အကြောင်းကြားချက် # ခု ရှိသည်}}"</string>
+ <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+ <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g> တွင် သတိပေးချက် <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> ခု ရှိသည်</item>
+ <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g> တွင် သတိပေးချက် <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> ခု ရှိသည်</item>
+ </plurals>
<string name="default_scroll_format" msgid="7475544710230993317">"စာမျက်နှာ %1$d မှ %2$d"</string>
<string name="workspace_scroll_format" msgid="8458889198184077399">"ပင်မစာမျက်နှာ %1$d မှ %2$d"</string>
<string name="workspace_new_page" msgid="257366611030256142">"ပင်မမျက်နှာပြင် စာမျက်နှာသစ်"</string>
@@ -99,38 +76,38 @@
<string name="folder_tap_to_rename" msgid="4017685068016979677">"အမည်ပြောင်းခြင်းကို သိမ်းရန် တို့ပါ"</string>
<string name="folder_closed" msgid="4100806530910930934">"ပိတ်ထားသောအကန့်"</string>
<string name="folder_renamed" msgid="1794088362165669656">"ပြောင်းလဲလိုက်သော အကန့်အမည် <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="folder_name_format_exact" msgid="8626242716117004803">"ဖိုင်တွဲ - <xliff:g id="NAME">%1$s</xliff:g>၊ <xliff:g id="SIZE">%2$d</xliff:g> ဖိုင်များ"</string>
- <string name="folder_name_format_overflow" msgid="4270108890534995199">"ဖိုင်တွဲ - <xliff:g id="NAME">%1$s</xliff:g>၊ <xliff:g id="SIZE">%2$d</xliff:g> သို့မဟုတ် နောက်ထပ်ဖိုင်များ"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"အကန့်အမည်: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"ဝိဂျက်များ"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"နောက်ခံများ"</string>
- <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"နောက်ခံနှင့် ပုံစံ"</string>
+ <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"ပုံစံနှင့် နောက်ခံပုံများ"</string>
<string name="settings_button_text" msgid="8873672322605444408">"ပင်မဆက်တင်များ"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"သင့်စီမံခန့်ခွဲသူက ပိတ်လိုက်ပါသည်"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"ပင်မစာမျက်နှာလှည့်ခြင်းကို ခွင့်ပြုပါ"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"ဖုန်းကိုလှည့်ထားစဉ်"</string>
<string name="notification_dots_title" msgid="9062440428204120317">"သတိပေးချက် အစက်များ"</string>
- <string name="notification_dots_desc_on" msgid="1679848116452218908">"ဖွင့်"</string>
- <string name="notification_dots_desc_off" msgid="1760796511504341095">"ပိတ်"</string>
+ <string name="notification_dots_desc_on" msgid="1679848116452218908">"ဖွင့်ထားသည်"</string>
+ <string name="notification_dots_desc_off" msgid="1760796511504341095">"ပိတ်ထားသည်"</string>
<string name="title_missing_notification_access" msgid="7503287056163941064">"အကြောင်းကြားချက် အသုံးပြုခွင့် လိုအပ်သည်"</string>
<string name="msg_missing_notification_access" msgid="281113995110910548">"အကြောင်းကြားချက် အစက်များကို ပြသရန် <xliff:g id="NAME">%1$s</xliff:g> အတွက် အက်ပ်အကြောင်းကြားချက်များကို ဖွင့်ပါ"</string>
<string name="title_change_settings" msgid="1376365968844349552">"ဆက်တင်များ ပြောင်းရန်"</string>
- <string name="notification_dots_service_title" msgid="4284221181793592871">"အကြောင်းကြားချက် အစက်များ ပြရန်"</string>
- <string name="auto_add_shortcuts_label" msgid="3698776050751790653">"ပင်မစာမျက်နှာတွင် အက်ပ်သင်္ကေတထည့်ရန်"</string>
+ <string name="notification_dots_service_title" msgid="4284221181793592871">"သတိပေးချက် အစက်များ ပြရန်"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"ပင်မစာမျက်နှာသို့ သင်္ကေတပုံ ထည့်ရန်"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"အက်ပ်အသစ်များအတွက်"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"မသိ"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"ဖယ်ရှားရန်"</string>
<string name="abandoned_search" msgid="891119232568284442">"ရှာဖွေရန်"</string>
<string name="abandoned_promises_title" msgid="7096178467971716750">"အက်ပ်မတပ်ဆင်ရသေးပါ"</string>
<string name="abandoned_promise_explanation" msgid="3990027586878167529">"ဤအိုင်ကွန်အတွက် အက်ပ်အားမထည့်သွင်းထားပါ။ You can remove it, or search for the အက်ပ်and install it manually."</string>
- <string name="app_installing_title" msgid="5864044122733792085">"<xliff:g id="NAME">%1$s</xliff:g> ကို ထည့်သွင်းနေသည်၊ <xliff:g id="PROGRESS">%2$s</xliff:g> ပြီးပါပြီ"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> ဒေါင်းလုဒ်လုပ်နေသည်၊ <xliff:g id="PROGRESS">%2$s</xliff:g> ပြီးပါပြီ"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> ကိုထည့်သွင်းရန်စောင့်နေသည်"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"<xliff:g id="NAME">%1$s</xliff:g> ဝိဂျက်များ"</string>
<string name="widgets_list" msgid="796804551140113767">"ဝိဂျက်စာရင်း"</string>
<string name="widgets_list_closed" msgid="6141506579418771922">"ဝိဂျက်စာရင်းကို ပိတ်ထားသည်"</string>
<string name="action_add_to_workspace" msgid="8902165848117513641">"ပင်မမျက်နှာစာသို့ ထည့်ပါ"</string>
<string name="action_move_here" msgid="2170188780612570250">"၎င်းအား ဤသို့ ရွှေ့ပါ"</string>
<string name="item_added_to_workspace" msgid="4211073925752213539">"ပင်မ ဖန်မျက်နှာပြင်သို့ ထည့်ပြီး၏"</string>
<string name="item_removed" msgid="851119963877842327">"၎င်းအား ဖယ်ရှားပြီး၏"</string>
- <string name="undo" msgid="4151576204245173321">"နောက်ပြန်ရန်"</string>
+ <string name="undo" msgid="4151576204245173321">"နောက်ပြန်"</string>
<string name="action_move" msgid="4339390619886385032">"၎င်းအား ရွှေ့ပါ"</string>
<string name="move_to_empty_cell" msgid="2833711483015685619">"အတန်း <xliff:g id="NUMBER_0">%1$s</xliff:g> အတိုင် <xliff:g id="NUMBER_1">%2$s</xliff:g> သို့ ရွှေ့ပါ"</string>
<string name="move_to_position" msgid="6750008980455459790">"<xliff:g id="NUMBER">%1$s</xliff:g> သို့ နေရာရွှေ့ပါ"</string>
@@ -151,20 +128,15 @@
<string name="action_deep_shortcut" msgid="2864038805849372848">"ဖြတ်လမ်းများ"</string>
<string name="shortcuts_menu_with_notifications_description" msgid="2676582286544232849">"ဖြတ်လမ်းလင့်ခ်နှင့် အကြောင်းကြားချက်များ"</string>
<string name="action_dismiss_notification" msgid="5909461085055959187">"ပယ်ရန်"</string>
- <string name="accessibility_close" msgid="2277148124685870734">"ပိတ်ရန်"</string>
<string name="notification_dismissed" msgid="6002233469409822874">"အသိပေးချက်ကို ဖယ်ထုတ်ပြီးပါပြီ"</string>
<string name="all_apps_personal_tab" msgid="4190252696685155002">"ကိုယ်ပိုင်"</string>
<string name="all_apps_work_tab" msgid="4884822796154055118">"အလုပ်"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"အလုပ်ပရိုဖိုင်"</string>
- <string name="work_profile_edu_work_apps" msgid="7895468576497746520">"အလုပ်သုံးအက်ပ်များကို တံဆိပ်တပ်ထားပြီး သင်၏ IT စီမံခန့်ခွဲသူက မြင်နိုင်ပါသည်"</string>
- <string name="work_profile_edu_accept" msgid="6069788082535149071">"ရပါပြီ"</string>
- <string name="work_apps_paused_title" msgid="3040901117349444598">"အလုပ်သုံးအက်ပ်များကို ခေတ္တရပ်ထားသည်"</string>
- <string name="work_apps_paused_body" msgid="261634750995824906">"သင်၏ အလုပ်သုံးအက်ပ်များက အကြောင်းကြားချက်များ ပို့ခြင်း၊ သင့်ဘက်ထရီ သုံးခြင်း (သို့) သင့်တည်နေရာ သုံးခြင်းတို့ မပြုလုပ်နိုင်ပါ"</string>
- <string name="work_apps_paused_content_description" msgid="5149623040804051095">"အလုပ်သုံးအက်ပ်များ ပိတ်ထားသည်။ သင်၏ အလုပ်သုံးအက်ပ်များက အကြောင်းကြားချက်များ ပို့ခြင်း၊ သင့်ဘက်ထရီ သုံးခြင်း (သို့) သင့်တည်နေရာ သုံးခြင်းတို့ မပြုလုပ်နိုင်ပါ"</string>
- <string name="work_apps_paused_edu_banner" msgid="8872412121608402058">"အလုပ်သုံးအက်ပ်များကို တံဆိပ်တပ်ထားပြီး သင်၏ IT စီမံခန့်ခွဲသူက မြင်နိုင်ပါသည်"</string>
- <string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"ရပြီ"</string>
- <string name="work_apps_pause_btn_text" msgid="1921059713673767460">"အလုပ်သုံးအက်ပ်များ ပိတ်ရန်"</string>
- <string name="work_apps_enable_btn_text" msgid="1156432622148413741">"အလုပ်သုံးအက်ပ်များ ဖွင့်ရန်"</string>
- <string name="developer_options_filter_hint" msgid="5896817443635989056">"စစ်ထုတ်ရန်"</string>
+ <string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"အလုပ်အက်ပ်များကို ဤနေရာတွင်ရှာဖွေပါ"</string>
+ <string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"အလုပ်အက်ပ်တိုင်းတွင် တံဆိပ် တစ်ခုစီရှိပြီး သင်၏ အဖွဲ့အစည်းက လုံခြုံအောင် ထားရှိပါသည်။ အသုံးပြုရ ပိုမိုလွယ်ကူစေရန် အက်ပ်များကို သင်၏ ပင်မမျက်နှာပြင်သို့ ရွှေ့ပါ။"</string>
+ <string name="work_mode_on_label" msgid="4781128097185272916">"သင်၏ အဖွဲ့အစည်းက စီမံခန့်ခွဲထားပါသည်"</string>
+ <string name="work_mode_off_label" msgid="3194894777601421047">"အကြောင်းကြားချက်များနှင့် အက်ပ်များကို ပိတ်ထားသည်"</string>
+ <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"ပိတ်ရန်"</string>
+ <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"ပိတ်ထားသည်"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"မအောင်မြင်ပါ− <xliff:g id="WHAT">%1$s</xliff:g>"</string>
</resources>
diff --git a/res/values-nb/strings.xml b/res/values-nb/strings.xml
index 6dff142805..2257367a6a 100644
--- a/res/values-nb/strings.xml
+++ b/res/values-nb/strings.xml
@@ -20,63 +20,39 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="649227358658669779">"Launcher3"</string>
+ <string name="folder_name" msgid="7371454440695724752"></string>
<string name="work_folder_name" msgid="3753320833950115786">"Jobb"</string>
<string name="activity_not_found" msgid="8071924732094499514">"Appen er ikke installert."</string>
<string name="activity_not_available" msgid="7456344436509528827">"Appen er ikke tilgjengelig"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"En nedlastet app er deaktivert i sikker modus"</string>
<string name="safemode_widget_error" msgid="4863470563535682004">"Moduler er deaktivert i sikker modus"</string>
<string name="shortcut_not_available" msgid="2536503539825726397">"Snarveien er ikke tilgjengelig"</string>
- <string name="home_screen" msgid="5629429142036709174">"Startskjerm"</string>
- <string name="recent_task_option_split_screen" msgid="6690461455618725183">"Delt skjerm"</string>
- <string name="split_screen_position_top" msgid="1504965011158689649">"Splitt øverst"</string>
- <string name="split_screen_position_left" msgid="7537793098851830883">"Splitt til venstre"</string>
- <string name="split_screen_position_right" msgid="1569377524925193369">"Splitt til høyre"</string>
- <string name="split_app_info_accessibility" msgid="5475288491241414932">"Appinformasjon for %1$s"</string>
- <string name="long_press_widget_to_add" msgid="3587712543577675817">"Trykk og hold for å flytte en modul."</string>
- <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Dobbelttrykk og hold inne for å flytte en modul eller bruke tilpassede handlinger."</string>
+ <string name="home_screen" msgid="806512411299847073">"Startskjerm"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"Tilpassede handlinger"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"Trykk og hold inne for å plukke opp en modul."</string>
+ <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Dobbelttrykk og hold inne for å velge en modul eller bruke tilpassede handlinger."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d bredde x %2$d høyde"</string>
- <string name="widget_preview_context_description" msgid="9045841361655787574">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g>-modul"</string>
- <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Trykk og hold på modulen for å bevege den rundt på startskjermen"</string>
- <string name="add_to_home_screen" msgid="8631549138215492708">"Legg til på startskjermen"</string>
- <string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g>-modulen er lagt til på startskjermen"</string>
- <string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# modul}other{# moduler}}"</string>
- <string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{# snarvei}other{# snarveier}}"</string>
- <string name="widgets_and_shortcuts_count" msgid="7209136747878365116">"<xliff:g id="WIDGETS_COUNT">%1$s</xliff:g>, <xliff:g id="SHORTCUTS_COUNT">%2$s</xliff:g>"</string>
- <string name="widget_button_text" msgid="2880537293434387943">"Moduler"</string>
- <string name="widgets_full_sheet_search_bar_hint" msgid="8484659090860596457">"Søk"</string>
- <string name="widgets_full_sheet_cancel_button_description" msgid="5766167035728653605">"Tøm tekst fra søkefeltet"</string>
- <string name="no_widgets_available" msgid="4337693382501046170">"Moduler og snarveier er ikke tilgjengelige"</string>
- <string name="no_search_results" msgid="3787956167293097509">"Fant ingen moduler eller snarveier"</string>
- <string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Personlige"</string>
- <string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Jobb"</string>
- <string name="widget_category_conversations" msgid="8894438636213590446">"Samtaler"</string>
- <string name="widget_education_header" msgid="4874760613775913787">"Lett tilgjengelig nyttig informasjon"</string>
- <string name="widget_education_content" msgid="745542879510751525">"For å se informasjon uten å åpne apper kan du legge til moduler på startskjermen"</string>
- <string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Trykk for å endre modulinnstillinger"</string>
- <string name="widget_education_close_button" msgid="8676165703104836580">"Greit"</string>
- <string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Endre modulinnstillinger"</string>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Trykk og hold for å plassere manuelt"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"Legg til automatisk"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Søk etter apper"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Laster inn appene …"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"Fant ingen apper som samsvarer med «<xliff:g id="QUERY">%1$s</xliff:g>»"</string>
<string name="all_apps_search_market_message" msgid="1366263386197059176">"Søk etter flere apper"</string>
<string name="label_application" msgid="8531721983832654978">"App"</string>
- <string name="all_apps_label" msgid="5015784846527570951">"Alle apper"</string>
<string name="notifications_header" msgid="1404149926117359025">"Varsler"</string>
- <string name="long_press_shortcut_to_add" msgid="5405328730817637737">"Trykk og hold for å flytte en snarvei."</string>
- <string name="long_accessible_way_to_add_shortcut" msgid="2199537273817090740">"Dobbelttrykk og hold for å flytte en snarvei eller bruke tilpassede handlinger."</string>
- <string name="out_of_space" msgid="6692471482459245734">"Ingen ledig plass på denne startskjermen"</string>
+ <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"Trykk og hold for å velge en snarvei."</string>
+ <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"Dobbelttrykk og hold for å velge en snarvei eller bruke tilpassede handlinger."</string>
+ <string name="out_of_space" msgid="4691004494942118364">"Denne startsiden er full."</string>
<string name="hotseat_out_of_space" msgid="7448809638125333693">"Favoritter-skuffen er full"</string>
<string name="all_apps_button_label" msgid="8130441508702294465">"App-liste"</string>
- <string name="all_apps_search_results" msgid="5889367432531296759">"Søkeresultater"</string>
<string name="all_apps_button_personal_label" msgid="1315764287305224468">"Personlige apper-liste"</string>
<string name="all_apps_button_work_label" msgid="7270707118948892488">"Jobbapper-liste"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"Startside"</string>
<string name="remove_drop_target_label" msgid="7812859488053230776">"Fjern"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"Avinstaller"</string>
<string name="app_info_drop_target_label" msgid="692894985365717661">"Info om appen"</string>
<string name="install_drop_target_label" msgid="2539096853673231757">"Installer"</string>
- <string name="dismiss_prediction_label" msgid="3357562989568808658">"Ikke foreslå app"</string>
- <string name="pin_prediction" msgid="4196423321649756498">"Fest forslaget"</string>
<string name="permlab_install_shortcut" msgid="5632423390354674437">"installere snarveier"</string>
<string name="permdesc_install_shortcut" msgid="923466509822011139">"Gir apper tillatelse til å legge til snarveier uten innblanding fra brukeren."</string>
<string name="permlab_read_settings" msgid="1941457408239617576">"lese startsideinnstillinger og -snarveier"</string>
@@ -84,13 +60,15 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"angi startsideinnstillinger og -snarveier"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"Lar appen endre innstillingene og snarveiene på startsiden."</string>
<string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> har ikke tillatelse til å ringe"</string>
- <string name="gadget_error_text" msgid="740356548025791839">"Kan ikke laste inn modulen"</string>
- <string name="gadget_setup_text" msgid="8348374825537681407">"Modulinnstillinger"</string>
- <string name="gadget_complete_setup_text" msgid="309040266978007925">"Trykk for å fullføre konfigureringen"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"Problem ved innlasting av modul"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"Konfigurering"</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"Dette er en systemapp som ikke kan avinstalleres."</string>
- <string name="folder_hint_text" msgid="5174843001373488816">"Rediger navn"</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"Mappe uten navn"</string>
<string name="disabled_app_label" msgid="6673129024321402780">"Slo av <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
- <string name="dotted_app_label" msgid="1704091277755818896">"{count,plural,offset:1 =1{{app_name} har # varsel}other{{app_name} har # varsler}}"</string>
+ <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+ <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g> har <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> varsler</item>
+ <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g> har <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> varsel</item>
+ </plurals>
<string name="default_scroll_format" msgid="7475544710230993317">"Side %1$d av %2$d"</string>
<string name="workspace_scroll_format" msgid="8458889198184077399">"Startside %1$d av %2$d"</string>
<string name="workspace_new_page" msgid="257366611030256142">"Ny side på startskjermen"</string>
@@ -99,10 +77,10 @@
<string name="folder_tap_to_rename" msgid="4017685068016979677">"Trykk for å lagre det nye navnet"</string>
<string name="folder_closed" msgid="4100806530910930934">"Mappen ble lukket"</string>
<string name="folder_renamed" msgid="1794088362165669656">"Mappen heter nå <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="folder_name_format_exact" msgid="8626242716117004803">"Mappe: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> elementer"</string>
- <string name="folder_name_format_overflow" msgid="4270108890534995199">"Mappe: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> eller flere elementer"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"Mappe: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"Moduler"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Bakgrunner"</string>
- <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Bakgrunn og stil"</string>
+ <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Stiler og bakgrunner"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Startsideinnstillinger"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Administratoren har slått av funksjonen"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Tillat rotasjon av startskjermen"</string>
@@ -114,16 +92,16 @@
<string name="msg_missing_notification_access" msgid="281113995110910548">"Slå på appvarsler for <xliff:g id="NAME">%1$s</xliff:g> for å vise varselsprikker"</string>
<string name="title_change_settings" msgid="1376365968844349552">"Endre innstillingene"</string>
<string name="notification_dots_service_title" msgid="4284221181793592871">"Vis varselsprikker"</string>
- <string name="auto_add_shortcuts_label" msgid="3698776050751790653">"Legg til appikoner på startskjermen"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Legg til ikon på startsiden"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"For nye apper"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"Ukjent"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"Fjern"</string>
<string name="abandoned_search" msgid="891119232568284442">"Søk"</string>
<string name="abandoned_promises_title" msgid="7096178467971716750">"Denne appen er ikke installert"</string>
<string name="abandoned_promise_explanation" msgid="3990027586878167529">"Appen for dette ikonet er ikke installert. Du kan fjerne det, eller prøve å søke etter appen og installere den manuelt."</string>
- <string name="app_installing_title" msgid="5864044122733792085">"<xliff:g id="NAME">%1$s</xliff:g> installerer, <xliff:g id="PROGRESS">%2$s</xliff:g> er fullført"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"Laster ned <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="PROGRESS">%2$s</xliff:g> er fullført"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"Venter på å installere <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"<xliff:g id="NAME">%1$s</xliff:g>-moduler"</string>
<string name="widgets_list" msgid="796804551140113767">"Modulliste"</string>
<string name="widgets_list_closed" msgid="6141506579418771922">"Modullisten er lukket"</string>
<string name="action_add_to_workspace" msgid="8902165848117513641">"Legg til på startskjermen"</string>
@@ -151,20 +129,15 @@
<string name="action_deep_shortcut" msgid="2864038805849372848">"Snarveier"</string>
<string name="shortcuts_menu_with_notifications_description" msgid="2676582286544232849">"Snarveier og varsler"</string>
<string name="action_dismiss_notification" msgid="5909461085055959187">"Avvis"</string>
- <string name="accessibility_close" msgid="2277148124685870734">"Lukk"</string>
<string name="notification_dismissed" msgid="6002233469409822874">"Varselet ble avvist"</string>
<string name="all_apps_personal_tab" msgid="4190252696685155002">"Personlig"</string>
<string name="all_apps_work_tab" msgid="4884822796154055118">"Jobb"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"Jobbprofil"</string>
- <string name="work_profile_edu_work_apps" msgid="7895468576497746520">"Jobbapper er merket og synlige for IT-administratoren din"</string>
- <string name="work_profile_edu_accept" msgid="6069788082535149071">"Greit"</string>
- <string name="work_apps_paused_title" msgid="3040901117349444598">"Jobbapper er satt på pause"</string>
- <string name="work_apps_paused_body" msgid="261634750995824906">"Jobbapper kan ikke sende deg varsler, bruke batteriet eller få tilgang til posisjonen din"</string>
- <string name="work_apps_paused_content_description" msgid="5149623040804051095">"Jobbapper er av. De kan ikke sende deg varsler, bruke batteriet eller få tilgang til posisjonen din"</string>
- <string name="work_apps_paused_edu_banner" msgid="8872412121608402058">"Jobbapper er merket og synlige for IT-administratoren din"</string>
- <string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"Greit"</string>
- <string name="work_apps_pause_btn_text" msgid="1921059713673767460">"Slå av jobbapper"</string>
- <string name="work_apps_enable_btn_text" msgid="1156432622148413741">"Slå på jobbapper"</string>
- <string name="developer_options_filter_hint" msgid="5896817443635989056">"Filter"</string>
+ <string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"Finn jobbapper her"</string>
+ <string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"Alle jobbapper har et merke og sikres av organisasjonen din. Flytt apper til startskjermen for å gjøre det enklere å finne dem."</string>
+ <string name="work_mode_on_label" msgid="4781128097185272916">"Administreres av organisasjonen din"</string>
+ <string name="work_mode_off_label" msgid="3194894777601421047">"Varsler og apper er slått av"</string>
+ <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Lukk"</string>
+ <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Lukket"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Mislyktes: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
</resources>
diff --git a/res/values-ne/strings.xml b/res/values-ne/strings.xml
index b735d025eb..1e7aee9e9e 100644
--- a/res/values-ne/strings.xml
+++ b/res/values-ne/strings.xml
@@ -20,77 +20,55 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="649227358658669779">"Launcher3"</string>
+ <string name="folder_name" msgid="7371454440695724752"></string>
<string name="work_folder_name" msgid="3753320833950115786">"कार्य"</string>
- <string name="activity_not_found" msgid="8071924732094499514">"एप स्थापित छैन।"</string>
- <string name="activity_not_available" msgid="7456344436509528827">"एप उपलब्ध छैन"</string>
- <string name="safemode_shortcut_error" msgid="9160126848219158407">"सुरक्षित मोडमा डाउनलोड गरेको एप अक्षम गरिएको छ"</string>
+ <string name="activity_not_found" msgid="8071924732094499514">"अनुप्रयोग स्थापित छैन।"</string>
+ <string name="activity_not_available" msgid="7456344436509528827">"अनुप्रयोग उपलब्ध छैन"</string>
+ <string name="safemode_shortcut_error" msgid="9160126848219158407">"सुरक्षित मोडमा डाउनलोड गरेको अनुप्रयोग अक्षम गरिएको छ"</string>
<string name="safemode_widget_error" msgid="4863470563535682004">"सुरक्षित मोडमा विगेटहरू अक्षम गरियो"</string>
<string name="shortcut_not_available" msgid="2536503539825726397">"सर्टकट उपलब्ध छैन"</string>
- <string name="home_screen" msgid="5629429142036709174">"होम"</string>
- <string name="recent_task_option_split_screen" msgid="6690461455618725183">"स्प्लिट स्क्रिन"</string>
- <string name="split_screen_position_top" msgid="1504965011158689649">"सिरानतिर स्प्लिट गर्नुहोस्"</string>
- <string name="split_screen_position_left" msgid="7537793098851830883">"बायाँतिर स्प्लिट गर्नुहोस्"</string>
- <string name="split_screen_position_right" msgid="1569377524925193369">"दायाँतिर स्प्लिट गर्नुहोस्"</string>
- <string name="split_app_info_accessibility" msgid="5475288491241414932">"%1$s का हकमा एपसम्बन्धी जानकारी"</string>
- <string name="long_press_widget_to_add" msgid="3587712543577675817">"कुनै विजेट सार्न डबल ट्याप गरेर छोइराख्नुहोस्।"</string>
- <string name="long_accessible_way_to_add" msgid="2733588281439571974">"कुनै विजेट सार्न वा आफ्नो रोजाइका कारबाही प्रयोग गर्न डबल ट्याप गरेर छोइराख्नुहोस्।"</string>
+ <string name="home_screen" msgid="806512411299847073">"गृह स्क्रिन"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"आफू अनुकूलका कारबाहीहरू"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"एउटा विजेटलाई टिप्नको लागि टच गरेर होल्ड गर्नुहोस्।"</string>
+ <string name="long_accessible_way_to_add" msgid="4289502106628154155">"विजेटलाई छान्न वा आफू अनुकूल कार्यहरू प्रयोग गर्न डबल ट्याप गरी होल्ड गर्नुहोस्।"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d चौडाइ गुणा %2$d उचाइ"</string>
- <string name="widget_preview_context_description" msgid="9045841361655787574">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g> विजेट"</string>
- <string name="add_item_request_drag_hint" msgid="5653291305078645405">"यो विजेट होम स्क्रिनमा यताउता सार्न त्यसमा टच एन्ड होल्ड गर्नुहोस्"</string>
- <string name="add_to_home_screen" msgid="8631549138215492708">"होम स्क्रिनमा हाल्नुहोस्"</string>
- <string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"होम स्क्रिनमा <xliff:g id="WIDGET_NAME">%1$s</xliff:g> विजेट हालियो"</string>
- <string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# विजेट}other{# वटा विजेट}}"</string>
- <string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{# सर्टकट}other{# वटा सर्टकट}}"</string>
- <string name="widgets_and_shortcuts_count" msgid="7209136747878365116">"<xliff:g id="WIDGETS_COUNT">%1$s</xliff:g>, <xliff:g id="SHORTCUTS_COUNT">%2$s</xliff:g>"</string>
- <string name="widget_button_text" msgid="2880537293434387943">"विजेटहरू"</string>
- <string name="widgets_full_sheet_search_bar_hint" msgid="8484659090860596457">"खोज्नुहोस्"</string>
- <string name="widgets_full_sheet_cancel_button_description" msgid="5766167035728653605">"खोज बाकसमा भएको पाठ हटाउनुहोस्"</string>
- <string name="no_widgets_available" msgid="4337693382501046170">"विजेट र सर्टकटहरू उपलब्ध छन्"</string>
- <string name="no_search_results" msgid="3787956167293097509">"कुनै पनि विजेट वा सर्टकट फेला परेन"</string>
- <string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"व्यक्तिगत"</string>
- <string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"कामसम्बन्धी"</string>
- <string name="widget_category_conversations" msgid="8894438636213590446">"वार्तालापहरू"</string>
- <string name="widget_education_header" msgid="4874760613775913787">"उपयोगी जानकारी सजिलै प्राप्त गर्नुहोस्"</string>
- <string name="widget_education_content" msgid="745542879510751525">"एपहरू नखोलिकनै तिनका बारेमा जानकारी प्राप्त गर्न तपाईं आफ्नो होम स्क्रिनमा विजेटहरू हाल्न सक्नुहुन्छ"</string>
- <string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"विजेटका सेटिङ बदल्न ट्याप गर्नुहोस्"</string>
- <string name="widget_education_close_button" msgid="8676165703104836580">"बुझेँ"</string>
- <string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"विजेटका सेटिङ बदल्नुहोस्"</string>
- <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"खोजसम्बन्धी एपहरू"</string>
- <string name="all_apps_loading_message" msgid="5813968043155271636">"एपहरू लोड गर्दै…"</string>
- <string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" सँग मिल्दो कुनै एप भेटिएन"</string>
- <string name="all_apps_search_market_message" msgid="1366263386197059176">"थप एपहरू खोज्नुहोस्"</string>
- <string name="label_application" msgid="8531721983832654978">"एप"</string>
- <string name="all_apps_label" msgid="5015784846527570951">"सबै एप"</string>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"म्यानुअल तरिकाले थप्न छुनुहोस् र थिची राख्नुहोस्‌"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"स्वतः थप्नुहोस्"</string>
+ <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"खोजसम्बन्धी अनुप्रयोगहरू"</string>
+ <string name="all_apps_loading_message" msgid="5813968043155271636">"अनुप्रयोगहरू लोड गर्दै…"</string>
+ <string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" सँग मिल्दो कुनै अनुप्रयोग भेटिएन"</string>
+ <string name="all_apps_search_market_message" msgid="1366263386197059176">"थप अनुप्रयोगहरू खोज्नुहोस्"</string>
+ <string name="label_application" msgid="8531721983832654978">"अनुप्रयोग"</string>
<string name="notifications_header" msgid="1404149926117359025">"सूचनाहरू"</string>
- <string name="long_press_shortcut_to_add" msgid="5405328730817637737">"कुनै सर्टकट सार्न डबल ट्याप गरेर छोइराख्नुहोस्।"</string>
- <string name="long_accessible_way_to_add_shortcut" msgid="2199537273817090740">"कुनै सर्टकट सार्न वा आफ्नो रोजाइका कारबाही प्रयोग गर्न डबल ट्याप गरेर छोइराख्नुहोस्।"</string>
- <string name="out_of_space" msgid="6692471482459245734">"यो होम स्क्रिनमा ठाउँ छैन"</string>
+ <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"कुनै सर्टकट छनौट गर्न छोइराख्नुहोस्।"</string>
+ <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"कुनै सर्टकट छनौट गर्न वा रोजेका कारबाहीहरू प्रयोग गर्न डबल ट्याप गरेर छोइराख्नुहोस्।"</string>
+ <string name="out_of_space" msgid="4691004494942118364">"यो गृह स्क्रिनमा कुनै थप ठाउँ छैन।"</string>
<string name="hotseat_out_of_space" msgid="7448809638125333693">"मन पर्ने ट्रे अब कुनै ठाँउ छैन"</string>
- <string name="all_apps_button_label" msgid="8130441508702294465">"एपको सूची"</string>
- <string name="all_apps_search_results" msgid="5889367432531296759">"खोज परिणामहरू"</string>
+ <string name="all_apps_button_label" msgid="8130441508702294465">"अनुप्रयोगको सूची"</string>
<string name="all_apps_button_personal_label" msgid="1315764287305224468">"व्यक्तिगत अनुप्रयोगहरूको सूची"</string>
<string name="all_apps_button_work_label" msgid="7270707118948892488">"कार्यसम्बन्धी अनुप्रयोगहरूको सूची"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"गृह"</string>
<string name="remove_drop_target_label" msgid="7812859488053230776">"हटाउनुहोस्"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"विस्थापित गर्नुहोस्"</string>
- <string name="app_info_drop_target_label" msgid="692894985365717661">"एपसम्बन्धी जानकारी"</string>
+ <string name="app_info_drop_target_label" msgid="692894985365717661">"अनुप्रयोग जानकारी"</string>
<string name="install_drop_target_label" msgid="2539096853673231757">"स्थापना गर्नुहोस्"</string>
- <string name="dismiss_prediction_label" msgid="3357562989568808658">"यो एप सिफारिस नगरियोस्"</string>
- <string name="pin_prediction" msgid="4196423321649756498">"सिफारिस गरिएको एप पिन गर्नुहोस्"</string>
<string name="permlab_install_shortcut" msgid="5632423390354674437">"सर्टकट स्थापना गर्नेहोस्"</string>
- <string name="permdesc_install_shortcut" msgid="923466509822011139">"प्रयोगकर्ताको हस्तक्षेप बिना एउटा एपलाई सर्टकटमा थप्नको लागि अनुमति दिनुहोस्।"</string>
+ <string name="permdesc_install_shortcut" msgid="923466509822011139">"प्रयोगकर्ताको हस्तक्षेप बिना एउटा अनुप्रयोगलाई सर्टकटमा थप्नको लागि अनुमति दिनुहोस्।"</string>
<string name="permlab_read_settings" msgid="1941457408239617576">"गृह सेटिङहरू र सर्टकटहरू पढ्नुहोस्"</string>
- <string name="permdesc_read_settings" msgid="5833423719057558387">"गृहमा एउटा एपलाई सेटिङहरू र सर्टकटहरू पढ्न अनुमति दिनुहोस्।"</string>
+ <string name="permdesc_read_settings" msgid="5833423719057558387">"गृहमा एउटा अनुप्रयोगलाई सेटिङहरू र सर्टकटहरू पढ्न अनुमति दिनुहोस्।"</string>
<string name="permlab_write_settings" msgid="3574213698004620587">"गृह सेटिङहरू र सर्टकटहरू लेख्नुहोस्"</string>
- <string name="permdesc_write_settings" msgid="5440712911516509985">"गृहमा एउटा एपलाई सेटिङ र सर्टकट बदल्न अनुमति दिनुहोस्।"</string>
+ <string name="permdesc_write_settings" msgid="5440712911516509985">"गृहमा एउटा अनुप्रयोगलाई सेटिङ र सर्टकट बदल्न अनुमति दिनुहोस्।"</string>
<string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> ले फोन कलहरू गर्न अनुमति छैन"</string>
- <string name="gadget_error_text" msgid="740356548025791839">"विजेट लोड गर्न सकिएन"</string>
- <string name="gadget_setup_text" msgid="8348374825537681407">"विजेटका सेटिङ"</string>
- <string name="gadget_complete_setup_text" msgid="309040266978007925">"सेटअप पूरा गर्न ट्याप गर्नुहोस्"</string>
- <string name="uninstall_system_app_text" msgid="4172046090762920660">"यो प्रणाली एप हो र यसलाई स्थापना रद्द गर्न सकिँदैन।"</string>
- <string name="folder_hint_text" msgid="5174843001373488816">"नाम सम्पादन गर्नुहोस्"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"समस्या लोडिङ गर्ने विजेट"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"सेटअप"</string>
+ <string name="uninstall_system_app_text" msgid="4172046090762920660">"यो प्रणाली अनुप्रयोग हो र यसलाई स्थापना रद्द गर्न सकिँदैन।"</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"बेनाम फोल्डर"</string>
<string name="disabled_app_label" msgid="6673129024321402780">"असक्षम पारिएको <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
- <string name="dotted_app_label" msgid="1704091277755818896">"{count,plural,offset:1 =1{{app_name} सँग सम्बन्धित # सूचना छ}other{{app_name} सँग सम्बन्धित # वटा सूचना छन्}}"</string>
+ <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+ <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, का <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> सूचनाहरू छन्</item>
+ <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g>, को <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> सूचना छ</item>
+ </plurals>
<string name="default_scroll_format" msgid="7475544710230993317">"पृष्ठ %2$d को %1$d"</string>
<string name="workspace_scroll_format" msgid="8458889198184077399">"गृह स्क्रिन %1$d को %2$d"</string>
<string name="workspace_new_page" msgid="257366611030256142">"नयाँ गृह स्क्रिन पृष्ठ"</string>
@@ -99,34 +77,34 @@
<string name="folder_tap_to_rename" msgid="4017685068016979677">"पुनःनामाकरणलाई सुरक्षित गर्न ट्याप गर्नुहोस्"</string>
<string name="folder_closed" msgid="4100806530910930934">"फोल्डर बन्द भयो"</string>
<string name="folder_renamed" msgid="1794088362165669656">"फोल्डर <xliff:g id="NAME">%1$s</xliff:g> मा पुनःनामाकरण गरियो।"</string>
- <string name="folder_name_format_exact" msgid="8626242716117004803">"फोल्डर: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> वस्तुहरू"</string>
- <string name="folder_name_format_overflow" msgid="4270108890534995199">"फोल्डर: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> वा सोभन्दा बढी वस्तुहरू"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"फोल्डर: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"विजेटहरू"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"वालपेपरहरु"</string>
- <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"वालपेपर तथा शैली"</string>
- <string name="settings_button_text" msgid="8873672322605444408">"होम पेजका सेटिङहरू"</string>
+ <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"शैली तथा वालपेपरहरू"</string>
+ <string name="settings_button_text" msgid="8873672322605444408">"गृहपृष्ठका सेटिङहरू"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"तपाईँको प्रशासकद्वारा असक्षम गरिएको"</string>
- <string name="allow_rotation_title" msgid="7728578836261442095">"होम स्क्रिन रोटेट हुन दिइयोस्"</string>
+ <string name="allow_rotation_title" msgid="7728578836261442095">"गृह स्क्रिनलाई घुम्ने अनुमति दिनुहोस्"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"फोनलाई घुमाइँदा"</string>
<string name="notification_dots_title" msgid="9062440428204120317">"सूचनाको प्रतीक जनाउने थोप्लाहरू"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"सक्रिय"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"निष्क्रिय"</string>
<string name="title_missing_notification_access" msgid="7503287056163941064">"सूचनासम्बन्धी पहुँच आवश्यक हुन्छ"</string>
- <string name="msg_missing_notification_access" msgid="281113995110910548">"सूचनाको प्रतीक जनाउने थोप्लाहरू देखाउन <xliff:g id="NAME">%1$s</xliff:g> को एपसम्बन्धी सूचनाहरूलाई सक्रिय गर्नुहोस्"</string>
+ <string name="msg_missing_notification_access" msgid="281113995110910548">"सूचनाको प्रतीक जनाउने थोप्लाहरू देखाउन <xliff:g id="NAME">%1$s</xliff:g> को अनुप्रयोगसम्बन्धी सूचनाहरूलाई सक्रिय गर्नुहोस्"</string>
<string name="title_change_settings" msgid="1376365968844349552">"सेटिङहरू बदल्नुहोस्"</string>
<string name="notification_dots_service_title" msgid="4284221181793592871">"सूचनाको प्रतीक जनाउने थोप्लाहरू देखाउनुहोस्"</string>
- <string name="auto_add_shortcuts_label" msgid="3698776050751790653">"होम स्क्रिनमा एपका आइकन थपियोस्"</string>
- <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"नयाँ एपका लागि"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"गृह स्क्रिनमा आइकन थप्नुहोस्"</string>
+ <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"नयाँ अनुप्रयोगका लागि"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"अज्ञात"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"हटाउनुहोस्"</string>
<string name="abandoned_search" msgid="891119232568284442">"खोजी गर्नुहोस्"</string>
- <string name="abandoned_promises_title" msgid="7096178467971716750">"यो एप स्थापित छैन"</string>
- <string name="abandoned_promise_explanation" msgid="3990027586878167529">"यो प्रतिमाका लागि एपलाई स्थापना गरिएको छैन। तपाईं यसलाई हटाउन, वा एप खोजी र स्वयं यो स्थापित गर्न सक्नुहुन्छ।"</string>
- <string name="app_installing_title" msgid="5864044122733792085">"<xliff:g id="NAME">%1$s</xliff:g> इन्स्टल गरिँदै छ, <xliff:g id="PROGRESS">%2$s</xliff:g> पूरा भयो"</string>
+ <string name="abandoned_promises_title" msgid="7096178467971716750">"यो अनुप्रयोग स्थापित छैन"</string>
+ <string name="abandoned_promise_explanation" msgid="3990027586878167529">"यो प्रतिमाका लागि अनुप्रयोगलाई स्थापना गरिएको छैन। तपाईं यसलाई हटाउन, वा अनुप्रयोग खोजी र स्वयं यो स्थापित गर्न सक्नुहुन्छ।"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> डाउनलोड गर्दै, <xliff:g id="PROGRESS">%2$s</xliff:g> सम्पन्‍न"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> स्थापना गर्न प्रतीक्षा गर्दै"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"<xliff:g id="NAME">%1$s</xliff:g> विजेटहरू"</string>
<string name="widgets_list" msgid="796804551140113767">"विजेटहरूको सूची"</string>
<string name="widgets_list_closed" msgid="6141506579418771922">"विजेटहरूको सूची बन्द गरियो"</string>
- <string name="action_add_to_workspace" msgid="8902165848117513641">"होम स्क्रिनमा हाल्नुहोस्"</string>
+ <string name="action_add_to_workspace" msgid="8902165848117513641">"गृह स्क्रिनमा थप्नुहोस्"</string>
<string name="action_move_here" msgid="2170188780612570250">"वस्तु यहाँ सार्नुहोस्"</string>
<string name="item_added_to_workspace" msgid="4211073925752213539">"वस्तु गृह स्क्रिनमा थपियो"</string>
<string name="item_removed" msgid="851119963877842327">"वस्तु हटाइयो"</string>
@@ -151,20 +129,15 @@
<string name="action_deep_shortcut" msgid="2864038805849372848">"सर्टकटहरू"</string>
<string name="shortcuts_menu_with_notifications_description" msgid="2676582286544232849">"सर्टकट तथा सूचनाहरू"</string>
<string name="action_dismiss_notification" msgid="5909461085055959187">"खारेज गर्नुहोस्"</string>
- <string name="accessibility_close" msgid="2277148124685870734">"बन्द गर्नुहोस्"</string>
<string name="notification_dismissed" msgid="6002233469409822874">"सूचना खारेज गरियो"</string>
<string name="all_apps_personal_tab" msgid="4190252696685155002">"व्यक्तिगत"</string>
<string name="all_apps_work_tab" msgid="4884822796154055118">"कार्यसम्बन्धी"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"कार्य प्रोफाइल"</string>
- <string name="work_profile_edu_work_apps" msgid="7895468576497746520">"कामसम्बन्धी एपहरूमा ब्याज अङ्कित हुन्छ र तपाईंका IT एड्मिन ती एप हेर्न सक्छन्"</string>
- <string name="work_profile_edu_accept" msgid="6069788082535149071">"बुझेँ"</string>
- <string name="work_apps_paused_title" msgid="3040901117349444598">"कार्यसम्बन्धी एपहरू पज गरिएका छन्"</string>
- <string name="work_apps_paused_body" msgid="261634750995824906">"तपाईंका कामसम्बन्धी एपहरूले तपाईंलाई सूचना पठाउन, तपाईंको डिभाइसको ब्याट्री प्रयोग गर्न वा तपाईंको लोकेसन हेर्न सक्दैनन्"</string>
- <string name="work_apps_paused_content_description" msgid="5149623040804051095">"कामसम्बन्धी एपहरू अफ गरिएका छन्। तपाईंका कामसम्बन्धी एपहरूले तपाईंलाई सूचना पठाउन, तपाईंको डिभाइसको ब्याट्री प्रयोग गर्न वा तपाईंको लोकेसन हेर्न सक्दैनन्"</string>
- <string name="work_apps_paused_edu_banner" msgid="8872412121608402058">"कामसम्बन्धी एपमा ब्याज अङ्कित हुन्छ र तपाईंका IT एड्मिन ती एप हेर्न सक्नुहुन्छ"</string>
- <string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"बुझेँ"</string>
- <string name="work_apps_pause_btn_text" msgid="1921059713673767460">"कामसम्बन्धी एपहरू अफ गर्नुहोस्"</string>
- <string name="work_apps_enable_btn_text" msgid="1156432622148413741">"कामसम्बन्धी एपहरू अन गर्नुहोस्"</string>
- <string name="developer_options_filter_hint" msgid="5896817443635989056">"फिल्टर"</string>
+ <string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"कार्यसम्बन्धी अनुप्रयोगहरू यहाँ प्राप्त गर्नुहोस्"</string>
+ <string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"कार्यसम्बन्धी प्रत्येक अनुप्रयोगमा एउटा ब्याज छ र तपाईंको संगठनले यसलाई सुरक्षित राखेको छ । अझ सजिलो गरी पहुँच राख्नका लागि अनुप्रयोगहरूलाई आफ्नो गृहस्क्रिनमा सार्नुहोस्‌।"</string>
+ <string name="work_mode_on_label" msgid="4781128097185272916">"तपाईंको सङ्गठनले व्यवस्थापन गरेको"</string>
+ <string name="work_mode_off_label" msgid="3194894777601421047">"सूचना र अनुप्रयोगहरू निष्क्रिय छन्‌"</string>
+ <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"बन्द गर्नुहोस्"</string>
+ <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"बन्द गरियो"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"कार्य पूरा गर्न सकिएन: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
</resources>
diff --git a/res/values-night-v31/colors.xml b/res/values-night-v31/colors.xml
deleted file mode 100644
index eefe8c5f81..0000000000
--- a/res/values-night-v31/colors.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?><!--
-/*
-* Copyright (C) 2021 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.
-*/
--->
-
-<resources>
- <color name="home_settings_header_accent">@android:color/system_accent1_100</color>
- <color name="home_settings_header_collapsed">@android:color/system_neutral1_700</color>
- <color name="home_settings_header_expanded">@android:color/system_neutral1_900</color>
-
- <color name="home_settings_thumb_off_color">@android:color/system_neutral2_300</color>
- <color name="home_settings_track_on_color">@android:color/system_accent2_700</color>
- <color name="home_settings_track_off_color">@android:color/system_neutral1_700</color>
-
- <color name="all_apps_button_bg_color">@android:color/system_neutral1_800</color>
- <color name="all_apps_button_color_1">@android:color/system_accent1_300</color>
- <color name="all_apps_button_color_3">@android:color/system_accent1_100</color>
- <color name="all_apps_button_color_4">@android:color/system_accent2_100</color>
-</resources> \ No newline at end of file
diff --git a/res/values-night/colors.xml b/res/values-night/colors.xml
deleted file mode 100644
index ce272ceade..0000000000
--- a/res/values-night/colors.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?><!--
-/*
-* Copyright (C) 2022 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
--->
-
-<resources>
- <color name="all_apps_button_bg_color">#2E3132</color>
- <color name="all_apps_button_color_1">#33B9DB</color>
- <color name="all_apps_button_color_2">#EFFBFF</color>
- <color name="all_apps_button_color_3">#B1EBFF</color>
- <color name="all_apps_button_color_4">#DEE0FF</color>
-</resources> \ No newline at end of file
diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml
index 51730a051f..ec30d8c6b2 100644
--- a/res/values-nl/strings.xml
+++ b/res/values-nl/strings.xml
@@ -20,63 +20,39 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="649227358658669779">"Launcher3"</string>
+ <string name="folder_name" msgid="7371454440695724752"></string>
<string name="work_folder_name" msgid="3753320833950115786">"Werk"</string>
<string name="activity_not_found" msgid="8071924732094499514">"App is niet geïnstalleerd."</string>
<string name="activity_not_available" msgid="7456344436509528827">"App is niet beschikbaar"</string>
- <string name="safemode_shortcut_error" msgid="9160126848219158407">"Gedownloade app uitgezet in veilige modus"</string>
- <string name="safemode_widget_error" msgid="4863470563535682004">"Widgets uitgezet in veilige modus"</string>
+ <string name="safemode_shortcut_error" msgid="9160126848219158407">"Gedownloade app uitgeschakeld in veilige modus"</string>
+ <string name="safemode_widget_error" msgid="4863470563535682004">"Widgets uitgeschakeld in Veilige modus"</string>
<string name="shortcut_not_available" msgid="2536503539825726397">"Snelkoppeling is niet beschikbaar"</string>
- <string name="home_screen" msgid="5629429142036709174">"Startscherm"</string>
- <string name="recent_task_option_split_screen" msgid="6690461455618725183">"Gesplitst scherm"</string>
- <string name="split_screen_position_top" msgid="1504965011158689649">"Gesplitst scherm boven"</string>
- <string name="split_screen_position_left" msgid="7537793098851830883">"Gesplitst scherm links"</string>
- <string name="split_screen_position_right" msgid="1569377524925193369">"Gesplitst scherm rechts"</string>
- <string name="split_app_info_accessibility" msgid="5475288491241414932">"App-info voor %1$s"</string>
- <string name="long_press_widget_to_add" msgid="3587712543577675817">"Tik en houd vast om een widget te verplaatsen."</string>
- <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Dubbeltik en houd vast om een widget te verplaatsen of aangepaste acties te gebruiken."</string>
+ <string name="home_screen" msgid="806512411299847073">"Startscherm"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"Aangepaste acties"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"Blijf aanraken om een widget toe te voegen."</string>
+ <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Dubbeltik en blijf aanraken om een widget toe te voegen of aangepaste acties te gebruiken."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d breed en %2$d hoog"</string>
- <string name="widget_preview_context_description" msgid="9045841361655787574">"Widget <xliff:g id="WIDGET_NAME">%1$s</xliff:g>"</string>
- <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Houd de widget ingedrukt om deze te verplaatsen op het startscherm"</string>
- <string name="add_to_home_screen" msgid="8631549138215492708">"Toevoegen aan startscherm"</string>
- <string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"Widget <xliff:g id="WIDGET_NAME">%1$s</xliff:g> toegevoegd aan startscherm"</string>
- <string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# widget}other{# widgets}}"</string>
- <string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{# snelkoppeling}other{# snelkoppelingen}}"</string>
- <string name="widgets_and_shortcuts_count" msgid="7209136747878365116">"<xliff:g id="WIDGETS_COUNT">%1$s</xliff:g>, <xliff:g id="SHORTCUTS_COUNT">%2$s</xliff:g>"</string>
- <string name="widget_button_text" msgid="2880537293434387943">"Widgets"</string>
- <string name="widgets_full_sheet_search_bar_hint" msgid="8484659090860596457">"Zoeken"</string>
- <string name="widgets_full_sheet_cancel_button_description" msgid="5766167035728653605">"Tekst in zoekvak wissen"</string>
- <string name="no_widgets_available" msgid="4337693382501046170">"Widgets en snelkoppelingen zijn niet beschikbaar"</string>
- <string name="no_search_results" msgid="3787956167293097509">"Geen widgets of snelkoppelingen gevonden"</string>
- <string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Persoonlijk"</string>
- <string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Werk"</string>
- <string name="widget_category_conversations" msgid="8894438636213590446">"Gesprekken"</string>
- <string name="widget_education_header" msgid="4874760613775913787">"Nuttige informatie binnen handbereik"</string>
- <string name="widget_education_content" msgid="745542879510751525">"Als je informatie wilt krijgen zonder apps te openen, kun je widgets toevoegen aan je startscherm"</string>
- <string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Tik om de widgetinstellingen te wijzigen"</string>
- <string name="widget_education_close_button" msgid="8676165703104836580">"OK"</string>
- <string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Widgetinstellingen wijzigen"</string>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Tik en houd vast om handmatig te plaatsen"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"Automatisch toevoegen"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Apps zoeken"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Apps laden…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"Er zijn geen apps gevonden die overeenkomen met \'<xliff:g id="QUERY">%1$s</xliff:g>\'"</string>
<string name="all_apps_search_market_message" msgid="1366263386197059176">"Zoeken naar meer apps"</string>
<string name="label_application" msgid="8531721983832654978">"App"</string>
- <string name="all_apps_label" msgid="5015784846527570951">"Alle apps"</string>
<string name="notifications_header" msgid="1404149926117359025">"Meldingen"</string>
- <string name="long_press_shortcut_to_add" msgid="5405328730817637737">"Tik en houd vast om een snelkoppeling te verplaatsen."</string>
- <string name="long_accessible_way_to_add_shortcut" msgid="2199537273817090740">"Dubbeltik en houd vast om een snelkoppeling te verplaatsen of aangepaste acties te gebruiken."</string>
- <string name="out_of_space" msgid="6692471482459245734">"Er is geen ruimte op dit startscherm"</string>
+ <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"Tik en houd vast om snelkoppeling toe te voegen."</string>
+ <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"Dubbeltik en houd vast om een snelkoppeling toe te voegen of aangepaste acties te gebruiken."</string>
+ <string name="out_of_space" msgid="4691004494942118364">"Er is geen ruimte meer op dit startscherm."</string>
<string name="hotseat_out_of_space" msgid="7448809638125333693">"Geen ruimte meer in het vak \'Favorieten\'"</string>
<string name="all_apps_button_label" msgid="8130441508702294465">"Lijst met apps"</string>
- <string name="all_apps_search_results" msgid="5889367432531296759">"Zoekresultaten"</string>
<string name="all_apps_button_personal_label" msgid="1315764287305224468">"Lijst met persoonlijke apps"</string>
<string name="all_apps_button_work_label" msgid="7270707118948892488">"Lijst met werk-apps"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"Homepage"</string>
<string name="remove_drop_target_label" msgid="7812859488053230776">"Verwijderen"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"Deïnstalleren"</string>
<string name="app_info_drop_target_label" msgid="692894985365717661">"App-info"</string>
<string name="install_drop_target_label" msgid="2539096853673231757">"Installeren"</string>
- <string name="dismiss_prediction_label" msgid="3357562989568808658">"Geen app voorstellen"</string>
- <string name="pin_prediction" msgid="4196423321649756498">"Vastzetvoorspelling"</string>
<string name="permlab_install_shortcut" msgid="5632423390354674437">"Snelle links instellen"</string>
<string name="permdesc_install_shortcut" msgid="923466509822011139">"Een app toestaan snelkoppelingen toe te voegen zonder tussenkomst van de gebruiker."</string>
<string name="permlab_read_settings" msgid="1941457408239617576">"instellingen en snelkoppelingen op startscherm lezen"</string>
@@ -84,13 +60,15 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"instellingen en snelkoppelingen op startscherm zetten"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"De app toestaan de instellingen en snelkoppelingen op de homepage te wijzigen."</string>
<string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> mag niet bellen"</string>
- <string name="gadget_error_text" msgid="740356548025791839">"Kan widget niet laden"</string>
- <string name="gadget_setup_text" msgid="8348374825537681407">"Widgetinstellingen"</string>
- <string name="gadget_complete_setup_text" msgid="309040266978007925">"Tik om instellen af te ronden"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"Probleem bij het laden van widget"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"Configuratie"</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"Dit is een systeemapp die niet kan worden verwijderd."</string>
- <string name="folder_hint_text" msgid="5174843001373488816">"Naam bewerken"</string>
- <string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> staat uit"</string>
- <string name="dotted_app_label" msgid="1704091277755818896">"{count,plural,offset:1 =1{{app_name} heeft # melding}other{{app_name} heeft # meldingen}}"</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"Naamloze map"</string>
+ <string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> is uitgeschakeld"</string>
+ <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+ <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, heeft <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> meldingen</item>
+ <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g>, heeft <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> melding</item>
+ </plurals>
<string name="default_scroll_format" msgid="7475544710230993317">"Pagina %1$d van %2$d"</string>
<string name="workspace_scroll_format" msgid="8458889198184077399">"Startscherm %1$d van %2$d"</string>
<string name="workspace_new_page" msgid="257366611030256142">"Nieuwe startschermpagina"</string>
@@ -99,31 +77,31 @@
<string name="folder_tap_to_rename" msgid="4017685068016979677">"Tik om de gewijzigde naam op te slaan"</string>
<string name="folder_closed" msgid="4100806530910930934">"Map gesloten"</string>
<string name="folder_renamed" msgid="1794088362165669656">"De naam van de map is gewijzigd in <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="folder_name_format_exact" msgid="8626242716117004803">"Map: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> items"</string>
- <string name="folder_name_format_overflow" msgid="4270108890534995199">"Map: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> of meer items"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"Map: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"Widgets"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Achtergrond"</string>
- <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Achtergrond en stijl"</string>
- <string name="settings_button_text" msgid="8873672322605444408">"Instellingen start"</string>
- <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Uitgezet door je beheerder"</string>
+ <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Stijl en achtergrond"</string>
+ <string name="settings_button_text" msgid="8873672322605444408">"Instellingen startscherm"</string>
+ <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Uitgeschakeld door je beheerder"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Draaien van startscherm toestaan"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Wanneer de telefoon gedraaid is"</string>
<string name="notification_dots_title" msgid="9062440428204120317">"Meldingsstipjes"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"Aan"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"Uit"</string>
<string name="title_missing_notification_access" msgid="7503287056163941064">"Toegang tot meldingen vereist"</string>
- <string name="msg_missing_notification_access" msgid="281113995110910548">"Als je meldingsstipjes wilt tonen, zet je app-meldingen aan voor <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="msg_missing_notification_access" msgid="281113995110910548">"Als je meldingsstipjes wilt weergeven, schakel je app-meldingen in voor <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="title_change_settings" msgid="1376365968844349552">"Instellingen wijzigen"</string>
- <string name="notification_dots_service_title" msgid="4284221181793592871">"Toon meldingsstipjes"</string>
- <string name="auto_add_shortcuts_label" msgid="3698776050751790653">"App-iconen toevoegen aan startscherm"</string>
+ <string name="notification_dots_service_title" msgid="4284221181793592871">"Meldingsstipjes weergeven"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Pictogram toevoegen aan startscherm"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Voor nieuwe apps"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"Onbekend"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"Verwijderen"</string>
<string name="abandoned_search" msgid="891119232568284442">"Zoeken"</string>
<string name="abandoned_promises_title" msgid="7096178467971716750">"Deze app is niet geïnstalleerd"</string>
- <string name="abandoned_promise_explanation" msgid="3990027586878167529">"De app voor dit icoon is niet geïnstalleerd. Je kunt het icoon verwijderen of de app zoeken en handmatig installeren."</string>
- <string name="app_installing_title" msgid="5864044122733792085">"<xliff:g id="NAME">%1$s</xliff:g> installeren, <xliff:g id="PROGRESS">%2$s</xliff:g> voltooid"</string>
+ <string name="abandoned_promise_explanation" msgid="3990027586878167529">"De app voor dit pictogram is niet geïnstalleerd. Je kunt het pictogram verwijderen of de app zoeken en handmatig installeren."</string>
<string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> wordt gedownload, <xliff:g id="PROGRESS">%2$s</xliff:g> voltooid"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> wacht op installatie"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"<xliff:g id="NAME">%1$s</xliff:g>-widgets"</string>
<string name="widgets_list" msgid="796804551140113767">"Lijst met widgets"</string>
<string name="widgets_list_closed" msgid="6141506579418771922">"Lijst met widgets gesloten"</string>
<string name="action_add_to_workspace" msgid="8902165848117513641">"Toevoegen aan startscherm"</string>
@@ -151,20 +129,15 @@
<string name="action_deep_shortcut" msgid="2864038805849372848">"Snelkoppelingen"</string>
<string name="shortcuts_menu_with_notifications_description" msgid="2676582286544232849">"Snelkoppelingen en meldingen"</string>
<string name="action_dismiss_notification" msgid="5909461085055959187">"Sluiten"</string>
- <string name="accessibility_close" msgid="2277148124685870734">"Sluiten"</string>
<string name="notification_dismissed" msgid="6002233469409822874">"Melding gesloten"</string>
<string name="all_apps_personal_tab" msgid="4190252696685155002">"Privé"</string>
<string name="all_apps_work_tab" msgid="4884822796154055118">"Werk"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"Werkprofiel"</string>
- <string name="work_profile_edu_work_apps" msgid="7895468576497746520">"Werk-apps hebben badges en zijn zichtbaar voor je IT-beheerder"</string>
- <string name="work_profile_edu_accept" msgid="6069788082535149071">"OK"</string>
- <string name="work_apps_paused_title" msgid="3040901117349444598">"Werk-apps zijn onderbroken"</string>
- <string name="work_apps_paused_body" msgid="261634750995824906">"Je werk-apps kunnen je geen meldingen sturen, je batterij niet gebruiken en geen toegang krijgen tot je locatie"</string>
- <string name="work_apps_paused_content_description" msgid="5149623040804051095">"Werk-apps staan uit. Je werk-apps kunnen geen meldingen sturen, je batterij niet gebruiken en hebben geen toegang tot je locatie."</string>
- <string name="work_apps_paused_edu_banner" msgid="8872412121608402058">"Werk-apps hebben badges en zijn zichtbaar voor je IT-beheerder"</string>
- <string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"OK"</string>
- <string name="work_apps_pause_btn_text" msgid="1921059713673767460">"Werk-apps uitzetten"</string>
- <string name="work_apps_enable_btn_text" msgid="1156432622148413741">"Werk-apps aanzetten"</string>
- <string name="developer_options_filter_hint" msgid="5896817443635989056">"Filteren"</string>
+ <string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"Zoek hier naar werk-apps"</string>
+ <string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"Elke werk-app heeft een badge en wordt beveiligd door je organisatie. Verplaats apps naar je startscherm voor snelle toegang."</string>
+ <string name="work_mode_on_label" msgid="4781128097185272916">"Beheerd door je organisatie"</string>
+ <string name="work_mode_off_label" msgid="3194894777601421047">"Meldingen en apps zijn uitgeschakeld"</string>
+ <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Sluiten"</string>
+ <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Gesloten"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Mislukt: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
</resources>
diff --git a/res/values-or/strings.xml b/res/values-or/strings.xml
index 1149e021d8..4ddc903474 100644
--- a/res/values-or/strings.xml
+++ b/res/values-or/strings.xml
@@ -20,77 +20,55 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="649227358658669779">"ଲଞ୍ଚର୍3"</string>
- <string name="work_folder_name" msgid="3753320833950115786">"ୱାର୍କ"</string>
+ <string name="folder_name" msgid="7371454440695724752"></string>
+ <string name="work_folder_name" msgid="3753320833950115786">"କାମ"</string>
<string name="activity_not_found" msgid="8071924732094499514">"ଆପ୍‌ ଇନଷ୍ଟଲ୍‌ ହୋଇନାହିଁ"</string>
<string name="activity_not_available" msgid="7456344436509528827">"ଆପ୍‌ ଉପଲବ୍ଧ ନାହିଁ"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"ନିରାପଦ ମୋଡରେ ଡାଉନଲୋଡ୍‌ ହେଇଥିବା ଆପ୍‌ ଅକ୍ଷମ କରାଗଲା"</string>
<string name="safemode_widget_error" msgid="4863470563535682004">"ନିରାପଦ ମୋଡରେ ୱିଜେଟ୍‌ ଅକ୍ଷମ କରାଗଲା"</string>
<string name="shortcut_not_available" msgid="2536503539825726397">"ଶର୍ଟକଟ୍‌ ଉପଲବ୍ଧ ନାହିଁ"</string>
- <string name="home_screen" msgid="5629429142036709174">"ମୂଳପୃଷ୍ଠା"</string>
- <string name="recent_task_option_split_screen" msgid="6690461455618725183">"ସ୍କ୍ରିନ‌କୁ ସ୍ପ୍ଲିଟ୍ କରନ୍ତୁ"</string>
- <string name="split_screen_position_top" msgid="1504965011158689649">"ଶୀର୍ଷକୁ ସ୍ପ୍ଲିଟ କରନ୍ତୁ"</string>
- <string name="split_screen_position_left" msgid="7537793098851830883">"ବାମପତକୁ ସ୍ପ୍ଲିଟ କରନ୍ତୁ"</string>
- <string name="split_screen_position_right" msgid="1569377524925193369">"ଡାହାଣପଟକୁ ସ୍ପ୍ଲିଟ କରନ୍ତୁ"</string>
- <string name="split_app_info_accessibility" msgid="5475288491241414932">"%1$s ପାଇଁ ଆପ ସୂଚନା"</string>
- <string name="long_press_widget_to_add" msgid="3587712543577675817">"ଏକ ୱିଜେଟକୁ ମୁଭ୍ କରିବା ପାଇଁ ସ୍ପର୍ଶ କରି ଧରି ରଖନ୍ତୁ।"</string>
- <string name="long_accessible_way_to_add" msgid="2733588281439571974">"ଏକ ୱିଜେଟକୁ ମୁଭ୍ କରିବା ପାଇଁ ଦୁଇଥର-ଟାପ୍ କରି ଧରି ରଖନ୍ତୁ କିମ୍ବା କଷ୍ଟମ୍ କାର୍ଯ୍ୟଗୁଡ଼ିକୁ ବ୍ୟବହାର କରନ୍ତୁ।"</string>
+ <string name="home_screen" msgid="806512411299847073">"ହୋମ୍‌ ସ୍କ୍ରୀନ୍‌"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"କାର୍ଯ୍ୟ କଷ୍ଟମ୍ କରନ୍ତୁ"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"ୱିଜେଟ୍‌ ନେବାକୁ ସ୍ପର୍ଶ କରନ୍ତୁ ଏବଂ ଧରି ରଖନ୍ତୁ।"</string>
+ <string name="long_accessible_way_to_add" msgid="4289502106628154155">"ଡବଲ୍‌-ଟାପ୍‌ କରନ୍ତୁ ଏବଂ ଏକ ୱିଜେଟ୍‌ ନେବାକୁ ଧରି ରଖନ୍ତୁ କିମ୍ୱା କଷ୍ଟମ୍ କାର୍ଯ୍ୟପ୍ରକ୍ରିୟା ବ୍ୟବହାର କରନ୍ତୁ।"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d ଓସାର ଓ %2$d ଉଚ୍ଚ"</string>
- <string name="widget_preview_context_description" msgid="9045841361655787574">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g> ୱିଜେଟ୍"</string>
- <string name="add_item_request_drag_hint" msgid="5653291305078645405">"ମୂଳସ୍କ୍ରିନର ଆଖପାଖରେ ୱିଜେଟକୁ ମୁଭ୍ କରିବା ପାଇଁ ଏହାକୁ ସ୍ପର୍ଶ କରି ଧରି ରଖନ୍ତୁ"</string>
- <string name="add_to_home_screen" msgid="8631549138215492708">"ମୂଳସ୍କ୍ରିନରେ ଯୋଗ କରନ୍ତୁ"</string>
- <string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g>ର ୱିଜେଟ୍ ମୂଳସ୍କ୍ରିନରେ ଯୋଡ଼ାଗଲା"</string>
- <string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{#ଟି ୱିଜେଟ୍}other{#ଟି ୱିଜେଟ୍}}"</string>
- <string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{#ଟି ସର୍ଟକଟ୍}other{#ଟି ସର୍ଟକଟ୍}}"</string>
- <string name="widgets_and_shortcuts_count" msgid="7209136747878365116">"<xliff:g id="WIDGETS_COUNT">%1$s</xliff:g>, <xliff:g id="SHORTCUTS_COUNT">%2$s</xliff:g>"</string>
- <string name="widget_button_text" msgid="2880537293434387943">"ୱିଜେଟ୍‌"</string>
- <string name="widgets_full_sheet_search_bar_hint" msgid="8484659090860596457">"ସନ୍ଧାନ କରନ୍ତୁ"</string>
- <string name="widgets_full_sheet_cancel_button_description" msgid="5766167035728653605">"ସନ୍ଧାନ ବାକ୍ସରୁ ଟେକ୍ସଟ୍ ଖାଲି କରନ୍ତୁ"</string>
- <string name="no_widgets_available" msgid="4337693382501046170">"ୱିଜେଟ୍ ଏବଂ ସର୍ଟକଟଗୁଡ଼ିକ ଉପଲବ୍ଧ ନାହିଁ"</string>
- <string name="no_search_results" msgid="3787956167293097509">"କୌଣସି ୱିଜେଟ୍ କିମ୍ବା ସର୍ଟକଟ୍ ମିଳିଲା ନାହିଁ"</string>
- <string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"ବ୍ୟକ୍ତିଗତ"</string>
- <string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"ୱାର୍କ"</string>
- <string name="widget_category_conversations" msgid="8894438636213590446">"ବାର୍ତ୍ତାଳାପଗୁଡ଼ିକ"</string>
- <string name="widget_education_header" msgid="4874760613775913787">"ଉପଯୋଗୀ ସୂଚନା ଆପଣଙ୍କ ପାଖରେ ସହଜରେ ଉପଲବ୍ଧ"</string>
- <string name="widget_education_content" msgid="745542879510751525">"ଆପଗୁଡ଼ିକୁ ନଖୋଲି ସୂଚନା ପାଇବା ପାଇଁ, ଆପଣ ଆପଣଙ୍କ ମୂଳସ୍କ୍ରିନରେ ୱିଜେଟଗୁଡ଼ିକୁ ଯୋଗ କରିପାରିବେ"</string>
- <string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"ୱିଜେଟ୍ ସେଟିଂସ୍ ପରିବର୍ତ୍ତନ କରିବାକୁ ଟାପ୍ କରନ୍ତୁ"</string>
- <string name="widget_education_close_button" msgid="8676165703104836580">"ବୁଝିଗଲି"</string>
- <string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"ୱିଜେଟ୍ ସେଟିଂସ୍ ପରିବର୍ତ୍ତନ କରନ୍ତୁ"</string>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"ମାନୁଆଲ୍‌ ଭାବରେ ରଖିବାକୁ ସ୍ପର୍ଶ କରନ୍ତୁ ଏବଂ ଧରି ରଖନ୍ତୁ"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"ସ୍ୱଚାଳିତ ଭାବେ ଯୋଡ଼ନ୍ତୁ"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"ଆପ୍‌ ଖୋଜନ୍ତୁ"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"ଆପ୍‌ ଲୋଡ୍‌ ହେଉଛି..."</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" ସହିତ ମେଳ ହେଉଥିବା କୌଣସି ଆପ୍‌ ମିଳିଲା ନାହିଁ"</string>
<string name="all_apps_search_market_message" msgid="1366263386197059176">"ଅଧିକ ଆପ୍‌ ଖୋଜନ୍ତୁ"</string>
<string name="label_application" msgid="8531721983832654978">"ଆପ୍"</string>
- <string name="all_apps_label" msgid="5015784846527570951">"ସବୁ ଆପ"</string>
<string name="notifications_header" msgid="1404149926117359025">"ବିଜ୍ଞପ୍ତି"</string>
- <string name="long_press_shortcut_to_add" msgid="5405328730817637737">"ଏକ ସର୍ଟକଟକୁ ମୁଭ୍ କରିବା ପାଇଁ ସ୍ପର୍ଶ କରି ଧରି ରଖନ୍ତୁ।"</string>
- <string name="long_accessible_way_to_add_shortcut" msgid="2199537273817090740">"ଏକ ସର୍ଟକଟକୁ ମୁଭ୍ କରିବା ପାଇଁ ଦୁଇଥର-ଟାପ୍ କରି ଧରି ରଖନ୍ତୁ କିମ୍ବା କଷ୍ଟମ୍ କାର୍ଯ୍ୟଗୁଡ଼ିକୁ ବ୍ୟବହାର କରନ୍ତୁ।"</string>
- <string name="out_of_space" msgid="6692471482459245734">"ଏହି ମୂଳସ୍କ୍ରିନରେ ଆଉ ଜାଗା ନାହିଁ"</string>
+ <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"ଏକ ଶର୍ଟକଟ୍ ଚୟନ କରିବାକୁ ସ୍ପର୍ଶ କରି ଧରି ରଖନ୍ତୁ।"</string>
+ <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"ଡବଲ୍‌-ଟାପ୍‌ କରନ୍ତୁ ଏବଂ ଏକ ଶର୍ଟକଟ୍ ଚୟନ କରିବାକୁ ଧରି ରଖନ୍ତୁ କିମ୍ୱା କଷ୍ଟମ୍ ପ୍ରକ୍ରିୟା ବ୍ୟବହାର କରନ୍ତୁ।"</string>
+ <string name="out_of_space" msgid="4691004494942118364">"ହୋମ୍‌ ସ୍କ୍ରୀନ ପାଇଁ ଆଉ କୋଠରୀ ନାହିଁ"</string>
<string name="hotseat_out_of_space" msgid="7448809638125333693">"ମନପସନ୍ଦ ଟ୍ରେରେ ଆଉ କୋଠରୀ ନାହିଁ"</string>
<string name="all_apps_button_label" msgid="8130441508702294465">"ଆପ୍‌ ତାଲିକା"</string>
- <string name="all_apps_search_results" msgid="5889367432531296759">"ସନ୍ଧାନ ଫଳାଫଳ"</string>
<string name="all_apps_button_personal_label" msgid="1315764287305224468">"ବ୍ୟକ୍ତିଗତ ଆପ୍ ତାଲିକା"</string>
<string name="all_apps_button_work_label" msgid="7270707118948892488">"କାର୍ଯ୍ୟକାରୀ ଆପ୍‌ ତାଲିକା"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"ହୋମ୍"</string>
<string name="remove_drop_target_label" msgid="7812859488053230776">"ବାହାର କରନ୍ତୁ"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"ଅନଇନଷ୍ଟଲ୍‌ କରନ୍ତୁ"</string>
<string name="app_info_drop_target_label" msgid="692894985365717661">"ଆପ୍‌ ସୂଚନା"</string>
<string name="install_drop_target_label" msgid="2539096853673231757">"ଇନଷ୍ଟଲ୍‌ କରନ୍ତୁ"</string>
- <string name="dismiss_prediction_label" msgid="3357562989568808658">"ଆପ୍ ପରାମର୍ଶ ଦିଅନ୍ତୁ ନାହିଁ"</string>
- <string name="pin_prediction" msgid="4196423321649756498">"ପୂର୍ବାନୁମାନକୁ ପିନ୍ କରନ୍ତୁ"</string>
- <string name="permlab_install_shortcut" msgid="5632423390354674437">"ସର୍ଟକଟ୍‍ ଇନଷ୍ଟଲ୍‌ କରନ୍ତୁ"</string>
+ <string name="permlab_install_shortcut" msgid="5632423390354674437">"ଶର୍ଟକଟ୍‍ ଇନଷ୍ଟଲ୍‌ କରନ୍ତୁ"</string>
<string name="permdesc_install_shortcut" msgid="923466509822011139">"ୟୁଜରଙ୍କ ବିନା ହସ୍ତକ୍ଷେପରେ ଶର୍ଟକଟ୍‌ ଯୋଡ଼ିବାକୁ ଆପକୁ ଅନୁମତି ଦିଏ।"</string>
<string name="permlab_read_settings" msgid="1941457408239617576">"ହୋମ୍‌ ସେଟିଙ୍ଗ ଏବଂ ଶର୍ଟକଟ୍‌ ପଢ଼ନ୍ତୁ"</string>
<string name="permdesc_read_settings" msgid="5833423719057558387">"ହୋମରେ ସେଟିଙ୍ଗ ପଢ଼ିବାକୁ ଆପ ଏବଂ ଶର୍ଟକଟକୁ ଅନୁମତି ଦିଏ।"</string>
<string name="permlab_write_settings" msgid="3574213698004620587">"ହୋମ୍‌ ସେଟିଙ୍ଗ ଏବଂ ଶର୍ଟକଟ୍‌ ଲେଖନ୍ତୁ"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"ହୋମରେ ସେଟିଙ୍ଗ ଏବଂ ଶର୍ଟକଟ୍‌ ପରିବର୍ତ୍ତନ କରିବାକୁ ଆପକୁ ଅନୁମତି ଦିଏ।"</string>
<string name="msg_no_phone_permission" msgid="9208659281529857371">"ଫୋନ୍‌ କଲ୍‌ କରିବାକୁ <xliff:g id="APP_NAME">%1$s</xliff:g>କୁ ଅନୁମତି ଦିଆଯାଇ ନାହିଁ"</string>
- <string name="gadget_error_text" msgid="740356548025791839">"ୱିଜେଟ୍ ଲୋଡ୍ କରାଯାଇପାରିବ ନାହିଁ"</string>
- <string name="gadget_setup_text" msgid="8348374825537681407">"ୱିଜେଟ ସେଟିଂସ"</string>
- <string name="gadget_complete_setup_text" msgid="309040266978007925">"ସେଟଅପ ସମ୍ପୂର୍ଣ୍ଣ କରିବାକୁ ଟାପ କରନ୍ତୁ"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"ୱିଜେଟ୍‌ ଲୋଡ୍‌ ହେବାରେ ସମସ୍ୟା ଅଛି"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"ସେଟ୍ ଅପ୍ କରନ୍ତୁ"</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"ଏହା ଏକ ସିଷ୍ଟମ୍‌ ଆପ୍‌ ଅଟେ ଏବଂ ଏହା ଅନଇନଷ୍ଟଲ୍‌ କରାଯାଇ ପାରିବ ନାହିଁ।"</string>
- <string name="folder_hint_text" msgid="5174843001373488816">"ନାମ ସମ୍ପାଦନ କରନ୍ତୁ"</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"ବେନାମୀ ଫୋଲ୍ଡର୍‌"</string>
<string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> ଅକ୍ଷମ କରାଗଲା"</string>
- <string name="dotted_app_label" msgid="1704091277755818896">"{count,plural,offset:1 =1{{app_name}ର #ଟି ବିଜ୍ଞପ୍ତି ରହିଛି}other{{app_name}ର #ଟି ବିଜ୍ଞପ୍ତି ରହିଛି}}"</string>
+ <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+ <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g>ଟି ବିଜ୍ଞପ୍ତି ରହିଛି</item>
+ <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g>, <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g>ଟି ବିଜ୍ଞପ୍ତି ରହିଛି</item>
+ </plurals>
<string name="default_scroll_format" msgid="7475544710230993317">"ମୋଟ %2$dରୁ %1$d ନମ୍ବର ପୃଷ୍ଠା"</string>
<string name="workspace_scroll_format" msgid="8458889198184077399">"%2$dରୁ %1$d ହୋମ୍‌ ସ୍କ୍ରୀନ୍"</string>
<string name="workspace_new_page" msgid="257366611030256142">"ନୂଆ ହୋମ୍‌ ସ୍କ୍ରୀନ୍‌ ପୃଷ୍ଠା"</string>
@@ -99,37 +77,37 @@
<string name="folder_tap_to_rename" msgid="4017685068016979677">"ନାମ ବଦଳାଇବା ସେଭ୍ କରିବାକୁ ଟାପ୍‌ କରନ୍ତୁ"</string>
<string name="folder_closed" msgid="4100806530910930934">"ଫୋଲ୍ଡର ବନ୍ଦ କରାଗଲା"</string>
<string name="folder_renamed" msgid="1794088362165669656">"ଫୋଲ୍ଡରର ନାମ <xliff:g id="NAME">%1$s</xliff:g>କୁ ବଦଳାଗଲା"</string>
- <string name="folder_name_format_exact" msgid="8626242716117004803">"ଫୋଲ୍ଡର୍: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> ଆଇଟମଗୁଡ଼ିକ"</string>
- <string name="folder_name_format_overflow" msgid="4270108890534995199">"ଫୋଲ୍ଡର୍: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> କିମ୍ବା ଅଧିକ ଆଇଟମ୍"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"ଫୋଲ୍ଡର: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"ୱିଜେଟ୍‌"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"ୱାଲପେପର୍‌"</string>
- <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"ୱାଲପେପର୍ ଏବଂ ଷ୍ଟାଇଲ୍"</string>
- <string name="settings_button_text" msgid="8873672322605444408">"ହୋମ୍‌ ସେଟିଂସ୍"</string>
+ <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"ଶୈଳୀ ଏବଂ ୱାଲ୍‍‍ପେପର୍"</string>
+ <string name="settings_button_text" msgid="8873672322605444408">"ହୋମ୍‌ ସେଟିଙ୍ଗ"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"ଆପଣଙ୍କ ଆଡମିନଙ୍କ ଦ୍ୱାରା ଅକ୍ଷମ କରାଯାଇଛି"</string>
- <string name="allow_rotation_title" msgid="7728578836261442095">"ହୋମ୍‌ ସ୍କ୍ରିନ୍ ବୁଲାଇବାକୁ ଅନୁମତି ଦିଅନ୍ତୁ"</string>
+ <string name="allow_rotation_title" msgid="7728578836261442095">"ହୋମ୍‌ ସ୍କ୍ରୀନ୍ ବୁଲାଇବା ଅନୁମତି ଦିଅନ୍ତୁ"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"ଯେତେବେଳେ ଫୋନକୁ ବୁଲାଯାଇଥାଏ"</string>
- <string name="notification_dots_title" msgid="9062440428204120317">"ବିଜ୍ଞପ୍ତି ଡଟ୍ସ"</string>
- <string name="notification_dots_desc_on" msgid="1679848116452218908">"ଚାଲୁ"</string>
+ <string name="notification_dots_title" msgid="9062440428204120317">"ବିଜ୍ଞପ୍ତି ବିନ୍ଦୁଗୁଡ଼ିକ"</string>
+ <string name="notification_dots_desc_on" msgid="1679848116452218908">"ଚାଲୁ କରନ୍ତୁ"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"ବନ୍ଦ କରନ୍ତୁ"</string>
<string name="title_missing_notification_access" msgid="7503287056163941064">"ବିଜ୍ଞପ୍ତି ଆକ୍ସେସ୍‌ ଆବଶ୍ୟକ ଅଟେ"</string>
<string name="msg_missing_notification_access" msgid="281113995110910548">"ବିଜ୍ଞପ୍ତି ବିନ୍ଦୁ ଦେଖାଇବାକୁ, <xliff:g id="NAME">%1$s</xliff:g> ପାଇଁ ଆପ୍‌ ବିଜ୍ଞପ୍ତି ଅନ୍‌ କରନ୍ତୁ"</string>
- <string name="title_change_settings" msgid="1376365968844349552">"ସେଟିଂସ୍ ପରିବର୍ତ୍ତନ କରନ୍ତୁ"</string>
+ <string name="title_change_settings" msgid="1376365968844349552">"ସେଟିଙ୍ଗ ପରିବର୍ତ୍ତନ କରନ୍ତୁ"</string>
<string name="notification_dots_service_title" msgid="4284221181793592871">"ବିଜ୍ଞପ୍ତି ଡଟ୍‌ଗୁଡ଼ିକୁ ଦେଖାନ୍ତୁ"</string>
- <string name="auto_add_shortcuts_label" msgid="3698776050751790653">"ହୋମ୍ ସ୍କ୍ରିନରେ ଆପ୍ ଆଇକନଗୁଡ଼ିକୁ ଯୋଗ କରନ୍ତୁ"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"ହୋମ୍‌ ସ୍କ୍ରୀନରେ ଆଇକନ୍‌କୁ ଯୋଡ଼ନ୍ତୁ"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"ନୂଆ ଆପ୍‌ ପାଇଁ"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"ଅଜଣା"</string>
- <string name="abandoned_clean_this" msgid="7610119707847920412">"କାଢ଼ି ଦିଅନ୍ତୁ"</string>
- <string name="abandoned_search" msgid="891119232568284442">"ସନ୍ଧାନ କରନ୍ତୁ"</string>
+ <string name="abandoned_clean_this" msgid="7610119707847920412">"ବାହାର କରନ୍ତୁ"</string>
+ <string name="abandoned_search" msgid="891119232568284442">"ସର୍ଚ୍ଚ କରନ୍ତୁ"</string>
<string name="abandoned_promises_title" msgid="7096178467971716750">"ଏହି ଆପ୍‌ ଇନଷ୍ଟଲ୍‌ ହୋଇନାହିଁ"</string>
<string name="abandoned_promise_explanation" msgid="3990027586878167529">"ଏହି ଆଇକନ୍‌ ପାଇଁ ଆପ୍‌ ଇନଷ୍ଟଲ୍‌ ହୋଇନାହିଁ। ଏହାକୁ ଆପଣ ଆପ୍‌ ପାଇଁ ବାହାର କରିପାରିବେ କିମ୍ୱା ସର୍ଚ୍ଚ କରି ପାରିବେ ଏବଂ ଏହାକୁ ମାନୁଆଲ୍‌ ଭାବରେ ଇନଷ୍ଟଲ୍‌ କରିପାରିବେ।"</string>
- <string name="app_installing_title" msgid="5864044122733792085">"<xliff:g id="NAME">%1$s</xliff:g> ଇନଷ୍ଟଲ୍ କରାଯାଉଛି, <xliff:g id="PROGRESS">%2$s</xliff:g> ସମ୍ପୂର୍ଣ୍ଣ ହୋଇଛି"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> ଡାଉନଲୋଡ୍‌ ହେଉଛି, <xliff:g id="PROGRESS">%2$s</xliff:g> ସମ୍ପୂର୍ଣ୍ଣ"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> ଇନଷ୍ଟଲ୍‌ ହେବାକୁ ଅପେକ୍ଷା କରିଛି"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"<xliff:g id="NAME">%1$s</xliff:g> ୱିଜେଟ୍‌"</string>
<string name="widgets_list" msgid="796804551140113767">"ୱିଜେଟ୍ ତାଲିକା"</string>
<string name="widgets_list_closed" msgid="6141506579418771922">"ୱିଜେଟ୍ ତାଲିକା ବନ୍ଦ ହୋଇଛି"</string>
<string name="action_add_to_workspace" msgid="8902165848117513641">"ହୋମ୍‌ ସ୍କ୍ରୀନରେ ଯୋଡ଼ନ୍ତୁ"</string>
<string name="action_move_here" msgid="2170188780612570250">"ଆଇଟମ୍‌କୁ ଏଠାକୁ ଘୁଞ୍ଚାନ୍ତୁ"</string>
<string name="item_added_to_workspace" msgid="4211073925752213539">"ହୋମ୍‌ ସ୍କ୍ରୀନରେ ଆଇଟମ୍‌ ଯୋଡ଼ାଗଲା"</string>
- <string name="item_removed" msgid="851119963877842327">"ଆଇଟମକୁ କାଢ଼ି ଦିଆଯାଇଛି"</string>
+ <string name="item_removed" msgid="851119963877842327">"ଆଇଟମ୍‌ ବାହାର କରାଗଲା"</string>
<string name="undo" msgid="4151576204245173321">"ପୂର୍ବବତ୍‍"</string>
<string name="action_move" msgid="4339390619886385032">"ଆଇଟମ୍‌ ଘୁଞ୍ଚାନ୍ତୁ"</string>
<string name="move_to_empty_cell" msgid="2833711483015685619">"ଧାଡ଼ି <xliff:g id="NUMBER_0">%1$s</xliff:g> ସ୍ତମ୍ଭ <xliff:g id="NUMBER_1">%2$s</xliff:g>କୁ ନିଅନ୍ତୁ"</string>
@@ -151,20 +129,15 @@
<string name="action_deep_shortcut" msgid="2864038805849372848">"ଶର୍ଟକଟ୍‍"</string>
<string name="shortcuts_menu_with_notifications_description" msgid="2676582286544232849">"ଶର୍ଟକଟ୍ ଓ ବିଜ୍ଞପ୍ତି"</string>
<string name="action_dismiss_notification" msgid="5909461085055959187">"ଖାରଜ କରନ୍ତୁ"</string>
- <string name="accessibility_close" msgid="2277148124685870734">"ବନ୍ଦ କରନ୍ତୁ"</string>
<string name="notification_dismissed" msgid="6002233469409822874">"ବିଜ୍ଞପ୍ତି ଖାରଜ କରାଗଲା"</string>
<string name="all_apps_personal_tab" msgid="4190252696685155002">"ବ୍ୟକ୍ତିଗତ"</string>
- <string name="all_apps_work_tab" msgid="4884822796154055118">"ୱାର୍କ"</string>
+ <string name="all_apps_work_tab" msgid="4884822796154055118">"କାମ"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"ୱର୍କ ପ୍ରୋଫାଇଲ୍‌"</string>
- <string name="work_profile_edu_work_apps" msgid="7895468576497746520">"ୱାର୍କ ଆପଗୁଡ଼ିକୁ ବ୍ୟାଜ୍ କରାଯାଇଛି ଏବଂ ସେଗୁଡ଼ିକ ଆପଣଙ୍କ IT ଆଡମିନଙ୍କୁ ଦୃଶ୍ୟମାନ ହେଉଛି"</string>
- <string name="work_profile_edu_accept" msgid="6069788082535149071">"ବୁଝିଗଲି"</string>
- <string name="work_apps_paused_title" msgid="3040901117349444598">"ୱାର୍କ ଆପ୍ସ ବିରତ କରାଯାଇଛି"</string>
- <string name="work_apps_paused_body" msgid="261634750995824906">"ଆପଣଙ୍କ ୱାର୍କ ଆପଗୁଡ଼ିକ ଆପଣଙ୍କୁ ବିଜ୍ଞପ୍ତି ପଠାଇପାରିବ ନାହିଁ, ଆପଣଙ୍କ ବ୍ୟାଟେରୀକୁ ବ୍ୟବହାର କରିପାରିବ ନାହିଁ କିମ୍ବା ଆପଣଙ୍କର ଲୋକେସନକୁ ଆକ୍ସେସ୍ କରିପାରିବ ନାହିଁ"</string>
- <string name="work_apps_paused_content_description" msgid="5149623040804051095">"ୱାର୍କ ଆପଗୁଡ଼ିକ ବନ୍ଦ ଅଛି। ଆପଣଙ୍କ ୱାର୍କ ଆପଗୁଡ଼ିକ ଆପଣଙ୍କୁ ବିଜ୍ଞପ୍ତି ପଠାଇପାରିବ ନାହିଁ, ଆପଣଙ୍କ ବ୍ୟାଟେରୀକୁ ବ୍ୟବହାର କରିପାରିବ ନାହିଁ କିମ୍ବା ଆପଣଙ୍କର ଲୋକେସନକୁ ଆକ୍ସେସ୍ କରିପାରିବ ନାହିଁ"</string>
- <string name="work_apps_paused_edu_banner" msgid="8872412121608402058">"ୱାର୍କ ଆପଗୁଡ଼ିକୁ ବ୍ୟାଜ୍ କରାଯାଇଛି ଏବଂ ଆପଣଙ୍କ IT ଆଡମିନଙ୍କୁ ଦେଖାଯାଉଛି"</string>
- <string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"ବୁଝିଗଲି"</string>
- <string name="work_apps_pause_btn_text" msgid="1921059713673767460">"ୱାର୍କ ଆପଗୁଡ଼ିକୁ ବନ୍ଦ କରନ୍ତୁ"</string>
- <string name="work_apps_enable_btn_text" msgid="1156432622148413741">"ୱାର୍କ ଆପଗୁଡ଼ିକୁ ଚାଲୁ କରନ୍ତୁ"</string>
- <string name="developer_options_filter_hint" msgid="5896817443635989056">"ଫିଲ୍ଟର୍"</string>
+ <string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"ଏଠାରେ କାମ ଆପ୍‌ ଖୋଜନ୍ତୁ"</string>
+ <string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"ପ୍ରତ୍ୟେକ କାଯ୍ୟକାରୀ ଆପ୍‌ର ଗୋଟିଏ ବ୍ୟାଜ୍ (ଚିହ୍ନ) ଅଛି, ଯାହାକୁ ଆପଣଙ୍କ ସଂସ୍ଥା ସୁରକ୍ଷିତ ରଖିଥାଏ। ସହଜରେ ଆକ୍ସେସ୍ କରିବା ପାଇଁ ଆପ୍‌କୁ ହୋମ୍ ସ୍କ୍ରୀନ୍ ଉପରକୁ ଆଣନ୍ତୁ।"</string>
+ <string name="work_mode_on_label" msgid="4781128097185272916">"ଆପଣଙ୍କ ସଂସ୍ଥା ଦ୍ୱାରା ପରିଚାଳିତ"</string>
+ <string name="work_mode_off_label" msgid="3194894777601421047">"ବିଜ୍ଞପ୍ତି ଓ ଆପ୍‌ଗୁଡ଼ିକ ବନ୍ଦ ଅଛି"</string>
+ <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"ବନ୍ଦ କରନ୍ତୁ"</string>
+ <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"ବନ୍ଦ ହୋଇଯାଇଛି"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"ବିଫଳ ହୋଇଛି: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
</resources>
diff --git a/res/values-pa/strings.xml b/res/values-pa/strings.xml
index 2d70d7f89c..d4cd5be4bc 100644
--- a/res/values-pa/strings.xml
+++ b/res/values-pa/strings.xml
@@ -20,63 +20,39 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="649227358658669779">"Launcher3"</string>
- <string name="work_folder_name" msgid="3753320833950115786">"ਕਾਰਜ-ਸਥਾਨ"</string>
+ <string name="folder_name" msgid="7371454440695724752"></string>
+ <string name="work_folder_name" msgid="3753320833950115786">"ਦਫ਼ਤਰ"</string>
<string name="activity_not_found" msgid="8071924732094499514">"ਐਪ ਇੰਸਟੌਲ ਨਹੀਂ ਕੀਤਾ ਹੋਇਆ ਹੈ।"</string>
<string name="activity_not_available" msgid="7456344436509528827">"ਐਪ ਉਪਲਬਧ ਨਹੀਂ ਹੈ"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"ਡਾਊਨਲੋਡ ਕੀਤਾ ਐਪ ਸੁਰੱਖਿਅਤ ਮੋਡ ਵਿੱਚ ਅਸਮਰਥਿਤ"</string>
<string name="safemode_widget_error" msgid="4863470563535682004">"ਵਿਜੇਟ ਸੁਰੱਖਿਅਤ ਮੋਡ ਵਿੱਚ ਅਸਮਰਥਿਤ"</string>
<string name="shortcut_not_available" msgid="2536503539825726397">"ਸ਼ਾਰਟਕੱਟ ਉਪਲਬਧ ਨਹੀਂ ਹੈ"</string>
- <string name="home_screen" msgid="5629429142036709174">"ਮੁੱਖ ਪੰਨਾ"</string>
- <string name="recent_task_option_split_screen" msgid="6690461455618725183">"ਸਪਲਿਟ ਸਕ੍ਰੀਨ"</string>
- <string name="split_screen_position_top" msgid="1504965011158689649">"ਸਿਖਰ \'ਤੇ ਵੰਡੋ"</string>
- <string name="split_screen_position_left" msgid="7537793098851830883">"ਖੱਬੇ ਪਾਸੇ ਵੰਡੋ"</string>
- <string name="split_screen_position_right" msgid="1569377524925193369">"ਸੱਜੇ ਪਾਸੇ ਵੰਡੋ"</string>
- <string name="split_app_info_accessibility" msgid="5475288491241414932">"%1$s ਲਈ ਐਪ ਜਾਣਕਾਰੀ"</string>
- <string name="long_press_widget_to_add" msgid="3587712543577675817">"ਕਿਸੇ ਵਿਜੇਟ ਨੂੰ ਲਿਜਾਉਣ ਲਈ ਸਪਰਸ਼ ਕਰਕੇ ਰੱਖੋ।"</string>
- <string name="long_accessible_way_to_add" msgid="2733588281439571974">"ਵਿਜੇਟ ਲਿਜਾਉਣ ਲਈ ਜਾਂ ਵਿਉਂਂਤੀਆਂ ਕਾਰਵਾਈਆਂ ਵਰਤਣ ਲਈ ਦੋ ਵਾਰ ਟੈਪ ਕਰਕੇ ਦਬਾ ਕੇ ਰੱਖੋ।"</string>
+ <string name="home_screen" msgid="806512411299847073">"ਹੋਮ ਸਕ੍ਰੀਨ"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"ਵਿਉਂਂਤੀ ਕਾਰਵਾਈਆਂ"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"ਇੱਕ ਵਿਜੇਟ ਚੁਣਨ ਲਈ ਛੋਹਵੋT &amp; ਹੋਲਡ ਕਰੋ।"</string>
+ <string name="long_accessible_way_to_add" msgid="4289502106628154155">"ਇੱਕ ਵਿਜੇਟ ਚੁਣਨ ਲਈ ਜਾਂ ਵਿਉਂਂਤੀ ਕਾਰਵਾਈਆਂ ਵਰਤਣ ਲਈ ਦੋ ਵਾਰ ਟੈਪ ਕਰੋ ਅਤੇ ਦਬਾ ਕੇ ਰੱਖੋ।"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d ਚੌੜਾਈ ਅਤੇ %2$d ਲੰਬਾਈ"</string>
- <string name="widget_preview_context_description" msgid="9045841361655787574">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g> ਵਿਜੇਟ"</string>
- <string name="add_item_request_drag_hint" msgid="5653291305078645405">"ਵਿਜੇਟ ਨੂੰ ਹੋਮ ਸਕ੍ਰੀਨ \'ਤੇ ਇੱਧਰ-ਉੱਧਰ ਲਿਜਾਉਣ ਲਈ ਸਪਰਸ਼ ਕਰਕੇ ਦਬਾਈ ਰੱਖੋ"</string>
- <string name="add_to_home_screen" msgid="8631549138215492708">"ਹੋਮ ਸਕ੍ਰੀਨ \'ਤੇ ਸ਼ਾਮਲ ਕਰੋ"</string>
- <string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g> ਵਿਜੇਟ ਨੂੰ ਹੋਮ ਸਕ੍ਰੀਨ \'ਤੇ ਸ਼ਾਮਲ ਕੀਤਾ ਗਿਆ"</string>
- <string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# ਵਿਜੇਟ}one{# ਵਿਜੇਟ}other{# ਵਿਜੇਟ}}"</string>
- <string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{# ਸ਼ਾਰਟਕੱਟ}one{# ਸ਼ਾਰਟਕੱਟ}other{# ਸ਼ਾਰਟਕੱਟ}}"</string>
- <string name="widgets_and_shortcuts_count" msgid="7209136747878365116">"<xliff:g id="WIDGETS_COUNT">%1$s</xliff:g>, <xliff:g id="SHORTCUTS_COUNT">%2$s</xliff:g>"</string>
- <string name="widget_button_text" msgid="2880537293434387943">"ਵਿਜੇਟ"</string>
- <string name="widgets_full_sheet_search_bar_hint" msgid="8484659090860596457">"ਖੋਜੋ"</string>
- <string name="widgets_full_sheet_cancel_button_description" msgid="5766167035728653605">"ਖੋਜ ਬਾਕਸ ਤੋਂ ਲਿਖਤ ਕਲੀਅਰ ਕਰੋ"</string>
- <string name="no_widgets_available" msgid="4337693382501046170">"ਵਿਜੇਟ ਜਾਂ ਸ਼ਾਰਟਕੱਟ ਉਪਲਬਧ ਨਹੀਂ ਹਨ"</string>
- <string name="no_search_results" msgid="3787956167293097509">"ਕੋਈ ਵੀ ਵਿਜੇਟ ਜਾਂ ਸ਼ਾਰਟਕੱਟ ਨਹੀਂ ਮਿਲਿਆ"</string>
- <string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"ਨਿੱਜੀ"</string>
- <string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"ਕਾਰਜ-ਸਥਾਨ"</string>
- <string name="widget_category_conversations" msgid="8894438636213590446">"ਗੱਲਾਂਬਾਤਾਂ"</string>
- <string name="widget_education_header" msgid="4874760613775913787">"ਤੁਹਾਡੀਆਂ ਉਂਗਲਾਂ \'ਤੇ ਲਾਹੇਵੰਦ ਜਾਣਕਾਰੀ"</string>
- <string name="widget_education_content" msgid="745542879510751525">"ਐਪਾਂ ਨੂੰ ਖੋਲ੍ਹੇ ਬਿਨਾਂ ਜਾਣਕਾਰੀ ਪ੍ਰਾਪਤ ਕਰਨ ਲਈ, ਤੁਸੀਂ ਆਪਣੀ ਹੋਮ ਸਕ੍ਰੀਨ \'ਤੇ ਵਿਜੇਟ ਸ਼ਾਮਲ ਕਰ ਸਕਦੇ ਹੋ"</string>
- <string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"ਵਿਜੇਟ ਸੈਟਿੰਗਾਂ ਨੂੰ ਬਦਲਣ ਲਈ ਟੈਪ ਕਰੋ"</string>
- <string name="widget_education_close_button" msgid="8676165703104836580">"ਸਮਝ ਲਿਆ"</string>
- <string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"ਵਿਜੇਟ ਸੈਟਿੰਗਾਂ ਬਦਲੋ"</string>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"ਹੱਥੀਂ ਰੱਖਣ ਲਈ ਸਪੱਰਸ਼ ਕਰੋ ਅਤੇ ਦਬਾਈ ਰੱਖੋ"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"ਸਵੈਚਲਿਤ ਤਰੀਕੇ ਨਾਲ ਸ਼ਾਮਲ ਕਰੋ"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"ਐਪਾਂ ਖੋਜੋ"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"ਐਪਾਂ ਨੂੰ ਲੋਡ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ..."</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" ਨਾਲ ਮੇਲ ਖਾਂਦੀਆਂ ਕੋਈ ਐਪਾਂ ਨਹੀਂ ਮਿਲੀਆਂ"</string>
<string name="all_apps_search_market_message" msgid="1366263386197059176">"ਹੋਰ ਐਪਾਂ ਖੋਜੋ"</string>
<string name="label_application" msgid="8531721983832654978">"ਐਪ"</string>
- <string name="all_apps_label" msgid="5015784846527570951">"ਸਾਰੀਆਂ ਐਪਾਂ"</string>
<string name="notifications_header" msgid="1404149926117359025">"ਸੂਚਨਾਵਾਂ"</string>
- <string name="long_press_shortcut_to_add" msgid="5405328730817637737">"ਕਿਸੇ ਸ਼ਾਰਟਕੱਟ ਨੂੰ ਲਿਜਾਉਣ ਲਈ ਸਪੱਰਸ਼ ਕਰਕੇ ਦਬਾਈ ਰੱਖੋ।"</string>
- <string name="long_accessible_way_to_add_shortcut" msgid="2199537273817090740">"ਕਿਸੇ ਸ਼ਾਰਟਕੱਟ ਨੂੰ ਲਿਜਾਉਣ ਲਈ ਡਬਲ ਟੈਪ ਕਰਕੇ ਦਬਾਈ ਰੱਖੋ ਜਾਂ ਵਿਉਂਤੀਆਂ ਕਾਰਵਾਈਆਂ ਵਰਤੋ।"</string>
- <string name="out_of_space" msgid="6692471482459245734">"ਇਸ ਹੋਮ ਸਕ੍ਰੀਨ \'ਤੇ ਜਗ੍ਹਾ ਨਹੀਂ ਬਚੀ"</string>
+ <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"ਕੋਈ ਸ਼ਾਰਟਕੱਟ ਚੁਣਨ ਲਈ ਸਪੱਰਸ਼ ਕਰਕੇ ਦਬਾਈ ਰੱਖੋ।"</string>
+ <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"ਕੋਈ ਸ਼ਾਰਟਕੱਟ ਚੁਣਨ ਲਈ ਡਬਲ ਟੈਪ ਕਰਕੇ ਦਬਾਈ ਰੱਖੋ ਜਾਂ ਵਿਉਂਤੀਆਂ ਕਾਰਵਾਈਆਂ ਵਰਤੋ।"</string>
+ <string name="out_of_space" msgid="4691004494942118364">"ਇਸ ਹੋਮ ਸਕ੍ਰੀਨ ਲਈ ਹੋਰ ਖਾਲੀ ਸਥਾਨ ਨਹੀਂ ਹੈ।"</string>
<string name="hotseat_out_of_space" msgid="7448809638125333693">"ਮਨਪਸੰਦ ਟ੍ਰੇ ਵਿੱਚ ਹੋਰ ਖਾਲੀ ਸਥਾਨ ਨਹੀਂ।"</string>
<string name="all_apps_button_label" msgid="8130441508702294465">"ਐਪ ਸੂਚੀ"</string>
- <string name="all_apps_search_results" msgid="5889367432531296759">"ਖੋਜ ਨਤੀਜੇ"</string>
<string name="all_apps_button_personal_label" msgid="1315764287305224468">"ਨਿੱਜੀ ਐਪਾਂ ਦੀ ਸੂਚੀ"</string>
<string name="all_apps_button_work_label" msgid="7270707118948892488">"ਕਾਰਜ-ਸਥਾਨ ਸੰਬੰਧੀ ਐਪਾਂ ਦੀ ਸੂਚੀ"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"ਹੋਮ"</string>
<string name="remove_drop_target_label" msgid="7812859488053230776">"ਹਟਾਓ"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"ਅਣਸਥਾਪਤ ਕਰੋ"</string>
<string name="app_info_drop_target_label" msgid="692894985365717661">"ਐਪ ਜਾਣਕਾਰੀ"</string>
<string name="install_drop_target_label" msgid="2539096853673231757">"ਸਥਾਪਤ ਕਰੋ"</string>
- <string name="dismiss_prediction_label" msgid="3357562989568808658">"ਐਪ ਦਾ ਸੁਝਾਅ ਨਾ ਦਿਓ"</string>
- <string name="pin_prediction" msgid="4196423321649756498">"ਪੂਰਵ-ਅਨੁਮਾਨ ਪਿੰਨ ਕਰੋ"</string>
<string name="permlab_install_shortcut" msgid="5632423390354674437">"ਸ਼ਾਰਟਕੱਟ ਸਥਾਪਤ ਕਰੋ"</string>
<string name="permdesc_install_shortcut" msgid="923466509822011139">"ਇੱਕ ਐਪ ਨੂੰ ਵਰਤੋਂਕਾਰ ਦੇ ਦਖ਼ਲ ਤੋਂ ਬਿਨਾਂ ਸ਼ਾਰਟਕੱਟ ਸ਼ਾਮਲ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
<string name="permlab_read_settings" msgid="1941457408239617576">"ਹੋਮ ਸੈਟਿੰਗਾਂ ਅਤੇ ਸ਼ਾਰਟਕੱਟ ਪੜ੍ਹੋ"</string>
@@ -84,13 +60,15 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"ਹੋਮ ਸੈਟਿੰਗਾਂ ਅਤੇ ਸ਼ਾਰਟਕੱਟ ਲਿਖੋ"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"ਐਪ ਨੂੰ ਹੋਮ ਵਿੱਚ ਸੈਟਿੰਗਾਂ ਅਤੇ ਸ਼ਾਰਟਕੱਟ ਬਦਲਣ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
<string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> ਨੂੰ ਫ਼ੋਨ ਕਾਲਾਂ ਕਰਨ ਦੀ ਆਗਿਆ ਨਹੀਂ ਹੈ"</string>
- <string name="gadget_error_text" msgid="740356548025791839">"ਵਿਜੇਟ ਨੂੰ ਲੋਡ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ"</string>
- <string name="gadget_setup_text" msgid="8348374825537681407">"ਵਿਜੇਟ ਸੈਟਿੰਗਾਂ"</string>
- <string name="gadget_complete_setup_text" msgid="309040266978007925">"ਸੈੱਟਅੱਪ ਪੂਰਾ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"ਵਿਜੇਟ ਲੋਡ ਕਰਨ ਵਿੱਚ ਸਮੱਸਿਆ"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"ਸਥਾਪਤ ਕਰੋ"</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"ਇਹ ਇੱਕ ਸਿਸਟਮ ਐਪ ਹੈ ਅਤੇ ਇਸਨੂੰ ਅਣਇੰਸਟੌਲ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ।"</string>
- <string name="folder_hint_text" msgid="5174843001373488816">"ਨਾਮ ਦਾ ਸੰਪਾਦਨ ਕਰੋ"</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"ਬਿਨਾਂ ਨਾਮ ਦਿੱਤਾ ਫੋਲਡਰ"</string>
<string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> ਨੂੰ ਅਯੋਗ ਬਣਾਇਆ ਗਿਆ"</string>
- <string name="dotted_app_label" msgid="1704091277755818896">"{count,plural,offset:1 =1{{app_name} \'ਤੇ # ਸੂਚਨਾ ਹੈ}one{{app_name} \'ਤੇ # ਸੂਚਨਾ ਹੈ}other{{app_name} \'ਤੇ # ਸੂਚਨਾਵਾਂ ਹਨ}}"</string>
+ <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+ <item quantity="one"><xliff:g id="APP_NAME_2">%1$s</xliff:g> ਦੀ <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> ਸੂਚਨਾ</item>
+ <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g> ਦੀਆਂ <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> ਸੂਚਨਾਵਾਂ</item>
+ </plurals>
<string name="default_scroll_format" msgid="7475544710230993317">"ਸਫ਼ਾ %2$d ਦਾ %1$d"</string>
<string name="workspace_scroll_format" msgid="8458889198184077399">"ਹੋਮ ਸਕ੍ਰੀਨ %2$d ਦੀ %1$d"</string>
<string name="workspace_new_page" msgid="257366611030256142">"ਨਵਾਂ ਹੋਮ ਸਕ੍ਰੀਨ ਸਫ਼ਾ"</string>
@@ -99,14 +77,14 @@
<string name="folder_tap_to_rename" msgid="4017685068016979677">"ਬਦਲੇ ਗਏ ਨਾਮ ਨੂੰ ਰੱਖਿਅਤ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ"</string>
<string name="folder_closed" msgid="4100806530910930934">"ਫੋਲਡਰ ਬੰਦ ਕੀਤਾ"</string>
<string name="folder_renamed" msgid="1794088362165669656">"ਫੋਲਡਰ ਨੂੰ <xliff:g id="NAME">%1$s</xliff:g> ਮੁੜ ਨਾਮ ਦਿੱਤਾ ਗਿਆ"</string>
- <string name="folder_name_format_exact" msgid="8626242716117004803">"ਫੋਲਡਰ: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> ਆਈਟਮਾਂ"</string>
- <string name="folder_name_format_overflow" msgid="4270108890534995199">"ਫੋਲਡਰ: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> ਜਾਂ ਹੋਰ ਆਈਟਮਾਂ"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"ਫੋਲਡਰ: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"ਵਿਜੇਟ"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"ਵਾਲਪੇਪਰ"</string>
- <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"ਵਾਲਪੇਪਰ ਅਤੇ ਸਟਾਈਲ"</string>
+ <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"ਸ਼ੈਲੀਆਂ ਅਤੇ ਵਾਲਪੇਪਰ"</string>
<string name="settings_button_text" msgid="8873672322605444408">"ਹੋਮ ਸੈਟਿੰਗਾਂ"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"ਤੁਹਾਡੇ ਪ੍ਰਸ਼ਾਸਕ ਦੁਆਰਾ ਅਯੋਗ ਬਣਾਈ ਗਈ"</string>
- <string name="allow_rotation_title" msgid="7728578836261442095">"ਹੋਮ ਸਕ੍ਰੀਨ ਨੂੰ ਘੁਮਾਉਣ ਦੀ ਆਗਿਆ ਦਿਓ"</string>
- <string name="allow_rotation_desc" msgid="8662546029078692509">"ਜਦੋਂ ਫ਼ੋਨ ਘੁਮਾਇਆ ਜਾਂਦਾ ਹੈ"</string>
+ <string name="allow_rotation_title" msgid="7728578836261442095">"ਹੋਮ ਸਕ੍ਰੀਨ ਨੂੰ ਘੁੰਮਾਉਣ ਦੀ ਆਗਿਆ ਦਿਓ"</string>
+ <string name="allow_rotation_desc" msgid="8662546029078692509">"ਜਦੋਂ ਫ਼ੋਨ ਘੁੰਮਾਇਆ ਜਾਂਦਾ ਹੈ"</string>
<string name="notification_dots_title" msgid="9062440428204120317">"ਸੂਚਨਾ ਬਿੰਦੂ"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"ਚਾਲੂ"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"ਬੰਦ"</string>
@@ -114,22 +92,22 @@
<string name="msg_missing_notification_access" msgid="281113995110910548">"ਸੂਚਨਾ ਬਿੰਦੂਆਂ ਦਿਖਾਉਣ ਲਈ, <xliff:g id="NAME">%1$s</xliff:g> ਲਈ ਐਪ ਸੂਚਨਾਵਾਂ ਚਾਲੂ ਕਰੋ"</string>
<string name="title_change_settings" msgid="1376365968844349552">"ਸੈਟਿੰਗਾਂ ਬਦਲੋ"</string>
<string name="notification_dots_service_title" msgid="4284221181793592871">"ਸੂਚਨਾ ਬਿੰਦੂ ਦਿਖਾਓ"</string>
- <string name="auto_add_shortcuts_label" msgid="3698776050751790653">"ਹੋਮ ਸਕ੍ਰੀਨ \'ਤੇ ਐਪ ਪ੍ਰਤੀਕਾਂ ਨੂੰ ਸ਼ਾਮਲ ਕਰੋ"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"ਹੋਮ ਸਕ੍ਰੀਨ \'ਤੇ ਪ੍ਰਤੀਕ ਸ਼ਾਮਲ ਕਰੋ"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"ਨਵੀਆਂ ਐਪਾਂ ਲਈ"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"ਅਗਿਆਤ"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"ਹਟਾਓ"</string>
<string name="abandoned_search" msgid="891119232568284442">"ਖੋਜੋ"</string>
<string name="abandoned_promises_title" msgid="7096178467971716750">"ਇਹ ਐਪ ਇੰਸਟੌਲ ਨਹੀਂ ਕੀਤਾ ਹੋਇਆ ਹੈ।"</string>
- <string name="abandoned_promise_explanation" msgid="3990027586878167529">"ਇਸ ਪ੍ਰਤੀਕ ਲਈ ਐਪ ਸਥਾਪਤ ਨਹੀਂ ਕੀਤੀ ਹੋਈ ਹੈ। ਤੁਸੀਂ ਇਸਨੂੰ ਹਟਾ ਸਕਦੇ ਹੋ ਜਾਂ ਐਪ ਨੂੰ ਹੱਥੀਂ ਖੋਜ ਕੇ ਉਸਨੂੰ ਸਥਾਪਤ ਕਰ ਸਕਦੇ ਹੋ।"</string>
- <string name="app_installing_title" msgid="5864044122733792085">"<xliff:g id="NAME">%1$s</xliff:g> ਨੂੰ ਸਥਾਪਤ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ, <xliff:g id="PROGRESS">%2$s</xliff:g> ਪੂਰਾ ਹੋਇਆ"</string>
+ <string name="abandoned_promise_explanation" msgid="3990027586878167529">"ਇਸ ਪ੍ਰਤੀਕ ਲਈ ਐਪ ਸਥਾਪਤ ਨਹੀਂ ਕੀਤਾ ਹੋਇਆ ਹੈ। ਤੁਸੀਂ ਇਸਨੂੰ ਹਟਾ ਸਕਦੇ ਹੋ ਜਾਂ ਐਪ ਖੋਜ ਸਕਦੇ ਹੋ ਅਤੇ ਇਸਨੂੰ ਮੈਨੂਅਲੀ ਸਥਾਪਤ ਕਰ ਸਕਦੇ ਹੋ।"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> ਡਾਉਨਲੋਡ ਹੋਰ ਰਿਹਾ ਹੈ, <xliff:g id="PROGRESS">%2$s</xliff:g> ਸੰਪੂਰਣ"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> ਸਥਾਪਤ ਕਰਨ ਦੀ ਉਡੀਕ ਕਰ ਰਿਹਾ ਹੈ"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"<xliff:g id="NAME">%1$s</xliff:g> ਵਿਜੇਟ"</string>
<string name="widgets_list" msgid="796804551140113767">"ਵਿਜੇਟਾਂ ਦੀ ਸੂਚੀ"</string>
<string name="widgets_list_closed" msgid="6141506579418771922">"ਵਿਜੇਟਾਂ ਦੀ ਸੂਚੀ ਬੰਦ ਕੀਤੀ ਗਈ"</string>
<string name="action_add_to_workspace" msgid="8902165848117513641">"ਹੋਮ ਸਕ੍ਰੀਨ \'ਤੇ ਸ਼ਾਮਲ ਕਰੋ"</string>
<string name="action_move_here" msgid="2170188780612570250">"ਆਈਟਮ ਨੂੰ ਇੱਥੇ ਮੂਵ ਕਰੋ"</string>
<string name="item_added_to_workspace" msgid="4211073925752213539">"ਆਈਟਮ ਨੂੰ ਹੋਮ ਸਕ੍ਰੀਨ ਵਿੱਚ ਜੋੜਿਆ ਗਿਆ"</string>
- <string name="item_removed" msgid="851119963877842327">"ਆਈਟਮ ਹਟਾਈ ਗਈ"</string>
+ <string name="item_removed" msgid="851119963877842327">"ਅਈਟਮ ਹਟਾਈ ਗਈ"</string>
<string name="undo" msgid="4151576204245173321">"ਅਣਕੀਤਾ ਕਰੋ"</string>
<string name="action_move" msgid="4339390619886385032">"ਆਈਟਮ ਨੂੰ ਮੂਵ ਕਰੋ"</string>
<string name="move_to_empty_cell" msgid="2833711483015685619">"ਕਤਾਰ <xliff:g id="NUMBER_0">%1$s</xliff:g> ਕਾਲਮ <xliff:g id="NUMBER_1">%2$s</xliff:g> ਵਿੱਚ ਮੂਵ ਕਰੋ"</string>
@@ -151,20 +129,15 @@
<string name="action_deep_shortcut" msgid="2864038805849372848">"ਸ਼ਾਰਟਕੱਟ"</string>
<string name="shortcuts_menu_with_notifications_description" msgid="2676582286544232849">"ਸ਼ਾਰਟਕੱਟ ਅਤੇ ਸੂਚਨਾਵਾਂ"</string>
<string name="action_dismiss_notification" msgid="5909461085055959187">"ਖਾਰਜ ਕਰੋ"</string>
- <string name="accessibility_close" msgid="2277148124685870734">"ਬੰਦ ਕਰੋ"</string>
<string name="notification_dismissed" msgid="6002233469409822874">"ਸੂਚਨਾ ਖਾਰਜ ਕੀਤੀ ਗਈ"</string>
<string name="all_apps_personal_tab" msgid="4190252696685155002">"ਨਿੱਜੀ"</string>
- <string name="all_apps_work_tab" msgid="4884822796154055118">"ਕੰਮ ਸੰਬੰਧੀ"</string>
+ <string name="all_apps_work_tab" msgid="4884822796154055118">"ਕਾਰਜ-ਸਥਾਨ"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ"</string>
- <string name="work_profile_edu_work_apps" msgid="7895468576497746520">"ਕੰਮ ਸੰਬੰਧੀ ਐਪਾਂ ਨੂੰ ਬੈਜ ਕੀਤਾ ਜਾਂਦਾ ਹੈ ਅਤੇ ਇਹ ਤੁਹਾਡੇ ਆਈ.ਟੀ. ਪ੍ਰਸ਼ਾਸਕ ਨੂੰ ਦਿਸਣਗੀਆਂ"</string>
- <string name="work_profile_edu_accept" msgid="6069788082535149071">"ਸਮਝ ਲਿਆ"</string>
- <string name="work_apps_paused_title" msgid="3040901117349444598">"ਕੰਮ ਸੰਬੰਧੀ ਐਪਾਂ ਨੂੰ ਰੋਕਿਆ ਗਿਆ ਹੈ"</string>
- <string name="work_apps_paused_body" msgid="261634750995824906">"ਤੁਹਾਡੀਆਂ ਕੰਮ ਸੰਬੰਧੀ ਐਪਾਂ ਤੁਹਾਨੂੰ ਸੂਚਨਾਵਾਂ ਨਹੀਂ ਭੇਜ ਸਕਦੀਆਂ, ਤੁਹਾਡੀ ਬੈਟਰੀ ਨਹੀਂ ਵਰਤ ਸਕਦੀਆਂ ਜਾਂ ਤੁਹਾਡੇ ਟਿਕਾਣੇ ਤੱਕ ਪਹੁੰਚ ਨਹੀਂ ਕਰ ਸਕਦੀਆਂ"</string>
- <string name="work_apps_paused_content_description" msgid="5149623040804051095">"ਕੰਮ ਸੰਬੰਧੀ ਐਪਾਂ ਬੰਦ ਹਨ। ਤੁਹਾਡੀਆਂ ਕੰਮ ਸੰਬੰਧੀ ਐਪਾਂ ਤੁਹਾਨੂੰ ਸੂਚਨਾਵਾਂ ਨਹੀਂ ਭੇਜ ਸਕਦੀਆਂ, ਤੁਹਾਡੀ ਬੈਟਰੀ ਨਹੀਂ ਵਰਤ ਸਕਦੀਆਂ ਜਾਂ ਤੁਹਾਡੇ ਟਿਕਾਣੇ ਤੱਕ ਪਹੁੰਚ ਨਹੀਂ ਕਰ ਸਕਦੀਆਂ"</string>
- <string name="work_apps_paused_edu_banner" msgid="8872412121608402058">"ਕੰਮ ਸੰਬੰਧੀ ਐਪਾਂ ਨੂੰ ਬੈਜ ਕੀਤਾ ਜਾਂਦਾ ਹੈ ਅਤੇ ਇਹ ਤੁਹਾਡੇ ਆਈ.ਟੀ. ਪ੍ਰਸ਼ਾਸਕ ਨੂੰ ਦਿਸਣਗੀਆਂ"</string>
- <string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"ਸਮਝ ਲਿਆ"</string>
- <string name="work_apps_pause_btn_text" msgid="1921059713673767460">"ਕੰਮ ਸੰਬੰਧੀ ਐਪਾਂ ਬੰਦ ਕਰੋ"</string>
- <string name="work_apps_enable_btn_text" msgid="1156432622148413741">"ਕੰਮ ਸੰਬੰਧੀ ਐਪਾਂ ਚਾਲੂ ਕਰੋ"</string>
- <string name="developer_options_filter_hint" msgid="5896817443635989056">"ਫਿਲਟਰ"</string>
+ <string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"ਕਾਰਜ-ਸਥਾਨ ਐਪਾਂ ਇੱਥੇ ਲੱਭੋ"</string>
+ <string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"ਹਰੇਕ ਕਾਰਜ-ਸਥਾਨ ਐਪ ਦਾ ਇੱਕ ਬੈਜ ਹੁੰਦਾ ਹੈ ਅਤੇ ਉਸਨੂੰ ਤੁਹਾਡੀ ਸੰਸਥਾ ਵੱਲੋਂ ਸੁਰੱਖਿਅਤ ਰੱਖਿਆ ਜਾਂਦਾ ਹੈ। ਵਧੇਰੇ ਆਸਾਨ ਪਹੁੰਚ ਲਈ ਐਪਾਂ ਨੂੰ ਹੋਮ ਸਕ੍ਰੀਨ \'ਤੇ ਲਿਜਾਓ।"</string>
+ <string name="work_mode_on_label" msgid="4781128097185272916">"ਤੁਹਾਡੀ ਸੰਸਥਾ ਵੱਲੋਂ ਪ੍ਰਬੰਧਿਤ ਕੀਤਾ ਜਾਂਦਾ ਹੈ"</string>
+ <string name="work_mode_off_label" msgid="3194894777601421047">"ਸੂਚਨਾਵਾਂ ਅਤੇ ਐਪਾਂ ਬੰਦ ਹਨ"</string>
+ <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"ਬੰਦ ਕਰੋ"</string>
+ <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"ਬੰਦ ਕੀਤਾ ਗਿਆ"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"ਇਹ ਕਾਰਵਾਈ ਅਸਫਲ ਹੋਈ: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
</resources>
diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml
index f730e685da..68859605fb 100644
--- a/res/values-pl/strings.xml
+++ b/res/values-pl/strings.xml
@@ -20,77 +20,57 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="649227358658669779">"Launcher3"</string>
- <string name="work_folder_name" msgid="3753320833950115786">"Służbowy"</string>
+ <string name="folder_name" msgid="7371454440695724752"></string>
+ <string name="work_folder_name" msgid="3753320833950115786">"Praca"</string>
<string name="activity_not_found" msgid="8071924732094499514">"Aplikacja nie jest zainstalowana."</string>
<string name="activity_not_available" msgid="7456344436509528827">"Aplikacja niedostępna"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"Pobrana aplikacja została wyłączona w trybie awaryjnym"</string>
<string name="safemode_widget_error" msgid="4863470563535682004">"Widżety są wyłączone w trybie bezpiecznym"</string>
<string name="shortcut_not_available" msgid="2536503539825726397">"Skrót nie jest dostępny"</string>
- <string name="home_screen" msgid="5629429142036709174">"Ekran główny"</string>
- <string name="recent_task_option_split_screen" msgid="6690461455618725183">"Podziel ekran"</string>
- <string name="split_screen_position_top" msgid="1504965011158689649">"Podziel u góry"</string>
- <string name="split_screen_position_left" msgid="7537793098851830883">"Podziel po lewej"</string>
- <string name="split_screen_position_right" msgid="1569377524925193369">"Podziel po prawej"</string>
- <string name="split_app_info_accessibility" msgid="5475288491241414932">"Informacje o aplikacji: %1$s"</string>
- <string name="long_press_widget_to_add" msgid="3587712543577675817">"Naciśnij i przytrzymaj, aby przenieść widżet."</string>
- <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Naciśnij dwukrotnie i przytrzymaj, aby przenieść widżet lub użyć działań niestandardowych."</string>
+ <string name="home_screen" msgid="806512411299847073">"Ekran główny"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"Działania niestandardowe"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"Aby dodać widżet, kliknij go i przytrzymaj."</string>
+ <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Kliknij dwukrotnie i przytrzymaj, by wybrać widżet lub użyć działań niestandardowych."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"Szerokość %1$d, wysokość %2$d"</string>
- <string name="widget_preview_context_description" msgid="9045841361655787574">"Widżet <xliff:g id="WIDGET_NAME">%1$s</xliff:g>"</string>
- <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Kliknij i przytrzymaj widżet, by poruszać nim po ekranie głównym"</string>
- <string name="add_to_home_screen" msgid="8631549138215492708">"Dodaj do ekranu głównego"</string>
- <string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"Widżet <xliff:g id="WIDGET_NAME">%1$s</xliff:g> został dodany do ekranu głównego"</string>
- <string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# widżet}few{# widżety}many{# widżetów}other{# widżetu}}"</string>
- <string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{# skrót}few{# skróty}many{# skrótów}other{# skrótu}}"</string>
- <string name="widgets_and_shortcuts_count" msgid="7209136747878365116">"<xliff:g id="WIDGETS_COUNT">%1$s</xliff:g>, <xliff:g id="SHORTCUTS_COUNT">%2$s</xliff:g>"</string>
- <string name="widget_button_text" msgid="2880537293434387943">"Widżety"</string>
- <string name="widgets_full_sheet_search_bar_hint" msgid="8484659090860596457">"Szukaj"</string>
- <string name="widgets_full_sheet_cancel_button_description" msgid="5766167035728653605">"Wyczyść tekst w polu wyszukiwania"</string>
- <string name="no_widgets_available" msgid="4337693382501046170">"Widżety i skróty nie są dostępne"</string>
- <string name="no_search_results" msgid="3787956167293097509">"Nie znaleziono widżetów ani skrótów"</string>
- <string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Osobiste"</string>
- <string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Służbowe"</string>
- <string name="widget_category_conversations" msgid="8894438636213590446">"Rozmowy"</string>
- <string name="widget_education_header" msgid="4874760613775913787">"Użyteczne informacje w zasięgu ręki"</string>
- <string name="widget_education_content" msgid="745542879510751525">"Aby uzyskać informacje bez otwierania aplikacji, możesz dodać widżety do ekranu głównego"</string>
- <string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Kliknij, aby zmienić ustawienia widżetu"</string>
- <string name="widget_education_close_button" msgid="8676165703104836580">"OK"</string>
- <string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Zmień ustawienia widżetu"</string>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Kliknij i przytrzymaj, by umieścić ręcznie"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"Dodaj automatycznie"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Wyszukaj aplikacje"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Ładuję aplikacje…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"Nie znaleziono aplikacji pasujących do zapytania „<xliff:g id="QUERY">%1$s</xliff:g>”"</string>
<string name="all_apps_search_market_message" msgid="1366263386197059176">"Wyszukaj więcej aplikacji"</string>
<string name="label_application" msgid="8531721983832654978">"Aplikacja"</string>
- <string name="all_apps_label" msgid="5015784846527570951">"Wszystkie aplikacje"</string>
<string name="notifications_header" msgid="1404149926117359025">"Powiadomienia"</string>
- <string name="long_press_shortcut_to_add" msgid="5405328730817637737">"Naciśnij i przytrzymaj, aby przenieść skrót."</string>
- <string name="long_accessible_way_to_add_shortcut" msgid="2199537273817090740">"Naciśnij dwukrotnie i przytrzymaj, aby przenieść skrót lub użyć działań niestandardowych."</string>
- <string name="out_of_space" msgid="6692471482459245734">"Brak miejsca na tym ekranie głównym"</string>
+ <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"Kliknij i przytrzymaj, by wybrać skrót."</string>
+ <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"Kliknij dwukrotnie i przytrzymaj, by wybrać skrót lub użyć działań niestandardowych."</string>
+ <string name="out_of_space" msgid="4691004494942118364">"Brak miejsca na tym ekranie głównym."</string>
<string name="hotseat_out_of_space" msgid="7448809638125333693">"Brak miejsca w Ulubionych"</string>
<string name="all_apps_button_label" msgid="8130441508702294465">"Lista aplikacji"</string>
- <string name="all_apps_search_results" msgid="5889367432531296759">"Wyniki wyszukiwania"</string>
<string name="all_apps_button_personal_label" msgid="1315764287305224468">"Lista aplikacji osobistych"</string>
- <string name="all_apps_button_work_label" msgid="7270707118948892488">"Lista aplikacji służbowych"</string>
+ <string name="all_apps_button_work_label" msgid="7270707118948892488">"Lista aplikacji do pracy"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"Ekran główny"</string>
<string name="remove_drop_target_label" msgid="7812859488053230776">"Usuń"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"Odinstaluj"</string>
<string name="app_info_drop_target_label" msgid="692894985365717661">"O aplikacji"</string>
<string name="install_drop_target_label" msgid="2539096853673231757">"Zainstaluj"</string>
- <string name="dismiss_prediction_label" msgid="3357562989568808658">"Nie proponuj aplikacji"</string>
- <string name="pin_prediction" msgid="4196423321649756498">"Przypnij podpowiedź"</string>
- <string name="permlab_install_shortcut" msgid="5632423390354674437">"Instalowanie skrótów"</string>
+ <string name="permlab_install_shortcut" msgid="5632423390354674437">"instalowanie skrótów"</string>
<string name="permdesc_install_shortcut" msgid="923466509822011139">"Pozwala aplikacji dodawać skróty bez interwencji użytkownika."</string>
<string name="permlab_read_settings" msgid="1941457408239617576">"odczytywanie ustawień i skrótów na ekranie głównym"</string>
<string name="permdesc_read_settings" msgid="5833423719057558387">"Pozwala aplikacji na odczytywanie ustawień i skrótów na ekranie głównym."</string>
<string name="permlab_write_settings" msgid="3574213698004620587">"zapisywanie ustawień i skrótów na ekranie głównym"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"Umożliwia aplikacji zmianę ustawień i skrótów na ekranie głównym."</string>
<string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> nie może wykonywać połączeń telefonicznych"</string>
- <string name="gadget_error_text" msgid="740356548025791839">"Nie udało się załadować widżetu"</string>
- <string name="gadget_setup_text" msgid="8348374825537681407">"Ustawienia widżetu"</string>
- <string name="gadget_complete_setup_text" msgid="309040266978007925">"Kliknij, aby dokończyć konfigurację"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"Problem podczas ładowania widżetu"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"Konfiguracja"</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"To aplikacja systemowa i nie można jej odinstalować."</string>
- <string name="folder_hint_text" msgid="5174843001373488816">"Edytuj nazwę"</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"Folder bez nazwy"</string>
<string name="disabled_app_label" msgid="6673129024321402780">"Aplikacja <xliff:g id="APP_NAME">%1$s</xliff:g> jest wyłączona"</string>
- <string name="dotted_app_label" msgid="1704091277755818896">"{count,plural,offset:1 =1{{app_name} – # powiadomienie}few{{app_name} – # powiadomienia}many{{app_name} – # powiadomień}other{{app_name} – # powiadomienia}}"</string>
+ <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+ <item quantity="few"><xliff:g id="APP_NAME_2">%1$s</xliff:g> – <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> powiadomienia</item>
+ <item quantity="many"><xliff:g id="APP_NAME_2">%1$s</xliff:g> – <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> powiadomień</item>
+ <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g> – <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> powiadomienia</item>
+ <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g> – <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> powiadomienie</item>
+ </plurals>
<string name="default_scroll_format" msgid="7475544710230993317">"Strona %1$d z %2$d"</string>
<string name="workspace_scroll_format" msgid="8458889198184077399">"Ekran główny %1$d z %2$d"</string>
<string name="workspace_new_page" msgid="257366611030256142">"Nowa strona ekranu głównego"</string>
@@ -99,11 +79,11 @@
<string name="folder_tap_to_rename" msgid="4017685068016979677">"Kliknij, by zapisać nową nazwę"</string>
<string name="folder_closed" msgid="4100806530910930934">"Folder zamknięty"</string>
<string name="folder_renamed" msgid="1794088362165669656">"Nazwa folderu zmieniona na <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="folder_name_format_exact" msgid="8626242716117004803">"Folder: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> elementy"</string>
- <string name="folder_name_format_overflow" msgid="4270108890534995199">"Folder: <xliff:g id="NAME">%1$s</xliff:g>, liczba elementów: <xliff:g id="SIZE">%2$d</xliff:g> lub więcej"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"Folder: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"Widżety"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Tapety"</string>
- <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Tapeta i styl"</string>
- <string name="settings_button_text" msgid="8873672322605444408">"Ustawienia ekranu głównego"</string>
+ <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Style i tapety"</string>
+ <string name="settings_button_text" msgid="8873672322605444408">"Ustawienia strony głównej"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Funkcja wyłączona przez administratora"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Zezwalaj na obrót ekranu głównego"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Po obróceniu telefonu"</string>
@@ -114,16 +94,16 @@
<string name="msg_missing_notification_access" msgid="281113995110910548">"Aby pokazać plakietki z powiadomieniami, włącz powiadomienia aplikacji <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="title_change_settings" msgid="1376365968844349552">"Zmień ustawienia"</string>
<string name="notification_dots_service_title" msgid="4284221181793592871">"Pokaż plakietki z powiadomieniami"</string>
- <string name="auto_add_shortcuts_label" msgid="3698776050751790653">"Dodawaj ikony aplikacji do ekranu głównego"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Dodaj ikonę do ekranu głównego"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"W przypadku nowych aplikacji"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"Brak informacji"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"Usuń"</string>
<string name="abandoned_search" msgid="891119232568284442">"Szukaj"</string>
<string name="abandoned_promises_title" msgid="7096178467971716750">"Ta aplikacja nie jest zainstalowana"</string>
<string name="abandoned_promise_explanation" msgid="3990027586878167529">"Aplikacja, której odpowiada ta ikona, nie jest zainstalowana. Możesz usunąć ikonę lub wyszukać aplikację i zainstalować ją ręcznie."</string>
- <string name="app_installing_title" msgid="5864044122733792085">"Instaluję aplikację <xliff:g id="NAME">%1$s</xliff:g>, postęp: <xliff:g id="PROGRESS">%2$s</xliff:g>"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"Pobieranie elementu <xliff:g id="NAME">%1$s</xliff:g>, ukończono: <xliff:g id="PROGRESS">%2$s</xliff:g>"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> oczekuje na instalację"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"<xliff:g id="NAME">%1$s</xliff:g> – widżety"</string>
<string name="widgets_list" msgid="796804551140113767">"Lista widgetów"</string>
<string name="widgets_list_closed" msgid="6141506579418771922">"Lista widgetów zamknięta"</string>
<string name="action_add_to_workspace" msgid="8902165848117513641">"Dodaj do ekranu głównego"</string>
@@ -150,21 +130,16 @@
<string name="widget_resized" msgid="9130327887929620">"Szerokość i wysokość widżetu zmieniła się na <xliff:g id="NUMBER_0">%1$s</xliff:g> x <xliff:g id="NUMBER_1">%2$s</xliff:g>"</string>
<string name="action_deep_shortcut" msgid="2864038805849372848">"Skróty"</string>
<string name="shortcuts_menu_with_notifications_description" msgid="2676582286544232849">"Skróty i powiadomienia"</string>
- <string name="action_dismiss_notification" msgid="5909461085055959187">"Zamknij"</string>
- <string name="accessibility_close" msgid="2277148124685870734">"Zamknij"</string>
+ <string name="action_dismiss_notification" msgid="5909461085055959187">"Odrzuć"</string>
<string name="notification_dismissed" msgid="6002233469409822874">"Powiadomienie odrzucone"</string>
<string name="all_apps_personal_tab" msgid="4190252696685155002">"Osobiste"</string>
- <string name="all_apps_work_tab" msgid="4884822796154055118">"Służbowe"</string>
+ <string name="all_apps_work_tab" msgid="4884822796154055118">"Praca"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"Profil służbowy"</string>
- <string name="work_profile_edu_work_apps" msgid="7895468576497746520">"Aplikacje służbowe mają plakietki i są widoczne dla administratora IT"</string>
- <string name="work_profile_edu_accept" msgid="6069788082535149071">"OK"</string>
- <string name="work_apps_paused_title" msgid="3040901117349444598">"Aplikacje służbowe zostały wstrzymane"</string>
- <string name="work_apps_paused_body" msgid="261634750995824906">"Aplikacje służbowe nie mogą wysyłać powiadomień, używać baterii ani uzyskiwać dostępu do Twojej lokalizacji"</string>
- <string name="work_apps_paused_content_description" msgid="5149623040804051095">"Aplikacje służbowe są wyłączone i nie mogą wysyłać powiadomień, używać baterii ani uzyskiwać dostępu do Twojej lokalizacji"</string>
- <string name="work_apps_paused_edu_banner" msgid="8872412121608402058">"Aplikacje służbowe mają plakietki i są widoczne dla administratora IT"</string>
- <string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"OK"</string>
- <string name="work_apps_pause_btn_text" msgid="1921059713673767460">"Wyłącz aplikacje służbowe"</string>
- <string name="work_apps_enable_btn_text" msgid="1156432622148413741">"Włącz aplikacje służbowe"</string>
- <string name="developer_options_filter_hint" msgid="5896817443635989056">"Filtruj"</string>
+ <string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"Aplikacje do pracy"</string>
+ <string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"Każda aplikacja do pracy ma plakietkę, a o jej bezpieczeństwo dba Twoja organizacja. Aplikacje można przenieść na ekran główny, by były łatwiej dostępne."</string>
+ <string name="work_mode_on_label" msgid="4781128097185272916">"Profil zarządzany przez Twoją organizację"</string>
+ <string name="work_mode_off_label" msgid="3194894777601421047">"Powiadomienia i aplikacje są wyłączone"</string>
+ <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Zamknij"</string>
+ <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Zamknięto"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Niepowodzenie: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
</resources>
diff --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml
index 0ddef70e34..e0d2c74645 100644
--- a/res/values-pt-rPT/strings.xml
+++ b/res/values-pt-rPT/strings.xml
@@ -21,76 +21,53 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="649227358658669779">"Launcher3"</string>
<string name="work_folder_name" msgid="3753320833950115786">"Trabalho"</string>
- <string name="activity_not_found" msgid="8071924732094499514">"A app não está instalada."</string>
- <string name="activity_not_available" msgid="7456344436509528827">"A app não está disponível"</string>
+ <string name="activity_not_found" msgid="8071924732094499514">"A aplicação não está instalada."</string>
+ <string name="activity_not_available" msgid="7456344436509528827">"A aplicação não está disponível"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"Aplicação transferida desativada no Modo de segurança"</string>
<string name="safemode_widget_error" msgid="4863470563535682004">"Widgets desativados no Modo de segurança"</string>
<string name="shortcut_not_available" msgid="2536503539825726397">"O atalho não está disponível"</string>
- <string name="home_screen" msgid="5629429142036709174">"Página inicial"</string>
- <string name="recent_task_option_split_screen" msgid="6690461455618725183">"Ecrã dividido"</string>
- <string name="split_screen_position_top" msgid="1504965011158689649">"Divisão na parte superior"</string>
- <string name="split_screen_position_left" msgid="7537793098851830883">"Divisão à esquerda"</string>
- <string name="split_screen_position_right" msgid="1569377524925193369">"Divisão à direita"</string>
- <string name="split_app_info_accessibility" msgid="5475288491241414932">"Informações da app para %1$s"</string>
- <string name="long_press_widget_to_add" msgid="3587712543577675817">"Toque sem soltar para mover um widget."</string>
- <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Toque duas vezes sem soltar para mover um widget ou utilizar ações personalizadas."</string>
+ <string name="home_screen" msgid="806512411299847073">"Ecrã principal"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"Ações personalizadas"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"Prima sem soltar para escolher um widget."</string>
+ <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Toque duas vezes sem soltar para escolher um widget ou utilize ações personalizadas."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d de largura por %2$d de altura"</string>
- <string name="widget_preview_context_description" msgid="9045841361655787574">"Widget <xliff:g id="WIDGET_NAME">%1$s</xliff:g>"</string>
- <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Toque sem soltar no widget para o mover à volta do ecrã principal"</string>
- <string name="add_to_home_screen" msgid="8631549138215492708">"Adicionar ao ecrã principal"</string>
- <string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"Widget <xliff:g id="WIDGET_NAME">%1$s</xliff:g> adicionado ao ecrã principal"</string>
- <string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# widget}one{# widget(s)}other{# widgets}}"</string>
- <string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{# atalho}one{# atalho(s)}other{# atalhos}}"</string>
- <string name="widgets_and_shortcuts_count" msgid="7209136747878365116">"<xliff:g id="WIDGETS_COUNT">%1$s</xliff:g>, <xliff:g id="SHORTCUTS_COUNT">%2$s</xliff:g>"</string>
- <string name="widget_button_text" msgid="2880537293434387943">"Widgets"</string>
- <string name="widgets_full_sheet_search_bar_hint" msgid="8484659090860596457">"Pesquisar"</string>
- <string name="widgets_full_sheet_cancel_button_description" msgid="5766167035728653605">"Limpe o texto da caixa de pesquisa"</string>
- <string name="no_widgets_available" msgid="4337693382501046170">"Os widgets e os atalhos não estão disponíveis"</string>
- <string name="no_search_results" msgid="3787956167293097509">"Nenhum widget ou atalho encontrado"</string>
- <string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Pessoais"</string>
- <string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Trabalho"</string>
- <string name="widget_category_conversations" msgid="8894438636213590446">"Conversas"</string>
- <string name="widget_education_header" msgid="4874760613775913787">"Informações úteis à sua disposição"</string>
- <string name="widget_education_content" msgid="745542879510751525">"Para obter informações sem abrir apps, pode adicionar widgets ao seu ecrã principal"</string>
- <string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Toque para alterar as definições do widget"</string>
- <string name="widget_education_close_button" msgid="8676165703104836580">"OK"</string>
- <string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Alterar definições do widget"</string>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Toque sem soltar para colocar manualmente"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"Adicionar automaticamente"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Pesquisar aplicações"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"A carregar aplicações…"</string>
- <string name="all_apps_no_search_results" msgid="3200346862396363786">"Nenhuma app correspondente a \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
+ <string name="all_apps_no_search_results" msgid="3200346862396363786">"Nenhuma aplicação correspondente a \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
<string name="all_apps_search_market_message" msgid="1366263386197059176">"Pesquisar mais aplicações"</string>
<string name="label_application" msgid="8531721983832654978">"Aplicação"</string>
- <string name="all_apps_label" msgid="5015784846527570951">"Todas as apps"</string>
<string name="notifications_header" msgid="1404149926117359025">"Notificações"</string>
- <string name="long_press_shortcut_to_add" msgid="5405328730817637737">"Toque sem soltar para mover um atalho."</string>
- <string name="long_accessible_way_to_add_shortcut" msgid="2199537273817090740">"Toque duas vezes sem soltar para mover um atalho ou utilizar ações personalizadas."</string>
- <string name="out_of_space" msgid="6692471482459245734">"Sem espaço neste ecrã principal."</string>
+ <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"Toque sem soltar para escolher um atalho."</string>
+ <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"Toque duas vezes sem soltar para escolher um atalho ou utilize ações personalizadas."</string>
+ <string name="out_of_space" msgid="4691004494942118364">"Sem espaço suficiente neste Ecrã principal."</string>
<string name="hotseat_out_of_space" msgid="7448809638125333693">"Não existe mais espaço no tabuleiro de Favoritos"</string>
<string name="all_apps_button_label" msgid="8130441508702294465">"Lista de aplicações"</string>
- <string name="all_apps_search_results" msgid="5889367432531296759">"Resultados da pesquisa"</string>
<string name="all_apps_button_personal_label" msgid="1315764287305224468">"Lista de aplicações pessoais"</string>
<string name="all_apps_button_work_label" msgid="7270707118948892488">"Lista de aplicações de trabalho"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"Ecrã principal"</string>
<string name="remove_drop_target_label" msgid="7812859488053230776">"Remover"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"Desinstalar"</string>
- <string name="app_info_drop_target_label" msgid="692894985365717661">"Info. da app"</string>
+ <string name="app_info_drop_target_label" msgid="692894985365717661">"Info. da aplicação"</string>
<string name="install_drop_target_label" msgid="2539096853673231757">"Instalar"</string>
- <string name="dismiss_prediction_label" msgid="3357562989568808658">"Não sugerir app"</string>
- <string name="pin_prediction" msgid="4196423321649756498">"Fixar previsão"</string>
<string name="permlab_install_shortcut" msgid="5632423390354674437">"instalar atalhos"</string>
- <string name="permdesc_install_shortcut" msgid="923466509822011139">"Permite a uma app adicionar atalhos sem a intervenção do utilizador."</string>
+ <string name="permdesc_install_shortcut" msgid="923466509822011139">"Permite a uma aplicação adicionar atalhos sem a intervenção do utilizador."</string>
<string name="permlab_read_settings" msgid="1941457408239617576">"ler definições e atalhos do Ecrã Principal"</string>
- <string name="permdesc_read_settings" msgid="5833423719057558387">"Permite à app ler as definições e os atalhos no Ecrã Principal."</string>
+ <string name="permdesc_read_settings" msgid="5833423719057558387">"Permite à aplicação ler as definições e os atalhos no Ecrã Principal."</string>
<string name="permlab_write_settings" msgid="3574213698004620587">"escrever definições e atalhos do Ecrã principal"</string>
- <string name="permdesc_write_settings" msgid="5440712911516509985">"Permite à app alterar as definições e os atalhos no Ecrã Principal."</string>
+ <string name="permdesc_write_settings" msgid="5440712911516509985">"Permite à aplicação alterar as definições e os atalhos no Ecrã Principal."</string>
<string name="msg_no_phone_permission" msgid="9208659281529857371">"O <xliff:g id="APP_NAME">%1$s</xliff:g> não tem autorização para efetuar chamadas telefónicas"</string>
- <string name="gadget_error_text" msgid="740356548025791839">"Não é possível carregar o widget"</string>
- <string name="gadget_setup_text" msgid="8348374825537681407">"Definições de widget"</string>
- <string name="gadget_complete_setup_text" msgid="309040266978007925">"Toque para concluir a configuração"</string>
- <string name="uninstall_system_app_text" msgid="4172046090762920660">"É uma app de sistema e não pode ser desinstalada."</string>
- <string name="folder_hint_text" msgid="5174843001373488816">"Edite o nome"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"Problema ao carregar o widget"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"Configuração"</string>
+ <string name="uninstall_system_app_text" msgid="4172046090762920660">"É uma aplicação de sistema e não pode ser desinstalada."</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"Pasta sem nome"</string>
<string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> desativado"</string>
- <string name="dotted_app_label" msgid="1704091277755818896">"{count,plural,offset:1 =1{A app {app_name} tem # notificação}one{A app {app_name} tem # notificação(ões)}other{A app {app_name} tem # notificações}}"</string>
+ <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+ <item quantity="other">A aplicação <xliff:g id="APP_NAME_2">%1$s</xliff:g> tem <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> notificações.</item>
+ <item quantity="one">A aplicação <xliff:g id="APP_NAME_0">%1$s</xliff:g> tem <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> notificação</item>
+ </plurals>
<string name="default_scroll_format" msgid="7475544710230993317">"Página %1$d de %2$d"</string>
<string name="workspace_scroll_format" msgid="8458889198184077399">"Ecrã principal %1$d de %2$d"</string>
<string name="workspace_new_page" msgid="257366611030256142">"Nova página do ecrã principal"</string>
@@ -99,10 +76,10 @@
<string name="folder_tap_to_rename" msgid="4017685068016979677">"Tocar para guardar o nome novo"</string>
<string name="folder_closed" msgid="4100806530910930934">"Pasta fechada"</string>
<string name="folder_renamed" msgid="1794088362165669656">"Nome de pasta alterado para <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="folder_name_format_exact" msgid="8626242716117004803">"Pasta: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> itens"</string>
- <string name="folder_name_format_overflow" msgid="4270108890534995199">"Pasta: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> ou mais itens"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"Pasta: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"Widgets"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Imagens de fundo"</string>
- <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Imagem fundo/estilo"</string>
+ <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Estilos e imagens de fundo"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Definições de início"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Desativada pelo gestor"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Permitir rotação do ecrã principal"</string>
@@ -114,16 +91,16 @@
<string name="msg_missing_notification_access" msgid="281113995110910548">"Para mostrar os Pontos de notificação, ative as notificações de aplicações para o <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="title_change_settings" msgid="1376365968844349552">"Alterar definições"</string>
<string name="notification_dots_service_title" msgid="4284221181793592871">"Mostrar pontos de notificação"</string>
- <string name="auto_add_shortcuts_label" msgid="3698776050751790653">"Adic. ícones de apps ao ecrã principal"</string>
- <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Para novas apps"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Adicionar ícone ao ecrã principal"</string>
+ <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Para novas aplicações"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"Desconhecido"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"Remover"</string>
<string name="abandoned_search" msgid="891119232568284442">"Pesquisar"</string>
- <string name="abandoned_promises_title" msgid="7096178467971716750">"Esta app não está instalada"</string>
- <string name="abandoned_promise_explanation" msgid="3990027586878167529">"A app deste ícone não está instalada. Pode removê-lo ou pesquisar a app e instalá-la manualmente."</string>
- <string name="app_installing_title" msgid="5864044122733792085">"A instalar <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="PROGRESS">%2$s</xliff:g> concluído"</string>
+ <string name="abandoned_promises_title" msgid="7096178467971716750">"Esta aplicação não está instalada"</string>
+ <string name="abandoned_promise_explanation" msgid="3990027586878167529">"A aplicação deste ícone não está instalada. Pode removê-lo ou pesquisar a aplicação e instalá-la manualmente."</string>
<string name="app_downloading_title" msgid="8336702962104482644">"A transferir o <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="PROGRESS">%2$s</xliff:g> concluído"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"A aguardar a instalação do <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"Widgets de <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="widgets_list" msgid="796804551140113767">"Lista de widgets"</string>
<string name="widgets_list_closed" msgid="6141506579418771922">"Lista de widgets fechada."</string>
<string name="action_add_to_workspace" msgid="8902165848117513641">"Adicionar ao ecrã principal"</string>
@@ -151,20 +128,15 @@
<string name="action_deep_shortcut" msgid="2864038805849372848">"Atalhos"</string>
<string name="shortcuts_menu_with_notifications_description" msgid="2676582286544232849">"Atalhos e notificações"</string>
<string name="action_dismiss_notification" msgid="5909461085055959187">"Ignorar"</string>
- <string name="accessibility_close" msgid="2277148124685870734">"Fechar"</string>
<string name="notification_dismissed" msgid="6002233469409822874">"Notificação ignorada"</string>
<string name="all_apps_personal_tab" msgid="4190252696685155002">"Pessoal"</string>
<string name="all_apps_work_tab" msgid="4884822796154055118">"Trabalho"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"Perfil de trabalho"</string>
- <string name="work_profile_edu_work_apps" msgid="7895468576497746520">"As apps de trabalho têm um emblema e estão visíveis para o seu administrador de TI"</string>
- <string name="work_profile_edu_accept" msgid="6069788082535149071">"OK"</string>
- <string name="work_apps_paused_title" msgid="3040901117349444598">"As apps de trabalho estão em pausa"</string>
- <string name="work_apps_paused_body" msgid="261634750995824906">"As apps de trabalho não podem enviar-lhe notificações, utilizar a bateria ou aceder à sua localização"</string>
- <string name="work_apps_paused_content_description" msgid="5149623040804051095">"As apps de trabalho estão desativadas. As apps de trabalho não podem enviar-lhe notificações, utilizar a bateria ou aceder à sua localização"</string>
- <string name="work_apps_paused_edu_banner" msgid="8872412121608402058">"As apps de trabalho têm um emblema e estão visíveis para o seu administrador de TI"</string>
- <string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"OK"</string>
- <string name="work_apps_pause_btn_text" msgid="1921059713673767460">"Desativar apps de trabalho"</string>
- <string name="work_apps_enable_btn_text" msgid="1156432622148413741">"Ativar apps de trabalho"</string>
- <string name="developer_options_filter_hint" msgid="5896817443635989056">"Filtrar"</string>
+ <string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"Encontrar as aplicações de trabalho aqui"</string>
+ <string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"Cada aplicação de trabalho apresenta um emblema, pelo que a sua entidade a mantém em segurança. Pode mover as aplicações para o ecrã principal para facilitar o acesso."</string>
+ <string name="work_mode_on_label" msgid="4781128097185272916">"Gerido pela sua entidade"</string>
+ <string name="work_mode_off_label" msgid="3194894777601421047">"As notificações e as aplicações estão desativadas."</string>
+ <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Fechar"</string>
+ <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Fechado"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Falhou: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
</resources>
diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml
index 7beedcba3f..bb4834f69d 100644
--- a/res/values-pt/strings.xml
+++ b/res/values-pt/strings.xml
@@ -26,57 +26,32 @@
<string name="safemode_shortcut_error" msgid="9160126848219158407">"App transferido por download desativado no modo de segurança"</string>
<string name="safemode_widget_error" msgid="4863470563535682004">"Widgets desativados no modo de segurança"</string>
<string name="shortcut_not_available" msgid="2536503539825726397">"O atalho não está disponível"</string>
- <string name="home_screen" msgid="5629429142036709174">"Início"</string>
- <string name="recent_task_option_split_screen" msgid="6690461455618725183">"Tela dividida"</string>
- <string name="split_screen_position_top" msgid="1504965011158689649">"Dividir para cima"</string>
- <string name="split_screen_position_left" msgid="7537793098851830883">"Dividir para a esquerda"</string>
- <string name="split_screen_position_right" msgid="1569377524925193369">"Dividir para a direita"</string>
- <string name="split_app_info_accessibility" msgid="5475288491241414932">"Informações do app %1$s"</string>
- <string name="long_press_widget_to_add" msgid="3587712543577675817">"Toque e mantenha pressionado para mover um widget."</string>
- <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Toque duas vezes e mantenha a tela pressionada para mover um widget ou usar ações personalizadas."</string>
+ <string name="home_screen" msgid="806512411299847073">"Tela inicial"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"Ações personalizadas"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"Toque e pressione para selecionar um widget."</string>
+ <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Toque duas vezes e segure para selecionar um widget ou usar ações personalizadas."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d de largura por %2$d de altura"</string>
- <string name="widget_preview_context_description" msgid="9045841361655787574">"Widget <xliff:g id="WIDGET_NAME">%1$s</xliff:g>"</string>
- <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Toque no widget e mantenha-o pressionado para movê-lo pela tela inicial"</string>
- <string name="add_to_home_screen" msgid="8631549138215492708">"Adicionar à tela inicial"</string>
- <string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"Widget <xliff:g id="WIDGET_NAME">%1$s</xliff:g> adicionado à tela inicial"</string>
- <string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# widget}one{# widget}other{# widgets}}"</string>
- <string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{# atalho}one{# atalho}other{# atalhos}}"</string>
- <string name="widgets_and_shortcuts_count" msgid="7209136747878365116">"<xliff:g id="WIDGETS_COUNT">%1$s</xliff:g>, <xliff:g id="SHORTCUTS_COUNT">%2$s</xliff:g>"</string>
- <string name="widget_button_text" msgid="2880537293434387943">"Widgets"</string>
- <string name="widgets_full_sheet_search_bar_hint" msgid="8484659090860596457">"Pesquisa"</string>
- <string name="widgets_full_sheet_cancel_button_description" msgid="5766167035728653605">"Limpar texto da caixa de pesquisa"</string>
- <string name="no_widgets_available" msgid="4337693382501046170">"Nenhum widget ou atalho disponível"</string>
- <string name="no_search_results" msgid="3787956167293097509">"Nenhum widget ou atalho encontrado"</string>
- <string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Pessoais"</string>
- <string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Trabalho"</string>
- <string name="widget_category_conversations" msgid="8894438636213590446">"Conversas"</string>
- <string name="widget_education_header" msgid="4874760613775913787">"Informações úteis ao seu alcance"</string>
- <string name="widget_education_content" msgid="745542879510751525">"Para receber informações sem precisar abrir apps, adicione widgets à sua tela inicial"</string>
- <string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Toque para mudar as configurações do widget"</string>
- <string name="widget_education_close_button" msgid="8676165703104836580">"Ok"</string>
- <string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Mudar as configurações do widget"</string>
- <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Pesquisar apps"</string>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Toque e mantenha pressionado para mover manualmente"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"Adicionar automaticamente"</string>
+ <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Apps de pesquisa"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Carregando apps…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"Nenhum app encontrado que corresponda a \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
<string name="all_apps_search_market_message" msgid="1366263386197059176">"Pesquisar mais apps"</string>
<string name="label_application" msgid="8531721983832654978">"App"</string>
- <string name="all_apps_label" msgid="5015784846527570951">"Todos os apps"</string>
<string name="notifications_header" msgid="1404149926117359025">"Notificações"</string>
- <string name="long_press_shortcut_to_add" msgid="5405328730817637737">"Toque e mantenha a tela pressionada para mover um atalho."</string>
- <string name="long_accessible_way_to_add_shortcut" msgid="2199537273817090740">"Toque duas vezes e mantenha a tela pressionada para mover um atalho ou usar ações personalizadas."</string>
- <string name="out_of_space" msgid="6692471482459245734">"Não há espaço nesta tela inicial"</string>
+ <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"Toque e segure para selecionar um atalho."</string>
+ <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"Toque duas vezes na tela e segure para selecionar um atalho ou usar ações personalizadas."</string>
+ <string name="out_of_space" msgid="4691004494942118364">"Não há mais espaço na tela inicial."</string>
<string name="hotseat_out_of_space" msgid="7448809638125333693">"Sem espaço na bandeja de favoritos"</string>
<string name="all_apps_button_label" msgid="8130441508702294465">"Lista de apps"</string>
- <string name="all_apps_search_results" msgid="5889367432531296759">"Resultados da pesquisa"</string>
<string name="all_apps_button_personal_label" msgid="1315764287305224468">"Lista de apps pessoais"</string>
<string name="all_apps_button_work_label" msgid="7270707118948892488">"Lista de apps profissionais"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"Início"</string>
<string name="remove_drop_target_label" msgid="7812859488053230776">"Remover"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"Desinstalar"</string>
<string name="app_info_drop_target_label" msgid="692894985365717661">"Informações do app"</string>
<string name="install_drop_target_label" msgid="2539096853673231757">"Instalar"</string>
- <string name="dismiss_prediction_label" msgid="3357562989568808658">"Não sugerir esse app"</string>
- <string name="pin_prediction" msgid="4196423321649756498">"Fixar previsão"</string>
<string name="permlab_install_shortcut" msgid="5632423390354674437">"instalar atalhos"</string>
<string name="permdesc_install_shortcut" msgid="923466509822011139">"Permite que um app adicione atalhos sem intervenção do usuário."</string>
<string name="permlab_read_settings" msgid="1941457408239617576">"ler configurações e atalhos da tela inicial"</string>
@@ -84,13 +59,15 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"gravar configurações e atalhos da tela inicial"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"Permite que o app altere as configurações e os atalhos na tela inicial."</string>
<string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> não tem permissão para fazer chamadas"</string>
- <string name="gadget_error_text" msgid="740356548025791839">"Não é possível carregar o widget"</string>
- <string name="gadget_setup_text" msgid="8348374825537681407">"Configurações de widget"</string>
- <string name="gadget_complete_setup_text" msgid="309040266978007925">"Toque para concluir a configuração"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"Problema ao carregar o widget"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"Configuração"</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"Este é um app do sistema e não pode ser desinstalado."</string>
- <string name="folder_hint_text" msgid="5174843001373488816">"Editar nome"</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"Pasta sem nome"</string>
<string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> desativado"</string>
- <string name="dotted_app_label" msgid="1704091277755818896">"{count,plural,offset:1 =1{O app {app_name} tem # notificação}one{O app {app_name} tem # notificação}other{O app {app_name} tem # notificações}}"</string>
+ <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+ <item quantity="one">O app <xliff:g id="APP_NAME_2">%1$s</xliff:g>tem <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> notificação</item>
+ <item quantity="other">O app <xliff:g id="APP_NAME_2">%1$s</xliff:g>tem <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> notificações</item>
+ </plurals>
<string name="default_scroll_format" msgid="7475544710230993317">"Página %1$d de %2$d"</string>
<string name="workspace_scroll_format" msgid="8458889198184077399">"Tela inicial %1$d de %2$d"</string>
<string name="workspace_new_page" msgid="257366611030256142">"Nova página na tela inicial"</string>
@@ -99,11 +76,11 @@
<string name="folder_tap_to_rename" msgid="4017685068016979677">"Toque para salvar o novo nome"</string>
<string name="folder_closed" msgid="4100806530910930934">"Pasta fechada"</string>
<string name="folder_renamed" msgid="1794088362165669656">"Pasta renomeada para <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="folder_name_format_exact" msgid="8626242716117004803">"Pasta: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> itens"</string>
- <string name="folder_name_format_overflow" msgid="4270108890534995199">"Pasta: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> ou mais itens"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"Pasta: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"Widgets"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Planos de fundo"</string>
- <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Plano de fundo e estilo"</string>
- <string name="settings_button_text" msgid="8873672322605444408">"Configurações da tela inicial"</string>
+ <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Estilos e planos de fundo"</string>
+ <string name="settings_button_text" msgid="8873672322605444408">"Config. tela inicial"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Desativado pelo administrador"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Permitir rotação da tela inicial"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Quando o smartphone for girado"</string>
@@ -114,16 +91,16 @@
<string name="msg_missing_notification_access" msgid="281113995110910548">"Para mostrar pontos de notificação, ative as notificações de app para <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="title_change_settings" msgid="1376365968844349552">"Alterar configurações"</string>
<string name="notification_dots_service_title" msgid="4284221181793592871">"Mostrar pontos de notificação"</string>
- <string name="auto_add_shortcuts_label" msgid="3698776050751790653">"Adicionar ícones de apps à tela inicial"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Adicionar ícone à tela inicial"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Para novos apps"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"Desconhecido"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"Remover"</string>
<string name="abandoned_search" msgid="891119232568284442">"Pesquisar"</string>
<string name="abandoned_promises_title" msgid="7096178467971716750">"Este app não está instalado"</string>
<string name="abandoned_promise_explanation" msgid="3990027586878167529">"O app deste ícone não está instalado. Você pode remover o ícone, ou procurar o app e instalá-lo manualmente."</string>
- <string name="app_installing_title" msgid="5864044122733792085">"Instalando <xliff:g id="NAME">%1$s</xliff:g>. <xliff:g id="PROGRESS">%2$s</xliff:g> concluído"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"Fazendo download de <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="PROGRESS">%2$s</xliff:g> concluído"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"Aguardando instalação de <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"Widgets do <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="widgets_list" msgid="796804551140113767">"Lista de widgets"</string>
<string name="widgets_list_closed" msgid="6141506579418771922">"Lista de widgets fechada"</string>
<string name="action_add_to_workspace" msgid="8902165848117513641">"Adicionar à tela inicial"</string>
@@ -151,20 +128,15 @@
<string name="action_deep_shortcut" msgid="2864038805849372848">"Atalhos"</string>
<string name="shortcuts_menu_with_notifications_description" msgid="2676582286544232849">"Atalhos e notificações"</string>
<string name="action_dismiss_notification" msgid="5909461085055959187">"Dispensar"</string>
- <string name="accessibility_close" msgid="2277148124685870734">"Fechar"</string>
<string name="notification_dismissed" msgid="6002233469409822874">"Notificação dispensada"</string>
<string name="all_apps_personal_tab" msgid="4190252696685155002">"Pessoais"</string>
- <string name="all_apps_work_tab" msgid="4884822796154055118">"Trabalho"</string>
+ <string name="all_apps_work_tab" msgid="4884822796154055118">"Comerciais"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"Perfil de trabalho"</string>
- <string name="work_profile_edu_work_apps" msgid="7895468576497746520">"Os apps de trabalho são identificados e ficam visíveis para o adm. de TI"</string>
- <string name="work_profile_edu_accept" msgid="6069788082535149071">"Ok"</string>
- <string name="work_apps_paused_title" msgid="3040901117349444598">"Os apps de trabalho foram pausados"</string>
- <string name="work_apps_paused_body" msgid="261634750995824906">"Os apps de trabalho não podem enviar notificações, usar a bateria nem acessar o local"</string>
- <string name="work_apps_paused_content_description" msgid="5149623040804051095">"Os apps de trabalho estão desativados. Eles não podem enviar notificações, usar a bateria nem acessar o local"</string>
- <string name="work_apps_paused_edu_banner" msgid="8872412121608402058">"Os apps de trabalho são identificados e ficam visíveis para o adm. de TI"</string>
- <string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"Ok"</string>
- <string name="work_apps_pause_btn_text" msgid="1921059713673767460">"Desativar apps de trabalho"</string>
- <string name="work_apps_enable_btn_text" msgid="1156432622148413741">"Ativar apps de trabalho"</string>
- <string name="developer_options_filter_hint" msgid="5896817443635989056">"Filtrar"</string>
+ <string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"Localizar apps de trabalho aqui"</string>
+ <string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"Cada app de trabalho tem um selo e é mantido em segurança pela sua organização. Mova os apps para sua tela inicial para facilitar o acesso."</string>
+ <string name="work_mode_on_label" msgid="4781128097185272916">"Gerenciados pela sua organização"</string>
+ <string name="work_mode_off_label" msgid="3194894777601421047">"As notificações e os apps estão desativados"</string>
+ <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Fechar"</string>
+ <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Fechado"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Falha: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
</resources>
diff --git a/res/values-ro/strings.xml b/res/values-ro/strings.xml
index 14db745fb6..f8a61f11f7 100644
--- a/res/values-ro/strings.xml
+++ b/res/values-ro/strings.xml
@@ -26,57 +26,32 @@
<string name="safemode_shortcut_error" msgid="9160126848219158407">"Aplicația descărcată este dezactivată în modul de siguranță"</string>
<string name="safemode_widget_error" msgid="4863470563535682004">"Widgeturile sunt dezactivate în modul de siguranță"</string>
<string name="shortcut_not_available" msgid="2536503539825726397">"Comanda rapidă nu este disponibilă"</string>
- <string name="home_screen" msgid="5629429142036709174">"Pagina de pornire"</string>
- <string name="recent_task_option_split_screen" msgid="6690461455618725183">"Ecran împărțit"</string>
- <string name="split_screen_position_top" msgid="1504965011158689649">"Împărțiți în sus"</string>
- <string name="split_screen_position_left" msgid="7537793098851830883">"Împărțiți în stânga"</string>
- <string name="split_screen_position_right" msgid="1569377524925193369">"Împărțiți în dreapta"</string>
- <string name="split_app_info_accessibility" msgid="5475288491241414932">"Informații despre aplicație pentru %1$s"</string>
- <string name="long_press_widget_to_add" msgid="3587712543577675817">"Atingeți și țineți apăsat pentru a muta un widget."</string>
- <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Atingeți de două ori și țineți apăsat pentru a muta un widget sau folosiți acțiuni personalizate."</string>
+ <string name="home_screen" msgid="806512411299847073">"Ecran de pornire"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"Acțiuni personalizate"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"Atingeți lung un widget pentru a-l alege."</string>
+ <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Atingeți de două ori și mențineți apăsat ca să alegeți un widget sau folosiți acțiuni personalizate."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d lățime și %2$d înălțime"</string>
- <string name="widget_preview_context_description" msgid="9045841361655787574">"Widgetul <xliff:g id="WIDGET_NAME">%1$s</xliff:g>"</string>
- <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Atingeți lung widgetul pentru a-l muta pe ecranul de pornire"</string>
- <string name="add_to_home_screen" msgid="8631549138215492708">"Adăugați pe ecranul de pornire"</string>
- <string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"Widgetul <xliff:g id="WIDGET_NAME">%1$s</xliff:g> a fost adăugat pe ecranul de pornire"</string>
- <string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# widget}few{# widgeturi}other{# de widgeturi}}"</string>
- <string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{# comandă rapidă}few{# comenzi rapide}other{# de comenzi rapide}}"</string>
- <string name="widgets_and_shortcuts_count" msgid="7209136747878365116">"<xliff:g id="WIDGETS_COUNT">%1$s</xliff:g> <xliff:g id="SHORTCUTS_COUNT">%2$s</xliff:g>"</string>
- <string name="widget_button_text" msgid="2880537293434387943">"Widgeturi"</string>
- <string name="widgets_full_sheet_search_bar_hint" msgid="8484659090860596457">"Căutare"</string>
- <string name="widgets_full_sheet_cancel_button_description" msgid="5766167035728653605">"Ștergeți textul din caseta de căutare"</string>
- <string name="no_widgets_available" msgid="4337693382501046170">"Widgeturile și comenzile rapide nu sunt disponibile"</string>
- <string name="no_search_results" msgid="3787956167293097509">"Nu au fost găsite widgeturi sau comenzi rapide"</string>
- <string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Personale"</string>
- <string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Serviciu"</string>
- <string name="widget_category_conversations" msgid="8894438636213590446">"Conversații"</string>
- <string name="widget_education_header" msgid="4874760613775913787">"Informații utile la îndemâna dvs."</string>
- <string name="widget_education_content" msgid="745542879510751525">"Pentru a primi informații fără să deschideți aplicațiile, puteți adăuga widgeturi pe ecranul de pornire"</string>
- <string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Atingeți ca să schimbați setările pentru widgeturi"</string>
- <string name="widget_education_close_button" msgid="8676165703104836580">"OK"</string>
- <string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Modificați setările pentru widgeturi"</string>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Atingeți lung pentru a plasa manual"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"Adăugați automat"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Căutați aplicații"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Se încarcă aplicații…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"Nu s-a găsit nicio aplicație pentru „<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
<string name="all_apps_search_market_message" msgid="1366263386197059176">"Căutați mai multe aplicații"</string>
<string name="label_application" msgid="8531721983832654978">"Aplicație"</string>
- <string name="all_apps_label" msgid="5015784846527570951">"Toate aplicațiile"</string>
<string name="notifications_header" msgid="1404149926117359025">"Notificări"</string>
- <string name="long_press_shortcut_to_add" msgid="5405328730817637737">"Atingeți și țineți apăsat pentru a muta comanda rapidă."</string>
- <string name="long_accessible_way_to_add_shortcut" msgid="2199537273817090740">"Atingeți de două ori și țineți apăsat pentru a muta o comandă rapidă sau folosiți acțiuni personalizate."</string>
- <string name="out_of_space" msgid="6692471482459245734">"Nu există spațiu liber pe acest ecran de pornire"</string>
+ <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"Atingeți lung pentru a selecta o comandă rapidă."</string>
+ <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"Atingeți lung pentru a selecta o comandă rapidă sau folosiți acțiuni personalizate."</string>
+ <string name="out_of_space" msgid="4691004494942118364">"Nu mai este loc pe acest Ecran de pornire."</string>
<string name="hotseat_out_of_space" msgid="7448809638125333693">"Spațiu epuizat în bara Preferate"</string>
<string name="all_apps_button_label" msgid="8130441508702294465">"Lista de aplicații"</string>
- <string name="all_apps_search_results" msgid="5889367432531296759">"Rezultatele căutării"</string>
<string name="all_apps_button_personal_label" msgid="1315764287305224468">"Lista de aplicații personale"</string>
<string name="all_apps_button_work_label" msgid="7270707118948892488">"Lista de aplicații de serviciu"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"Ecran de pornire"</string>
<string name="remove_drop_target_label" msgid="7812859488053230776">"Eliminați"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"Dezinstalați"</string>
<string name="app_info_drop_target_label" msgid="692894985365717661">"Informații despre aplicații"</string>
<string name="install_drop_target_label" msgid="2539096853673231757">"Instalați"</string>
- <string name="dismiss_prediction_label" msgid="3357562989568808658">"Nu sugera aplicația"</string>
- <string name="pin_prediction" msgid="4196423321649756498">"Fixează predicția"</string>
<string name="permlab_install_shortcut" msgid="5632423390354674437">"instalează comenzi rapide"</string>
<string name="permdesc_install_shortcut" msgid="923466509822011139">"Permite unei aplicații să adauge comenzi rapide fără intervenția utilizatorului."</string>
<string name="permlab_read_settings" msgid="1941457408239617576">"citește setări și comenzi rapide pentru ecranul de pornire"</string>
@@ -84,13 +59,16 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"scrie setări și comenzi rapide pentru ecranul de pornire"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"Permite aplicației să modifice setările și comenzile rapide din ecranul de pornire."</string>
<string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> nu are permisiunea de a apela"</string>
- <string name="gadget_error_text" msgid="740356548025791839">"Widgetul nu poate fi încărcat"</string>
- <string name="gadget_setup_text" msgid="8348374825537681407">"Setări pentru widget"</string>
- <string name="gadget_complete_setup_text" msgid="309040266978007925">"Atingeți pentru a finaliza configurarea"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"Problemă la încărcarea widgetului"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"Configurați"</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"Aceasta este o aplicație de sistem și nu poate fi dezinstalată."</string>
- <string name="folder_hint_text" msgid="5174843001373488816">"Modificați numele"</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"Dosar fără nume"</string>
<string name="disabled_app_label" msgid="6673129024321402780">"S-a dezactivat <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
- <string name="dotted_app_label" msgid="1704091277755818896">"{count,plural,offset:1 =1{{app_name} are # notificare}few{{app_name} are # notificări}other{{app_name} are # de notificări}}"</string>
+ <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+ <item quantity="few"><xliff:g id="APP_NAME_2">%1$s</xliff:g> are <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> notificări</item>
+ <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>​ are <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> de notificări</item>
+ <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g> are <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> notificare</item>
+ </plurals>
<string name="default_scroll_format" msgid="7475544710230993317">"Pagina %1$d din %2$d"</string>
<string name="workspace_scroll_format" msgid="8458889198184077399">"Ecranul de pornire %1$d din %2$d"</string>
<string name="workspace_new_page" msgid="257366611030256142">"Pagină nouă pe ecranul de pornire"</string>
@@ -99,10 +77,10 @@
<string name="folder_tap_to_rename" msgid="4017685068016979677">"Atingeți pentru a salva noul nume"</string>
<string name="folder_closed" msgid="4100806530910930934">"Dosar închis"</string>
<string name="folder_renamed" msgid="1794088362165669656">"Dosar redenumit <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="folder_name_format_exact" msgid="8626242716117004803">"Dosar: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> elemente"</string>
- <string name="folder_name_format_overflow" msgid="4270108890534995199">"Dosar: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> sau mai multe elemente"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"Dosar: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"Widgeturi"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Imagini de fundal"</string>
- <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Imagine de fundal și stil"</string>
+ <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Stiluri și imagini de fundal"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Setări ecran de pornire"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Dezactivată de administrator"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Permite rotirea ecranului de pornire"</string>
@@ -114,16 +92,16 @@
<string name="msg_missing_notification_access" msgid="281113995110910548">"Pentru a afișa punctele de notificare, activați notificările din aplicație pentru <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="title_change_settings" msgid="1376365968844349552">"Modificați setările"</string>
<string name="notification_dots_service_title" msgid="4284221181793592871">"Afișați punctele de notificare"</string>
- <string name="auto_add_shortcuts_label" msgid="3698776050751790653">"Adaugă pictograme de aplicații pe ecran"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Adaugă pictograme în ecranul de pornire"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Pentru aplicații noi"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"Necunoscut"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"Eliminați"</string>
<string name="abandoned_search" msgid="891119232568284442">"Căutați"</string>
<string name="abandoned_promises_title" msgid="7096178467971716750">"Aplicația nu este instalată"</string>
<string name="abandoned_promise_explanation" msgid="3990027586878167529">"Aplicația pentru această pictogramă nu este instalată. Puteți să ștergeți pictograma sau să căutați aplicația și s-o instalați manual."</string>
- <string name="app_installing_title" msgid="5864044122733792085">"<xliff:g id="NAME">%1$s</xliff:g> se instalează, <xliff:g id="PROGRESS">%2$s</xliff:g> finalizat"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> se descarcă (finalizat <xliff:g id="PROGRESS">%2$s</xliff:g>)"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> așteaptă instalarea"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"Widgeturi <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="widgets_list" msgid="796804551140113767">"Listă de widgeturi"</string>
<string name="widgets_list_closed" msgid="6141506579418771922">"Lista de widgeturi este închisă"</string>
<string name="action_add_to_workspace" msgid="8902165848117513641">"Adăugați pe ecranul de pornire"</string>
@@ -151,20 +129,15 @@
<string name="action_deep_shortcut" msgid="2864038805849372848">"Comenzi rapide"</string>
<string name="shortcuts_menu_with_notifications_description" msgid="2676582286544232849">"Comenzi rapide și notificări"</string>
<string name="action_dismiss_notification" msgid="5909461085055959187">"Închideți"</string>
- <string name="accessibility_close" msgid="2277148124685870734">"Închideți"</string>
<string name="notification_dismissed" msgid="6002233469409822874">"Notificare închisă"</string>
<string name="all_apps_personal_tab" msgid="4190252696685155002">"Personale"</string>
<string name="all_apps_work_tab" msgid="4884822796154055118">"Profesionale"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"Profil de serviciu"</string>
- <string name="work_profile_edu_work_apps" msgid="7895468576497746520">"Aplicațiile pentru lucru sunt marcate și vizibile pentru administratorul IT"</string>
- <string name="work_profile_edu_accept" msgid="6069788082535149071">"OK"</string>
- <string name="work_apps_paused_title" msgid="3040901117349444598">"Aplicațiile pentru lucru sunt întrerupte"</string>
- <string name="work_apps_paused_body" msgid="261634750995824906">"Aplicațiile pentru lucru nu pot să vă trimită notificări, să folosească bateria sau să vă acceseze locația"</string>
- <string name="work_apps_paused_content_description" msgid="5149623040804051095">"Aplicațiile pentru lucru sunt dezactivate. Acestea nu pot să vă trimită notificări, să folosească bateria sau să vă acceseze locația."</string>
- <string name="work_apps_paused_edu_banner" msgid="8872412121608402058">"Aplicațiile pentru lucru sunt marcate și vizibile pentru administratorul IT"</string>
- <string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"OK"</string>
- <string name="work_apps_pause_btn_text" msgid="1921059713673767460">"Dezactivați aplicațiile pentru lucru"</string>
- <string name="work_apps_enable_btn_text" msgid="1156432622148413741">"Activați aplicațiile pentru lucru"</string>
- <string name="developer_options_filter_hint" msgid="5896817443635989056">"Filtru"</string>
+ <string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"Găsiți aplicații de serviciu aici"</string>
+ <string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"Fiecare aplicație de serviciu are o insignă și este păstrată în siguranță de organizația dvs. Mutați aplicațiile pe ecranul de pornire pentru acces mai ușor."</string>
+ <string name="work_mode_on_label" msgid="4781128097185272916">"Gestionat de organizația dvs."</string>
+ <string name="work_mode_off_label" msgid="3194894777601421047">"Notificările și aplicațiile sunt dezactivate"</string>
+ <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Închideți"</string>
+ <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Închis"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Eșuare: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
</resources>
diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml
index 4e72d40f63..23b00d0936 100644
--- a/res/values-ru/strings.xml
+++ b/res/values-ru/strings.xml
@@ -20,63 +20,39 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="649227358658669779">"Launcher3"</string>
+ <string name="folder_name" msgid="7371454440695724752"></string>
<string name="work_folder_name" msgid="3753320833950115786">"Работа"</string>
<string name="activity_not_found" msgid="8071924732094499514">"Приложение удалено"</string>
<string name="activity_not_available" msgid="7456344436509528827">"Приложение недоступно"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"Скачанное приложение отключено в безопасном режиме"</string>
<string name="safemode_widget_error" msgid="4863470563535682004">"Виджеты отключены в безопасном режиме"</string>
<string name="shortcut_not_available" msgid="2536503539825726397">"Ярлык недоступен"</string>
- <string name="home_screen" msgid="5629429142036709174">"Главный экран"</string>
- <string name="recent_task_option_split_screen" msgid="6690461455618725183">"Разделить экран"</string>
- <string name="split_screen_position_top" msgid="1504965011158689649">"Приложение сверху"</string>
- <string name="split_screen_position_left" msgid="7537793098851830883">"Приложение слева"</string>
- <string name="split_screen_position_right" msgid="1569377524925193369">"Приложение справа"</string>
- <string name="split_app_info_accessibility" msgid="5475288491241414932">"Сведения о приложении \"%1$s\""</string>
- <string name="long_press_widget_to_add" msgid="3587712543577675817">"Нажмите и удерживайте для переноса виджета."</string>
- <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Чтобы использовать специальные действия или перенести виджет, нажмите на него дважды и удерживайте."</string>
+ <string name="home_screen" msgid="806512411299847073">"Главный экран"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"Специальные действия"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"Чтобы выбрать виджет, нажмите на значок и удерживайте его."</string>
+ <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Чтобы выбрать виджет или использовать специальные действия, нажмите на него дважды и не отпускайте."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d x %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"Ширина %1$d, высота %2$d"</string>
- <string name="widget_preview_context_description" msgid="9045841361655787574">"Виджет \"<xliff:g id="WIDGET_NAME">%1$s</xliff:g>\""</string>
- <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Чтобы переместить виджет, нажмите на него и удерживайте."</string>
- <string name="add_to_home_screen" msgid="8631549138215492708">"Добавить на главный экран"</string>
- <string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"Виджет \"<xliff:g id="WIDGET_NAME">%1$s</xliff:g>\" добавлен на главный экран"</string>
- <string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# виджет}one{# виджет}few{# виджета}many{# виджетов}other{# виджета}}"</string>
- <string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{# быстрая команда}one{# быстрая команда}few{# быстрые команды}many{# быстрых команд}other{# быстрой команды}}"</string>
- <string name="widgets_and_shortcuts_count" msgid="7209136747878365116">"<xliff:g id="WIDGETS_COUNT">%1$s</xliff:g>, <xliff:g id="SHORTCUTS_COUNT">%2$s</xliff:g>"</string>
- <string name="widget_button_text" msgid="2880537293434387943">"Виджеты"</string>
- <string name="widgets_full_sheet_search_bar_hint" msgid="8484659090860596457">"Поиск"</string>
- <string name="widgets_full_sheet_cancel_button_description" msgid="5766167035728653605">"Удалить текст из окна поиска"</string>
- <string name="no_widgets_available" msgid="4337693382501046170">"Виджеты и ярлыки недоступны."</string>
- <string name="no_search_results" msgid="3787956167293097509">"Виджеты и ярлыки не найдены."</string>
- <string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Личные виджеты"</string>
- <string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Рабочие виджеты"</string>
- <string name="widget_category_conversations" msgid="8894438636213590446">"Разговоры"</string>
- <string name="widget_education_header" msgid="4874760613775913787">"Вся нужная информация перед глазами"</string>
- <string name="widget_education_content" msgid="745542879510751525">"Чтобы не открывать приложения каждый раз, когда нужна информация, добавьте виджеты на главный экран."</string>
- <string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Нажмите, чтобы изменить настройки виджета"</string>
- <string name="widget_education_close_button" msgid="8676165703104836580">"ОК"</string>
- <string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Изменить настройки виджета"</string>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Нажмите и удерживайте, чтобы добавить вручную."</string>
+ <string name="place_automatically" msgid="8064208734425456485">"Добавить автоматически"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Поиск приложений"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Загрузка приложений…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"По запросу \"<xliff:g id="QUERY">%1$s</xliff:g>\" ничего не найдено"</string>
<string name="all_apps_search_market_message" msgid="1366263386197059176">"Искать другие приложения"</string>
<string name="label_application" msgid="8531721983832654978">"Приложение"</string>
- <string name="all_apps_label" msgid="5015784846527570951">"Все приложения"</string>
<string name="notifications_header" msgid="1404149926117359025">"Уведомления"</string>
- <string name="long_press_shortcut_to_add" msgid="5405328730817637737">"Нажмите и удерживайте для переноса ярлыка."</string>
- <string name="long_accessible_way_to_add_shortcut" msgid="2199537273817090740">"Чтобы использовать специальные действия или перенести ярлык, нажмите на него дважды и удерживайте."</string>
- <string name="out_of_space" msgid="6692471482459245734">"На главном экране нет свободного места."</string>
+ <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"Нажмите и удерживайте, чтобы выбрать ярлык."</string>
+ <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"Нажмите дважды и удерживайте, чтобы выбрать ярлык или использовать специальные действия."</string>
+ <string name="out_of_space" msgid="4691004494942118364">"На этом экране все занято"</string>
<string name="hotseat_out_of_space" msgid="7448809638125333693">"В разделе \"Избранное\" больше нет места"</string>
<string name="all_apps_button_label" msgid="8130441508702294465">"Список приложений"</string>
- <string name="all_apps_search_results" msgid="5889367432531296759">"Результаты поиска"</string>
<string name="all_apps_button_personal_label" msgid="1315764287305224468">"Открыть список личных приложений"</string>
<string name="all_apps_button_work_label" msgid="7270707118948892488">"Открыть список приложений для работы"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"Главный экран"</string>
<string name="remove_drop_target_label" msgid="7812859488053230776">"Убрать"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"Удалить"</string>
<string name="app_info_drop_target_label" msgid="692894985365717661">"О приложении"</string>
<string name="install_drop_target_label" msgid="2539096853673231757">"Установить"</string>
- <string name="dismiss_prediction_label" msgid="3357562989568808658">"Не рекомендовать"</string>
- <string name="pin_prediction" msgid="4196423321649756498">"Закрепить рекомендацию"</string>
<string name="permlab_install_shortcut" msgid="5632423390354674437">"Создание ярлыков"</string>
<string name="permdesc_install_shortcut" msgid="923466509822011139">"Приложение сможет самостоятельно добавлять ярлыки."</string>
<string name="permlab_read_settings" msgid="1941457408239617576">"Доступ к настройкам и ярлыкам главного экрана"</string>
@@ -84,13 +60,17 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"Изменение настроек и ярлыков главного экрана"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"Приложение сможет изменять настройки и ярлыки на главном экране."</string>
<string name="msg_no_phone_permission" msgid="9208659281529857371">"Приложение <xliff:g id="APP_NAME">%1$s</xliff:g> не может делать телефонные звонки"</string>
- <string name="gadget_error_text" msgid="740356548025791839">"Не удается загрузить виджет."</string>
- <string name="gadget_setup_text" msgid="8348374825537681407">"Настройки виджета"</string>
- <string name="gadget_complete_setup_text" msgid="309040266978007925">"Нажмите, чтобы завершить настройку."</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"Не удалось загрузить виджет"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"Настройка"</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"Это системное приложение, его нельзя удалить."</string>
- <string name="folder_hint_text" msgid="5174843001373488816">"Измените название"</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"Папка без названия"</string>
<string name="disabled_app_label" msgid="6673129024321402780">"Приложение <xliff:g id="APP_NAME">%1$s</xliff:g> отключено"</string>
- <string name="dotted_app_label" msgid="1704091277755818896">"{count,plural,offset:1 =1{В приложении \"{app_name}\" # уведомление}one{В приложении \"{app_name}\" # уведомление}few{В приложении \"{app_name}\" # уведомления}many{В приложении \"{app_name}\" # уведомлений}other{В приложении \"{app_name}\" # уведомления}}"</string>
+ <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+ <item quantity="one">В приложении \"<xliff:g id="APP_NAME_2">%1$s</xliff:g>\" <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> уведомление</item>
+ <item quantity="few">В приложении \"<xliff:g id="APP_NAME_2">%1$s</xliff:g>\" <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> уведомления</item>
+ <item quantity="many">В приложении \"<xliff:g id="APP_NAME_2">%1$s</xliff:g>\" <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> уведомлений</item>
+ <item quantity="other">В приложении \"<xliff:g id="APP_NAME_2">%1$s</xliff:g>\" <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> уведомления</item>
+ </plurals>
<string name="default_scroll_format" msgid="7475544710230993317">"Стр. %1$d из %2$d"</string>
<string name="workspace_scroll_format" msgid="8458889198184077399">"Главный экран %1$d из %2$d"</string>
<string name="workspace_new_page" msgid="257366611030256142">"Новый экран"</string>
@@ -99,14 +79,14 @@
<string name="folder_tap_to_rename" msgid="4017685068016979677">"Нажмите, чтобы подтвердить переименование"</string>
<string name="folder_closed" msgid="4100806530910930934">"Папка закрыта"</string>
<string name="folder_renamed" msgid="1794088362165669656">"Папка переименована в \"<xliff:g id="NAME">%1$s</xliff:g>\""</string>
- <string name="folder_name_format_exact" msgid="8626242716117004803">"Папка \"<xliff:g id="NAME">%1$s</xliff:g>\" (объектов: <xliff:g id="SIZE">%2$d</xliff:g>)"</string>
- <string name="folder_name_format_overflow" msgid="4270108890534995199">"Папка \"<xliff:g id="NAME">%1$s</xliff:g>\" (объектов: <xliff:g id="SIZE">%2$d</xliff:g> или больше)"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"Папка: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"Виджеты"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Обои"</string>
- <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Обои и стиль"</string>
+ <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Стили и обои"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Главный экран"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Функция отключена администратором"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Разрешить поворачивать главный экран"</string>
- <string name="allow_rotation_desc" msgid="8662546029078692509">"При повороте телефона"</string>
+ <string name="allow_rotation_desc" msgid="8662546029078692509">"Когда телефон повернут"</string>
<string name="notification_dots_title" msgid="9062440428204120317">"Значки уведомлений"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"Включены"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"Отключены"</string>
@@ -114,22 +94,22 @@
<string name="msg_missing_notification_access" msgid="281113995110910548">"Чтобы показывать значки уведомлений, включите уведомления в приложении \"<xliff:g id="NAME">%1$s</xliff:g>\""</string>
<string name="title_change_settings" msgid="1376365968844349552">"Изменить настройки"</string>
<string name="notification_dots_service_title" msgid="4284221181793592871">"Показывать значки уведомлений"</string>
- <string name="auto_add_shortcuts_label" msgid="3698776050751790653">"Добавлять значки на главный экран"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Добавлять значки"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Добавлять значки установленных приложений на главный экран"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"Неизвестно"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"Убрать"</string>
<string name="abandoned_search" msgid="891119232568284442">"Найти"</string>
<string name="abandoned_promises_title" msgid="7096178467971716750">"Приложение не установлено"</string>
<string name="abandoned_promise_explanation" msgid="3990027586878167529">"Приложение не установлено. Вы можете удалить значок или найти приложение и установить его вручную."</string>
- <string name="app_installing_title" msgid="5864044122733792085">"Установка приложения \"<xliff:g id="NAME">%1$s</xliff:g>\" (выполнено <xliff:g id="PROGRESS">%2$s</xliff:g>)"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"Скачивается \"<xliff:g id="NAME">%1$s</xliff:g>\" (<xliff:g id="PROGRESS">%2$s</xliff:g>)"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"Ожидание установки \"<xliff:g id="NAME">%1$s</xliff:g>\""</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"<xliff:g id="NAME">%1$s</xliff:g>: виджеты"</string>
<string name="widgets_list" msgid="796804551140113767">"Список виджетов"</string>
<string name="widgets_list_closed" msgid="6141506579418771922">"Список виджетов закрыт"</string>
<string name="action_add_to_workspace" msgid="8902165848117513641">"Добавить на главный экран"</string>
<string name="action_move_here" msgid="2170188780612570250">"Переместить элемент сюда"</string>
<string name="item_added_to_workspace" msgid="4211073925752213539">"Элемент добавлен на главный экран"</string>
- <string name="item_removed" msgid="851119963877842327">"Объект удален."</string>
+ <string name="item_removed" msgid="851119963877842327">"Элемент удален"</string>
<string name="undo" msgid="4151576204245173321">"Отменить"</string>
<string name="action_move" msgid="4339390619886385032">"Переместить элемент"</string>
<string name="move_to_empty_cell" msgid="2833711483015685619">"Переместить в ячейку <xliff:g id="NUMBER_0">%1$s</xliff:g> <xliff:g id="NUMBER_1">%2$s</xliff:g>"</string>
@@ -151,20 +131,15 @@
<string name="action_deep_shortcut" msgid="2864038805849372848">"Ярлыки"</string>
<string name="shortcuts_menu_with_notifications_description" msgid="2676582286544232849">"Ярлыки и уведомления"</string>
<string name="action_dismiss_notification" msgid="5909461085055959187">"Закрыть"</string>
- <string name="accessibility_close" msgid="2277148124685870734">"Закрыть"</string>
<string name="notification_dismissed" msgid="6002233469409822874">"Уведомление закрыто"</string>
<string name="all_apps_personal_tab" msgid="4190252696685155002">"Личные"</string>
<string name="all_apps_work_tab" msgid="4884822796154055118">"Рабочие"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"Рабочий профиль"</string>
- <string name="work_profile_edu_work_apps" msgid="7895468576497746520">"У рабочих приложений есть специальная пометка. Они видны системному администратору."</string>
- <string name="work_profile_edu_accept" msgid="6069788082535149071">"ОК"</string>
- <string name="work_apps_paused_title" msgid="3040901117349444598">"Рабочие приложения приостановлены"</string>
- <string name="work_apps_paused_body" msgid="261634750995824906">"Рабочие приложения не могут отправлять уведомления, расходовать заряд батареи и получать доступ к данным о вашем местоположении."</string>
- <string name="work_apps_paused_content_description" msgid="5149623040804051095">"Рабочие приложения отключены. Они не могут отправлять уведомления, расходовать заряд батареи и получать доступ к вашему местоположению."</string>
- <string name="work_apps_paused_edu_banner" msgid="8872412121608402058">"У рабочих приложений есть специальная пометка. Они видны системному администратору."</string>
- <string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"ОК"</string>
- <string name="work_apps_pause_btn_text" msgid="1921059713673767460">"Отключить рабочие приложения"</string>
- <string name="work_apps_enable_btn_text" msgid="1156432622148413741">"Включить рабочие приложения"</string>
- <string name="developer_options_filter_hint" msgid="5896817443635989056">"Фильтр"</string>
+ <string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"Приложения для работы"</string>
+ <string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"Рабочие приложения отмечены специальным значком. Их безопасность обеспечивает ваша организация. Для удобства перенесите эти приложения на главный экран."</string>
+ <string name="work_mode_on_label" msgid="4781128097185272916">"Управляется вашей организацией"</string>
+ <string name="work_mode_off_label" msgid="3194894777601421047">"Уведомления и приложения отключены."</string>
+ <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Закрыть"</string>
+ <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Закрыта"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Не удалось выполнить действие (<xliff:g id="WHAT">%1$s</xliff:g>)."</string>
</resources>
diff --git a/res/values-si/strings.xml b/res/values-si/strings.xml
index 17531bd2fe..ef99a59e4e 100644
--- a/res/values-si/strings.xml
+++ b/res/values-si/strings.xml
@@ -20,63 +20,39 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="649227358658669779">"Launcher3"</string>
+ <string name="folder_name" msgid="7371454440695724752"></string>
<string name="work_folder_name" msgid="3753320833950115786">"කාර්යාලය"</string>
<string name="activity_not_found" msgid="8071924732094499514">"යෙදුම ස්ථාපනය කර නැත."</string>
<string name="activity_not_available" msgid="7456344436509528827">"යෙදුම නොතිබේ"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"ආරක්ෂිත ආකාරය තුළ බාගන්න ලද යෙදුම් අබල කරන්න"</string>
<string name="safemode_widget_error" msgid="4863470563535682004">"සුරක්ෂිත ආකාරය තුළ විජටය අබල කරන ලදි"</string>
<string name="shortcut_not_available" msgid="2536503539825726397">"කෙටි මග ලබා ගත නොහැකිය"</string>
- <string name="home_screen" msgid="5629429142036709174">"මුල් පිටුව"</string>
- <string name="recent_task_option_split_screen" msgid="6690461455618725183">"බෙදුම් තිරය"</string>
- <string name="split_screen_position_top" msgid="1504965011158689649">"ඉහළ බෙදන්න"</string>
- <string name="split_screen_position_left" msgid="7537793098851830883">"වම බෙදන්න"</string>
- <string name="split_screen_position_right" msgid="1569377524925193369">"දකුණ බෙදන්න"</string>
- <string name="split_app_info_accessibility" msgid="5475288491241414932">"%1$s සඳහා යෙදුම් තතු"</string>
- <string name="long_press_widget_to_add" msgid="3587712543577675817">"විජට් එකක් ගෙන යාමට ස්පර්ශ කර අල්ලා ගෙන සිටින්න."</string>
- <string name="long_accessible_way_to_add" msgid="2733588281439571974">"විජට් එකක් ගෙන යාමට හෝ අභිරුචි ක්‍රියා භාවිත කිරීමට දෙවරක් තට්ටු කර අල්ලා ගෙන සිටින්න."</string>
+ <string name="home_screen" msgid="806512411299847073">"මුල් පිටු තිරය"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"අභිරුචි ක්‍රියා"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"විජට් එක ස්පර්ශ කර අහුලා ගැනීමට අල්ලාගෙන සිටින්න."</string>
+ <string name="long_accessible_way_to_add" msgid="4289502106628154155">"විජට් එකක් අහුලා ගැනීමට හෝ අභිරුචි ක්‍රියා කිරීමට ඩබල් ටැප් කර අල්ලා ගෙන සිටින්න."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"පළල %1$d උස %2$d"</string>
- <string name="widget_preview_context_description" msgid="9045841361655787574">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g> විජට්ටුව"</string>
- <string name="add_item_request_drag_hint" msgid="5653291305078645405">"එය මුල් පිටු තිරය වටා ගෙන යාමට විජට් එක ස්පර්ශ කර අල්ලා ගන්න"</string>
- <string name="add_to_home_screen" msgid="8631549138215492708">"මුල් පිටු තිරය වෙත එක් කරන්න"</string>
- <string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g> විජට්ටුව මුල් පිටු තිරය වෙත එක් කරන ලදි"</string>
- <string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{විජට් #}one{විජට් #}other{විජට් #}}"</string>
- <string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{කෙටි මං #}one{කෙටි මං #}other{කෙටි මං #}}"</string>
- <string name="widgets_and_shortcuts_count" msgid="7209136747878365116">"<xliff:g id="WIDGETS_COUNT">%1$s</xliff:g>, <xliff:g id="SHORTCUTS_COUNT">%2$s</xliff:g>"</string>
- <string name="widget_button_text" msgid="2880537293434387943">"විජට්"</string>
- <string name="widgets_full_sheet_search_bar_hint" msgid="8484659090860596457">"සෙවීම"</string>
- <string name="widgets_full_sheet_cancel_button_description" msgid="5766167035728653605">"සෙවීම් කොටුවෙන් පෙළ හිස් කරන්න"</string>
- <string name="no_widgets_available" msgid="4337693382501046170">"විජට් සහ කෙටි මං ලබා ගත නොහැකිය"</string>
- <string name="no_search_results" msgid="3787956167293097509">"විජට් හෝ කෙටි මං හමු නොවීය"</string>
- <string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"පුද්ගලික"</string>
- <string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"කාර්යාලය"</string>
- <string name="widget_category_conversations" msgid="8894438636213590446">"සංවාද"</string>
- <string name="widget_education_header" msgid="4874760613775913787">"ප්‍රයෝජනවත් තොරතුරු ඔබගේ ඇඟිලි තුඩු අග"</string>
- <string name="widget_education_content" msgid="745542879510751525">"යෙදුම් විවෘත නොකර තොරතුරු ලබා ගැනීම සඳහා, ඔබට ඔබගේ මුල් තිරයට විජට් එක් කළ හැකිය"</string>
- <string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"විජට් සැකසීම් වෙනස් කිරීමට තට්ටු කරන්න"</string>
- <string name="widget_education_close_button" msgid="8676165703104836580">"තේරුණා"</string>
- <string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"විජට් සැකසීම් වෙනස් කරන්න"</string>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"අතින් ස්ථානගත කිරීමට ස්පර්ශ කර අල්ලාගෙන සිටින්න"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"ස්වයංක්‍රියව එක් කරන්න"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"යෙදුම් සොයන්න"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"යෙදුම් පූරණය වෙමින්…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" සමග ගැළපෙන යෙදුම් හමු නොවිණි"</string>
<string name="all_apps_search_market_message" msgid="1366263386197059176">"තව යෙදුම් සඳහා සොයන්න"</string>
<string name="label_application" msgid="8531721983832654978">"යෙදුම"</string>
- <string name="all_apps_label" msgid="5015784846527570951">"සියලු යෙදුම්"</string>
<string name="notifications_header" msgid="1404149926117359025">"දැනුම්දීම්"</string>
- <string name="long_press_shortcut_to_add" msgid="5405328730817637737">"කෙටි මගක් ගෙන යාමට ස්පර්ශ කර අල්ලාගෙන සිටින්න."</string>
- <string name="long_accessible_way_to_add_shortcut" msgid="2199537273817090740">"කෙටි මගක් ගෙන යාමට හෝ අභිරුචි ක්‍රියා භාවිත කිරීමට දෙවරක් තට්ටු කර අල්ලා ගෙන සිටින්න."</string>
- <string name="out_of_space" msgid="6692471482459245734">"මෙම මුල් තිරයේ ඉඩ නැත"</string>
+ <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"කෙටි මගක් තෝරා ගැනීමට ස්පර්ශ කර අල්ලාගෙන සිටින්න."</string>
+ <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"විජට් එකක් තෝරා ගැනීමට හෝ අභිරුචි භාවිත කිරීමට දෙවරක් තට්ටු කර අල්ලා ගෙන සිටින්න."</string>
+ <string name="out_of_space" msgid="4691004494942118364">"මෙම මුල් පිටු තිරය මත තවත් අවසර නැත."</string>
<string name="hotseat_out_of_space" msgid="7448809638125333693">"ප්‍රියතම දෑ ඇති තැටියේ තවත් ඉඩ නොමැත"</string>
<string name="all_apps_button_label" msgid="8130441508702294465">"යෙදුම් ලැයිස්තුව"</string>
- <string name="all_apps_search_results" msgid="5889367432531296759">"සෙවීම් ප්‍රතිඵල"</string>
<string name="all_apps_button_personal_label" msgid="1315764287305224468">"පෞද්ගලික යෙදුම් ලැයිස්තුව"</string>
<string name="all_apps_button_work_label" msgid="7270707118948892488">"වැඩ යෙදුම් ලැයිස්තුව"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"මුල් පිටුව"</string>
<string name="remove_drop_target_label" msgid="7812859488053230776">"ඉවත් කරන්න"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"අස්ථාපනය කරන්න"</string>
<string name="app_info_drop_target_label" msgid="692894985365717661">"යෙදුම් තොරතුරු"</string>
<string name="install_drop_target_label" msgid="2539096853673231757">"ස්ථාපනය කරන්න"</string>
- <string name="dismiss_prediction_label" msgid="3357562989568808658">"යෙදුම යෝජනා නොකරන්න"</string>
- <string name="pin_prediction" msgid="4196423321649756498">"පුරෝකථනය අමුණන්න"</string>
<string name="permlab_install_shortcut" msgid="5632423390354674437">"කෙටිමං ස්ථාපනය කරන්න"</string>
<string name="permdesc_install_shortcut" msgid="923466509822011139">"පරිශීලක මැදිහත්වීමෙන් තොරව කෙටිමං එක් කිරීමට යෙදුමකට අවසර දෙයි."</string>
<string name="permlab_read_settings" msgid="1941457408239617576">"මුල් පිටු සැකසීම් සහ කෙටිමං කියවන්න"</string>
@@ -84,13 +60,15 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"මුල් පිටු සැකසීම් සහ කෙටිමං ලියන්න"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"මුල් පිටුවේ සැකසීම් සහ කෙටිමං ඉවත් කිරීමට යෙදුමට අවසර දෙයි."</string>
<string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> හට දුරකථන ඇමතුම් සිදු කිරීමට ඉඩ නොදේ"</string>
- <string name="gadget_error_text" msgid="740356548025791839">"විජට් පූරණය කළ නොහැකිය"</string>
- <string name="gadget_setup_text" msgid="8348374825537681407">"විජට් සැකසීම්"</string>
- <string name="gadget_complete_setup_text" msgid="309040266978007925">"පිහිටුවීම අවසන් කිරීමට තට්ටු කරන්න"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"ගැටලු පූරණ විජට් එක"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"ස්ථාපනය කරන්න"</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"මෙය පද්ධති යෙදුමක් වන අතර අස්ථාපනය කළ නොහැක."</string>
- <string name="folder_hint_text" msgid="5174843001373488816">"නම සංස්කරණය කරන්න"</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"නම් නොකළ ෆෝල්ඩරය"</string>
<string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> අබල කෙරිණි"</string>
- <string name="dotted_app_label" msgid="1704091277755818896">"{count,plural,offset:1 =1{{app_name} හට දැනුම්දීම් #ක් ඇත}one{{app_name} හට දැනුම්දීම් #ක් ඇත}other{{app_name} හට දැනුම්දීම් #ක් ඇත}}"</string>
+ <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+ <item quantity="one"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, දැනුම්දීම් <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g>ක් ඇත</item>
+ <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, දැනුම්දීම් <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g>ක් ඇත</item>
+ </plurals>
<string name="default_scroll_format" msgid="7475544710230993317">"%2$d හි %1$d පිටුව"</string>
<string name="workspace_scroll_format" msgid="8458889198184077399">"මුල් පිටු තිරය %2$d හි %1$d"</string>
<string name="workspace_new_page" msgid="257366611030256142">"නව මුල් පිටුව"</string>
@@ -99,10 +77,10 @@
<string name="folder_tap_to_rename" msgid="4017685068016979677">"යළි නම් කිරීම සුරැකීමට තට්ටු කරන්න"</string>
<string name="folder_closed" msgid="4100806530910930934">"ෆෝල්ඩරය වසා ඇත"</string>
<string name="folder_renamed" msgid="1794088362165669656">"<xliff:g id="NAME">%1$s</xliff:g> වෙත ෆෝල්ඩරය නැවත නම් කෙරිණි"</string>
- <string name="folder_name_format_exact" msgid="8626242716117004803">"ෆෝල්ඩරය: <xliff:g id="NAME">%1$s</xliff:g>, අයිතම <xliff:g id="SIZE">%2$d</xliff:g>"</string>
- <string name="folder_name_format_overflow" msgid="4270108890534995199">"ෆෝල්ඩර: <xliff:g id="NAME">%1$s</xliff:g>, අයිතම <xliff:g id="SIZE">%2$d</xliff:g>ක් හෝ වැඩි ගණනක්"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"ෆෝල්ඩරය: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"විජට්"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"වෝල්පේපර"</string>
- <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"වෝල්පේපරය සහ මෝස්තරය"</string>
+ <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"විලාස සහ වෝල්පේපර"</string>
<string name="settings_button_text" msgid="8873672322605444408">"නිවසේ සැකසීම්"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"ඔබගේ පරිපාලක විසින් අබල කරන ලදී"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"මුල් පිටු තිරය කරකැවීමට ඉඩ දෙන්න"</string>
@@ -114,16 +92,16 @@
<string name="msg_missing_notification_access" msgid="281113995110910548">"දැනුම්දීම් තිත් පෙන්වීමට, <xliff:g id="NAME">%1$s</xliff:g> සඳහා යෙදුම් දැනුම්දීම් සබල කරන්න"</string>
<string name="title_change_settings" msgid="1376365968844349552">"සැකසීම් වෙනස් කරන්න"</string>
<string name="notification_dots_service_title" msgid="4284221181793592871">"දැනුම්දීම් තිත් පෙන්වන්න"</string>
- <string name="auto_add_shortcuts_label" msgid="3698776050751790653">"මුල් තිරයට යෙදුම් අයිකන එක් කරන්න"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"මුල් පිටු තිරය වෙත අයිකනය එක් කරන්න"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"නව යෙදුම් සඳහා"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"නොදනී"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"ඉවත් කරන්න"</string>
<string name="abandoned_search" msgid="891119232568284442">"සොයන්න"</string>
<string name="abandoned_promises_title" msgid="7096178467971716750">"මෙම යෙදුම ස්ථාපනය කර නොමැත"</string>
<string name="abandoned_promise_explanation" msgid="3990027586878167529">"මෙම නිරුපකයට යෙදුම ස්ථාපනය කර නොමැත. ඔබට එය ඉවත් කළ හැක, හෝ යෙදුම් සඳහා සොයන්න සහ අතින් ස්ථාපනය කරන්න."</string>
- <string name="app_installing_title" msgid="5864044122733792085">"<xliff:g id="NAME">%1$s</xliff:g> ස්ථාපනය කරමින්, <xliff:g id="PROGRESS">%2$s</xliff:g> සම්පූර්ණයි"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> බාගත කරමින්, <xliff:g id="PROGRESS">%2$s</xliff:g> සම්පූර්ණයි"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> ස්ථාපනය කිරීමට බලා සිටිමින්"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"<xliff:g id="NAME">%1$s</xliff:g> විජට්"</string>
<string name="widgets_list" msgid="796804551140113767">"විජට් ලැයිස්තුව"</string>
<string name="widgets_list_closed" msgid="6141506579418771922">"විජට් ලැයිස්තුව වසා ඇත"</string>
<string name="action_add_to_workspace" msgid="8902165848117513641">"මුල් තිරය වෙත එක් කරන්න"</string>
@@ -151,20 +129,15 @@
<string name="action_deep_shortcut" msgid="2864038805849372848">"කෙටිමං"</string>
<string name="shortcuts_menu_with_notifications_description" msgid="2676582286544232849">"කෙටි මං සහ දැනුම්දීම්"</string>
<string name="action_dismiss_notification" msgid="5909461085055959187">"ඉවතලන්න"</string>
- <string name="accessibility_close" msgid="2277148124685870734">"වසන්න"</string>
<string name="notification_dismissed" msgid="6002233469409822874">"දැනුම්දීම ඉවතලන ලදී"</string>
<string name="all_apps_personal_tab" msgid="4190252696685155002">"පුද්ගලික"</string>
<string name="all_apps_work_tab" msgid="4884822796154055118">"කාර්යාලය"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"කාර්යාල පැතිකඩ"</string>
- <string name="work_profile_edu_work_apps" msgid="7895468576497746520">"කාර්යාල යෙදුම්වලට ලාංඡන යොදා ඇති අතර ඔබගේ IT පරිපාලකට දෘශ්‍යමාන වේ"</string>
- <string name="work_profile_edu_accept" msgid="6069788082535149071">"තේරුණා"</string>
- <string name="work_apps_paused_title" msgid="3040901117349444598">"කාර්යාල යෙදුම් විරාම කර ඇත"</string>
- <string name="work_apps_paused_body" msgid="261634750995824906">"ඔබගේ කාර්යාල යෙදුම්වලට ඔබට දැනුම්දීම් එවීමට, ඔබගේ බැටරිය භාවිත කිරීමට හෝ ඔබගේ ස්ථානයට ප්‍රවේශ වීමට නොහැකිය"</string>
- <string name="work_apps_paused_content_description" msgid="5149623040804051095">"කාර්යාල යෙදුම් ක්‍රියාවිරහිතයි. ඔබගේ කාර්යාල යෙදුම්වලට ඔබට දැනුම්දීම් එවීමට, ඔබගේ බැටරිය භාවිත කිරීමට හෝ ඔබගේ ස්ථානයට ප්‍රවේශ වීමට නොහැකිය"</string>
- <string name="work_apps_paused_edu_banner" msgid="8872412121608402058">"කාර්යාල යෙදුම්වලට ලාංඡන යොදා ඇති අතර ඔබගේ IT පරිපාලකට දෘශ්‍යමාන වේ"</string>
- <string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"තේරුණා"</string>
- <string name="work_apps_pause_btn_text" msgid="1921059713673767460">"කාර්යාල යෙදුම් ක්‍රියාවිරහිත කරන්න"</string>
- <string name="work_apps_enable_btn_text" msgid="1156432622148413741">"කාර්යාල යෙදුම් ක්‍රියාත්මක කරන්න"</string>
- <string name="developer_options_filter_hint" msgid="5896817443635989056">"පෙරහන"</string>
+ <string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"මෙහි කාර්යාල යෙදුම් සොයා ගන්න"</string>
+ <string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"සෑම කාර්යාල යෙදුමකම ලාංඡනයක් ඇත ඇති අතර එය ඔබේ සංවිධානය මගින් සුරක්ෂිතව තබා ගනී. වඩාත් පහසු ප්‍රවේශයකට යෙදුම් ඔබේ මුල් පිටු තිරය වෙත ගෙන යන්න."</string>
+ <string name="work_mode_on_label" msgid="4781128097185272916">"ඔබේ සංවිධානය විසින් කළමනාකරණය කරනු ලැබේ"</string>
+ <string name="work_mode_off_label" msgid="3194894777601421047">"දැනුම්දීම් සහ යෙදුම් ක්‍රියාවිරහිතයි"</string>
+ <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"වසන්න"</string>
+ <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"වසා ඇත"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"අසාර්ථකයි: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
</resources>
diff --git a/res/values-sk/strings.xml b/res/values-sk/strings.xml
index 3f212dcb0d..5bbf7c3cdc 100644
--- a/res/values-sk/strings.xml
+++ b/res/values-sk/strings.xml
@@ -26,71 +26,50 @@
<string name="safemode_shortcut_error" msgid="9160126848219158407">"Stiahnutá aplikácia je v núdzovom režime zakázaná"</string>
<string name="safemode_widget_error" msgid="4863470563535682004">"Miniaplikácie sú v núdzovom režime zakázané"</string>
<string name="shortcut_not_available" msgid="2536503539825726397">"Skratky nie sú k dispozícii"</string>
- <string name="home_screen" msgid="5629429142036709174">"Domov"</string>
- <string name="recent_task_option_split_screen" msgid="6690461455618725183">"Rozdeliť obrazovku"</string>
- <string name="split_screen_position_top" msgid="1504965011158689649">"Rozdeliť hore"</string>
- <string name="split_screen_position_left" msgid="7537793098851830883">"Rozdeliť vľavo"</string>
- <string name="split_screen_position_right" msgid="1569377524925193369">"Rozdeliť vpravo"</string>
- <string name="split_app_info_accessibility" msgid="5475288491241414932">"Informácie o aplikácii pre %1$s"</string>
- <string name="long_press_widget_to_add" msgid="3587712543577675817">"Pridržaním presuňte miniaplikáciu."</string>
- <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Dvojitým klepnutím a pridržaním presuňte miniaplikáciu alebo použite vlastné akcie."</string>
+ <string name="home_screen" msgid="806512411299847073">"Plocha"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"Vlastné akcie"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"Miniaplikáciu pridáte stlačením a podržaním."</string>
+ <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Miniaplikáciu pridáte dvojitým klepnutím a pridržaním alebo pomocou vlastných akcií."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"šírka %1$d, výška %2$d"</string>
- <string name="widget_preview_context_description" msgid="9045841361655787574">"Miniaplikácia <xliff:g id="WIDGET_NAME">%1$s</xliff:g>"</string>
- <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Po pridržaní môžete miniaplikáciu posúvať po ploche"</string>
- <string name="add_to_home_screen" msgid="8631549138215492708">"Pridať na plochu"</string>
- <string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"Na plochu bola pridaná miniaplikácia <xliff:g id="WIDGET_NAME">%1$s</xliff:g>"</string>
- <string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# miniaplikácia}few{# miniaplikácie}many{# widgets}other{# miniaplikácií}}"</string>
- <string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{# odkaz}few{# odkazy}many{# shortcuts}other{# odkazov}}"</string>
- <string name="widgets_and_shortcuts_count" msgid="7209136747878365116">"<xliff:g id="WIDGETS_COUNT">%1$s</xliff:g>, <xliff:g id="SHORTCUTS_COUNT">%2$s</xliff:g>"</string>
- <string name="widget_button_text" msgid="2880537293434387943">"Miniaplikácie"</string>
- <string name="widgets_full_sheet_search_bar_hint" msgid="8484659090860596457">"Vyhľadajte"</string>
- <string name="widgets_full_sheet_cancel_button_description" msgid="5766167035728653605">"Vymazať text z vyhľadávacieho poľa"</string>
- <string name="no_widgets_available" msgid="4337693382501046170">"Miniaplikácie a odkazy nie sú k dispozícii"</string>
- <string name="no_search_results" msgid="3787956167293097509">"Nenašli sa žiadne miniaplikácie ani odkazy"</string>
- <string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Osobné"</string>
- <string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Práca"</string>
- <string name="widget_category_conversations" msgid="8894438636213590446">"Konverzácie"</string>
- <string name="widget_education_header" msgid="4874760613775913787">"Užitočné informácie poruke"</string>
- <string name="widget_education_content" msgid="745542879510751525">"Ak chcete získavať informácie bez otvárania aplikácií, môžete si pridať miniaplikácie na plochu"</string>
- <string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Klepnutím zmeňte nastavenia miniaplikácie"</string>
- <string name="widget_education_close_button" msgid="8676165703104836580">"Dobre"</string>
- <string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Zmena nastavení miniaplikácie"</string>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Ak chcete položku umiestniť ručne, pridržte ju"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"Pridať automaticky"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Hľadať aplikácie"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Načítavajú sa aplikácie…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"Nenašli sa žiadne aplikácie zodpovedajúce dopytu <xliff:g id="QUERY">%1$s</xliff:g>"</string>
<string name="all_apps_search_market_message" msgid="1366263386197059176">"Hľadať ďalšie aplikácie"</string>
<string name="label_application" msgid="8531721983832654978">"Aplikácia"</string>
- <string name="all_apps_label" msgid="5015784846527570951">"Všetky aplikácie"</string>
<string name="notifications_header" msgid="1404149926117359025">"Upozornenia"</string>
- <string name="long_press_shortcut_to_add" msgid="5405328730817637737">"Pridržaním presuňte skratku."</string>
- <string name="long_accessible_way_to_add_shortcut" msgid="2199537273817090740">"Dvojitým klepnutím a pridržaním presuňte odkaz alebo použite vlastné akcie."</string>
- <string name="out_of_space" msgid="6692471482459245734">"Na tejto ploche nie je miesto"</string>
+ <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"Skratku pridáte pridržaním."</string>
+ <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"Skratku pridáte dvojitým klepnutím a pridržaním alebo pomocou vlastných akcií."</string>
+ <string name="out_of_space" msgid="4691004494942118364">"Na tejto ploche už nie je miesto"</string>
<string name="hotseat_out_of_space" msgid="7448809638125333693">"Na paneli Obľúbené položky už nie je miesto"</string>
<string name="all_apps_button_label" msgid="8130441508702294465">"Zoznam aplikácií"</string>
- <string name="all_apps_search_results" msgid="5889367432531296759">"Výsledky vyhľadávania"</string>
<string name="all_apps_button_personal_label" msgid="1315764287305224468">"Zoznam osobných aplikácií"</string>
<string name="all_apps_button_work_label" msgid="7270707118948892488">"Zoznam pracovných aplikácií"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"Domovská stránka"</string>
<string name="remove_drop_target_label" msgid="7812859488053230776">"Odstrániť"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"Odinštalovať"</string>
<string name="app_info_drop_target_label" msgid="692894985365717661">"Info o aplikácii"</string>
<string name="install_drop_target_label" msgid="2539096853673231757">"Inštalovať"</string>
- <string name="dismiss_prediction_label" msgid="3357562989568808658">"Nenavrhovať aplikáciu"</string>
- <string name="pin_prediction" msgid="4196423321649756498">"Pripnúť predpoveď"</string>
- <string name="permlab_install_shortcut" msgid="5632423390354674437">"inštalácia odkazov"</string>
+ <string name="permlab_install_shortcut" msgid="5632423390354674437">"inštalovať odkazy"</string>
<string name="permdesc_install_shortcut" msgid="923466509822011139">"Povoľuje aplikácii pridať odkazy bez zásahu používateľa."</string>
<string name="permlab_read_settings" msgid="1941457408239617576">"čítanie nastavení a odkazov plochy"</string>
<string name="permdesc_read_settings" msgid="5833423719057558387">"Povoľuje aplikácii čítať nastavenia a odkazy na ploche."</string>
<string name="permlab_write_settings" msgid="3574213698004620587">"zápis nastavení a odkazov plochy"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"Povoľuje aplikácii zmeniť nastavenia a odkazy na ploche."</string>
<string name="msg_no_phone_permission" msgid="9208659281529857371">"Aplikácia <xliff:g id="APP_NAME">%1$s</xliff:g> nemá povolenie uskutočňovať telefonické hovory"</string>
- <string name="gadget_error_text" msgid="740356548025791839">"Miniaplikáciu sa nepodarilo načítať"</string>
- <string name="gadget_setup_text" msgid="8348374825537681407">"Nastavenia miniaplikácie"</string>
- <string name="gadget_complete_setup_text" msgid="309040266978007925">"Nastavenie dokončíte klepnutím"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"Problém s načítaním miniaplikácií"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"Nastavenie"</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"Toto je systémová aplikácia a nedá sa odinštalovať."</string>
- <string name="folder_hint_text" msgid="5174843001373488816">"Úprava názvu"</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"Nepomenovaný priečinok"</string>
<string name="disabled_app_label" msgid="6673129024321402780">"Aplikácia <xliff:g id="APP_NAME">%1$s</xliff:g> je deaktivovaná"</string>
- <string name="dotted_app_label" msgid="1704091277755818896">"{count,plural,offset:1 =1{Aplikácia {app_name} má # upozornenie}few{Aplikácia {app_name} má # upozornenia}many{{app_name} has # notifications}other{Aplikácia {app_name} má # upozornení}}"</string>
+ <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+ <item quantity="few"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, má <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> upozornenia</item>
+ <item quantity="many"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, has <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> notifications</item>
+ <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, má <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> upozornení</item>
+ <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g>, má <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> upozornenie</item>
+ </plurals>
<string name="default_scroll_format" msgid="7475544710230993317">"Stránka %1$d z %2$d"</string>
<string name="workspace_scroll_format" msgid="8458889198184077399">"Plocha %1$d z %2$d"</string>
<string name="workspace_new_page" msgid="257366611030256142">"Nová stránka plochy"</string>
@@ -99,10 +78,10 @@
<string name="folder_tap_to_rename" msgid="4017685068016979677">"Nový názov uložíte klepnutím"</string>
<string name="folder_closed" msgid="4100806530910930934">"Priečinok je uzavretý"</string>
<string name="folder_renamed" msgid="1794088362165669656">"Priečinok bol premenovaný na <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="folder_name_format_exact" msgid="8626242716117004803">"Priečinok: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> položky"</string>
- <string name="folder_name_format_overflow" msgid="4270108890534995199">"Priečinok: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> alebo viac položiek"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"Priečinok: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"Miniaplikácie"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Tapety"</string>
- <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Tapeta a štýl"</string>
+ <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Štýly a tapety"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Nastavenia plochy"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Zakázané vaším správcom"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Povoliť otáčanie plochy"</string>
@@ -114,16 +93,16 @@
<string name="msg_missing_notification_access" msgid="281113995110910548">"Ak chcete, aby sa zobrazovali bodky upozornení, zapnite upozornenia aplikácie <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="title_change_settings" msgid="1376365968844349552">"Zmeniť nastavenia"</string>
<string name="notification_dots_service_title" msgid="4284221181793592871">"Zobrazovať bodky upozornení"</string>
- <string name="auto_add_shortcuts_label" msgid="3698776050751790653">"Pridať ikony aplikácií na plochu"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Pridať ikonu na plochu"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Pri inštalácii novej aplikácie"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"Neznáme"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"Odstrániť"</string>
<string name="abandoned_search" msgid="891119232568284442">"Vyhľadať"</string>
<string name="abandoned_promises_title" msgid="7096178467971716750">"Táto aplikácia nie je nainštalovaná"</string>
<string name="abandoned_promise_explanation" msgid="3990027586878167529">"Aplikácia, ktorú zastupuje táto ikona, nie je nainštalovaná. Ikonu môžete odstrániť alebo vyhľadajte aplikáciu a ručne ju nainštalujte."</string>
- <string name="app_installing_title" msgid="5864044122733792085">"Inštaluje sa <xliff:g id="NAME">%1$s</xliff:g>. Dokončené: <xliff:g id="PROGRESS">%2$s</xliff:g>."</string>
<string name="app_downloading_title" msgid="8336702962104482644">"Sťahuje sa aplikácia <xliff:g id="NAME">%1$s</xliff:g>. Stiahnuté: <xliff:g id="PROGRESS">%2$s</xliff:g>"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"Aplikácia <xliff:g id="NAME">%1$s</xliff:g> čaká na inštaláciu"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"Miniaplikácie <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="widgets_list" msgid="796804551140113767">"Zoznam miniaplikácií"</string>
<string name="widgets_list_closed" msgid="6141506579418771922">"Zoznam miniaplikácií je zavretý"</string>
<string name="action_add_to_workspace" msgid="8902165848117513641">"Pridať na plochu"</string>
@@ -151,20 +130,15 @@
<string name="action_deep_shortcut" msgid="2864038805849372848">"Skratky"</string>
<string name="shortcuts_menu_with_notifications_description" msgid="2676582286544232849">"Odkazy a upozornenia"</string>
<string name="action_dismiss_notification" msgid="5909461085055959187">"Zavrieť"</string>
- <string name="accessibility_close" msgid="2277148124685870734">"Zavrieť"</string>
<string name="notification_dismissed" msgid="6002233469409822874">"Upozornenie bolo zavreté"</string>
<string name="all_apps_personal_tab" msgid="4190252696685155002">"Osobné"</string>
<string name="all_apps_work_tab" msgid="4884822796154055118">"Pracovné"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"Pracovný profil"</string>
- <string name="work_profile_edu_work_apps" msgid="7895468576497746520">"Pracovné aplikácie majú odznak a zobrazujú sa správcovi IT"</string>
- <string name="work_profile_edu_accept" msgid="6069788082535149071">"Dobre"</string>
- <string name="work_apps_paused_title" msgid="3040901117349444598">"Pracovné aplikácie sú pozastavené"</string>
- <string name="work_apps_paused_body" msgid="261634750995824906">"Pracovné aplikácie nemôžu posielať upozornenia ani používať batériu či polohu."</string>
- <string name="work_apps_paused_content_description" msgid="5149623040804051095">"Pracovné aplikácie sú vypnuté. Nemôžu posielať upozornenia ani používať batériu či polohu."</string>
- <string name="work_apps_paused_edu_banner" msgid="8872412121608402058">"Pracovné aplikácie majú odznak a zobrazujú sa správcovi IT"</string>
- <string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"Dobre"</string>
- <string name="work_apps_pause_btn_text" msgid="1921059713673767460">"Vypnúť pracovné aplikácie"</string>
- <string name="work_apps_enable_btn_text" msgid="1156432622148413741">"Zapnúť pracovné aplikácie"</string>
- <string name="developer_options_filter_hint" msgid="5896817443635989056">"Filtrujte"</string>
+ <string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"Tu nájdete pracovné aplikácie"</string>
+ <string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"Všetky pracovné aplikácie majú štítok a sú bezpečne uchovávané vašou organizáciou. Ak chcete mať k aplikáciám ľahší prístup, presuňte ich na plochu."</string>
+ <string name="work_mode_on_label" msgid="4781128097185272916">"Spravované vašou organizáciou"</string>
+ <string name="work_mode_off_label" msgid="3194894777601421047">"Upozornenia a aplikácie sú vypnuté"</string>
+ <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Zavrieť"</string>
+ <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Zavreté"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Zlyhalo: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
</resources>
diff --git a/res/values-sl/strings.xml b/res/values-sl/strings.xml
index 485a525743..044a4b42b0 100644
--- a/res/values-sl/strings.xml
+++ b/res/values-sl/strings.xml
@@ -20,63 +20,39 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="649227358658669779">"Launcher3"</string>
+ <string name="folder_name" msgid="7371454440695724752"></string>
<string name="work_folder_name" msgid="3753320833950115786">"Služba"</string>
<string name="activity_not_found" msgid="8071924732094499514">"Aplikacija ni nameščena."</string>
<string name="activity_not_available" msgid="7456344436509528827">"Aplikacija ni na voljo"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"Prenesena aplikacija je onemogočena v Varnem načinu"</string>
<string name="safemode_widget_error" msgid="4863470563535682004">"Pripomočki so onemogočeni v varnem načinu"</string>
<string name="shortcut_not_available" msgid="2536503539825726397">"Bližnjica ni na voljo"</string>
- <string name="home_screen" msgid="5629429142036709174">"Začetni zaslon"</string>
- <string name="recent_task_option_split_screen" msgid="6690461455618725183">"Razdeljen zaslon"</string>
- <string name="split_screen_position_top" msgid="1504965011158689649">"Zgornja stran razdeljenega zaslona"</string>
- <string name="split_screen_position_left" msgid="7537793098851830883">"Leva stran razdeljenega zaslona"</string>
- <string name="split_screen_position_right" msgid="1569377524925193369">"Desna stran razdeljenega zaslona"</string>
- <string name="split_app_info_accessibility" msgid="5475288491241414932">"Podatki o aplikaciji za: %1$s"</string>
- <string name="long_press_widget_to_add" msgid="3587712543577675817">"Pridržite pripomoček, da ga premaknete."</string>
- <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Dvakrat se dotaknite pripomočka in ga pridržite, da ga premaknete, ali pa uporabite dejanja po meri."</string>
+ <string name="home_screen" msgid="806512411299847073">"Začetni zaslon"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"Dejanja po meri"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"Za izbiro pripomočka se ga dotaknite in pridržite."</string>
+ <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Če želite izbrati pripomoček ali uporabiti dejanja po meri, se ga dvakrat dotaknite in ga pridržite."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"Širina %1$d, višina %2$d"</string>
- <string name="widget_preview_context_description" msgid="9045841361655787574">"Pripomoček <xliff:g id="WIDGET_NAME">%1$s</xliff:g>"</string>
- <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Pridržite pripomoček, če ga želite premikati po začetnem zaslonu."</string>
- <string name="add_to_home_screen" msgid="8631549138215492708">"Dodaj na začetni zaslon"</string>
- <string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"Pripomoček »<xliff:g id="WIDGET_NAME">%1$s</xliff:g>« je dodan na začetni zaslon."</string>
- <string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# pripomoček}one{# pripomoček}two{# pripomočka}few{# pripomočki}other{# pripomočkov}}"</string>
- <string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{# bližnjica}one{# bližnjica}two{# bližnjici}few{# bližnjice}other{# bližnjic}}"</string>
- <string name="widgets_and_shortcuts_count" msgid="7209136747878365116">"<xliff:g id="WIDGETS_COUNT">%1$s</xliff:g>, <xliff:g id="SHORTCUTS_COUNT">%2$s</xliff:g>"</string>
- <string name="widget_button_text" msgid="2880537293434387943">"Pripomočki"</string>
- <string name="widgets_full_sheet_search_bar_hint" msgid="8484659090860596457">"Iskanje"</string>
- <string name="widgets_full_sheet_cancel_button_description" msgid="5766167035728653605">"Brisanje besedila v iskalnem polju"</string>
- <string name="no_widgets_available" msgid="4337693382501046170">"Pripomočki in bližnjice niso na voljo."</string>
- <string name="no_search_results" msgid="3787956167293097509">"Najden ni noben pripomoček ali bližnjica."</string>
- <string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Osebni"</string>
- <string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Služba"</string>
- <string name="widget_category_conversations" msgid="8894438636213590446">"Pogovori"</string>
- <string name="widget_education_header" msgid="4874760613775913787">"Koristne informacije na dosegu prstov"</string>
- <string name="widget_education_content" msgid="745542879510751525">"Če si želite podatke ogledati brez odpiranja aplikacij, lahko na začetni zaslon dodate pripomočke."</string>
- <string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Dotaknite se, če želite spremeniti nastavitve pripomočka."</string>
- <string name="widget_education_close_button" msgid="8676165703104836580">"Razumem"</string>
- <string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Spreminjanje nastavitev pripomočka"</string>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Dotaknite se elementa in ga pridržite, da ga ročno dodate"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"Samodejno dodaj"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Iskanje programov"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Nalaganje aplikacij …"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"Ni aplikacij, ki bi ustrezale poizvedbi »<xliff:g id="QUERY">%1$s</xliff:g>«"</string>
<string name="all_apps_search_market_message" msgid="1366263386197059176">"Iskanje več aplikacij"</string>
<string name="label_application" msgid="8531721983832654978">"Aplikacija"</string>
- <string name="all_apps_label" msgid="5015784846527570951">"Vse aplikacije"</string>
<string name="notifications_header" msgid="1404149926117359025">"Obvestila"</string>
- <string name="long_press_shortcut_to_add" msgid="5405328730817637737">"Pridržite bližnjico, da jo premaknete."</string>
- <string name="long_accessible_way_to_add_shortcut" msgid="2199537273817090740">"Dvakrat se dotaknite bližnjice in jo pridržite, da jo premaknete, ali pa uporabite dejanja po meri."</string>
- <string name="out_of_space" msgid="6692471482459245734">"Na tem začetnem zaslonu ni prostora."</string>
+ <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"Pridržite bližnjico, da jo izberete."</string>
+ <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"Dvakrat se dotaknite bližnjice in jo pridržite, da jo izberete, ali pa uporabite dejanja po meri."</string>
+ <string name="out_of_space" msgid="4691004494942118364">"Na tem začetnem zaslonu ni več prostora."</string>
<string name="hotseat_out_of_space" msgid="7448809638125333693">"V vrstici za priljubljene ni več prostora"</string>
<string name="all_apps_button_label" msgid="8130441508702294465">"Seznam aplikacij"</string>
- <string name="all_apps_search_results" msgid="5889367432531296759">"Rezultati iskanja"</string>
<string name="all_apps_button_personal_label" msgid="1315764287305224468">"Seznam osebnih aplikacij"</string>
<string name="all_apps_button_work_label" msgid="7270707118948892488">"Seznam delovnih aplikacij"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"Začetni zaslon"</string>
<string name="remove_drop_target_label" msgid="7812859488053230776">"Odstrani"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"Odmesti"</string>
<string name="app_info_drop_target_label" msgid="692894985365717661">"Podatki o aplikaciji"</string>
<string name="install_drop_target_label" msgid="2539096853673231757">"Namesti"</string>
- <string name="dismiss_prediction_label" msgid="3357562989568808658">"Ne predlagaj aplikacij"</string>
- <string name="pin_prediction" msgid="4196423321649756498">"Predvidevanje pripenjanja"</string>
<string name="permlab_install_shortcut" msgid="5632423390354674437">"namestitev bližnjic"</string>
<string name="permdesc_install_shortcut" msgid="923466509822011139">"Aplikaciji dovoli dodajanje bližnjic brez posredovanja uporabnika."</string>
<string name="permlab_read_settings" msgid="1941457408239617576">"branje nastavitev in bližnjic na začetnem zaslonu"</string>
@@ -84,13 +60,17 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"zapis nastavitev in bližnjic na začetnem zaslonu"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"Aplikaciji dovoli spreminjanje nastavitev in bližnjic na začetnem zaslonu."</string>
<string name="msg_no_phone_permission" msgid="9208659281529857371">"Aplikaciji <xliff:g id="APP_NAME">%1$s</xliff:g> ni dovoljeno opravljanje klicev"</string>
- <string name="gadget_error_text" msgid="740356548025791839">"Pripomočka ni mogoče naložiti."</string>
- <string name="gadget_setup_text" msgid="8348374825537681407">"Nastavitve pripomočka"</string>
- <string name="gadget_complete_setup_text" msgid="309040266978007925">"Dotaknite se, da dokončate postopek nastavitve."</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"Težava pri nalaganju pripomočka"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"Nastavitev"</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"To je sistemska aplikacija in je ni mogoče odstraniti."</string>
- <string name="folder_hint_text" msgid="5174843001373488816">"Urejanje imena"</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"Neimenovana mapa"</string>
<string name="disabled_app_label" msgid="6673129024321402780">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> je onemogočena"</string>
- <string name="dotted_app_label" msgid="1704091277755818896">"{count,plural,offset:1 =1{{app_name} ima # obvestilo}one{{app_name} ima # obvestilo}two{{app_name} ima # obvestili}few{{app_name} ima # obvestila}other{{app_name} ima # obvestil}}"</string>
+ <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+ <item quantity="one"><xliff:g id="APP_NAME_2">%1$s</xliff:g> ima <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> obvestilo</item>
+ <item quantity="two"><xliff:g id="APP_NAME_2">%1$s</xliff:g> ima <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> obvestili</item>
+ <item quantity="few"><xliff:g id="APP_NAME_2">%1$s</xliff:g> ima <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> obvestila</item>
+ <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g> ima <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> obvestil</item>
+ </plurals>
<string name="default_scroll_format" msgid="7475544710230993317">"Stran %1$d od %2$d"</string>
<string name="workspace_scroll_format" msgid="8458889198184077399">"Začetni zaslon %1$d od %2$d"</string>
<string name="workspace_new_page" msgid="257366611030256142">"Nova stran na začetnem zaslonu"</string>
@@ -99,13 +79,13 @@
<string name="folder_tap_to_rename" msgid="4017685068016979677">"Dotaknite se, da shranite preimenovanje"</string>
<string name="folder_closed" msgid="4100806530910930934">"Mapa je zaprta"</string>
<string name="folder_renamed" msgid="1794088362165669656">"Mapa je preimenovana v <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="folder_name_format_exact" msgid="8626242716117004803">"Mapa: <xliff:g id="NAME">%1$s</xliff:g>, št. elementov: <xliff:g id="SIZE">%2$d</xliff:g>"</string>
- <string name="folder_name_format_overflow" msgid="4270108890534995199">"Mapa: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> ali več elementov"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"Mapa: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"Pripomočki"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Ozadja"</string>
- <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Zaslonsko ozadje in slog"</string>
- <string name="settings_button_text" msgid="8873672322605444408">"Domače nastavitve"</string>
+ <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Slogi in ozadja"</string>
+ <string name="settings_button_text" msgid="8873672322605444408">"Nastavitve začetnega zaslona"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Onemogočil skrbnik."</string>
- <string name="allow_rotation_title" msgid="7728578836261442095">"Omogoči sukanje začetnega zaslona"</string>
+ <string name="allow_rotation_title" msgid="7728578836261442095">"Omogočanje sukanja začetnega zaslona"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Ko se telefon zasuka"</string>
<string name="notification_dots_title" msgid="9062440428204120317">"Obvestilne pike"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"Vklopljeno"</string>
@@ -114,16 +94,16 @@
<string name="msg_missing_notification_access" msgid="281113995110910548">"Za prikaz obvestilnih pik vklopite obvestila aplikacije <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="title_change_settings" msgid="1376365968844349552">"Spremeni nastavitve"</string>
<string name="notification_dots_service_title" msgid="4284221181793592871">"Pokaži obvestilne pike"</string>
- <string name="auto_add_shortcuts_label" msgid="3698776050751790653">"Dodaj ikone aplikacij na začetni zaslon"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Dodaj ikono na začetni zaslon"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Za nove aplikacije"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"Neznano"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"Odstrani"</string>
<string name="abandoned_search" msgid="891119232568284442">"Iskanje"</string>
<string name="abandoned_promises_title" msgid="7096178467971716750">"Ta aplikacija ni nameščena."</string>
<string name="abandoned_promise_explanation" msgid="3990027586878167529">"Aplikacija za to ikono ni nameščena. Lahko jo odstranite ali poiščete aplikacijo in to namestite ročno."</string>
- <string name="app_installing_title" msgid="5864044122733792085">"<xliff:g id="NAME">%1$s</xliff:g> se namešča, dokončano: <xliff:g id="PROGRESS">%2$s</xliff:g>"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"Prenašanje aplikacije <xliff:g id="NAME">%1$s</xliff:g>; preneseno <xliff:g id="PROGRESS">%2$s</xliff:g>"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"Aplikacija <xliff:g id="NAME">%1$s</xliff:g> čaka na namestitev"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"Pripomočki za <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="widgets_list" msgid="796804551140113767">"Seznam pripomočkov"</string>
<string name="widgets_list_closed" msgid="6141506579418771922">"Seznam pripomočkov se je zaprl"</string>
<string name="action_add_to_workspace" msgid="8902165848117513641">"Dodajanje na začetni zaslon"</string>
@@ -151,20 +131,15 @@
<string name="action_deep_shortcut" msgid="2864038805849372848">"Bližnjice"</string>
<string name="shortcuts_menu_with_notifications_description" msgid="2676582286544232849">"Bližnjice in obvestila"</string>
<string name="action_dismiss_notification" msgid="5909461085055959187">"Opusti"</string>
- <string name="accessibility_close" msgid="2277148124685870734">"Zapri"</string>
<string name="notification_dismissed" msgid="6002233469409822874">"Obvestilo je bilo opuščeno"</string>
<string name="all_apps_personal_tab" msgid="4190252696685155002">"Osebno"</string>
- <string name="all_apps_work_tab" msgid="4884822796154055118">"Delo"</string>
+ <string name="all_apps_work_tab" msgid="4884822796154055118">"Služba"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"Delovni profil"</string>
- <string name="work_profile_edu_work_apps" msgid="7895468576497746520">"Delovne aplikacije so označene z značko in vidne skrbniku za IT."</string>
- <string name="work_profile_edu_accept" msgid="6069788082535149071">"Razumem"</string>
- <string name="work_apps_paused_title" msgid="3040901117349444598">"Delovne aplikacije so začasno zaustavljene"</string>
- <string name="work_apps_paused_body" msgid="261634750995824906">"Delovne aplikacije ne smejo pošiljati obvestil, porabljati energije baterije ali dostopati do lokacije."</string>
- <string name="work_apps_paused_content_description" msgid="5149623040804051095">"Delovne aplikacije so izklopljene in ne smejo pošiljati obvestil, porabljati energije baterije ali dostopati do lokacije."</string>
- <string name="work_apps_paused_edu_banner" msgid="8872412121608402058">"Delovne aplikacije so označene z značko in vidne skrbniku za IT."</string>
- <string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"V redu"</string>
- <string name="work_apps_pause_btn_text" msgid="1921059713673767460">"Izklopi delovne aplikacije"</string>
- <string name="work_apps_enable_btn_text" msgid="1156432622148413741">"Vklopi delovne aplikacije"</string>
- <string name="developer_options_filter_hint" msgid="5896817443635989056">"Filtriranje"</string>
+ <string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"Tukaj poiščite delovne aplikacije"</string>
+ <string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"Vsaka delovna aplikacija ima značko. Za varnost teh aplikacij skrbi vaša organizacija. Za preprostejši dostop premaknite aplikacije na začetni zaslon."</string>
+ <string name="work_mode_on_label" msgid="4781128097185272916">"Upravlja vaša organizacija"</string>
+ <string name="work_mode_off_label" msgid="3194894777601421047">"Obvestila in aplikacije – izklopljeno"</string>
+ <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Zapri"</string>
+ <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Zaprto"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Ni uspelo: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
</resources>
diff --git a/res/values-sq/strings.xml b/res/values-sq/strings.xml
index 88ed4fade0..7f2567c60c 100644
--- a/res/values-sq/strings.xml
+++ b/res/values-sq/strings.xml
@@ -26,71 +26,48 @@
<string name="safemode_shortcut_error" msgid="9160126848219158407">"Aplikacioni i shkarkuar është i çaktivizuar në modalitetin e sigurt"</string>
<string name="safemode_widget_error" msgid="4863470563535682004">"Miniaplikacionet janë të çaktivizuara në modalitetin e sigurt"</string>
<string name="shortcut_not_available" msgid="2536503539825726397">"Shkurtorja nuk është e disponueshme"</string>
- <string name="home_screen" msgid="5629429142036709174">"Ekrani bazë"</string>
- <string name="recent_task_option_split_screen" msgid="6690461455618725183">"Ekrani i ndarë"</string>
- <string name="split_screen_position_top" msgid="1504965011158689649">"Ndaj lart"</string>
- <string name="split_screen_position_left" msgid="7537793098851830883">"Ndaj majtas"</string>
- <string name="split_screen_position_right" msgid="1569377524925193369">"Ndaj djathtas"</string>
- <string name="split_app_info_accessibility" msgid="5475288491241414932">"Informacioni i aplikacionit për %1$s"</string>
- <string name="long_press_widget_to_add" msgid="3587712543577675817">"Prek dhe mbaj shtypur një miniaplikacion për ta zhvendosur."</string>
- <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Trokit dy herë dhe mbaje shtypur një miniapliikacion për ta zhvendosur atë ose për të përdorur veprimet e personalizuara."</string>
+ <string name="home_screen" msgid="806512411299847073">"Ekrani bazë"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"Veprimet e personalizuara"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"Prek dhe mbaj shtypur për të zgjedhur një miniaplikacion."</string>
+ <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Prek dy herë dhe mbaj shtypur për të zgjedhur një miniaplikacion ose për të përdorur veprimet e personalizuara."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d i gjerë me %2$d i lartë"</string>
- <string name="widget_preview_context_description" msgid="9045841361655787574">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g> miniaplikacion"</string>
- <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Prek dhe mbaj të shtypur miniaplikacionin për ta lëvizur nëpër \"Ekranin bazë\""</string>
- <string name="add_to_home_screen" msgid="8631549138215492708">"Shto në \"Ekranin bazë\""</string>
- <string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"Miniaplikacioni <xliff:g id="WIDGET_NAME">%1$s</xliff:g> u shtua në ekranin bazë"</string>
- <string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# miniaplikacion}other{# miniaplikacione}}"</string>
- <string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{# shkurtore}other{# shkurtore}}"</string>
- <string name="widgets_and_shortcuts_count" msgid="7209136747878365116">"<xliff:g id="WIDGETS_COUNT">%1$s</xliff:g>, <xliff:g id="SHORTCUTS_COUNT">%2$s</xliff:g>"</string>
- <string name="widget_button_text" msgid="2880537293434387943">"Miniaplikacionet"</string>
- <string name="widgets_full_sheet_search_bar_hint" msgid="8484659090860596457">"Kërko"</string>
- <string name="widgets_full_sheet_cancel_button_description" msgid="5766167035728653605">"Pastro tekstin nga kutia e kërkimit"</string>
- <string name="no_widgets_available" msgid="4337693382501046170">"Miniaplikacionet dhe shkurtoret nuk ofrohen"</string>
- <string name="no_search_results" msgid="3787956167293097509">"Nuk u gjet asnjë miniaplikacion ose shkurtore"</string>
- <string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Personale"</string>
- <string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Puna"</string>
- <string name="widget_category_conversations" msgid="8894438636213590446">"Bisedat"</string>
- <string name="widget_education_header" msgid="4874760613775913787">"Informacione të dobishme në majë të gishtave të tu"</string>
- <string name="widget_education_content" msgid="745542879510751525">"Për të marrë informacione pa i hapur aplikacionet, mund të shtosh miniaplikacione në ekranin bazë"</string>
- <string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Trokit për të ndryshuar cilësimet e miniaplikacionit"</string>
- <string name="widget_education_close_button" msgid="8676165703104836580">"E kuptova"</string>
- <string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Ndrysho cilësimet e miniaplikacionit"</string>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Prek dhe mbaj të shtypur për të vendosur në mënyrë manuale"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"Shto automatikisht"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Kërko për aplikacione"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Po ngarkon aplikacionet..."</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"Nuk u gjet asnjë aplikacion që përputhet me \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
<string name="all_apps_search_market_message" msgid="1366263386197059176">"Kërko për më shumë aplikacione"</string>
<string name="label_application" msgid="8531721983832654978">"Aplikacioni"</string>
- <string name="all_apps_label" msgid="5015784846527570951">"Të gjitha aplikacionet"</string>
<string name="notifications_header" msgid="1404149926117359025">"Njoftimet"</string>
- <string name="long_press_shortcut_to_add" msgid="5405328730817637737">"Prek dhe mbaj shtypur një shkurtore për ta zhvendosur."</string>
- <string name="long_accessible_way_to_add_shortcut" msgid="2199537273817090740">"Trokit dy herë dhe mbaje shtypur një shkurtore për ta zhvendosur atë ose për të përdorur veprimet e personalizuara."</string>
- <string name="out_of_space" msgid="6692471482459245734">"Nuk ka vend në këtë ekran bazë"</string>
+ <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"Prek dhe mbaj të shtypur për të zgjedhur një shkurtore."</string>
+ <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"Prek dy herë dhe mbaj të shtypur për të zgjedhur një shkurtore ose për të përdorur veprimet e personalizuara."</string>
+ <string name="out_of_space" msgid="4691004494942118364">"Nuk ka më hapësirë në këtë ekran bazë."</string>
<string name="hotseat_out_of_space" msgid="7448809638125333693">"Nuk ka më hapësirë në tabakanë \"Të preferuarat\""</string>
<string name="all_apps_button_label" msgid="8130441508702294465">"Lista e aplikacioneve"</string>
- <string name="all_apps_search_results" msgid="5889367432531296759">"Rezultatet e kërkimit"</string>
<string name="all_apps_button_personal_label" msgid="1315764287305224468">"Lista e aplikacioneve personale"</string>
<string name="all_apps_button_work_label" msgid="7270707118948892488">"Lista e aplikacioneve të punës"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"Faqja kryesore"</string>
<string name="remove_drop_target_label" msgid="7812859488053230776">"Hiqe"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"Çinstalo"</string>
- <string name="app_info_drop_target_label" msgid="692894985365717661">"Info mbi aplikacionin"</string>
+ <string name="app_info_drop_target_label" msgid="692894985365717661">"Informacion mbi aplikacionin"</string>
<string name="install_drop_target_label" msgid="2539096853673231757">"Instalo"</string>
- <string name="dismiss_prediction_label" msgid="3357562989568808658">"Mos sugjero aplikacion"</string>
- <string name="pin_prediction" msgid="4196423321649756498">"Gozhdo parashikimin"</string>
- <string name="permlab_install_shortcut" msgid="5632423390354674437">"instalimi i shkurtoreve"</string>
+ <string name="permlab_install_shortcut" msgid="5632423390354674437">"instalo shkurtore"</string>
<string name="permdesc_install_shortcut" msgid="923466509822011139">"Lejon një aplikacion të shtojë shkurtore pa ndërhyrjen e përdoruesit."</string>
<string name="permlab_read_settings" msgid="1941457408239617576">"lexo cilësimet dhe shkurtoret e ekranit bazë"</string>
<string name="permdesc_read_settings" msgid="5833423719057558387">"Lejon aplikacionin të lexojë cilësimet dhe shkurtoret në ekranin bazë."</string>
<string name="permlab_write_settings" msgid="3574213698004620587">"shkruaj cilësimet dhe shkurtoret e ekranit bazë"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"Lejon aplikacionin të ndryshojë cilësimet dhe shkurtoret në ekranin bazë."</string>
<string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> nuk lejohet të kryejë telefonata"</string>
- <string name="gadget_error_text" msgid="740356548025791839">"S\'mund të ngarkohet miniaplikacioni"</string>
- <string name="gadget_setup_text" msgid="8348374825537681407">"Cilësimet e miniaplikacionit"</string>
- <string name="gadget_complete_setup_text" msgid="309040266978007925">"Trokit për të përfunduar konfigurimin"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"Problem në ngarkimin e miniaplikacionit"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"Konfiguro"</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"Ky është aplikacion sistemi dhe nuk mund të çinstalohet."</string>
- <string name="folder_hint_text" msgid="5174843001373488816">"Redakto emrin"</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"Dosje e paemërtuar"</string>
<string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> u çaktivizua"</string>
- <string name="dotted_app_label" msgid="1704091277755818896">"{count,plural,offset:1 =1{{app_name} ka # njoftim}other{{app_name} ka # njoftime}}"</string>
+ <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+ <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, ka <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> njoftime</item>
+ <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g>, ka <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> njoftim</item>
+ </plurals>
<string name="default_scroll_format" msgid="7475544710230993317">"Faqja: %1$d nga gjithsej %2$d"</string>
<string name="workspace_scroll_format" msgid="8458889198184077399">"Ekrani bazë: %1$d nga gjithsej %2$d"</string>
<string name="workspace_new_page" msgid="257366611030256142">"Faqja e ekranit të ri kryesor"</string>
@@ -99,13 +76,13 @@
<string name="folder_tap_to_rename" msgid="4017685068016979677">"Trokit për të ruajtur riemërtimin"</string>
<string name="folder_closed" msgid="4100806530910930934">"Dosja u mbyll"</string>
<string name="folder_renamed" msgid="1794088362165669656">"Dosja u riemërtua në <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="folder_name_format_exact" msgid="8626242716117004803">"Dosja: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> artikuj"</string>
- <string name="folder_name_format_overflow" msgid="4270108890534995199">"Dosja: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> ose më shumë artikuj"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"Dosja: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"Miniaplikacionet"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Imazhet e sfondit"</string>
- <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Imazhi i sfondit dhe stili"</string>
- <string name="settings_button_text" msgid="8873672322605444408">"Cilësimet e ekranit bazë"</string>
+ <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Stilet dhe imazhet e sfondit"</string>
+ <string name="settings_button_text" msgid="8873672322605444408">"Cilësimet e Home"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Çaktivizuar nga administratori"</string>
- <string name="allow_rotation_title" msgid="7728578836261442095">"Lejo rrotullimin e ekranit bazë"</string>
+ <string name="allow_rotation_title" msgid="7728578836261442095">"Lejo rrotullimin e ekranit kryesor"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Kur telefoni rrotullohet"</string>
<string name="notification_dots_title" msgid="9062440428204120317">"Pikat e njoftimeve"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"Aktiv"</string>
@@ -114,16 +91,16 @@
<string name="msg_missing_notification_access" msgid="281113995110910548">"Për të shfaqur \"Pikat e njoftimeve\", aktivizo njoftimet e aplikacionit për <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="title_change_settings" msgid="1376365968844349552">"Ndrysho cilësimet"</string>
<string name="notification_dots_service_title" msgid="4284221181793592871">"Shfaq pikat e njoftimeve"</string>
- <string name="auto_add_shortcuts_label" msgid="3698776050751790653">"Shto ikona aplikacionesh në ekranin bazë"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Shto ikonë në ekranin bazë"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Për aplikacionet e reja"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"I panjohur"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"Hiq"</string>
<string name="abandoned_search" msgid="891119232568284442">"Kërko"</string>
<string name="abandoned_promises_title" msgid="7096178467971716750">"Aplikacioni nuk është i instaluar"</string>
<string name="abandoned_promise_explanation" msgid="3990027586878167529">"Aplikacioni për këtë ikonë nuk është i instaluar. Mund ta heqësh ose të kërkosh aplikacionin dhe ta instalosh atë në mënyrë manuale."</string>
- <string name="app_installing_title" msgid="5864044122733792085">"<xliff:g id="NAME">%1$s</xliff:g> po instalohet, <xliff:g id="PROGRESS">%2$s</xliff:g> i përfunduar"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> po shkarkohet, <xliff:g id="PROGRESS">%2$s</xliff:g> të përfunduara"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> po pret të instalohet"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"Miniaplikacionet e <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="widgets_list" msgid="796804551140113767">"Lista e miniaplikacioneve"</string>
<string name="widgets_list_closed" msgid="6141506579418771922">"Lista e miniaplikacioneve u mbyll"</string>
<string name="action_add_to_workspace" msgid="8902165848117513641">"Shto në Ekranin bazë"</string>
@@ -151,20 +128,15 @@
<string name="action_deep_shortcut" msgid="2864038805849372848">"Shkurtoret"</string>
<string name="shortcuts_menu_with_notifications_description" msgid="2676582286544232849">"Shkurtoret dhe njoftimet"</string>
<string name="action_dismiss_notification" msgid="5909461085055959187">"Hiqe"</string>
- <string name="accessibility_close" msgid="2277148124685870734">"Mbyll"</string>
<string name="notification_dismissed" msgid="6002233469409822874">"Njoftimi u hoq"</string>
<string name="all_apps_personal_tab" msgid="4190252696685155002">"Personale"</string>
<string name="all_apps_work_tab" msgid="4884822796154055118">"Punë"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"Profili i punës"</string>
- <string name="work_profile_edu_work_apps" msgid="7895468576497746520">"Aplikacionet e punës janë të shënuara dhe të dukshme për administratorin e teknologjisë së informacionit"</string>
- <string name="work_profile_edu_accept" msgid="6069788082535149071">"E kuptova"</string>
- <string name="work_apps_paused_title" msgid="3040901117349444598">"Aplikacionet e punës janë vendosur në pauzë"</string>
- <string name="work_apps_paused_body" msgid="261634750995824906">"Aplikacionet e tua të punës nuk mund të të dërgojnë njoftime, të përdorin baterinë tënde apo të kenë qasje në vendndodhjen tënde"</string>
- <string name="work_apps_paused_content_description" msgid="5149623040804051095">"Aplikacionet e punës janë joaktive. Aplikacionet e tua të punës nuk mund të të dërgojnë njoftime, të përdorin baterinë tënde apo të kenë qasje në vendndodhjen tënde"</string>
- <string name="work_apps_paused_edu_banner" msgid="8872412121608402058">"Aplikacionet e punës janë të shënuara dhe të dukshme për administratorin e teknologjisë së informacionit"</string>
- <string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"E kuptova"</string>
- <string name="work_apps_pause_btn_text" msgid="1921059713673767460">"Çaktivizo aplikacionet e punës"</string>
- <string name="work_apps_enable_btn_text" msgid="1156432622148413741">"Aktivizo aplikacionet e punës"</string>
- <string name="developer_options_filter_hint" msgid="5896817443635989056">"Filtro"</string>
+ <string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"Gjej këtu aplikacionet e punës"</string>
+ <string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"Secili aplikacion pune ka një distinktiv dhe mbahet i sigurt nga organizata jote. Zhvendosi aplikacionet e punës në ekranin tënd kryesor për qasje më të lehtë."</string>
+ <string name="work_mode_on_label" msgid="4781128097185272916">"Menaxhohet nga organizata jote"</string>
+ <string name="work_mode_off_label" msgid="3194894777601421047">"Njoftimet dhe aplikacionet janë joaktive"</string>
+ <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Mbyll"</string>
+ <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Mbyllur"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Dështoi: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
</resources>
diff --git a/res/values-sr/strings.xml b/res/values-sr/strings.xml
index e719db6109..4e52592687 100644
--- a/res/values-sr/strings.xml
+++ b/res/values-sr/strings.xml
@@ -20,63 +20,39 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="649227358658669779">"Launcher3"</string>
+ <string name="folder_name" msgid="7371454440695724752"></string>
<string name="work_folder_name" msgid="3753320833950115786">"Work"</string>
<string name="activity_not_found" msgid="8071924732094499514">"Апликација није инсталирана."</string>
<string name="activity_not_available" msgid="7456344436509528827">"Апликација није доступна"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"Преузета апликација је онемогућена у Безбедном режиму"</string>
<string name="safemode_widget_error" msgid="4863470563535682004">"Виџети су онемогућени у Безбедном режиму"</string>
<string name="shortcut_not_available" msgid="2536503539825726397">"Пречица није доступна"</string>
- <string name="home_screen" msgid="5629429142036709174">"Почетни екран"</string>
- <string name="recent_task_option_split_screen" msgid="6690461455618725183">"Подељени екран"</string>
- <string name="split_screen_position_top" msgid="1504965011158689649">"Подели у врху"</string>
- <string name="split_screen_position_left" msgid="7537793098851830883">"Подели лево"</string>
- <string name="split_screen_position_right" msgid="1569377524925193369">"Подели десно"</string>
- <string name="split_app_info_accessibility" msgid="5475288491241414932">"Информације о апликацији за: %1$s"</string>
- <string name="long_press_widget_to_add" msgid="3587712543577675817">"Додирните и задржите ради померања виџета."</string>
- <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Двапут додирните и задржите да бисте померали виџет или користите прилагођене радње."</string>
+ <string name="home_screen" msgid="806512411299847073">"Почетни екран"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"Прилагођене радње"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"Додирните и задржите да бисте изабрали виџет."</string>
+ <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Двапут додирните и задржите да бисте изабрали виџет или користите прилагођене радње."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d×%2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"ширина од %1$d и висина од %2$d"</string>
- <string name="widget_preview_context_description" msgid="9045841361655787574">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g> виџет"</string>
- <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Додирните и задржите виџет да бисте га померали по почетном екрану"</string>
- <string name="add_to_home_screen" msgid="8631549138215492708">"Додај на почетни екран"</string>
- <string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"Додали сте виџет <xliff:g id="WIDGET_NAME">%1$s</xliff:g> на почетни екран"</string>
- <string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# виџет}one{# виџет}few{# виџета}other{# виџета}}"</string>
- <string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{# пречица}one{# пречица}few{# пречице}other{# пречица}}"</string>
- <string name="widgets_and_shortcuts_count" msgid="7209136747878365116">"<xliff:g id="WIDGETS_COUNT">%1$s</xliff:g>, <xliff:g id="SHORTCUTS_COUNT">%2$s</xliff:g>"</string>
- <string name="widget_button_text" msgid="2880537293434387943">"Виџети"</string>
- <string name="widgets_full_sheet_search_bar_hint" msgid="8484659090860596457">"Претражите"</string>
- <string name="widgets_full_sheet_cancel_button_description" msgid="5766167035728653605">"Обришите текст из оквира за претрагу"</string>
- <string name="no_widgets_available" msgid="4337693382501046170">"Виџети и пречице нису доступни"</string>
- <string name="no_search_results" msgid="3787956167293097509">"Није пронађен ниједан виџет или пречица"</string>
- <string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Лично"</string>
- <string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Посао"</string>
- <string name="widget_category_conversations" msgid="8894438636213590446">"Конверзације"</string>
- <string name="widget_education_header" msgid="4874760613775913787">"Корисне информације надохват руке"</string>
- <string name="widget_education_content" msgid="745542879510751525">"Да бисте пронашли информације без отварања апликација, можете да додате виџете на почетни екран"</string>
- <string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Додирните да бисте променили подешавања виџета"</string>
- <string name="widget_education_close_button" msgid="8676165703104836580">"Важи"</string>
- <string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Промените подешавања виџета"</string>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Додирните и задржите да бисте поставили ручно"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"Аутоматски додај"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Претражите апликације"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Апликације се учитавају…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"Није пронађена ниједна апликација за „<xliff:g id="QUERY">%1$s</xliff:g>“"</string>
<string name="all_apps_search_market_message" msgid="1366263386197059176">"Претражи још апликација"</string>
<string name="label_application" msgid="8531721983832654978">"Апликација"</string>
- <string name="all_apps_label" msgid="5015784846527570951">"Све апликације"</string>
<string name="notifications_header" msgid="1404149926117359025">"Обавештења"</string>
- <string name="long_press_shortcut_to_add" msgid="5405328730817637737">"Додирните и задржите ради померања пречице."</string>
- <string name="long_accessible_way_to_add_shortcut" msgid="2199537273817090740">"Двапут додирните и задржите да бисте померали пречицу или користите прилагођене радње."</string>
- <string name="out_of_space" msgid="6692471482459245734">"Нема простора на овом почетном екрану"</string>
+ <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"Додирните и задржите да бисте изабрали пречицу."</string>
+ <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"Двапут додирните и задржите да бисте изабрали пречицу или користите прилагођене радње."</string>
+ <string name="out_of_space" msgid="4691004494942118364">"Нема више простора на овом почетном екрану."</string>
<string name="hotseat_out_of_space" msgid="7448809638125333693">"Нема више простора на траци Омиљено"</string>
<string name="all_apps_button_label" msgid="8130441508702294465">"Листа апликација"</string>
- <string name="all_apps_search_results" msgid="5889367432531296759">"Резултати претраге"</string>
<string name="all_apps_button_personal_label" msgid="1315764287305224468">"Листа личних апликација"</string>
<string name="all_apps_button_work_label" msgid="7270707118948892488">"Листа пословних апликација"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"Почетна"</string>
<string name="remove_drop_target_label" msgid="7812859488053230776">"Уклони"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"Деинсталирај"</string>
- <string name="app_info_drop_target_label" msgid="692894985365717661">"Инфор. о апликацији"</string>
+ <string name="app_info_drop_target_label" msgid="692894985365717661">"Информ. о апликацији"</string>
<string name="install_drop_target_label" msgid="2539096853673231757">"Инсталирај"</string>
- <string name="dismiss_prediction_label" msgid="3357562989568808658">"Не предлажи апликацију"</string>
- <string name="pin_prediction" msgid="4196423321649756498">"Закачи предвиђање"</string>
<string name="permlab_install_shortcut" msgid="5632423390354674437">"инсталирање пречица"</string>
<string name="permdesc_install_shortcut" msgid="923466509822011139">"Дозвољава апликацији да додаје пречице без интервенције корисника."</string>
<string name="permlab_read_settings" msgid="1941457408239617576">"читање подешавања и пречица на почетном екрану"</string>
@@ -84,25 +60,28 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"уписивање подешавања и пречица на почетном екрану"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"Дозвољава апликацији да мења подешавања и пречице на почетном екрану."</string>
<string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> нема дозволу за упућивање телефонских позива"</string>
- <string name="gadget_error_text" msgid="740356548025791839">"Учитавање виџета није успело"</string>
- <string name="gadget_setup_text" msgid="8348374825537681407">"Подешавања виџета"</string>
- <string name="gadget_complete_setup_text" msgid="309040266978007925">"Додирните да бисте довршили подешавање"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"Проблем при учитавању виџета"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"Подешавање"</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"Ово је системска апликација и не може да се деинсталира."</string>
- <string name="folder_hint_text" msgid="5174843001373488816">"Измените назив"</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"Неименовани директоријум"</string>
<string name="disabled_app_label" msgid="6673129024321402780">"Апликација <xliff:g id="APP_NAME">%1$s</xliff:g> је онемогућена"</string>
- <string name="dotted_app_label" msgid="1704091277755818896">"{count,plural,offset:1 =1{{app_name}, има # обавештење}one{{app_name}, има # обавештење}few{{app_name}, има # обавештења}other{{app_name}, има # обавештења}}"</string>
+ <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+ <item quantity="one"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, има <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> обавештење</item>
+ <item quantity="few"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, има <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> обавештења</item>
+ <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, има <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> обавештења</item>
+ </plurals>
<string name="default_scroll_format" msgid="7475544710230993317">"%1$d. страница од %2$d"</string>
<string name="workspace_scroll_format" msgid="8458889198184077399">"%1$d. почетни екран од %2$d"</string>
<string name="workspace_new_page" msgid="257366611030256142">"Нова страница почетног екрана"</string>
- <string name="folder_opened" msgid="94695026776264709">"Фолдер је отворен, <xliff:g id="WIDTH">%1$d</xliff:g> пута <xliff:g id="HEIGHT">%2$d</xliff:g>"</string>
- <string name="folder_tap_to_close" msgid="4625795376335528256">"Додирните да бисте затворили фолдер"</string>
+ <string name="folder_opened" msgid="94695026776264709">"Директоријум је отворен, <xliff:g id="WIDTH">%1$d</xliff:g> пута <xliff:g id="HEIGHT">%2$d</xliff:g>"</string>
+ <string name="folder_tap_to_close" msgid="4625795376335528256">"Додирните да бисте затворили директоријум"</string>
<string name="folder_tap_to_rename" msgid="4017685068016979677">"Додирните да бисте сачували преименовање"</string>
- <string name="folder_closed" msgid="4100806530910930934">"Фолдер је затворен"</string>
- <string name="folder_renamed" msgid="1794088362165669656">"Фолдер је преименован у <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="folder_name_format_exact" msgid="8626242716117004803">"Фолдер: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> ставке"</string>
- <string name="folder_name_format_overflow" msgid="4270108890534995199">"Фолдер: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> или више ставки"</string>
+ <string name="folder_closed" msgid="4100806530910930934">"Директоријум је затворен"</string>
+ <string name="folder_renamed" msgid="1794088362165669656">"Директоријум је преименован у <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"Директоријум: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"Виџети"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Позадине"</string>
- <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Позадина и стил"</string>
+ <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Стилови и позадине"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Подешавања почетног екрана"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Администратор је онемогућио"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Дозволи ротацију почетног екрана"</string>
@@ -114,16 +93,16 @@
<string name="msg_missing_notification_access" msgid="281113995110910548">"Да бисте приказали тачке за обавештења, укључите обавештења за апликацију <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="title_change_settings" msgid="1376365968844349552">"Промените подешавања"</string>
<string name="notification_dots_service_title" msgid="4284221181793592871">"Приказуј тачке за обавештења"</string>
- <string name="auto_add_shortcuts_label" msgid="3698776050751790653">"Додај иконе апликација на почетни екран"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Додај икону на почетни екран"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"За нове апликације"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"Непознато"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"Уклони"</string>
<string name="abandoned_search" msgid="891119232568284442">"Претражи"</string>
<string name="abandoned_promises_title" msgid="7096178467971716750">"Ова апликација није инсталирана"</string>
<string name="abandoned_promise_explanation" msgid="3990027586878167529">"Апликација за ову икону није инсталирана. Можете да је уклоните или да потражите апликацију и инсталирате је ручно."</string>
- <string name="app_installing_title" msgid="5864044122733792085">"<xliff:g id="NAME">%1$s</xliff:g> се инсталира, <xliff:g id="PROGRESS">%2$s</xliff:g> готово"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> се преузима, завршено је <xliff:g id="PROGRESS">%2$s</xliff:g>"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> чека на инсталирање"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"Виџети за <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="widgets_list" msgid="796804551140113767">"Листа виџета"</string>
<string name="widgets_list_closed" msgid="6141506579418771922">"Листа виџета је затворена"</string>
<string name="action_add_to_workspace" msgid="8902165848117513641">"Додајте на почетни екран"</string>
@@ -136,11 +115,11 @@
<string name="move_to_position" msgid="6750008980455459790">"Премести на <xliff:g id="NUMBER">%1$s</xliff:g>. позицију"</string>
<string name="move_to_hotseat_position" msgid="6295412897075147808">"Премести на <xliff:g id="NUMBER">%1$s</xliff:g>. позицију у омиљеним"</string>
<string name="item_moved" msgid="4606538322571412879">"Ставка је премештена"</string>
- <string name="add_to_folder" msgid="9040534766770853243">"Додај у фолдер: <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="add_to_folder_with_app" msgid="4534929978967147231">"Додај у фолдер у коме је <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="added_to_folder" msgid="4793259502305558003">"Ставка је додата у фолдер"</string>
- <string name="create_folder_with" msgid="4050141361160214248">"Направите фолдер са: <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="folder_created" msgid="6409794597405184510">"Фолдер је направљен"</string>
+ <string name="add_to_folder" msgid="9040534766770853243">"Додај у директоријум: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="add_to_folder_with_app" msgid="4534929978967147231">"Додај у директоријум у коме је <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="added_to_folder" msgid="4793259502305558003">"Ставка је додата у директоријум"</string>
+ <string name="create_folder_with" msgid="4050141361160214248">"Направите директоријум са: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="folder_created" msgid="6409794597405184510">"Директоријум је направљен"</string>
<string name="action_move_to_workspace" msgid="1603837886334246317">"Премести на почетни екран"</string>
<string name="action_resize" msgid="1802976324781771067">"Промени величину"</string>
<string name="action_increase_width" msgid="8773715375078513326">"Повећај ширину"</string>
@@ -151,20 +130,15 @@
<string name="action_deep_shortcut" msgid="2864038805849372848">"Пречице"</string>
<string name="shortcuts_menu_with_notifications_description" msgid="2676582286544232849">"Пречице и обавештења"</string>
<string name="action_dismiss_notification" msgid="5909461085055959187">"Одбаци"</string>
- <string name="accessibility_close" msgid="2277148124685870734">"Затвори"</string>
<string name="notification_dismissed" msgid="6002233469409822874">"Обавештење је одбачено"</string>
<string name="all_apps_personal_tab" msgid="4190252696685155002">"Личне"</string>
<string name="all_apps_work_tab" msgid="4884822796154055118">"Пословне"</string>
- <string name="work_profile_toggle_label" msgid="3081029915775481146">"Пословни профил"</string>
- <string name="work_profile_edu_work_apps" msgid="7895468576497746520">"Пословне апликације су означене значком и ИТ администратор може да их види"</string>
- <string name="work_profile_edu_accept" msgid="6069788082535149071">"Важи"</string>
- <string name="work_apps_paused_title" msgid="3040901117349444598">"Пословне апликације су паузиране"</string>
- <string name="work_apps_paused_body" msgid="261634750995824906">"Пословне апликације не могу да вам шаљу обавештења, користе батерију нити приступају локацији"</string>
- <string name="work_apps_paused_content_description" msgid="5149623040804051095">"Пословне апликације су искључене. Пословне апликације не могу да вам шаљу обавештења, користе батерију нити приступају локацији"</string>
- <string name="work_apps_paused_edu_banner" msgid="8872412121608402058">"Пословне апликације су означене значком и ИТ администратор може да их види"</string>
- <string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"Важи"</string>
- <string name="work_apps_pause_btn_text" msgid="1921059713673767460">"Искључи пословне апликације"</string>
- <string name="work_apps_enable_btn_text" msgid="1156432622148413741">"Укључи пословне апликације"</string>
- <string name="developer_options_filter_hint" msgid="5896817443635989056">"Филтер"</string>
+ <string name="work_profile_toggle_label" msgid="3081029915775481146">"Профил за Work"</string>
+ <string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"Пронађите пословне апликације овде"</string>
+ <string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"Свака пословна апликација има значку и штити је ваша организација. Преместите апликације на почетни екран да бисте им лакше приступали."</string>
+ <string name="work_mode_on_label" msgid="4781128097185272916">"Овим управља организација"</string>
+ <string name="work_mode_off_label" msgid="3194894777601421047">"Обавештења и апликације су искључени"</string>
+ <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Затвори"</string>
+ <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Затворено"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Није успело: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
</resources>
diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml
index e590ec98b2..e7400a6d00 100644
--- a/res/values-sv/strings.xml
+++ b/res/values-sv/strings.xml
@@ -20,63 +20,39 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="649227358658669779">"Launcher3"</string>
+ <string name="folder_name" msgid="7371454440695724752"></string>
<string name="work_folder_name" msgid="3753320833950115786">"Arbete"</string>
<string name="activity_not_found" msgid="8071924732094499514">"Appen är inte installerad."</string>
<string name="activity_not_available" msgid="7456344436509528827">"Appen är inte tillgänglig"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"Den hämtade appen inaktiverades i säkert läge"</string>
<string name="safemode_widget_error" msgid="4863470563535682004">"Widgets är inaktiverade i felsäkert läge"</string>
<string name="shortcut_not_available" msgid="2536503539825726397">"Genvägen är inte tillgänglig"</string>
- <string name="home_screen" msgid="5629429142036709174">"Startskärm"</string>
- <string name="recent_task_option_split_screen" msgid="6690461455618725183">"Delad skärm"</string>
- <string name="split_screen_position_top" msgid="1504965011158689649">"Upptill på delad skärm"</string>
- <string name="split_screen_position_left" msgid="7537793098851830883">"Till vänster på delad skärm"</string>
- <string name="split_screen_position_right" msgid="1569377524925193369">"Till höger på delad skärm"</string>
- <string name="split_app_info_accessibility" msgid="5475288491241414932">"Appinformation för %1$s"</string>
- <string name="long_press_widget_to_add" msgid="3587712543577675817">"Tryck länge för att flytta en widget."</string>
- <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Tryck snabbt två gånger och håll kvar för att flytta en widget eller använda anpassade åtgärder."</string>
+ <string name="home_screen" msgid="806512411299847073">"Startskärm"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"Anpassade åtgärder"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"Tryck länge om du vill flytta en widget."</string>
+ <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Tryck två gånger och håll kvar om du vill ta upp en widget eller använda anpassade åtgärder."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d bred gånger %2$d hög"</string>
- <string name="widget_preview_context_description" msgid="9045841361655787574">"Widget för <xliff:g id="WIDGET_NAME">%1$s</xliff:g>"</string>
- <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Tryck länge på widgeten om du vill flytta den på startskärmen"</string>
- <string name="add_to_home_screen" msgid="8631549138215492708">"Lägg till på startskärmen"</string>
- <string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"Widget för <xliff:g id="WIDGET_NAME">%1$s</xliff:g> har lagts till på startskärmen"</string>
- <string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# widget}other{# widgetar}}"</string>
- <string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{# genväg}other{# genvägar}}"</string>
- <string name="widgets_and_shortcuts_count" msgid="7209136747878365116">"<xliff:g id="WIDGETS_COUNT">%1$s</xliff:g>, <xliff:g id="SHORTCUTS_COUNT">%2$s</xliff:g>"</string>
- <string name="widget_button_text" msgid="2880537293434387943">"Widgetar"</string>
- <string name="widgets_full_sheet_search_bar_hint" msgid="8484659090860596457">"Sök"</string>
- <string name="widgets_full_sheet_cancel_button_description" msgid="5766167035728653605">"Rensa texten från sökrutan"</string>
- <string name="no_widgets_available" msgid="4337693382501046170">"Widgetar och genvägar är inte tillgängliga"</string>
- <string name="no_search_results" msgid="3787956167293097509">"Inga widgetar eller genvägar hittades"</string>
- <string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Privata"</string>
- <string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Arbete"</string>
- <string name="widget_category_conversations" msgid="8894438636213590446">"Konversationer"</string>
- <string name="widget_education_header" msgid="4874760613775913787">"Användbar information nära till hands"</string>
- <string name="widget_education_content" msgid="745542879510751525">"Om du vill ha information utan att öppna appar kan du lägga till widgetar på startskärmen"</string>
- <string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Tryck för att ändra inställningarna för widgeten"</string>
- <string name="widget_education_close_button" msgid="8676165703104836580">"OK"</string>
- <string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Ändra inställningarna för widgeten"</string>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Placera manuellt genom att trycka länge"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"Lägg till automatiskt"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Sök efter appar"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Läser in appar …"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"Inga appar som matchar <xliff:g id="QUERY">%1$s</xliff:g> hittades"</string>
<string name="all_apps_search_market_message" msgid="1366263386197059176">"Sök efter fler appar"</string>
<string name="label_application" msgid="8531721983832654978">"App"</string>
- <string name="all_apps_label" msgid="5015784846527570951">"Alla appar"</string>
<string name="notifications_header" msgid="1404149926117359025">"Aviseringar"</string>
- <string name="long_press_shortcut_to_add" msgid="5405328730817637737">"Tryck länge för att flytta en genväg."</string>
- <string name="long_accessible_way_to_add_shortcut" msgid="2199537273817090740">"Tryck snabbt två gånger och håll kvar för att flytta en genväg eller använda anpassade åtgärder."</string>
- <string name="out_of_space" msgid="6692471482459245734">"Det finns inte plats på den här startskärmen."</string>
+ <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"Tryck länge om du vill ta upp en genväg."</string>
+ <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"Tryck snabbt två gånger och håll kvar om du vill ta upp en genväg eller använda anpassade åtgärder."</string>
+ <string name="out_of_space" msgid="4691004494942118364">"Det finns inte plats för mer på den här startskärmen."</string>
<string name="hotseat_out_of_space" msgid="7448809638125333693">"Favoritfältet är fullt"</string>
<string name="all_apps_button_label" msgid="8130441508702294465">"Applista"</string>
- <string name="all_apps_search_results" msgid="5889367432531296759">"Sökresultat"</string>
<string name="all_apps_button_personal_label" msgid="1315764287305224468">"Listan Personliga appar"</string>
<string name="all_apps_button_work_label" msgid="7270707118948892488">"Listan Jobbappar"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"Startskärm"</string>
<string name="remove_drop_target_label" msgid="7812859488053230776">"Ta bort"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"Avinstallera"</string>
<string name="app_info_drop_target_label" msgid="692894985365717661">"Info om appen"</string>
<string name="install_drop_target_label" msgid="2539096853673231757">"Installera"</string>
- <string name="dismiss_prediction_label" msgid="3357562989568808658">"Föreslå inte app"</string>
- <string name="pin_prediction" msgid="4196423321649756498">"Fäst förslag"</string>
<string name="permlab_install_shortcut" msgid="5632423390354674437">"installera genvägar"</string>
<string name="permdesc_install_shortcut" msgid="923466509822011139">"Tillåter att en app lägger till genvägar utan åtgärd från användaren."</string>
<string name="permlab_read_settings" msgid="1941457408239617576">"läsa inställningar och genvägar för startsidan"</string>
@@ -84,13 +60,15 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"skriva inställningar och genvägar för startsidan"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"Tillåter att appen ändrar inställningar och genvägar på startsidan."</string>
<string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> har inte behörighet att ringa samtal"</string>
- <string name="gadget_error_text" msgid="740356548025791839">"Det gick inte att läsa in widgeten"</string>
- <string name="gadget_setup_text" msgid="8348374825537681407">"Widgetinställningar"</string>
- <string name="gadget_complete_setup_text" msgid="309040266978007925">"Tryck för att slutföra konfigureringen"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"Det gick inte att läsa in widgeten"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"Konfiguration"</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"Det här är en systemapp som inte kan avinstalleras."</string>
- <string name="folder_hint_text" msgid="5174843001373488816">"Redigera namn"</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"Namnlös mapp"</string>
<string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> har inaktiverats"</string>
- <string name="dotted_app_label" msgid="1704091277755818896">"{count,plural,offset:1 =1{{app_name} har # avisering}other{{app_name} har # aviseringar}}"</string>
+ <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+ <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g> har <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> aviseringar</item>
+ <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g> har <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> avisering</item>
+ </plurals>
<string name="default_scroll_format" msgid="7475544710230993317">"Sidan %1$d av %2$d"</string>
<string name="workspace_scroll_format" msgid="8458889198184077399">"Startskärmen %1$d av %2$d"</string>
<string name="workspace_new_page" msgid="257366611030256142">"Ny sida på startskärmen"</string>
@@ -99,10 +77,10 @@
<string name="folder_tap_to_rename" msgid="4017685068016979677">"Tryck för att spara namnändringen"</string>
<string name="folder_closed" msgid="4100806530910930934">"Mappen är stängd"</string>
<string name="folder_renamed" msgid="1794088362165669656">"Mappen har bytt namn till <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="folder_name_format_exact" msgid="8626242716117004803">"Mapp: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> objekt"</string>
- <string name="folder_name_format_overflow" msgid="4270108890534995199">"Mapp: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> eller fler objekt"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"Mapp: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"Widgetar"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Bakgrunder"</string>
- <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Bakgrund och utseende"</string>
+ <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Format och bakgrunder"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Startinställningar"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Inaktiverat av administratören"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Tillåt rotering av startskärmen"</string>
@@ -114,16 +92,16 @@
<string name="msg_missing_notification_access" msgid="281113995110910548">"Aktivera appaviseringar för <xliff:g id="NAME">%1$s</xliff:g> om du vill att aviseringsprickar ska visas"</string>
<string name="title_change_settings" msgid="1376365968844349552">"Ändra inställningar"</string>
<string name="notification_dots_service_title" msgid="4284221181793592871">"Visa aviseringsprickar"</string>
- <string name="auto_add_shortcuts_label" msgid="3698776050751790653">"Lägg till appikoner på startskärmen"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Lägg till ikonen på startskärmen"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"För nya appar"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"Okänt"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"Ta bort"</string>
<string name="abandoned_search" msgid="891119232568284442">"Sök"</string>
<string name="abandoned_promises_title" msgid="7096178467971716750">"Appen är inte installerad"</string>
<string name="abandoned_promise_explanation" msgid="3990027586878167529">"Appen för den här ikonen har inte installerats. Du kan ta bort den eller söka efter appen och installera den manuellt."</string>
- <string name="app_installing_title" msgid="5864044122733792085">"<xliff:g id="NAME">%1$s</xliff:g> installeras. <xliff:g id="PROGRESS">%2$s</xliff:g> har slutförts"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> laddas ned, <xliff:g id="PROGRESS">%2$s</xliff:g> klart"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> väntar på installation"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"<xliff:g id="NAME">%1$s</xliff:g> widgetar"</string>
<string name="widgets_list" msgid="796804551140113767">"Widgetlista"</string>
<string name="widgets_list_closed" msgid="6141506579418771922">"Widgetslistan har stängts"</string>
<string name="action_add_to_workspace" msgid="8902165848117513641">"Lägg till på startskärmen"</string>
@@ -151,20 +129,15 @@
<string name="action_deep_shortcut" msgid="2864038805849372848">"Genvägar"</string>
<string name="shortcuts_menu_with_notifications_description" msgid="2676582286544232849">"Genvägar och aviseringar"</string>
<string name="action_dismiss_notification" msgid="5909461085055959187">"Ignorera"</string>
- <string name="accessibility_close" msgid="2277148124685870734">"Stäng"</string>
<string name="notification_dismissed" msgid="6002233469409822874">"Aviseringen togs bort"</string>
<string name="all_apps_personal_tab" msgid="4190252696685155002">"Privat"</string>
<string name="all_apps_work_tab" msgid="4884822796154055118">"Arbete"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"Jobbprofil"</string>
- <string name="work_profile_edu_work_apps" msgid="7895468576497746520">"Jobbappar är märkta och synliga för IT-administratören"</string>
- <string name="work_profile_edu_accept" msgid="6069788082535149071">"OK"</string>
- <string name="work_apps_paused_title" msgid="3040901117349444598">"Jobbappar har pausats"</string>
- <string name="work_apps_paused_body" msgid="261634750995824906">"Dina jobbappar kan inte skicka aviseringar, använda batteriet eller komma åt din plats"</string>
- <string name="work_apps_paused_content_description" msgid="5149623040804051095">"Jobbappar är inaktiverade. Dina jobbappar kan inte skicka aviseringar, använda batteriet eller komma åt din plats"</string>
- <string name="work_apps_paused_edu_banner" msgid="8872412121608402058">"Jobbappar är märkta och synliga för IT-administratören"</string>
- <string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"OK"</string>
- <string name="work_apps_pause_btn_text" msgid="1921059713673767460">"Inaktivera jobbappar"</string>
- <string name="work_apps_enable_btn_text" msgid="1156432622148413741">"Aktivera jobbappar"</string>
- <string name="developer_options_filter_hint" msgid="5896817443635989056">"Filter"</string>
+ <string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"Här hittar du jobbappar"</string>
+ <string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"Alla jobbappar har ett märke och organisationen ser till att de är skyddade. Flytta apparna till startskärmen så kommer du åt dem lättare."</string>
+ <string name="work_mode_on_label" msgid="4781128097185272916">"Hanteras av organisationen"</string>
+ <string name="work_mode_off_label" msgid="3194894777601421047">"Aviseringar och appar är inaktiverade"</string>
+ <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Stäng"</string>
+ <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Stängd"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Misslyckades: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
</resources>
diff --git a/res/values-sw/strings.xml b/res/values-sw/strings.xml
index fa58703671..445e382f2d 100644
--- a/res/values-sw/strings.xml
+++ b/res/values-sw/strings.xml
@@ -26,57 +26,32 @@
<string name="safemode_shortcut_error" msgid="9160126848219158407">"Programu iliyopakuliwa imezimwa katika Hali Salama"</string>
<string name="safemode_widget_error" msgid="4863470563535682004">"Wijeti zimezimwa katika hali ya Usalama"</string>
<string name="shortcut_not_available" msgid="2536503539825726397">"Hakuna njia ya mkato"</string>
- <string name="home_screen" msgid="5629429142036709174">"Skrini ya kwanza"</string>
- <string name="recent_task_option_split_screen" msgid="6690461455618725183">"Gawa skrini"</string>
- <string name="split_screen_position_top" msgid="1504965011158689649">"Gawanya sehemu ya juu"</string>
- <string name="split_screen_position_left" msgid="7537793098851830883">"Gawanya sehemu ya kushoto"</string>
- <string name="split_screen_position_right" msgid="1569377524925193369">"Gawanya sehemu ya kulia"</string>
- <string name="split_app_info_accessibility" msgid="5475288491241414932">"Maelezo ya programu ya %1$s"</string>
- <string name="long_press_widget_to_add" msgid="3587712543577675817">"Gusa na ushikilie ili usogeze wijeti."</string>
- <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Gusa mara mbili na ushikilie ili usogeze wijeti au utumie vitendo maalum."</string>
+ <string name="home_screen" msgid="806512411299847073">"Skrini ya kwanza"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"Vitendo maalum"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"Gusa na ushikilie ili kuteua wijeti."</string>
+ <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Gusa mara mbili na ushikilie ile uchague wijeti au utumie vitendo maalum."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"Upana wa %1$d na kimo cha %2$d"</string>
- <string name="widget_preview_context_description" msgid="9045841361655787574">"Wijeti ya <xliff:g id="WIDGET_NAME">%1$s</xliff:g>"</string>
- <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Gusa na ushikilie wijeti ili uisogeze kwenye Skrini ya kwanza"</string>
- <string name="add_to_home_screen" msgid="8631549138215492708">"Weka kwenye Skrini ya kwanza"</string>
- <string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"Umeongeza wijeti ya <xliff:g id="WIDGET_NAME">%1$s</xliff:g> kwenye skrini ya kwanza"</string>
- <string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{Wijeti #}other{Wijeti #}}"</string>
- <string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{Njia # ya mkato}other{Njia # za mkato}}"</string>
- <string name="widgets_and_shortcuts_count" msgid="7209136747878365116">"<xliff:g id="WIDGETS_COUNT">%1$s</xliff:g>, <xliff:g id="SHORTCUTS_COUNT">%2$s</xliff:g>"</string>
- <string name="widget_button_text" msgid="2880537293434387943">"Wijeti"</string>
- <string name="widgets_full_sheet_search_bar_hint" msgid="8484659090860596457">"Tafuta"</string>
- <string name="widgets_full_sheet_cancel_button_description" msgid="5766167035728653605">"Futa maandishi kwenye kisanduku cha kutafutia"</string>
- <string name="no_widgets_available" msgid="4337693382501046170">"Wijeti na njia za mkato hazipatikani"</string>
- <string name="no_search_results" msgid="3787956167293097509">"Hakuna wijeti wala njia za mkato zilizopatikana"</string>
- <string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Binafsi"</string>
- <string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Kazini"</string>
- <string name="widget_category_conversations" msgid="8894438636213590446">"Mazungumzo"</string>
- <string name="widget_education_header" msgid="4874760613775913787">"Maelezo muhimu, popote ulipo"</string>
- <string name="widget_education_content" msgid="745542879510751525">"Ili upate maelezo bila kufungua programu, unaweza kuweka wijeti kwenye Skrini yako ya kwanza"</string>
- <string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Gusa ili ubadilishe mipangilio ya wijeti"</string>
- <string name="widget_education_close_button" msgid="8676165703104836580">"Nimeelewa"</string>
- <string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Badilisha mipangilio ya wijeti"</string>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Gusa na ushikilie ili uweke mwenyewe"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"Ongeza kiotomatiki"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Tafuta programu"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Inapakia programu..."</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"Haikupata programu zozote zinazolingana na \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
<string name="all_apps_search_market_message" msgid="1366263386197059176">"Tafuta programu zaidi"</string>
<string name="label_application" msgid="8531721983832654978">"Programu"</string>
- <string name="all_apps_label" msgid="5015784846527570951">"Programu zote"</string>
<string name="notifications_header" msgid="1404149926117359025">"Arifa"</string>
- <string name="long_press_shortcut_to_add" msgid="5405328730817637737">"Gusa na ushikilie ili usogeze njia ya mkato."</string>
- <string name="long_accessible_way_to_add_shortcut" msgid="2199537273817090740">"Gusa mara mbili na ushikilie ili usogeze njia ya mkato au utumie vitendo maalum."</string>
- <string name="out_of_space" msgid="6692471482459245734">"Hakuna nafasi kwenye Skrini hii ya kwanza"</string>
+ <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"Gusa na ushikilie ili uchague njia ya mkato."</string>
+ <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"Gusa mara mbili na ushikilie ili uchague njia ya mkato au utumie vitendo maalum."</string>
+ <string name="out_of_space" msgid="4691004494942118364">"Hakuna nafasi katika skrini hii ya Mwanzo."</string>
<string name="hotseat_out_of_space" msgid="7448809638125333693">"Hakuna nafasi zaidi katika treya ya Vipendeleo"</string>
<string name="all_apps_button_label" msgid="8130441508702294465">"Orodha ya programu"</string>
- <string name="all_apps_search_results" msgid="5889367432531296759">"Matokeo ya utafutaji"</string>
<string name="all_apps_button_personal_label" msgid="1315764287305224468">"Orodha ya programu za binafsi"</string>
<string name="all_apps_button_work_label" msgid="7270707118948892488">"Orodha ya programu za kazini"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"Mwanzo"</string>
<string name="remove_drop_target_label" msgid="7812859488053230776">"Ondoa"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"Sakinua"</string>
<string name="app_info_drop_target_label" msgid="692894985365717661">"Maelezo ya programu"</string>
<string name="install_drop_target_label" msgid="2539096853673231757">"Sakinisha"</string>
- <string name="dismiss_prediction_label" msgid="3357562989568808658">"Isipendekeze programu"</string>
- <string name="pin_prediction" msgid="4196423321649756498">"Bandika Utabiri"</string>
<string name="permlab_install_shortcut" msgid="5632423390354674437">"kuweka njia za mkato"</string>
<string name="permdesc_install_shortcut" msgid="923466509822011139">"Huruhusu programu kuongeza njia za mkato bila mtumiaji kuingilia kati."</string>
<string name="permlab_read_settings" msgid="1941457408239617576">"soma mipangilio ya Mwanzo na njia za mkato"</string>
@@ -84,25 +59,29 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"andika mipangilio ya skrini ya Mwanzo na njia za mkato"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"Huruhusu programu kubadilisha mipangilio na njia za mkato katika skrini ya Mwanzo."</string>
<string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> hairuhusiwi kupiga simu"</string>
- <string name="gadget_error_text" msgid="740356548025791839">"Imeshindwa kupakia wijeti"</string>
- <string name="gadget_setup_text" msgid="8348374825537681407">"Mipangilio ya wijeti"</string>
- <string name="gadget_complete_setup_text" msgid="309040266978007925">"Gusa ili umalize kuweka mipangilio"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"Tatizo la kupakia wijeti"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"Sanidi"</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"Hii ni programu ya mfumo na haiwezi kuondolewa."</string>
- <string name="folder_hint_text" msgid="5174843001373488816">"Badilisha Jina"</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"Folda isiyo na jina"</string>
<string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> imezimwa"</string>
- <string name="dotted_app_label" msgid="1704091277755818896">"{count,plural,offset:1 =1{{app_name} ina arifa #}other{{app_name} ina arifa #}}"</string>
+ <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+ <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, ina arifa <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g></item>
+ <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g>, ina arifa <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g></item>
+ </plurals>
<string name="default_scroll_format" msgid="7475544710230993317">"Ukurasa%1$d wa %2$d"</string>
- <string name="workspace_scroll_format" msgid="8458889198184077399">"Skrini ya mwanzo %1$d ya %2$d"</string>
+ <!-- String.format failed for translation -->
+ <!-- no translation found for workspace_scroll_format (8458889198184077399) -->
+ <skip />
<string name="workspace_new_page" msgid="257366611030256142">"Ukurasa mpya wa skrini ya kwanza"</string>
<string name="folder_opened" msgid="94695026776264709">"Folda imefunguliwa, <xliff:g id="WIDTH">%1$d</xliff:g> kwa <xliff:g id="HEIGHT">%2$d</xliff:g>"</string>
<string name="folder_tap_to_close" msgid="4625795376335528256">"Gusa ili ufunge folda"</string>
<string name="folder_tap_to_rename" msgid="4017685068016979677">"Gusa ili ubadilishe jina"</string>
<string name="folder_closed" msgid="4100806530910930934">"Folda imefungwa"</string>
<string name="folder_renamed" msgid="1794088362165669656">"Folda imebadilishwa jina kuwa <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="folder_name_format_exact" msgid="8626242716117004803">"Folda: <xliff:g id="NAME">%1$s</xliff:g>, vipengee <xliff:g id="SIZE">%2$d</xliff:g>"</string>
- <string name="folder_name_format_overflow" msgid="4270108890534995199">"Folda: <xliff:g id="NAME">%1$s</xliff:g>, vipengee <xliff:g id="SIZE">%2$d</xliff:g> au zaidi"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"Folda: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"Wijeti"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Mandhari"</string>
- <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Mandhari na muundo"</string>
+ <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Mitindo na mandhari"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Mipangilio ya mwanzo"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Imezimwa na msimamizi wako"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Ruhusu kuzungusha skrini ya Kwanza"</string>
@@ -114,19 +93,19 @@
<string name="msg_missing_notification_access" msgid="281113995110910548">"Ili kuonyesha Vitone vya Arifa, washa kipengele cha arifa za programu katika <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="title_change_settings" msgid="1376365968844349552">"Badilisha mipangilio"</string>
<string name="notification_dots_service_title" msgid="4284221181793592871">"Onyesha vitone vya arifa"</string>
- <string name="auto_add_shortcuts_label" msgid="3698776050751790653">"Weka aikoni za programu kwenye Skrini ya kwanza"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Ongeza aikoni kwenye Skrini ya kwanza"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Kwa ajili ya programu mpya"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"Yasiyojulikana"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"Ondoa"</string>
<string name="abandoned_search" msgid="891119232568284442">"Tafuta"</string>
<string name="abandoned_promises_title" msgid="7096178467971716750">"Programu hii haijasakinishwa"</string>
<string name="abandoned_promise_explanation" msgid="3990027586878167529">"Programu ya aikoni hii haijasakinishwa. Unaweza kuiondoa, au utafute programu na uisakinishe wewe mwenyewe."</string>
- <string name="app_installing_title" msgid="5864044122733792085">"Inasakinisha <xliff:g id="NAME">%1$s</xliff:g>, imekamilika <xliff:g id="PROGRESS">%2$s</xliff:g>"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> inapakuliwa, <xliff:g id="PROGRESS">%2$s</xliff:g> imekamilika"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> inasubiri kusakinisha"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"Wijeti za <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="widgets_list" msgid="796804551140113767">"Orodha ya wijeti"</string>
<string name="widgets_list_closed" msgid="6141506579418771922">"Orodha ya wijeti imefungwa"</string>
- <string name="action_add_to_workspace" msgid="8902165848117513641">"Weka kwenye Skrini ya Kwanza"</string>
+ <string name="action_add_to_workspace" msgid="8902165848117513641">"Ongeza kwenye Skrini ya Kwanza"</string>
<string name="action_move_here" msgid="2170188780612570250">"Hamishia kipengee hapa"</string>
<string name="item_added_to_workspace" msgid="4211073925752213539">"Kipengee kimeongezwa kwenye skrini ya kwanza"</string>
<string name="item_removed" msgid="851119963877842327">"Kipengee kimeondolewa"</string>
@@ -151,20 +130,15 @@
<string name="action_deep_shortcut" msgid="2864038805849372848">"Njia za mkato"</string>
<string name="shortcuts_menu_with_notifications_description" msgid="2676582286544232849">"Arifa na njia za mkato"</string>
<string name="action_dismiss_notification" msgid="5909461085055959187">"Ondoa"</string>
- <string name="accessibility_close" msgid="2277148124685870734">"Funga"</string>
<string name="notification_dismissed" msgid="6002233469409822874">"Arifa imeondolewa"</string>
<string name="all_apps_personal_tab" msgid="4190252696685155002">"Binafsi"</string>
<string name="all_apps_work_tab" msgid="4884822796154055118">"Kazini"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"Wasifu wa kazini"</string>
- <string name="work_profile_edu_work_apps" msgid="7895468576497746520">"Programu za kazini zina beji na msimamizi wako wa TEHAMA anaziona"</string>
- <string name="work_profile_edu_accept" msgid="6069788082535149071">"Nimeelewa"</string>
- <string name="work_apps_paused_title" msgid="3040901117349444598">"Programu za kazini zimesimamishwa"</string>
- <string name="work_apps_paused_body" msgid="261634750995824906">"Programu zako za kazini haziwezi kukutumia arifa, kutumia betri yako au kufikia maelezo ya mahali ulipo"</string>
- <string name="work_apps_paused_content_description" msgid="5149623040804051095">"Programu za kazini zimezimwa. Programu zako za kazini haziwezi kukutumia arifa, kutumia betri yako au kufikia maelezo ya mahali ulipo"</string>
- <string name="work_apps_paused_edu_banner" msgid="8872412121608402058">"Programu za kazini zina beji na msimamizi wako wa TEHAMA anaziona"</string>
- <string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"Nimeelewa"</string>
- <string name="work_apps_pause_btn_text" msgid="1921059713673767460">"Zima programu za kazini"</string>
- <string name="work_apps_enable_btn_text" msgid="1156432622148413741">"Washa programu za kazini"</string>
- <string name="developer_options_filter_hint" msgid="5896817443635989056">"Kichujio"</string>
+ <string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"Pata programu za kazi hapa"</string>
+ <string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"Kila programu ya kazi ina beji na hulindwa na shirika lako. Hamishia programu kwenye skrini yako ya kwanza ili uzifikie kwa urahisi."</string>
+ <string name="work_mode_on_label" msgid="4781128097185272916">"Inasimamiwa na shirika lako"</string>
+ <string name="work_mode_off_label" msgid="3194894777601421047">"Vipenge vya arifa na programu vimezimwa"</string>
+ <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Funga"</string>
+ <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Imefungwa"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Hitilafu: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
</resources>
diff --git a/res/values-sw600dp-land/dimens.xml b/res/values-sw600dp-land/dimens.xml
deleted file mode 100644
index 63970cddc6..0000000000
--- a/res/values-sw600dp-land/dimens.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2022 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-
-<resources>
-<!-- PagedView -->
- <dimen name="min_page_snap_velocity">3600dp</dimen>
-
-<!-- Hotseat -->
- <dimen name="spring_loaded_hotseat_top_margin">44dp</dimen>
-
-<!-- Dragging -->
- <dimen name="drop_target_top_margin">0dp</dimen>
- <dimen name="drop_target_bottom_margin">16dp</dimen>
-
-<!-- Dynamic grid -->
- <dimen name="dynamic_grid_edge_margin">11.33dp</dimen>
- <dimen name="cell_layout_padding">11.33dp</dimen>
-
-<!-- AllApps -->
- <dimen name="all_apps_bottom_sheet_horizontal_padding">52dp</dimen>
-</resources>
diff --git a/res/values-sw600dp/config.xml b/res/values-sw600dp/config.xml
deleted file mode 100644
index 072b92d5f2..0000000000
--- a/res/values-sw600dp/config.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2022 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<resources>
-
- <!-- The duration of the PagedView page snap animation -->
- <integer name="config_pageSnapAnimationDuration">550</integer>
-
-</resources>
diff --git a/res/values-sw600dp/dimens.xml b/res/values-sw600dp/dimens.xml
index d69e7777b0..47a88f2263 100644
--- a/res/values-sw600dp/dimens.xml
+++ b/res/values-sw600dp/dimens.xml
@@ -15,41 +15,6 @@
-->
<resources>
-<!-- PagedView-->
- <dimen name="min_page_snap_velocity">3000dp</dimen>
-
<!-- DragController -->
<dimen name="drag_flingToDeleteMinVelocity">-1000dp</dimen>
-
-<!-- Widgets pickers -->
- <dimen name="widget_list_horizontal_margin">32dp</dimen>
-
-<!-- AllApps -->
- <dimen name="all_apps_search_bar_content_overlap">0dp</dimen>
- <dimen name="all_apps_bottom_sheet_horizontal_padding">48dp</dimen>
-
-<!-- Fast scroll -->
- <dimen name="fastscroll_popup_width">75dp</dimen>
- <dimen name="fastscroll_popup_height">62dp</dimen>
- <dimen name="fastscroll_popup_padding">13dp</dimen>
- <dimen name="fastscroll_popup_text_size">32dp</dimen>
-
-<!-- Dynamic grid -->
- <dimen name="dynamic_grid_edge_margin">9dp</dimen>
- <dimen name="dynamic_grid_icon_drawable_padding">7dp</dimen>
- <dimen name="cell_layout_padding">9dp</dimen>
-
-<!-- Hotseat -->
- <dimen name="dynamic_grid_hotseat_side_padding">0dp</dimen>
- <dimen name="spring_loaded_hotseat_top_margin">65dp</dimen>
-
-<!-- Dragging -->
- <dimen name="drop_target_top_margin">64dp</dimen>
- <dimen name="drop_target_bottom_margin">16dp</dimen>
- <dimen name="drop_target_button_drawable_horizontal_padding">16dp</dimen>
- <dimen name="drop_target_button_drawable_vertical_padding">16dp</dimen>
- <dimen name="dynamic_grid_drop_target_size">56dp</dimen>
-
-<!-- Workspace grid visualization parameters -->
- <dimen name="grid_visualization_horizontal_cell_spacing">6dp</dimen>
</resources>
diff --git a/res/values-sw720dp-land/dimens.xml b/res/values-sw720dp-land/dimens.xml
deleted file mode 100644
index 235631d6fa..0000000000
--- a/res/values-sw720dp-land/dimens.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2022 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at`
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<resources>
-<!-- PagedView -->
- <dimen name="min_page_snap_velocity">5300dp</dimen>
-
-<!-- Dynamic grid -->
- <dimen name="dynamic_grid_edge_margin">21.93dp</dimen>
- <dimen name="cell_layout_padding">29.33dp</dimen>
-
-<!-- AllApps -->
- <dimen name="all_apps_bottom_sheet_horizontal_padding">32dp</dimen>
-
-<!-- Dragging-->
- <dimen name="drop_target_top_margin">0dp</dimen>
- <dimen name="drop_target_bottom_margin">32dp</dimen>
-
-<!-- Hotseat -->
- <dimen name="spring_loaded_hotseat_top_margin">64dp</dimen>
-
-<!-- Widget picker-->
- <dimen name="widget_list_horizontal_margin">49dp</dimen>
-
-<!-- Bottom sheet-->
- <dimen name="bottom_sheet_extra_top_padding">0dp</dimen>
-</resources>
diff --git a/res/values-sw720dp/dimens.xml b/res/values-sw720dp/dimens.xml
deleted file mode 100644
index 7b2ed8bc65..0000000000
--- a/res/values-sw720dp/dimens.xml
+++ /dev/null
@@ -1,46 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2022 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at`
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<resources>
-<!-- PagedView -->
- <dimen name="min_page_snap_velocity">3400dp</dimen>
-
-<!-- AllApps -->
- <dimen name="all_apps_bottom_sheet_horizontal_padding">28dp</dimen>
-
-<!-- Dynamic grid -->
- <dimen name="dynamic_grid_edge_margin">27.59dp</dimen>
- <dimen name="cell_layout_padding">36dp</dimen>
-
-<!-- Dragging -->
- <dimen name="drop_target_text_size">20sp</dimen>
- <dimen name="dynamic_grid_drop_target_size">72dp</dimen>
- <dimen name="drop_target_button_drawable_horizontal_padding">24dp</dimen>
- <dimen name="drop_target_button_drawable_vertical_padding">20dp</dimen>
- <dimen name="drop_target_button_gap">32dp</dimen>
- <dimen name="drop_target_button_workspace_edge_gap">32dp</dimen>
- <dimen name="drop_target_top_margin">110dp</dimen>
- <dimen name="drop_target_bottom_margin">48dp</dimen>
-
-<!-- Hotseat -->
- <dimen name="spring_loaded_hotseat_top_margin">108dp</dimen>
-
-<!-- Widget picker-->
- <dimen name="widget_list_horizontal_margin">30dp</dimen>
-
-<!-- Bottom sheet-->
- <dimen name="bottom_sheet_extra_top_padding">300dp</dimen>
-</resources>
diff --git a/res/values-ta/strings.xml b/res/values-ta/strings.xml
index 2fa95f85f0..6e933a12e3 100644
--- a/res/values-ta/strings.xml
+++ b/res/values-ta/strings.xml
@@ -26,57 +26,32 @@
<string name="safemode_shortcut_error" msgid="9160126848219158407">"இறக்கிய ஆப்ஸ் பாதுகாப்பு முறையில் முடக்கப்பட்டது"</string>
<string name="safemode_widget_error" msgid="4863470563535682004">"பாதுகாப்புப் பயன்முறையில் விட்ஜெட்கள் முடக்கப்பட்டுள்ளன"</string>
<string name="shortcut_not_available" msgid="2536503539825726397">"ஷார்ட்கட் இல்லை"</string>
- <string name="home_screen" msgid="5629429142036709174">"முகப்பு"</string>
- <string name="recent_task_option_split_screen" msgid="6690461455618725183">"திரைப் பிரிப்பு"</string>
- <string name="split_screen_position_top" msgid="1504965011158689649">"மேற்புறமாகப் பிரி"</string>
- <string name="split_screen_position_left" msgid="7537793098851830883">"இடதுபுறமாகப் பிரி"</string>
- <string name="split_screen_position_right" msgid="1569377524925193369">"வலதுபுறமாகப் பிரி"</string>
- <string name="split_app_info_accessibility" msgid="5475288491241414932">"%1$sக்கான ஆப்ஸ் தகவல்கள்"</string>
- <string name="long_press_widget_to_add" msgid="3587712543577675817">"விட்ஜெட்டை நகர்த்தத் தொட்டுப் பிடிக்கவும்."</string>
- <string name="long_accessible_way_to_add" msgid="2733588281439571974">"விட்ஜெட்டை நகர்த்த இருமுறை தட்டிப் பிடிக்கவும் அல்லது பிரத்தியேகச் செயல்களைப் பயன்படுத்தவும்."</string>
+ <string name="home_screen" msgid="806512411299847073">"முகப்புத் திரை"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"தனிப்பயன் செயல்கள்"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"விட்ஜெட்டைத் தேர்வுசெய்ய தொட்டுப் பிடிக்கவும்."</string>
+ <string name="long_accessible_way_to_add" msgid="4289502106628154155">"விட்ஜெட்டைத் தேர்ந்தெடுக்க இருமுறை தட்டிப் பிடிக்கவும் அல்லது தனிப்பயன் செயல்களைப் பயன்படுத்தவும்."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d அகலத்திற்கு %2$d உயரம்"</string>
- <string name="widget_preview_context_description" msgid="9045841361655787574">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g> விட்ஜெட்"</string>
- <string name="add_item_request_drag_hint" msgid="5653291305078645405">"முகப்புத் திரைக்கு விட்ஜெட்டை நகர்த்த அதைத் தொட்டுப் பிடிக்கவும்"</string>
- <string name="add_to_home_screen" msgid="8631549138215492708">"முகப்புத் திரையில் சேர்"</string>
- <string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g> விட்ஜெட் முகப்புத் திரையில் சேர்க்கப்பட்டது"</string>
- <string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# விட்ஜெட்}other{# விட்ஜெட்டுகள்}}"</string>
- <string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{# ஷார்ட்கட்}other{# ஷார்ட்கட்கள்}}"</string>
- <string name="widgets_and_shortcuts_count" msgid="7209136747878365116">"<xliff:g id="WIDGETS_COUNT">%1$s</xliff:g>, <xliff:g id="SHORTCUTS_COUNT">%2$s</xliff:g>"</string>
- <string name="widget_button_text" msgid="2880537293434387943">"விட்ஜெட்கள்"</string>
- <string name="widgets_full_sheet_search_bar_hint" msgid="8484659090860596457">"தேடுக"</string>
- <string name="widgets_full_sheet_cancel_button_description" msgid="5766167035728653605">"தேடல் பெட்டியிலுள்ள உரையை அழிக்கும்"</string>
- <string name="no_widgets_available" msgid="4337693382501046170">"விட்ஜெட்டுகளும் ஷார்ட்கட்களும் கிடைக்கவில்லை"</string>
- <string name="no_search_results" msgid="3787956167293097509">"விட்ஜெட்டுகள்/ஷார்ட்கட்டுகள் எதுவும் இல்லை"</string>
- <string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"தனிப்பட்டவை"</string>
- <string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"பணி"</string>
- <string name="widget_category_conversations" msgid="8894438636213590446">"உரையாடல்கள்"</string>
- <string name="widget_education_header" msgid="4874760613775913787">"விரல்நுனியில் பயனுள்ள தகவல்களைப் பெறுங்கள்"</string>
- <string name="widget_education_content" msgid="745542879510751525">"ஆப்ஸைத் திறக்காமல் தகவல்களைப் பெற, முகப்புத் திரையில் விட்ஜெட்டுகளைச் சேர்க்கலாம்"</string>
- <string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"விட்ஜெட் அமைப்புகளை மாற்றத் தட்டவும்"</string>
- <string name="widget_education_close_button" msgid="8676165703104836580">"சரி"</string>
- <string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"விட்ஜெட் அமைப்புகளை மாற்றும்"</string>
- <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"ஆப்ஸில் தேடுக"</string>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"நீங்களே சேர்க்க, தொட்டுப் பிடித்திருக்கவும்"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"தானாகவே சேர்"</string>
+ <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"பயன்பாடுகளில் தேடுக"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"ஆப்ஸை ஏற்றுகிறது…"</string>
- <string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" உடன் பொருந்தும் ஆப்ஸ் இல்லை"</string>
+ <string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" உடன் பொருந்தும் பயன்பாடுகள் இல்லை"</string>
<string name="all_apps_search_market_message" msgid="1366263386197059176">"கூடுதல் பயன்பாடுகளைத் தேடு"</string>
<string name="label_application" msgid="8531721983832654978">"ஆப்ஸ்"</string>
- <string name="all_apps_label" msgid="5015784846527570951">"அனைத்து ஆப்ஸும்"</string>
<string name="notifications_header" msgid="1404149926117359025">"அறிவிப்புகள்"</string>
- <string name="long_press_shortcut_to_add" msgid="5405328730817637737">"ஷார்ட்கட்டை நகர்த்தத் தொட்டுப் பிடிக்கவும்."</string>
- <string name="long_accessible_way_to_add_shortcut" msgid="2199537273817090740">"ஷார்ட்கட்டை நகர்த்த இருமுறை தட்டிப் பிடிக்கவும் அல்லது பிரத்தியேகச் செயல்களைப் பயன்படுத்தவும்."</string>
- <string name="out_of_space" msgid="6692471482459245734">"இந்த முகப்புத் திரையில் இடமில்லை"</string>
+ <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"ஷார்ட்கட்டைச் சேர்க்க, தொட்டு பிடித்திருக்கவும்."</string>
+ <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"ஷார்ட்கட்டைச் சேர்க்க, இருமுறை தட்டிப் பிடித்திருக்கவும் (அ) தனிப்பயன் செயல்களைப் பயன்படுத்தவும்."</string>
+ <string name="out_of_space" msgid="4691004494942118364">"முகப்புத் திரையில் இடமில்லை."</string>
<string name="hotseat_out_of_space" msgid="7448809638125333693">"பிடித்தவை ட்ரேயில் இடமில்லை"</string>
<string name="all_apps_button_label" msgid="8130441508702294465">"ஆப்ஸின் பட்டியல்"</string>
- <string name="all_apps_search_results" msgid="5889367432531296759">"தேடல் முடிவுகள்"</string>
<string name="all_apps_button_personal_label" msgid="1315764287305224468">"தனிப்பட்ட ஆப்ஸ் பட்டியல்"</string>
<string name="all_apps_button_work_label" msgid="7270707118948892488">"பணி ஆப்ஸ் பட்டியல்"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"முகப்பு"</string>
<string name="remove_drop_target_label" msgid="7812859488053230776">"அகற்று"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"நிறுவல் நீக்கு"</string>
<string name="app_info_drop_target_label" msgid="692894985365717661">"ஆப்ஸ் தகவல்"</string>
<string name="install_drop_target_label" msgid="2539096853673231757">"நிறுவு"</string>
- <string name="dismiss_prediction_label" msgid="3357562989568808658">"ஆப்ஸைப் பரிந்துரைக்க வேண்டாம்"</string>
- <string name="pin_prediction" msgid="4196423321649756498">"கணிக்கப்பட்ட ஆப்ஸைப் பின் செய்தல்"</string>
<string name="permlab_install_shortcut" msgid="5632423390354674437">"குறுக்குவழிகளை நிறுவுதல்"</string>
<string name="permdesc_install_shortcut" msgid="923466509822011139">"பயனரின் அனுமதி இல்லாமல் குறுக்குவழிகளைச் சேர்க்கப் ஆப்ஸை அனுமதிக்கிறது."</string>
<string name="permlab_read_settings" msgid="1941457408239617576">"முகப்பின் அமைப்பு மற்றும் குறுக்குவழிகளைப் படித்தல்"</string>
@@ -84,25 +59,27 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"முகப்பின் அமைப்பு மற்றும் குறுக்குவழிகளை எழுதுதல்"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"முகப்பில் உள்ள அமைப்பு மற்றும் குறுக்குவழிகளை மாற்ற ஆப்ஸை அனுமதிக்கிறது."</string>
<string name="msg_no_phone_permission" msgid="9208659281529857371">"ஃபோன் அழைப்புகள் செய்ய, <xliff:g id="APP_NAME">%1$s</xliff:g> அனுமதிக்கப்படவில்லை"</string>
- <string name="gadget_error_text" msgid="740356548025791839">"விட்ஜெட்டை ஏற்ற முடியவில்லை"</string>
- <string name="gadget_setup_text" msgid="8348374825537681407">"விட்ஜெட் அமைப்புகள்"</string>
- <string name="gadget_complete_setup_text" msgid="309040266978007925">"அமைவை நிறைவுசெய்யத் தட்டவும்"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"விட்ஜெட்டை ஏற்றுவதில் சிக்கல்"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"அமைவு"</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"இது அமைப்பு ஆப்ஸ் என்பதால் நிறுவல் நீக்கம் செய்ய முடியாது."</string>
- <string name="folder_hint_text" msgid="5174843001373488816">"பெயரைத் திருத்துதல்"</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"பெயரிடப்படாத கோப்புறை"</string>
<string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> முடக்கப்பட்டது"</string>
- <string name="dotted_app_label" msgid="1704091277755818896">"{count,plural,offset:1 =1{{app_name} ஆப்ஸில் # அறிவிப்பு வந்துள்ளது}other{{app_name} ஆப்ஸில் # அறிவிப்புகள் வந்துள்ளன}}"</string>
+ <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+ <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g> ஆப்ஸில் <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> அறிவிப்புகள் வந்துள்ளன</item>
+ <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g> ஆப்ஸில் <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> அறிவிப்பு வந்துள்ளது</item>
+ </plurals>
<string name="default_scroll_format" msgid="7475544710230993317">"பக்கம் %1$d / %2$d"</string>
<string name="workspace_scroll_format" msgid="8458889198184077399">"முகப்புத் திரை %1$d of %2$d"</string>
<string name="workspace_new_page" msgid="257366611030256142">"புதிய முகப்புத் திரை பக்கம்"</string>
- <string name="folder_opened" msgid="94695026776264709">"திறக்கப்பட்ட ஃபோல்டர், <xliff:g id="WIDTH">%1$d</xliff:g> x <xliff:g id="HEIGHT">%2$d</xliff:g>"</string>
- <string name="folder_tap_to_close" msgid="4625795376335528256">"ஃபோல்டரை மூட, தட்டவும்"</string>
+ <string name="folder_opened" msgid="94695026776264709">"திறக்கப்பட்டக் கோப்புறை, <xliff:g id="WIDTH">%1$d</xliff:g> x <xliff:g id="HEIGHT">%2$d</xliff:g>"</string>
+ <string name="folder_tap_to_close" msgid="4625795376335528256">"கோப்புறையை மூட, தட்டவும்"</string>
<string name="folder_tap_to_rename" msgid="4017685068016979677">"மாற்றிய பெயரைச் சேமிக்க, தட்டவும்"</string>
- <string name="folder_closed" msgid="4100806530910930934">"ஃபோல்டர் மூடப்பட்டது"</string>
- <string name="folder_renamed" msgid="1794088362165669656">"ஃபோல்டர் <xliff:g id="NAME">%1$s</xliff:g> என மறுபெயரிடப்பட்டது"</string>
- <string name="folder_name_format_exact" msgid="8626242716117004803">"ஃபோல்டர்: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> ஃபைல்கள்"</string>
- <string name="folder_name_format_overflow" msgid="4270108890534995199">"ஃபோல்டர்: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> அல்லது அதற்கு அதிகமான ஃபைல்கள்"</string>
+ <string name="folder_closed" msgid="4100806530910930934">"கோப்புறை மூடப்பட்டது"</string>
+ <string name="folder_renamed" msgid="1794088362165669656">"கோப்புறை <xliff:g id="NAME">%1$s</xliff:g> என மறுபெயரிடப்பட்டது"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"கோப்புறை: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"விட்ஜெட்கள்"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"வால்பேப்பர்கள்"</string>
- <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"வால்பேப்பர் &amp; ஸ்டைல்"</string>
+ <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"ஸ்டைல்கள் &amp; வால்பேப்பர்கள்"</string>
<string name="settings_button_text" msgid="8873672322605444408">"முகப்பு அமைப்புகள்"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"உங்கள் நிர்வாகி முடக்கியுள்ளார்"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"முகப்புத் திரை சுழற்சியை அனுமதி"</string>
@@ -114,19 +91,19 @@
<string name="msg_missing_notification_access" msgid="281113995110910548">"அறிவிப்புப் புள்ளிகளைக் காட்ட, <xliff:g id="NAME">%1$s</xliff:g> இன் ஆப்ஸ் அறிவிப்புகளை இயக்கவும்"</string>
<string name="title_change_settings" msgid="1376365968844349552">"அமைப்புகளை மாற்று"</string>
<string name="notification_dots_service_title" msgid="4284221181793592871">"அறிவிப்புப் புள்ளிகளைக் காட்டு"</string>
- <string name="auto_add_shortcuts_label" msgid="3698776050751790653">"முகப்புத் திரையில் ஆப்ஸ் ஐகான்களைச் சேர்"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"முகப்புத் திரையில் ஐகானைச் சேர்"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"புதிய ஆப்ஸை நிறுவும்போது"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"தெரியாதது"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"அகற்று"</string>
<string name="abandoned_search" msgid="891119232568284442">"தேடு"</string>
<string name="abandoned_promises_title" msgid="7096178467971716750">"ஆப்ஸ் நிறுவப்படவில்லை"</string>
<string name="abandoned_promise_explanation" msgid="3990027586878167529">"ஐகானுக்கான ஆப்ஸ் நிறுவப்படவில்லை. இதை அகற்றலாம் அல்லது பயன்பாட்டைத் தேடி கைமுறையாக நிறுவலாம்."</string>
- <string name="app_installing_title" msgid="5864044122733792085">"<xliff:g id="NAME">%1$s</xliff:g> நிறுவப்படுகிறது, <xliff:g id="PROGRESS">%2$s</xliff:g> முடிந்தது"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g>ஐப் பதிவிறக்குகிறது, <xliff:g id="PROGRESS">%2$s</xliff:g> முடிந்தது"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g>ஐ நிறுவுவதற்காகக் காத்திருக்கிறது"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"<xliff:g id="NAME">%1$s</xliff:g> விட்ஜெட்டுகள்"</string>
<string name="widgets_list" msgid="796804551140113767">"விட்ஜெட்கள் பட்டியல்"</string>
<string name="widgets_list_closed" msgid="6141506579418771922">"விட்ஜெட்கள் பட்டியல் மூடப்பட்டது"</string>
- <string name="action_add_to_workspace" msgid="8902165848117513641">"முகப்புத் திரையில் சேருங்கள்"</string>
+ <string name="action_add_to_workspace" msgid="8902165848117513641">"முகப்புத் திரையில் சேர்"</string>
<string name="action_move_here" msgid="2170188780612570250">"இங்கு நகர்த்து"</string>
<string name="item_added_to_workspace" msgid="4211073925752213539">"முகப்புத் திரையில் சேர்க்கப்பட்டது"</string>
<string name="item_removed" msgid="851119963877842327">"அகற்றப்பட்டது"</string>
@@ -136,11 +113,11 @@
<string name="move_to_position" msgid="6750008980455459790">"நிலை <xliff:g id="NUMBER">%1$s</xliff:g>க்கு நகர்த்து"</string>
<string name="move_to_hotseat_position" msgid="6295412897075147808">"விரும்பும் நிலை <xliff:g id="NUMBER">%1$s</xliff:g>க்கு நகர்த்து"</string>
<string name="item_moved" msgid="4606538322571412879">"உருப்படி நகர்த்தப்பட்டது"</string>
- <string name="add_to_folder" msgid="9040534766770853243">"இந்த ஃபோல்டரில் சேர்க்கும்: <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="add_to_folder_with_app" msgid="4534929978967147231">"<xliff:g id="NAME">%1$s</xliff:g> உள்ள ஃபோல்டரில் சேர்க்கும்"</string>
- <string name="added_to_folder" msgid="4793259502305558003">"ஃபோல்டரில் உருப்படி சேர்க்கப்பட்டது"</string>
- <string name="create_folder_with" msgid="4050141361160214248">"இதனுடன் ஃபோல்டரை உருவாக்கும்: <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="folder_created" msgid="6409794597405184510">"ஃபோல்டர் உருவாக்கப்பட்டது"</string>
+ <string name="add_to_folder" msgid="9040534766770853243">"இந்தக் கோப்புறையில் சேர்க்கும்: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="add_to_folder_with_app" msgid="4534929978967147231">"<xliff:g id="NAME">%1$s</xliff:g> உள்ள கோப்புறையில் சேர்க்கும்"</string>
+ <string name="added_to_folder" msgid="4793259502305558003">"கோப்புறையில் உருப்படி சேர்க்கப்பட்டது"</string>
+ <string name="create_folder_with" msgid="4050141361160214248">"இதனுடன் கோப்புறையை உருவாக்கும்: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="folder_created" msgid="6409794597405184510">"கோப்புறை உருவாக்கப்பட்டது"</string>
<string name="action_move_to_workspace" msgid="1603837886334246317">"முகப்புத் திரைக்கு நகர்த்து"</string>
<string name="action_resize" msgid="1802976324781771067">"அளவு மாற்று"</string>
<string name="action_increase_width" msgid="8773715375078513326">"அகலத்தை அதிகரி"</string>
@@ -151,20 +128,15 @@
<string name="action_deep_shortcut" msgid="2864038805849372848">"ஷார்ட்கட்கள்"</string>
<string name="shortcuts_menu_with_notifications_description" msgid="2676582286544232849">"ஷார்ட்கட்கள் மற்றும் அறிவிப்புகள்"</string>
<string name="action_dismiss_notification" msgid="5909461085055959187">"நிராகரி"</string>
- <string name="accessibility_close" msgid="2277148124685870734">"மூடும் பட்டன்"</string>
<string name="notification_dismissed" msgid="6002233469409822874">"அறிவிப்பு நிராகரிக்கப்பட்டது"</string>
<string name="all_apps_personal_tab" msgid="4190252696685155002">"தனிப்பட்டவை"</string>
<string name="all_apps_work_tab" msgid="4884822796154055118">"பணி"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"பணிக் கணக்கு"</string>
- <string name="work_profile_edu_work_apps" msgid="7895468576497746520">"பணி ஆப்ஸில் பேட்ஜ் இடப்பட்டுள்ளன. உங்கள் IT நிர்வாகியால் அவற்றைப் பார்க்க முடியும்"</string>
- <string name="work_profile_edu_accept" msgid="6069788082535149071">"முடிந்தது"</string>
- <string name="work_apps_paused_title" msgid="3040901117349444598">"பணி ஆப்ஸ் இடைநிறுத்தப்பட்டுள்ளன"</string>
- <string name="work_apps_paused_body" msgid="261634750995824906">"பணி ஆப்ஸால் உங்களுக்கு அறிவிப்புகளை அனுப்பவோ பேட்டரியைப் பயன்படுத்தவோ உங்கள் இருப்பிடத்தை அணுகவோ முடியாது"</string>
- <string name="work_apps_paused_content_description" msgid="5149623040804051095">"பணி ஆப்ஸ் முடக்கப்பட்டுள்ளன. அவற்றால் உங்களுக்கு அறிவிப்புகளை அனுப்பவோ பேட்டரியைப் பயன்படுத்தவோ உங்கள் இருப்பிடத்தை அணுகவோ முடியாது"</string>
- <string name="work_apps_paused_edu_banner" msgid="8872412121608402058">"பணி ஆப்ஸ் பேட்ஜ் குறியிடப்பட்டுள்ளன. மேலும் உங்கள் IT நிர்வாகியால் அவற்றைப் பார்க்க முடியும்"</string>
- <string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"சரி"</string>
- <string name="work_apps_pause_btn_text" msgid="1921059713673767460">"பணி ஆப்ஸை முடக்கு"</string>
- <string name="work_apps_enable_btn_text" msgid="1156432622148413741">"பணி ஆப்ஸை இயக்கு"</string>
- <string name="developer_options_filter_hint" msgid="5896817443635989056">"வடிப்பான்"</string>
+ <string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"பணி ஆப்ஸை இங்கு காணலாம்"</string>
+ <string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"ஒவ்வொரு பணிப் பயன்பாடும் ஒரு பேட்ஜைக் கொண்டிருக்கும். இவை, ஆப்ஸ் உங்கள் நிறுவனத்தால் பாதுகாப்பாக வைக்கப்பட்டுள்ளன என்பதைக் குறிக்கின்றன. இந்த ஆப்ஸை எளிதாக அணுக, முகப்புத் திரைக்கு நகர்த்திக்கொள்ளவும்."</string>
+ <string name="work_mode_on_label" msgid="4781128097185272916">"உங்கள் நிறுவனம் நிர்வகிக்கிறது"</string>
+ <string name="work_mode_off_label" msgid="3194894777601421047">"ஆப்ஸும் அறிவிப்புகளும் ஆஃப் செய்யப்பட்டுள்ளன"</string>
+ <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"மூடுக"</string>
+ <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"மூடப்பட்டது"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"தோல்வி: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
</resources>
diff --git a/res/values-te/strings.xml b/res/values-te/strings.xml
index ce364bdef7..1f8d3b8c4f 100644
--- a/res/values-te/strings.xml
+++ b/res/values-te/strings.xml
@@ -20,77 +20,54 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="649227358658669779">"Launcher3"</string>
- <string name="work_folder_name" msgid="3753320833950115786">"వర్క్"</string>
+ <string name="work_folder_name" msgid="3753320833950115786">"కార్యాలయం"</string>
<string name="activity_not_found" msgid="8071924732094499514">"యాప్ ఇన్‌స్టాల్ చేయబడలేదు."</string>
<string name="activity_not_available" msgid="7456344436509528827">"యాప్ అందుబాటులో లేదు"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"డౌన్‌లోడ్ చేసిన యాప్ సురక్షిత మోడ్‌లో నిలిపివేయబడింది"</string>
<string name="safemode_widget_error" msgid="4863470563535682004">"సురక్షిత మోడ్‌లో విడ్జెట్‌లు నిలిపివేయబడ్డాయి"</string>
<string name="shortcut_not_available" msgid="2536503539825726397">"షార్ట్‌కట్ అందుబాటులో లేదు"</string>
- <string name="home_screen" msgid="5629429142036709174">"మొదటి ట్యాబ్"</string>
- <string name="recent_task_option_split_screen" msgid="6690461455618725183">"స్క్రీన్‌ను విభజించు"</string>
- <string name="split_screen_position_top" msgid="1504965011158689649">"స్ప్లిట్ ఎగువన"</string>
- <string name="split_screen_position_left" msgid="7537793098851830883">"స్ప్లిట్ ఎడమవైపు"</string>
- <string name="split_screen_position_right" msgid="1569377524925193369">"స్ప్లిట్ కుడివైపు"</string>
- <string name="split_app_info_accessibility" msgid="5475288491241414932">"%1$s కోసం యాప్ సమాచారం"</string>
- <string name="long_press_widget_to_add" msgid="3587712543577675817">"విడ్జెట్‌ను తరలించడానికి తాకి &amp; నొక్కి ఉంచండి."</string>
- <string name="long_accessible_way_to_add" msgid="2733588281439571974">"విడ్జెట్‌ను తరలించడానికి లేదా అనుకూల చర్యలను ఉపయోగించడానికి రెండుసార్లు నొక్కండి &amp; హోల్డ్ చేయి."</string>
+ <string name="home_screen" msgid="806512411299847073">"హోమ్ స్క్రీన్"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"అనుకూల చర్యలు"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"విడ్జెట్‌ను ఎంచుకోవడానికి తాకి &amp; నొక్కి పెట్టండి."</string>
+ <string name="long_accessible_way_to_add" msgid="4289502106628154155">"విడ్జెట్‌ను ఎంచుకోవడానికి లేదా అనుకూల చర్యలను ఉపయోగించడానికి రెండుసార్లు నొక్కి, ఉంచండి."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d వెడల్పు X %2$d ఎత్తు"</string>
- <string name="widget_preview_context_description" msgid="9045841361655787574">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g> విడ్జెట్"</string>
- <string name="add_item_request_drag_hint" msgid="5653291305078645405">"ఈ విడ్జెట్‌ను మొదటి స్క్రీన్‌లో కావాల్సిన చోట ఉంచడానికి, దాన్ని తాకి అలాగే నొక్కి పట్టుకోండి"</string>
- <string name="add_to_home_screen" msgid="8631549138215492708">"మొదటి స్క్రీన్‌కు జోడించు"</string>
- <string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"మొదటి స్క్రీన్‌కు <xliff:g id="WIDGET_NAME">%1$s</xliff:g> విడ్జెట్ జోడించబడింది"</string>
- <string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# విడ్జెట్}other{# విడ్జెట్‌లు}}"</string>
- <string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{# షార్ట్‌కట్}other{# షార్ట్‌కట్‌లు}}"</string>
- <string name="widgets_and_shortcuts_count" msgid="7209136747878365116">"<xliff:g id="WIDGETS_COUNT">%1$s</xliff:g>, <xliff:g id="SHORTCUTS_COUNT">%2$s</xliff:g>"</string>
- <string name="widget_button_text" msgid="2880537293434387943">"విడ్జెట్‌లు"</string>
- <string name="widgets_full_sheet_search_bar_hint" msgid="8484659090860596457">"సెర్చ్ చేయండి"</string>
- <string name="widgets_full_sheet_cancel_button_description" msgid="5766167035728653605">"సెర్చ్ బాక్స్ నుండి టెక్స్ట్‌ను క్లియర్ చేయండి"</string>
- <string name="no_widgets_available" msgid="4337693382501046170">"విడ్జెట్‌లు, షార్ట్‌కట్‌లు అందుబాటులో లేవు"</string>
- <string name="no_search_results" msgid="3787956167293097509">"విడ్జెట్‌లు లేదా షార్ట్‌కట్‌లు కనుగొనబడలేదు"</string>
- <string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"వ్యక్తిగత గ్యాడ్జెట్స్"</string>
- <string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"ఆఫీస్"</string>
- <string name="widget_category_conversations" msgid="8894438636213590446">"సంభాషణలు"</string>
- <string name="widget_education_header" msgid="4874760613775913787">"మీ చేతివేళ్ల మీద ఉపయోగకరమైన సమాచారం"</string>
- <string name="widget_education_content" msgid="745542879510751525">"యాప్‌లను తెరవకుండా సమాచారం పొందడానికి, మీరు మీ మొదటి స్క్రీన్‌కు విడ్జెట్‌లను జోడించవచ్చు"</string>
- <string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"విడ్జెట్ సెట్టింగ్‌లను మార్చడానికి ట్యాప్ చేయండి"</string>
- <string name="widget_education_close_button" msgid="8676165703104836580">"అర్థమైంది"</string>
- <string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"విడ్జెట్ సెట్టింగ్‌లను మార్చండి"</string>
- <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"యాప్‌ల కోసం సెర్చ్ చేయండి"</string>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"మాన్యువల్‌గా ఉంచడానికి నొక్కి, పట్టుకోండి"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"ఆటోమేటిక్‌గా జోడించు"</string>
+ <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"అప్లికేషన్‌లను శోధించండి"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"అప్లికేషన్‌లను లోడ్ చేస్తోంది…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\"కి సరిపోలే అప్లికేషన్‌లేవీ కనుగొనబడలేదు"</string>
- <string name="all_apps_search_market_message" msgid="1366263386197059176">"మరిన్ని యాప్‌ల కోసం సెర్చ్ చేయండి"</string>
+ <string name="all_apps_search_market_message" msgid="1366263386197059176">"మరిన్ని యాప్‌ల కోసం వెతుకు"</string>
<string name="label_application" msgid="8531721983832654978">"యాప్"</string>
- <string name="all_apps_label" msgid="5015784846527570951">"అన్ని యాప్‌లు"</string>
<string name="notifications_header" msgid="1404149926117359025">"నోటిఫికేషన్‌లు"</string>
- <string name="long_press_shortcut_to_add" msgid="5405328730817637737">"షార్ట్‌కట్‌ను తరలించడానికి తాకి &amp; నొక్కి ఉంచు."</string>
- <string name="long_accessible_way_to_add_shortcut" msgid="2199537273817090740">"షార్ట్‌కట్‌ను తరలించడానికి లేదా అనుకూల చర్యలను ఉపయోగించడానికి రెండుసార్లు నొక్కండి &amp; హోల్డ్ చేయండి."</string>
- <string name="out_of_space" msgid="6692471482459245734">"ఈ మొదటి స్క్రీన్‌లో స్థలం లేదు"</string>
+ <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"షార్ట్‌కట్‌ని ఎంచుకోవడం కోసం నొక్కి, పట్టుకోండి."</string>
+ <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"రెండుసార్లు నొక్కి, పట్టుకోవడం ద్వారా షార్ట్‌కట్‌ని ఎంచుకోండి లేదా అనుకూల చర్యలను ఉపయోగించండి."</string>
+ <string name="out_of_space" msgid="4691004494942118364">"ఈ హోమ్ స్క్రీన్‌లో ఖాళీ లేదు."</string>
<string name="hotseat_out_of_space" msgid="7448809638125333693">"ఇష్టమైనవి ట్రేలో ఖాళీ లేదు"</string>
- <string name="all_apps_button_label" msgid="8130441508702294465">"యాప్‌ల లిస్ట్‌"</string>
- <string name="all_apps_search_results" msgid="5889367432531296759">"సెర్చ్ ఫలితాలు"</string>
- <string name="all_apps_button_personal_label" msgid="1315764287305224468">"వ్యక్తిగత యాప్‌ల లిస్ట్‌"</string>
- <string name="all_apps_button_work_label" msgid="7270707118948892488">"కార్యాలయ యాప్‌ల లిస్ట్‌"</string>
+ <string name="all_apps_button_label" msgid="8130441508702294465">"అనువర్తనాల జాబితా"</string>
+ <string name="all_apps_button_personal_label" msgid="1315764287305224468">"వ్యక్తిగత యాప్‌ల జాబితా"</string>
+ <string name="all_apps_button_work_label" msgid="7270707118948892488">"కార్యాలయ యాప్‌ల జాబితా"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"హోమ్"</string>
<string name="remove_drop_target_label" msgid="7812859488053230776">"తీసివేయి"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"అన్ఇన్‌స్టాల్ చేయి"</string>
<string name="app_info_drop_target_label" msgid="692894985365717661">"యాప్ సమాచారం"</string>
<string name="install_drop_target_label" msgid="2539096853673231757">"ఇన్‌స్టాల్ చేయండి"</string>
- <string name="dismiss_prediction_label" msgid="3357562989568808658">"యాప్‌ను సూచించవద్దు"</string>
- <string name="pin_prediction" msgid="4196423321649756498">"సూచనను పిన్ చేయండి"</string>
<string name="permlab_install_shortcut" msgid="5632423390354674437">"షార్ట్‌కట్‌లను ఇన్‌స్టాల్ చేయడం"</string>
- <string name="permdesc_install_shortcut" msgid="923466509822011139">"వినియోగదారు ప్రమేయం లేకుండా షార్ట్‌కట్‌లను జోడించడానికి యాప్‌ను అనుమతిస్తుంది."</string>
- <string name="permlab_read_settings" msgid="1941457408239617576">"హోమ్ సెట్టింగ్‌లు మరియు షార్ట్‌కట్‌లను చదవడం"</string>
- <string name="permdesc_read_settings" msgid="5833423719057558387">"హోమ్‌లో సెట్టింగ్‌లు మరియు షార్ట్‌కట్‌లను చదవడానికి యాప్‌ను అనుమతిస్తుంది."</string>
- <string name="permlab_write_settings" msgid="3574213698004620587">"హోమ్ సెట్టింగ్‌లు మరియు షార్ట్‌కట్‌లను రాయడం"</string>
- <string name="permdesc_write_settings" msgid="5440712911516509985">"హోమ్‌లో సెట్టింగ్‌లు మరియు షార్ట్‌కట్‌లను మార్చడానికి యాప్‌ను అనుమతిస్తుంది."</string>
- <string name="msg_no_phone_permission" msgid="9208659281529857371">"ఫోన్ కాల్స్‌ను చేసేందుకు <xliff:g id="APP_NAME">%1$s</xliff:g>కి అనుమతి లేదు"</string>
- <string name="gadget_error_text" msgid="740356548025791839">"విడ్జెట్‌ను లోడ్ చేయడం సాధ్యం కాలేదు"</string>
- <string name="gadget_setup_text" msgid="8348374825537681407">"విడ్జెట్ సెట్టింగ్‌లు"</string>
- <string name="gadget_complete_setup_text" msgid="309040266978007925">"సెటప్‌ను ముగించడానికి ట్యాప్ చేయండి"</string>
+ <string name="permdesc_install_shortcut" msgid="923466509822011139">"వినియోగదారు ప్రమేయం లేకుండా సత్వరమార్గాలను జోడించడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string>
+ <string name="permlab_read_settings" msgid="1941457408239617576">"హోమ్ సెట్టింగ్‌లు మరియు సత్వరమార్గాలను చదవడం"</string>
+ <string name="permdesc_read_settings" msgid="5833423719057558387">"హోమ్‌లో సెట్టింగ్‌లు మరియు సత్వరమార్గాలను చదవడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string>
+ <string name="permlab_write_settings" msgid="3574213698004620587">"హోమ్ సెట్టింగ్‌లు మరియు సత్వరమార్గాలను వ్రాయడం"</string>
+ <string name="permdesc_write_settings" msgid="5440712911516509985">"హోమ్‌లో సెట్టింగ్‌లు మరియు సత్వరమార్గాలను మార్చడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string>
+ <string name="msg_no_phone_permission" msgid="9208659281529857371">"ఫోన్ కాల్‌లను చేసేందుకు <xliff:g id="APP_NAME">%1$s</xliff:g>కి అనుమతి లేదు"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"విడ్జెట్‌ను లోడ్ చేయడంలో సమస్య"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"సెటప్ చేయి"</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"ఇది సిస్టమ్ యాప్ మరియు దీన్ని అన్‌ఇన్‌స్టాల్ చేయడం సాధ్యపడదు."</string>
- <string name="folder_hint_text" msgid="5174843001373488816">"పేరును ఎడిట్ చేయండి"</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"పేరు లేని ఫోల్డర్"</string>
<string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> నిలిపివేయబడింది"</string>
- <string name="dotted_app_label" msgid="1704091277755818896">"{count,plural,offset:1 =1{{app_name}లో # నోటిఫికేషన్ ఉంది}other{{app_name}లో # నోటిఫికేషన్‌లు ఉన్నాయి}}"</string>
+ <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+ <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, నుంచి <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> నోటిఫికేషన్‌లు ఉన్నాయి</item>
+ <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g>, నుంచి <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> నోటిఫికేషన్ ఉంది</item>
+ </plurals>
<string name="default_scroll_format" msgid="7475544710230993317">"%2$dలో %1$dవ పేజీ"</string>
<string name="workspace_scroll_format" msgid="8458889198184077399">"%2$dలో %1$dవ హోమ్ స్క్రీన్"</string>
<string name="workspace_new_page" msgid="257366611030256142">"కొత్త హోమ్ స్క్రీన్ పేజీ"</string>
@@ -99,13 +76,13 @@
<string name="folder_tap_to_rename" msgid="4017685068016979677">"పేరు మార్పును సేవ్ చేయడానికి నొక్కండి"</string>
<string name="folder_closed" msgid="4100806530910930934">"ఫోల్డర్ మూసివేయబడింది"</string>
<string name="folder_renamed" msgid="1794088362165669656">"ఫోల్డర్ పేరు <xliff:g id="NAME">%1$s</xliff:g>గా మార్చబడింది"</string>
- <string name="folder_name_format_exact" msgid="8626242716117004803">"ఫోల్డర్: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> ఐటెమ్‌లు"</string>
- <string name="folder_name_format_overflow" msgid="4270108890534995199">"ఫోల్డర్: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> లేదా అంతకంటే ఎక్కువ ఐటెమ్‌లు"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"ఫోల్డర్: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"విడ్జెట్‌లు"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"వాల్‌పేపర్‌లు"</string>
- <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"వాల్‌పేపర్ &amp; స్టయిల్"</string>
- <string name="settings_button_text" msgid="8873672322605444408">"మొదటి స్క్రీన్ సెట్టింగ్‌లు"</string>
+ <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"స్ట‌యిల్స్‌ &amp; వాల్‌పేపర్‌లు"</string>
+ <string name="settings_button_text" msgid="8873672322605444408">"హోమ్ సెట్టింగ్‌లు"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"మీ నిర్వాహకులు నిలిపివేసారు"</string>
- <string name="allow_rotation_title" msgid="7728578836261442095">"మొదటి స్క్రీన్ రొటేషన్‌ను అనుమతించండి"</string>
+ <string name="allow_rotation_title" msgid="7728578836261442095">"హోమ్ స్క్రీన్ భ్రమణాన్ని అనుమతించండి"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"ఫోన్‌‌ను తిప్పినప్పుడు"</string>
<string name="notification_dots_title" msgid="9062440428204120317">"నోటిఫికేషన్ డాట్‌లు"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"ఆన్"</string>
@@ -114,22 +91,22 @@
<string name="msg_missing_notification_access" msgid="281113995110910548">"నోటిఫికేషన్ డాట్‌లను చూపించడానికి <xliff:g id="NAME">%1$s</xliff:g>కు యాప్ నోటిఫికేషన్‌లను ఆన్ చేయండి"</string>
<string name="title_change_settings" msgid="1376365968844349552">"సెట్టింగ్‌లను మార్చు"</string>
<string name="notification_dots_service_title" msgid="4284221181793592871">"నోటిఫికేషన్ డాట్‌లను చూపు"</string>
- <string name="auto_add_shortcuts_label" msgid="3698776050751790653">"యాప్ చిహ్నాలను మొదటి స్క్రీన్‌కు జోడించు"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"హోమ్ స్క్రీన్‌కి చిహ్నాన్ని జోడించు"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"కొత్త యాప్‌ల కోసం"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"తెలియదు"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"తీసివేయి"</string>
- <string name="abandoned_search" msgid="891119232568284442">"సెర్చ్"</string>
+ <string name="abandoned_search" msgid="891119232568284442">"వెతుకు"</string>
<string name="abandoned_promises_title" msgid="7096178467971716750">"ఈ యాప్ ఇన్‌స్టాల్ చేయబడలేదు"</string>
- <string name="abandoned_promise_explanation" msgid="3990027586878167529">"ఈ ఐకాన్‌కు చెందిన యాప్ ఇన్‌స్టాల్ చేయలేదు. మీరు దీన్ని తీసివేయవచ్చు లేదా ఆ యాప్ కోసం సెర్చ్ చేసి, దాన్ని మాన్యువల్‌గా ఇన్‌స్టాల్ చేయవచ్చు."</string>
- <string name="app_installing_title" msgid="5864044122733792085">"<xliff:g id="NAME">%1$s</xliff:g>‌ను ఇన్‌స్టాల్ చేయడం, <xliff:g id="PROGRESS">%2$s</xliff:g> పూర్తయింది"</string>
+ <string name="abandoned_promise_explanation" msgid="3990027586878167529">"ఈ చిహ్నం యొక్క యాప్ ఇన్‌స్టాల్ చేయబడలేదు. మీరు దీన్ని తీసివేయవచ్చు లేదా ఆ యాప్ కోసం శోధించి దాన్ని మాన్యువల్‌గా ఇన్‌స్టాల్ చేయవచ్చు."</string>
<string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> డౌన్‌లోడ్ అవుతోంది, <xliff:g id="PROGRESS">%2$s</xliff:g> పూర్తయింది"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> ఇన్‌స్టాల్ కావడానికి వేచి ఉంది"</string>
- <string name="widgets_list" msgid="796804551140113767">"విడ్జెట్‌ల లిస్ట్‌"</string>
- <string name="widgets_list_closed" msgid="6141506579418771922">"విడ్జెట్‌ల లిస్ట్‌ మూసివేయబడింది"</string>
- <string name="action_add_to_workspace" msgid="8902165848117513641">"హోమ్ స్క్రీన్‌కు జోడించండి"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"<xliff:g id="NAME">%1$s</xliff:g> విడ్జెట్‌లు"</string>
+ <string name="widgets_list" msgid="796804551140113767">"విడ్జెట్‌ల జాబితా"</string>
+ <string name="widgets_list_closed" msgid="6141506579418771922">"విడ్జెట్‌ల జాబితా మూసివేయబడింది"</string>
+ <string name="action_add_to_workspace" msgid="8902165848117513641">"హోమ్ స్క్రీన్‌కు జోడించు"</string>
<string name="action_move_here" msgid="2170188780612570250">"అంశాన్ని ఇక్కడికి తరలించు"</string>
<string name="item_added_to_workspace" msgid="4211073925752213539">"అంశం హోమ్‌స్క్రీన్‌కి జోడించబడింది"</string>
- <string name="item_removed" msgid="851119963877842327">"ఐటెమ్ తీసివేయబడింది"</string>
+ <string name="item_removed" msgid="851119963877842327">"అంశం తీసివేయబడింది"</string>
<string name="undo" msgid="4151576204245173321">"చర్య రద్దు"</string>
<string name="action_move" msgid="4339390619886385032">"అంశాన్ని తరలించు"</string>
<string name="move_to_empty_cell" msgid="2833711483015685619">"అడ్డు వరుస <xliff:g id="NUMBER_0">%1$s</xliff:g> నిలువు వరుస <xliff:g id="NUMBER_1">%2$s</xliff:g>కి తరలించు"</string>
@@ -139,7 +116,7 @@
<string name="add_to_folder" msgid="9040534766770853243">"ఈ ఫోల్డర్‌కి జోడించండి: <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="add_to_folder_with_app" msgid="4534929978967147231">"<xliff:g id="NAME">%1$s</xliff:g> గల ఫోల్డర్‌కు జోడించు"</string>
<string name="added_to_folder" msgid="4793259502305558003">"అంశం ఫోల్డర్‌కు జోడించబడింది"</string>
- <string name="create_folder_with" msgid="4050141361160214248">"ఈ పేరుతో ఫోల్డర్‌ను క్రియేట్ చేయండి: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="create_folder_with" msgid="4050141361160214248">"ఈ పేరుతో ఫోల్డర్‌ను సృష్టించండి: <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="folder_created" msgid="6409794597405184510">"ఫోల్డర్ సృష్టించబడింది"</string>
<string name="action_move_to_workspace" msgid="1603837886334246317">"హోమ్‌స్క్రీన్‌కు తరలించు"</string>
<string name="action_resize" msgid="1802976324781771067">"పరిమాణం మార్చు"</string>
@@ -148,23 +125,18 @@
<string name="action_decrease_width" msgid="1374549771083094654">"వెడల్పును తగ్గించు"</string>
<string name="action_decrease_height" msgid="282377193880900022">"ఎత్తును తగ్గించు"</string>
<string name="widget_resized" msgid="9130327887929620">"విడ్జెట్ పరిమాణం వెడల్పు <xliff:g id="NUMBER_0">%1$s</xliff:g>కి, ఎత్తు <xliff:g id="NUMBER_1">%2$s</xliff:g>కి మార్చబడింది"</string>
- <string name="action_deep_shortcut" msgid="2864038805849372848">"షార్ట్‌కట్స్"</string>
+ <string name="action_deep_shortcut" msgid="2864038805849372848">"సత్వరమార్గాలు"</string>
<string name="shortcuts_menu_with_notifications_description" msgid="2676582286544232849">"షార్ట్‌కట్‌లు మరియు నోటిఫికేషన్‌లు"</string>
<string name="action_dismiss_notification" msgid="5909461085055959187">"తీసివేయి"</string>
- <string name="accessibility_close" msgid="2277148124685870734">"మూసివేస్తుంది"</string>
<string name="notification_dismissed" msgid="6002233469409822874">"నోటిఫికేషన్ తీసివేయబడింది"</string>
<string name="all_apps_personal_tab" msgid="4190252696685155002">"వ్యక్తిగతం"</string>
- <string name="all_apps_work_tab" msgid="4884822796154055118">"వర్క్"</string>
+ <string name="all_apps_work_tab" msgid="4884822796154055118">"కార్యాలయం"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"కార్యాలయ ప్రొఫైల్"</string>
- <string name="work_profile_edu_work_apps" msgid="7895468576497746520">"వర్క్ యాప్‌లకు బ్యాడ్జ్ ఉంటుంది, అవి మీ IT అడ్మిన్‌కు కనిపిస్తాయి"</string>
- <string name="work_profile_edu_accept" msgid="6069788082535149071">"అర్థమైంది"</string>
- <string name="work_apps_paused_title" msgid="3040901117349444598">"వర్క్ యాప్‌లు పాజ్ చేయబడ్డాయి"</string>
- <string name="work_apps_paused_body" msgid="261634750995824906">"మీకు నోటిఫికేషన్‌లు పంపడం, మీ బ్యాటరీని ఉపయోగించడం, లేదా మీ లొకేషన్‌ను యాక్సెస్ చేయడం మీ వర్క్ యాప్‌లకు సాధ్యపడదు"</string>
- <string name="work_apps_paused_content_description" msgid="5149623040804051095">"వర్క్ యాప్‌లు ఆఫ్‌లో ఉన్నాయి. మీకు నోటిఫికేషన్‌లు పంపడం, మీ బ్యాటరీని ఉపయోగించడం, లేదా మీ లొకేషన్‌ను యాక్సెస్ చేయడం మీ వర్క్ యాప్‌లకు సాధ్యపడదు"</string>
- <string name="work_apps_paused_edu_banner" msgid="8872412121608402058">"వర్క్ యాప్‌లకు బ్యాడ్జ్ ఉంటుంది, అవి మీ IT అడ్మిన్‌కు కనిపిస్తాయి"</string>
- <string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"అర్థమైంది"</string>
- <string name="work_apps_pause_btn_text" msgid="1921059713673767460">"వర్క్ యాప్‌లను ఆఫ్ చేయండి"</string>
- <string name="work_apps_enable_btn_text" msgid="1156432622148413741">"వర్క్ యాప్‌లను ఆన్ చేయి"</string>
- <string name="developer_options_filter_hint" msgid="5896817443635989056">"ఫిల్టర్ చేయి"</string>
+ <string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"కార్యాలయ యాప్‌లను ఇక్కడ కనుగొనండి"</string>
+ <string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"ప్రతి కార్యాలయ యాప్‌కు బ్యాడ్జ్‌ ఉంది మరియు మీ సంస్థ ద్వారా సురక్షితంగా ఉంచబడుతుంది. సులభ యాక్సెస్ కోసం యాప్‌లను మీ హోమ్ స్క్రీన్‌కి తరలించండి."</string>
+ <string name="work_mode_on_label" msgid="4781128097185272916">"మీ సంస్థ ద్వారా నిర్వహించబడతాయి"</string>
+ <string name="work_mode_off_label" msgid="3194894777601421047">"నోటిఫికేషన్‌లు మరియు యాప్‌లు ఆఫ్ చేయబడ్డాయి"</string>
+ <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"మూసివేయి"</string>
+ <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"మూసివేయబడింది"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"విఫలమైంది: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
</resources>
diff --git a/res/values-th/strings.xml b/res/values-th/strings.xml
index 768bff66d4..5ab9b860ef 100644
--- a/res/values-th/strings.xml
+++ b/res/values-th/strings.xml
@@ -26,57 +26,32 @@
<string name="safemode_shortcut_error" msgid="9160126848219158407">"แอปที่ดาวน์โหลดถูกปิดในโหมดปลอดภัย"</string>
<string name="safemode_widget_error" msgid="4863470563535682004">"มีการปิดใช้งานวิดเจ็ตในเซฟโหมด"</string>
<string name="shortcut_not_available" msgid="2536503539825726397">"ทางลัดไม่พร้อมใช้งาน"</string>
- <string name="home_screen" msgid="5629429142036709174">"หน้าแรก"</string>
- <string name="recent_task_option_split_screen" msgid="6690461455618725183">"แบ่งหน้าจอ"</string>
- <string name="split_screen_position_top" msgid="1504965011158689649">"แยกไปด้านบน"</string>
- <string name="split_screen_position_left" msgid="7537793098851830883">"แยกไปทางซ้าย"</string>
- <string name="split_screen_position_right" msgid="1569377524925193369">"แยกไปทางขวา"</string>
- <string name="split_app_info_accessibility" msgid="5475288491241414932">"ข้อมูลแอปสำหรับ %1$s"</string>
- <string name="long_press_widget_to_add" msgid="3587712543577675817">"แตะค้างไว้เพื่อย้ายวิดเจ็ต"</string>
- <string name="long_accessible_way_to_add" msgid="2733588281439571974">"แตะสองครั้งค้างไว้เพื่อย้ายวิดเจ็ตหรือใช้การดำเนินการที่กำหนดเอง"</string>
+ <string name="home_screen" msgid="806512411299847073">"หน้าจอหลัก"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"การทำงานที่กำหนดเอง"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"แตะค้างเพื่อรับวิดเจ็ต"</string>
+ <string name="long_accessible_way_to_add" msgid="4289502106628154155">"แตะ 2 ครั้งค้างไว้เพื่อเลือกวิดเจ็ตหรือใช้การกระทำที่กำหนดเอง"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"กว้าง %1$d x สูง %2$d"</string>
- <string name="widget_preview_context_description" msgid="9045841361655787574">"วิดเจ็ต <xliff:g id="WIDGET_NAME">%1$s</xliff:g>"</string>
- <string name="add_item_request_drag_hint" msgid="5653291305078645405">"แตะวิดเจ็ตค้างไว้เพื่อย้ายไปรอบๆ หน้าจอหลัก"</string>
- <string name="add_to_home_screen" msgid="8631549138215492708">"เพิ่มลงในหน้าจอหลัก"</string>
- <string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"เพิ่มวิดเจ็ต <xliff:g id="WIDGET_NAME">%1$s</xliff:g> ลงในหน้าจอหลักแล้ว"</string>
- <string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{วิดเจ็ต # รายการ}other{วิดเจ็ต # รายการ}}"</string>
- <string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{ทางลัด # รายการ}other{ทางลัด # รายการ}}"</string>
- <string name="widgets_and_shortcuts_count" msgid="7209136747878365116">"<xliff:g id="WIDGETS_COUNT">%1$s</xliff:g>, <xliff:g id="SHORTCUTS_COUNT">%2$s</xliff:g>"</string>
- <string name="widget_button_text" msgid="2880537293434387943">"วิดเจ็ต"</string>
- <string name="widgets_full_sheet_search_bar_hint" msgid="8484659090860596457">"ค้นหา"</string>
- <string name="widgets_full_sheet_cancel_button_description" msgid="5766167035728653605">"ล้างข้อความออกจากช่องค้นหา"</string>
- <string name="no_widgets_available" msgid="4337693382501046170">"วิดเจ็ตและทางลัดไม่พร้อมให้บริการ"</string>
- <string name="no_search_results" msgid="3787956167293097509">"ไม่พบวิดเจ็ตหรือทางลัด"</string>
- <string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"ส่วนตัว"</string>
- <string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"งาน"</string>
- <string name="widget_category_conversations" msgid="8894438636213590446">"การสนทนา"</string>
- <string name="widget_education_header" msgid="4874760613775913787">"เข้าถึงข้อมูลที่เป็นประโยชน์ได้ที่ปลายนิ้ว"</string>
- <string name="widget_education_content" msgid="745542879510751525">"หากต้องการรับข้อมูลโดยไม่เปิดแอป ให้เพิ่มวิดเจ็ตลงในหน้าจอหลัก"</string>
- <string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"แตะเพื่อเปลี่ยนการตั้งค่าวิดเจ็ต"</string>
- <string name="widget_education_close_button" msgid="8676165703104836580">"รับทราบ"</string>
- <string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"เปลี่ยนการตั้งค่าวิดเจ็ต"</string>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"แตะค้างไว้เพื่อวางด้วยตัวเอง"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"เพิ่มโดยอัตโนมัติ"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"ค้นหาแอป"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"กำลังโหลดแอป…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"ไม่พบแอปที่ตรงกับ \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
<string name="all_apps_search_market_message" msgid="1366263386197059176">"ค้นหาแอปเพิ่มเติม"</string>
<string name="label_application" msgid="8531721983832654978">"แอป"</string>
- <string name="all_apps_label" msgid="5015784846527570951">"แอปทั้งหมด"</string>
<string name="notifications_header" msgid="1404149926117359025">"การแจ้งเตือน"</string>
- <string name="long_press_shortcut_to_add" msgid="5405328730817637737">"แตะค้างไว้เพื่อย้ายทางลัด"</string>
- <string name="long_accessible_way_to_add_shortcut" msgid="2199537273817090740">"แตะสองครั้งค้างไว้เพื่อย้ายทางลัดหรือใช้การดำเนินการที่กำหนดเอง"</string>
- <string name="out_of_space" msgid="6692471482459245734">"ไม่มีที่ว่างในหน้าจอหลักนี้"</string>
+ <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"แตะค้างไว้เพื่อเลือกทางลัด"</string>
+ <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"แตะสองครั้งค้างไว้เพื่อเลือกทางลัดหรือใช้การกระทำที่กำหนดเอง"</string>
+ <string name="out_of_space" msgid="4691004494942118364">"ไม่มีที่ว่างในหน้าจอหลักนี้"</string>
<string name="hotseat_out_of_space" msgid="7448809638125333693">"ไม่มีพื้นที่เหลือในถาดรายการโปรด"</string>
<string name="all_apps_button_label" msgid="8130441508702294465">"รายชื่อแอป"</string>
- <string name="all_apps_search_results" msgid="5889367432531296759">"ผลการค้นหา"</string>
<string name="all_apps_button_personal_label" msgid="1315764287305224468">"รายการแอปส่วนตัว"</string>
<string name="all_apps_button_work_label" msgid="7270707118948892488">"รายการแอปสำหรับทำงาน"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"หน้าแรก"</string>
<string name="remove_drop_target_label" msgid="7812859488053230776">"นำออก"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"ถอนการติดตั้ง"</string>
<string name="app_info_drop_target_label" msgid="692894985365717661">"ข้อมูลแอป"</string>
<string name="install_drop_target_label" msgid="2539096853673231757">"ติดตั้ง"</string>
- <string name="dismiss_prediction_label" msgid="3357562989568808658">"ไม่ต้องแนะนำแอป"</string>
- <string name="pin_prediction" msgid="4196423321649756498">"ปักหมุดแอปที่คาดการณ์ไว้"</string>
<string name="permlab_install_shortcut" msgid="5632423390354674437">"ติดตั้งทางลัด"</string>
<string name="permdesc_install_shortcut" msgid="923466509822011139">"อนุญาตให้แอปเพิ่มทางลัดโดยไม่ต้องให้ผู้ใช้จัดการ"</string>
<string name="permlab_read_settings" msgid="1941457408239617576">"อ่านการตั้งค่าและทางลัดหน้าแรกแล้ว"</string>
@@ -84,13 +59,15 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"เขียนการตั้งค่าและทางลัดหน้าแรกแล้ว"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"อนุญาตให้แอปเปลี่ยนการตั้งค่าและทางลัดในหน้าแรก"</string>
<string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> ไม่ได้รับอนุญาตให้โทรออก"</string>
- <string name="gadget_error_text" msgid="740356548025791839">"โหลดวิดเจ็ตไม่ได้"</string>
- <string name="gadget_setup_text" msgid="8348374825537681407">"การตั้งค่าวิดเจ็ต"</string>
- <string name="gadget_complete_setup_text" msgid="309040266978007925">"แตะเพื่อสิ้นสุดการตั้งค่า"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"มีปัญหาขณะโหลดวิดเจ็ต"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"ตั้งค่า"</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"นี่เป็นแอประบบและไม่สามารถถอนการติดตั้งได้"</string>
- <string name="folder_hint_text" msgid="5174843001373488816">"แก้ไขชื่อ"</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"โฟลเดอร์ที่ไม่มีชื่อ"</string>
<string name="disabled_app_label" msgid="6673129024321402780">"ปิดใช้ <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
- <string name="dotted_app_label" msgid="1704091277755818896">"{count,plural,offset:1 =1{{app_name} มีการแจ้งเตือน # รายการ}other{{app_name} มีการแจ้งเตือน # รายการ}}"</string>
+ <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+ <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g> มีการแจ้งเตือน <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> รายการ</item>
+ <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g> มีการแจ้งเตือน <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> รายการ</item>
+ </plurals>
<string name="default_scroll_format" msgid="7475544710230993317">"หน้า %1$d จาก %2$d"</string>
<string name="workspace_scroll_format" msgid="8458889198184077399">"หน้าจอหลัก %1$d จาก %2$d"</string>
<string name="workspace_new_page" msgid="257366611030256142">"หน้าใหม่ในหน้าจอหลัก"</string>
@@ -99,10 +76,10 @@
<string name="folder_tap_to_rename" msgid="4017685068016979677">"แตะเพื่อบันทึกการเปลี่ยนชื่อ"</string>
<string name="folder_closed" msgid="4100806530910930934">"โฟลเดอร์ปิดอยู่"</string>
<string name="folder_renamed" msgid="1794088362165669656">"เปลี่ยนชื่อโฟลเดอร์เป็น <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="folder_name_format_exact" msgid="8626242716117004803">"โฟลเดอร์: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> รายการ"</string>
- <string name="folder_name_format_overflow" msgid="4270108890534995199">"โฟลเดอร์: <xliff:g id="NAME">%1$s</xliff:g>, อย่างน้อย <xliff:g id="SIZE">%2$d</xliff:g> รายการ"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"โฟลเดอร์: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"วิดเจ็ต"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"วอลเปเปอร์"</string>
- <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"วอลเปเปอร์และรูปแบบ"</string>
+ <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"รูปแบบและวอลเปเปอร์"</string>
<string name="settings_button_text" msgid="8873672322605444408">"การตั้งค่าหน้าแรก"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"ปิดใช้โดยผู้ดูแลระบบ"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"อนุญาตให้หมุนหน้าจอหลัก"</string>
@@ -111,25 +88,25 @@
<string name="notification_dots_desc_on" msgid="1679848116452218908">"เปิด"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"ปิด"</string>
<string name="title_missing_notification_access" msgid="7503287056163941064">"ต้องได้รับสิทธิ์เข้าถึงการแจ้งเตือน"</string>
- <string name="msg_missing_notification_access" msgid="281113995110910548">"เปิดการแจ้งเตือนแอปของ <xliff:g id="NAME">%1$s</xliff:g> เพื่อแสดงเครื่องหมายจุดแสดงการแจ้งเตือน"</string>
+ <string name="msg_missing_notification_access" msgid="281113995110910548">"เปิดการแจ้งเตือนแอปของ <xliff:g id="NAME">%1$s</xliff:g> เพื่อแสดงจุดแจ้งเตือน"</string>
<string name="title_change_settings" msgid="1376365968844349552">"เปลี่ยนการตั้งค่า"</string>
<string name="notification_dots_service_title" msgid="4284221181793592871">"แสดงเครื่องหมายจุดแสดงการแจ้งเตือน"</string>
- <string name="auto_add_shortcuts_label" msgid="3698776050751790653">"เพิ่มไอคอนแอปในหน้าจอหลัก"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"เพิ่มไอคอนในหน้าจอหลัก"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"สำหรับแอปใหม่"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"ไม่รู้จัก"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"ลบ"</string>
<string name="abandoned_search" msgid="891119232568284442">"ค้นหา"</string>
<string name="abandoned_promises_title" msgid="7096178467971716750">"ไม่ได้ติดตั้งแอปนี้"</string>
<string name="abandoned_promise_explanation" msgid="3990027586878167529">"ยังไม่ได้ติดตั้งแอปสำหรับไอคอนนี้ คุณสามารถนำไอคอนออก หรือค้นหาแอปดังกล่าวแล้วติดตั้งด้วยตนเอง"</string>
- <string name="app_installing_title" msgid="5864044122733792085">"กำลังติดตั้ง <xliff:g id="NAME">%1$s</xliff:g> เสร็จแล้ว <xliff:g id="PROGRESS">%2$s</xliff:g>"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"กำลังดาวน์โหลด <xliff:g id="NAME">%1$s</xliff:g> เสร็จแล้ว <xliff:g id="PROGRESS">%2$s</xliff:g>"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> กำลังรอติดตั้ง"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"วิดเจ็ตของ <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="widgets_list" msgid="796804551140113767">"รายการวิดเจ็ต"</string>
<string name="widgets_list_closed" msgid="6141506579418771922">"ปิดรายการวิดเจ็ตแล้ว"</string>
<string name="action_add_to_workspace" msgid="8902165848117513641">"เพิ่มลงในหน้าจอหลัก"</string>
<string name="action_move_here" msgid="2170188780612570250">"ย้ายรายการมาที่นี่"</string>
<string name="item_added_to_workspace" msgid="4211073925752213539">"เพิ่มรายการไปยังหน้าจอหลักแล้ว"</string>
- <string name="item_removed" msgid="851119963877842327">"นำรายการออกแล้ว"</string>
+ <string name="item_removed" msgid="851119963877842327">"นำออกรายการออกแล้ว"</string>
<string name="undo" msgid="4151576204245173321">"เลิกทำ"</string>
<string name="action_move" msgid="4339390619886385032">"ย้ายรายการ"</string>
<string name="move_to_empty_cell" msgid="2833711483015685619">"ย้ายไปที่แถว <xliff:g id="NUMBER_0">%1$s</xliff:g> คอลัมน์ <xliff:g id="NUMBER_1">%2$s</xliff:g>"</string>
@@ -151,20 +128,15 @@
<string name="action_deep_shortcut" msgid="2864038805849372848">"ทางลัด"</string>
<string name="shortcuts_menu_with_notifications_description" msgid="2676582286544232849">"ทางลัดและการแจ้งเตือน"</string>
<string name="action_dismiss_notification" msgid="5909461085055959187">"ปิด"</string>
- <string name="accessibility_close" msgid="2277148124685870734">"ปิด"</string>
<string name="notification_dismissed" msgid="6002233469409822874">"ปิดการแจ้งเตือนแล้ว"</string>
<string name="all_apps_personal_tab" msgid="4190252696685155002">"ส่วนตัว"</string>
<string name="all_apps_work_tab" msgid="4884822796154055118">"งาน"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"โปรไฟล์งาน"</string>
- <string name="work_profile_edu_work_apps" msgid="7895468576497746520">"แอปงานจะติดป้ายไว้และผู้ดูแลระบบไอทีจะมองเห็น"</string>
- <string name="work_profile_edu_accept" msgid="6069788082535149071">"รับทราบ"</string>
- <string name="work_apps_paused_title" msgid="3040901117349444598">"แอปงานปิดอยู่"</string>
- <string name="work_apps_paused_body" msgid="261634750995824906">"แอปงานจะส่งการแจ้งเตือน ใช้แบตเตอรี่ หรือเข้าถึงตำแหน่งของคุณไม่ได้"</string>
- <string name="work_apps_paused_content_description" msgid="5149623040804051095">"แอปงานปิดอยู่ แอปงานจะส่งการแจ้งเตือน ใช้แบตเตอรี่ หรือเข้าถึงตำแหน่งของคุณไม่ได้"</string>
- <string name="work_apps_paused_edu_banner" msgid="8872412121608402058">"แอปงานจะติดป้ายไว้และผู้ดูแลระบบไอทีจะมองเห็น"</string>
- <string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"รับทราบ"</string>
- <string name="work_apps_pause_btn_text" msgid="1921059713673767460">"ปิดแอปงาน"</string>
- <string name="work_apps_enable_btn_text" msgid="1156432622148413741">"เปิดแอปงาน"</string>
- <string name="developer_options_filter_hint" msgid="5896817443635989056">"ตัวกรอง"</string>
+ <string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"หาแอปงานที่นี่"</string>
+ <string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"แอปงานแต่ละแอปมีป้ายและได้รับการรักษาความปลอดภัยจากองค์กรของคุณ ย้ายแอปไปยังหน้าจอหลักเพื่อให้เข้าถึงได้ง่ายขึ้น"</string>
+ <string name="work_mode_on_label" msgid="4781128097185272916">"จัดการโดยองค์กร"</string>
+ <string name="work_mode_off_label" msgid="3194894777601421047">"ปิดการแจ้งเตือนและแอปอยู่"</string>
+ <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"ปิด"</string>
+ <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"ปิด"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"ไม่สำเร็จ: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
</resources>
diff --git a/res/values-tl/strings.xml b/res/values-tl/strings.xml
index 49465c5340..0df94c7104 100644
--- a/res/values-tl/strings.xml
+++ b/res/values-tl/strings.xml
@@ -20,63 +20,39 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="649227358658669779">"Launcher3"</string>
+ <string name="folder_name" msgid="7371454440695724752"></string>
<string name="work_folder_name" msgid="3753320833950115786">"Trabaho"</string>
<string name="activity_not_found" msgid="8071924732094499514">"Hindi naka-install ang app."</string>
<string name="activity_not_available" msgid="7456344436509528827">"Hindi available ang app"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"Naka-disable ang na-download na app sa Safe mode"</string>
<string name="safemode_widget_error" msgid="4863470563535682004">"Naka-disable ang mga widget sa Safe mode"</string>
<string name="shortcut_not_available" msgid="2536503539825726397">"Hindi available ang shortcut"</string>
- <string name="home_screen" msgid="5629429142036709174">"Home"</string>
- <string name="recent_task_option_split_screen" msgid="6690461455618725183">"Split screen"</string>
- <string name="split_screen_position_top" msgid="1504965011158689649">"Hatiin sa itaas"</string>
- <string name="split_screen_position_left" msgid="7537793098851830883">"Hatiin sa kaliwa"</string>
- <string name="split_screen_position_right" msgid="1569377524925193369">"Hatiin sa kanan"</string>
- <string name="split_app_info_accessibility" msgid="5475288491241414932">"Impormasyon ng app para sa %1$s"</string>
- <string name="long_press_widget_to_add" msgid="3587712543577675817">"Pindutin nang matagal para ilipat ang widget."</string>
- <string name="long_accessible_way_to_add" msgid="2733588281439571974">"I-double tap at pindutin nang matagal para ilipat ang widget o gumamit ng mga custom na pagkilos."</string>
+ <string name="home_screen" msgid="806512411299847073">"Home screen"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"Mga custom na pagkilos"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"Pindutin nang matagal upang kumuha ng widget."</string>
+ <string name="long_accessible_way_to_add" msgid="4289502106628154155">"I-double tap nang matagal upang pumili ng widget o gumamit ng mga custom na pagkilos."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d ang lapad at %2$d ang taas"</string>
- <string name="widget_preview_context_description" msgid="9045841361655787574">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g> widget"</string>
- <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Pindutin nang matagal ang widget para ilipat-lipat ito sa Home screen"</string>
- <string name="add_to_home_screen" msgid="8631549138215492708">"Idagdag sa Home screen"</string>
- <string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"Idinagdag sa home screen ang widget na <xliff:g id="WIDGET_NAME">%1$s</xliff:g>"</string>
- <string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# widget}one{# widget}other{# na widget}}"</string>
- <string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{# shortcut}one{# shortcut}other{# na shortcut}}"</string>
- <string name="widgets_and_shortcuts_count" msgid="7209136747878365116">"<xliff:g id="WIDGETS_COUNT">%1$s</xliff:g>, <xliff:g id="SHORTCUTS_COUNT">%2$s</xliff:g>"</string>
- <string name="widget_button_text" msgid="2880537293434387943">"Mga Widget"</string>
- <string name="widgets_full_sheet_search_bar_hint" msgid="8484659090860596457">"Maghanap"</string>
- <string name="widgets_full_sheet_cancel_button_description" msgid="5766167035728653605">"I-clear ang text sa box para sa paghahanap"</string>
- <string name="no_widgets_available" msgid="4337693382501046170">"Hindi available ang mga widget at shortcut"</string>
- <string name="no_search_results" msgid="3787956167293097509">"Walang nakitang widget o shortcut"</string>
- <string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Personal"</string>
- <string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Trabaho"</string>
- <string name="widget_category_conversations" msgid="8894438636213590446">"Mga Pag-uusap"</string>
- <string name="widget_education_header" msgid="4874760613775913787">"Abot-kamay na mahalagang impormasyon"</string>
- <string name="widget_education_content" msgid="745542879510751525">"Para makakuha ng impormasyon nang hindi nagbubukas ng mga app, puwede kang magdagdag ng mga widget sa iyong Home screen"</string>
- <string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"I-tap para baguhin ang mga setting ng widget"</string>
- <string name="widget_education_close_button" msgid="8676165703104836580">"OK"</string>
- <string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Baguhin ang mga setting ng widget"</string>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Pindutin nang matagal para manual na ilagay"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"Awtomatikong idagdag"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Maghanap ng mga app"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Naglo-load ng mga app…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"Walang nahanap na app na tumutugma sa \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
<string name="all_apps_search_market_message" msgid="1366263386197059176">"Maghanap ng higit pang mga app"</string>
<string name="label_application" msgid="8531721983832654978">"App"</string>
- <string name="all_apps_label" msgid="5015784846527570951">"Lahat ng app"</string>
<string name="notifications_header" msgid="1404149926117359025">"Mga Notification"</string>
- <string name="long_press_shortcut_to_add" msgid="5405328730817637737">"Pindutin nang matagal para ilipat ang shortcut."</string>
- <string name="long_accessible_way_to_add_shortcut" msgid="2199537273817090740">"I-double tap at pindutin nang matagal para ilipat ang shortcut o gumamit ng mga custom na pagkilos."</string>
- <string name="out_of_space" msgid="6692471482459245734">"Walang espasyo sa Home screen na ito"</string>
+ <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"Pindutin nang matagal para kumuha ng shortcut."</string>
+ <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"I-double tap nang matagal para kumuha ng shortcut o gumamit ng mga custom na pagkilos."</string>
+ <string name="out_of_space" msgid="4691004494942118364">"Wala nang lugar sa Home screen na ito."</string>
<string name="hotseat_out_of_space" msgid="7448809638125333693">"Wala nang lugar sa tray ng Mga Paborito"</string>
<string name="all_apps_button_label" msgid="8130441508702294465">"Listahan ng mga app"</string>
- <string name="all_apps_search_results" msgid="5889367432531296759">"Mga resulta ng paghahanap"</string>
<string name="all_apps_button_personal_label" msgid="1315764287305224468">"Listahan ng mga personal na app"</string>
<string name="all_apps_button_work_label" msgid="7270707118948892488">"Listahan ng mga app sa trabaho"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"Home"</string>
<string name="remove_drop_target_label" msgid="7812859488053230776">"Alisin"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"I-uninstall"</string>
<string name="app_info_drop_target_label" msgid="692894985365717661">"Impormasyon ng app"</string>
<string name="install_drop_target_label" msgid="2539096853673231757">"I-install"</string>
- <string name="dismiss_prediction_label" msgid="3357562989568808658">"Huwag magmungkahi ng app"</string>
- <string name="pin_prediction" msgid="4196423321649756498">"I-pin ang Hula"</string>
<string name="permlab_install_shortcut" msgid="5632423390354674437">"i-install ang mga shortcut"</string>
<string name="permdesc_install_shortcut" msgid="923466509822011139">"Pinapayagan ang isang app na magdagdag ng mga shortcut nang walang panghihimasok ng user."</string>
<string name="permlab_read_settings" msgid="1941457408239617576">"basahin ang mga setting at shortcut ng Home"</string>
@@ -84,13 +60,15 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"magsulat ng mga setting at shortcut ng Home"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"Pinapayagan ang app na baguhin ang mga setting at shortcut sa Home."</string>
<string name="msg_no_phone_permission" msgid="9208659281529857371">"Hindi pinahihintulutang tumawag ang <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
- <string name="gadget_error_text" msgid="740356548025791839">"Hindi ma-load ang widget"</string>
- <string name="gadget_setup_text" msgid="8348374825537681407">"Mga setting ng widget"</string>
- <string name="gadget_complete_setup_text" msgid="309040266978007925">"I-tap para tapusin ang pag-set up"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"Problema sa pag-load ng widget"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"I-setup"</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"Isa itong app ng system at hindi maaaring i-uninstall."</string>
- <string name="folder_hint_text" msgid="5174843001373488816">"I-edit ang Pangalan"</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"Walang Pangalang Folder"</string>
<string name="disabled_app_label" msgid="6673129024321402780">"Naka-disable ang <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
- <string name="dotted_app_label" msgid="1704091277755818896">"{count,plural,offset:1 =1{May # notification ang {app_name}}one{May # notification ang {app_name}}other{May # na notification ang {app_name}}}"</string>
+ <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+ <item quantity="one">May <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> (na) notification ang <xliff:g id="APP_NAME_2">%1$s</xliff:g></item>
+ <item quantity="other">May <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> (na) notification ang <xliff:g id="APP_NAME_2">%1$s</xliff:g></item>
+ </plurals>
<string name="default_scroll_format" msgid="7475544710230993317">"Pahina %1$d ng %2$d"</string>
<string name="workspace_scroll_format" msgid="8458889198184077399">"Home screen %1$d ng %2$d"</string>
<string name="workspace_new_page" msgid="257366611030256142">"Bagong page ng home screen"</string>
@@ -99,10 +77,10 @@
<string name="folder_tap_to_rename" msgid="4017685068016979677">"I-tap upang i-save ang bagong pangalan"</string>
<string name="folder_closed" msgid="4100806530910930934">"Nakasara ang folder"</string>
<string name="folder_renamed" msgid="1794088362165669656">"Pinalitan ang pangalan ng folder ng <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="folder_name_format_exact" msgid="8626242716117004803">"Folder: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> (na) item"</string>
- <string name="folder_name_format_overflow" msgid="4270108890534995199">"Folder: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> o higit pang item"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"Folder: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"Mga Widget"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Mga Wallpaper"</string>
- <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Wallpaper &amp; istilo"</string>
+ <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Mga istilo at wallpaper"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Mga setting ng Home"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Na-disable ng iyong admin"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Payagan ang pag-rotate ng Home screen"</string>
@@ -114,16 +92,16 @@
<string name="msg_missing_notification_access" msgid="281113995110910548">"Upang ipakita ang Mga Notification Dot, i-on ang mga notification ng app para sa <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="title_change_settings" msgid="1376365968844349552">"Baguhin ang mga setting"</string>
<string name="notification_dots_service_title" msgid="4284221181793592871">"Ipakita ang mga notification dot"</string>
- <string name="auto_add_shortcuts_label" msgid="3698776050751790653">"Magdagdag ng mga app icon sa Home screen"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Idagdag ang icon sa Home screen"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Para sa mga bagong app"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"Hindi kilala"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"Alisin"</string>
<string name="abandoned_search" msgid="891119232568284442">"Maghanap"</string>
<string name="abandoned_promises_title" msgid="7096178467971716750">"Hindi naka-install ang app na ito"</string>
<string name="abandoned_promise_explanation" msgid="3990027586878167529">"Hindi naka-install ang app para sa icon na ito. Puwede mo itong alisin, o maaari mong hanapin ang app at i-install ito nang manual."</string>
- <string name="app_installing_title" msgid="5864044122733792085">"Ini-install ang <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="PROGRESS">%2$s</xliff:g> kumpleto"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"Dina-download na ang <xliff:g id="NAME">%1$s</xliff:g>, tapos na ang <xliff:g id="PROGRESS">%2$s</xliff:g>"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"Hinihintay nang mag-install ang <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"Mga widget ng <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="widgets_list" msgid="796804551140113767">"Listahan ng mga widget"</string>
<string name="widgets_list_closed" msgid="6141506579418771922">"Nakasara ang listahan ng mga widget"</string>
<string name="action_add_to_workspace" msgid="8902165848117513641">"Idagdag sa Home screen"</string>
@@ -151,20 +129,15 @@
<string name="action_deep_shortcut" msgid="2864038805849372848">"Mga Shortcut"</string>
<string name="shortcuts_menu_with_notifications_description" msgid="2676582286544232849">"Mga shortcut at notification"</string>
<string name="action_dismiss_notification" msgid="5909461085055959187">"I-dismiss"</string>
- <string name="accessibility_close" msgid="2277148124685870734">"Isara"</string>
<string name="notification_dismissed" msgid="6002233469409822874">"Na-dismiss ang notification"</string>
<string name="all_apps_personal_tab" msgid="4190252696685155002">"Personal"</string>
<string name="all_apps_work_tab" msgid="4884822796154055118">"Trabaho"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"Profile sa trabaho"</string>
- <string name="work_profile_edu_work_apps" msgid="7895468576497746520">"May badge at nakikita ng iyong IT admin ang mga app para sa trabaho"</string>
- <string name="work_profile_edu_accept" msgid="6069788082535149071">"OK"</string>
- <string name="work_apps_paused_title" msgid="3040901117349444598">"Naka-pause ang mga app para sa trabaho"</string>
- <string name="work_apps_paused_body" msgid="261634750995824906">"Ang mga app mo para sa trabaho ay hindi makakapagpadala sa iyo ng mga notification, makakagamit ng baterya mo, o makaka-access ng iyong lokasyon"</string>
- <string name="work_apps_paused_content_description" msgid="5149623040804051095">"Naka-off ang mga app para sa trabaho. Ang mga app mo para sa trabaho ay hindi makakapagpadala sa iyo ng mga notification, makakagamit ng baterya mo, o makaka-access ng iyong lokasyon"</string>
- <string name="work_apps_paused_edu_banner" msgid="8872412121608402058">"May badge at nakikita ng iyong IT admin ang mga app para sa trabaho"</string>
- <string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"OK"</string>
- <string name="work_apps_pause_btn_text" msgid="1921059713673767460">"I-off ang mga app para sa trabaho"</string>
- <string name="work_apps_enable_btn_text" msgid="1156432622148413741">"I-on ang mga app para sa trabaho"</string>
- <string name="developer_options_filter_hint" msgid="5896817443635989056">"Filter"</string>
+ <string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"Maghanap ng mga app para sa trabaho rito"</string>
+ <string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"Ang bawat app para sa trabaho ay may badge at pinapanatiling ligtas ng iyong organisasyon. Ilipat ang mga app sa iyong Home screen para mas madaling ma-access."</string>
+ <string name="work_mode_on_label" msgid="4781128097185272916">"Pinamamahalaan ng iyong organisasyon"</string>
+ <string name="work_mode_off_label" msgid="3194894777601421047">"Naka-off ang mga notification at app"</string>
+ <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Isara"</string>
+ <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Nakasara"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Hindi nagawa: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
</resources>
diff --git a/res/values-tr/strings.xml b/res/values-tr/strings.xml
index bb0e1a8a51..56f8447bf1 100644
--- a/res/values-tr/strings.xml
+++ b/res/values-tr/strings.xml
@@ -20,63 +20,39 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="649227358658669779">"Launcher3"</string>
+ <string name="folder_name" msgid="7371454440695724752"></string>
<string name="work_folder_name" msgid="3753320833950115786">"İş"</string>
<string name="activity_not_found" msgid="8071924732094499514">"Uygulama yüklü değil."</string>
<string name="activity_not_available" msgid="7456344436509528827">"Uygulama kullanılamıyor"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"İndirilen uygulama Güvenli modda devre dışı bırakıldı"</string>
<string name="safemode_widget_error" msgid="4863470563535682004">"Güvenli modda widget\'lar devre dışı"</string>
<string name="shortcut_not_available" msgid="2536503539825726397">"Kısayol kullanılamıyor"</string>
- <string name="home_screen" msgid="5629429142036709174">"Ana ekran"</string>
- <string name="recent_task_option_split_screen" msgid="6690461455618725183">"Bölünmüş ekran"</string>
- <string name="split_screen_position_top" msgid="1504965011158689649">"Üst tarafta böl"</string>
- <string name="split_screen_position_left" msgid="7537793098851830883">"Sol tarafta böl"</string>
- <string name="split_screen_position_right" msgid="1569377524925193369">"Sağ tarafta böl"</string>
- <string name="split_app_info_accessibility" msgid="5475288491241414932">"%1$s uygulama bilgileri"</string>
- <string name="long_press_widget_to_add" msgid="3587712543577675817">"Widget\'ı taşımak için dokunup basılı tutun."</string>
- <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Widget\'ı taşımak veya özel işlemleri kullanmak için iki kez dokunup basılı tutun."</string>
+ <string name="home_screen" msgid="806512411299847073">"Ana ekran"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"Özel işlemler"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"Widget seçmek için dokunun ve basılı tutun."</string>
+ <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Bir widget\'ı seçmek veya özel işlemleri kullanmak için iki kez dokunun ve basılı tutun."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"genişlik: %1$d, yükseklik: %2$d"</string>
- <string name="widget_preview_context_description" msgid="9045841361655787574">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g> widget\'ı"</string>
- <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Ana ekranda taşımak için widget\'a dokunup basılı tutun"</string>
- <string name="add_to_home_screen" msgid="8631549138215492708">"Ana ekrana ekle"</string>
- <string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g> widget\'ı ana ekrana eklendi"</string>
- <string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# widget}other{# widget}}"</string>
- <string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{# kısayol}other{# kısayol}}"</string>
- <string name="widgets_and_shortcuts_count" msgid="7209136747878365116">"<xliff:g id="WIDGETS_COUNT">%1$s</xliff:g>, <xliff:g id="SHORTCUTS_COUNT">%2$s</xliff:g>"</string>
- <string name="widget_button_text" msgid="2880537293434387943">"Widget\'lar"</string>
- <string name="widgets_full_sheet_search_bar_hint" msgid="8484659090860596457">"Ara"</string>
- <string name="widgets_full_sheet_cancel_button_description" msgid="5766167035728653605">"Arama kutusundaki metni temizle"</string>
- <string name="no_widgets_available" msgid="4337693382501046170">"Widget\'lar ve kısayollar kullanılamıyor"</string>
- <string name="no_search_results" msgid="3787956167293097509">"Widget veya kısayol bulunamadı"</string>
- <string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Kişisel"</string>
- <string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"İş"</string>
- <string name="widget_category_conversations" msgid="8894438636213590446">"Görüşmeler"</string>
- <string name="widget_education_header" msgid="4874760613775913787">"Faydalı bilgiler parmaklarınızın ucunda"</string>
- <string name="widget_education_content" msgid="745542879510751525">"Uygulamaları açmadan bilgi almak için Ana ekranınıza widget\'lar ekleyebilirsiniz"</string>
- <string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Widget ayarlarını değiştirmek için dokunun"</string>
- <string name="widget_education_close_button" msgid="8676165703104836580">"Anladım"</string>
- <string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Widget ayarlarını değiştir"</string>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Manuel olarak yerleştirmek için dokunun ve basılı tutun"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"Otomatik olarak ekle"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Uygulamalarda ara"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Uygulamalar yükleniyor…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" ile eşleşen uygulama bulunamadı"</string>
<string name="all_apps_search_market_message" msgid="1366263386197059176">"Başka uygulamalar ara"</string>
<string name="label_application" msgid="8531721983832654978">"Uygulama"</string>
- <string name="all_apps_label" msgid="5015784846527570951">"Tüm uygulamalar"</string>
<string name="notifications_header" msgid="1404149926117359025">"Bildirimler"</string>
- <string name="long_press_shortcut_to_add" msgid="5405328730817637737">"Kısayolu taşımak için dokunup basılı tutun."</string>
- <string name="long_accessible_way_to_add_shortcut" msgid="2199537273817090740">"Kısayolu taşımak veya özel işlemleri kullanmak için iki kez dokunup basılı tutun."</string>
- <string name="out_of_space" msgid="6692471482459245734">"Bu Ana ekranda yer yok"</string>
+ <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"Kısayol seçmek için dokunun ve basılı tutun."</string>
+ <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"Bir kısayolu seçmek veya özel işlemleri kullanmak için iki kez dokunun ve basılı tutun."</string>
+ <string name="out_of_space" msgid="4691004494942118364">"Bu Ana ekranda yer kalmadı."</string>
<string name="hotseat_out_of_space" msgid="7448809638125333693">"Favoriler tepsisinde başka yer kalmadı"</string>
<string name="all_apps_button_label" msgid="8130441508702294465">"Uygulamalar listesi"</string>
- <string name="all_apps_search_results" msgid="5889367432531296759">"Arama sonuçları"</string>
<string name="all_apps_button_personal_label" msgid="1315764287305224468">"Kişisel uygulamalar listesi"</string>
<string name="all_apps_button_work_label" msgid="7270707118948892488">"İş uygulamaları listesi"</string>
- <string name="remove_drop_target_label" msgid="7812859488053230776">"Sil"</string>
- <string name="uninstall_drop_target_label" msgid="4722034217958379417">"Kaldır"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"Ana ekran"</string>
+ <string name="remove_drop_target_label" msgid="7812859488053230776">"Kaldır"</string>
+ <string name="uninstall_drop_target_label" msgid="4722034217958379417">"Yüklemeyi kaldır"</string>
<string name="app_info_drop_target_label" msgid="692894985365717661">"Uygulama bilgileri"</string>
<string name="install_drop_target_label" msgid="2539096853673231757">"Yükle"</string>
- <string name="dismiss_prediction_label" msgid="3357562989568808658">"Uygulama önerme"</string>
- <string name="pin_prediction" msgid="4196423321649756498">"Tahmini Sabitle"</string>
<string name="permlab_install_shortcut" msgid="5632423390354674437">"kısayolları yükle"</string>
<string name="permdesc_install_shortcut" msgid="923466509822011139">"Uygulamaya, kullanıcı müdahalesi olmadan kısayol ekleme izni verir."</string>
<string name="permlab_read_settings" msgid="1941457408239617576">"Ana ekran ayarlarını ve kısayollarını oku"</string>
@@ -84,13 +60,15 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"Ana ekran ayarlarını ve kısayollarını yaz"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"Uygulamaya, Ana ekrandaki ayarları ve kısayolları değiştirme izni verir."</string>
<string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> uygulamasının telefon etmesine izin verilmiyor"</string>
- <string name="gadget_error_text" msgid="740356548025791839">"Widget yüklenemiyor"</string>
- <string name="gadget_setup_text" msgid="8348374825537681407">"Widget ayarları"</string>
- <string name="gadget_complete_setup_text" msgid="309040266978007925">"Kurulumu tamamlamak için dokunun"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"Widget yüklenirken sorun oluştu"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"Kurulum"</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"Bu bir sistem uygulamasıdır ve yüklemesi kaldırılamaz."</string>
- <string name="folder_hint_text" msgid="5174843001373488816">"Adı Düzenle"</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"Adsız Klasör"</string>
<string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> devre dışı"</string>
- <string name="dotted_app_label" msgid="1704091277755818896">"{count,plural,offset:1 =1{{app_name} uygulamasının # bildirimi var}other{{app_name} uygulamasının # bildirimi var}}"</string>
+ <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+ <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g> uygulamasının <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> bildirimi var</item>
+ <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g> uygulamasının <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> bildirimi var</item>
+ </plurals>
<string name="default_scroll_format" msgid="7475544710230993317">"Sayfa %1$d / %2$d"</string>
<string name="workspace_scroll_format" msgid="8458889198184077399">"Ana ekran %1$d / %2$d"</string>
<string name="workspace_new_page" msgid="257366611030256142">"Yeni ana ekran sayfası"</string>
@@ -99,10 +77,10 @@
<string name="folder_tap_to_rename" msgid="4017685068016979677">"Yeni adın kaydedilmesi için dokunun"</string>
<string name="folder_closed" msgid="4100806530910930934">"Klasör kapatıldı"</string>
<string name="folder_renamed" msgid="1794088362165669656">"Klasörün adı <xliff:g id="NAME">%1$s</xliff:g> olarak değiştirildi"</string>
- <string name="folder_name_format_exact" msgid="8626242716117004803">"Klasör: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> öğe"</string>
- <string name="folder_name_format_overflow" msgid="4270108890534995199">"Klasör: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> veya daha fazla öğe"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"Klasör: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"Widget\'lar"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Duvar Kağıtları"</string>
- <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Duvar kağıdı ve stil"</string>
+ <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Stiller ve duvar kağıtları"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Ana ekran ayarları"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Yöneticiniz tarafından devre dışı bırakıldı"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Ana ekranı döndürmeye izin ver"</string>
@@ -114,16 +92,16 @@
<string name="msg_missing_notification_access" msgid="281113995110910548">"Bildirim Noktaları\'nı göstermek için <xliff:g id="NAME">%1$s</xliff:g> uygulamasının bildirimlerini açın"</string>
<string name="title_change_settings" msgid="1376365968844349552">"Ayarları değiştir"</string>
<string name="notification_dots_service_title" msgid="4284221181793592871">"Bildirim noktalarını göster"</string>
- <string name="auto_add_shortcuts_label" msgid="3698776050751790653">"Uygulama simgelerini Ana ekrana ekle"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Ana ekrana simge ekle"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Yeni uygulamalar için"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"Bilinmiyor"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"Kaldır"</string>
<string name="abandoned_search" msgid="891119232568284442">"Ara"</string>
<string name="abandoned_promises_title" msgid="7096178467971716750">"Bu uygulama yüklü değil"</string>
<string name="abandoned_promise_explanation" msgid="3990027586878167529">"Bu simgenin uygulaması yüklü değil. Uygulamayı kaldırabilir veya arayıp manuel olarak yükleyebilirsiniz."</string>
- <string name="app_installing_title" msgid="5864044122733792085">"<xliff:g id="NAME">%1$s</xliff:g> yükleniyor, <xliff:g id="PROGRESS">%2$s</xliff:g> tamamlandı"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> indiriliyor, <xliff:g id="PROGRESS">%2$s</xliff:g> tamamlandı"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> uygulaması yüklenmek için bekliyor"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"<xliff:g id="NAME">%1$s</xliff:g> widget\'ları"</string>
<string name="widgets_list" msgid="796804551140113767">"Widget listesi"</string>
<string name="widgets_list_closed" msgid="6141506579418771922">"Widget listesi kapalı"</string>
<string name="action_add_to_workspace" msgid="8902165848117513641">"Ana ekrana ekle"</string>
@@ -151,20 +129,15 @@
<string name="action_deep_shortcut" msgid="2864038805849372848">"Kısayollar"</string>
<string name="shortcuts_menu_with_notifications_description" msgid="2676582286544232849">"Kısayollar ve bildirimler"</string>
<string name="action_dismiss_notification" msgid="5909461085055959187">"Kapat"</string>
- <string name="accessibility_close" msgid="2277148124685870734">"Kapat"</string>
<string name="notification_dismissed" msgid="6002233469409822874">"Bildirim kapatıldı"</string>
<string name="all_apps_personal_tab" msgid="4190252696685155002">"Kişisel"</string>
<string name="all_apps_work_tab" msgid="4884822796154055118">"İş"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"İş profili"</string>
- <string name="work_profile_edu_work_apps" msgid="7895468576497746520">"İş uygulamaları rozetle işaretlenmiş olup BT yöneticisi tarafından görülebilir"</string>
- <string name="work_profile_edu_accept" msgid="6069788082535149071">"Anladım"</string>
- <string name="work_apps_paused_title" msgid="3040901117349444598">"İş uygulamaları duraklatıldı"</string>
- <string name="work_apps_paused_body" msgid="261634750995824906">"İş uygulamaları size bildirim gönderemez, pilinizi kullanamaz veya konum bilginize erişemez"</string>
- <string name="work_apps_paused_content_description" msgid="5149623040804051095">"İş uygulamaları kapalı. İş uygulamalarınız size bildirim gönderemez, pilinizi kullanamaz veya konum bilginize erişemez"</string>
- <string name="work_apps_paused_edu_banner" msgid="8872412121608402058">"İş uygulamaları rozetle işaretlenmiş olup BT yöneticisi tarafından görülebilir"</string>
- <string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"Anladım"</string>
- <string name="work_apps_pause_btn_text" msgid="1921059713673767460">"İş uygulamalarını kapat"</string>
- <string name="work_apps_enable_btn_text" msgid="1156432622148413741">"İş uygulamalarını aç"</string>
- <string name="developer_options_filter_hint" msgid="5896817443635989056">"Filtre"</string>
+ <string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"İş uygulamalarını burada bulabilirsiniz"</string>
+ <string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"Her iş uygulamasında, uygulama güvenliğinin kuruluşunuz tarafından sağlandığını gösteren bir rozet bulunur. Daha kolay erişim için uygulamaları Ana ekranınıza taşıyın."</string>
+ <string name="work_mode_on_label" msgid="4781128097185272916">"Kuruluşunuz tarafından yönetiliyor"</string>
+ <string name="work_mode_off_label" msgid="3194894777601421047">"Bildirimler ve uygulamalar kapalı"</string>
+ <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Kapat"</string>
+ <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Kapalı"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Başarısız: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
</resources>
diff --git a/res/values-uk/strings.xml b/res/values-uk/strings.xml
index 998ad84545..13ba701815 100644
--- a/res/values-uk/strings.xml
+++ b/res/values-uk/strings.xml
@@ -20,63 +20,39 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="649227358658669779">"Launcher3"</string>
+ <string name="folder_name" msgid="7371454440695724752"></string>
<string name="work_folder_name" msgid="3753320833950115786">"Робоча папка"</string>
<string name="activity_not_found" msgid="8071924732094499514">"Додаток видалено."</string>
<string name="activity_not_available" msgid="7456344436509528827">"Додаток недоступний"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"Завантажений додаток вимкнено в безпечному режимі"</string>
<string name="safemode_widget_error" msgid="4863470563535682004">"У безпечному режимі віджети вимкнено"</string>
<string name="shortcut_not_available" msgid="2536503539825726397">"Ярлик недоступний"</string>
- <string name="home_screen" msgid="5629429142036709174">"Головний екран"</string>
- <string name="recent_task_option_split_screen" msgid="6690461455618725183">"Розділити екран"</string>
- <string name="split_screen_position_top" msgid="1504965011158689649">"Розділити вгорі"</string>
- <string name="split_screen_position_left" msgid="7537793098851830883">"Розділити зліва"</string>
- <string name="split_screen_position_right" msgid="1569377524925193369">"Розділити справа"</string>
- <string name="split_app_info_accessibility" msgid="5475288491241414932">"Інформація про додаток для %1$s"</string>
- <string name="long_press_widget_to_add" msgid="3587712543577675817">"Натисніть і втримуйте, щоб перемістити віджет."</string>
- <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Двічі натисніть і втримуйте віджет, щоб перемістити його або виконати інші дії."</string>
+ <string name="home_screen" msgid="806512411299847073">"Головний екран"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"Спеціальні дії"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"Натисніть і утримуйте, щоб вибрати віджет."</string>
+ <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Двічі натисніть і утримуйте, щоб вибрати віджет, або виконайте іншу дію."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"Ширина – %1$d, висота – %2$d"</string>
- <string name="widget_preview_context_description" msgid="9045841361655787574">"Віджет <xliff:g id="WIDGET_NAME">%1$s</xliff:g>"</string>
- <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Натисніть і втримуйте віджет, щоб перемістити його в потрібне місце на головному екрані"</string>
- <string name="add_to_home_screen" msgid="8631549138215492708">"Додати на головний екран"</string>
- <string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"Віджет <xliff:g id="WIDGET_NAME">%1$s</xliff:g> додано на головний екран"</string>
- <string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# віджет}one{# віджет}few{# віджети}many{# віджетів}other{# віджета}}"</string>
- <string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{# ярлик}one{# ярлик}few{# ярлики}many{# ярликів}other{# ярлика}}"</string>
- <string name="widgets_and_shortcuts_count" msgid="7209136747878365116">"<xliff:g id="WIDGETS_COUNT">%1$s</xliff:g>, <xliff:g id="SHORTCUTS_COUNT">%2$s</xliff:g>"</string>
- <string name="widget_button_text" msgid="2880537293434387943">"Віджети"</string>
- <string name="widgets_full_sheet_search_bar_hint" msgid="8484659090860596457">"Пошук"</string>
- <string name="widgets_full_sheet_cancel_button_description" msgid="5766167035728653605">"Очистити текст у полі пошуку"</string>
- <string name="no_widgets_available" msgid="4337693382501046170">"Віджети та ярлики недоступні"</string>
- <string name="no_search_results" msgid="3787956167293097509">"Не знайдено віджетів чи ярликів"</string>
- <string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Особисті"</string>
- <string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Робочі"</string>
- <string name="widget_category_conversations" msgid="8894438636213590446">"Розмови"</string>
- <string name="widget_education_header" msgid="4874760613775913787">"Корисна інформація завжди під рукою"</string>
- <string name="widget_education_content" msgid="745542879510751525">"Щоб отримувати інформацію, не відкриваючи додатки, ви можете додати на головний екран віджети"</string>
- <string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Натисніть, щоб змінити налаштування віджета"</string>
- <string name="widget_education_close_button" msgid="8676165703104836580">"OK"</string>
- <string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Змінити налаштування віджета"</string>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Натисніть і утримуйте, щоб додати вручну"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"Додати автоматично"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Пошук додатків"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Завантаження додатків…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"Немає додатків для запиту \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
<string name="all_apps_search_market_message" msgid="1366263386197059176">"Шукати ще додатки"</string>
<string name="label_application" msgid="8531721983832654978">"Додаток"</string>
- <string name="all_apps_label" msgid="5015784846527570951">"Усі додатки"</string>
<string name="notifications_header" msgid="1404149926117359025">"Сповіщення"</string>
- <string name="long_press_shortcut_to_add" msgid="5405328730817637737">"Натисніть і втримуйте, щоб перемістити ярлик."</string>
- <string name="long_accessible_way_to_add_shortcut" msgid="2199537273817090740">"Двічі натисніть і втримуйте ярлик, щоб перемістити його або виконати інші дії."</string>
- <string name="out_of_space" msgid="6692471482459245734">"На головному екрані немає місця"</string>
+ <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"Натисніть і втримуйте, щоб вибрати ярлик."</string>
+ <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"Двічі натисніть і втримуйте, щоб вибрати ярлик, або виконайте іншу дію."</string>
+ <string name="out_of_space" msgid="4691004494942118364">"На цьому головному екрані більше немає місця."</string>
<string name="hotseat_out_of_space" msgid="7448809638125333693">"В області \"Вибране\" немає місця"</string>
<string name="all_apps_button_label" msgid="8130441508702294465">"Список додатків"</string>
- <string name="all_apps_search_results" msgid="5889367432531296759">"Результати пошуку"</string>
<string name="all_apps_button_personal_label" msgid="1315764287305224468">"Список особистих додатків"</string>
<string name="all_apps_button_work_label" msgid="7270707118948892488">"Список робочих додатків"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"Головний екран"</string>
<string name="remove_drop_target_label" msgid="7812859488053230776">"Видалити"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"Видалити додаток"</string>
<string name="app_info_drop_target_label" msgid="692894985365717661">"Про додаток"</string>
<string name="install_drop_target_label" msgid="2539096853673231757">"Установити"</string>
- <string name="dismiss_prediction_label" msgid="3357562989568808658">"Не пропонувати додаток"</string>
- <string name="pin_prediction" msgid="4196423321649756498">"Закріпити передбачений додаток"</string>
<string name="permlab_install_shortcut" msgid="5632423390354674437">"створення ярликів"</string>
<string name="permdesc_install_shortcut" msgid="923466509822011139">"Дозволяє програмі самостійно додавати ярлики."</string>
<string name="permlab_read_settings" msgid="1941457408239617576">"читати налаштування та ярлики головного екрана"</string>
@@ -84,13 +60,17 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"записувати налаштування та ярлики головного екрана"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"Дозволяє програмі змінювати налаштування та ярлики на головному екрані."</string>
<string name="msg_no_phone_permission" msgid="9208659281529857371">"Додаток <xliff:g id="APP_NAME">%1$s</xliff:g> не має дозволу телефонувати"</string>
- <string name="gadget_error_text" msgid="740356548025791839">"Не вдається завантажити віджет"</string>
- <string name="gadget_setup_text" msgid="8348374825537681407">"Налаштування віджета"</string>
- <string name="gadget_complete_setup_text" msgid="309040266978007925">"Торкніться, щоб завершити налаштування"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"Проблема із завантаженням віджета"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"Налаштування"</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"Це системна програма, її неможливо видалити."</string>
- <string name="folder_hint_text" msgid="5174843001373488816">"Редагувати назву"</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"Папка без назви"</string>
<string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> вимкнено"</string>
- <string name="dotted_app_label" msgid="1704091277755818896">"{count,plural,offset:1 =1{Додаток {app_name} має # сповіщення}one{Додаток {app_name} має # сповіщення}few{Додаток {app_name} має # сповіщення}many{Додаток {app_name} має # сповіщень}other{Додаток {app_name} має # сповіщення}}"</string>
+ <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+ <item quantity="one">Додаток <xliff:g id="APP_NAME_2">%1$s</xliff:g> має <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> сповіщення</item>
+ <item quantity="few">Додаток <xliff:g id="APP_NAME_2">%1$s</xliff:g> має <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> сповіщення</item>
+ <item quantity="many">Додаток <xliff:g id="APP_NAME_2">%1$s</xliff:g> має <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> сповіщень</item>
+ <item quantity="other">Додаток <xliff:g id="APP_NAME_2">%1$s</xliff:g> має <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> сповіщення</item>
+ </plurals>
<string name="default_scroll_format" msgid="7475544710230993317">"Сторінка %1$d з %2$d"</string>
<string name="workspace_scroll_format" msgid="8458889198184077399">"Головний екран %1$d з %2$d"</string>
<string name="workspace_new_page" msgid="257366611030256142">"Нова сторінка головного екрана"</string>
@@ -99,10 +79,10 @@
<string name="folder_tap_to_rename" msgid="4017685068016979677">"Торкніться, щоб зберегти зміни"</string>
<string name="folder_closed" msgid="4100806530910930934">"Папку закрито"</string>
<string name="folder_renamed" msgid="1794088362165669656">"Папку перейменовано на <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="folder_name_format_exact" msgid="8626242716117004803">"Папка \"<xliff:g id="NAME">%1$s</xliff:g>\", елементів: <xliff:g id="SIZE">%2$d</xliff:g>"</string>
- <string name="folder_name_format_overflow" msgid="4270108890534995199">"Папка \"<xliff:g id="NAME">%1$s</xliff:g>\", елементів: <xliff:g id="SIZE">%2$d</xliff:g> або більше"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"Папка <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"Віджети"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Фонові малюнки"</string>
- <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Оформлення та стиль"</string>
+ <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Стиль і фон"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Налаштування головного екрана"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Вимкнув адміністратор"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Дозволити обертання головного екрана"</string>
@@ -114,16 +94,16 @@
<string name="msg_missing_notification_access" msgid="281113995110910548">"Щоб показувати значки сповіщень, увімкніть сповіщення в додатку <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="title_change_settings" msgid="1376365968844349552">"Змінити налаштування"</string>
<string name="notification_dots_service_title" msgid="4284221181793592871">"Показувати значки сповіщень"</string>
- <string name="auto_add_shortcuts_label" msgid="3698776050751790653">"Додавати значки додатків на головний екран"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Додавати значок на головний екран"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Для нових додатків"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"Невідомо"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"Прибрати"</string>
<string name="abandoned_search" msgid="891119232568284442">"Шукати"</string>
<string name="abandoned_promises_title" msgid="7096178467971716750">"Цей додаток не встановлено"</string>
<string name="abandoned_promise_explanation" msgid="3990027586878167529">"Додаток для цього значка не встановлено. Можна видалити значок або знайти додаток і встановити його вручну."</string>
- <string name="app_installing_title" msgid="5864044122733792085">"<xliff:g id="NAME">%1$s</xliff:g> встановлюється, виконано <xliff:g id="PROGRESS">%2$s</xliff:g>"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> завантажується, <xliff:g id="PROGRESS">%2$s</xliff:g>"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> очікує на завантаження"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"Віджети додатка <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="widgets_list" msgid="796804551140113767">"Список віджетів"</string>
<string name="widgets_list_closed" msgid="6141506579418771922">"Список віджектів закрито"</string>
<string name="action_add_to_workspace" msgid="8902165848117513641">"Додати на головний екран"</string>
@@ -151,20 +131,15 @@
<string name="action_deep_shortcut" msgid="2864038805849372848">"Ярлики"</string>
<string name="shortcuts_menu_with_notifications_description" msgid="2676582286544232849">"Ярлики та сповіщення"</string>
<string name="action_dismiss_notification" msgid="5909461085055959187">"Закрити"</string>
- <string name="accessibility_close" msgid="2277148124685870734">"Закрити"</string>
<string name="notification_dismissed" msgid="6002233469409822874">"Сповіщення закрито"</string>
<string name="all_apps_personal_tab" msgid="4190252696685155002">"Особисті додатки"</string>
<string name="all_apps_work_tab" msgid="4884822796154055118">"Робочі додатки"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"Робочий профіль"</string>
- <string name="work_profile_edu_work_apps" msgid="7895468576497746520">"Робочі додатки мають спеціальну позначку. Їх бачить системний адміністратор."</string>
- <string name="work_profile_edu_accept" msgid="6069788082535149071">"OK"</string>
- <string name="work_apps_paused_title" msgid="3040901117349444598">"Робочі додатки призупинено"</string>
- <string name="work_apps_paused_body" msgid="261634750995824906">"Ваші робочі додатки не можуть надсилати сповіщення, використовувати заряд акумулятора й отримувати доступ до геоданих"</string>
- <string name="work_apps_paused_content_description" msgid="5149623040804051095">"Робочі додатки вимкнено. Вони не можуть надсилати сповіщення, використовувати заряд акумулятора й отримувати доступ до геоданих."</string>
- <string name="work_apps_paused_edu_banner" msgid="8872412121608402058">"Робочі додатки мають спеціальну позначку. Їх бачить системноий адміністратор."</string>
- <string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"Зрозуміло"</string>
- <string name="work_apps_pause_btn_text" msgid="1921059713673767460">"Вимкнути робочі додатки"</string>
- <string name="work_apps_enable_btn_text" msgid="1156432622148413741">"Увімкнути робочі додатки"</string>
- <string name="developer_options_filter_hint" msgid="5896817443635989056">"Фільтр"</string>
+ <string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"Робочі додатки містяться тут"</string>
+ <string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"Кожний робочий додаток має значок і перебуває під захистом організації. Перенесіть додатки на головний екран, щоб швидко запускати їх."</string>
+ <string name="work_mode_on_label" msgid="4781128097185272916">"Профілем керує ваша організація"</string>
+ <string name="work_mode_off_label" msgid="3194894777601421047">"Сповіщення та додатки вимкнено"</string>
+ <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Закрити"</string>
+ <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Закрито"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Не вдалося <xliff:g id="WHAT">%1$s</xliff:g>"</string>
</resources>
diff --git a/res/values-ur/strings.xml b/res/values-ur/strings.xml
index 1b4a3d1a4d..4f776701e5 100644
--- a/res/values-ur/strings.xml
+++ b/res/values-ur/strings.xml
@@ -20,63 +20,39 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="649227358658669779">"Launcher3"</string>
+ <string name="folder_name" msgid="7371454440695724752"></string>
<string name="work_folder_name" msgid="3753320833950115786">"دفتری"</string>
<string name="activity_not_found" msgid="8071924732094499514">"ایپ انسٹال نہیں ہے۔"</string>
<string name="activity_not_available" msgid="7456344436509528827">"ایپ دستیاب نہیں ہے"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"ڈاؤن لوڈ کردہ ایپ کو محفوظ وضع میں غیر فعال کر دیا گیا"</string>
<string name="safemode_widget_error" msgid="4863470563535682004">"ویجیٹس کو محفوظ وضع میں غیر فعال کر دیا گیا"</string>
<string name="shortcut_not_available" msgid="2536503539825726397">"شارٹ کٹ دستیاب نہیں ہے"</string>
- <string name="home_screen" msgid="5629429142036709174">"ہوم"</string>
- <string name="recent_task_option_split_screen" msgid="6690461455618725183">"اسپلٹ اسکرین"</string>
- <string name="split_screen_position_top" msgid="1504965011158689649">"اوپر کی طرف تقسیم کریں"</string>
- <string name="split_screen_position_left" msgid="7537793098851830883">"بائیں طرف تقسیم کریں"</string>
- <string name="split_screen_position_right" msgid="1569377524925193369">"دائیں طرف تقسیم کریں"</string>
- <string name="split_app_info_accessibility" msgid="5475288491241414932">"‏%1$s کے لیے ایپ کی معلومات"</string>
- <string name="long_press_widget_to_add" msgid="3587712543577675817">"ویجیٹ منتقل کرنے کے لیے ٹچ کریں اور پکڑ کر رکھیں۔"</string>
- <string name="long_accessible_way_to_add" msgid="2733588281439571974">"ویجیٹ کو منتقل کرنے یا حسب ضرورت کارروائیاں استعمال کرنے کے لیے دوبار تھپتھپائیں اور پکڑ کر رکھیں۔"</string>
+ <string name="home_screen" msgid="806512411299847073">"ہوم اسکرین"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"حسب ضرورت کارروائیاں"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"کوئی ویجیٹ منتخب کرنے کیلئے ٹچ کریں اور پکڑے رہیں۔"</string>
+ <string name="long_accessible_way_to_add" msgid="4289502106628154155">"کوئی ویجٹ منتخب کرنے یا حسب ضرورت کاروائیاں استعمال کرنے کیلئے دو بار تھپتھپائیں اور پکڑے رکھیں۔"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"‏%1$d چوڑا اور ‎%2$d اونچا"</string>
- <string name="widget_preview_context_description" msgid="9045841361655787574">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g> ویجیٹ"</string>
- <string name="add_item_request_drag_hint" msgid="5653291305078645405">"ویجیٹ کو ہوم اسکرین کے چاروں طرف منتقل کرنے کیلئے اسے ٹچ کریں اور دبائے رکھیں"</string>
- <string name="add_to_home_screen" msgid="8631549138215492708">"ہوم اسکرین میں شامل کریں"</string>
- <string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g> ویجیٹ کو ہوم اسکرین میں شامل کیا گیا"</string>
- <string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# ویجیٹ}other{# ویجیٹس}}"</string>
- <string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{# شارٹ کٹ}other{# شارٹ کٹس}}"</string>
- <string name="widgets_and_shortcuts_count" msgid="7209136747878365116">"<xliff:g id="WIDGETS_COUNT">%1$s</xliff:g>، <xliff:g id="SHORTCUTS_COUNT">%2$s</xliff:g>"</string>
- <string name="widget_button_text" msgid="2880537293434387943">"ویجیٹس"</string>
- <string name="widgets_full_sheet_search_bar_hint" msgid="8484659090860596457">"تلاش کریں"</string>
- <string name="widgets_full_sheet_cancel_button_description" msgid="5766167035728653605">"تلاش کے خانے سے ٹیکسٹ صاف کریں"</string>
- <string name="no_widgets_available" msgid="4337693382501046170">"ویجیٹس اور شارٹ کٹس دستیاب نہیں ہیں"</string>
- <string name="no_search_results" msgid="3787956167293097509">"کوئی ویجیٹ یا شارٹ کٹ نہیں ملا"</string>
- <string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"ذاتی"</string>
- <string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"دفتری ویجیٹس"</string>
- <string name="widget_category_conversations" msgid="8894438636213590446">"گفتگوئیں"</string>
- <string name="widget_education_header" msgid="4874760613775913787">"مفید معلومات کو آسانی سے حاصل کریں"</string>
- <string name="widget_education_content" msgid="745542879510751525">"ایپس کو کھولے بغیر معلومات حاصل کرنے کے لیے آپ اپنی ہوم اسکرین پر ویجیٹس شامل کر سکتے ہیں"</string>
- <string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"ویجیٹ ترتیبات تبدیل کرنے کے لیے تھپتھپائیں"</string>
- <string name="widget_education_close_button" msgid="8676165703104836580">"سمجھ آ گئی"</string>
- <string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"ویجیٹ ترتیبات تبدیل کریں"</string>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"‏دستی طور پر رکھنے کیلئے ‎ٹچ کر کے دبائے رکھیں"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"خود کار طور پر شامل کریں"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"ایپس تلاش کریں"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"ایپس لوڈ کی جا رہی ہیں…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" سے مماثل کوئی ایپس نہیں ملیں"</string>
<string name="all_apps_search_market_message" msgid="1366263386197059176">"مزید ایپس تلاش کریں"</string>
<string name="label_application" msgid="8531721983832654978">"ایپ"</string>
- <string name="all_apps_label" msgid="5015784846527570951">"سبھی ایپس"</string>
<string name="notifications_header" msgid="1404149926117359025">"اطلاعات"</string>
- <string name="long_press_shortcut_to_add" msgid="5405328730817637737">"شارٹ کٹ منتقل کرنے کیلیے ٹچ کریں اور پکڑ کر رکھیں۔"</string>
- <string name="long_accessible_way_to_add_shortcut" msgid="2199537273817090740">"شارٹ کٹ کو منتقل کرنے یا حسب ضرورت کارروائیاں استعمال کرنے کے لیے دوبار تھپتھپائیں اور پکڑ کر رکھیں۔"</string>
- <string name="out_of_space" msgid="6692471482459245734">"اس ہوم اسکرین پر کوئی گنجائش نہیں ہے"</string>
+ <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"ایک شارٹ کٹ منتخب کرنے کیلئے ٹچ کر کے دبائے رکھیں۔"</string>
+ <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"ایک شارٹ کٹ منتخب کرنے یا حسب ضرورت کارروائیاں استعمال کرنے کیلئے دو بار تھپتھپائیں اور دبائے رکھیں۔"</string>
+ <string name="out_of_space" msgid="4691004494942118364">"اس ہوم اسکرین پر مزید کوئی گنجائش نہیں ہے۔"</string>
<string name="hotseat_out_of_space" msgid="7448809638125333693">"پسندیدہ ٹرے میں مزید کوئی گنجائش نہیں ہے"</string>
<string name="all_apps_button_label" msgid="8130441508702294465">"ایپس کی فہرست"</string>
- <string name="all_apps_search_results" msgid="5889367432531296759">"تلاش کے نتائج"</string>
<string name="all_apps_button_personal_label" msgid="1315764287305224468">"ذاتی ایپس کی فہرست"</string>
<string name="all_apps_button_work_label" msgid="7270707118948892488">"دفتری ایپس کی فہرست"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"ہوم"</string>
<string name="remove_drop_target_label" msgid="7812859488053230776">"ہٹائیں"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"اَن انسٹال کریں"</string>
<string name="app_info_drop_target_label" msgid="692894985365717661">"ایپ کی معلومات"</string>
<string name="install_drop_target_label" msgid="2539096853673231757">"انسٹال کریں"</string>
- <string name="dismiss_prediction_label" msgid="3357562989568808658">"ایپ تجویز نہ کریں"</string>
- <string name="pin_prediction" msgid="4196423321649756498">"پیشگوئی پن کریں"</string>
<string name="permlab_install_shortcut" msgid="5632423390354674437">"شارٹ کٹس انسٹال کریں"</string>
<string name="permdesc_install_shortcut" msgid="923466509822011139">"کسی ایپ کو صارف کی مداخلت کے بغیر شارٹ کٹس شامل کرنے کی اجازت دیتا ہے۔"</string>
<string name="permlab_read_settings" msgid="1941457408239617576">"ہوم ترتیبات اور شارٹ کٹس کو پڑھیں"</string>
@@ -84,13 +60,15 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"ہوم ترتیبات اور شارٹ کٹس کو لکھیں"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"ایپ کو ہوم میں ترتیبات اور شارٹ کٹس کو تبدیل کرنے کی اجازت دیتا ہے۔"</string>
<string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> کو فون کالیں کرنے کی اجازت نہیں ہے"</string>
- <string name="gadget_error_text" msgid="740356548025791839">"ویجیٹ لوڈ نہیں کیا جا سکتا"</string>
- <string name="gadget_setup_text" msgid="8348374825537681407">"ویجیٹ کی ترتیبات"</string>
- <string name="gadget_complete_setup_text" msgid="309040266978007925">"سیٹ اپ مکمل کرنے کیلئے تھپتھپائیں"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"ویجیٹ کو لوڈ کرنے میں مسئلہ"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"ترتیب دیں"</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"یہ ایک سسٹم ایپ ہے اور اسے اَن انسٹال نہیں کیا جا سکتا ہے۔"</string>
- <string name="folder_hint_text" msgid="5174843001373488816">"نام میں ترمیم کریں"</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"بلا نام فولڈر"</string>
<string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> غیر فعال ہے"</string>
- <string name="dotted_app_label" msgid="1704091277755818896">"{count,plural,offset:1 =1{{app_name} میں # اطلاع ہے}other{{app_name} میں # اطلاعات ہیں}}"</string>
+ <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+ <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g> میں<xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> اطلاعات ہیں</item>
+ <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g> میں<xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> اطلاع ہے</item>
+ </plurals>
<string name="default_scroll_format" msgid="7475544710230993317">"‏صفحہ ‎%1$d از ‎%2$d"</string>
<string name="workspace_scroll_format" msgid="8458889198184077399">"‏ہوم اسکرین ‎%1$d از ‎%2$d"</string>
<string name="workspace_new_page" msgid="257366611030256142">"نیا ہوم اسکرین صفحہ"</string>
@@ -99,10 +77,10 @@
<string name="folder_tap_to_rename" msgid="4017685068016979677">"نام کی تبدیلی محفوظ کرنے کیلئے تھپتھپائیں"</string>
<string name="folder_closed" msgid="4100806530910930934">"فولڈر بند ہو گیا"</string>
<string name="folder_renamed" msgid="1794088362165669656">"فولڈر کا نام تبدیل کر کے <xliff:g id="NAME">%1$s</xliff:g> کر دیا گیا"</string>
- <string name="folder_name_format_exact" msgid="8626242716117004803">"فولڈر: <xliff:g id="NAME">%1$s</xliff:g>، <xliff:g id="SIZE">%2$d</xliff:g> آئٹمز"</string>
- <string name="folder_name_format_overflow" msgid="4270108890534995199">"فولڈر: <xliff:g id="NAME">%1$s</xliff:g>، <xliff:g id="SIZE">%2$d</xliff:g> یا مزید آئٹمز"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"فولڈر: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"ویجیٹس"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"وال پیپرز"</string>
- <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"وال پیپر اور طرز"</string>
+ <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"طرزیں اور وال پیپر"</string>
<string name="settings_button_text" msgid="8873672322605444408">"ہوم ترتیبات"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"آپ کے منتظم کی طرف سے غیر فعال کر دیا گیا"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"ہوم اسکرین گھمانے کی اجازت دیں"</string>
@@ -114,16 +92,16 @@
<string name="msg_missing_notification_access" msgid="281113995110910548">"اطلاعاتی ڈاٹس دکھانے کی خاطر <xliff:g id="NAME">%1$s</xliff:g> کیلئے ایپ کی اطلاعات آن کریں"</string>
<string name="title_change_settings" msgid="1376365968844349552">"ترتیبات تبدیل کریں"</string>
<string name="notification_dots_service_title" msgid="4284221181793592871">"اطلاعاتی ڈاٹس دکھائیں"</string>
- <string name="auto_add_shortcuts_label" msgid="3698776050751790653">"ہوم اسکرین میں ایپ آئیکنز شامل کریں"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"آئیکن کو ہوم اسکرین میں شامل کریں"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"نئی ایپس کیلئے"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"نامعلوم"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"ہٹائیں"</string>
<string name="abandoned_search" msgid="891119232568284442">"تلاش کریں"</string>
<string name="abandoned_promises_title" msgid="7096178467971716750">"یہ ایپ انسٹال کردہ نہیں ہے"</string>
<string name="abandoned_promise_explanation" msgid="3990027586878167529">"اس آئیکن کیلئے ایپ انسٹال کردہ نہیں ہے۔ آپ اسے ہٹا سکتے ہیں یا ایپ کو تلاش کر سکتے اور دستی طور پر اسے انسٹال کر سکتے ہیں۔"</string>
- <string name="app_installing_title" msgid="5864044122733792085">"<xliff:g id="NAME">%1$s</xliff:g> انسٹال کی جا رہی ہے، <xliff:g id="PROGRESS">%2$s</xliff:g> مکمل ہو گئی"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> ڈاؤن لوڈ ہو رہا ہے، <xliff:g id="PROGRESS">%2$s</xliff:g> مکمل ہو گیا"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> انسٹال ہونے کا انتظار کر رہی ہے"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"<xliff:g id="NAME">%1$s</xliff:g> ویجیٹس"</string>
<string name="widgets_list" msgid="796804551140113767">"ویجیٹس کی فہرست"</string>
<string name="widgets_list_closed" msgid="6141506579418771922">"ویجیٹس کی فہرست بند کر دی گئی"</string>
<string name="action_add_to_workspace" msgid="8902165848117513641">"ہوم اسکرین میں شامل کریں"</string>
@@ -151,20 +129,15 @@
<string name="action_deep_shortcut" msgid="2864038805849372848">"شارٹ کٹس"</string>
<string name="shortcuts_menu_with_notifications_description" msgid="2676582286544232849">"شارٹ کٹس اور اطلاعات"</string>
<string name="action_dismiss_notification" msgid="5909461085055959187">"برخاست کریں"</string>
- <string name="accessibility_close" msgid="2277148124685870734">"بند کریں"</string>
<string name="notification_dismissed" msgid="6002233469409822874">"اطلاع مسترد ہو گئی"</string>
<string name="all_apps_personal_tab" msgid="4190252696685155002">"ذاتی"</string>
<string name="all_apps_work_tab" msgid="4884822796154055118">"دفتری"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"دفتری پروفائل"</string>
- <string name="work_profile_edu_work_apps" msgid="7895468576497746520">"‏ورک ایپس پر بَیج لگا ہوتا ہے اور آپ کا IT منتظم انہیں دیکھ سکتا ہے"</string>
- <string name="work_profile_edu_accept" msgid="6069788082535149071">"سمجھ آ گئی"</string>
- <string name="work_apps_paused_title" msgid="3040901117349444598">"ورک ایپس موقوف ہیں"</string>
- <string name="work_apps_paused_body" msgid="261634750995824906">"آپ کی ورک ایپس آپ کو اطلاعات نہیں بھیج سکتیں، آپ کی بیٹری کا استعمال یا آپ کے مقام تک رسائی حاصل نہیں کر سکتی ہیں"</string>
- <string name="work_apps_paused_content_description" msgid="5149623040804051095">"ورک ایپس آف ہیں۔ آپ کی ورک ایپس آپ کو اطلاعات نہیں بھیج سکتیں، آپ کی بیٹری استعمال یا آپ کے مقام تک رسائی حاصل نہیں کر سکتی ہیں"</string>
- <string name="work_apps_paused_edu_banner" msgid="8872412121608402058">"‏ورک ایپس پر بَیج لگا ہوتا ہے اور آپ کا IT منتظم انہیں دیکھ سکتا ہے"</string>
- <string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"سمجھ آ گئی"</string>
- <string name="work_apps_pause_btn_text" msgid="1921059713673767460">"ورک ایپس آف کریں"</string>
- <string name="work_apps_enable_btn_text" msgid="1156432622148413741">"ورک ایپس آن کریں"</string>
- <string name="developer_options_filter_hint" msgid="5896817443635989056">"فلٹر"</string>
+ <string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"یہاں دفتری ایپس تلاش کریں"</string>
+ <string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"ہر دفتری ایپ میں ایک بَیج ہوتا ہے اور اسے آپ کی تنظیم محفوظ رکھتی ہے۔ زیادہ آسان رسائی کیلئے ایپس کو اپنی ہوم اسکرین پر منتقل کریں۔"</string>
+ <string name="work_mode_on_label" msgid="4781128097185272916">"آپ کی تنظیم کے زیر انتظام"</string>
+ <string name="work_mode_off_label" msgid="3194894777601421047">"اطلاعات اور ایپس آف ہیں"</string>
+ <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"بند کریں"</string>
+ <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"بند"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"ناکام ہو گيا: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
</resources>
diff --git a/res/values-uz/strings.xml b/res/values-uz/strings.xml
index 8984af8972..69084d7041 100644
--- a/res/values-uz/strings.xml
+++ b/res/values-uz/strings.xml
@@ -20,63 +20,39 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="649227358658669779">"Launcher3"</string>
- <string name="work_folder_name" msgid="3753320833950115786">"Ish"</string>
+ <string name="folder_name" msgid="7371454440695724752"></string>
+ <string name="work_folder_name" msgid="3753320833950115786">"Ishga oid"</string>
<string name="activity_not_found" msgid="8071924732094499514">"Ilova o‘rnatilmadi."</string>
<string name="activity_not_available" msgid="7456344436509528827">"Ilova mavjud emas"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"Yuklab olingan ilova xavfsiz rejimda o‘chirib qo‘yildi"</string>
<string name="safemode_widget_error" msgid="4863470563535682004">"Xavfsiz rejimda vidjetlar o‘chirib qo‘yilgan"</string>
<string name="shortcut_not_available" msgid="2536503539825726397">"Tezkor tugmadan foydalanib bo‘lmaydi"</string>
- <string name="home_screen" msgid="5629429142036709174">"Bosh ekran"</string>
- <string name="recent_task_option_split_screen" msgid="6690461455618725183">"Ekranni ikkiga ajratish"</string>
- <string name="split_screen_position_top" msgid="1504965011158689649">"Yuqoriga ajratish"</string>
- <string name="split_screen_position_left" msgid="7537793098851830883">"Chapga ajratish"</string>
- <string name="split_screen_position_right" msgid="1569377524925193369">"Oʻngga ajratish"</string>
- <string name="split_app_info_accessibility" msgid="5475288491241414932">"%1$s ilovasi axboroti"</string>
- <string name="long_press_widget_to_add" msgid="3587712543577675817">"Vidjetni bosib turgan holatda suring."</string>
- <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Ikki marta bosib va bosib turgan holatda vidjetni tanlang yoki maxsus amaldan foydalaning."</string>
+ <string name="home_screen" msgid="806512411299847073">"Bosh ekran"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"Maxsus amallar"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"Vidjetni tanlash uchun bosib turing."</string>
+ <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Ikki marta bosib va bosib turgan holatda vidjetni tanlang yoki maxsus amaldan foydalaning."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"Eni %1$d, bo‘yi %2$d"</string>
- <string name="widget_preview_context_description" msgid="9045841361655787574">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g> ta vidjet"</string>
- <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Vidjetni ushlagan holda kerakli joyga siljiting"</string>
- <string name="add_to_home_screen" msgid="8631549138215492708">"Bosh ekranga chiqarish"</string>
- <string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g> vidjeti bosh ekranga qoʻshildi"</string>
- <string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# ta vidjet}other{# ta vidjet}}"</string>
- <string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{# ta yorliq}other{# ta yorliq}}"</string>
- <string name="widgets_and_shortcuts_count" msgid="7209136747878365116">"<xliff:g id="WIDGETS_COUNT">%1$s</xliff:g>, <xliff:g id="SHORTCUTS_COUNT">%2$s</xliff:g>"</string>
- <string name="widget_button_text" msgid="2880537293434387943">"Vidjetlar"</string>
- <string name="widgets_full_sheet_search_bar_hint" msgid="8484659090860596457">"Qidiruv"</string>
- <string name="widgets_full_sheet_cancel_button_description" msgid="5766167035728653605">"Qidiruv maydoni matnini tozalash"</string>
- <string name="no_widgets_available" msgid="4337693382501046170">"Vidjet va yorliqlar mavjud emas"</string>
- <string name="no_search_results" msgid="3787956167293097509">"Hech qanday vidjet yoki yorliq topilmadi"</string>
- <string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Shaxsiy"</string>
- <string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Ish"</string>
- <string name="widget_category_conversations" msgid="8894438636213590446">"Suhbatlar"</string>
- <string name="widget_education_header" msgid="4874760613775913787">"Barcha kerakli axborot doim yoningizda"</string>
- <string name="widget_education_content" msgid="745542879510751525">"Kerakli ilovalarni ochmasdan turib ulardan axborot olish uchun vidjetlarni bosh ekranga chiqaring"</string>
- <string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Vidjet sozlamalarini oʻzgartirish uchun bosing"</string>
- <string name="widget_education_close_button" msgid="8676165703104836580">"OK"</string>
- <string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Vidjet sozlamalarini oʻzgartirish"</string>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Joylash uchun bosib turing"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"Avtomatik chiqarish"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Ilovalarni qidirish"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Ilovalar yuklanmoqda…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"“<xliff:g id="QUERY">%1$s</xliff:g>” bilan mos hech qanday ilova topilmadi"</string>
<string name="all_apps_search_market_message" msgid="1366263386197059176">"Boshqa ilovalarni qidirish"</string>
<string name="label_application" msgid="8531721983832654978">"Ilova"</string>
- <string name="all_apps_label" msgid="5015784846527570951">"Barcha ilovalar"</string>
<string name="notifications_header" msgid="1404149926117359025">"Bildirishnomalar"</string>
- <string name="long_press_shortcut_to_add" msgid="5405328730817637737">"Yorliqni bosib turgan holatda suring."</string>
- <string name="long_accessible_way_to_add_shortcut" msgid="2199537273817090740">"Ikki marta bosing va yorliqni bosib turgan holatda suring yoki maxsus amaldan foydalaning."</string>
- <string name="out_of_space" msgid="6692471482459245734">"Bosh ekranda joy qolmadi."</string>
+ <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"Yorliqni tanlab olish uchun bosib turing."</string>
+ <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"Ikki marta bosib va bosib turgan holatda yorliqni tanlang yoki maxsus amaldan foydalaning."</string>
+ <string name="out_of_space" msgid="4691004494942118364">"Uy ekranida bitta ham xona yo‘q."</string>
<string name="hotseat_out_of_space" msgid="7448809638125333693">"Ajratilganlarda birorta ham xona yo‘q"</string>
<string name="all_apps_button_label" msgid="8130441508702294465">"Ilovalar ro‘yxati"</string>
- <string name="all_apps_search_results" msgid="5889367432531296759">"Qidiruv natijalari"</string>
<string name="all_apps_button_personal_label" msgid="1315764287305224468">"Shaxsiy ilovalar ro‘yxati"</string>
- <string name="all_apps_button_work_label" msgid="7270707118948892488">"Ishga oid ilovalar ro‘yxati"</string>
+ <string name="all_apps_button_work_label" msgid="7270707118948892488">"Ishchi ilovalar ro‘yxati"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"Bosh sahifa"</string>
<string name="remove_drop_target_label" msgid="7812859488053230776">"Olib tashlash"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"O‘chirib tashlash"</string>
<string name="app_info_drop_target_label" msgid="692894985365717661">"Ilova haqida"</string>
<string name="install_drop_target_label" msgid="2539096853673231757">"O‘rnatish"</string>
- <string name="dismiss_prediction_label" msgid="3357562989568808658">"Tavsiya qilinmasin"</string>
- <string name="pin_prediction" msgid="4196423321649756498">"Tavsiyani mahkamlash"</string>
<string name="permlab_install_shortcut" msgid="5632423390354674437">"yorliqlar yaratish"</string>
<string name="permdesc_install_shortcut" msgid="923466509822011139">"Ilovalarga foydalanuvchidan so‘ramasdan yorliqlar qo‘shishga ruxsat beradi."</string>
<string name="permlab_read_settings" msgid="1941457408239617576">"Uy sozlamalari va yorliqlarini o‘qish"</string>
@@ -84,13 +60,15 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"Uy sozlamalari va yorliqlarini yozish"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"Ilovaga \"Uy\" ekranidagi yorliqlar va sozlamalrni o‘zgartirish uchun ruxsat beradi."</string>
<string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> ilovasiga qo‘ng‘iroqlarni amalga oshirishga ruxsat berilmagan"</string>
- <string name="gadget_error_text" msgid="740356548025791839">"Vidjet yuklanmadi"</string>
- <string name="gadget_setup_text" msgid="8348374825537681407">"Vidjet sozlamalari"</string>
- <string name="gadget_complete_setup_text" msgid="309040266978007925">"Sozlashni yakunlash uchun bosing"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"Vidjetni yuklashda muammo"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"Sozlash"</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"Bu tizim ilovasi, shuning uchun o‘chirib bo‘lmaydi."</string>
- <string name="folder_hint_text" msgid="5174843001373488816">"Nomini tahrirlash"</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"Nomsiz jild"</string>
<string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> ilovasi o‘chirib qo‘yildi"</string>
- <string name="dotted_app_label" msgid="1704091277755818896">"{count,plural,offset:1 =1{{app_name} ilovasida # ta bildirishnoma bor}other{{app_name} ilovasida # ta bildirishnoma bor}}"</string>
+ <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+ <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g> ilovasida <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> ta bildirishnoma bor</item>
+ <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g> ilovasida <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> ta bildirishnoma bor</item>
+ </plurals>
<string name="default_scroll_format" msgid="7475544710230993317">"%2$ddan %1$d ta sahifa"</string>
<string name="workspace_scroll_format" msgid="8458889198184077399">"Uy ekrani %2$ddan %1$d"</string>
<string name="workspace_new_page" msgid="257366611030256142">"Yangi bosh ekran sahifasi"</string>
@@ -99,10 +77,10 @@
<string name="folder_tap_to_rename" msgid="4017685068016979677">"O‘zgarishni saqlash uchun ustiga bosing"</string>
<string name="folder_closed" msgid="4100806530910930934">"Jild yopildi"</string>
<string name="folder_renamed" msgid="1794088362165669656">"Jild nomi <xliff:g id="NAME">%1$s</xliff:g>ga o‘zgartirildi"</string>
- <string name="folder_name_format_exact" msgid="8626242716117004803">"Jild: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> fayllar"</string>
- <string name="folder_name_format_overflow" msgid="4270108890534995199">"Jild: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> va undan ortiq fayllar"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"Jild: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"Vidjetlar"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Fon rasmlari"</string>
- <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Fon rasmi va uslubi"</string>
+ <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Mavzu va fon rasmlari"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Bosh ekran sozlamalari"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Administrator tomonidan o‘chirilgan"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Bosh ekranni burishga ruxsat"</string>
@@ -114,22 +92,22 @@
<string name="msg_missing_notification_access" msgid="281113995110910548">"Bildirishnoma belgilarini ko‘rsatish uchun <xliff:g id="NAME">%1$s</xliff:g> ilovasida bildirishnomalarni yoqing"</string>
<string name="title_change_settings" msgid="1376365968844349552">"Sozlamalarni o‘zgartirish"</string>
<string name="notification_dots_service_title" msgid="4284221181793592871">"Bildirishnoma belgilarini chiqarish"</string>
- <string name="auto_add_shortcuts_label" msgid="3698776050751790653">"Ilova ikonkalarini bosh ekranga chiqarish"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Bosh ekranga ikonka chiqarish"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Yangi o‘rnatilgan ilovalar ikonkasini bosh ekranga chiqarish"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"Noma’lum"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"Olib tashlash"</string>
<string name="abandoned_search" msgid="891119232568284442">"Qidirish"</string>
<string name="abandoned_promises_title" msgid="7096178467971716750">"Ushbu ilova o‘rnatilmagan"</string>
<string name="abandoned_promise_explanation" msgid="3990027586878167529">"Ilova o‘rnatilmagan. Belgini o‘chirib tashlashingiz yoki ilovani topib, uni qo‘lda o‘rnatishingiz mumkin."</string>
- <string name="app_installing_title" msgid="5864044122733792085">"<xliff:g id="NAME">%1$s</xliff:g> oʻrnatlmoqda, <xliff:g id="PROGRESS">%2$s</xliff:g> yakunlandi"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> yuklab olinmoqda, <xliff:g id="PROGRESS">%2$s</xliff:g> bajarildi"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> ilovasi o‘rnatilishi kutilmoqda"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"<xliff:g id="NAME">%1$s</xliff:g> vidjetlari"</string>
<string name="widgets_list" msgid="796804551140113767">"Vidjetlar ro‘yxati"</string>
<string name="widgets_list_closed" msgid="6141506579418771922">"Vidjetlar ro‘yxati yopildi"</string>
<string name="action_add_to_workspace" msgid="8902165848117513641">"Bosh ekranga chiqarish"</string>
<string name="action_move_here" msgid="2170188780612570250">"Obyektni bu yerga ko‘chirish"</string>
<string name="item_added_to_workspace" msgid="4211073925752213539">"Obyekt bosh ekranga qo‘shildi"</string>
- <string name="item_removed" msgid="851119963877842327">"Element olib tashlandi"</string>
+ <string name="item_removed" msgid="851119963877842327">"Obyekt o‘chirib tashlandi"</string>
<string name="undo" msgid="4151576204245173321">"Qaytarish"</string>
<string name="action_move" msgid="4339390619886385032">"Obyektni ko‘chirib o‘tkazish"</string>
<string name="move_to_empty_cell" msgid="2833711483015685619">"<xliff:g id="NUMBER_0">%1$s</xliff:g> <xliff:g id="NUMBER_1">%2$s</xliff:g> katakka olish"</string>
@@ -151,20 +129,15 @@
<string name="action_deep_shortcut" msgid="2864038805849372848">"Tezkor tugmalar"</string>
<string name="shortcuts_menu_with_notifications_description" msgid="2676582286544232849">"Yorliqlar va bildirishnomalar"</string>
<string name="action_dismiss_notification" msgid="5909461085055959187">"Yopish"</string>
- <string name="accessibility_close" msgid="2277148124685870734">"Yopish"</string>
<string name="notification_dismissed" msgid="6002233469409822874">"Bildirishnoma yopildi"</string>
<string name="all_apps_personal_tab" msgid="4190252696685155002">"Shaxsiy"</string>
- <string name="all_apps_work_tab" msgid="4884822796154055118">"Ish"</string>
- <string name="work_profile_toggle_label" msgid="3081029915775481146">"Ish profili"</string>
- <string name="work_profile_edu_work_apps" msgid="7895468576497746520">"Ishga oid ilovalarning maxsus belgisi bor hamda ular administratoringizga koʻrinadi"</string>
- <string name="work_profile_edu_accept" msgid="6069788082535149071">"OK"</string>
- <string name="work_apps_paused_title" msgid="3040901117349444598">"Ishga oid ilovalar pauza qilingan"</string>
- <string name="work_apps_paused_body" msgid="261634750995824906">"Ishga oid ilovalar batareya sarfi haqida bildirishnomalar yubora olmaydi va joylashuv axborotidan foydalana olmaydi"</string>
- <string name="work_apps_paused_content_description" msgid="5149623040804051095">"Ishga oid ilovalar faolsizlantirilgan. Ular batareya sarfi haqida bildirishnomalar yubora olmaydi va joylashuv axborotidan foydalana olmaydi"</string>
- <string name="work_apps_paused_edu_banner" msgid="8872412121608402058">"Ishga oid ilovalarning maxsus belgisi bor hamda ular administratoringizga koʻrinadi"</string>
- <string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"OK"</string>
- <string name="work_apps_pause_btn_text" msgid="1921059713673767460">"Ishga oid ilovalarni faolsizlantirish"</string>
- <string name="work_apps_enable_btn_text" msgid="1156432622148413741">"Ishga oid ilovalarni yoqish"</string>
- <string name="developer_options_filter_hint" msgid="5896817443635989056">"Saralash"</string>
+ <string name="all_apps_work_tab" msgid="4884822796154055118">"Ishchi"</string>
+ <string name="work_profile_toggle_label" msgid="3081029915775481146">"Ishchi profil"</string>
+ <string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"Ishga oid ilovalarni shu yerdan topish mumkin"</string>
+ <string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"Nishonga ega har bir ishga oid ilova tashkilotingiz tomonidan himoyalanadi. Ishga oid ilovalarga osonroq kirish uchun ularni bosh ekranga chiqaring."</string>
+ <string name="work_mode_on_label" msgid="4781128097185272916">"Tashkilotingiz tomonidan boshqariladi"</string>
+ <string name="work_mode_off_label" msgid="3194894777601421047">"Bildirishnomalar va ilovalar faol emas"</string>
+ <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Yopish"</string>
+ <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Yopiq"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Xato: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
</resources>
diff --git a/res/values-v31/colors.xml b/res/values-v31/colors.xml
index 7bbdbd18fa..d73ee57080 100644
--- a/res/values-v31/colors.xml
+++ b/res/values-v31/colors.xml
@@ -40,19 +40,7 @@
<color name="wallpaper_popup_scrim">@android:color/system_neutral1_900</color>
- <color name="folder_dot_color">@android:color/system_accent3_100</color>
- <color name="folder_pagination_color_light">@android:color/system_accent1_600</color>
- <color name="folder_pagination_color_dark">@android:color/system_accent2_100</color>
-
- <color name="home_settings_header_accent">@android:color/system_accent1_600</color>
- <color name="home_settings_header_collapsed">@android:color/system_neutral1_100</color>
- <color name="home_settings_header_expanded">@android:color/system_neutral1_50</color>
-
- <color name="home_settings_state_on_color">@android:color/system_accent1_100</color>
- <color name="home_settings_state_off_color">@android:color/system_accent2_100</color>
- <color name="home_settings_thumb_off_color">@android:color/system_neutral2_100</color>
- <color name="home_settings_track_on_color">@android:color/system_accent1_600</color>
- <color name="home_settings_track_off_color">@android:color/system_neutral2_600</color>
+ <color name="folder_dot_color">@android:color/system_accent2_50</color>
<color name="workspace_accent_color_light">@android:color/system_accent1_100</color>
<color name="workspace_accent_color_dark">@android:color/system_accent2_600</color>
diff --git a/res/values-v31/config.xml b/res/values-v31/config.xml
deleted file mode 100644
index afb9e6d9e8..0000000000
--- a/res/values-v31/config.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2021 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.
- -->
-<resources>
- <bool name="home_settings_icon_space_reserved">false</bool>
- <bool name="home_settings_allow_divider">false</bool>
-</resources> \ No newline at end of file
diff --git a/res/values-v31/styles.xml b/res/values-v31/styles.xml
deleted file mode 100644
index 008a77c3a8..0000000000
--- a/res/values-v31/styles.xml
+++ /dev/null
@@ -1,97 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-* Copyright (C) 2021 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.
-*/
--->
-
-<resources>
-
- <style name="HomeSettings.Theme" parent="@android:style/Theme.DeviceDefault.Settings">
- <item name="android:listPreferredItemPaddingEnd">16dp</item>
- <item name="android:listPreferredItemPaddingStart">24dp</item>
- <item name="android:navigationBarColor">@android:color/transparent</item>
- <item name="android:statusBarColor">@android:color/transparent</item>
- <item name="android:switchStyle">@style/HomeSettings.SwitchStyle</item>
- <item name="android:textAppearanceListItem">@style/HomeSettings.PreferenceTitle</item>
- <item name="android:windowActionBar">false</item>
- <item name="android:windowNoTitle">true</item>
- <item name="preferenceTheme">@style/HomeSettings.PreferenceTheme</item>
- </style>
-
- <style name="HomeSettings.PreferenceTheme" parent="@style/PreferenceThemeOverlay">
- <item name="preferenceCategoryStyle">@style/HomeSettings.CategoryStyle</item>
- <item name="preferenceCategoryTitleTextAppearance">@style/HomeSettings.CategoryTitle</item>
- <item name="preferenceFragmentCompatStyle">@style/HomeSettings.FragmentCompatStyle</item>
- <item name="preferenceScreenStyle">@style/HomeSettings.PreferenceScreenStyle</item>
- <item name="preferenceStyle">@style/HomeSettings.PreferenceStyle</item>
- <item name="switchPreferenceStyle">@style/HomeSettings.SwitchPreferenceStyle</item>
- <item name="android:fontFamily">google-sans-text</item>
- </style>
-
- <style name="HomeSettings.CategoryStyle" parent="@style/Preference.Category.Material">
- <item name="allowDividerAbove">@bool/home_settings_allow_divider</item>
- <item name="allowDividerBelow">@bool/home_settings_allow_divider</item>
- <item name="iconSpaceReserved">@bool/home_settings_icon_space_reserved</item>
- </style>
-
- <style name="HomeSettings.PreferenceStyle" parent="@style/Preference.Material">
- <item name="iconSpaceReserved">@bool/home_settings_icon_space_reserved</item>
- </style>
-
- <style name="HomeSettings.PreferenceScreenStyle"
- parent="@style/Preference.PreferenceScreen.Material">
- <item name="iconSpaceReserved">@bool/home_settings_icon_space_reserved</item>
- </style>
-
- <style name="HomeSettings.SwitchPreferenceStyle"
- parent="@style/Preference.SwitchPreference.Material">
- <item name="iconSpaceReserved">@bool/home_settings_icon_space_reserved</item>
- </style>
-
- <style name="HomeSettings.SwitchStyle"
- parent="@android:style/Widget.Material.CompoundButton.Switch">
- <item name="android:switchMinWidth">52dp</item>
- <item name="android:thumb">@drawable/home_settings_switch_thumb</item>
- <item name="android:track">@drawable/home_settings_switch_track</item>
- </style>
-
- <style name="HomeSettings.PreferenceTitle"
- parent="@android:style/TextAppearance.Material.Subhead">
- <item name="android:fontFamily">google-sans</item>
- <item name="android:textSize">20sp</item>
- </style>
-
- <style name="HomeSettings.CategoryTitle" parent="@android:style/TextAppearance.Material.Body2">
- <item name="android:fontFamily">google-sans-text-medium</item>
- </style>
-
- <style name="HomeSettings.CollapsingToolbar" parent="@style/Theme.MaterialComponents.DayNight">
- <item name="colorAccent">@color/home_settings_header_accent</item>
- <item name="colorPrimary">@color/home_settings_header_expanded</item>
- <item name="elevationOverlayColor">?attr/colorPrimary</item>
- <item name="elevationOverlayEnabled">true</item>
- </style>
-
- <style name="HomeSettings.CollapsedToolbarTitle"
- parent="@android:style/TextAppearance.DeviceDefault.Widget.ActionBar.Title">
- <item name="android:fontFamily">google-sans</item>
- <item name="android:textSize">20sp</item>
- </style>
-
- <style name="HomeSettings.ExpandedToolbarTitle" parent="HomeSettings.CollapsedToolbarTitle">
- <item name="android:textSize">36sp</item>
- </style>
-</resources> \ No newline at end of file
diff --git a/res/values-v33/style.xml b/res/values-v33/style.xml
deleted file mode 100644
index bd484683d0..0000000000
--- a/res/values-v33/style.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-* Copyright (C) 2022 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
--->
-
-<resources>
- <style name="HomeSettings.Theme" parent="@android:style/Theme.DeviceDefault.Settings">
- <item name="android:listPreferredItemPaddingEnd">16dp</item>
- <item name="android:listPreferredItemPaddingStart">24dp</item>
- <item name="android:navigationBarColor">@android:color/transparent</item>
- <item name="android:statusBarColor">@android:color/transparent</item>
- <item name="android:switchStyle">@style/HomeSettings.SwitchStyle</item>
- <item name="android:textAppearanceListItem">@style/HomeSettings.PreferenceTitle</item>
- <item name="android:windowActionBar">false</item>
- <item name="android:windowNoTitle">true</item>
- <item name="preferenceTheme">@style/HomeSettings.PreferenceTheme</item>
- <item name="android:windowAnimationStyle">@style/Animation.SharedBackground</item>
- </style>
-
- <style name="Animation.SharedBackground" parent="@android:style/Animation.Activity">
- <item name="android:activityOpenEnterAnimation">@anim/shared_x_axis_activity_open_enter</item>
- <item name="android:activityOpenExitAnimation">@anim/shared_x_axis_activity_open_exit</item>
- <item name="android:activityCloseEnterAnimation">@anim/shared_x_axis_activity_close_enter</item>
- <item name="android:activityCloseExitAnimation">@anim/shared_x_axis_activity_close_exit</item>
- </style>
-</resources> \ No newline at end of file
diff --git a/res/values-vi/strings.xml b/res/values-vi/strings.xml
index 6972ee325e..71decfca68 100644
--- a/res/values-vi/strings.xml
+++ b/res/values-vi/strings.xml
@@ -20,63 +20,39 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="649227358658669779">"Trình chạy 3"</string>
+ <string name="folder_name" msgid="7371454440695724752"></string>
<string name="work_folder_name" msgid="3753320833950115786">"Work"</string>
<string name="activity_not_found" msgid="8071924732094499514">"Ứng dụng chưa được cài đặt."</string>
<string name="activity_not_available" msgid="7456344436509528827">"Ứng dụng không có sẵn"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"Ứng dụng đã tải xuống bị tắt ở chế độ An toàn"</string>
- <string name="safemode_widget_error" msgid="4863470563535682004">"Tiện ích bị vô hiệu hóa ở chế độ an toàn"</string>
+ <string name="safemode_widget_error" msgid="4863470563535682004">"Tiện ích con bị vô hiệu hóa ở chế độ an toàn"</string>
<string name="shortcut_not_available" msgid="2536503539825726397">"Lối tắt không khả dụng"</string>
- <string name="home_screen" msgid="5629429142036709174">"Màn hình chính"</string>
- <string name="recent_task_option_split_screen" msgid="6690461455618725183">"Chia đôi màn hình"</string>
- <string name="split_screen_position_top" msgid="1504965011158689649">"Chia đôi màn hình lên phía trên cùng"</string>
- <string name="split_screen_position_left" msgid="7537793098851830883">"Chia đôi màn hình về bên trái"</string>
- <string name="split_screen_position_right" msgid="1569377524925193369">"Chia đôi màn hình về bên phải"</string>
- <string name="split_app_info_accessibility" msgid="5475288491241414932">"Thông tin ứng dụng cho %1$s"</string>
- <string name="long_press_widget_to_add" msgid="3587712543577675817">"Chạm và giữ để di chuyển một tiện ích."</string>
- <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Nhấn đúp và giữ để di chuyển một tiện ích hoặc sử dụng các thao tác tùy chỉnh."</string>
+ <string name="home_screen" msgid="806512411299847073">"Màn hình chính"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"Tác vụ tùy chỉnh"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"Chạm và giữ để chọn tiện ích con."</string>
+ <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Nhấn đúp và giữ để chọn tiện ích hoặc sử dụng tác vụ tùy chỉnh."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"Rộng %1$d x cao %2$d"</string>
- <string name="widget_preview_context_description" msgid="9045841361655787574">"Tiện ích <xliff:g id="WIDGET_NAME">%1$s</xliff:g>"</string>
- <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Chạm và giữ để di chuyển tiện ích xung quanh Màn hình chính"</string>
- <string name="add_to_home_screen" msgid="8631549138215492708">"Thêm vào Màn hình chính"</string>
- <string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"Đã thêm tiện ích <xliff:g id="WIDGET_NAME">%1$s</xliff:g> vào màn hình chính"</string>
- <string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# tiện ích}other{# tiện ích}}"</string>
- <string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{# lối tắt}other{# lối tắt}}"</string>
- <string name="widgets_and_shortcuts_count" msgid="7209136747878365116">"<xliff:g id="WIDGETS_COUNT">%1$s</xliff:g>, <xliff:g id="SHORTCUTS_COUNT">%2$s</xliff:g>"</string>
- <string name="widget_button_text" msgid="2880537293434387943">"Tiện ích"</string>
- <string name="widgets_full_sheet_search_bar_hint" msgid="8484659090860596457">"Tìm kiếm"</string>
- <string name="widgets_full_sheet_cancel_button_description" msgid="5766167035728653605">"Xóa văn bản khỏi hộp tìm kiếm"</string>
- <string name="no_widgets_available" msgid="4337693382501046170">"Không có tiện ích và lối tắt nào"</string>
- <string name="no_search_results" msgid="3787956167293097509">"Không tìm thấy tiện ích hoặc lối tắt nào"</string>
- <string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Cá nhân"</string>
- <string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Công việc"</string>
- <string name="widget_category_conversations" msgid="8894438636213590446">"Cuộc trò chuyện"</string>
- <string name="widget_education_header" msgid="4874760613775913787">"Thông tin hữu ích ngay trong tầm tay bạn"</string>
- <string name="widget_education_content" msgid="745542879510751525">"Để nhận thông tin mà không cần mở các ứng dụng, bạn có thể thêm tiện ích vào Màn hình chính"</string>
- <string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Nhấn để thay đổi chế độ cài đặt tiện ích"</string>
- <string name="widget_education_close_button" msgid="8676165703104836580">"Tôi hiểu"</string>
- <string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Thay đổi chế độ cài đặt tiện ích"</string>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Chạm và giữ để thêm theo cách thủ công"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"Tự động thêm"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Tìm kiếm ứng dụng"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Đang tải ứng dụng…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"Không tìm thấy ứng dụng nào phù hợp với \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
<string name="all_apps_search_market_message" msgid="1366263386197059176">"Tìm kiếm thêm ứng dụng"</string>
<string name="label_application" msgid="8531721983832654978">"Ứng dụng"</string>
- <string name="all_apps_label" msgid="5015784846527570951">"Tất cả ứng dụng"</string>
<string name="notifications_header" msgid="1404149926117359025">"Thông báo"</string>
- <string name="long_press_shortcut_to_add" msgid="5405328730817637737">"Chạm và giữ để di chuyển một lối tắt."</string>
- <string name="long_accessible_way_to_add_shortcut" msgid="2199537273817090740">"Nhấn đúp và giữ để di chuyển một lối tắt hoặc sử dụng các thao tác tùy chỉnh."</string>
- <string name="out_of_space" msgid="6692471482459245734">"Không còn khoảng trống trên Màn hình chính này"</string>
+ <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"Chạm và giữ để chọn lối tắt."</string>
+ <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"Nhấn đúp và giữ để chọn lối tắt hoặc sử dụng hành động tùy chỉnh."</string>
+ <string name="out_of_space" msgid="4691004494942118364">"Không còn chỗ trên Màn hình chính này."</string>
<string name="hotseat_out_of_space" msgid="7448809638125333693">"Không còn chỗ trong khay Mục yêu thích"</string>
<string name="all_apps_button_label" msgid="8130441508702294465">"Danh sách ứng dụng"</string>
- <string name="all_apps_search_results" msgid="5889367432531296759">"Kết quả tìm kiếm"</string>
<string name="all_apps_button_personal_label" msgid="1315764287305224468">"Danh sách ứng dụng cá nhân"</string>
<string name="all_apps_button_work_label" msgid="7270707118948892488">"Danh sách ứng dụng công việc"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"Màn hình chính"</string>
<string name="remove_drop_target_label" msgid="7812859488053230776">"Xóa"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"Gỡ cài đặt"</string>
<string name="app_info_drop_target_label" msgid="692894985365717661">"Thông tin ứng dụng"</string>
<string name="install_drop_target_label" msgid="2539096853673231757">"Cài đặt"</string>
- <string name="dismiss_prediction_label" msgid="3357562989568808658">"Không đề xuất ứng dụng"</string>
- <string name="pin_prediction" msgid="4196423321649756498">"Ghim ứng dụng dự đoán"</string>
<string name="permlab_install_shortcut" msgid="5632423390354674437">"cài đặt lối tắt"</string>
<string name="permdesc_install_shortcut" msgid="923466509822011139">"Cho phép ứng dụng thêm lối tắt mà không cần sự can thiệp của người dùng."</string>
<string name="permlab_read_settings" msgid="1941457408239617576">"đọc cài đặt và lối tắt trên Màn hình chính"</string>
@@ -84,13 +60,15 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"ghi cài đặt và lối tắt trên Màn hình chính"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"Cho phép ứng dụng thay đổi cài đặt và lối tắt trên Màn hình chính."</string>
<string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> không được phép thực hiện cuộc gọi điện thoại"</string>
- <string name="gadget_error_text" msgid="740356548025791839">"Không thể tải tiện ích"</string>
- <string name="gadget_setup_text" msgid="8348374825537681407">"Cài đặt tiện ích"</string>
- <string name="gadget_complete_setup_text" msgid="309040266978007925">"Nhấn để hoàn tất thiết lập"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"Sự cố khi tải tiện ích con"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"Thiết lập"</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"Đây là ứng dụng hệ thống và không thể gỡ cài đặt."</string>
- <string name="folder_hint_text" msgid="5174843001373488816">"Chỉnh sửa tên"</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"Thư mục chưa đặt tên"</string>
<string name="disabled_app_label" msgid="6673129024321402780">"Đã vô hiệu hóa <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
- <string name="dotted_app_label" msgid="1704091277755818896">"{count,plural,offset:1 =1{{app_name} có # thông báo}other{{app_name} có # thông báo}}"</string>
+ <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+ <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, có <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> thông báo</item>
+ <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g>, có <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> thông báo</item>
+ </plurals>
<string name="default_scroll_format" msgid="7475544710230993317">"Trang %1$d / %2$d"</string>
<string name="workspace_scroll_format" msgid="8458889198184077399">"Màn hình chính %1$d / %2$d"</string>
<string name="workspace_new_page" msgid="257366611030256142">"Trang màn hình chính mới"</string>
@@ -99,38 +77,38 @@
<string name="folder_tap_to_rename" msgid="4017685068016979677">"Nhấn để lưu đổi tên"</string>
<string name="folder_closed" msgid="4100806530910930934">"Đã đóng thư mục"</string>
<string name="folder_renamed" msgid="1794088362165669656">"Đã đổi tên thư mục thành <xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="folder_name_format_exact" msgid="8626242716117004803">"Thư mục: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> mục"</string>
- <string name="folder_name_format_overflow" msgid="4270108890534995199">"Thư mục: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> mục trở lên"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"Thư mục: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"Tiện ích"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Hình nền"</string>
- <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Hình nền và phong cách"</string>
+ <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Kiểu và hình nền"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Cài đặt màn hình chính"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Bị tắt bởi quản trị viên của bạn"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Cho phép xoay Màn hình chính"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"Khi xoay điện thoại"</string>
<string name="notification_dots_title" msgid="9062440428204120317">"Dấu chấm thông báo"</string>
- <string name="notification_dots_desc_on" msgid="1679848116452218908">"Đang bật"</string>
+ <string name="notification_dots_desc_on" msgid="1679848116452218908">"Bật"</string>
<string name="notification_dots_desc_off" msgid="1760796511504341095">"Tắt"</string>
<string name="title_missing_notification_access" msgid="7503287056163941064">"Cần quyền truy cập thông báo"</string>
<string name="msg_missing_notification_access" msgid="281113995110910548">"Để hiển thị Dấu chấm thông báo, hãy bật thông báo ứng dụng cho <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="title_change_settings" msgid="1376365968844349552">"Thay đổi cài đặt"</string>
- <string name="notification_dots_service_title" msgid="4284221181793592871">"Hiện dấu chấm thông báo"</string>
- <string name="auto_add_shortcuts_label" msgid="3698776050751790653">"Thêm biểu tượng ứng dụng vào Màn hình chính"</string>
+ <string name="notification_dots_service_title" msgid="4284221181793592871">"Hiển thị dấu chấm thông báo"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Thêm biểu tượng vào màn hình chính"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Cho ứng dụng mới"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"Không xác định"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"Xóa"</string>
<string name="abandoned_search" msgid="891119232568284442">"Tìm kiếm"</string>
<string name="abandoned_promises_title" msgid="7096178467971716750">"Ứng dụng này chưa được cài đặt"</string>
<string name="abandoned_promise_explanation" msgid="3990027586878167529">"Ứng dụng cho biểu tượng này chưa được cài đặt. Bạn có thể xóa ứng dụng hoặc tìm kiếm và cài đặt ứng dụng theo cách thủ công."</string>
- <string name="app_installing_title" msgid="5864044122733792085">"Đang cài đặt <xliff:g id="NAME">%1$s</xliff:g>, hoàn tất <xliff:g id="PROGRESS">%2$s</xliff:g>"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"Đang tải xuống <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="PROGRESS">%2$s</xliff:g> hoàn tất"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"Đang chờ cài đặt <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"Tiện ích của <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="widgets_list" msgid="796804551140113767">"Danh sách tiện ích"</string>
<string name="widgets_list_closed" msgid="6141506579418771922">"Đã đóng danh sách tiện ích"</string>
<string name="action_add_to_workspace" msgid="8902165848117513641">"Thêm vào màn hình chính"</string>
<string name="action_move_here" msgid="2170188780612570250">"Di chuyển mục vào đây"</string>
<string name="item_added_to_workspace" msgid="4211073925752213539">"Đã thêm mục vào màn hình chính"</string>
<string name="item_removed" msgid="851119963877842327">"Đã xóa mục"</string>
- <string name="undo" msgid="4151576204245173321">"Hủy"</string>
+ <string name="undo" msgid="4151576204245173321">"Hoàn tác"</string>
<string name="action_move" msgid="4339390619886385032">"Di chuyển mục"</string>
<string name="move_to_empty_cell" msgid="2833711483015685619">"Di chuyển đến hàng <xliff:g id="NUMBER_0">%1$s</xliff:g> cột <xliff:g id="NUMBER_1">%2$s</xliff:g>"</string>
<string name="move_to_position" msgid="6750008980455459790">"Di chuyển tới vị trí <xliff:g id="NUMBER">%1$s</xliff:g>"</string>
@@ -151,20 +129,15 @@
<string name="action_deep_shortcut" msgid="2864038805849372848">"Lối tắt"</string>
<string name="shortcuts_menu_with_notifications_description" msgid="2676582286544232849">"Phím tắt và thông báo"</string>
<string name="action_dismiss_notification" msgid="5909461085055959187">"Loại bỏ"</string>
- <string name="accessibility_close" msgid="2277148124685870734">"Đóng"</string>
<string name="notification_dismissed" msgid="6002233469409822874">"Đã loại bỏ thông báo"</string>
<string name="all_apps_personal_tab" msgid="4190252696685155002">"Cá nhân"</string>
- <string name="all_apps_work_tab" msgid="4884822796154055118">"Công việc"</string>
+ <string name="all_apps_work_tab" msgid="4884822796154055118">"Cơ quan"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"Hồ sơ công việc"</string>
- <string name="work_profile_edu_work_apps" msgid="7895468576497746520">"Các ứng dụng công việc được gắn huy hiệu và quản trị viên CNTT có thể nhìn thấy"</string>
- <string name="work_profile_edu_accept" msgid="6069788082535149071">"OK"</string>
- <string name="work_apps_paused_title" msgid="3040901117349444598">"Đã tạm dừng các ứng dụng công việc"</string>
- <string name="work_apps_paused_body" msgid="261634750995824906">"Các ứng dụng công việc không thể gửi thông báo cho bạn, sử dụng pin hoặc truy cập thông tin vị trí của bạn"</string>
- <string name="work_apps_paused_content_description" msgid="5149623040804051095">"Ứng dụng công việc đang tắt. Các ứng dụng công việc không thể gửi thông báo cho bạn, sử dụng pin hoặc truy cập thông tin vị trí của bạn"</string>
- <string name="work_apps_paused_edu_banner" msgid="8872412121608402058">"Các ứng dụng công việc được gắn huy hiệu và quản trị viên CNTT có thể nhìn thấy"</string>
- <string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"Tôi hiểu"</string>
- <string name="work_apps_pause_btn_text" msgid="1921059713673767460">"Tắt ứng dụng công việc"</string>
- <string name="work_apps_enable_btn_text" msgid="1156432622148413741">"Bật ứng dụng công việc"</string>
- <string name="developer_options_filter_hint" msgid="5896817443635989056">"Bộ lọc"</string>
+ <string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"Tìm ứng dụng công việc tại đây"</string>
+ <string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"Mỗi ứng dụng công việc đều có một huy hiệu và được tổ chức của bạn bảo mật. Bạn có thể di chuyển ứng dụng đến Màn hình chính để truy cập dễ dàng hơn."</string>
+ <string name="work_mode_on_label" msgid="4781128097185272916">"Do tổ chức của bạn quản lý"</string>
+ <string name="work_mode_off_label" msgid="3194894777601421047">"Thông báo và ứng dụng đang tắt"</string>
+ <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Đóng"</string>
+ <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Đã đóng"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Không thực hiện được thao tác: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
</resources>
diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml
index c7eb21e54b..9804af1e89 100644
--- a/res/values-zh-rCN/strings.xml
+++ b/res/values-zh-rCN/strings.xml
@@ -20,63 +20,39 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="649227358658669779">"Launcher3"</string>
+ <string name="folder_name" msgid="7371454440695724752"></string>
<string name="work_folder_name" msgid="3753320833950115786">"Work"</string>
<string name="activity_not_found" msgid="8071924732094499514">"未安装该应用。"</string>
<string name="activity_not_available" msgid="7456344436509528827">"应用不可用"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"安全模式下不允许使用下载的此应用"</string>
<string name="safemode_widget_error" msgid="4863470563535682004">"安全模式下不允许使用微件"</string>
<string name="shortcut_not_available" msgid="2536503539825726397">"无法使用快捷方式"</string>
- <string name="home_screen" msgid="5629429142036709174">"主屏幕"</string>
- <string name="recent_task_option_split_screen" msgid="6690461455618725183">"分屏"</string>
- <string name="split_screen_position_top" msgid="1504965011158689649">"上分屏"</string>
- <string name="split_screen_position_left" msgid="7537793098851830883">"左分屏"</string>
- <string name="split_screen_position_right" msgid="1569377524925193369">"右分屏"</string>
- <string name="split_app_info_accessibility" msgid="5475288491241414932">"%1$s 的应用信息"</string>
- <string name="long_press_widget_to_add" msgid="3587712543577675817">"轻触并按住微件即可移动该微件。"</string>
- <string name="long_accessible_way_to_add" msgid="2733588281439571974">"点按两次并按住微件即可移动该微件或使用自定义操作。"</string>
+ <string name="home_screen" msgid="806512411299847073">"主屏幕"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"自定义操作"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"触摸并按住微件即可选择。"</string>
+ <string name="long_accessible_way_to_add" msgid="4289502106628154155">"点按两次并按住微件即可选择微件,您也可以使用自定义操作。"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"宽 %1$d,高 %2$d"</string>
- <string name="widget_preview_context_description" msgid="9045841361655787574">"“<xliff:g id="WIDGET_NAME">%1$s</xliff:g>”微件"</string>
- <string name="add_item_request_drag_hint" msgid="5653291305078645405">"轻触并按住该微件即可将其在主屏幕上四处移动"</string>
- <string name="add_to_home_screen" msgid="8631549138215492708">"添加到主屏幕"</string>
- <string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"已将“<xliff:g id="WIDGET_NAME">%1$s</xliff:g>”微件添加到主屏幕"</string>
- <string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# 个微件}other{# 个微件}}"</string>
- <string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{# 个快捷方式}other{# 个快捷方式}}"</string>
- <string name="widgets_and_shortcuts_count" msgid="7209136747878365116">"<xliff:g id="WIDGETS_COUNT">%1$s</xliff:g>,<xliff:g id="SHORTCUTS_COUNT">%2$s</xliff:g>"</string>
- <string name="widget_button_text" msgid="2880537293434387943">"微件"</string>
- <string name="widgets_full_sheet_search_bar_hint" msgid="8484659090860596457">"搜索"</string>
- <string name="widgets_full_sheet_cancel_button_description" msgid="5766167035728653605">"清除搜索框中的文字"</string>
- <string name="no_widgets_available" msgid="4337693382501046170">"无法使用微件和快捷方式"</string>
- <string name="no_search_results" msgid="3787956167293097509">"未找到任何微件或快捷方式"</string>
- <string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"个人"</string>
- <string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"工作"</string>
- <string name="widget_category_conversations" msgid="8894438636213590446">"对话"</string>
- <string name="widget_education_header" msgid="4874760613775913787">"实用信息触手可及"</string>
- <string name="widget_education_content" msgid="745542879510751525">"要想不打开应用就能获取信息,您可以将相应微件添加到主屏幕"</string>
- <string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"点按即可更改微件设置"</string>
- <string name="widget_education_close_button" msgid="8676165703104836580">"知道了"</string>
- <string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"更改微件设置"</string>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"轻触并按住即可手动放置"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"自动添加"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"搜索应用"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"正在加载应用…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"未找到与“<xliff:g id="QUERY">%1$s</xliff:g>”相符的应用"</string>
<string name="all_apps_search_market_message" msgid="1366263386197059176">"搜索更多应用"</string>
<string name="label_application" msgid="8531721983832654978">"应用"</string>
- <string name="all_apps_label" msgid="5015784846527570951">"所有应用"</string>
<string name="notifications_header" msgid="1404149926117359025">"通知"</string>
- <string name="long_press_shortcut_to_add" msgid="5405328730817637737">"轻触并按住快捷方式即可移动该快捷方式。"</string>
- <string name="long_accessible_way_to_add_shortcut" msgid="2199537273817090740">"点按两次并按住快捷方式即可移动该快捷方式或使用自定义操作。"</string>
- <string name="out_of_space" msgid="6692471482459245734">"此主屏幕上已没有空间"</string>
+ <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"触摸并按住快捷方式即可选择快捷方式。"</string>
+ <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"点按两次并按住快捷方式即可选择快捷方式,您也可以使用自定义操作。"</string>
+ <string name="out_of_space" msgid="4691004494942118364">"此主屏幕上已没有空间。"</string>
<string name="hotseat_out_of_space" msgid="7448809638125333693">"收藏栏已满"</string>
<string name="all_apps_button_label" msgid="8130441508702294465">"应用列表"</string>
- <string name="all_apps_search_results" msgid="5889367432531296759">"搜索结果"</string>
<string name="all_apps_button_personal_label" msgid="1315764287305224468">"个人应用列表"</string>
<string name="all_apps_button_work_label" msgid="7270707118948892488">"工作应用列表"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"主屏幕"</string>
<string name="remove_drop_target_label" msgid="7812859488053230776">"移除"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"卸载"</string>
<string name="app_info_drop_target_label" msgid="692894985365717661">"应用信息"</string>
<string name="install_drop_target_label" msgid="2539096853673231757">"安装"</string>
- <string name="dismiss_prediction_label" msgid="3357562989568808658">"不要提供应用建议"</string>
- <string name="pin_prediction" msgid="4196423321649756498">"固定预测的应用"</string>
<string name="permlab_install_shortcut" msgid="5632423390354674437">"安装快捷方式"</string>
<string name="permdesc_install_shortcut" msgid="923466509822011139">"允许应用自行添加快捷方式。"</string>
<string name="permlab_read_settings" msgid="1941457408239617576">"读取主屏幕设置和快捷方式"</string>
@@ -84,13 +60,15 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"写入主屏幕设置和快捷方式"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"允许应用更改主屏幕中的设置和快捷方式。"</string>
<string name="msg_no_phone_permission" msgid="9208659281529857371">"不允许使用“<xliff:g id="APP_NAME">%1$s</xliff:g>”拨打电话"</string>
- <string name="gadget_error_text" msgid="740356548025791839">"无法加载微件"</string>
- <string name="gadget_setup_text" msgid="8348374825537681407">"微件设置"</string>
- <string name="gadget_complete_setup_text" msgid="309040266978007925">"点按即可完成设置"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"加载微件时出现问题"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"设置"</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"这是系统应用,无法卸载。"</string>
- <string name="folder_hint_text" msgid="5174843001373488816">"修改名称"</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"未命名文件夹"</string>
<string name="disabled_app_label" msgid="6673129024321402780">"已停用<xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
- <string name="dotted_app_label" msgid="1704091277755818896">"{count,plural,offset:1 =1{“{app_name}”有 # 条通知}other{“{app_name}”有 # 条通知}}"</string>
+ <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+ <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>,有 <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> 个通知</item>
+ <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g>,有 <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> 个通知</item>
+ </plurals>
<string name="default_scroll_format" msgid="7475544710230993317">"第%1$d页,共%2$d页"</string>
<string name="workspace_scroll_format" msgid="8458889198184077399">"主屏幕:第%1$d屏,共%2$d屏"</string>
<string name="workspace_new_page" msgid="257366611030256142">"主屏幕新页面"</string>
@@ -99,31 +77,31 @@
<string name="folder_tap_to_rename" msgid="4017685068016979677">"点按可保存新名称"</string>
<string name="folder_closed" msgid="4100806530910930934">"文件夹已关闭"</string>
<string name="folder_renamed" msgid="1794088362165669656">"已将文件夹重命名为“<xliff:g id="NAME">%1$s</xliff:g>”"</string>
- <string name="folder_name_format_exact" msgid="8626242716117004803">"文件夹:<xliff:g id="NAME">%1$s</xliff:g>,<xliff:g id="SIZE">%2$d</xliff:g> 个项目"</string>
- <string name="folder_name_format_overflow" msgid="4270108890534995199">"文件夹:<xliff:g id="NAME">%1$s</xliff:g>,<xliff:g id="SIZE">%2$d</xliff:g> 个或更多项目"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"文件夹:<xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"微件"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"壁纸"</string>
- <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"壁纸和样式"</string>
+ <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"样式和壁纸"</string>
<string name="settings_button_text" msgid="8873672322605444408">"主屏幕设置"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"已被您的管理员停用"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"允许旋转主屏幕"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"手机旋转时"</string>
<string name="notification_dots_title" msgid="9062440428204120317">"通知圆点"</string>
- <string name="notification_dots_desc_on" msgid="1679848116452218908">"已开启"</string>
- <string name="notification_dots_desc_off" msgid="1760796511504341095">"已关闭"</string>
+ <string name="notification_dots_desc_on" msgid="1679848116452218908">"开启"</string>
+ <string name="notification_dots_desc_off" msgid="1760796511504341095">"关闭"</string>
<string name="title_missing_notification_access" msgid="7503287056163941064">"需要获取通知使用权"</string>
<string name="msg_missing_notification_access" msgid="281113995110910548">"要显示通知圆点,请开启<xliff:g id="NAME">%1$s</xliff:g>的应用通知功能"</string>
<string name="title_change_settings" msgid="1376365968844349552">"更改设置"</string>
<string name="notification_dots_service_title" msgid="4284221181793592871">"显示通知圆点"</string>
- <string name="auto_add_shortcuts_label" msgid="3698776050751790653">"将应用图标添加到主屏幕"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"将图标添加到主屏幕"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"适用于新应用"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"未知"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"移除"</string>
<string name="abandoned_search" msgid="891119232568284442">"搜索"</string>
<string name="abandoned_promises_title" msgid="7096178467971716750">"未安装此应用"</string>
<string name="abandoned_promise_explanation" msgid="3990027586878167529">"未安装此图标对应的应用。您可以移除此图标,也可以尝试搜索相应的应用并手动安装。"</string>
- <string name="app_installing_title" msgid="5864044122733792085">"正在安装<xliff:g id="NAME">%1$s</xliff:g>,已完成 <xliff:g id="PROGRESS">%2$s</xliff:g>"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"正在下载<xliff:g id="NAME">%1$s</xliff:g>,已完成 <xliff:g id="PROGRESS">%2$s</xliff:g>"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g>正在等待安装"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"<xliff:g id="NAME">%1$s</xliff:g>微件"</string>
<string name="widgets_list" msgid="796804551140113767">"微件列表"</string>
<string name="widgets_list_closed" msgid="6141506579418771922">"微件列表已关闭"</string>
<string name="action_add_to_workspace" msgid="8902165848117513641">"添加到主屏幕"</string>
@@ -151,20 +129,15 @@
<string name="action_deep_shortcut" msgid="2864038805849372848">"快捷方式"</string>
<string name="shortcuts_menu_with_notifications_description" msgid="2676582286544232849">"快捷方式和通知"</string>
<string name="action_dismiss_notification" msgid="5909461085055959187">"关闭"</string>
- <string name="accessibility_close" msgid="2277148124685870734">"关闭"</string>
<string name="notification_dismissed" msgid="6002233469409822874">"已关闭通知"</string>
<string name="all_apps_personal_tab" msgid="4190252696685155002">"个人"</string>
<string name="all_apps_work_tab" msgid="4884822796154055118">"工作"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"工作资料"</string>
- <string name="work_profile_edu_work_apps" msgid="7895468576497746520">"工作应用带有标志,您的 IT 管理员可以看到此类应用"</string>
- <string name="work_profile_edu_accept" msgid="6069788082535149071">"知道了"</string>
- <string name="work_apps_paused_title" msgid="3040901117349444598">"工作应用已暂停"</string>
- <string name="work_apps_paused_body" msgid="261634750995824906">"工作应用无法向您发送通知、不能耗用电池电量,也无法获取您的位置信息"</string>
- <string name="work_apps_paused_content_description" msgid="5149623040804051095">"工作应用已关闭。工作应用无法向您发送通知、不能耗用电池电量,也无法获取您的位置信息"</string>
- <string name="work_apps_paused_edu_banner" msgid="8872412121608402058">"工作应用带有标志,您的 IT 管理员可以看到工作应用"</string>
- <string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"知道了"</string>
- <string name="work_apps_pause_btn_text" msgid="1921059713673767460">"关闭工作应用"</string>
- <string name="work_apps_enable_btn_text" msgid="1156432622148413741">"开启工作应用"</string>
- <string name="developer_options_filter_hint" msgid="5896817443635989056">"过滤器"</string>
+ <string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"请在此处查找工作应用"</string>
+ <string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"每个工作应用均有一个徽标,并由贵单位负责确保其安全。请将工作应用移到主屏幕,以便轻松访问。"</string>
+ <string name="work_mode_on_label" msgid="4781128097185272916">"由贵单位管理"</string>
+ <string name="work_mode_off_label" msgid="3194894777601421047">"通知和应用均已关闭"</string>
+ <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"关闭"</string>
+ <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"已关闭"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"失败:<xliff:g id="WHAT">%1$s</xliff:g>"</string>
</resources>
diff --git a/res/values-zh-rHK/strings.xml b/res/values-zh-rHK/strings.xml
index a278327f75..e7377440c1 100644
--- a/res/values-zh-rHK/strings.xml
+++ b/res/values-zh-rHK/strings.xml
@@ -20,63 +20,39 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="649227358658669779">"Launcher3"</string>
+ <string name="folder_name" msgid="7371454440695724752"></string>
<string name="work_folder_name" msgid="3753320833950115786">"工作"</string>
<string name="activity_not_found" msgid="8071924732094499514">"尚未安裝應用程式。"</string>
<string name="activity_not_available" msgid="7456344436509528827">"目前無法使用這個應用程式"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"在安全模式中無法使用「已下載的應用程式」功能"</string>
<string name="safemode_widget_error" msgid="4863470563535682004">"在安全模式中無法使用小工具"</string>
<string name="shortcut_not_available" msgid="2536503539825726397">"沒有可用的捷徑"</string>
- <string name="home_screen" msgid="5629429142036709174">"主畫面"</string>
- <string name="recent_task_option_split_screen" msgid="6690461455618725183">"分割螢幕"</string>
- <string name="split_screen_position_top" msgid="1504965011158689649">"頂部分割"</string>
- <string name="split_screen_position_left" msgid="7537793098851830883">"左側分割"</string>
- <string name="split_screen_position_right" msgid="1569377524925193369">"右側分割"</string>
- <string name="split_app_info_accessibility" msgid="5475288491241414932">"%1$s 的應用程式資料"</string>
- <string name="long_press_widget_to_add" msgid="3587712543577675817">"輕觸並按住即可移動小工具。"</string>
- <string name="long_accessible_way_to_add" msgid="2733588281439571974">"㩒兩下之後㩒住,就可以郁小工具或者用自訂操作。"</string>
+ <string name="home_screen" msgid="806512411299847073">"主畫面"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"自訂操作"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"輕觸並按住小工具即可選取。"</string>
+ <string name="long_accessible_way_to_add" msgid="4289502106628154155">"連扲兩下,然後扲住,就可以新增小工具,或者執行自訂操作。"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d 闊,%2$d 高"</string>
- <string name="widget_preview_context_description" msgid="9045841361655787574">"「<xliff:g id="WIDGET_NAME">%1$s</xliff:g>」小工具"</string>
- <string name="add_item_request_drag_hint" msgid="5653291305078645405">"按住小工具即可隨意在主畫面上移動"</string>
- <string name="add_to_home_screen" msgid="8631549138215492708">"新增至主畫面"</string>
- <string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"已經將「<xliff:g id="WIDGET_NAME">%1$s</xliff:g>」小工具加咗去主畫面"</string>
- <string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# 個小工具}other{# 個小工具}}"</string>
- <string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{# 個捷徑}other{# 個捷徑}}"</string>
- <string name="widgets_and_shortcuts_count" msgid="7209136747878365116">"<xliff:g id="WIDGETS_COUNT">%1$s</xliff:g>、<xliff:g id="SHORTCUTS_COUNT">%2$s</xliff:g>"</string>
- <string name="widget_button_text" msgid="2880537293434387943">"小工具"</string>
- <string name="widgets_full_sheet_search_bar_hint" msgid="8484659090860596457">"搜尋"</string>
- <string name="widgets_full_sheet_cancel_button_description" msgid="5766167035728653605">"清除搜尋框中的文字"</string>
- <string name="no_widgets_available" msgid="4337693382501046170">"無法使用小工具和捷徑"</string>
- <string name="no_search_results" msgid="3787956167293097509">"找不到小工具或捷徑"</string>
- <string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"個人"</string>
- <string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"工作"</string>
- <string name="widget_category_conversations" msgid="8894438636213590446">"對話"</string>
- <string name="widget_education_header" msgid="4874760613775913787">"實用資訊,唾手可得"</string>
- <string name="widget_education_content" msgid="745542879510751525">"將小工具新增到主畫面,不用開啟應用程式就可直接查看資訊"</string>
- <string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"輕按即可變更小工具設定"</string>
- <string name="widget_education_close_button" msgid="8676165703104836580">"知道了"</string>
- <string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"變更小工具設定"</string>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"按住即可手動新增"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"自動新增"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"搜尋應用程式"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"正在載入應用程式…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"找不到與「<xliff:g id="QUERY">%1$s</xliff:g>」相符的應用程式"</string>
<string name="all_apps_search_market_message" msgid="1366263386197059176">"搜尋更多應用程式"</string>
<string name="label_application" msgid="8531721983832654978">"應用程式"</string>
- <string name="all_apps_label" msgid="5015784846527570951">"所有應用程式"</string>
<string name="notifications_header" msgid="1404149926117359025">"通知"</string>
- <string name="long_press_shortcut_to_add" msgid="5405328730817637737">"輕觸並按住即可移動捷徑。"</string>
- <string name="long_accessible_way_to_add_shortcut" msgid="2199537273817090740">"㩒兩下之後㩒住,就可以郁捷徑或者用自訂操作。"</string>
- <string name="out_of_space" msgid="6692471482459245734">"這個主畫面沒有空間了"</string>
+ <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"按住捷徑即可選取。"</string>
+ <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"連㩒兩下之後繼續㩒住,就可以揀選捷徑或者用自訂嘅操作。"</string>
+ <string name="out_of_space" msgid="4691004494942118364">"主畫面已無空間。"</string>
<string name="hotseat_out_of_space" msgid="7448809638125333693">"我的收藏寄存區沒有足夠空間"</string>
<string name="all_apps_button_label" msgid="8130441508702294465">"應用程式清單"</string>
- <string name="all_apps_search_results" msgid="5889367432531296759">"搜尋結果"</string>
<string name="all_apps_button_personal_label" msgid="1315764287305224468">"個人應用程式清單"</string>
<string name="all_apps_button_work_label" msgid="7270707118948892488">"工作應用程式清單"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"主畫面"</string>
<string name="remove_drop_target_label" msgid="7812859488053230776">"移除"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"解除安裝"</string>
<string name="app_info_drop_target_label" msgid="692894985365717661">"應用程式資料"</string>
<string name="install_drop_target_label" msgid="2539096853673231757">"安裝"</string>
- <string name="dismiss_prediction_label" msgid="3357562989568808658">"不要提供應用程式建議"</string>
- <string name="pin_prediction" msgid="4196423321649756498">"固定預測"</string>
<string name="permlab_install_shortcut" msgid="5632423390354674437">"安裝捷徑"</string>
<string name="permdesc_install_shortcut" msgid="923466509822011139">"允許應用程式無需使用者許可也可新增捷徑。"</string>
<string name="permlab_read_settings" msgid="1941457408239617576">"讀取主畫面的設定和捷徑"</string>
@@ -84,13 +60,15 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"寫入主畫面的設定和捷徑"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"允許應用程式更改主畫面中的設定和捷徑。"</string>
<string name="msg_no_phone_permission" msgid="9208659281529857371">"不允許 <xliff:g id="APP_NAME">%1$s</xliff:g> 撥打電話"</string>
- <string name="gadget_error_text" msgid="740356548025791839">"無法載入小工具"</string>
- <string name="gadget_setup_text" msgid="8348374825537681407">"小工具設定"</string>
- <string name="gadget_complete_setup_text" msgid="309040266978007925">"輕按即可完成設定"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"載入小工具時發生問題"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"設定"</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"這是系統應用程式,無法將其解除安裝。"</string>
- <string name="folder_hint_text" msgid="5174843001373488816">"編輯名稱"</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"未命名的資料夾"</string>
<string name="disabled_app_label" msgid="6673129024321402780">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」已停用"</string>
- <string name="dotted_app_label" msgid="1704091277755818896">"{count,plural,offset:1 =1{「{app_name}」有 # 項通知}other{「{app_name}」有 # 項通知}}"</string>
+ <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+ <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>,有 <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> 項通知</item>
+ <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g>,有 <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> 項通知</item>
+ </plurals>
<string name="default_scroll_format" msgid="7475544710230993317">"第 %1$d 頁,共 %2$d 頁"</string>
<string name="workspace_scroll_format" msgid="8458889198184077399">"主畫面 %1$d,共 %2$d 個"</string>
<string name="workspace_new_page" msgid="257366611030256142">"新主畫面頁面"</string>
@@ -99,10 +77,10 @@
<string name="folder_tap_to_rename" msgid="4017685068016979677">"輕按即可儲存新名稱"</string>
<string name="folder_closed" msgid="4100806530910930934">"已關閉資料夾"</string>
<string name="folder_renamed" msgid="1794088362165669656">"資料夾已重新命名為「<xliff:g id="NAME">%1$s</xliff:g>」"</string>
- <string name="folder_name_format_exact" msgid="8626242716117004803">"資料夾:<xliff:g id="NAME">%1$s</xliff:g>,<xliff:g id="SIZE">%2$d</xliff:g> 個項目"</string>
- <string name="folder_name_format_overflow" msgid="4270108890534995199">"資料夾:<xliff:g id="NAME">%1$s</xliff:g>,<xliff:g id="SIZE">%2$d</xliff:g> 個或以上的項目"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"資料夾:<xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"小工具"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"桌布"</string>
- <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"桌布和樣式"</string>
+ <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"樣式和桌布"</string>
<string name="settings_button_text" msgid="8873672322605444408">"主畫面設定"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"已由您的管理員停用"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"允許主畫面旋轉"</string>
@@ -114,16 +92,16 @@
<string name="msg_missing_notification_access" msgid="281113995110910548">"如要顯示「通知圓點」,請開啟「<xliff:g id="NAME">%1$s</xliff:g>」的應用程式通知功能"</string>
<string name="title_change_settings" msgid="1376365968844349552">"變更設定"</string>
<string name="notification_dots_service_title" msgid="4284221181793592871">"顯示通知圓點"</string>
- <string name="auto_add_shortcuts_label" msgid="3698776050751790653">"將應用程式圖示新增至主畫面"</string>
- <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"新安裝的應用程式"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"將圖示加到主畫面"</string>
+ <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"適用於新安裝的應用程式"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"不明"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"移除"</string>
<string name="abandoned_search" msgid="891119232568284442">"搜尋"</string>
<string name="abandoned_promises_title" msgid="7096178467971716750">"尚未安裝這個應用程式"</string>
<string name="abandoned_promise_explanation" msgid="3990027586878167529">"您尚未安裝這個圖示代表的應用程式。您可以移除這個圖示,也可以搜尋該應用程式並手動安裝。"</string>
- <string name="app_installing_title" msgid="5864044122733792085">"正在安裝「<xliff:g id="NAME">%1$s</xliff:g>」(已完成 <xliff:g id="PROGRESS">%2$s</xliff:g>)"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"正在下載 <xliff:g id="NAME">%1$s</xliff:g>,已完成 <xliff:g id="PROGRESS">%2$s</xliff:g>"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"正在等待安裝 <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"<xliff:g id="NAME">%1$s</xliff:g>小工具"</string>
<string name="widgets_list" msgid="796804551140113767">"小工具清單"</string>
<string name="widgets_list_closed" msgid="6141506579418771922">"已經關閉嘅小工具清單"</string>
<string name="action_add_to_workspace" msgid="8902165848117513641">"新增至主畫面"</string>
@@ -151,20 +129,15 @@
<string name="action_deep_shortcut" msgid="2864038805849372848">"捷徑"</string>
<string name="shortcuts_menu_with_notifications_description" msgid="2676582286544232849">"捷徑同通知"</string>
<string name="action_dismiss_notification" msgid="5909461085055959187">"關閉"</string>
- <string name="accessibility_close" msgid="2277148124685870734">"關閉"</string>
<string name="notification_dismissed" msgid="6002233469409822874">"關閉咗通知"</string>
<string name="all_apps_personal_tab" msgid="4190252696685155002">"個人"</string>
- <string name="all_apps_work_tab" msgid="4884822796154055118">"工作"</string>
+ <string name="all_apps_work_tab" msgid="4884822796154055118">"商務"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"工作設定檔"</string>
- <string name="work_profile_edu_work_apps" msgid="7895468576497746520">"工作應用程式均加有標誌。您的 IT 管理員可以看到這些應用程式"</string>
- <string name="work_profile_edu_accept" msgid="6069788082535149071">"知道了"</string>
- <string name="work_apps_paused_title" msgid="3040901117349444598">"已暫停工作應用程式"</string>
- <string name="work_apps_paused_body" msgid="261634750995824906">"工作應用程式無法向您傳送通知、使用電池電量或存取您的位置"</string>
- <string name="work_apps_paused_content_description" msgid="5149623040804051095">"已暫停工作應用程式。工作應用程式無法向您傳送通知、使用電池電量或存取您的位置"</string>
- <string name="work_apps_paused_edu_banner" msgid="8872412121608402058">"工作應用程式均加有標誌。您的 IT 管理員可以看到這些應用程式"</string>
- <string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"知道了"</string>
- <string name="work_apps_pause_btn_text" msgid="1921059713673767460">"關閉工作應用程式"</string>
- <string name="work_apps_enable_btn_text" msgid="1156432622148413741">"開啟工作應用程式"</string>
- <string name="developer_options_filter_hint" msgid="5896817443635989056">"篩選器"</string>
+ <string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"請在此處尋找工作應用程式"</string>
+ <string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"每個工作應用程式都有一個徽章,並由您的機構負責保持安全。您可以將工作應用程式移至主畫面,以便輕鬆存取。"</string>
+ <string name="work_mode_on_label" msgid="4781128097185272916">"由您的機構管理"</string>
+ <string name="work_mode_off_label" msgid="3194894777601421047">"通知和應用程式已關閉"</string>
+ <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"關閉"</string>
+ <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"已關閉"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"操作失敗:<xliff:g id="WHAT">%1$s</xliff:g>"</string>
</resources>
diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml
index a2cfcc780e..e971b69f1f 100644
--- a/res/values-zh-rTW/strings.xml
+++ b/res/values-zh-rTW/strings.xml
@@ -20,92 +20,70 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="649227358658669779">"Launcher3"</string>
+ <string name="folder_name" msgid="7371454440695724752"></string>
<string name="work_folder_name" msgid="3753320833950115786">"公司"</string>
<string name="activity_not_found" msgid="8071924732094499514">"應用程式未安裝。"</string>
<string name="activity_not_available" msgid="7456344436509528827">"應用程式目前無法使用"</string>
<string name="safemode_shortcut_error" msgid="9160126848219158407">"在安全模式中無法使用「已下載的應用程式」功能"</string>
<string name="safemode_widget_error" msgid="4863470563535682004">"在安全模式下無法使用小工具"</string>
<string name="shortcut_not_available" msgid="2536503539825726397">"目前無法使用捷徑"</string>
- <string name="home_screen" msgid="5629429142036709174">"主畫面"</string>
- <string name="recent_task_option_split_screen" msgid="6690461455618725183">"分割畫面"</string>
- <string name="split_screen_position_top" msgid="1504965011158689649">"分割上方畫面"</string>
- <string name="split_screen_position_left" msgid="7537793098851830883">"分割左側畫面"</string>
- <string name="split_screen_position_right" msgid="1569377524925193369">"分割右側畫面"</string>
- <string name="split_app_info_accessibility" msgid="5475288491241414932">"「%1$s」的應用程式資訊"</string>
- <string name="long_press_widget_to_add" msgid="3587712543577675817">"按住即可移動小工具。"</string>
- <string name="long_accessible_way_to_add" msgid="2733588281439571974">"輕觸兩下並按住即可移動小工具或使用自訂操作。"</string>
+ <string name="home_screen" msgid="806512411299847073">"主螢幕"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"自訂動作"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"輕觸並按住小工具即可選取。"</string>
+ <string name="long_accessible_way_to_add" msgid="4289502106628154155">"輕觸兩下並按住小工具即可選取,你也可以使用自訂動作。"</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"寬度為 %1$d,高度為 %2$d"</string>
- <string name="widget_preview_context_description" msgid="9045841361655787574">"「<xliff:g id="WIDGET_NAME">%1$s</xliff:g>」小工具"</string>
- <string name="add_item_request_drag_hint" msgid="5653291305078645405">"按住小工具即可將它拖放到主畫面上的任何位置"</string>
- <string name="add_to_home_screen" msgid="8631549138215492708">"新增到主畫面"</string>
- <string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"已將「<xliff:g id="WIDGET_NAME">%1$s</xliff:g>」小工具新增到主畫面"</string>
- <string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# 項小工具}other{# 項小工具}}"</string>
- <string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{# 個捷徑}other{# 個捷徑}}"</string>
- <string name="widgets_and_shortcuts_count" msgid="7209136747878365116">"<xliff:g id="WIDGETS_COUNT">%1$s</xliff:g>、<xliff:g id="SHORTCUTS_COUNT">%2$s</xliff:g>"</string>
- <string name="widget_button_text" msgid="2880537293434387943">"小工具"</string>
- <string name="widgets_full_sheet_search_bar_hint" msgid="8484659090860596457">"搜尋"</string>
- <string name="widgets_full_sheet_cancel_button_description" msgid="5766167035728653605">"清除搜尋框中的文字"</string>
- <string name="no_widgets_available" msgid="4337693382501046170">"無法使用小工具和捷徑"</string>
- <string name="no_search_results" msgid="3787956167293097509">"找不到小工具或捷徑"</string>
- <string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"個人"</string>
- <string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"工作"</string>
- <string name="widget_category_conversations" msgid="8894438636213590446">"對話"</string>
- <string name="widget_education_header" msgid="4874760613775913787">"實用資訊隨手可得"</string>
- <string name="widget_education_content" msgid="745542879510751525">"只要將小工具新增到主畫面,就可以直接查看資訊,不必開啟應用程式"</string>
- <string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"輕觸即可變更小工具設定"</string>
- <string name="widget_education_close_button" msgid="8676165703104836580">"我知道了"</string>
- <string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"變更小工具設定"</string>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"按住圖示即可手動新增"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"自動新增"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"搜尋應用程式"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"正在載入應用程式…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"找不到與「<xliff:g id="QUERY">%1$s</xliff:g>」相符的應用程式"</string>
<string name="all_apps_search_market_message" msgid="1366263386197059176">"搜尋更多應用程式"</string>
<string name="label_application" msgid="8531721983832654978">"應用程式"</string>
- <string name="all_apps_label" msgid="5015784846527570951">"所有應用程式"</string>
<string name="notifications_header" msgid="1404149926117359025">"通知"</string>
- <string name="long_press_shortcut_to_add" msgid="5405328730817637737">"按住即可移動捷徑。"</string>
- <string name="long_accessible_way_to_add_shortcut" msgid="2199537273817090740">"輕觸兩下並按住即可移動捷徑或使用自訂操作。"</string>
- <string name="out_of_space" msgid="6692471482459245734">"這個主畫面已無空間"</string>
+ <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"按住捷徑即可選取。"</string>
+ <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"輕觸兩下並按住捷徑即可選取,你也可以使用自訂動作。"</string>
+ <string name="out_of_space" msgid="4691004494942118364">"這個主螢幕已無空間。"</string>
<string name="hotseat_out_of_space" msgid="7448809638125333693">"「我的最愛」匣已無可用空間"</string>
<string name="all_apps_button_label" msgid="8130441508702294465">"應用程式清單"</string>
- <string name="all_apps_search_results" msgid="5889367432531296759">"搜尋結果"</string>
<string name="all_apps_button_personal_label" msgid="1315764287305224468">"個人應用程式清單"</string>
<string name="all_apps_button_work_label" msgid="7270707118948892488">"辦公應用程式清單"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"主螢幕"</string>
<string name="remove_drop_target_label" msgid="7812859488053230776">"移除"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"解除安裝"</string>
<string name="app_info_drop_target_label" msgid="692894985365717661">"應用程式資訊"</string>
<string name="install_drop_target_label" msgid="2539096853673231757">"安裝"</string>
- <string name="dismiss_prediction_label" msgid="3357562989568808658">"不要提供應用程式建議"</string>
- <string name="pin_prediction" msgid="4196423321649756498">"固定預測的應用程式"</string>
<string name="permlab_install_shortcut" msgid="5632423390354674437">"安裝捷徑"</string>
<string name="permdesc_install_shortcut" msgid="923466509822011139">"允許應用程式自動新增捷徑。"</string>
- <string name="permlab_read_settings" msgid="1941457408239617576">"讀取主畫面的設定和捷徑"</string>
- <string name="permdesc_read_settings" msgid="5833423719057558387">"允許應用程式讀取主畫面中的設定和捷徑。"</string>
- <string name="permlab_write_settings" msgid="3574213698004620587">"寫入主畫面設定和捷徑"</string>
- <string name="permdesc_write_settings" msgid="5440712911516509985">"允許應用程式變更主畫面中的設定和捷徑。"</string>
+ <string name="permlab_read_settings" msgid="1941457408239617576">"讀取主螢幕的設定和捷徑"</string>
+ <string name="permdesc_read_settings" msgid="5833423719057558387">"允許應用程式讀取主螢幕中的設定和捷徑。"</string>
+ <string name="permlab_write_settings" msgid="3574213698004620587">"寫入主螢幕設定和捷徑"</string>
+ <string name="permdesc_write_settings" msgid="5440712911516509985">"允許應用程式變更主螢幕中的設定和捷徑。"</string>
<string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> 無法撥打電話"</string>
- <string name="gadget_error_text" msgid="740356548025791839">"無法載入小工具"</string>
- <string name="gadget_setup_text" msgid="8348374825537681407">"小工具設定"</string>
- <string name="gadget_complete_setup_text" msgid="309040266978007925">"輕觸即可完成設定"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"載入小工具時發生問題"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"設定"</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"這是系統應用程式,不可解除安裝。"</string>
- <string name="folder_hint_text" msgid="5174843001373488816">"編輯名稱"</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"未命名的資料夾"</string>
<string name="disabled_app_label" msgid="6673129024321402780">"已停用 <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
- <string name="dotted_app_label" msgid="1704091277755818896">"{count,plural,offset:1 =1{「{app_name}」有 # 則通知}other{「{app_name}」有 # 則通知}}"</string>
+ <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+ <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>,有 <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> 則通知</item>
+ <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g>,有 <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> 則通知</item>
+ </plurals>
<string name="default_scroll_format" msgid="7475544710230993317">"第 %1$d 頁,共 %2$d 頁"</string>
- <string name="workspace_scroll_format" msgid="8458889198184077399">"主畫面:第 %1$d 頁,共 %2$d 頁"</string>
+ <string name="workspace_scroll_format" msgid="8458889198184077399">"主螢幕:第 %1$d 頁,共 %2$d 頁"</string>
<string name="workspace_new_page" msgid="257366611030256142">"新的主畫面頁面"</string>
<string name="folder_opened" msgid="94695026776264709">"資料夾已開啟 (<xliff:g id="WIDTH">%1$d</xliff:g> x <xliff:g id="HEIGHT">%2$d</xliff:g>)"</string>
<string name="folder_tap_to_close" msgid="4625795376335528256">"輕觸即可關閉資料夾"</string>
<string name="folder_tap_to_rename" msgid="4017685068016979677">"輕觸即可儲存新名稱"</string>
<string name="folder_closed" msgid="4100806530910930934">"資料夾已關閉"</string>
<string name="folder_renamed" msgid="1794088362165669656">"已將資料夾重新命名為「<xliff:g id="NAME">%1$s</xliff:g>」"</string>
- <string name="folder_name_format_exact" msgid="8626242716117004803">"資料夾:<xliff:g id="NAME">%1$s</xliff:g>,<xliff:g id="SIZE">%2$d</xliff:g> 個項目"</string>
- <string name="folder_name_format_overflow" msgid="4270108890534995199">"資料夾:<xliff:g id="NAME">%1$s</xliff:g>,<xliff:g id="SIZE">%2$d</xliff:g> 個以上的項目"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"資料夾:<xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"小工具"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"桌布"</string>
- <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"桌布和樣式"</string>
- <string name="settings_button_text" msgid="8873672322605444408">"主畫面設定"</string>
+ <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"樣式和桌布"</string>
+ <string name="settings_button_text" msgid="8873672322605444408">"主螢幕設定"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"已由你的管理員停用"</string>
- <string name="allow_rotation_title" msgid="7728578836261442095">"允許旋轉主畫面"</string>
+ <string name="allow_rotation_title" msgid="7728578836261442095">"允許旋轉主螢幕"</string>
<string name="allow_rotation_desc" msgid="8662546029078692509">"當手機旋轉時"</string>
<string name="notification_dots_title" msgid="9062440428204120317">"通知圓點"</string>
<string name="notification_dots_desc_on" msgid="1679848116452218908">"開啟"</string>
@@ -114,16 +92,16 @@
<string name="msg_missing_notification_access" msgid="281113995110910548">"如要顯示通知圓點,請開啟「<xliff:g id="NAME">%1$s</xliff:g>」的應用程式通知功能"</string>
<string name="title_change_settings" msgid="1376365968844349552">"變更設定"</string>
<string name="notification_dots_service_title" msgid="4284221181793592871">"顯示通知圓點"</string>
- <string name="auto_add_shortcuts_label" msgid="3698776050751790653">"將應用程式圖示加到主畫面"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"將圖示加到主螢幕"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"適用於新安裝的應用程式"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"不明"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"移除"</string>
<string name="abandoned_search" msgid="891119232568284442">"搜尋"</string>
<string name="abandoned_promises_title" msgid="7096178467971716750">"尚未安裝這個應用程式"</string>
<string name="abandoned_promise_explanation" msgid="3990027586878167529">"你尚未安裝這個圖示代表的應用程式。你可以移除這個圖示,也可以搜尋該應用程式並手動安裝。"</string>
- <string name="app_installing_title" msgid="5864044122733792085">"正在安裝「<xliff:g id="NAME">%1$s</xliff:g>」(已完成 <xliff:g id="PROGRESS">%2$s</xliff:g>)"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"正在下載「<xliff:g id="NAME">%1$s</xliff:g>」,已完成 <xliff:g id="PROGRESS">%2$s</xliff:g>"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"正在等待安裝「<xliff:g id="NAME">%1$s</xliff:g>」"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"「<xliff:g id="NAME">%1$s</xliff:g>」小工具"</string>
<string name="widgets_list" msgid="796804551140113767">"小工具清單"</string>
<string name="widgets_list_closed" msgid="6141506579418771922">"已關閉小工具清單"</string>
<string name="action_add_to_workspace" msgid="8902165848117513641">"新增至主畫面"</string>
@@ -151,20 +129,15 @@
<string name="action_deep_shortcut" msgid="2864038805849372848">"捷徑"</string>
<string name="shortcuts_menu_with_notifications_description" msgid="2676582286544232849">"捷徑和通知"</string>
<string name="action_dismiss_notification" msgid="5909461085055959187">"關閉"</string>
- <string name="accessibility_close" msgid="2277148124685870734">"關閉"</string>
<string name="notification_dismissed" msgid="6002233469409822874">"已關閉通知"</string>
<string name="all_apps_personal_tab" msgid="4190252696685155002">"個人"</string>
- <string name="all_apps_work_tab" msgid="4884822796154055118">"工作"</string>
+ <string name="all_apps_work_tab" msgid="4884822796154055118">"公司"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"工作資料夾"</string>
- <string name="work_profile_edu_work_apps" msgid="7895468576497746520">"工作應用程式會加上標記,且你的 IT 管理員可以看到這類應用程式"</string>
- <string name="work_profile_edu_accept" msgid="6069788082535149071">"我知道了"</string>
- <string name="work_apps_paused_title" msgid="3040901117349444598">"系統已暫停工作應用程式"</string>
- <string name="work_apps_paused_body" msgid="261634750995824906">"工作應用程式不會消耗電量、無法傳送通知,也無法存取你的位置資訊"</string>
- <string name="work_apps_paused_content_description" msgid="5149623040804051095">"工作應用程式已關閉。工作應用程式不會消耗電量、無法傳送通知,也無法存取你的位置資訊"</string>
- <string name="work_apps_paused_edu_banner" msgid="8872412121608402058">"工作應用程式會加上標記,且你的 IT 管理員可以看到這類應用程式"</string>
- <string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"我知道了"</string>
- <string name="work_apps_pause_btn_text" msgid="1921059713673767460">"關閉工作應用程式"</string>
- <string name="work_apps_enable_btn_text" msgid="1156432622148413741">"開啟工作應用程式"</string>
- <string name="developer_options_filter_hint" msgid="5896817443635989056">"篩選器"</string>
+ <string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"在這裡尋找辦公應用程式"</string>
+ <string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"每個辦公應用程式都有徽章,並由貴機構負責管理及確保其安全。請將辦公應用程式移至主螢幕以便輕鬆存取。"</string>
+ <string name="work_mode_on_label" msgid="4781128097185272916">"由貴機構所管理"</string>
+ <string name="work_mode_off_label" msgid="3194894777601421047">"已關閉通知和應用程式"</string>
+ <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"關閉"</string>
+ <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"已關閉"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"失敗:<xliff:g id="WHAT">%1$s</xliff:g>"</string>
</resources>
diff --git a/res/values-zu/strings.xml b/res/values-zu/strings.xml
index ca0176940f..b937764ace 100644
--- a/res/values-zu/strings.xml
+++ b/res/values-zu/strings.xml
@@ -26,57 +26,32 @@
<string name="safemode_shortcut_error" msgid="9160126848219158407">"Uhlelo lokusebenza olulandiwe lukhutshaziwe kumodi ephephile"</string>
<string name="safemode_widget_error" msgid="4863470563535682004">"Amawijethi akhutshaziwe kwimodi yokuphepha"</string>
<string name="shortcut_not_available" msgid="2536503539825726397">"Isinqamuleli asitholakali"</string>
- <string name="home_screen" msgid="5629429142036709174">"Ikhaya"</string>
- <string name="recent_task_option_split_screen" msgid="6690461455618725183">"Hlukanisa isikrini"</string>
- <string name="split_screen_position_top" msgid="1504965011158689649">"Hlukanisa phezulu"</string>
- <string name="split_screen_position_left" msgid="7537793098851830883">"Hlukanisa ngakwesobunxele"</string>
- <string name="split_screen_position_right" msgid="1569377524925193369">"Hlukanisa ngakwesokudla"</string>
- <string name="split_app_info_accessibility" msgid="5475288491241414932">"Ulwazi lwe-App ye-%1$s"</string>
- <string name="long_press_widget_to_add" msgid="3587712543577675817">"Thinta uphinde ubambe ukuze uhambise iwijethi."</string>
- <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Thepha kabili uphinde ubambe ukuze uhambise iwijethi noma usebenzise izindlela ezingokwezifiso."</string>
+ <string name="home_screen" msgid="806512411299847073">"Isikrini sasekhaya"</string>
+ <string name="custom_actions" msgid="3747508247759093328">"Izenzo zangokwezifiso"</string>
+ <string name="long_press_widget_to_add" msgid="7699152356777458215">"Thinta uphinde ubambe ukuze uphakamise iwijethi."</string>
+ <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Thepha kabili bese uyabamba ukuze uthathe iwijethi noma sebenzisa izenzo ezingokwezifiso."</string>
<string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d ububanzi ngokungu-%2$d ukuya phezulu"</string>
- <string name="widget_preview_context_description" msgid="9045841361655787574">"Iwijethi elingu-<xliff:g id="WIDGET_NAME">%1$s</xliff:g>"</string>
- <string name="add_item_request_drag_hint" msgid="5653291305078645405">"Thinta uphinde ubambe iwijethi ukuyihambisa Kusikrini sasekhaya"</string>
- <string name="add_to_home_screen" msgid="8631549138215492708">"Engeza kusikrini sasekhaya"</string>
- <string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"Iwijethi ye-<xliff:g id="WIDGET_NAME">%1$s</xliff:g> yengezwe kusikrini sasekhaya"</string>
- <string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{iwijethi #}one{amawijethi #}other{amawijethi #}}"</string>
- <string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{isinqamuleli #}one{izinqamuleli #}other{izinqamuleli #}}"</string>
- <string name="widgets_and_shortcuts_count" msgid="7209136747878365116">"<xliff:g id="WIDGETS_COUNT">%1$s</xliff:g>, <xliff:g id="SHORTCUTS_COUNT">%2$s</xliff:g>"</string>
- <string name="widget_button_text" msgid="2880537293434387943">"Amawijethi"</string>
- <string name="widgets_full_sheet_search_bar_hint" msgid="8484659090860596457">"Sesha"</string>
- <string name="widgets_full_sheet_cancel_button_description" msgid="5766167035728653605">"Sula umbhalo ovela ebhokisini lokusesha"</string>
- <string name="no_widgets_available" msgid="4337693382501046170">"Amawijethi nezinqamuleli akutholakali"</string>
- <string name="no_search_results" msgid="3787956167293097509">"Awekho amajiwethi noma izinqamuleli ezitholakele"</string>
- <string name="widgets_full_sheet_personal_tab" msgid="2743540105607120182">"Okwabantu siqu"</string>
- <string name="widgets_full_sheet_work_tab" msgid="3767150027110633765">"Umsebenzi"</string>
- <string name="widget_category_conversations" msgid="8894438636213590446">"Izingxoxo"</string>
- <string name="widget_education_header" msgid="4874760613775913787">"Ulwazi oluwusizo phambi nje kwakho"</string>
- <string name="widget_education_content" msgid="745542879510751525">"Ukuze utholeulwazi ngaphandle kokuvula ama-app, ungakwazi ukwengeza amawijethi kusikrini sakho sasekhaya"</string>
- <string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"Thepha ukuze ushintshe amasethingi ewijethi"</string>
- <string name="widget_education_close_button" msgid="8676165703104836580">"Ngiyezwa"</string>
- <string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"Shintsha amasethingi ewijethi"</string>
+ <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Thinta futhi ubambe ukuze ubeke ngokwenza"</string>
+ <string name="place_automatically" msgid="8064208734425456485">"Engeza ngokuzenzakalelayo"</string>
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Sesha izinhlelo zokusebenza"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Ilayisha izinhlelo zokusebenza..."</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"Azikho izinhlelo zokusebenza ezitholiwe ezifana ne-\"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
<string name="all_apps_search_market_message" msgid="1366263386197059176">"Sesha izinhlelo zokusebenza eziningi"</string>
<string name="label_application" msgid="8531721983832654978">"Uhlelo lokusebenza"</string>
- <string name="all_apps_label" msgid="5015784846527570951">"Zonke izinhlelo zokusebenza"</string>
<string name="notifications_header" msgid="1404149926117359025">"Izaziso"</string>
- <string name="long_press_shortcut_to_add" msgid="5405328730817637737">"Thinta uphinde ubambe ukuze uhambise isinqamuleli."</string>
- <string name="long_accessible_way_to_add_shortcut" msgid="2199537273817090740">"Thepha kabili uphinde ubambe ukuze uhambise isinqamuleli noma usebenzise izenzo ezingokwezifiso."</string>
- <string name="out_of_space" msgid="6692471482459245734">"Asikho isikhala kulesi sikrini sasekhaya"</string>
+ <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"Thinta futhi ubambe ukuze ukhethe isinqamuleli."</string>
+ <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"Thepha kabili uphinde ubambe ukuze uphakamise isinqamuleli noma usebenzise izenzo zangokwezifiso."</string>
+ <string name="out_of_space" msgid="4691004494942118364">"Asisekho isikhala kulesi sikrini Sasekhaya."</string>
<string name="hotseat_out_of_space" msgid="7448809638125333693">"Asisekho isikhala kwitreyi lezintandokazi"</string>
<string name="all_apps_button_label" msgid="8130441508702294465">"Uhlu lwezinhlelo zokusebenza"</string>
- <string name="all_apps_search_results" msgid="5889367432531296759">"Imiphumela yosesho"</string>
<string name="all_apps_button_personal_label" msgid="1315764287305224468">"Uhlu lwezinhlelo zokusebenza zomuntu siqu"</string>
<string name="all_apps_button_work_label" msgid="7270707118948892488">"Uhlu lwezinhlelo zokusebenza zomsebenzi"</string>
+ <string name="all_apps_home_button_label" msgid="252062713717058851">"Ikhaya"</string>
<string name="remove_drop_target_label" msgid="7812859488053230776">"Susa"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"Khipha"</string>
- <string name="app_info_drop_target_label" msgid="692894985365717661">"Ulwazi nge-app"</string>
+ <string name="app_info_drop_target_label" msgid="692894985365717661">"Ulwazi lohlelo lokusebenza"</string>
<string name="install_drop_target_label" msgid="2539096853673231757">"Faka"</string>
- <string name="dismiss_prediction_label" msgid="3357562989568808658">"Ungaphakamisi uhlelo lokusebenza"</string>
- <string name="pin_prediction" msgid="4196423321649756498">"Ukubikezela Iphinikhodi"</string>
<string name="permlab_install_shortcut" msgid="5632423390354674437">"faka izinqamuleli"</string>
<string name="permdesc_install_shortcut" msgid="923466509822011139">"Ivumela uhlelo lokusebenza ukufaka izinqamuleli ngaphandle kokungenelela komsebenzisi."</string>
<string name="permlab_read_settings" msgid="1941457408239617576">"funda izilungiselelo zokuthi Ikhaya nezinqamuleli"</string>
@@ -84,13 +59,15 @@
<string name="permlab_write_settings" msgid="3574213698004620587">"bhala izilungiselelo zokuthi Ikhaya nezinqamuleli"</string>
<string name="permdesc_write_settings" msgid="5440712911516509985">"Ivumela uhlelo lokusebenza ukuthi lushintshe izilungiselelo nezinqamuleli Ekhaya."</string>
<string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> ayivunyelwe ukwenza amakholi wefoni"</string>
- <string name="gadget_error_text" msgid="740356548025791839">"Ayikwazi ukulayisha iwijethi"</string>
- <string name="gadget_setup_text" msgid="8348374825537681407">"Amasethingi ewijethi"</string>
- <string name="gadget_complete_setup_text" msgid="309040266978007925">"Thepha ukuze uqede ukusetha"</string>
+ <string name="gadget_error_text" msgid="6081085226050792095">"Inkinga yokulayisha iwijethi"</string>
+ <string name="gadget_setup_text" msgid="8274003207686040488">"Ukumisa"</string>
<string name="uninstall_system_app_text" msgid="4172046090762920660">"Lolu uhlelo lokusebenza lwesistimu futhi alikwazi ukukhishwa."</string>
- <string name="folder_hint_text" msgid="5174843001373488816">"Hlela igama"</string>
+ <string name="folder_hint_text" msgid="6617836969016293992">"Ifolda engenagama"</string>
<string name="disabled_app_label" msgid="6673129024321402780">"Kukhutshaziwe <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
- <string name="dotted_app_label" msgid="1704091277755818896">"{count,plural,offset:1 =1{I-{app_name}, inesaziso esingu-#}one{I-{app_name}, inezaziso ezingu-#}other{I-{app_name}, inezaziso ezingu-#}}"</string>
+ <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+ <item quantity="one"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, unezaziso ezingu-<xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g></item>
+ <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, unezaziso ezingu-<xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g></item>
+ </plurals>
<string name="default_scroll_format" msgid="7475544710230993317">"Ikhasi elingu-%1$d kwangu-%2$d"</string>
<string name="workspace_scroll_format" msgid="8458889198184077399">"Isikrini sasekhaya esingu-%1$d se-%2$d"</string>
<string name="workspace_new_page" msgid="257366611030256142">"Ikhasi elisha lesikrini sasekhaya"</string>
@@ -99,10 +76,10 @@
<string name="folder_tap_to_rename" msgid="4017685068016979677">"Thepha ukuze ulondoloze ukuqamba kabusha"</string>
<string name="folder_closed" msgid="4100806530910930934">"Ifolda ivaliwe"</string>
<string name="folder_renamed" msgid="1794088362165669656">"Ifolda iqanjwe kabusha ngo-<xliff:g id="NAME">%1$s</xliff:g>"</string>
- <string name="folder_name_format_exact" msgid="8626242716117004803">"Ifolda: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> izinto"</string>
- <string name="folder_name_format_overflow" msgid="4270108890534995199">"Ifolda: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> noma izinto eziningi"</string>
+ <string name="folder_name_format" msgid="6629239338071103179">"Ifolda: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="widget_button_text" msgid="2880537293434387943">"Amawijethi"</string>
<string name="wallpaper_button_text" msgid="8404103075899945851">"Izithombe zangemuva"</string>
- <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Isithombe sangemuva nesitayela"</string>
+ <string name="styles_wallpaper_button_text" msgid="4342122323125579619">"Izitayela nezithombe zangemuva"</string>
<string name="settings_button_text" msgid="8873672322605444408">"Izilungiselelo zasekhaya"</string>
<string name="msg_disabled_by_admin" msgid="6898038085516271325">"Kukhutshazwe umlawuli wakho"</string>
<string name="allow_rotation_title" msgid="7728578836261442095">"Vumela ukuphendukiswa kwesikrini sasekhaya"</string>
@@ -114,16 +91,16 @@
<string name="msg_missing_notification_access" msgid="281113995110910548">"Ukuze ubonisa amcashazi esaziso, vula izaziso zohlelo lokusebenza ze-<xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="title_change_settings" msgid="1376365968844349552">"Shintsha izilungiselelo"</string>
<string name="notification_dots_service_title" msgid="4284221181793592871">"Bonisa amacashazi esaziso"</string>
- <string name="auto_add_shortcuts_label" msgid="3698776050751790653">"Engeza izithonjana zohlelo lokusebenza kusikrini sasekhaya"</string>
+ <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Engeza isithonjana eskrinini sasekhaya"</string>
<string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Kwezinhlelo zokusebenza ezintsha"</string>
<string name="package_state_unknown" msgid="7592128424511031410">"Akwaziwa"</string>
<string name="abandoned_clean_this" msgid="7610119707847920412">"Susa"</string>
<string name="abandoned_search" msgid="891119232568284442">"Sesha"</string>
<string name="abandoned_promises_title" msgid="7096178467971716750">"Lolu hlelo lokusebenza alifakiwe"</string>
<string name="abandoned_promise_explanation" msgid="3990027586878167529">"Uhlelo lokusebenza lalesi sithonjana alufakiwe. Ungalisusa, noma sesha uhlelo lokusebenza bese uzifakela lona ngokuzenzela."</string>
- <string name="app_installing_title" msgid="5864044122733792085">"I-<xliff:g id="NAME">%1$s</xliff:g> iyafakwa, seyiqede <xliff:g id="PROGRESS">%2$s</xliff:g>"</string>
<string name="app_downloading_title" msgid="8336702962104482644">"I-<xliff:g id="NAME">%1$s</xliff:g> iyalandwa, <xliff:g id="PROGRESS">%2$s</xliff:g> kuqediwe"</string>
<string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> ilinde ukufakwa"</string>
+ <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"<xliff:g id="NAME">%1$s</xliff:g> amawijethi"</string>
<string name="widgets_list" msgid="796804551140113767">"Uhlu lwamawijethi"</string>
<string name="widgets_list_closed" msgid="6141506579418771922">"Uhlu lwamawijethi luvaliwe"</string>
<string name="action_add_to_workspace" msgid="8902165848117513641">"Faka kusikrini sasekhaya"</string>
@@ -151,20 +128,15 @@
<string name="action_deep_shortcut" msgid="2864038805849372848">"Izinqamuleli"</string>
<string name="shortcuts_menu_with_notifications_description" msgid="2676582286544232849">"Izinqamuleli nezaziso"</string>
<string name="action_dismiss_notification" msgid="5909461085055959187">"Cashisa"</string>
- <string name="accessibility_close" msgid="2277148124685870734">"Vala"</string>
<string name="notification_dismissed" msgid="6002233469409822874">"Isaziso sicashisiwe"</string>
<string name="all_apps_personal_tab" msgid="4190252696685155002">"Okomuntu siqu"</string>
<string name="all_apps_work_tab" msgid="4884822796154055118">"Umsebenzi"</string>
<string name="work_profile_toggle_label" msgid="3081029915775481146">"Iphrofayela yomsebenzi"</string>
- <string name="work_profile_edu_work_apps" msgid="7895468576497746520">"Ama-app omsebenzi anebheji futhi ayabonakala kumphathi wakho we-IT"</string>
- <string name="work_profile_edu_accept" msgid="6069788082535149071">"Ngiyezwa"</string>
- <string name="work_apps_paused_title" msgid="3040901117349444598">"Izinhlelo zokusebenza zomsebenzi ziphunyuziwe"</string>
- <string name="work_apps_paused_body" msgid="261634750995824906">"Ama-app akho omsebenzi awakwazi ukukuthumela izaziso, ukusebenzisa ibhethri lakho, noma ukufinyelela indawo yakho"</string>
- <string name="work_apps_paused_content_description" msgid="5149623040804051095">"Ama-app omsebenzi avaliwe. Ama-app akho omsebenzi awakwazi ukukuthumela izaziso, ukusebenzisa ibhethri lakho, noma ukufinyelela indawo yakho"</string>
- <string name="work_apps_paused_edu_banner" msgid="8872412121608402058">"Ama-app omsebenzi anebheji futhi ayabonakala kumphathi wakho we-IT"</string>
- <string name="work_apps_paused_edu_accept" msgid="6377476824357318532">"Ngiyezwa"</string>
- <string name="work_apps_pause_btn_text" msgid="1921059713673767460">"Vala ama-app omsebenzi"</string>
- <string name="work_apps_enable_btn_text" msgid="1156432622148413741">"Vula ama-app omsebenzi"</string>
- <string name="developer_options_filter_hint" msgid="5896817443635989056">"Hlunga"</string>
+ <string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"Thola izinhlelo zokusebenza lapha"</string>
+ <string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"Uhlo lokusebenza ngalunye lomsebenzi linebheji futhi igcinwa iphephile inhlangano yakho. Hambisa izinhlelo zokusebenza esikrinini sakho sasekhaya ngokufinyelela okulula."</string>
+ <string name="work_mode_on_label" msgid="4781128097185272916">"Kuphethwe inhlangano yakho"</string>
+ <string name="work_mode_off_label" msgid="3194894777601421047">"Izaziso nezinhlelo zokusebenza kuvaliwe"</string>
+ <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Vala"</string>
+ <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Kuvaliwe"</string>
<string name="remote_action_failed" msgid="1383965239183576790">"Yehlulekile: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
</resources>
diff --git a/res/values/attrs.xml b/res/values/attrs.xml
index 13f20c22c4..00cf31c65c 100644
--- a/res/values/attrs.xml
+++ b/res/values/attrs.xml
@@ -42,9 +42,7 @@
<attr name="popupNotificationDotColor" format="color" />
<attr name="folderDotColor" format="color" />
- <attr name="folderPaginationColor" format="color" />
- <attr name="folderPreviewColor" format="color" />
- <attr name="folderBackgroundColor" format="color" />
+ <attr name="folderFillColor" format="color" />
<attr name="folderIconRadius" format="float" />
<attr name="folderIconBorderColor" format="color" />
<attr name="folderTextColor" format="color" />
@@ -54,12 +52,6 @@
<attr name="workspaceAccentColor" format="color" />
<attr name="dropTargetHoverTextColor" format="color" />
- <attr name="allAppsButtonBgColor" format="color" />
- <attr name="allAppsButtonColor1" format="color" />
- <attr name="allAppsButtonColor2" format="color" />
- <attr name="allAppsButtonColor3" format="color" />
- <attr name="allAppsButtonColor4" format="color" />
-
<!-- BubbleTextView specific attributes. -->
<declare-styleable name="BubbleTextView">
<attr name="layoutHorizontal" format="boolean" />
@@ -79,7 +71,7 @@
<!-- BubbleTextView specific attributes. -->
<declare-styleable name="FolderIconPreview">
- <attr name="folderPreviewColor" />
+ <attr name="folderFillColor" />
<attr name="folderIconBorderColor" />
<attr name="folderDotColor" />
</declare-styleable>
@@ -139,8 +131,6 @@
<attr name="numRows" format="integer" />
<attr name="numColumns" format="integer" />
- <!-- numSearchContainerColumns defaults to numColumns, if not specified -->
- <attr name="numSearchContainerColumns" format="integer" />
<!-- numFolderRows & numFolderColumns defaults to numRows & numColumns, if not specified -->
<attr name="numFolderRows" format="integer" />
<attr name="numFolderColumns" format="integer" />
@@ -152,39 +142,15 @@
<!-- numHotseatIcons defaults to numColumns, if not specified -->
<attr name="numHotseatIcons" format="integer" />
- <!-- Number of icons to use when shrinking the hotseat size,
- defaults to numHotseatIcons / 2 -->
- <attr name="numShrunkenHotseatIcons" format="integer" />
<!-- Number of icons to use when extending the hotseat size,
defaults to 2 * numHotseatIcons -->
<attr name="numExtendedHotseatIcons" format="integer" />
- <!-- alignment of hotseat to the grid.
- Not applicable for 3 button mode when taskbar is enabled -->
- <!-- defaults to numColumns, if not specified -->
- <attr name="hotseatColumnSpan" format="integer" />
- <!-- defaults to numColumns, if not specified -->
- <attr name="hotseatColumnSpanLandscape" format="integer" />
- <!-- defaults to numColumns, if not specified -->
- <attr name="hotseatColumnSpanTwoPanelLandscape" format="integer" />
- <!-- defaults to numColumns, if not specified -->
- <attr name="hotseatColumnSpanTwoPanelPortrait" format="integer" />
-
<attr name="dbFile" format="string" />
<attr name="defaultLayoutId" format="reference" />
- <attr name="defaultSplitDisplayLayoutId" format="reference" />
<attr name="demoModeLayoutId" format="reference" />
<attr name="isScalable" format="boolean" />
<attr name="devicePaddingId" format="reference" />
- <!-- By default all categories are enabled -->
- <attr name="deviceCategory" format="integer" >
- <!-- Enable on phone only -->
- <flag name="phone" value="1" />
- <!-- Enable on tablets only -->
- <flag name="tablet" value="2" />
- <!-- Enable on multi display devices only -->
- <flag name="multi_display" value="4" />
- </attr>
</declare-styleable>
@@ -203,168 +169,31 @@
<attr name="minWidthDps" format="float" />
<attr name="minHeightDps" format="float" />
- <!-- These min cell values are only used if GridDisplayOption#isScalable is true -->
- <attr name="minCellHeight" format="float" />
- <attr name="minCellWidth" format="float" />
- <!-- defaults to minCellHeight, if not specified -->
- <attr name="minCellHeightLandscape" format="float" />
- <!-- defaults to minCellWidth, if not specified -->
- <attr name="minCellWidthLandscape" format="float" />
- <!-- defaults to minCellHeight, if not specified -->
- <attr name="minCellHeightTwoPanelPortrait" format="float" />
- <!-- defaults to minCellWidth, if not specified -->
- <attr name="minCellWidthTwoPanelPortrait" format="float" />
- <!-- defaults to minCellHeight, if not specified -->
- <attr name="minCellHeightTwoPanelLandscape" format="float" />
- <!-- defaults to minCellWidth, if not specified -->
- <attr name="minCellWidthTwoPanelLandscape" format="float" />
-
- <!-- These border spaces are only used if GridDisplayOption#isScalable is true -->
- <!-- space to be used horizontally and vertically -->
- <attr name="borderSpace" format="float" />
- <!-- space to the right of the cell, defaults to borderSpace if not specified -->
- <attr name="borderSpaceHorizontal" format="float" />
- <!-- space below the cell, defaults to borderSpace if not specified -->
- <attr name="borderSpaceVertical" format="float" />
- <!-- space to be used horizontally and vertically,
- defaults to borderSpace if not specified -->
- <attr name="borderSpaceLandscape" format="float" />
- <!-- space to the right of the cell, defaults to borderSpaceLandscape if not specified -->
- <attr name="borderSpaceLandscapeHorizontal" format="float" />
- <!-- space below the cell, defaults to borderSpaceLandscape if not specified -->
- <attr name="borderSpaceLandscapeVertical" format="float" />
- <!-- space to be used horizontally and vertically in two panels,
- defaults to borderSpace if not specified -->
- <attr name="borderSpaceTwoPanelPortrait" format="float" />
- <!-- space to the right of the cell in two panels, defaults to
- borderSpaceTwoPanelPortrait if not specified -->
- <attr name="borderSpaceTwoPanelPortraitHorizontal" format="float" />
- <!-- space below the cell in two panels, defaults to borderSpaceTwoPanelPortrait
- if not specified -->
- <attr name="borderSpaceTwoPanelPortraitVertical" format="float" />
- <!-- space to be used horizontally and vertically in two panels,
- defaults to borderSpace if not specified -->
- <attr name="borderSpaceTwoPanelLandscape" format="float" />
- <!-- space to the right of the cell in two panels, defaults to
- borderSpaceTwoPanelLandscape if not specified -->
- <attr name="borderSpaceTwoPanelLandscapeHorizontal" format="float" />
- <!-- space below the cell in two panels, defaults to borderSpaceTwoPanelLandscape
- if not specified -->
- <attr name="borderSpaceTwoPanelLandscapeVertical" format="float" />
-
- <!-- These min cell values are only used if GridDisplayOption#isScalable is true -->
- <!-- defaults to minCellHeight, if not specified -->
- <attr name="allAppsCellHeight" format="float" />
- <!-- defaults to minCellWidth, if not specified -->
- <attr name="allAppsCellWidth" format="float" />
- <!-- defaults to allAppsCellHeight, if not specified -->
- <attr name="allAppsCellHeightLandscape" format="float" />
- <!-- defaults to allAppsCellWidth, if not specified -->
- <attr name="allAppsCellWidthLandscape" format="float" />
- <!-- defaults to allAppsCellHeight, if not specified -->
- <attr name="allAppsCellHeightTwoPanelPortrait" format="float" />
- <!-- defaults to allAppsCellWidth, if not specified -->
- <attr name="allAppsCellWidthTwoPanelPortrait" format="float" />
- <!-- defaults to allAppsCellHeight, if not specified -->
- <attr name="allAppsCellHeightTwoPanelLandscape" format="float" />
- <!-- defaults to allAppsCellWidth, if not specified -->
- <attr name="allAppsCellWidthTwoPanelLandscape" format="float" />
- <!-- The following values are only enabled if grid is supported. -->
- <!-- defaults to iconImageSize, if not specified -->
- <attr name="allAppsIconSize" format="float" />
- <!-- defaults to allAppsIconSize, if not specified -->
- <attr name="allAppsIconSizeTwoPanelPortrait" format="float" />
- <!-- defaults to allAppsIconSize, if not specified -->
- <attr name="allAppsIconSizeTwoPanelLandscape" format="float" />
- <!-- defaults to iconTextSize, if not specified -->
- <attr name="allAppsIconTextSize" format="float" />
- <!-- defaults to allAppsIconTextSize, if not specified -->
- <attr name="allAppsIconTextSizeTwoPanelPortrait" format="float" />
- <!-- defaults to allAppsIconTextSize, if not specified -->
- <attr name="allAppsIconTextSizeTwoPanelLandscape" format="float" />
-
- <!-- defaults to borderSpace, if not specified -->
- <!-- space to be used horizontally and vertically -->
- <attr name="allAppsBorderSpace" format="float" />
- <!-- space to the right of the cell, defaults to allAppsBorderSpace if not specified -->
- <attr name="allAppsBorderSpaceHorizontal" format="float" />
- <!-- space below the cell, defaults to allAppsBorderSpace if not specified -->
- <attr name="allAppsBorderSpaceVertical" format="float" />
- <!-- space to be used horizontally and vertically,
- defaults to allAppsBorderSpace if not specified -->
- <attr name="allAppsBorderSpaceLandscape" format="float" />
- <!-- space to the right of the cell, defaults to allAppsBorderSpaceLandscape
- if not specified -->
- <attr name="allAppsBorderSpaceLandscapeHorizontal" format="float" />
- <!-- space below the cell, defaults to allAppsBorderSpaceLandscape if not specified -->
- <attr name="allAppsBorderSpaceLandscapeVertical" format="float" />
- <!-- space to be used horizontally and vertically in two panels,
- defaults to allAppsBorderSpace if not specified -->
- <attr name="allAppsBorderSpaceTwoPanelPortrait" format="float" />
- <!-- space to the right of the cell in two panels, defaults to
- allAppsBorderSpaceTwoPanelPortrait if not specified -->
- <attr name="allAppsBorderSpaceTwoPanelPortraitHorizontal" format="float" />
- <!-- space below the cell in two panels, defaults to allAppsBorderSpaceTwoPanelPortrait
- if not specified -->
- <attr name="allAppsBorderSpaceTwoPanelPortraitVertical" format="float" />
- <!-- space to be used horizontally and vertically in two panels,
- defaults to allAppsBorderSpace if not specified -->
- <attr name="allAppsBorderSpaceTwoPanelLandscape" format="float" />
- <!-- space to the right of the cell in two panels, defaults to
- allAppsBorderSpaceTwoPanelLandscape if not specified -->
- <attr name="allAppsBorderSpaceTwoPanelLandscapeHorizontal" format="float" />
- <!-- space below the cell in two panels, defaults to allAppsBorderSpaceTwoPanelLandscape
- if not specified -->
- <attr name="allAppsBorderSpaceTwoPanelLandscapeVertical" format="float" />
-
- <!-- defaults to borderSpaceDps, if not specified -->
- <attr name="hotseatBorderSpace" format="float" />
- <!-- defaults to hotseatBorderSpace, if not specified -->
- <attr name="hotseatBorderSpaceLandscape" format="float" />
- <!-- defaults to hotseatBorderSpace, if not specified -->
- <attr name="hotseatBorderSpaceTwoPanelLandscape" format="float" />
- <!-- defaults to hotseatBorderSpace, if not specified -->
- <attr name="hotseatBorderSpaceTwoPanelPortrait" format="float" />
+ <!-- These min cell values are only used if GridDisplayOption#isScalable is true-->
+ <attr name="minCellHeightDps" format="float" />
+ <attr name="minCellWidthDps" format="float" />
- <attr name="iconImageSize" format="float" />
- <!-- defaults to iconImageSize, if not specified -->
- <attr name="iconSizeLandscape" format="float" />
- <!-- defaults to iconSize, if not specified -->
- <attr name="iconSizeTwoPanelPortrait" format="float" />
- <!-- defaults to iconSize, if not specified -->
- <attr name="iconSizeTwoPanelLandscape" format="float" />
+ <attr name="borderSpacingDps" format="float" />
+ <attr name="iconImageSize" format="float" />
+ <!-- landscapeIconSize defaults to iconSize, if not specified -->
+ <attr name="landscapeIconSize" format="float" />
<attr name="iconTextSize" format="float" />
- <!-- defaults to iconTextSize, if not specified -->
- <attr name="iconTextSizeLandscape" format="float" />
- <!-- defaults to iconTextSize, if not specified -->
- <attr name="iconTextSizeTwoPanelPortrait" format="float" />
- <!-- defaults to iconTextSize, if not specified -->
- <attr name="iconTextSizeTwoPanelLandscape" format="float" />
+ <!-- landscapeIconTextSize defaults to iconTextSize, if not specified -->
+ <attr name="landscapeIconTextSize" format="float" />
<!-- If set, this display option is used to determine the default grid -->
- <attr name="canBeDefault" format="boolean" />
-
- <!-- Margin on left and right of the workspace when GridDisplayOption#isScalable is true -->
- <attr name="horizontalMargin" format="float"/>
- <!-- defaults to horizontalMargin if not specified -->
- <attr name="horizontalMarginLandscape" format="float"/>
- <!-- defaults to horizontalMargin if not specified -->
- <attr name="horizontalMarginTwoPanelLandscape" format="float"/>
- <!-- defaults to horizontalMargin if not specified -->
- <attr name="horizontalMarginTwoPanelPortrait" format="float"/>
-
- <!-- By default all are false -->
- <attr name="inlineQsb" format="integer" >
- <!-- Enable on landscape only -->
- <flag name="portrait" value="1" />
- <!-- Enable on portrait only -->
- <flag name="landscape" value="2" />
- <!-- Enable on two panel portrait only -->
- <flag name="twoPanelPortrait" value="4" />
- <!-- Enable on two panel landscape only -->
- <flag name="twoPanelLandscape" value="8" />
+ <attr name="canBeDefault" format="boolean|integer" >
+ <!-- The profile can be default on split display devices -->
+ <flag name="split_display" value="0x2" />
</attr>
+
+ <!-- The following values are only enabled if grid is supported. -->
+ <!-- allAppsIconSize defaults to iconSize, if not specified -->
+ <attr name="allAppsIconSize" format="float" />
+ <!-- allAppsIconTextSize defaults to iconTextSize, if not specified -->
+ <attr name="allAppsIconTextSize" format="float" />
+
</declare-styleable>
<declare-styleable name="CellLayout">
@@ -402,18 +231,4 @@
<declare-styleable name="WidgetsListRowHeader">
<attr name="appIconSize" format="dimension" />
</declare-styleable>
-
- <declare-styleable name="WidgetSections">
- <!-- Component name of an app widget provider. -->
- <attr name="provider" format="string" />
- <!-- If true, keep the app widget under its app listing in addition to the widget category
- in the widget picker. Defaults to false if not specified. -->
- <attr name="alsoKeepInApp" format="boolean" />
- <!-- The category of an app widget provider. Defaults to -1 if not specified. -->
- <attr name="category" format="integer" />
- <!-- The title name of a widget category. -->
- <attr name="sectionTitle" format="reference" />
- <!-- The icon drawable of a widget category. -->
- <attr name="sectionDrawable" format="reference" />
- </declare-styleable>
</resources>
diff --git a/res/values/colors.xml b/res/values/colors.xml
index 2bc923952d..1b68fb68a7 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -36,6 +36,15 @@
<color name="icon_background">#E0E0E0</color> <!-- Gray 300 -->
+ <color name="gesture_tutorial_ripple_color">#A0C2F9</color> <!-- Light Blue -->
+ <color name="gesture_tutorial_fake_task_view_color">#6DA1FF</color> <!-- Light Blue -->
+ <color name="fake_wallpaper_color_dark_mode">#000000</color> <!-- Black -->
+ <color name="fake_wallpaper_color_light_mode">#f9f9f9</color> <!-- White -->
+ <!-- Must contrast fake_wallpaper_color_dark_mode and fake_wallpaper_color_light_mode -->
+ <color name="gesture_tutorial_fake_previous_task_view_color">#3C4043</color> <!-- Gray -->
+ <color name="gesture_tutorial_action_button_label_color">#FF000000</color>
+ <color name="gesture_tutorial_primary_color">#B7F29F</color> <!-- Light Green -->
+
<color name="popup_color_primary_light">#FFF</color>
<color name="popup_color_secondary_light">#F1F3F4</color>
<color name="popup_color_tertiary_light">#E0E0E0</color> <!-- Gray 300 -->
@@ -63,12 +72,7 @@
<color name="folder_background_light">#F9F9F9</color>
<color name="folder_background_dark">#464746</color>
- <color name="folder_preview_light">#F9F9F9</color>
- <color name="folder_preview_dark">#464746</color>
-
<color name="folder_dot_color">?attr/colorPrimary</color>
- <color name="folder_pagination_color_light">#ff006c5f</color>
- <color name="folder_pagination_color_dark">#ffbfebe3</color>
<color name="text_color_primary_dark">#FFFFFFFF</color>
<color name="text_color_secondary_dark">#FFFFFFFF</color>
@@ -79,10 +83,4 @@
<color name="workspace_accent_color_light">#ff8df5e3</color>
<color name="workspace_accent_color_dark">#ff3d665f</color>
-
- <color name="all_apps_button_bg_color">#F7F9FA</color>
- <color name="all_apps_button_color_1">#00677E</color>
- <color name="all_apps_button_color_2">#00677E</color>
- <color name="all_apps_button_color_3">#5F757E</color>
- <color name="all_apps_button_color_4">#005A6E</color>
</resources>
diff --git a/res/values/config.xml b/res/values/config.xml
index 9aa1f03734..04c359ede3 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -1,18 +1,3 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2022 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
<resources>
<!-- Miscellaneous -->
<bool name="config_largeHeap">false</bool>
@@ -37,21 +22,18 @@
<item type="id" name="drag_event_parity" />
<!-- AllApps & Launcher transitions -->
+ <!-- Out of 100, the percent to shrink the workspace during spring loaded mode. -->
+ <integer name="config_workspaceSpringLoadShrinkPercentage">85</integer>
+
<!-- The duration of the animation from search hint to text entry -->
<integer name="config_searchHintAnimationDuration">50</integer>
- <!-- The duration of the PagedView page snap animation -->
- <integer name="config_pageSnapAnimationDuration">750</integer>
-
<!-- View tag key used to store SpringAnimation data. -->
<item type="id" name="spring_animation_tag" />
<!-- View tag key used to determine if we should fade in the child views.. -->
<string name="popup_container_iterate_children" translatable="false">popup_container_iterate_children</string>
- <!-- config used to determine if header protection is supported in AllApps -->
- <bool name="config_header_protection_supported">false</bool>
-
<!-- Workspace -->
<!-- The duration (in ms) of the fade animation on the object outlines, used when
we are dragging objects around on the home screen. -->
@@ -84,7 +66,6 @@
<string name="test_information_handler_class" translatable="false"></string>
<string name="launcher_activity_logic_class" translatable="false"></string>
<string name="model_delegate_class" translatable="false"></string>
- <string name="window_manager_proxy_class" translatable="false"></string>
<!-- View ID to use for QSB widget -->
<item type="id" name="qsb_widget" />
@@ -103,10 +84,7 @@
<!-- Default packages -->
<string name="wallpaper_picker_package" translatable="false"></string>
- <string name="custom_activity_picker" translatable="false">
- com.android.customization.picker.CustomizationPickerActivity</string>
<string name="local_colors_extraction_class" translatable="false"></string>
- <string name="search_session_manager_class" translatable="false"></string>
<!-- Accessibility actions -->
<item type="id" name="action_remove" />
@@ -155,13 +133,47 @@
<item name="swipe_up_rect_xy_fling_friction" type="dimen" format="float">1.5</item>
<item name="swipe_up_scale_start" type="dimen" format="float">0.88</item>
+ <item name="swipe_up_duration" type="dimen" format="float">400</item>
+
+ <item name="swipe_up_trans_y_dp" type="dimen" format="float">4.5</item>
+ <item name="swipe_up_trans_y_dp_per_s" type="dimen" format="float">3</item>
+
+ <item name="swipe_up_trans_y_damping" type="dimen" format="float">0.45</item>
+ <item name="swipe_up_trans_y_stiffness" type="dimen" format="float">200</item>
<item name="swipe_up_rect_xy_damping_ratio" type="dimen" format="float">0.8</item>
<item name="swipe_up_rect_xy_stiffness" type="dimen" format="float">200</item>
+
+ <item name="swipe_up_rect_2_x_damping_ratio" type="dimen" format="float">1</item>
+ <item name="swipe_up_rect_2_x_stiffness" type="dimen" format="float">250</item>
+
+ <item name="swipe_up_rect_2_y_damping_ratio" type="dimen" format="float">1</item>
+ <item name="swipe_up_rect_2_y_stiffness" type="dimen" format="float">600</item>
+
+ <item name="swipe_up_rect_2_y_stiffness_low_swipe_multiplier" type="dimen" format="float">0.8</item>
+ <item name="swipe_up_low_swipe_duration_multiplier" type="dimen" format="float">1</item>
+
+ <item name="swipe_up_launcher_alpha_max_progress" type="dimen" format="float">0.85</item>
+
+
+ <item name="c1_a" type="dimen" format="float">0.05</item>
+ <item name="c1_b" type="dimen" format="float">0</item>
+ <item name="c1_c" type="dimen" format="float">0.133333</item>
+ <item name="c1_d" type="dimen" format="float">0.06</item>
+
+ <item name="mp_x" type="dimen" format="float">0.166666</item>
+ <item name="mp_y" type="dimen" format="float">.4</item>
+
+ <item name="c2_a" type="dimen" format="float">0.208333</item>
+ <item name="c2_b" type="dimen" format="float">.82</item>
+ <item name="c2_c" type="dimen" format="float">.25</item>
+ <item name="c2_d" type="dimen" format="float">1</item>
+
+
<item name="staggered_damping_ratio" type="dimen" format="float">0.7</item>
<item name="staggered_stiffness" type="dimen" format="float">150</item>
- <dimen name="unlock_staggered_velocity_dp_per_s">2dp</dimen>
+ <dimen name="unlock_staggered_velocity_dp_per_s">4dp</dimen>
<item name="hint_scale_damping_ratio" type="dimen" format="float">0.7</item>
<item name="hint_scale_stiffness" type="dimen" format="float">200</item>
@@ -169,12 +181,36 @@
<!-- Swipe up to home related -->
<dimen name="swipe_up_fling_min_visible_change">18dp</dimen>
+ <dimen name="swipe_up_y_overshoot">10dp</dimen>
<dimen name="swipe_up_max_workspace_trans_y">-60dp</dimen>
- <dimen name="swipe_up_max_velocity">7.619dp</dimen>
<array name="dynamic_resources">
+ <item>@dimen/swipe_up_duration</item>
<item>@dimen/swipe_up_scale_start</item>
- <item>@dimen/swipe_up_max_velocity</item>
+ <item>@dimen/swipe_up_trans_y_dp</item>
+ <item>@dimen/swipe_up_trans_y_dp_per_s</item>
+ <item>@dimen/swipe_up_trans_y_damping</item>
+ <item>@dimen/swipe_up_trans_y_stiffness</item>
+ <item>@dimen/swipe_up_rect_2_x_damping_ratio</item>
+ <item>@dimen/swipe_up_rect_2_x_stiffness</item>
+ <item>@dimen/swipe_up_rect_2_y_damping_ratio</item>
+ <item>@dimen/swipe_up_rect_2_y_stiffness</item>
+ <item>@dimen/swipe_up_launcher_alpha_max_progress</item>
+ <item>@dimen/swipe_up_rect_2_y_stiffness_low_swipe_multiplier</item>
+ <item>@dimen/swipe_up_low_swipe_duration_multiplier</item>
+
+ <item>@dimen/c1_a</item>
+ <item>@dimen/c1_b</item>
+ <item>@dimen/c1_c</item>
+ <item>@dimen/c1_d</item>
+
+ <item>@dimen/mp_x</item>
+ <item>@dimen/mp_y</item>
+
+ <item>@dimen/c2_a</item>
+ <item>@dimen/c2_b</item>
+ <item>@dimen/c2_c</item>
+ <item>@dimen/c2_d</item>
</array>
<string-array name="filtered_components" ></string-array>
@@ -182,8 +218,4 @@
<!-- Name of the class used to generate colors from the wallpaper colors. Must be implementing the LauncherAppWidgetHostView.ColorGenerator interface. -->
<string name="color_generator_class" translatable="false"/>
- <!-- Swipe back to home related -->
- <dimen name="swipe_back_window_scale_x_margin">10dp</dimen>
- <dimen name="swipe_back_window_max_delta_y">160dp</dimen>
- <dimen name="swipe_back_window_corner_radius">40dp</dimen>
</resources>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 8403af46b7..f434644996 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -19,37 +19,28 @@
<dimen name="click_shadow_elevation">4dp</dimen>
<!-- Dynamic Grid -->
- <dimen name="dynamic_grid_edge_margin">10.77dp</dimen>
+ <dimen name="dynamic_grid_edge_margin">8dp</dimen>
<dimen name="dynamic_grid_left_right_margin">8dp</dimen>
<dimen name="dynamic_grid_icon_drawable_padding">7dp</dimen>
<!-- Minimum space between workspace and hotseat in spring loaded mode -->
<dimen name="dynamic_grid_min_spring_loaded_space">8dp</dimen>
- <!-- Minimum amount of next page visible in spring loaded mode -->
- <dimen name="dynamic_grid_spring_loaded_min_next_space_visible">24dp</dimen>
<dimen name="dynamic_grid_cell_border_spacing">16dp</dimen>
- <dimen name="cell_layout_padding">10.77dp</dimen>
+ <dimen name="dynamic_grid_cell_layout_padding">5.5dp</dimen>
<dimen name="dynamic_grid_cell_padding_x">8dp</dimen>
+ <dimen name="two_panel_home_side_padding">18dp</dimen>
+
<!-- Hotseat -->
<dimen name="dynamic_grid_hotseat_top_padding">8dp</dimen>
<dimen name="dynamic_grid_hotseat_bottom_padding">2dp</dimen>
- <dimen name="dynamic_grid_hotseat_bottom_tall_padding">0dp</dimen>
- <dimen name="inline_qsb_bottom_margin">0dp</dimen>
- <dimen name="spring_loaded_hotseat_top_margin">76dp</dimen>
-
- <!-- Qsb -->
- <!-- Used for adjusting the position of QSB when placed in hotseat. This is a ratio and a higher
- number signifies that the QSB is close to the hotseat icons and a lower number signifies that
- it is close to the bottom of the screen -->
- <item name="qsb_center_factor" format="float" type="dimen">0.325</item>
-
<!-- Extra bottom padding for non-tall devices. -->
<dimen name="dynamic_grid_hotseat_bottom_non_tall_padding">0dp</dimen>
<dimen name="dynamic_grid_hotseat_extra_vertical_size">34dp</dimen>
<dimen name="dynamic_grid_hotseat_side_padding">0dp</dimen>
<!-- Scalable Grid -->
+ <dimen name="scalable_grid_left_right_margin">22dp</dimen>
<dimen name="scalable_grid_qsb_bottom_margin">42dp</dimen>
<!-- Workspace page indicator -->
@@ -57,22 +48,14 @@
<dimen name="workspace_page_indicator_line_height">1dp</dimen>
<dimen name="workspace_page_indicator_overlap_workspace">0dp</dimen>
- <!-- Drop target bar -->
- <dimen name="dynamic_grid_drop_target_size">56dp</dimen>
+<!-- Drop target bar -->
+ <dimen name="dynamic_grid_drop_target_size">52dp</dimen>
<dimen name="drop_target_vertical_gap">20dp</dimen>
- <dimen name="drop_target_top_margin">32dp</dimen>
- <dimen name="drop_target_bottom_margin">16dp</dimen>
-
- <!-- App Widget resize frame -->
- <!-- Button drop target bar -->
- <dimen name="button_drop_target_min_text_size">10sp</dimen>
- <dimen name="button_drop_target_resize_text_increment">1sp</dimen>
- <!-- App Widget resize frame -->
+<!-- App Widget resize frame -->
<dimen name="widget_handle_margin">13dp</dimen>
<dimen name="resize_frame_background_padding">24dp</dimen>
<dimen name="resize_frame_margin">22dp</dimen>
- <dimen name="resize_frame_invalid_drag_across_two_panel_opacity_margin">24dp</dimen>
<!-- App widget reconfigure button -->
<dimen name="widget_reconfigure_button_corner_radius">14dp</dimen>
@@ -81,7 +64,7 @@
<dimen name="widget_reconfigure_button_size">36dp</dimen>
<dimen name="widget_reconfigure_tip_top_margin">16dp</dimen>
- <!-- Fast scroll -->
+<!-- Fast scroll -->
<dimen name="fastscroll_track_min_width">6dp</dimen>
<dimen name="fastscroll_track_max_width">8dp</dimen>
<dimen name="fastscroll_thumb_padding">1dp</dimen>
@@ -102,18 +85,9 @@
<dimen name="fastscroll_width">58dp</dimen>
<dimen name="fastscroll_end_margin">-26dp</dimen>
- <!-- PagedView -->
- <dimen name="fling_threshold_velocity">500dp</dimen>
- <dimen name="easy_fling_threshold_velocity">400dp</dimen>
- <dimen name="min_fling_velocity">250dp</dimen>
- <!-- The minimum velocity of a page snap after a fling gesture -->
- <dimen name="min_page_snap_velocity">1500dp</dimen>
-
<!-- All Apps -->
- <dimen name="all_apps_starting_vertical_translate">300dp</dimen>
+ <dimen name="all_apps_open_vertical_translate">320dp</dimen>
<dimen name="all_apps_search_bar_field_height">48dp</dimen>
- <!-- all_apps_search_bar_field_height / 2 -->
- <dimen name="all_apps_search_bar_content_overlap">24dp</dimen>
<dimen name="all_apps_search_bar_bottom_padding">30dp</dimen>
<dimen name="all_apps_empty_search_message_top_offset">40dp</dimen>
<dimen name="all_apps_empty_search_bg_top_offset">144dp</dimen>
@@ -123,60 +97,42 @@
<dimen name="all_apps_header_pill_corner_radius">12dp</dimen>
<dimen name="all_apps_header_tab_height">48dp</dimen>
<dimen name="all_apps_tabs_indicator_height">2dp</dimen>
- <dimen name="all_apps_header_top_margin">33dp</dimen>
<dimen name="all_apps_header_top_padding">36dp</dimen>
- <dimen name="all_apps_header_bottom_padding">14dp</dimen>
- <dimen name="all_apps_header_top_adjustment">6dp</dimen>
- <dimen name="all_apps_header_bottom_adjustment">4dp</dimen>
+ <dimen name="all_apps_header_bottom_padding">6dp</dimen>
<dimen name="all_apps_work_profile_tab_footer_top_padding">16dp</dimen>
<dimen name="all_apps_work_profile_tab_footer_bottom_padding">20dp</dimen>
<dimen name="all_apps_tabs_button_horizontal_padding">4dp</dimen>
<dimen name="all_apps_tabs_vertical_padding">6dp</dimen>
<dimen name="all_apps_divider_height">2dp</dimen>
<dimen name="all_apps_divider_width">128dp</dimen>
- <dimen name="all_apps_content_fade_in_offset">150dp</dimen>
- <dimen name="all_apps_tip_bottom_margin">8dp</dimen>
- <dimen name="all_apps_height_extra">6dp</dimen>
- <dimen name="all_apps_bottom_sheet_horizontal_padding">0dp</dimen>
- <dimen name="all_apps_paged_view_top_padding">40dp</dimen>
- <dimen name="all_apps_personal_work_tabs_vertical_margin">16dp</dimen>
- <dimen name="all_apps_icon_drawable_padding">8dp</dimen>
+ <dimen name="all_apps_tip_bottom_margin">8dp</dimen>
<!-- The size of corner radius of the arrow in the arrow toast. -->
<dimen name="arrow_toast_corner_radius">2dp</dimen>
- <dimen name="arrow_toast_elevation">2dp</dimen>
<dimen name="arrow_toast_arrow_width">10dp</dimen>
- <!-- Search bar in All Apps -->
+<!-- Search bar in All Apps -->
<dimen name="all_apps_header_max_elevation">3dp</dimen>
<dimen name="all_apps_header_scroll_to_elevation">16dp</dimen>
<dimen name="all_apps_header_shadow_height">6dp</dimen>
<dimen name="all_apps_divider_margin_vertical">8dp</dimen>
- <!-- Floating action button inside work tab to toggle work profile -->
+<!-- Floating action button inside work tab to toggle work profile -->
<dimen name="work_fab_height">56dp</dimen>
- <dimen name="work_fab_radius">16dp</dimen>
- <dimen name="work_card_padding_horizontal">10dp</dimen>
+ <dimen name="work_fab_radius">28dp</dimen>
+ <dimen name="work_card_padding_horizontal">24dp</dimen>
<dimen name="work_card_button_height">52dp</dimen>
<dimen name="work_fab_margin">16dp</dimen>
- <dimen name="work_fab_margin_bottom">20dp</dimen>
- <dimen name="work_mode_fab_padding">16dp</dimen>
<dimen name="work_profile_footer_padding">20dp</dimen>
+ <dimen name="work_profile_footer_text_size">16sp</dimen>
<dimen name="work_edu_card_margin">16dp</dimen>
- <dimen name="work_edu_card_radius">16dp</dimen>
- <dimen name="work_edu_card_bottom_margin">26dp</dimen>
-
- <dimen name="work_card_margin">24dp</dimen>
- <!-- (x) icon button inside work edu card -->
- <dimen name="rounded_button_width">24dp</dimen>
- <dimen name="x_icon_size">16dp</dimen>
- <dimen name="x_icon_padding">4dp</dimen>
+ <dimen name="work_edu_card_radius">28dp</dimen>
<!-- rounded button shown inside card views, and snack bars -->
<dimen name="padded_rounded_button_height">48dp</dimen>
- <dimen name="rounded_button_height">48dp</dimen>
- <dimen name="rounded_button_radius">200dp</dimen>
+ <dimen name="rounded_button_height">32dp</dimen>
+ <dimen name="rounded_button_radius">16dp</dimen>
<dimen name="rounded_button_padding">8dp</dimen>
@@ -186,7 +142,8 @@
<dimen name="widget_cell_font_size">14sp</dimen>
<dimen name="widget_tabs_button_horizontal_padding">4dp</dimen>
- <dimen name="widget_tabs_horizontal_padding">16dp</dimen>
+ <dimen name="widget_tabs_horizontal_margin">32dp</dimen>
+ <dimen name="widget_apps_header_pill_height">48dp</dimen>
<dimen name="widget_apps_tabs_vertical_padding">6dp</dimen>
<dimen name="recommended_widgets_table_vertical_padding">8dp</dimen>
@@ -220,28 +177,25 @@
<dimen name="widget_picker_education_tip_max_width">308dp</dimen>
<dimen name="widget_picker_education_tip_min_margin">4dp</dimen>
+ <dimen name="widget_picker_view_pager_top_padding">10dp</dimen>
+
<!-- Padding applied to shortcut previews -->
<dimen name="shortcut_preview_padding_left">0dp</dimen>
<dimen name="shortcut_preview_padding_right">0dp</dimen>
<dimen name="shortcut_preview_padding_top">0dp</dimen>
- <!-- Pin widget dialog -->
+<!-- Pin widget dialog -->
<dimen name="pin_widget_button_padding_horizontal">8dp</dimen>
<dimen name="pin_widget_button_padding_vertical">4dp</dimen>
<dimen name="pin_widget_button_inset_horizontal">4dp</dimen>
<dimen name="pin_widget_button_inset_vertical">6dp</dimen>
- <!-- Dragging -->
+<!-- Dragging -->
<!-- Drag padding to add to the bottom of drop targets -->
<dimen name="drop_target_drag_padding">14dp</dimen>
<dimen name="drop_target_text_size">16sp</dimen>
<dimen name="drop_target_shadow_elevation">2dp</dimen>
<dimen name="drop_target_bar_margin_horizontal">4dp</dimen>
- <dimen name="drop_target_button_drawable_padding">8dp</dimen>
- <dimen name="drop_target_button_drawable_horizontal_padding">16dp</dimen>
- <dimen name="drop_target_button_drawable_vertical_padding">8dp</dimen>
- <dimen name="drop_target_button_gap">28dp</dimen>
- <dimen name="drop_target_button_workspace_edge_gap">0dp</dimen>
<!-- the distance an icon must be dragged before button drop targets accept it -->
<dimen name="drag_distanceThreshold">30dp</dimen>
@@ -255,7 +209,7 @@
<dimen name="spring_loaded_panel_border">2dp</dimen>
<dimen name="keyboard_drag_stroke_width">4dp</dimen>
- <!-- Folders -->
+<!-- Folders -->
<dimen name="page_indicator_dot_size">8dp</dimen>
<dimen name="folder_cell_x_padding">9dp</dimen>
@@ -267,27 +221,26 @@
<dimen name="folder_content_padding_left_right">8dp</dimen>
<dimen name="folder_content_padding_top">16dp</dimen>
- <!-- Sizes for managed profile badges -->
+<!-- Sizes for managed profile badges -->
<dimen name="profile_badge_size">24dp</dimen>
<dimen name="profile_badge_margin">5dp</dimen>
<dimen name="profile_badge_minimum_top">2dp</dimen>
- <!-- Shadows and outlines -->
+<!-- Shadows and outlines -->
<dimen name="blur_size_thin_outline">1dp</dimen>
<dimen name="blur_size_medium_outline">2dp</dimen>
<dimen name="blur_size_click_shadow">4dp</dimen>
<dimen name="click_shadow_high_shift">2dp</dimen>
- <!-- Pending widget -->
+<!-- Pending widget -->
<dimen name="pending_widget_min_padding">8dp</dimen>
<dimen name="pending_widget_elevation">2dp</dimen>
- <!-- Deep shortcuts -->
+<!-- Deep shortcuts -->
<dimen name="deep_shortcuts_elevation">2dp</dimen>
<dimen name="bg_popup_padding">2dp</dimen>
<dimen name="bg_popup_item_width">216dp</dimen>
<dimen name="bg_popup_item_height">56dp</dimen>
- <dimen name="bg_popup_item_vertical_padding">12dp</dimen>
<dimen name="pre_drag_view_scale">6dp</dimen>
<!-- an icon with shortcuts must be dragged this far before the container is removed. -->
<dimen name="deep_shortcuts_start_drag_threshold">16dp</dimen>
@@ -306,20 +259,18 @@
<!-- popup_padding_start + deep_shortcut_icon_size / 2 -->
<dimen name="popup_arrow_horizontal_center_offset">26dp</dimen>
<dimen name="popup_arrow_corner_radius">2dp</dimen>
- <!-- popup_padding_start + deep_shortcut_icon_size + 10dp -->
+ <!-- popup_padding_start + icon_size + 10dp -->
<dimen name="deep_shortcuts_text_padding_start">52dp</dimen>
- <dimen name="system_shortcut_icon_size">20dp</dimen>
+ <dimen name="system_shortcut_icon_size">24dp</dimen>
<!-- popup_arrow_horizontal_center_offset - system_shortcut_icon_size / 2 -->
<dimen name="system_shortcut_margin_start">16dp</dimen>
<dimen name="system_shortcut_header_height">56dp</dimen>
<dimen name="system_shortcut_header_icon_touch_size">48dp</dimen>
- <!-- (system_shortcut_header_icon_touch_size - system_shortcut_icon_size) / 2 -->
- <dimen name="system_shortcut_header_icon_padding">14dp</dimen>
+ <!-- (touch_size - icon_size) / 2 -->
+ <dimen name="system_shortcut_header_icon_padding">12dp</dimen>
- <!-- Notifications -->
+<!-- Notifications -->
<dimen name="bg_round_rect_radius">8dp</dimen>
- <dimen name="notification_max_trans">8dp</dimen>
- <dimen name="notification_space">8dp</dimen>
<dimen name="notification_padding">16dp</dimen>
<dimen name="notification_padding_top">18dp</dimen>
<dimen name="notification_header_text_size">14sp</dimen>
@@ -334,11 +285,11 @@
<dimen name="notification_main_text_padding_start">56dp</dimen>
<dimen name="horizontal_ellipsis_size">18dp</dimen>
- <!-- Overview -->
+<!-- Overview -->
<dimen name="options_menu_icon_size">24dp</dimen>
<dimen name="options_menu_thumb_size">32dp</dimen>
- <!-- Snackbar -->
+<!-- Snackbar -->
<dimen name="snackbar_height">48dp</dimen>
<dimen name="snackbar_content_height">32dp</dimen>
<dimen name="snackbar_padding">8dp</dimen>
@@ -348,65 +299,36 @@
<dimen name="snackbar_elevation">3dp</dimen>
<dimen name="snackbar_min_text_size">12sp</dimen>
<dimen name="snackbar_max_text_size">14sp</dimen>
- <dimen name="snackbar_max_width">504dp</dimen>
- <!-- Developer Options -->
+<!-- Developer Options -->
<dimen name="developer_options_filter_margins">10dp</dimen>
- <!-- Theming related -->
+<!-- Theming related -->
<dimen name="default_dialog_corner_radius">8dp</dimen>
<dimen name="dialogCornerRadius">@dimen/default_dialog_corner_radius</dimen>
<!-- Onboarding bottomsheet related -->
<dimen name="bottom_sheet_edu_padding">24dp</dimen>
- <!-- Taskbar related (placeholders to compile in Launcher3 without Quickstep) -->
+<!-- Taskbar related (placeholders to compile in Launcher3 without Quickstep) -->
<dimen name="taskbar_size">0dp</dimen>
- <dimen name="taskbar_stashed_size">0dp</dimen>
- <dimen name="qsb_widget_height">0dp</dimen>
- <dimen name="taskbar_icon_size">44dp</dimen>
- <!-- Note that this applies to both sides of all icons, so visible space is double this. -->
- <dimen name="taskbar_icon_spacing">8dp</dimen>
<!-- Size of the maximum radius for the enforced rounded rectangles. -->
<dimen name="enforced_rounded_corner_max_radius">16dp</dimen>
- <!-- Base Swipe Detector, speed in dp/s -->
- <dimen name="base_swift_detector_fling_release_velocity">1dp</dimen>
-
- <!-- Overview placeholder to compile in Launcher3 without Quickstep -->
+<!-- Overview placeholder to compile in Launcer3 without Quickstep -->
<dimen name="task_thumbnail_icon_size">0dp</dimen>
- <dimen name="task_thumbnail_icon_drawable_size">0dp</dimen>
- <dimen name="task_thumbnail_icon_drawable_size_grid">0dp</dimen>
+ <dimen name="task_thumbnail_icon_size_grid">0dp</dimen>
<dimen name="overview_task_margin">0dp</dimen>
- <dimen name="overview_task_margin_grid">0dp</dimen>
- <dimen name="overview_actions_height">0dp</dimen>
- <dimen name="overview_actions_button_spacing">0dp</dimen>
- <dimen name="overview_actions_margin_gesture">0dp</dimen>
- <dimen name="overview_actions_top_margin">0dp</dimen>
- <dimen name="overview_grid_side_margin">0dp</dimen>
- <dimen name="overview_grid_row_spacing">0dp</dimen>
- <dimen name="overview_page_spacing">0dp</dimen>
- <dimen name="split_placeholder_size">72dp</dimen>
- <dimen name="split_placeholder_inset">16dp</dimen>
- <dimen name="split_placeholder_icon_size">44dp</dimen>
- <dimen name="task_menu_width_grid">216dp</dimen>
-
-
- <!-- Workspace grid visualization parameters -->
- <dimen name="grid_visualization_rounding_radius">28dp</dimen>
- <dimen name="grid_visualization_horizontal_cell_spacing">6dp</dimen>
- <dimen name="grid_visualization_vertical_cell_spacing">6dp</dimen>
-
- <!-- Search results related parameters -->
+ <dimen name="overview_actions_bottom_margin_gesture">0dp</dimen>
+ <dimen name="overview_actions_bottom_margin_three_button">0dp</dimen>
+
+<!-- Workspace grid visualization parameters -->
+ <dimen name="grid_visualization_rounding_radius">22dp</dimen>
+ <dimen name="grid_visualization_cell_spacing">6dp</dimen>
+
+<!-- Search results related parameters -->
<dimen name="search_row_icon_size">48dp</dimen>
<dimen name="search_row_small_icon_size">32dp</dimen>
<dimen name="padded_rounded_button_padding">8dp</dimen>
-
- <!-- Bottom sheet related parameters -->
- <dimen name="bottom_sheet_extra_top_padding">0dp</dimen>
- <dimen name="bottom_sheet_handle_width">32dp</dimen>
- <dimen name="bottom_sheet_handle_height">4dp</dimen>
- <dimen name="bottom_sheet_handle_margin">16dp</dimen>
- <dimen name="bottom_sheet_handle_corner_radius">2dp</dimen>
</resources>
diff --git a/res/values/id.xml b/res/values/id.xml
index af21b27caf..1709c5961e 100644
--- a/res/values/id.xml
+++ b/res/values/id.xml
@@ -17,25 +17,7 @@
<resources>
<item type="id" name="apps_list_view_work" />
<item type="id" name="tag_widget_entry" />
- <item type="id" name="view_type_widgets_space" />
<item type="id" name="view_type_widgets_list" />
<item type="id" name="view_type_widgets_header" />
<item type="id" name="view_type_widgets_search_header" />
- <!-- Used for A11y actions in staged split to identify each task uniquely -->
- <item type="id" name="split_topLeft_appInfo" />
- <item type="id" name="split_bottomRight_appInfo" />
-
-
- <!-- Do not change, must be kept in sync with sysui navbar button IDs for tests! -->
- <item type="id" name="home" />
- <item type="id" name="recent_apps" />
- <item type="id" name="back" />
- <item type="id" name="ime_switcher" />
- <item type="id" name="accessibility_button" />
- <item type="id" name="rotate_suggestion" />
- <!-- /Do not change, must be kept in sync with sysui navbar button IDs for tests! -->
-
- <item type="id" name="quick_settings_button" />
- <item type="id" name="notifications_button" />
- <item type="id" name="cache_entry_tag_id" />
</resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 847e4a8625..d1774e5a03 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -1,4 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?><!--
+<?xml version="1.0" encoding="utf-8"?>
+<!--
/*
* Copyright (C) 2008 The Android Open Source Project
*
@@ -40,10 +41,9 @@
<!-- Options for recent tasks -->
<!-- Title for an option to enter split screen mode for a given app -->
<string name="recent_task_option_split_screen">Split screen</string>
- <string name="split_screen_position_top">Split top</string>
- <string name="split_screen_position_left">Split left</string>
- <string name="split_screen_position_right">Split right</string>
- <string name="split_app_info_accessibility">App info for %1$s</string>
+ <string translatable="false" name="split_screen_position_top">Pin to top</string>
+ <string translatable="false" name="split_screen_position_left">Pin to left</string>
+ <string translatable="false" name="split_screen_position_right">Pin to right</string>
<!-- Widgets -->
<!-- Message to tell the user to press and hold on a widget to add it [CHAR_LIMIT=50] -->
@@ -60,22 +60,24 @@
<string name="widget_preview_context_description"><xliff:g id="widget_name" example="Calendar month view">%1$s</xliff:g> widget</string>
<!-- Message to tell the user to press and hold a widget/icon to add it to the home screen.
[CHAR LIMIT=NONE] -->
- <string name="add_item_request_drag_hint">Touch &amp; hold the widget to move it around the home screen</string>
+ <string name="add_item_request_drag_hint">Touch &amp; hold the widget to move it around the Home screen</string>
<!-- Button label to automatically add a widget to home screen [CHAR_LIMIT=50] -->
- <string name="add_to_home_screen">Add to home screen</string>
+ <string name="add_to_home_screen">Add to Home screen</string>
<!-- Accessibility spoken message announced when a widget gets added to the home screen using a
button in a dialog. [CHAR_LIMIT=none] -->
<string name="added_to_home_screen_accessibility_text"><xliff:g id="widget_name" example="Calendar month view">%1$s</xliff:g> widget added to home screen</string>
<!-- Label for showing the number of widgets an app has in the full widgets picker.
- [CHAR_LIMIT=25][ICU SYNTAX] -->
- <string name="widgets_count">
- {count, plural, =1{# widget} other{# widgets}}
- </string>
+ [CHAR_LIMIT=25] -->
+ <plurals name="widgets_count">
+ <item quantity="one"><xliff:g id="widgets_count" example="1">%1$d</xliff:g> widget</item>
+ <item quantity="other"><xliff:g id="widgets_count" example="2">%1$d</xliff:g> widgets</item>
+ </plurals>
<!-- Label for showing the number of shortcut an app has in the full widgets picker.
- [CHAR_LIMIT=25][ICU SYNTAX] -->
- <string name="shortcuts_count">
- {count, plural, =1{# shortcut} other{# shortcuts}}
- </string>
+ [CHAR_LIMIT=25] -->
+ <plurals name="shortcuts_count">
+ <item quantity="one"><xliff:g id="shortcuts_count" example="1">%1$d</xliff:g> shortcut</item>
+ <item quantity="other"><xliff:g id="shortcuts_count" example="2">%1$d</xliff:g> shortcuts</item>
+ </plurals>
<!-- Label for showing both the number of widgets and shortcuts an app has in the full widgets
picker. [CHAR_LIMIT=50] -->
<string name="widgets_and_shortcuts_count"><xliff:g id="widgets_count" example="5 widgets">%1$s</xliff:g>, <xliff:g id="shortcuts_count" example="1 shortcut">%2$s</xliff:g></string>
@@ -108,7 +110,7 @@
<string name="widget_education_header">Useful info at your fingertips</string>
<!-- Dialog text. This dialog lets a user know how they can use widgets on their phone.
[CHAR_LIMIT=NONE] -->
- <string name="widget_education_content">To get info without opening apps, you can add widgets to your home screen</string>
+ <string name="widget_education_content">To get info without opening apps, you can add widgets to your Home screen</string>
<!-- Text on an educational tip on widget informing users that they can change widget settings.
[CHAR_LIMIT=NONE] -->
@@ -132,8 +134,6 @@
<string name="all_apps_search_market_message">Search for more apps</string>
<!-- Label for an icon representing any generic app. [CHAR_LIMIT=50] -->
<string name="label_application">App</string>
- <!-- Label for the header text of the All Apps section in All Apps view, used to separate Predicted Apps and Actions section from All Apps section. [CHAR_LIMIT=50] -->
- <string name="all_apps_label">All apps</string>
<!-- Popup items -->
<!-- Text to display as the header above notifications. [CHAR_LIMIT=30] -->
@@ -147,13 +147,12 @@
<skip />
<!-- Error message when a user can't add more apps, widgets, or shortcuts to a Home screen. -->
- <string name="out_of_space">No room on this home screen</string>
+ <string name="out_of_space">No room on this Home screen</string>
<!-- Error message when user has filled the hotseat -->
<string name="hotseat_out_of_space">No more room in the Favorites tray</string>
<!-- All applications label -->
<string name="all_apps_button_label">Apps list</string>
- <string name="all_apps_search_results">Search results</string>
<string name="all_apps_button_personal_label">Personal apps list</string>
<string name="all_apps_button_work_label">Work apps list</string>
@@ -181,30 +180,27 @@
<string name="permdesc_install_shortcut">Allows an app to add
shortcuts without user intervention.</string>
<!-- Permission short label -->
- <string name="permlab_read_settings">read home settings and shortcuts</string>
+ <string name="permlab_read_settings">read Home settings and shortcuts</string>
<!-- Permission description -->
<string name="permdesc_read_settings">Allows the app to read the settings and
- shortcuts in home.</string>
+ shortcuts in Home.</string>
<!-- Permission short label -->
- <string name="permlab_write_settings">write home settings and shortcuts</string>
+ <string name="permlab_write_settings">write Home settings and shortcuts</string>
<!-- Permission description -->
<string name="permdesc_write_settings">Allows the app to change the settings and
- shortcuts in home.</string>
+ shortcuts in Home.</string>
<!-- Toast shown on clicking a direct call shortcut. [CHAR_LIMIT=80] -->
<string name="msg_no_phone_permission"><xliff:g id="app_name" example="Launcher3">%1$s</xliff:g> is not allowed to make phone calls</string>
<!-- Widgets: -->
- <skip />
+ <skip />
<!-- Error text that lets a user know that the widget can't load. -->
<string name="gadget_error_text">Can\'t load widget</string>
- <!-- Button text. This button lets a user change a widget's settings. -->
- <string name="gadget_setup_text">Widget settings</string>
-
<!-- Instructional text to encourage a user to finish setting up the widget. -->
- <string name="gadget_complete_setup_text">Tap to finish setup</string>
+ <string name="gadget_setup_text">Tap to finish setup</string>
<!-- Text to inform the user that they can't uninstall a system application -->
<string name="uninstall_system_app_text">This is a system app and can\'t be uninstalled.</string>
@@ -215,13 +211,11 @@
<!-- Accessibility -->
<!-- The format string for when an app is temporarily disabled. -->
<string name="disabled_app_label">Disabled <xliff:g id="app_name" example="Messenger">%1$s</xliff:g></string>
- <!-- The format string for when an app has a notification dot (meaning it has associated notifications). [ICU_FORMAT]-->
- <string name="dotted_app_label">
- {count, plural,
- =1 {{app_name} has # notification}
- other {{app_name} has # notifications}
- }
- </string>
+ <!-- The format string for when an app has a notification dot (meaning it has associated notifications). -->
+ <plurals name="dotted_app_label">
+ <item quantity="one"><xliff:g id="app_name" example="Messenger">%1$s</xliff:g>, has <xliff:g id="notification_count" example="1">%2$d</xliff:g> notification</item>
+ <item quantity="other"><xliff:g id="app_name" example="Messenger">%1$s</xliff:g>, has <xliff:g id="notification_count" example="3">%2$d</xliff:g> notifications</item>
+ </plurals>
<skip />
<!-- The format string for default page scroll text [CHAR_LIMIT=none] -->
@@ -252,14 +246,14 @@
<string name="wallpaper_button_text">Wallpapers</string>
<!-- Text for wallpaper change button [CHAR LIMIT=30]-->
<string name="styles_wallpaper_button_text">Wallpaper &amp; style</string>
- <!-- Text for settings button [CHAR LIMIT=20]-->
+ <!-- Text for settings button [CHAR LIMIT=30]-->
<string name="settings_button_text">Home settings</string>
<!-- Message shown when a feature is disabled by the administrator -->
<string name="msg_disabled_by_admin">Disabled by your admin</string>
<!-- Strings for settings -->
<!-- Title for Allow Rotation setting. [CHAR LIMIT=50] -->
- <string name="allow_rotation_title">Allow home screen rotation</string>
+ <string name="allow_rotation_title">Allow Home screen rotation</string>
<!-- Text explaining when the home screen will get rotated. [CHAR LIMIT=100] -->
<string name="allow_rotation_desc">When phone is rotated</string>
<!-- Title for Notification dots setting. Tapping this will link to the system Notifications settings screen where the user can turn off notification dots globally. [CHAR LIMIT=50] -->
@@ -277,11 +271,8 @@
<!-- Summary for Notification dots setting. Tapping this will link enable/disable notification dots feature on the home screen. [CHAR LIMIT=50] -->
<string name="notification_dots_service_title">Show notification dots</string>
- <!-- Title for Developer Options setting. [CHAR LIMIT=50] -->
- <string name="developer_options_title">Developer Options</string>
-
<!-- Label for the setting that allows the automatic placement of launcher shortcuts for applications and games installed on the device [CHAR LIMIT=60] -->
- <string name="auto_add_shortcuts_label">Add app icons to home screen</string>
+ <string name="auto_add_shortcuts_label">Add app icons to Home screen</string>
<!-- Text description of the setting that allows the automatic placement of launcher shortcuts for applications and games installed on the device [CHAR LIMIT=NONE] -->
<string name="auto_add_shortcuts_description">For new apps</string>
@@ -306,17 +297,6 @@
<!-- Title for an app whose download has been started. -->
<string name="app_waiting_download_title"><xliff:g id="name" example="Messenger">%1$s</xliff:g> waiting to install</string>
-
- <!-- Title shown on the alert dialog prompting the user to update the application in market
- in order to re-enable the disabled shortcuts -->
- <string name="dialog_update_title">App update required</string>
- <!-- Message shown on the alert dialog prompting the user to update the application -->
- <string name="dialog_update_message">The app for this icon isn\'t updated. You can update manually to re-enable this shortcut, or remove the icon.</string>
- <!-- Message for the update button in the alert dialog, will bring the user to market -->
- <string name="dialog_update">Update</string>
- <!-- Message for the remove button in the alert dialog -->
- <string name="dialog_remove">Remove</string>
-
<!-- Strings for widgets & more in the popup container/bottom sheet -->
<!-- Accessibility title for the popup containing a list of widgets. [CHAR_LIMIT=50] -->
@@ -324,9 +304,9 @@
<!-- Text announced by accessibility when the popup containing the list of widgets is closed. [CHAR_LIMIT=100] -->
<string name="widgets_list_closed">Widgets list closed</string>
- <!-- Strings for accessibility actions -->
+<!-- Strings for accessibility actions -->
<!-- Accessibility action to add an app to workspace. [CHAR_LIMIT=30] -->
- <string name="action_add_to_workspace">Add to home screen</string>
+ <string name="action_add_to_workspace">Add to Home screen</string>
<!-- Accessibility action to move item to the current location. [CHAR_LIMIT=30] -->
<string name="action_move_here">Move item here</string>
@@ -371,7 +351,7 @@
<string name="folder_created">Folder created</string>
<!-- Accessibility action to move an item from folder to workspace. [CHAR_LIMIT=30] -->
- <string name="action_move_to_workspace">Move to home screen</string>
+ <string name="action_move_to_workspace">Move to Home screen</string>
<!-- Accessibility action to resize a widget. [CHAR_LIMIT=30] -->
<string name="action_resize">Resize</string>
@@ -431,17 +411,13 @@
<string name="work_apps_paused_edu_accept">Got it</string>
<!-- button string shown pause work profile -->
- <string name="work_apps_pause_btn_text">Pause work apps</string>
+ <string name="work_apps_pause_btn_text">Turn off work apps</string>
<!-- button string shown enable work profile -->
<string name="work_apps_enable_btn_text">Turn on work apps</string>
<!-- A hint shown in launcher settings develop options filter box -->
<string name="developer_options_filter_hint">Filter</string>
- <!-- Title for preference screen show in Home Settings related to smart search preferences. [CHAR LIMIT=50]-->
- <string name="search_pref_screen_title">Search your phone</string>
- <!-- Title for preference screen show in Home Settings related to smart search preferences. [CHAR LIMIT=50]-->
- <string name="search_pref_screen_title_tablet">Search your tablet</string>
<!-- Failed action error message: e.g. Failed: Pause -->
<string name="remote_action_failed">Failed: <xliff:g id="what" example="Pause">%1$s</xliff:g></string>
</resources>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 21095109a6..d30b80c813 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -50,9 +50,7 @@
<item name="workspaceStatusBarScrim">@drawable/workspace_bg</item>
<item name="widgetsTheme">@style/WidgetContainerTheme</item>
<item name="folderDotColor">@color/folder_dot_color</item>
- <item name="folderPaginationColor">@color/folder_pagination_color_light</item>
- <item name="folderPreviewColor">@color/folder_preview_light</item>
- <item name="folderBackgroundColor">@color/folder_background_light</item>
+ <item name="folderFillColor">@color/folder_background_light</item>
<item name="folderIconBorderColor">?android:attr/colorPrimary</item>
<item name="folderTextColor">@color/workspace_text_color_dark</item>
<item name="isFolderDarkText">true</item>
@@ -76,7 +74,7 @@
</style>
<style name="LauncherTheme.DarkMainColor" parent="@style/LauncherTheme">
- <item name="disabledIconAlpha">.54</item>
+ <item name="disabledIconAlpha">.254</item>
</style>
@@ -110,9 +108,7 @@
<item name="popupShadeThird">@color/popup_shade_third_dark</item>
<item name="widgetsTheme">@style/WidgetContainerTheme.Dark</item>
<item name="folderDotColor">@color/folder_dot_color</item>
- <item name="folderPaginationColor">@color/folder_pagination_color_dark</item>
- <item name="folderPreviewColor">@color/folder_preview_dark</item>
- <item name="folderBackgroundColor">@color/folder_background_dark</item>
+ <item name="folderFillColor">@color/folder_background_dark</item>
<item name="folderIconBorderColor">?android:attr/colorPrimary</item>
<item name="folderTextColor">@color/workspace_text_color_light</item>
<item name="isFolderDarkText">false</item>
@@ -151,18 +147,18 @@
<style name="AppTheme.Dark.DarkMainColor" parent="@style/LauncherTheme.Dark.DarkMainColor" />
<style name="AppTheme.Dark.DarkText" parent="@style/LauncherTheme.Dark.DarkText" />
- <style name="HomeSettings.Theme" parent="@android:style/Theme.DeviceDefault.Settings">
+ <style name="HomeSettingsTheme" parent="@android:style/Theme.DeviceDefault.Settings">
<item name="android:navigationBarColor">?android:colorPrimaryDark</item>
<item name="android:windowActionBar">false</item>
<item name="android:windowNoTitle">true</item>
- <item name="preferenceTheme">@style/HomeSettings.PreferenceTheme</item>
+ <item name="preferenceTheme">@style/HomeSettingsPreferenceTheme</item>
</style>
- <style name="HomeSettings.PreferenceTheme" parent="@style/PreferenceThemeOverlay.v14.Material">
- <item name="preferenceFragmentCompatStyle">@style/HomeSettings.FragmentCompatStyle</item>
+ <style name="HomeSettingsPreferenceTheme" parent="@style/PreferenceThemeOverlay.v14.Material">
+ <item name="preferenceFragmentCompatStyle">@style/HomeSettingsFragmentCompatStyle</item>
</style>
- <style name="HomeSettings.FragmentCompatStyle" parent="@style/PreferenceFragment.Material">
+ <style name="HomeSettingsFragmentCompatStyle" parent="@style/PreferenceFragment.Material">
<item name="android:layout">@layout/home_settings</item>
</style>
@@ -203,14 +199,6 @@
<item name="android:importantForAccessibility">no</item>
</style>
- <style name="AllAppsButtonTheme">
- <item name="allAppsButtonBgColor">@color/all_apps_button_bg_color</item>
- <item name="allAppsButtonColor1">@color/all_apps_button_color_1</item>
- <item name="allAppsButtonColor2">@color/all_apps_button_color_2</item>
- <item name="allAppsButtonColor3">@color/all_apps_button_color_3</item>
- <item name="allAppsButtonColor4">@color/all_apps_button_color_4</item>
- </style>
-
<style name="AllAppsTheme">
<item name="disabledIconAlpha">.54</item>
</style>
@@ -271,7 +259,7 @@
<!-- Drop targets -->
<style name="DropTargetButtonBase" parent="@android:style/TextAppearance.DeviceDefault">
- <item name="android:drawablePadding">@dimen/drop_target_button_drawable_padding</item>
+ <item name="android:drawablePadding">8dp</item>
<item name="android:padding">14dp</item>
<item name="android:textColor">@color/drop_target_text</item>
<item name="android:textSize">@dimen/drop_target_text_size</item>
diff --git a/res/xml/backupscheme.xml b/res/xml/backupscheme.xml
index 0f0dde24e2..299e92ea10 100644
--- a/res/xml/backupscheme.xml
+++ b/res/xml/backupscheme.xml
@@ -2,11 +2,6 @@
<full-backup-content xmlns:android="http://schemas.android.com/apk/res/android">
<include domain="database" path="launcher.db" />
- <include domain="database" path="launcher_6_by_5.db" />
- <include domain="database" path="launcher_4_by_5.db" />
- <include domain="database" path="launcher_4_by_4.db" />
- <include domain="database" path="launcher_3_by_3.db" />
- <include domain="database" path="launcher_2_by_2.db" />
<include domain="sharedpref" path="com.android.launcher3.prefs.xml" />
<include domain="file" path="downgrade_schema.json" />
diff --git a/res/xml/default_test_workspace.xml b/res/xml/default_test_workspace.xml
deleted file mode 100644
index bd718b3b14..0000000000
--- a/res/xml/default_test_workspace.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2022 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<!-- Split display specific version of Launcher3/res/xml/default_workspace_4x4.xml -->
-<favorites xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3" >
-
- <!-- Launcher Test Activity -->
- <resolve
- launcher:container="-101"
- launcher:screen="0"
- launcher:x="0"
- launcher:y="0" >
- <favorite launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.CATEGORY_TEST;component=com.google.android.apps.nexuslauncher.tests/com.android.launcher3.testcomponent.BaseTestingActivity;end" />
- </resolve>
-
-</favorites>
diff --git a/res/xml/default_workspace_5x5.xml b/res/xml/default_workspace_5x5.xml
index b4ac8f63df..ccdde2ca80 100644
--- a/res/xml/default_workspace_5x5.xml
+++ b/res/xml/default_workspace_5x5.xml
@@ -94,5 +94,4 @@
<favorite launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_MARKET;end" />
<favorite launcher:uri="market://details?id=com.android.launcher" />
</resolve>
-
</favorites>
diff --git a/res/xml/default_workspace_6x5.xml b/res/xml/default_workspace_6x5.xml
deleted file mode 100644
index b078cfd7f8..0000000000
--- a/res/xml/default_workspace_6x5.xml
+++ /dev/null
@@ -1,76 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2021 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.
--->
-
-<favorites xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3">
-
- <!-- Hotseat (We use the screen as the position of the item in the hotseat) -->
- <!-- Mail Calendar Gallery Store Internet Camera -->
- <resolve
- launcher:container="-101"
- launcher:screen="0"
- launcher:x="0"
- launcher:y="0" >
- <favorite launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_EMAIL;end" />
- <favorite launcher:uri="mailto:" />
- </resolve>
-
- <resolve
- launcher:container="-101"
- launcher:screen="1"
- launcher:x="1"
- launcher:y="0" >
- <favorite launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_CALENDAR;end" />
- </resolve>
-
- <resolve
- launcher:container="-101"
- launcher:screen="2"
- launcher:x="2"
- launcher:y="0" >
- <favorite launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_GALLERY;end" />
- <favorite launcher:uri="#Intent;type=images/*;end" />
- </resolve>
-
- <resolve
- launcher:container="-101"
- launcher:screen="3"
- launcher:x="3"
- launcher:y="0" >
- <favorite launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_MARKET;end" />
- <favorite launcher:uri="market://details?id=com.android.launcher" />
- </resolve>
-
- <resolve
- launcher:container="-101"
- launcher:screen="4"
- launcher:x="4"
- launcher:y="0" >
- <favorite
- launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_BROWSER;end" />
- <favorite launcher:uri="http://www.example.com/" />
- </resolve>
-
- <!-- Resolve camera intent if GoogleCamera is not available e.g. on emulator -->
- <resolve
- launcher:container="-101"
- launcher:screen="5"
- launcher:x="5"
- launcher:y="0" >
- <favorite launcher:uri="#Intent;action=android.media.action.STILL_IMAGE_CAMERA;end" />
- <favorite launcher:uri="#Intent;action=android.intent.action.CAMERA_BUTTON;end" />
- </resolve>
-
-</favorites>
diff --git a/res/xml/device_profiles.xml b/res/xml/device_profiles.xml
index 08025528ce..256999cd7f 100644
--- a/res/xml/device_profiles.xml
+++ b/res/xml/device_profiles.xml
@@ -25,8 +25,7 @@
launcher:numFolderColumns="3"
launcher:numHotseatIcons="3"
launcher:dbFile="launcher_3_by_3.db"
- launcher:defaultLayoutId="@xml/default_workspace_3x3"
- launcher:deviceCategory="phone|multi_display" >
+ launcher:defaultLayoutId="@xml/default_workspace_3x3" >
<display-option
launcher:name="Super Short Stubby"
@@ -34,8 +33,6 @@
launcher:minHeightDps="300"
launcher:iconImageSize="48"
launcher:iconTextSize="13.0"
- launcher:allAppsBorderSpace="16"
- launcher:allAppsCellHeight="104"
launcher:canBeDefault="true" />
<display-option
@@ -44,8 +41,6 @@
launcher:minHeightDps="400"
launcher:iconImageSize="48"
launcher:iconTextSize="13.0"
- launcher:allAppsBorderSpace="16"
- launcher:allAppsCellHeight="104"
launcher:canBeDefault="true" />
</grid-option>
@@ -58,8 +53,7 @@
launcher:numFolderColumns="4"
launcher:numHotseatIcons="4"
launcher:dbFile="launcher_4_by_4.db"
- launcher:defaultLayoutId="@xml/default_workspace_4x4"
- launcher:deviceCategory="phone|multi_display" >
+ launcher:defaultLayoutId="@xml/default_workspace_4x4" >
<display-option
launcher:name="Short Stubby"
@@ -67,8 +61,6 @@
launcher:minHeightDps="420"
launcher:iconImageSize="48"
launcher:iconTextSize="13.0"
- launcher:allAppsBorderSpace="16"
- launcher:allAppsCellHeight="104"
launcher:canBeDefault="true" />
<display-option
@@ -77,8 +69,6 @@
launcher:minHeightDps="450"
launcher:iconImageSize="48"
launcher:iconTextSize="13.0"
- launcher:allAppsBorderSpace="16"
- launcher:allAppsCellHeight="104"
launcher:canBeDefault="true" />
<display-option
@@ -87,8 +77,6 @@
launcher:minHeightDps="491.33"
launcher:iconImageSize="48"
launcher:iconTextSize="13.0"
- launcher:allAppsBorderSpace="16"
- launcher:allAppsCellHeight="104"
launcher:canBeDefault="true" />
<display-option
@@ -97,8 +85,6 @@
launcher:minHeightDps="567"
launcher:iconImageSize="54"
launcher:iconTextSize="13.0"
- launcher:allAppsBorderSpace="16"
- launcher:allAppsCellHeight="104"
launcher:canBeDefault="true" />
<display-option
@@ -107,8 +93,6 @@
launcher:minHeightDps="567"
launcher:iconImageSize="54"
launcher:iconTextSize="13.0"
- launcher:allAppsBorderSpace="16"
- launcher:allAppsCellHeight="104"
launcher:canBeDefault="true" />
</grid-option>
@@ -121,8 +105,7 @@
launcher:numFolderColumns="4"
launcher:numHotseatIcons="5"
launcher:dbFile="launcher.db"
- launcher:defaultLayoutId="@xml/default_workspace_5x5"
- launcher:deviceCategory="phone|multi_display" >
+ launcher:defaultLayoutId="@xml/default_workspace_5x5" >
<display-option
launcher:name="Large Phone"
@@ -130,8 +113,6 @@
launcher:minHeightDps="694"
launcher:iconImageSize="56"
launcher:iconTextSize="14.4"
- launcher:allAppsBorderSpace="16"
- launcher:allAppsCellHeight="104"
launcher:canBeDefault="true" />
<display-option
@@ -140,9 +121,7 @@
launcher:minHeightDps="694"
launcher:iconImageSize="56"
launcher:iconTextSize="14.4"
- launcher:allAppsBorderSpace="16"
- launcher:allAppsCellHeight="104"
- launcher:canBeDefault="true" />
+ launcher:canBeDefault="split_display" />
<display-option
launcher:name="Shorter Stubby"
@@ -150,55 +129,6 @@
launcher:minHeightDps="400"
launcher:iconImageSize="48"
launcher:iconTextSize="13.0"
- launcher:allAppsBorderSpace="16"
- launcher:allAppsCellHeight="104"
- launcher:canBeDefault="true" />
-
- </grid-option>
-
- <grid-option
- launcher:name="6_by_5"
- launcher:numRows="5"
- launcher:numColumns="6"
- launcher:numSearchContainerColumns="3"
- launcher:numFolderRows="3"
- launcher:numFolderColumns="3"
- launcher:numHotseatIcons="6"
- launcher:hotseatColumnSpanLandscape="4"
- launcher:numAllAppsColumns="6"
- launcher:isScalable="true"
- launcher:devicePaddingId="@xml/paddings_6x5"
- launcher:dbFile="launcher_6_by_5.db"
- launcher:defaultLayoutId="@xml/default_workspace_6x5"
- launcher:deviceCategory="tablet" >
-
- <display-option
- launcher:name="Tablet"
- launcher:minWidthDps="900"
- launcher:minHeightDps="820"
- launcher:minCellHeight="120"
- launcher:minCellWidth="102"
- launcher:minCellHeightLandscape="104"
- launcher:minCellWidthLandscape="120"
- launcher:iconImageSize="60"
- launcher:iconTextSize="14"
- launcher:borderSpaceHorizontal="16"
- launcher:borderSpaceVertical="64"
- launcher:borderSpaceLandscapeHorizontal="64"
- launcher:borderSpaceLandscapeVertical="16"
- launcher:horizontalMargin="54"
- launcher:horizontalMarginLandscape="120"
- launcher:allAppsCellWidth="96"
- launcher:allAppsCellHeight="142"
- launcher:allAppsCellWidthLandscape="126"
- launcher:allAppsCellHeightLandscape="126"
- launcher:allAppsIconSize="60"
- launcher:allAppsIconTextSize="14"
- launcher:allAppsBorderSpaceHorizontal="8"
- launcher:allAppsBorderSpaceVertical="16"
- launcher:allAppsBorderSpaceLandscape="16"
- launcher:hotseatBorderSpace="58"
- launcher:hotseatBorderSpaceLandscape="50.4"
launcher:canBeDefault="true" />
</grid-option>
diff --git a/res/xml/launcher_preferences.xml b/res/xml/launcher_preferences.xml
index 8a0c909ed8..90de4987f5 100644
--- a/res/xml/launcher_preferences.xml
+++ b/res/xml/launcher_preferences.xml
@@ -53,7 +53,7 @@
<androidx.preference.PreferenceScreen
android:key="pref_developer_options"
android:persistent="false"
- android:title="@string/developer_options_title"
+ android:title="Developer Options"
android:fragment="com.android.launcher3.settings.DeveloperOptionsFragment"/>
</androidx.preference.PreferenceScreen>
diff --git a/res/xml/paddings_6x5.xml b/res/xml/paddings_6x5.xml
deleted file mode 100644
index a72f55412c..0000000000
--- a/res/xml/paddings_6x5.xml
+++ /dev/null
@@ -1,76 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2022 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-
-<device-paddings xmlns:launcher="http://schemas.android.com/apk/res-auto" >
-
- <!-- Some non default screen sizes -->
- <device-padding
- launcher:maxEmptySpace="30dp">
- <workspaceTopPadding
- launcher:a="0.34"
- launcher:b="0"/>
- <workspaceBottomPadding
- launcher:a="0.26"
- launcher:b="0"/>
- <hotseatBottomPadding
- launcher:a="0.4"
- launcher:b="0"/>
- </device-padding>
-
- <device-padding
- launcher:maxEmptySpace="170dp">
- <workspaceTopPadding
- launcher:a="0"
- launcher:b="20dp"/>
- <workspaceBottomPadding
- launcher:a="0.4"
- launcher:b="0"
- launcher:c="20dp"/>
- <hotseatBottomPadding
- launcher:a="0.6"
- launcher:b="0"
- launcher:c="20dp"/>
- </device-padding>
-
- <device-padding
- launcher:maxEmptySpace="410dp">
- <workspaceTopPadding
- launcher:a="0"
- launcher:b="112dp"/>
- <workspaceBottomPadding
- launcher:a="0.4"
- launcher:b="0"
- launcher:c="112dp"/>
- <hotseatBottomPadding
- launcher:a="0.6"
- launcher:b="0"
- launcher:c="112dp"/>
- </device-padding>
-
- <device-padding
- launcher:maxEmptySpace="9999dp">
- <workspaceTopPadding
- launcher:a="0.40"
- launcher:c="36dp"/>
- <workspaceBottomPadding
- launcher:a="0.60"
- launcher:c="36dp"/>
- <hotseatBottomPadding
- launcher:a="0"
- launcher:b="36dp"/>
- </device-padding>
-</device-paddings> \ No newline at end of file
diff --git a/res/xml/size_limits_80x104.xml b/res/xml/size_limits_80x104.xml
new file mode 100644
index 0000000000..41786644fb
--- /dev/null
+++ b/res/xml/size_limits_80x104.xml
@@ -0,0 +1,114 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2021 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.
+-->
+
+<device-paddings xmlns:launcher="http://schemas.android.com/apk/res-auto" >
+
+ <device-padding
+ launcher:maxEmptySpace="88dp">
+ <workspaceTopPadding
+ launcher:a="0"
+ launcher:b="0"/>
+ <workspaceBottomPadding
+ launcher:a="0.52"
+ launcher:b="0"/>
+ <hotseatBottomPadding
+ launcher:a="0.48"
+ launcher:b="0"/>
+ </device-padding>
+
+ <device-padding
+ launcher:maxEmptySpace="100dp">
+ <workspaceTopPadding
+ launcher:a="0"
+ launcher:b="9dp"/>
+ <workspaceBottomPadding
+ launcher:a="0.40"
+ launcher:b="0"
+ launcher:c="9dp"/>
+ <hotseatBottomPadding
+ launcher:a="0.60"
+ launcher:b="0"
+ launcher:c="9dp"/>
+ </device-padding>
+
+ <device-padding
+ launcher:maxEmptySpace="103dp">
+ <workspaceTopPadding
+ launcher:a="0"
+ launcher:b="26dp"/>
+ <workspaceBottomPadding
+ launcher:a="0"
+ launcher:b="20dp"/>
+ <hotseatBottomPadding
+ launcher:a="1"
+ launcher:b="0"
+ launcher:c="46dp"/>
+ </device-padding>
+
+ <device-padding
+ launcher:maxEmptySpace="107dp">
+ <workspaceTopPadding
+ launcher:a="0"
+ launcher:b="9dp"/>
+ <workspaceBottomPadding
+ launcher:a="0"
+ launcher:b="34dp"/>
+ <hotseatBottomPadding
+ launcher:a="1"
+ launcher:b="0"
+ launcher:c="43dp"/>
+ </device-padding>
+
+ <device-padding
+ launcher:maxEmptySpace="120dp">
+ <workspaceTopPadding
+ launcher:a="0"
+ launcher:b="16dp"/>
+ <workspaceBottomPadding
+ launcher:a="1"
+ launcher:c="72dp"/>
+ <hotseatBottomPadding
+ launcher:a="0"
+ launcher:b="56dp"/>
+ </device-padding>
+
+ <device-padding
+ launcher:maxEmptySpace="135dp">
+ <workspaceTopPadding
+ launcher:a="0"
+ launcher:b="39dp"/>
+ <workspaceBottomPadding
+ launcher:a="1"
+ launcher:c="95dp"/>
+ <hotseatBottomPadding
+ launcher:a="0"
+ launcher:b="56dp"/>
+ </device-padding>
+
+ <device-padding
+ launcher:maxEmptySpace="9999dp">
+ <workspaceTopPadding
+ launcher:a="0.40"
+ launcher:c="36dp"/>
+ <workspaceBottomPadding
+ launcher:a="0.60"
+ launcher:c="36dp"/>
+ <hotseatBottomPadding
+ launcher:a="0"
+ launcher:b="36dp"/>
+ </device-padding>
+</device-paddings> \ No newline at end of file
diff --git a/res/xml/widget_sections.xml b/res/xml/widget_sections.xml
deleted file mode 100644
index d755de6f8a..0000000000
--- a/res/xml/widget_sections.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2021 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.
--->
-
-<widget-sections xmlns:launcher="http://schemas.android.com/apk/res-auto">
- <section
- launcher:category="0"
- launcher:sectionDrawable="@drawable/ic_conversations_widget_category"
- launcher:sectionTitle="@string/widget_category_conversations">
- <widget launcher:provider="com.android.systemui/.people.widget.PeopleSpaceWidgetProvider" />
- </section>
-</widget-sections> \ No newline at end of file
diff --git a/robolectric_tests/Android.bp b/robolectric_tests/Android.bp
new file mode 100644
index 0000000000..9ed26ff89e
--- /dev/null
+++ b/robolectric_tests/Android.bp
@@ -0,0 +1,63 @@
+// Copyright (C) 2021 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.
+
+//
+// Launcher Robolectric test target.
+//
+// "robolectric_android-all-stub", not needed, we write our own stubs
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "packages_apps_Launcher3_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["packages_apps_Launcher3_license"],
+}
+
+filegroup {
+ name: "launcher3-robolectric-resources",
+ path: "resources",
+ srcs: ["resources/*"],
+}
+
+filegroup {
+ name: "launcher3-robolectric-src",
+ srcs: ["src/**/*.java"],
+}
+
+android_robolectric_test {
+ name: "LauncherRoboTests",
+ srcs: [
+ ":launcher3-robolectric-src",
+ ":launcher3-test-src-common",
+ ],
+ java_resources: [":launcher3-robolectric-resources"],
+ static_libs: [
+ "truth-prebuilt",
+ "androidx.test.espresso.contrib",
+ "androidx.test.espresso.core",
+ "androidx.test.espresso.intents",
+ "androidx.test.ext.junit",
+ "androidx.test.runner",
+ "androidx.test.rules",
+ "mockito-robolectric-prebuilt",
+ "SystemUISharedLib",
+ ],
+ robolectric_prebuilt_version: "4.5.1",
+ instrumentation_for: "Launcher3",
+
+ test_options: {
+ timeout: 36000,
+ },
+}
diff --git a/robolectric_tests/res/values/overlayable_icons_test.xml b/robolectric_tests/res/values/overlayable_icons_test.xml
new file mode 100644
index 0000000000..5144e52501
--- /dev/null
+++ b/robolectric_tests/res/values/overlayable_icons_test.xml
@@ -0,0 +1,36 @@
+<!--
+ 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.
+-->
+<resources>
+ <!-- overlayable_icons references all of the drawables in this package
+ that are being overlayed by resource overlays. If you remove/rename
+ any of these resources, you must also change the resource overlay icons.-->
+ <array name="overlayable_icons">
+ <item>@drawable/ic_corp</item>
+ <item>@drawable/ic_drag_handle</item>
+ <item>@drawable/ic_hourglass_top</item>
+ <item>@drawable/ic_info_no_shadow</item>
+ <item>@drawable/ic_install_no_shadow</item>
+ <item>@drawable/ic_palette</item>
+ <item>@drawable/ic_pin</item>
+ <item>@drawable/ic_remove_no_shadow</item>
+ <item>@drawable/ic_setting</item>
+ <item>@drawable/ic_smartspace_preferences</item>
+ <item>@drawable/ic_split_screen</item>
+ <item>@drawable/ic_uninstall_no_shadow</item>
+ <item>@drawable/ic_warning</item>
+ <item>@drawable/ic_widget</item>
+ </array>
+</resources>
diff --git a/tests/res/raw/cache_data_updated_task_data.txt b/robolectric_tests/resources/cache_data_updated_task_data.txt
index 603dbe3f92..603dbe3f92 100644
--- a/tests/res/raw/cache_data_updated_task_data.txt
+++ b/robolectric_tests/resources/cache_data_updated_task_data.txt
diff --git a/tests/res/raw/db_schema_v10.json b/robolectric_tests/resources/db_schema_v10.json
index a5e290ef7a..a5e290ef7a 100644
--- a/tests/res/raw/db_schema_v10.json
+++ b/robolectric_tests/resources/db_schema_v10.json
diff --git a/tests/res/raw/package_install_state_change_task_data.txt b/robolectric_tests/resources/package_install_state_change_task_data.txt
index e82ea9d4d6..e82ea9d4d6 100644
--- a/tests/res/raw/package_install_state_change_task_data.txt
+++ b/robolectric_tests/resources/package_install_state_change_task_data.txt
diff --git a/robolectric_tests/resources/robolectric.properties b/robolectric_tests/resources/robolectric.properties
new file mode 100644
index 0000000000..abb6968431
--- /dev/null
+++ b/robolectric_tests/resources/robolectric.properties
@@ -0,0 +1,15 @@
+sdk=30
+
+shadows= \
+ com.android.launcher3.shadows.LShadowAppPredictionManager \
+ com.android.launcher3.shadows.LShadowAppWidgetManager \
+ com.android.launcher3.shadows.LShadowBackupManager \
+ com.android.launcher3.shadows.LShadowDisplay \
+ com.android.launcher3.shadows.LShadowLauncherApps \
+ com.android.launcher3.shadows.ShadowDeviceFlag \
+ com.android.launcher3.shadows.ShadowLooperExecutor \
+ com.android.launcher3.shadows.ShadowMainThreadInitializedObject \
+ com.android.launcher3.shadows.ShadowOverrides \
+ com.android.launcher3.shadows.ShadowSurfaceTransactionApplier \
+
+application=com.android.launcher3.util.LauncherTestApplication
diff --git a/tests/res/raw/widgets_predication_update_task_data.txt b/robolectric_tests/resources/widgets_predication_update_task_data.txt
index 941d1954e2..941d1954e2 100644
--- a/tests/res/raw/widgets_predication_update_task_data.txt
+++ b/robolectric_tests/resources/widgets_predication_update_task_data.txt
diff --git a/tests/src/com/android/launcher3/folder/FolderNameProviderTest.java b/robolectric_tests/src/com/android/launcher3/folder/FolderNameProviderTest.java
index 9c15309f82..2a94d9bc73 100644
--- a/tests/src/com/android/launcher3/folder/FolderNameProviderTest.java
+++ b/robolectric_tests/src/com/android/launcher3/folder/FolderNameProviderTest.java
@@ -15,8 +15,6 @@
*/
package com.android.launcher3.folder;
-import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
-
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
@@ -25,22 +23,22 @@ import android.content.Context;
import android.content.Intent;
import android.os.UserHandle;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
-
import com.android.launcher3.model.data.AppInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo;
-import com.android.launcher3.util.ActivityContextWrapper;
import com.android.launcher3.util.Executors;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.LooperMode;
+import org.robolectric.annotation.LooperMode.Mode;
import java.util.ArrayList;
-@SmallTest
-@RunWith(AndroidJUnit4.class)
+@RunWith(RobolectricTestRunner.class)
+@LooperMode(Mode.PAUSED)
public final class FolderNameProviderTest {
private Context mContext;
private WorkspaceItemInfo mItem1;
@@ -48,7 +46,7 @@ public final class FolderNameProviderTest {
@Before
public void setUp() {
- mContext = new ActivityContextWrapper(getApplicationContext());
+ mContext = RuntimeEnvironment.application;
mItem1 = new WorkspaceItemInfo(new AppInfo(
new ComponentName("a.b.c", "a.b.c/a.b.c.d"),
"title1",
diff --git a/tests/src/com/android/launcher3/logging/FileLogTest.java b/robolectric_tests/src/com/android/launcher3/logging/FileLogTest.java
index e5f8cec114..01b23ba966 100644
--- a/tests/src/com/android/launcher3/logging/FileLogTest.java
+++ b/robolectric_tests/src/com/android/launcher3/logging/FileLogTest.java
@@ -1,17 +1,16 @@
package com.android.launcher3.logging;
-import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
-
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
-
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.LooperMode;
+import org.robolectric.annotation.LooperMode.Mode;
import java.io.File;
import java.io.PrintWriter;
@@ -21,8 +20,8 @@ import java.util.Calendar;
/**
* Tests for {@link FileLog}
*/
-@SmallTest
-@RunWith(AndroidJUnit4.class)
+@RunWith(RobolectricTestRunner.class)
+@LooperMode(Mode.PAUSED)
public class FileLogTest {
private File mTempDir;
@@ -30,7 +29,7 @@ public class FileLogTest {
public void setUp() {
int count = 0;
do {
- mTempDir = new File(getApplicationContext().getCacheDir(),
+ mTempDir = new File(RuntimeEnvironment.application.getCacheDir(),
"log-test-" + (count++));
} while (!mTempDir.mkdir());
diff --git a/robolectric_tests/src/com/android/launcher3/model/AddWorkspaceItemsTaskTest.java b/robolectric_tests/src/com/android/launcher3/model/AddWorkspaceItemsTaskTest.java
new file mode 100644
index 0000000000..8aa6f374aa
--- /dev/null
+++ b/robolectric_tests/src/com/android/launcher3/model/AddWorkspaceItemsTaskTest.java
@@ -0,0 +1,195 @@
+package com.android.launcher3.model;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.Rect;
+import android.util.Pair;
+
+import com.android.launcher3.InvariantDeviceProfile;
+import com.android.launcher3.LauncherAppState;
+import com.android.launcher3.LauncherSettings;
+import com.android.launcher3.LauncherSettings.Favorites;
+import com.android.launcher3.model.BgDataModel.Callbacks;
+import com.android.launcher3.model.data.ItemInfo;
+import com.android.launcher3.model.data.WorkspaceItemInfo;
+import com.android.launcher3.util.ContentWriter;
+import com.android.launcher3.util.GridOccupancy;
+import com.android.launcher3.util.IntArray;
+import com.android.launcher3.util.IntSparseArrayMap;
+import com.android.launcher3.util.LauncherModelHelper;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.LooperMode;
+import org.robolectric.annotation.LooperMode.Mode;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Tests for {@link AddWorkspaceItemsTask}
+ */
+@RunWith(RobolectricTestRunner.class)
+@LooperMode(Mode.PAUSED)
+public class AddWorkspaceItemsTaskTest {
+
+ private final ComponentName mComponent1 = new ComponentName("a", "b");
+ private final ComponentName mComponent2 = new ComponentName("b", "b");
+
+ private Context mTargetContext;
+ private InvariantDeviceProfile mIdp;
+ private LauncherAppState mAppState;
+ private LauncherModelHelper mModelHelper;
+
+ private IntArray mExistingScreens;
+ private IntArray mNewScreens;
+ private IntSparseArrayMap<GridOccupancy> mScreenOccupancy;
+
+ @Before
+ public void setup() {
+ mModelHelper = new LauncherModelHelper();
+ mTargetContext = RuntimeEnvironment.application;
+ mIdp = InvariantDeviceProfile.INSTANCE.get(mTargetContext);
+ mIdp.numColumns = mIdp.numRows = 5;
+ mAppState = LauncherAppState.getInstance(mTargetContext);
+
+ mExistingScreens = new IntArray();
+ mScreenOccupancy = new IntSparseArrayMap<>();
+ mNewScreens = new IntArray();
+ }
+
+ private AddWorkspaceItemsTask newTask(ItemInfo... items) {
+ List<Pair<ItemInfo, Object>> list = new ArrayList<>();
+ for (ItemInfo item : items) {
+ list.add(Pair.create(item, null));
+ }
+ return new AddWorkspaceItemsTask(list);
+ }
+
+ @Test
+ public void testFindSpaceForItem_prefers_second() throws Exception {
+ // First screen has only one hole of size 1
+ int nextId = setupWorkspaceWithHoles(1, 1, new Rect(2, 2, 3, 3));
+
+ // Second screen has 2 holes of sizes 3x2 and 2x3
+ setupWorkspaceWithHoles(nextId, 2, new Rect(2, 0, 5, 2), new Rect(0, 2, 2, 5));
+
+ int[] spaceFound = newTask().findSpaceForItem(
+ mAppState, mModelHelper.getBgDataModel(), mExistingScreens, mNewScreens, 1, 1);
+ assertEquals(2, spaceFound[0]);
+ assertTrue(mScreenOccupancy.get(spaceFound[0])
+ .isRegionVacant(spaceFound[1], spaceFound[2], 1, 1));
+
+ // Find a larger space
+ spaceFound = newTask().findSpaceForItem(
+ mAppState, mModelHelper.getBgDataModel(), mExistingScreens, mNewScreens, 2, 3);
+ assertEquals(2, spaceFound[0]);
+ assertTrue(mScreenOccupancy.get(spaceFound[0])
+ .isRegionVacant(spaceFound[1], spaceFound[2], 2, 3));
+ }
+
+ @Test
+ public void testFindSpaceForItem_adds_new_screen() throws Exception {
+ // First screen has 2 holes of sizes 3x2 and 2x3
+ setupWorkspaceWithHoles(1, 1, new Rect(2, 0, 5, 2), new Rect(0, 2, 2, 5));
+
+ IntArray oldScreens = mExistingScreens.clone();
+ int[] spaceFound = newTask().findSpaceForItem(
+ mAppState, mModelHelper.getBgDataModel(), mExistingScreens, mNewScreens, 3, 3);
+ assertFalse(oldScreens.contains(spaceFound[0]));
+ assertTrue(mNewScreens.contains(spaceFound[0]));
+ }
+
+ @Test
+ public void testAddItem_existing_item_ignored() throws Exception {
+ WorkspaceItemInfo info = new WorkspaceItemInfo();
+ info.intent = new Intent().setComponent(mComponent1);
+
+ // Setup a screen with a hole
+ setupWorkspaceWithHoles(1, 1, new Rect(2, 2, 3, 3));
+
+ // Nothing was added
+ assertTrue(mModelHelper.executeTaskForTest(newTask(info)).isEmpty());
+ }
+
+ @Test
+ public void testAddItem_some_items_added() throws Exception {
+ Callbacks callbacks = mock(Callbacks.class);
+ mModelHelper.getModel().addCallbacks(callbacks);
+
+ WorkspaceItemInfo info = new WorkspaceItemInfo();
+ info.intent = new Intent().setComponent(mComponent1);
+
+ WorkspaceItemInfo info2 = new WorkspaceItemInfo();
+ info2.intent = new Intent().setComponent(mComponent2);
+
+ // Setup a screen with a hole
+ setupWorkspaceWithHoles(1, 1, new Rect(2, 2, 3, 3));
+
+ mModelHelper.executeTaskForTest(newTask(info, info2)).get(0).run();
+ ArgumentCaptor<ArrayList> notAnimated = ArgumentCaptor.forClass(ArrayList.class);
+ ArgumentCaptor<ArrayList> animated = ArgumentCaptor.forClass(ArrayList.class);
+
+ // only info2 should be added because info was already added to the workspace
+ // in setupWorkspaceWithHoles()
+ verify(callbacks).bindAppsAdded(any(IntArray.class), notAnimated.capture(),
+ animated.capture());
+ assertTrue(notAnimated.getValue().isEmpty());
+
+ assertEquals(1, animated.getValue().size());
+ assertTrue(animated.getValue().contains(info2));
+ }
+
+ private int setupWorkspaceWithHoles(int startId, int screenId, Rect... holes) throws Exception {
+ return mModelHelper.executeSimpleTask(
+ model -> writeWorkspaceWithHoles(model, startId, screenId, holes));
+ }
+
+ private int writeWorkspaceWithHoles(
+ BgDataModel bgDataModel, int startId, int screenId, Rect... holes) {
+ GridOccupancy occupancy = new GridOccupancy(mIdp.numColumns, mIdp.numRows);
+ occupancy.markCells(0, 0, mIdp.numColumns, mIdp.numRows, true);
+ for (Rect r : holes) {
+ occupancy.markCells(r, false);
+ }
+
+ mExistingScreens.add(screenId);
+ mScreenOccupancy.append(screenId, occupancy);
+
+ for (int x = 0; x < mIdp.numColumns; x++) {
+ for (int y = 0; y < mIdp.numRows; y++) {
+ if (!occupancy.cells[x][y]) {
+ continue;
+ }
+
+ WorkspaceItemInfo info = new WorkspaceItemInfo();
+ info.intent = new Intent().setComponent(mComponent1);
+ info.id = startId++;
+ info.screenId = screenId;
+ info.cellX = x;
+ info.cellY = y;
+ info.container = LauncherSettings.Favorites.CONTAINER_DESKTOP;
+ bgDataModel.addItem(mTargetContext, info, false);
+
+ ContentWriter writer = new ContentWriter(mTargetContext);
+ info.writeToValues(writer);
+ writer.put(Favorites._ID, info.id);
+ mTargetContext.getContentResolver().insert(Favorites.CONTENT_URI,
+ writer.getValues(mTargetContext));
+ }
+ }
+ return startId;
+ }
+}
diff --git a/tests/src/com/android/launcher3/model/BackupRestoreTest.java b/robolectric_tests/src/com/android/launcher3/model/BackupRestoreTest.java
index 41914de1ab..34a8025b39 100644
--- a/tests/src/com/android/launcher3/model/BackupRestoreTest.java
+++ b/robolectric_tests/src/com/android/launcher3/model/BackupRestoreTest.java
@@ -17,7 +17,6 @@
package com.android.launcher3.model;
import static android.content.pm.PackageManager.INSTALL_REASON_DEVICE_RESTORE;
-import static android.os.Process.myUserHandle;
import static com.android.launcher3.LauncherSettings.Favorites.BACKUP_TABLE_NAME;
import static com.android.launcher3.LauncherSettings.Favorites.TABLE_NAME;
@@ -27,110 +26,74 @@ import static com.android.launcher3.provider.LauncherDbUtils.tableExists;
import static com.android.launcher3.util.LauncherModelHelper.APP_ICON;
import static com.android.launcher3.util.LauncherModelHelper.NO__ICON;
import static com.android.launcher3.util.LauncherModelHelper.SHORTCUT;
-import static com.android.launcher3.util.ReflectionHelpers.getField;
-import static com.android.launcher3.util.ReflectionHelpers.setField;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.spy;
+import static org.robolectric.util.ReflectionHelpers.setField;
import android.app.backup.BackupManager;
import android.content.pm.PackageInstaller;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
+import android.os.Process;
import android.os.UserHandle;
-import android.util.ArrayMap;
-import android.util.LongSparseArray;
-
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
+import android.os.UserManager;
import com.android.launcher3.InvariantDeviceProfile;
-import com.android.launcher3.pm.UserCache;
import com.android.launcher3.provider.RestoreDbTask;
+import com.android.launcher3.shadows.LShadowBackupManager;
import com.android.launcher3.util.LauncherModelHelper;
-import com.android.launcher3.util.SafeCloseable;
-import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.LooperMode;
+import org.robolectric.shadow.api.Shadow;
+import org.robolectric.shadows.ShadowUserManager;
/**
* Tests to verify backup and restore flow.
*/
-@SmallTest
-@RunWith(AndroidJUnit4.class)
+@RunWith(RobolectricTestRunner.class)
+@LooperMode(LooperMode.Mode.PAUSED)
public class BackupRestoreTest {
- private static final int PER_USER_RANGE = 200000;
-
-
- private long mCurrentMyProfileId;
- private long mOldMyProfileId;
-
- private long mCurrentWorkProfileId;
- private long mOldWorkProfileId;
+ private static final long MY_OLD_PROFILE_ID = 1;
+ private static final long MY_PROFILE_ID = 0;
+ private static final long OLD_WORK_PROFILE_ID = 11;
+ private static final int WORK_PROFILE_ID = 10;
+ private ShadowUserManager mUserManager;
private BackupManager mBackupManager;
private LauncherModelHelper mModelHelper;
private SQLiteDatabase mDb;
private InvariantDeviceProfile mIdp;
- private UserHandle mWorkUserHandle;
-
- private SafeCloseable mUserChangeListener;
-
@Before
public void setUp() {
- mModelHelper = new LauncherModelHelper();
-
- mCurrentMyProfileId = mModelHelper.defaultProfileId;
- mOldMyProfileId = mCurrentMyProfileId + 1;
- mCurrentWorkProfileId = mOldMyProfileId + 1;
- mOldWorkProfileId = mCurrentWorkProfileId + 1;
-
- mWorkUserHandle = UserHandle.getUserHandleForUid(PER_USER_RANGE);
- mUserChangeListener = UserCache.INSTANCE.get(mModelHelper.sandboxContext)
- .addUserChangeListener(() -> { });
-
setupUserManager();
setupBackupManager();
- RestoreDbTask.setPending(mModelHelper.sandboxContext);
+ mModelHelper = new LauncherModelHelper();
+ RestoreDbTask.setPending(RuntimeEnvironment.application, true);
mDb = mModelHelper.provider.getDb();
- mIdp = InvariantDeviceProfile.INSTANCE.get(mModelHelper.sandboxContext);
-
- }
-
- @After
- public void tearDown() {
- mUserChangeListener.close();
- mModelHelper.destroy();
+ mIdp = InvariantDeviceProfile.INSTANCE.get(RuntimeEnvironment.application);
}
private void setupUserManager() {
- UserCache cache = UserCache.INSTANCE.get(mModelHelper.sandboxContext);
- synchronized (cache) {
- LongSparseArray<UserHandle> users = getField(cache, "mUsers");
- users.clear();
- users.put(mCurrentMyProfileId, myUserHandle());
- users.put(mCurrentWorkProfileId, mWorkUserHandle);
-
- ArrayMap<UserHandle, Long> userMap = getField(cache, "mUserToSerialMap");
- userMap.clear();
- userMap.put(myUserHandle(), mCurrentMyProfileId);
- userMap.put(mWorkUserHandle, mCurrentWorkProfileId);
- }
+ final UserManager userManager = RuntimeEnvironment.application.getSystemService(
+ UserManager.class);
+ mUserManager = Shadow.extract(userManager);
+ // sign in to work profile
+ mUserManager.addUser(WORK_PROFILE_ID, "work", ShadowUserManager.FLAG_MANAGED_PROFILE);
}
private void setupBackupManager() {
- mBackupManager = spy(new BackupManager(mModelHelper.sandboxContext));
- doReturn(myUserHandle()).when(mBackupManager)
- .getUserForAncestralSerialNumber(eq(mOldMyProfileId));
- doReturn(mWorkUserHandle).when(mBackupManager)
- .getUserForAncestralSerialNumber(eq(mOldWorkProfileId));
+ mBackupManager = new BackupManager(RuntimeEnvironment.application);
+ final LShadowBackupManager bm = Shadow.extract(mBackupManager);
+ bm.addProfile(MY_OLD_PROFILE_ID, Process.myUserHandle());
+ bm.addProfile(OLD_WORK_PROFILE_ID, UserHandle.of(WORK_PROFILE_ID));
}
@Test
@@ -155,18 +118,18 @@ public class BackupRestoreTest {
{ SHORTCUT, SHORTCUT, NO__ICON, NO__ICON},
{ NO__ICON, NO__ICON, SHORTCUT, SHORTCUT},
{ APP_ICON, SHORTCUT, SHORTCUT, APP_ICON},
- }}, 1, mOldMyProfileId);
+ }}, 1, MY_OLD_PROFILE_ID);
// setup grid for work profile on second screen
mModelHelper.createGrid(new int[][][]{{
{ NO__ICON, APP_ICON, SHORTCUT, SHORTCUT},
{ SHORTCUT, SHORTCUT, NO__ICON, NO__ICON},
{ NO__ICON, NO__ICON, SHORTCUT, SHORTCUT},
{ APP_ICON, SHORTCUT, SHORTCUT, NO__ICON},
- }}, 2, mOldWorkProfileId);
+ }}, 2, OLD_WORK_PROFILE_ID);
// simulates the creation of backup upon restore
- new GridBackupTable(mModelHelper.sandboxContext, mDb, mIdp.numDatabaseHotseatIcons,
+ new GridBackupTable(RuntimeEnvironment.application, mDb, mIdp.numDatabaseHotseatIcons,
mIdp.numColumns, mIdp.numRows).doBackup(
- mOldMyProfileId, GridBackupTable.OPTION_REQUIRES_SANITIZATION);
+ MY_OLD_PROFILE_ID, GridBackupTable.OPTION_REQUIRES_SANITIZATION);
// reset favorites table
createTableUsingOldProfileId();
}
@@ -178,28 +141,28 @@ public class BackupRestoreTest {
private void verifyTableIsFilled(String tableName, boolean sanitized) {
assertEquals(sanitized ? 12 : 13, getCount(mDb,
"SELECT * FROM " + tableName + " WHERE profileId = "
- + (sanitized ? mCurrentMyProfileId : mOldMyProfileId)));
+ + (sanitized ? MY_PROFILE_ID : MY_OLD_PROFILE_ID)));
assertEquals(10, getCount(mDb, "SELECT * FROM " + tableName + " WHERE profileId = "
- + (sanitized ? mCurrentWorkProfileId : mOldWorkProfileId)));
+ + (sanitized ? WORK_PROFILE_ID : OLD_WORK_PROFILE_ID)));
}
private void createTableUsingOldProfileId() {
// simulates the creation of favorites table on old device
dropTable(mDb, TABLE_NAME);
- addTableToDb(mDb, mOldMyProfileId, false);
+ addTableToDb(mDb, MY_OLD_PROFILE_ID, false);
}
private void createRestoreSession() throws Exception {
final PackageInstaller.SessionParams params = new PackageInstaller.SessionParams(
PackageInstaller.SessionParams.MODE_FULL_INSTALL);
- final PackageInstaller installer = mModelHelper.sandboxContext.getPackageManager()
+ final PackageInstaller installer = RuntimeEnvironment.application.getPackageManager()
.getPackageInstaller();
final int sessionId = installer.createSession(params);
final PackageInstaller.SessionInfo info = installer.getSessionInfo(sessionId);
setField(info, "installReason", INSTALL_REASON_DEVICE_RESTORE);
// TODO: (b/148410677) we should verify the following call instead
// InstallSessionHelper.INSTANCE.get(getContext()).restoreDbIfApplicable(info);
- RestoreDbTask.restoreIfPossible(mModelHelper.sandboxContext,
+ RestoreDbTask.restoreIfPossible(RuntimeEnvironment.application,
mModelHelper.provider.getHelper(), mBackupManager);
}
diff --git a/tests/src/com/android/launcher3/model/CacheDataUpdatedTaskTest.java b/robolectric_tests/src/com/android/launcher3/model/CacheDataUpdatedTaskTest.java
index dba0a4063f..9ac3fe761e 100644
--- a/tests/src/com/android/launcher3/model/CacheDataUpdatedTaskTest.java
+++ b/robolectric_tests/src/com/android/launcher3/model/CacheDataUpdatedTaskTest.java
@@ -16,8 +16,6 @@ import android.os.UserHandle;
import android.os.UserManager;
import androidx.annotation.NonNull;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.icons.BitmapInfo;
@@ -28,10 +26,13 @@ import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.launcher3.util.LauncherModelHelper;
-import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.LooperMode;
+import org.robolectric.annotation.LooperMode.Mode;
import java.util.Arrays;
import java.util.HashSet;
@@ -39,8 +40,8 @@ import java.util.HashSet;
/**
* Tests for {@link CacheDataUpdatedTask}
*/
-@SmallTest
-@RunWith(AndroidJUnit4.class)
+@RunWith(RobolectricTestRunner.class)
+@LooperMode(Mode.PAUSED)
public class CacheDataUpdatedTaskTest {
private static final String NEW_LABEL_PREFIX = "new-label-";
@@ -50,10 +51,10 @@ public class CacheDataUpdatedTaskTest {
@Before
public void setup() throws Exception {
mModelHelper = new LauncherModelHelper();
- mModelHelper.initializeData("cache_data_updated_task_data");
+ mModelHelper.initializeData("/cache_data_updated_task_data.txt");
// Add placeholder entries in the cache to simulate update
- Context context = mModelHelper.sandboxContext;
+ Context context = RuntimeEnvironment.application;
IconCache iconCache = LauncherAppState.getInstance(context).getIconCache();
CachingLogic<ItemInfo> placeholderLogic = new CachingLogic<ItemInfo>() {
@Override
@@ -85,11 +86,6 @@ public class CacheDataUpdatedTaskTest {
}
}
- @After
- public void tearDown() {
- mModelHelper.destroy();
- }
-
private CacheDataUpdatedTask newTask(int op, String... pkg) {
return new CacheDataUpdatedTask(op, Process.myUserHandle(),
new HashSet<>(Arrays.asList(pkg)));
diff --git a/tests/src/com/android/launcher3/model/DbDowngradeHelperTest.java b/robolectric_tests/src/com/android/launcher3/model/DbDowngradeHelperTest.java
index d849c8fff9..be03c7dd4b 100644
--- a/tests/src/com/android/launcher3/model/DbDowngradeHelperTest.java
+++ b/robolectric_tests/src/com/android/launcher3/model/DbDowngradeHelperTest.java
@@ -15,13 +15,12 @@
*/
package com.android.launcher3.model;
-import static androidx.test.InstrumentationRegistry.getContext;
-
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertNotSame;
import static junit.framework.Assert.assertTrue;
+import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
@@ -33,10 +32,6 @@ import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
-import androidx.test.platform.app.InstrumentationRegistry;
-
import com.android.launcher3.LauncherProvider;
import com.android.launcher3.LauncherProvider.DatabaseHelper;
import com.android.launcher3.LauncherSettings.Favorites;
@@ -45,14 +40,15 @@ import com.android.launcher3.R;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
import java.io.File;
/**
* Tests for {@link DbDowngradeHelper}
*/
-@SmallTest
-@RunWith(AndroidJUnit4.class)
+@RunWith(RobolectricTestRunner.class)
public class DbDowngradeHelperTest {
private static final String SCHEMA_FILE = "test_schema.json";
@@ -64,7 +60,7 @@ public class DbDowngradeHelperTest {
@Before
public void setup() {
- mContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
+ mContext = RuntimeEnvironment.application;
mSchemaFile = mContext.getFileStreamPath(SCHEMA_FILE);
mDbFile = mContext.getDatabasePath(DB_FILE);
}
@@ -81,10 +77,8 @@ public class DbDowngradeHelperTest {
public void testUpdateSchemaFile() throws Exception {
// Setup mock resources
Resources res = spy(mContext.getResources());
- Resources myRes = getContext().getResources();
- doAnswer(i -> myRes.openRawResource(
- myRes.getIdentifier("db_schema_v10", "raw", getContext().getPackageName())))
- .when(res).openRawResource(R.raw.downgrade_schema);
+ doAnswer(i ->this.getClass().getResourceAsStream("/db_schema_v10.json"))
+ .when(res).openRawResource(eq(R.raw.downgrade_schema));
Context context = spy(mContext);
when(context.getResources()).thenReturn(res);
diff --git a/tests/src/com/android/launcher3/model/DefaultLayoutProviderTest.java b/robolectric_tests/src/com/android/launcher3/model/DefaultLayoutProviderTest.java
index 004ed06b32..655237d08c 100644
--- a/tests/src/com/android/launcher3/model/DefaultLayoutProviderTest.java
+++ b/robolectric_tests/src/com/android/launcher3/model/DefaultLayoutProviderTest.java
@@ -16,18 +16,18 @@
package com.android.launcher3.model;
-import static com.android.launcher3.util.LauncherModelHelper.TEST_ACTIVITY;
import static com.android.launcher3.util.LauncherModelHelper.TEST_PACKAGE;
import static org.junit.Assert.assertEquals;
+import static org.robolectric.Shadows.shadowOf;
+import static org.robolectric.util.ReflectionHelpers.setField;
+import android.content.ComponentName;
import android.content.Context;
import android.content.pm.PackageInstaller;
+import android.content.pm.PackageInstaller.SessionInfo;
import android.content.pm.PackageInstaller.SessionParams;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
-
import com.android.launcher3.LauncherSettings;
import com.android.launcher3.icons.BitmapInfo;
import com.android.launcher3.model.data.FolderInfo;
@@ -35,16 +35,19 @@ import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.util.LauncherLayoutBuilder;
import com.android.launcher3.util.LauncherModelHelper;
-import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.LooperMode;
+import org.robolectric.annotation.LooperMode.Mode;
/**
* Tests for layout parser for remote layout
*/
-@SmallTest
-@RunWith(AndroidJUnit4.class)
+@RunWith(RobolectricTestRunner.class)
+@LooperMode(Mode.PAUSED)
public class DefaultLayoutProviderTest {
private LauncherModelHelper mModelHelper;
@@ -53,18 +56,16 @@ public class DefaultLayoutProviderTest {
@Before
public void setUp() {
mModelHelper = new LauncherModelHelper();
- mTargetContext = mModelHelper.sandboxContext;
- }
+ mTargetContext = RuntimeEnvironment.application;
- @After
- public void tearDown() {
- mModelHelper.destroy();
+ shadowOf(mTargetContext.getPackageManager())
+ .addActivityIfNotPresent(new ComponentName(TEST_PACKAGE, TEST_PACKAGE));
}
@Test
public void testCustomProfileLoaded_with_icon_on_hotseat() throws Exception {
writeLayoutAndLoad(new LauncherLayoutBuilder().atHotseat(0)
- .putApp(TEST_PACKAGE, TEST_ACTIVITY));
+ .putApp(TEST_PACKAGE, TEST_PACKAGE));
// Verify one item in hotseat
assertEquals(1, mModelHelper.getBgDataModel().workspaceItems.size());
@@ -76,9 +77,9 @@ public class DefaultLayoutProviderTest {
@Test
public void testCustomProfileLoaded_with_folder() throws Exception {
writeLayoutAndLoad(new LauncherLayoutBuilder().atHotseat(0).putFolder(android.R.string.copy)
- .addApp(TEST_PACKAGE, TEST_ACTIVITY)
- .addApp(TEST_PACKAGE, TEST_ACTIVITY)
- .addApp(TEST_PACKAGE, TEST_ACTIVITY)
+ .addApp(TEST_PACKAGE, TEST_PACKAGE)
+ .addApp(TEST_PACKAGE, TEST_PACKAGE)
+ .addApp(TEST_PACKAGE, TEST_PACKAGE)
.build());
// Verify folder
@@ -91,9 +92,9 @@ public class DefaultLayoutProviderTest {
@Test
public void testCustomProfileLoaded_with_folder_custom_title() throws Exception {
writeLayoutAndLoad(new LauncherLayoutBuilder().atHotseat(0).putFolder("CustomFolder")
- .addApp(TEST_PACKAGE, TEST_ACTIVITY)
- .addApp(TEST_PACKAGE, TEST_ACTIVITY)
- .addApp(TEST_PACKAGE, TEST_ACTIVITY)
+ .addApp(TEST_PACKAGE, TEST_PACKAGE)
+ .addApp(TEST_PACKAGE, TEST_PACKAGE)
+ .addApp(TEST_PACKAGE, TEST_PACKAGE)
.build());
// Verify folder
@@ -111,10 +112,12 @@ public class DefaultLayoutProviderTest {
// Add a placeholder session info so that the widget exists
SessionParams params = new SessionParams(SessionParams.MODE_FULL_INSTALL);
params.setAppPackageName(pendingAppPkg);
- params.setAppIcon(BitmapInfo.LOW_RES_ICON);
PackageInstaller installer = mTargetContext.getPackageManager().getPackageInstaller();
- installer.createSession(params);
+ int sessionId = installer.createSession(params);
+ SessionInfo sessionInfo = installer.getSessionInfo(sessionId);
+ setField(sessionInfo, "installerPackageName", "com.test");
+ setField(sessionInfo, "appIcon", BitmapInfo.LOW_RES_ICON);
writeLayoutAndLoad(new LauncherLayoutBuilder().atWorkspace(0, 1, 0)
.putWidget(pendingAppPkg, "PlaceholderWidget", 2, 2));
diff --git a/robolectric_tests/src/com/android/launcher3/model/GridBackupTableTest.java b/robolectric_tests/src/com/android/launcher3/model/GridBackupTableTest.java
new file mode 100644
index 0000000000..56ce215d96
--- /dev/null
+++ b/robolectric_tests/src/com/android/launcher3/model/GridBackupTableTest.java
@@ -0,0 +1,135 @@
+package com.android.launcher3.model;
+
+
+import static android.database.DatabaseUtils.queryNumEntries;
+
+import static com.android.launcher3.LauncherSettings.Favorites.BACKUP_TABLE_NAME;
+import static com.android.launcher3.LauncherSettings.Favorites.TABLE_NAME;
+import static com.android.launcher3.provider.LauncherDbUtils.tableExists;
+import static com.android.launcher3.util.LauncherModelHelper.APP_ICON;
+import static com.android.launcher3.util.LauncherModelHelper.DESKTOP;
+import static com.android.launcher3.util.LauncherModelHelper.NO__ICON;
+import static com.android.launcher3.util.LauncherModelHelper.SHORTCUT;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.sqlite.SQLiteDatabase;
+import android.graphics.Point;
+
+import com.android.launcher3.LauncherSettings.Favorites;
+import com.android.launcher3.LauncherSettings.Settings;
+import com.android.launcher3.util.LauncherModelHelper;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+
+/**
+ * Unit tests for {@link GridBackupTable}
+ */
+@RunWith(RobolectricTestRunner.class)
+public class GridBackupTableTest {
+
+ private static final int BACKUP_ITEM_COUNT = 12;
+
+ private LauncherModelHelper mModelHelper;
+ private Context mContext;
+ private SQLiteDatabase mDb;
+
+ @Before
+ public void setUp() {
+ mModelHelper = new LauncherModelHelper();
+ mContext = RuntimeEnvironment.application;
+ mDb = mModelHelper.provider.getDb();
+
+ setupGridData();
+ }
+
+ private void setupGridData() {
+ mModelHelper.createGrid(new int[][][]{{
+ { APP_ICON, APP_ICON, SHORTCUT, SHORTCUT},
+ { SHORTCUT, SHORTCUT, NO__ICON, NO__ICON},
+ { NO__ICON, NO__ICON, SHORTCUT, SHORTCUT},
+ { APP_ICON, SHORTCUT, SHORTCUT, APP_ICON},
+ }});
+ assertEquals(BACKUP_ITEM_COUNT, queryNumEntries(mDb, TABLE_NAME));
+ }
+
+ @Test
+ public void backupTableCreated() {
+ GridBackupTable backupTable = new GridBackupTable(mContext, mDb, 4, 4, 4);
+ assertFalse(backupTable.backupOrRestoreAsNeeded());
+ Settings.call(mContext.getContentResolver(), Settings.METHOD_REFRESH_BACKUP_TABLE);
+
+ assertTrue(tableExists(mDb, BACKUP_TABLE_NAME));
+
+ // One extra entry for properties
+ assertEquals(BACKUP_ITEM_COUNT + 1, queryNumEntries(mDb, BACKUP_TABLE_NAME));
+ }
+
+ @Test
+ public void backupTableRestored() {
+ assertFalse(new GridBackupTable(mContext, mDb, 4, 4, 4).backupOrRestoreAsNeeded());
+ Settings.call(mContext.getContentResolver(), Settings.METHOD_REFRESH_BACKUP_TABLE);
+
+ // Delete entries
+ mDb.delete(TABLE_NAME, null, null);
+ assertEquals(0, queryNumEntries(mDb, TABLE_NAME));
+
+ GridBackupTable backupTable = new GridBackupTable(mContext, mDb, 3, 3, 3);
+ assertTrue(backupTable.backupOrRestoreAsNeeded());
+
+ // Items have been restored
+ assertEquals(BACKUP_ITEM_COUNT, queryNumEntries(mDb, TABLE_NAME));
+
+ Point outSize = new Point();
+ assertEquals(4, backupTable.getRestoreHotseatAndGridSize(outSize));
+ assertEquals(4, outSize.x);
+ assertEquals(4, outSize.y);
+ }
+
+ @Test
+ public void backupTableRemovedOnAdd() {
+ assertFalse(new GridBackupTable(mContext, mDb, 4, 4, 4).backupOrRestoreAsNeeded());
+ Settings.call(mContext.getContentResolver(), Settings.METHOD_REFRESH_BACKUP_TABLE);
+
+ assertTrue(tableExists(mDb, BACKUP_TABLE_NAME));
+
+ mModelHelper.addItem(1, 2, DESKTOP, 1, 1);
+ assertFalse(tableExists(mDb, BACKUP_TABLE_NAME));
+ }
+
+ @Test
+ public void backupTableRemovedOnDelete() {
+ assertFalse(new GridBackupTable(mContext, mDb, 4, 4, 4).backupOrRestoreAsNeeded());
+ Settings.call(mContext.getContentResolver(), Settings.METHOD_REFRESH_BACKUP_TABLE);
+
+ assertTrue(tableExists(mDb, BACKUP_TABLE_NAME));
+
+ mContext.getContentResolver().delete(Favorites.CONTENT_URI, null, null);
+ assertFalse(tableExists(mDb, BACKUP_TABLE_NAME));
+ }
+
+ @Test
+ public void backupTableRetainedOnUpdate() {
+ assertFalse(new GridBackupTable(mContext, mDb, 4, 4, 4).backupOrRestoreAsNeeded());
+ Settings.call(mContext.getContentResolver(), Settings.METHOD_REFRESH_BACKUP_TABLE);
+
+ assertTrue(tableExists(mDb, BACKUP_TABLE_NAME));
+
+ ContentValues values = new ContentValues();
+ values.put(Favorites.RANK, 4);
+ // Something was updated
+ assertTrue(mContext.getContentResolver()
+ .update(Favorites.CONTENT_URI, values, null, null) > 0);
+
+ // Backup table remains
+ assertTrue(tableExists(mDb, BACKUP_TABLE_NAME));
+ }
+}
diff --git a/robolectric_tests/src/com/android/launcher3/model/GridSizeMigrationTaskTest.java b/robolectric_tests/src/com/android/launcher3/model/GridSizeMigrationTaskTest.java
new file mode 100644
index 0000000000..d544a0b5f3
--- /dev/null
+++ b/robolectric_tests/src/com/android/launcher3/model/GridSizeMigrationTaskTest.java
@@ -0,0 +1,373 @@
+package com.android.launcher3.model;
+
+import static com.android.launcher3.model.GridSizeMigrationTask.getWorkspaceScreenIds;
+import static com.android.launcher3.util.LauncherModelHelper.APP_ICON;
+import static com.android.launcher3.util.LauncherModelHelper.HOTSEAT;
+import static com.android.launcher3.util.LauncherModelHelper.SHORTCUT;
+import static com.android.launcher3.util.LauncherModelHelper.TEST_PACKAGE;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import android.content.Context;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.graphics.Point;
+
+import com.android.launcher3.InvariantDeviceProfile;
+import com.android.launcher3.LauncherSettings;
+import com.android.launcher3.config.FeatureFlags;
+import com.android.launcher3.model.GridSizeMigrationTask.MultiStepMigrationTask;
+import com.android.launcher3.util.IntArray;
+import com.android.launcher3.util.LauncherModelHelper;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+
+import java.util.HashSet;
+import java.util.LinkedList;
+
+/**
+ * Unit tests for {@link GridSizeMigrationTask}
+ */
+@RunWith(RobolectricTestRunner.class)
+public class GridSizeMigrationTaskTest {
+
+ private LauncherModelHelper mModelHelper;
+ private Context mContext;
+ private SQLiteDatabase mDb;
+
+ private HashSet<String> mValidPackages;
+ private InvariantDeviceProfile mIdp;
+
+ @Before
+ public void setUp() {
+ mModelHelper = new LauncherModelHelper();
+ mContext = RuntimeEnvironment.application;
+ mDb = mModelHelper.provider.getDb();
+
+ mValidPackages = new HashSet<>();
+ mValidPackages.add(TEST_PACKAGE);
+ mIdp = InvariantDeviceProfile.INSTANCE.get(mContext);
+ }
+
+ @Test
+ public void testHotseatMigration_apps_dropped() throws Exception {
+ int[] hotseatItems = {
+ mModelHelper.addItem(APP_ICON, 0, HOTSEAT, 0, 0),
+ mModelHelper.addItem(SHORTCUT, 1, HOTSEAT, 0, 0),
+ -1,
+ mModelHelper.addItem(SHORTCUT, 3, HOTSEAT, 0, 0),
+ mModelHelper.addItem(APP_ICON, 4, HOTSEAT, 0, 0),
+ };
+
+ mIdp.numDatabaseHotseatIcons = 3;
+ new GridSizeMigrationTask(mContext, mDb, mValidPackages, false, 5, 3)
+ .migrateHotseat();
+ // First item is dropped as it has the least weight.
+ verifyHotseat(hotseatItems[1], hotseatItems[3], hotseatItems[4]);
+ }
+
+ @Test
+ public void testHotseatMigration_shortcuts_dropped() throws Exception {
+ int[] hotseatItems = {
+ mModelHelper.addItem(APP_ICON, 0, HOTSEAT, 0, 0),
+ mModelHelper.addItem(30, 1, HOTSEAT, 0, 0),
+ -1,
+ mModelHelper.addItem(SHORTCUT, 3, HOTSEAT, 0, 0),
+ mModelHelper.addItem(10, 4, HOTSEAT, 0, 0),
+ };
+
+ mIdp.numDatabaseHotseatIcons = 3;
+ new GridSizeMigrationTask(mContext, mDb, mValidPackages, false, 5, 3)
+ .migrateHotseat();
+ // First item is dropped as it has the least weight.
+ verifyHotseat(hotseatItems[1], hotseatItems[3], hotseatItems[4]);
+ }
+
+ private void verifyHotseat(int... sortedIds) {
+ int screenId = 0;
+ int total = 0;
+
+ for (int id : sortedIds) {
+ Cursor c = mContext.getContentResolver().query(LauncherSettings.Favorites.CONTENT_URI,
+ new String[]{LauncherSettings.Favorites._ID},
+ "container=-101 and screen=" + screenId, null, null, null);
+
+ if (id == -1) {
+ assertEquals(0, c.getCount());
+ } else {
+ assertEquals(1, c.getCount());
+ c.moveToNext();
+ assertEquals(id, c.getLong(0));
+ total ++;
+ }
+ c.close();
+
+ screenId++;
+ }
+
+ // Verify that not other entry exist in the DB.
+ Cursor c = mContext.getContentResolver().query(LauncherSettings.Favorites.CONTENT_URI,
+ new String[]{LauncherSettings.Favorites._ID},
+ "container=-101", null, null, null);
+ assertEquals(total, c.getCount());
+ c.close();
+ }
+
+ @Test
+ public void testWorkspace_empty_row_column_removed() throws Exception {
+ int[][][] ids = mModelHelper.createGrid(new int[][][]{{
+ { 0, 0, -1, 1},
+ { 3, 1, -1, 4},
+ { -1, -1, -1, -1},
+ { 5, 2, -1, 6},
+ }});
+
+ new GridSizeMigrationTask(mContext, mDb, mValidPackages, false,
+ new Point(4, 4), new Point(3, 3)).migrateWorkspace();
+
+ // Column 2 and row 2 got removed.
+ verifyWorkspace(new int[][][] {{
+ {ids[0][0][0], ids[0][0][1], ids[0][0][3]},
+ {ids[0][1][0], ids[0][1][1], ids[0][1][3]},
+ {ids[0][3][0], ids[0][3][1], ids[0][3][3]},
+ }});
+ }
+
+ @Test
+ public void testWorkspace_new_screen_created() throws Exception {
+ int[][][] ids = mModelHelper.createGrid(new int[][][]{{
+ { 0, 0, 0, 1},
+ { 3, 1, 0, 4},
+ { -1, -1, -1, -1},
+ { 5, 2, -1, 6},
+ }});
+
+ new GridSizeMigrationTask(mContext, mDb, mValidPackages, false,
+ new Point(4, 4), new Point(3, 3)).migrateWorkspace();
+
+ // Items in the second column get moved to new screen
+ verifyWorkspace(new int[][][] {{
+ {ids[0][0][0], ids[0][0][1], ids[0][0][3]},
+ {ids[0][1][0], ids[0][1][1], ids[0][1][3]},
+ {ids[0][3][0], ids[0][3][1], ids[0][3][3]},
+ }, {
+ {ids[0][0][2], ids[0][1][2], -1},
+ }});
+ }
+
+ @Test
+ public void testWorkspace_items_merged_in_next_screen() throws Exception {
+ int[][][] ids = mModelHelper.createGrid(new int[][][]{{
+ { 0, 0, 0, 1},
+ { 3, 1, 0, 4},
+ { -1, -1, -1, -1},
+ { 5, 2, -1, 6},
+ },{
+ { 0, 0, -1, 1},
+ { 3, 1, -1, 4},
+ }});
+
+ new GridSizeMigrationTask(mContext, mDb, mValidPackages, false,
+ new Point(4, 4), new Point(3, 3)).migrateWorkspace();
+
+ // Items in the second column of the first screen should get placed on the 3rd
+ // row of the second screen
+ verifyWorkspace(new int[][][] {{
+ {ids[0][0][0], ids[0][0][1], ids[0][0][3]},
+ {ids[0][1][0], ids[0][1][1], ids[0][1][3]},
+ {ids[0][3][0], ids[0][3][1], ids[0][3][3]},
+ }, {
+ {ids[1][0][0], ids[1][0][1], ids[1][0][3]},
+ {ids[1][1][0], ids[1][1][1], ids[1][1][3]},
+ {ids[0][0][2], ids[0][1][2], -1},
+ }});
+ }
+
+ @Test
+ public void testWorkspace_items_not_merged_in_next_screen() throws Exception {
+ // First screen has 2 mItems that need to be moved, but second screen has only one
+ // empty space after migration (top-left corner)
+ int[][][] ids = mModelHelper.createGrid(new int[][][]{{
+ { 0, 0, 0, 1},
+ { 3, 1, 0, 4},
+ { -1, -1, -1, -1},
+ { 5, 2, -1, 6},
+ },{
+ { -1, 0, -1, 1},
+ { 3, 1, -1, 4},
+ { -1, -1, -1, -1},
+ { 5, 2, -1, 6},
+ }});
+
+ new GridSizeMigrationTask(mContext, mDb, mValidPackages, false,
+ new Point(4, 4), new Point(3, 3)).migrateWorkspace();
+
+ // Items in the second column of the first screen should get placed on a new screen.
+ verifyWorkspace(new int[][][] {{
+ {ids[0][0][0], ids[0][0][1], ids[0][0][3]},
+ {ids[0][1][0], ids[0][1][1], ids[0][1][3]},
+ {ids[0][3][0], ids[0][3][1], ids[0][3][3]},
+ }, {
+ { -1, ids[1][0][1], ids[1][0][3]},
+ {ids[1][1][0], ids[1][1][1], ids[1][1][3]},
+ {ids[1][3][0], ids[1][3][1], ids[1][3][3]},
+ }, {
+ {ids[0][0][2], ids[0][1][2], -1},
+ }});
+ }
+
+ @Test
+ public void testWorkspace_first_row_blocked() throws Exception {
+ if (!FeatureFlags.QSB_ON_FIRST_SCREEN) {
+ return;
+ }
+ // The first screen has one item on the 4th column which needs moving, as the first row
+ // will be kept empty.
+ int[][][] ids = mModelHelper.createGrid(new int[][][]{{
+ { -1, -1, -1, -1},
+ { 3, 1, 7, 0},
+ { 8, 7, 7, -1},
+ { 5, 2, 7, -1},
+ }}, 0);
+
+ new GridSizeMigrationTask(mContext, mDb, mValidPackages, false,
+ new Point(4, 4), new Point(3, 4)).migrateWorkspace();
+
+ // Items in the second column of the first screen should get placed on a new screen.
+ verifyWorkspace(new int[][][] {{
+ { -1, -1, -1},
+ {ids[0][1][0], ids[0][1][1], ids[0][1][2]},
+ {ids[0][2][0], ids[0][2][1], ids[0][2][2]},
+ {ids[0][3][0], ids[0][3][1], ids[0][3][2]},
+ }, {
+ {ids[0][1][3]},
+ }});
+ }
+
+ @Test
+ public void testWorkspace_items_moved_to_empty_first_row() throws Exception {
+ if (!FeatureFlags.QSB_ON_FIRST_SCREEN) {
+ return;
+ }
+ // Items will get moved to the next screen to keep the first screen empty.
+ int[][][] ids = mModelHelper.createGrid(new int[][][]{{
+ { -1, -1, -1, -1},
+ { 0, 1, 0, 0},
+ { 8, 7, 7, -1},
+ { 5, 6, 7, -1},
+ }}, 0);
+
+ new GridSizeMigrationTask(mContext, mDb, mValidPackages, false,
+ new Point(4, 4), new Point(3, 3)).migrateWorkspace();
+
+ // Items in the second column of the first screen should get placed on a new screen.
+ verifyWorkspace(new int[][][] {{
+ { -1, -1, -1},
+ {ids[0][2][0], ids[0][2][1], ids[0][2][2]},
+ {ids[0][3][0], ids[0][3][1], ids[0][3][2]},
+ }, {
+ {ids[0][1][1], ids[0][1][0], ids[0][1][2]},
+ {ids[0][1][3]},
+ }});
+ }
+
+ /**
+ * Verifies that the workspace mItems are arranged in the provided order.
+ * @param ids A 3d array where the first dimension represents the screen, and the rest two
+ * represent the workspace grid.
+ */
+ private void verifyWorkspace(int[][][] ids) {
+ IntArray allScreens = getWorkspaceScreenIds(mDb, LauncherSettings.Favorites.TABLE_NAME);
+ assertEquals(ids.length, allScreens.size());
+ int total = 0;
+
+ for (int i = 0; i < ids.length; i++) {
+ int screenId = allScreens.get(i);
+ for (int y = 0; y < ids[i].length; y++) {
+ for (int x = 0; x < ids[i][y].length; x++) {
+ int id = ids[i][y][x];
+
+ Cursor c = mContext.getContentResolver().query(
+ LauncherSettings.Favorites.CONTENT_URI,
+ new String[]{LauncherSettings.Favorites._ID},
+ "container=-100 and screen=" + screenId +
+ " and cellX=" + x + " and cellY=" + y, null, null, null);
+ if (id == -1) {
+ assertEquals(0, c.getCount());
+ } else {
+ assertEquals(1, c.getCount());
+ c.moveToNext();
+ assertEquals(String.format("Failed to verify item at %d %d, %d", i, y, x),
+ id, c.getLong(0));
+ total++;
+ }
+ c.close();
+ }
+ }
+ }
+
+ // Verify that not other entry exist in the DB.
+ Cursor c = mContext.getContentResolver().query(LauncherSettings.Favorites.CONTENT_URI,
+ new String[]{LauncherSettings.Favorites._ID},
+ "container=-100", null, null, null);
+ assertEquals(total, c.getCount());
+ c.close();
+ }
+
+ @Test
+ public void testMultiStepMigration_small_to_large() throws Exception {
+ MultiStepMigrationTaskVerifier verifier = new MultiStepMigrationTaskVerifier();
+ verifier.migrate(new Point(3, 3), new Point(5, 5));
+ verifier.assertCompleted();
+ }
+
+ @Test
+ public void testMultiStepMigration_large_to_small() throws Exception {
+ MultiStepMigrationTaskVerifier verifier = new MultiStepMigrationTaskVerifier(
+ 5, 5, 4, 4,
+ 4, 4, 3, 4
+ );
+ verifier.migrate(new Point(5, 5), new Point(3, 4));
+ verifier.assertCompleted();
+ }
+
+ @Test
+ public void testMultiStepMigration_zig_zag() throws Exception {
+ MultiStepMigrationTaskVerifier verifier = new MultiStepMigrationTaskVerifier(
+ 5, 7, 4, 7,
+ 4, 7, 3, 7
+ );
+ verifier.migrate(new Point(5, 5), new Point(3, 7));
+ verifier.assertCompleted();
+ }
+
+ private static class MultiStepMigrationTaskVerifier extends MultiStepMigrationTask {
+
+ private final LinkedList<Point> mPoints;
+
+ public MultiStepMigrationTaskVerifier(int... points) {
+ super(null, null, null, false);
+
+ mPoints = new LinkedList<>();
+ for (int i = 0; i < points.length; i += 2) {
+ mPoints.add(new Point(points[i], points[i + 1]));
+ }
+ }
+
+ @Override
+ protected boolean runStepTask(Point sourceSize, Point nextSize) throws Exception {
+ assertEquals(sourceSize, mPoints.poll());
+ assertEquals(nextSize, mPoints.poll());
+ return false;
+ }
+
+ public void assertCompleted() {
+ assertTrue(mPoints.isEmpty());
+ }
+ }
+}
diff --git a/robolectric_tests/src/com/android/launcher3/model/GridSizeMigrationTaskV2Test.java b/robolectric_tests/src/com/android/launcher3/model/GridSizeMigrationTaskV2Test.java
new file mode 100644
index 0000000000..8e49fae1c7
--- /dev/null
+++ b/robolectric_tests/src/com/android/launcher3/model/GridSizeMigrationTaskV2Test.java
@@ -0,0 +1,286 @@
+/*
+ * Copyright (C) 2020 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.launcher3.model;
+
+import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_DESKTOP;
+import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_HOTSEAT;
+import static com.android.launcher3.LauncherSettings.Favorites.TMP_CONTENT_URI;
+import static com.android.launcher3.provider.LauncherDbUtils.dropTable;
+import static com.android.launcher3.util.LauncherModelHelper.APP_ICON;
+import static com.android.launcher3.util.LauncherModelHelper.DESKTOP;
+import static com.android.launcher3.util.LauncherModelHelper.HOTSEAT;
+import static com.android.launcher3.util.LauncherModelHelper.SHORTCUT;
+import static com.android.launcher3.util.LauncherModelHelper.TEST_PACKAGE;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import android.content.Context;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.graphics.Point;
+import android.os.Process;
+
+import com.android.launcher3.InvariantDeviceProfile;
+import com.android.launcher3.LauncherSettings;
+import com.android.launcher3.pm.UserCache;
+import com.android.launcher3.util.LauncherModelHelper;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+
+import java.util.HashSet;
+
+/** Unit tests for {@link GridSizeMigrationTaskV2} */
+@RunWith(RobolectricTestRunner.class)
+public class GridSizeMigrationTaskV2Test {
+
+ private LauncherModelHelper mModelHelper;
+ private Context mContext;
+ private SQLiteDatabase mDb;
+
+ private HashSet<String> mValidPackages;
+ private InvariantDeviceProfile mIdp;
+
+ private final String testPackage1 = "com.android.launcher3.validpackage1";
+ private final String testPackage2 = "com.android.launcher3.validpackage2";
+ private final String testPackage3 = "com.android.launcher3.validpackage3";
+ private final String testPackage4 = "com.android.launcher3.validpackage4";
+ private final String testPackage5 = "com.android.launcher3.validpackage5";
+ private final String testPackage6 = "com.android.launcher3.validpackage6";
+ private final String testPackage7 = "com.android.launcher3.validpackage7";
+ private final String testPackage8 = "com.android.launcher3.validpackage8";
+ private final String testPackage9 = "com.android.launcher3.validpackage9";
+ private final String testPackage10 = "com.android.launcher3.validpackage10";
+
+ @Before
+ public void setUp() {
+ mModelHelper = new LauncherModelHelper();
+ mContext = RuntimeEnvironment.application;
+ mDb = mModelHelper.provider.getDb();
+
+ mValidPackages = new HashSet<>();
+ mValidPackages.add(TEST_PACKAGE);
+ mValidPackages.add(testPackage1);
+ mValidPackages.add(testPackage2);
+ mValidPackages.add(testPackage3);
+ mValidPackages.add(testPackage4);
+ mValidPackages.add(testPackage5);
+ mValidPackages.add(testPackage6);
+ mValidPackages.add(testPackage7);
+ mValidPackages.add(testPackage8);
+ mValidPackages.add(testPackage9);
+ mValidPackages.add(testPackage10);
+
+ mIdp = InvariantDeviceProfile.INSTANCE.get(mContext);
+
+ long userSerial = UserCache.INSTANCE.get(mContext).getSerialNumberForUser(
+ Process.myUserHandle());
+ dropTable(mDb, LauncherSettings.Favorites.TMP_TABLE);
+ LauncherSettings.Favorites.addTableToDb(mDb, userSerial, false,
+ LauncherSettings.Favorites.TMP_TABLE);
+ }
+
+ @Test
+ public void testMigration() {
+ int[] srcHotseatItems = {
+ mModelHelper.addItem(APP_ICON, 0, HOTSEAT, 0, 0, testPackage1, 1, TMP_CONTENT_URI),
+ mModelHelper.addItem(SHORTCUT, 1, HOTSEAT, 0, 0, testPackage2, 2, TMP_CONTENT_URI),
+ -1,
+ mModelHelper.addItem(SHORTCUT, 3, HOTSEAT, 0, 0, testPackage3, 3, TMP_CONTENT_URI),
+ mModelHelper.addItem(APP_ICON, 4, HOTSEAT, 0, 0, testPackage4, 4, TMP_CONTENT_URI),
+ };
+ mModelHelper.addItem(APP_ICON, 0, DESKTOP, 2, 2, testPackage5, 5, TMP_CONTENT_URI);
+ mModelHelper.addItem(APP_ICON, 0, DESKTOP, 2, 3, testPackage6, 6, TMP_CONTENT_URI);
+ mModelHelper.addItem(APP_ICON, 0, DESKTOP, 4, 1, testPackage8, 8, TMP_CONTENT_URI);
+ mModelHelper.addItem(APP_ICON, 0, DESKTOP, 4, 2, testPackage9, 9, TMP_CONTENT_URI);
+ mModelHelper.addItem(APP_ICON, 0, DESKTOP, 4, 3, testPackage10, 10, TMP_CONTENT_URI);
+
+ int[] destHotseatItems = {
+ -1,
+ mModelHelper.addItem(SHORTCUT, 1, HOTSEAT, 0, 0, testPackage2),
+ -1,
+ };
+ mModelHelper.addItem(APP_ICON, 0, DESKTOP, 2, 2, testPackage7);
+
+ mIdp.numDatabaseHotseatIcons = 4;
+ mIdp.numColumns = 4;
+ mIdp.numRows = 4;
+ GridSizeMigrationTaskV2.DbReader srcReader = new GridSizeMigrationTaskV2.DbReader(mDb,
+ LauncherSettings.Favorites.TMP_TABLE, mContext, mValidPackages,
+ srcHotseatItems.length);
+ GridSizeMigrationTaskV2.DbReader destReader = new GridSizeMigrationTaskV2.DbReader(mDb,
+ LauncherSettings.Favorites.TABLE_NAME, mContext, mValidPackages,
+ mIdp.numDatabaseHotseatIcons);
+ GridSizeMigrationTaskV2 task = new GridSizeMigrationTaskV2(mContext, mDb, srcReader,
+ destReader, mIdp.numDatabaseHotseatIcons, new Point(mIdp.numColumns, mIdp.numRows));
+ task.migrate();
+
+ // Check hotseat items
+ Cursor c = mContext.getContentResolver().query(LauncherSettings.Favorites.CONTENT_URI,
+ new String[]{LauncherSettings.Favorites.SCREEN, LauncherSettings.Favorites.INTENT},
+ "container=" + CONTAINER_HOTSEAT, null, null, null);
+ assertEquals(c.getCount(), mIdp.numDatabaseHotseatIcons);
+ int screenIndex = c.getColumnIndex(LauncherSettings.Favorites.SCREEN);
+ int intentIndex = c.getColumnIndex(LauncherSettings.Favorites.INTENT);
+ c.moveToNext();
+ assertEquals(c.getInt(screenIndex), 1);
+ assertTrue(c.getString(intentIndex).contains(testPackage2));
+ c.moveToNext();
+ assertEquals(c.getInt(screenIndex), 0);
+ assertTrue(c.getString(intentIndex).contains(testPackage1));
+ c.moveToNext();
+ assertEquals(c.getInt(screenIndex), 2);
+ assertTrue(c.getString(intentIndex).contains(testPackage3));
+ c.moveToNext();
+ assertEquals(c.getInt(screenIndex), 3);
+ assertTrue(c.getString(intentIndex).contains(testPackage4));
+ c.close();
+
+ // Check workspace items
+ c = mContext.getContentResolver().query(LauncherSettings.Favorites.CONTENT_URI,
+ new String[]{LauncherSettings.Favorites.CELLX, LauncherSettings.Favorites.CELLY,
+ LauncherSettings.Favorites.INTENT},
+ "container=" + CONTAINER_DESKTOP, null, null, null);
+ assertEquals(c.getCount(), 6);
+ intentIndex = c.getColumnIndex(LauncherSettings.Favorites.INTENT);
+ int cellXIndex = c.getColumnIndex(LauncherSettings.Favorites.CELLX);
+ int cellYIndex = c.getColumnIndex(LauncherSettings.Favorites.CELLY);
+
+ c.moveToNext();
+ assertTrue(c.getString(intentIndex).contains(testPackage7));
+ c.moveToNext();
+ assertTrue(c.getString(intentIndex).contains(testPackage6));
+ assertEquals(c.getInt(cellXIndex), 0);
+ assertEquals(c.getInt(cellYIndex), 3);
+ c.moveToNext();
+ assertTrue(c.getString(intentIndex).contains(testPackage10));
+ assertEquals(c.getInt(cellXIndex), 1);
+ assertEquals(c.getInt(cellYIndex), 3);
+ c.moveToNext();
+ assertTrue(c.getString(intentIndex).contains(testPackage5));
+ assertEquals(c.getInt(cellXIndex), 2);
+ assertEquals(c.getInt(cellYIndex), 3);
+ c.moveToNext();
+ assertTrue(c.getString(intentIndex).contains(testPackage9));
+ assertEquals(c.getInt(cellXIndex), 3);
+ assertEquals(c.getInt(cellYIndex), 3);
+ c.moveToNext();
+ assertTrue(c.getString(intentIndex).contains(testPackage8));
+ assertEquals(c.getInt(cellXIndex), 0);
+ assertEquals(c.getInt(cellYIndex), 2);
+
+ c.close();
+ }
+
+ @Test
+ public void migrateToLargerHotseat() {
+ int[] srcHotseatItems = {
+ mModelHelper.addItem(APP_ICON, 0, HOTSEAT, 0, 0, testPackage1, 1, TMP_CONTENT_URI),
+ mModelHelper.addItem(SHORTCUT, 1, HOTSEAT, 0, 0, testPackage2, 2, TMP_CONTENT_URI),
+ mModelHelper.addItem(APP_ICON, 2, HOTSEAT, 0, 0, testPackage3, 3, TMP_CONTENT_URI),
+ mModelHelper.addItem(SHORTCUT, 3, HOTSEAT, 0, 0, testPackage4, 4, TMP_CONTENT_URI),
+ };
+
+ int numSrcDatabaseHotseatIcons = srcHotseatItems.length;
+ mIdp.numDatabaseHotseatIcons = 6;
+ mIdp.numColumns = 4;
+ mIdp.numRows = 4;
+ GridSizeMigrationTaskV2.DbReader srcReader = new GridSizeMigrationTaskV2.DbReader(mDb,
+ LauncherSettings.Favorites.TMP_TABLE, mContext, mValidPackages,
+ numSrcDatabaseHotseatIcons);
+ GridSizeMigrationTaskV2.DbReader destReader = new GridSizeMigrationTaskV2.DbReader(mDb,
+ LauncherSettings.Favorites.TABLE_NAME, mContext, mValidPackages,
+ mIdp.numDatabaseHotseatIcons);
+ GridSizeMigrationTaskV2 task = new GridSizeMigrationTaskV2(mContext, mDb, srcReader,
+ destReader, mIdp.numDatabaseHotseatIcons, new Point(mIdp.numColumns, mIdp.numRows));
+ task.migrate();
+
+ // Check hotseat items
+ Cursor c = mContext.getContentResolver().query(LauncherSettings.Favorites.CONTENT_URI,
+ new String[]{LauncherSettings.Favorites.SCREEN, LauncherSettings.Favorites.INTENT},
+ "container=" + CONTAINER_HOTSEAT, null, null, null);
+ assertEquals(c.getCount(), numSrcDatabaseHotseatIcons);
+ int screenIndex = c.getColumnIndex(LauncherSettings.Favorites.SCREEN);
+ int intentIndex = c.getColumnIndex(LauncherSettings.Favorites.INTENT);
+ c.moveToNext();
+ assertEquals(c.getInt(screenIndex), 0);
+ assertTrue(c.getString(intentIndex).contains(testPackage1));
+ c.moveToNext();
+ assertEquals(c.getInt(screenIndex), 1);
+ assertTrue(c.getString(intentIndex).contains(testPackage2));
+ c.moveToNext();
+ assertEquals(c.getInt(screenIndex), 2);
+ assertTrue(c.getString(intentIndex).contains(testPackage3));
+ c.moveToNext();
+ assertEquals(c.getInt(screenIndex), 3);
+ assertTrue(c.getString(intentIndex).contains(testPackage4));
+
+ c.close();
+ }
+
+ @Test
+ public void migrateFromLargerHotseat() {
+ int[] srcHotseatItems = {
+ mModelHelper.addItem(APP_ICON, 0, HOTSEAT, 0, 0, testPackage1, 1, TMP_CONTENT_URI),
+ -1,
+ mModelHelper.addItem(SHORTCUT, 2, HOTSEAT, 0, 0, testPackage2, 2, TMP_CONTENT_URI),
+ mModelHelper.addItem(APP_ICON, 3, HOTSEAT, 0, 0, testPackage3, 3, TMP_CONTENT_URI),
+ mModelHelper.addItem(SHORTCUT, 4, HOTSEAT, 0, 0, testPackage4, 4, TMP_CONTENT_URI),
+ mModelHelper.addItem(APP_ICON, 5, HOTSEAT, 0, 0, testPackage5, 5, TMP_CONTENT_URI),
+ };
+
+ int numSrcDatabaseHotseatIcons = srcHotseatItems.length;
+ mIdp.numDatabaseHotseatIcons = 4;
+ mIdp.numColumns = 4;
+ mIdp.numRows = 4;
+ GridSizeMigrationTaskV2.DbReader srcReader = new GridSizeMigrationTaskV2.DbReader(mDb,
+ LauncherSettings.Favorites.TMP_TABLE, mContext, mValidPackages,
+ numSrcDatabaseHotseatIcons);
+ GridSizeMigrationTaskV2.DbReader destReader = new GridSizeMigrationTaskV2.DbReader(mDb,
+ LauncherSettings.Favorites.TABLE_NAME, mContext, mValidPackages,
+ mIdp.numDatabaseHotseatIcons);
+ GridSizeMigrationTaskV2 task = new GridSizeMigrationTaskV2(mContext, mDb, srcReader,
+ destReader, mIdp.numDatabaseHotseatIcons, new Point(mIdp.numColumns, mIdp.numRows));
+ task.migrate();
+
+ // Check hotseat items
+ Cursor c = mContext.getContentResolver().query(LauncherSettings.Favorites.CONTENT_URI,
+ new String[]{LauncherSettings.Favorites.SCREEN, LauncherSettings.Favorites.INTENT},
+ "container=" + CONTAINER_HOTSEAT, null, null, null);
+ assertEquals(c.getCount(), mIdp.numDatabaseHotseatIcons);
+ int screenIndex = c.getColumnIndex(LauncherSettings.Favorites.SCREEN);
+ int intentIndex = c.getColumnIndex(LauncherSettings.Favorites.INTENT);
+ c.moveToNext();
+ assertEquals(c.getInt(screenIndex), 0);
+ assertTrue(c.getString(intentIndex).contains(testPackage1));
+ c.moveToNext();
+ assertEquals(c.getInt(screenIndex), 1);
+ assertTrue(c.getString(intentIndex).contains(testPackage2));
+ c.moveToNext();
+ assertEquals(c.getInt(screenIndex), 2);
+ assertTrue(c.getString(intentIndex).contains(testPackage3));
+ c.moveToNext();
+ assertEquals(c.getInt(screenIndex), 3);
+ assertTrue(c.getString(intentIndex).contains(testPackage4));
+
+ c.close();
+ }
+}
diff --git a/tests/src/com/android/launcher3/model/LoaderCursorTest.java b/robolectric_tests/src/com/android/launcher3/model/LoaderCursorTest.java
index 6444ef6927..800311afb6 100644
--- a/tests/src/com/android/launcher3/model/LoaderCursorTest.java
+++ b/robolectric_tests/src/com/android/launcher3/model/LoaderCursorTest.java
@@ -16,8 +16,6 @@
package com.android.launcher3.model;
-import static androidx.test.InstrumentationRegistry.getContext;
-
import static com.android.launcher3.LauncherSettings.Favorites.CELLX;
import static com.android.launcher3.LauncherSettings.Favorites.CELLY;
import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER;
@@ -35,7 +33,7 @@ import static com.android.launcher3.LauncherSettings.Favorites.RESTORED;
import static com.android.launcher3.LauncherSettings.Favorites.SCREEN;
import static com.android.launcher3.LauncherSettings.Favorites.TITLE;
import static com.android.launcher3.LauncherSettings.Favorites._ID;
-import static com.android.launcher3.util.LauncherModelHelper.TEST_ACTIVITY;
+import static com.android.launcher3.util.LauncherModelHelper.TEST_PACKAGE;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse;
@@ -43,37 +41,37 @@ import static junit.framework.Assert.assertNotNull;
import static junit.framework.Assert.assertNull;
import static junit.framework.Assert.assertTrue;
+import static org.robolectric.Shadows.shadowOf;
+
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.database.MatrixCursor;
import android.os.Process;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
-
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.LauncherSettings.Favorites;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.launcher3.util.Executors;
-import com.android.launcher3.util.LauncherModelHelper;
import com.android.launcher3.util.PackageManagerHelper;
-import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.LooperMode;
+import org.robolectric.annotation.LooperMode.Mode;
/**
* Tests for {@link LoaderCursor}
*/
-@SmallTest
-@RunWith(AndroidJUnit4.class)
+@RunWith(RobolectricTestRunner.class)
+@LooperMode(Mode.PAUSED)
public class LoaderCursorTest {
- private LauncherModelHelper mModelHelper;
private LauncherAppState mApp;
private MatrixCursor mCursor;
@@ -84,8 +82,7 @@ public class LoaderCursorTest {
@Before
public void setup() {
- mModelHelper = new LauncherModelHelper();
- mContext = mModelHelper.sandboxContext;
+ mContext = RuntimeEnvironment.application;
mIDP = InvariantDeviceProfile.INSTANCE.get(mContext);
mApp = LauncherAppState.getInstance(mContext);
@@ -100,11 +97,6 @@ public class LoaderCursorTest {
ums.allUsers.put(0, Process.myUserHandle());
}
- @After
- public void tearDown() {
- mModelHelper.destroy();
- }
-
private void initCursor(int itemType, String title) {
mCursor.newRow()
.add(_ID, 1)
@@ -125,7 +117,9 @@ public class LoaderCursorTest {
@Test
public void getAppShortcutInfo_dontAllowMissing_validComponent() throws Exception {
- ComponentName cn = new ComponentName(getContext(), TEST_ACTIVITY);
+ ComponentName cn = new ComponentName(TEST_PACKAGE, TEST_PACKAGE);
+ shadowOf(mContext.getPackageManager()).addActivityIfNotPresent(cn);
+
initCursor(ITEM_TYPE_APPLICATION, "");
assertTrue(mLoaderCursor.moveToNext());
diff --git a/tests/src/com/android/launcher3/model/ModelMultiCallbacksTest.java b/robolectric_tests/src/com/android/launcher3/model/ModelMultiCallbacksTest.java
index 42c9f11a52..a2abfd55aa 100644
--- a/tests/src/com/android/launcher3/model/ModelMultiCallbacksTest.java
+++ b/robolectric_tests/src/com/android/launcher3/model/ModelMultiCallbacksTest.java
@@ -15,60 +15,68 @@
*/
package com.android.launcher3.model;
+import static com.android.launcher3.util.Executors.createAndStartNewLooper;
import static com.android.launcher3.util.LauncherModelHelper.TEST_PACKAGE;
import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.spy;
+import static org.robolectric.Shadows.shadowOf;
import android.os.Process;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
-
+import com.android.launcher3.PagedView;
import com.android.launcher3.model.BgDataModel.Callbacks;
import com.android.launcher3.model.data.AppInfo;
import com.android.launcher3.model.data.ItemInfo;
+import com.android.launcher3.shadows.ShadowLooperExecutor;
import com.android.launcher3.util.Executors;
-import com.android.launcher3.util.IntArray;
-import com.android.launcher3.util.IntSet;
import com.android.launcher3.util.LauncherLayoutBuilder;
import com.android.launcher3.util.LauncherModelHelper;
-import com.android.launcher3.util.RunnableList;
-import com.android.launcher3.util.TestUtil;
+import com.android.launcher3.util.LooperExecutor;
+import com.android.launcher3.util.ViewOnDrawExecutor;
-import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.LooperMode;
+import org.robolectric.annotation.LooperMode.Mode;
+import org.robolectric.shadow.api.Shadow;
+import org.robolectric.shadows.ShadowPackageManager;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.HashSet;
import java.util.List;
-import java.util.Set;
import java.util.stream.Collectors;
/**
* Tests to verify multiple callbacks in Loader
*/
-@SmallTest
-@RunWith(AndroidJUnit4.class)
+@RunWith(RobolectricTestRunner.class)
+@LooperMode(Mode.PAUSED)
public class ModelMultiCallbacksTest {
private LauncherModelHelper mModelHelper;
+ private ShadowPackageManager mSpm;
+ private LooperExecutor mTempMainExecutor;
+
@Before
- public void setUp() {
+ public void setUp() throws Exception {
mModelHelper = new LauncherModelHelper();
- }
+ mModelHelper.installApp(TEST_PACKAGE);
+
+ mSpm = shadowOf(RuntimeEnvironment.application.getPackageManager());
- @After
- public void tearDown() throws Exception {
- mModelHelper.destroy();
- TestUtil.uninstallDummyApp();
+ // Since robolectric tests run on main thread, we run the loader-UI calls on a temp thread,
+ // so that we can wait appropriately for the loader to complete.
+ mTempMainExecutor = new LooperExecutor(createAndStartNewLooper("tempMain"));
+ ShadowLooperExecutor sle = Shadow.extract(Executors.MAIN_EXECUTOR);
+ sle.setHandler(mTempMainExecutor.getHandler());
}
@Test
@@ -76,7 +84,7 @@ public class ModelMultiCallbacksTest {
setupWorkspacePages(3);
MyCallbacks cb1 = spy(MyCallbacks.class);
- Executors.MAIN_EXECUTOR.execute(() -> mModelHelper.getModel().addCallbacksAndLoad(cb1));
+ mModelHelper.getModel().addCallbacksAndLoad(cb1);
waitForLoaderAndTempMainThread();
cb1.verifySynchronouslyBound(3);
@@ -84,11 +92,11 @@ public class ModelMultiCallbacksTest {
// Add a new callback
cb1.reset();
MyCallbacks cb2 = spy(MyCallbacks.class);
- cb2.mPageToBindSync = IntSet.wrap(2);
- Executors.MAIN_EXECUTOR.execute(() -> mModelHelper.getModel().addCallbacksAndLoad(cb2));
+ cb2.mPageToBindSync = 2;
+ mModelHelper.getModel().addCallbacksAndLoad(cb2);
waitForLoaderAndTempMainThread();
- assertFalse(cb1.bindStarted);
+ cb1.verifySynchronouslyBound(3);
cb2.verifySynchronouslyBound(3);
// Remove callbacks
@@ -96,62 +104,66 @@ public class ModelMultiCallbacksTest {
cb2.reset();
// No effect on callbacks when removing an callback
- Executors.MAIN_EXECUTOR.execute(() -> mModelHelper.getModel().removeCallbacks(cb2));
+ mModelHelper.getModel().removeCallbacks(cb2);
waitForLoaderAndTempMainThread();
- assertNull(cb1.mPendingTasks);
- assertNull(cb2.mPendingTasks);
+ assertNull(cb1.mDeferredExecutor);
+ assertNull(cb2.mDeferredExecutor);
// Reloading only loads registered callbacks
mModelHelper.getModel().startLoader();
waitForLoaderAndTempMainThread();
cb1.verifySynchronouslyBound(3);
- assertNull(cb2.mPendingTasks);
+ assertNull(cb2.mDeferredExecutor);
}
@Test
public void testTwoCallbacks_receiveUpdates() throws Exception {
- TestUtil.uninstallDummyApp();
-
setupWorkspacePages(1);
MyCallbacks cb1 = spy(MyCallbacks.class);
MyCallbacks cb2 = spy(MyCallbacks.class);
- Executors.MAIN_EXECUTOR.execute(() -> mModelHelper.getModel().addCallbacksAndLoad(cb1));
- Executors.MAIN_EXECUTOR.execute(() -> mModelHelper.getModel().addCallbacksAndLoad(cb2));
+ mModelHelper.getModel().addCallbacksAndLoad(cb1);
+ mModelHelper.getModel().addCallbacksAndLoad(cb2);
waitForLoaderAndTempMainThread();
- assertTrue(cb1.allApps().contains(TEST_PACKAGE));
- assertTrue(cb2.allApps().contains(TEST_PACKAGE));
+ cb1.verifyApps(TEST_PACKAGE);
+ cb2.verifyApps(TEST_PACKAGE);
// Install package 1
- TestUtil.installDummyApp();
- mModelHelper.getModel().onPackageAdded(TestUtil.DUMMY_PACKAGE, Process.myUserHandle());
+ String pkg1 = "com.test.pkg1";
+ mModelHelper.installApp(pkg1);
+ mModelHelper.getModel().onPackageAdded(pkg1, Process.myUserHandle());
waitForLoaderAndTempMainThread();
- assertTrue(cb1.allApps().contains(TestUtil.DUMMY_PACKAGE));
- assertTrue(cb2.allApps().contains(TestUtil.DUMMY_PACKAGE));
+ cb1.verifyApps(TEST_PACKAGE, pkg1);
+ cb2.verifyApps(TEST_PACKAGE, pkg1);
+
+ // Install package 2
+ String pkg2 = "com.test.pkg2";
+ mModelHelper.installApp(pkg2);
+ mModelHelper.getModel().onPackageAdded(pkg2, Process.myUserHandle());
+ waitForLoaderAndTempMainThread();
+ cb1.verifyApps(TEST_PACKAGE, pkg1, pkg2);
+ cb2.verifyApps(TEST_PACKAGE, pkg1, pkg2);
// Uninstall package 2
- TestUtil.uninstallDummyApp();
- mModelHelper.getModel().onPackageRemoved(TestUtil.DUMMY_PACKAGE, Process.myUserHandle());
+ mSpm.removePackage(pkg1);
+ mModelHelper.getModel().onPackageRemoved(pkg1, Process.myUserHandle());
waitForLoaderAndTempMainThread();
- assertFalse(cb1.allApps().contains(TestUtil.DUMMY_PACKAGE));
- assertFalse(cb2.allApps().contains(TestUtil.DUMMY_PACKAGE));
+ cb1.verifyApps(TEST_PACKAGE, pkg2);
+ cb2.verifyApps(TEST_PACKAGE, pkg2);
// Unregister a callback and verify updates no longer received
- Executors.MAIN_EXECUTOR.execute(() -> mModelHelper.getModel().removeCallbacks(cb2));
- TestUtil.installDummyApp();
- mModelHelper.getModel().onPackageAdded(TestUtil.DUMMY_PACKAGE, Process.myUserHandle());
+ mModelHelper.getModel().removeCallbacks(cb2);
+ mSpm.removePackage(pkg2);
+ mModelHelper.getModel().onPackageRemoved(pkg2, Process.myUserHandle());
waitForLoaderAndTempMainThread();
-
- // cb2 didn't get the update
- assertTrue(cb1.allApps().contains(TestUtil.DUMMY_PACKAGE));
- assertFalse(cb2.allApps().contains(TestUtil.DUMMY_PACKAGE));
+ cb1.verifyApps(TEST_PACKAGE);
+ cb2.verifyApps(TEST_PACKAGE, pkg2);
}
private void waitForLoaderAndTempMainThread() throws Exception {
- Executors.MAIN_EXECUTOR.submit(() -> { }).get();
Executors.MODEL_EXECUTOR.submit(() -> { }).get();
- Executors.MAIN_EXECUTOR.submit(() -> { }).get();
+ mTempMainExecutor.submit(() -> { }).get();
}
private void setupWorkspacePages(int pageCount) throws Exception {
@@ -166,23 +178,21 @@ public class ModelMultiCallbacksTest {
private abstract static class MyCallbacks implements Callbacks {
final List<ItemInfo> mItems = new ArrayList<>();
- IntSet mPageToBindSync = IntSet.wrap(0);
- IntSet mPageBoundSync = new IntSet();
- RunnableList mPendingTasks;
+ int mPageToBindSync = 0;
+ int mPageBoundSync = PagedView.INVALID_PAGE;
+ ViewOnDrawExecutor mDeferredExecutor;
AppInfo[] mAppInfos;
- boolean bindStarted;
MyCallbacks() { }
@Override
- public void startBinding() {
- bindStarted = true;
+ public void onPageBoundSynchronously(int page) {
+ mPageBoundSync = page;
}
@Override
- public void onInitialBindComplete(IntSet boundPages, RunnableList pendingTasks) {
- mPageBoundSync = boundPages;
- mPendingTasks = pendingTasks;
+ public void executeOnNextDraw(ViewOnDrawExecutor executor) {
+ mDeferredExecutor = executor;
}
@Override
@@ -196,39 +206,35 @@ public class ModelMultiCallbacksTest {
}
@Override
- public IntSet getPagesToBindSynchronously(IntArray orderedScreenIds) {
+ public int getPageToBindSynchronously() {
return mPageToBindSync;
}
public void reset() {
mItems.clear();
- mPageBoundSync = new IntSet();
- mPendingTasks = null;
+ mPageBoundSync = PagedView.INVALID_PAGE;
+ mDeferredExecutor = null;
mAppInfos = null;
- bindStarted = false;
}
public void verifySynchronouslyBound(int totalItems) {
// Verify that the requested page is bound synchronously
- assertTrue(bindStarted);
- assertEquals(mPageToBindSync, mPageBoundSync);
+ assertEquals(mPageBoundSync, mPageToBindSync);
assertEquals(mItems.size(), 1);
- assertEquals(IntSet.wrap(mItems.get(0).screenId), mPageBoundSync);
- assertNotNull(mPendingTasks);
+ assertEquals(mItems.get(0).screenId, mPageBoundSync);
+ assertNotNull(mDeferredExecutor);
// Verify that all other pages are bound properly
- mPendingTasks.executeAllAndDestroy();
+ mDeferredExecutor.runAllTasks();
assertEquals(mItems.size(), totalItems);
}
- public Set<String> allApps() {
- return Arrays.stream(mAppInfos)
- .map(ai -> ai.getTargetComponent().getPackageName())
- .collect(Collectors.toSet());
- }
-
public void verifyApps(String... apps) {
- assertTrue(allApps().containsAll(Arrays.asList(apps)));
+ assertEquals(apps.length, mAppInfos.length);
+ assertEquals(Arrays.stream(mAppInfos)
+ .map(ai -> ai.getTargetComponent().getPackageName())
+ .collect(Collectors.toSet()),
+ new HashSet<>(Arrays.asList(apps)));
}
}
}
diff --git a/tests/src/com/android/launcher3/model/PackageInstallStateChangedTaskTest.java b/robolectric_tests/src/com/android/launcher3/model/PackageInstallStateChangedTaskTest.java
index 519191e251..412ace03ff 100644
--- a/tests/src/com/android/launcher3/model/PackageInstallStateChangedTaskTest.java
+++ b/robolectric_tests/src/com/android/launcher3/model/PackageInstallStateChangedTaskTest.java
@@ -2,19 +2,18 @@ package com.android.launcher3.model;
import static org.junit.Assert.assertEquals;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
-
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.LauncherAppWidgetInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.launcher3.pm.PackageInstallInfo;
import com.android.launcher3.util.LauncherModelHelper;
-import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.annotation.LooperMode;
+import org.robolectric.annotation.LooperMode.Mode;
import java.util.Arrays;
import java.util.HashSet;
@@ -22,8 +21,8 @@ import java.util.HashSet;
/**
* Tests for {@link PackageInstallStateChangedTask}
*/
-@SmallTest
-@RunWith(AndroidJUnit4.class)
+@RunWith(RobolectricTestRunner.class)
+@LooperMode(Mode.PAUSED)
public class PackageInstallStateChangedTaskTest {
private LauncherModelHelper mModelHelper;
@@ -31,12 +30,7 @@ public class PackageInstallStateChangedTaskTest {
@Before
public void setup() throws Exception {
mModelHelper = new LauncherModelHelper();
- mModelHelper.initializeData("package_install_state_change_task_data");
- }
-
- @After
- public void tearDown() {
- mModelHelper.destroy();
+ mModelHelper.initializeData("/package_install_state_change_task_data.txt");
}
private PackageInstallStateChangedTask newTask(String pkg, int progress) {
@@ -72,7 +66,7 @@ public class PackageInstallStateChangedTaskTest {
HashSet<Integer> updates = new HashSet<>(Arrays.asList(idsUpdated));
for (ItemInfo info : mModelHelper.getBgDataModel().itemsIdMap) {
if (info instanceof WorkspaceItemInfo) {
- assertEquals(updates.contains(info.id) ? progress: 100,
+ assertEquals(updates.contains(info.id) ? progress: 0,
((WorkspaceItemInfo) info).getProgressLevel());
} else {
assertEquals(updates.contains(info.id) ? progress: -1,
diff --git a/tests/src/com/android/launcher3/popup/PopupPopulatorTest.java b/robolectric_tests/src/com/android/launcher3/popup/PopupPopulatorTest.java
index 6764e09fa1..83bf7dac89 100644
--- a/tests/src/com/android/launcher3/popup/PopupPopulatorTest.java
+++ b/robolectric_tests/src/com/android/launcher3/popup/PopupPopulatorTest.java
@@ -16,8 +16,6 @@
package com.android.launcher3.popup;
-import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
-
import static com.android.launcher3.popup.PopupPopulator.MAX_SHORTCUTS;
import static com.android.launcher3.popup.PopupPopulator.NUM_DYNAMIC;
@@ -29,11 +27,10 @@ import static org.mockito.Mockito.spy;
import android.content.pm.ShortcutInfo;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
-
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
import java.util.ArrayList;
import java.util.Collections;
@@ -42,8 +39,7 @@ import java.util.List;
/**
* Tests the sorting and filtering of shortcuts in {@link PopupPopulator}.
*/
-@SmallTest
-@RunWith(AndroidJUnit4.class)
+@RunWith(RobolectricTestRunner.class)
public class PopupPopulatorTest {
@Test
@@ -141,7 +137,7 @@ public class PopupPopulatorTest {
private ShortcutInfo createInfo(boolean isStatic, int rank) {
ShortcutInfo info = spy(new ShortcutInfo.Builder(
- getApplicationContext(), generateId(isStatic, rank))
+ RuntimeEnvironment.application, generateId(isStatic, rank))
.setRank(rank)
.build());
doReturn(isStatic).when(info).isDeclaredInManifest();
diff --git a/tests/src/com/android/launcher3/provider/RestoreDbTaskTest.java b/robolectric_tests/src/com/android/launcher3/provider/RestoreDbTaskTest.java
index 9c8de1c007..4184d33a68 100644
--- a/tests/src/com/android/launcher3/provider/RestoreDbTaskTest.java
+++ b/robolectric_tests/src/com/android/launcher3/provider/RestoreDbTaskTest.java
@@ -15,28 +15,24 @@
*/
package com.android.launcher3.provider;
-import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
-import androidx.test.InstrumentationRegistry;
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
import com.android.launcher3.LauncherProvider.DatabaseHelper;
import com.android.launcher3.LauncherSettings.Favorites;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
/**
* Tests for {@link RestoreDbTask}
*/
-@SmallTest
-@RunWith(AndroidJUnit4.class)
+@RunWith(RobolectricTestRunner.class)
public class RestoreDbTaskTest {
@Test
@@ -88,56 +84,6 @@ public class RestoreDbTaskTest {
assertEquals(1, getCount(db, "select * from favorites where profileId = 33"));
}
- @Test
- public void testRemoveScreenIdGaps_firstScreenEmpty() {
- runRemoveScreenIdGapsTest(
- new int[]{1, 2, 5, 6, 6, 7, 9, 9},
- new int[]{1, 2, 3, 4, 4, 5, 6, 6});
- }
-
- @Test
- public void testRemoveScreenIdGaps_firstScreenOccupied() {
- runRemoveScreenIdGapsTest(
- new int[]{0, 2, 5, 6, 6, 7, 9, 9},
- new int[]{0, 1, 2, 3, 3, 4, 5, 5});
- }
-
- @Test
- public void testRemoveScreenIdGaps_noGap() {
- runRemoveScreenIdGapsTest(
- new int[]{0, 1, 1, 2, 3, 3, 4, 5},
- new int[]{0, 1, 1, 2, 3, 3, 4, 5});
- }
-
- private void runRemoveScreenIdGapsTest(int[] screenIds, int[] expectedScreenIds) {
- SQLiteDatabase db = new MyDatabaseHelper(42).getWritableDatabase();
- // Add some mock data
- for (int i = 0; i < screenIds.length; i++) {
- ContentValues values = new ContentValues();
- values.put(Favorites._ID, i);
- values.put(Favorites.SCREEN, screenIds[i]);
- values.put(Favorites.CONTAINER, Favorites.CONTAINER_DESKTOP);
- db.insert(Favorites.TABLE_NAME, null, values);
- }
- // Verify items are added
- assertEquals(screenIds.length,
- getCount(db, "select * from favorites where container = -100"));
-
- new RestoreDbTask().removeScreenIdGaps(db);
-
- // verify screenId gaps removed
- int[] resultScreenIds = new int[screenIds.length];
- try (Cursor c = db.rawQuery(
- "select screen from favorites where container = -100 order by screen", null)) {
- int i = 0;
- while (c.moveToNext()) {
- resultScreenIds[i++] = c.getInt(0);
- }
- }
-
- assertArrayEquals(expectedScreenIds, resultScreenIds);
- }
-
private int getCount(SQLiteDatabase db, String sql) {
try (Cursor c = db.rawQuery(sql, null)) {
return c.getCount();
@@ -149,7 +95,7 @@ public class RestoreDbTaskTest {
private final long mProfileId;
MyDatabaseHelper(long profileId) {
- super(InstrumentationRegistry.getInstrumentation().getTargetContext(), null, false);
+ super(RuntimeEnvironment.application, null, false);
mProfileId = profileId;
}
diff --git a/robolectric_tests/src/com/android/launcher3/secondarydisplay/SDWorkModeTest.java b/robolectric_tests/src/com/android/launcher3/secondarydisplay/SDWorkModeTest.java
new file mode 100644
index 0000000000..e3694aeddc
--- /dev/null
+++ b/robolectric_tests/src/com/android/launcher3/secondarydisplay/SDWorkModeTest.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2020 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.launcher3.secondarydisplay;
+
+import static com.android.launcher3.util.LauncherModelHelper.TEST_PACKAGE;
+import static com.android.launcher3.util.LauncherUIHelper.doLayout;
+import static com.android.launcher3.util.Preconditions.assertNotNull;
+
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertTrue;
+
+import android.content.Context;
+import android.os.UserManager;
+import android.provider.Settings;
+
+import com.android.launcher3.InvariantDeviceProfile;
+import com.android.launcher3.allapps.AllAppsPagedView;
+import com.android.launcher3.allapps.AllAppsRecyclerView;
+import com.android.launcher3.util.LauncherLayoutBuilder;
+import com.android.launcher3.util.LauncherModelHelper;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.Robolectric;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.LooperMode;
+import org.robolectric.annotation.LooperMode.Mode;
+import org.robolectric.shadow.api.Shadow;
+import org.robolectric.shadows.ShadowUserManager;
+
+/**
+ * Tests for {@link SecondaryDisplayLauncher} with work profile
+ */
+@RunWith(RobolectricTestRunner.class)
+@LooperMode(Mode.PAUSED)
+public class SDWorkModeTest {
+
+ private static final int SYSTEM_USER = 0;
+ private static final int FLAG_SYSTEM = 0x00000800;
+ private static final int WORK_PROFILE_ID = 10;
+ private static final int FLAG_PROFILE = 0x00001000;
+
+ private Context mTargetContext;
+ private InvariantDeviceProfile mIdp;
+ private LauncherModelHelper mModelHelper;
+
+ @Before
+ public void setup() throws Exception {
+ mModelHelper = new LauncherModelHelper();
+ mTargetContext = RuntimeEnvironment.application;
+ mIdp = InvariantDeviceProfile.INSTANCE.get(mTargetContext);
+ Settings.Global.putFloat(mTargetContext.getContentResolver(),
+ Settings.Global.WINDOW_ANIMATION_SCALE, 0);
+
+ mModelHelper.installApp(TEST_PACKAGE);
+ }
+
+ @Test
+ public void testAllAppsList_noWorkProfile() throws Exception {
+ SecondaryDisplayLauncher launcher = loadLauncher();
+ launcher.showAppDrawer(true);
+ doLayout(launcher);
+
+ verifyRecyclerViewCount(launcher.getAppsView().getActiveRecyclerView());
+ }
+
+ @Test
+ public void testAllAppsList_workProfile() throws Exception {
+ ShadowUserManager sum = Shadow.extract(mTargetContext.getSystemService(UserManager.class));
+ sum.addUser(SYSTEM_USER, "me", FLAG_SYSTEM);
+ sum.addProfile(SYSTEM_USER, WORK_PROFILE_ID, "work", FLAG_PROFILE);
+
+ SecondaryDisplayLauncher launcher = loadLauncher();
+ launcher.showAppDrawer(true);
+ doLayout(launcher);
+
+ AllAppsRecyclerView rv1 = launcher.getAppsView().getActiveRecyclerView();
+ verifyRecyclerViewCount(rv1);
+
+ assertNotNull(launcher.getAppsView().getWorkModeSwitch());
+ assertTrue(launcher.getAppsView().getRecyclerViewContainer() instanceof AllAppsPagedView);
+
+ AllAppsPagedView pagedView =
+ (AllAppsPagedView) launcher.getAppsView().getRecyclerViewContainer();
+ pagedView.snapToPageImmediately(1);
+ doLayout(launcher);
+
+ AllAppsRecyclerView rv2 = launcher.getAppsView().getActiveRecyclerView();
+ verifyRecyclerViewCount(rv2);
+ assertNotSame(rv1, rv2);
+ }
+
+ private SecondaryDisplayLauncher loadLauncher() throws Exception {
+ // Install 100 apps
+ for (int i = 0; i < 100; i++) {
+ mModelHelper.installApp(TEST_PACKAGE + i);
+ }
+ mModelHelper.setupDefaultLayoutProvider(new LauncherLayoutBuilder()).loadModelSync();
+ SecondaryDisplayLauncher launcher =
+ Robolectric.buildActivity(SecondaryDisplayLauncher.class).setup().get();
+ doLayout(launcher);
+ return launcher;
+ }
+
+ private void verifyRecyclerViewCount(AllAppsRecyclerView rv) {
+ int childCount = rv.getChildCount();
+ assertTrue(childCount > 0);
+ assertTrue(childCount < 100);
+ }
+}
diff --git a/tests/src/com/android/launcher3/settings/SettingsActivityTest.java b/robolectric_tests/src/com/android/launcher3/settings/SettingsActivityTest.java
index 1c205f0a6e..3271812b45 100644
--- a/tests/src/com/android/launcher3/settings/SettingsActivityTest.java
+++ b/robolectric_tests/src/com/android/launcher3/settings/SettingsActivityTest.java
@@ -55,7 +55,6 @@ import com.android.systemui.shared.plugins.PluginPrefs;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
-import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -76,7 +75,6 @@ public class SettingsActivityTest {
}
@Test
- @Ignore // b/199309785
public void testSettings_aboutTap_launchesActivity() {
ActivityScenario.launch(SettingsActivity.class);
onView(withId(R.id.recycler_view)).perform(
@@ -90,7 +88,6 @@ public class SettingsActivityTest {
}
@Test
- @Ignore // b/199309785
public void testSettings_developerOptionsTap_launchesActivityWithFragment() {
PluginPrefs.setHasPlugins(mApplicationContext);
ActivityScenario.launch(SettingsActivity.class);
@@ -103,7 +100,6 @@ public class SettingsActivityTest {
}
@Test
- @Ignore // b/199309785
public void testSettings_aboutScreenIntent() {
Bundle fragmentArgs = new Bundle();
fragmentArgs.putString(ARG_PREFERENCE_ROOT, "about_screen");
@@ -118,7 +114,6 @@ public class SettingsActivityTest {
}
@Test
- @Ignore // b/199309785
public void testSettings_developerOptionsFragmentIntent() {
Intent intent = new Intent(mApplicationContext, SettingsActivity.class)
.putExtra(EXTRA_FRAGMENT, DeveloperOptionsFragment.class.getName());
@@ -130,7 +125,6 @@ public class SettingsActivityTest {
}
@Test
- @Ignore // b/199309785
public void testSettings_intentWithUnknownFragment() {
String fragmentClass = PreferenceFragmentCompat.class.getName();
Intent intent = new Intent(mApplicationContext, SettingsActivity.class)
@@ -145,7 +139,6 @@ public class SettingsActivityTest {
}
@Test
- @Ignore // b/199309785
public void testSettings_backButtonFinishesActivity() {
Bundle fragmentArgs = new Bundle();
fragmentArgs.putString(ARG_PREFERENCE_ROOT, "about_screen");
diff --git a/robolectric_tests/src/com/android/launcher3/shadows/LShadowAppPredictionManager.java b/robolectric_tests/src/com/android/launcher3/shadows/LShadowAppPredictionManager.java
new file mode 100644
index 0000000000..ae051f7d7c
--- /dev/null
+++ b/robolectric_tests/src/com/android/launcher3/shadows/LShadowAppPredictionManager.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2020 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.launcher3.shadows;
+
+import static org.mockito.Mockito.mock;
+
+import android.app.prediction.AppPredictionContext;
+import android.app.prediction.AppPredictionManager;
+import android.app.prediction.AppPredictor;
+
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+
+/**
+ * Shadow for {@link AppPredictionManager} which create mock predictors
+ */
+@Implements(value = AppPredictionManager.class)
+public class LShadowAppPredictionManager {
+
+ @Implementation
+ public AppPredictor createAppPredictionSession(AppPredictionContext predictionContext) {
+ return mock(AppPredictor.class);
+ }
+}
diff --git a/robolectric_tests/src/com/android/launcher3/shadows/LShadowAppWidgetManager.java b/robolectric_tests/src/com/android/launcher3/shadows/LShadowAppWidgetManager.java
new file mode 100644
index 0000000000..696ffd0b54
--- /dev/null
+++ b/robolectric_tests/src/com/android/launcher3/shadows/LShadowAppWidgetManager.java
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ */
+
+package com.android.launcher3.shadows;
+
+import android.appwidget.AppWidgetManager;
+import android.appwidget.AppWidgetProviderInfo;
+import android.os.Process;
+import android.os.UserHandle;
+
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+import org.robolectric.shadows.ShadowAppWidgetManager;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * Extension of {@link ShadowAppWidgetManager} with missing shadow methods
+ */
+@Implements(value = AppWidgetManager.class)
+public class LShadowAppWidgetManager extends ShadowAppWidgetManager {
+
+ @Override
+ protected List<AppWidgetProviderInfo> getInstalledProviders() {
+ return getInstalledProvidersForProfile(null);
+ }
+
+ @Implementation
+ public List<AppWidgetProviderInfo> getInstalledProvidersForProfile(UserHandle profile) {
+ UserHandle user = profile == null ? Process.myUserHandle() : profile;
+ return super.getInstalledProviders().stream().filter(
+ info -> user.equals(info.getProfile())).collect(Collectors.toList());
+ }
+}
diff --git a/robolectric_tests/src/com/android/launcher3/shadows/LShadowBackupManager.java b/robolectric_tests/src/com/android/launcher3/shadows/LShadowBackupManager.java
new file mode 100644
index 0000000000..eae0101719
--- /dev/null
+++ b/robolectric_tests/src/com/android/launcher3/shadows/LShadowBackupManager.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2020 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.launcher3.shadows;
+
+import android.app.backup.BackupManager;
+import android.os.UserHandle;
+import android.util.LongSparseArray;
+
+import androidx.annotation.Nullable;
+
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+import org.robolectric.shadows.ShadowBackupManager;
+
+/**
+ * Extension of {@link ShadowBackupManager} with missing shadow methods
+ */
+@Implements(value = BackupManager.class)
+public class LShadowBackupManager extends ShadowBackupManager {
+
+ private LongSparseArray<UserHandle> mProfileMapping = new LongSparseArray<>();
+
+ public void addProfile(long userSerial, UserHandle userHandle) {
+ mProfileMapping.put(userSerial, userHandle);
+ }
+
+ @Implementation
+ @Nullable
+ public UserHandle getUserForAncestralSerialNumber(long ancestralSerialNumber) {
+ return mProfileMapping.get(ancestralSerialNumber);
+ }
+}
diff --git a/robolectric_tests/src/com/android/launcher3/shadows/LShadowDisplay.java b/robolectric_tests/src/com/android/launcher3/shadows/LShadowDisplay.java
new file mode 100644
index 0000000000..3813fa182f
--- /dev/null
+++ b/robolectric_tests/src/com/android/launcher3/shadows/LShadowDisplay.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2020 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.launcher3.shadows;
+
+import static org.robolectric.shadow.api.Shadow.directlyOn;
+
+import android.graphics.Point;
+import android.graphics.Rect;
+import android.view.Display;
+
+import org.robolectric.annotation.Implements;
+import org.robolectric.annotation.RealObject;
+import org.robolectric.shadows.ShadowDisplay;
+
+/**
+ * Extension of {@link ShadowDisplay} with missing shadow methods
+ */
+@Implements(value = Display.class)
+public class LShadowDisplay extends ShadowDisplay {
+
+ private final Rect mInsets = new Rect();
+
+ @RealObject Display realObject;
+
+ /**
+ * Sets the insets for the display
+ */
+ public void setInsets(Rect insets) {
+ mInsets.set(insets);
+ }
+
+ @Override
+ protected void getCurrentSizeRange(Point outSmallestSize, Point outLargestSize) {
+ directlyOn(realObject, Display.class).getCurrentSizeRange(outSmallestSize, outLargestSize);
+ outSmallestSize.x -= mInsets.left + mInsets.right;
+ outLargestSize.x -= mInsets.left + mInsets.right;
+
+ outSmallestSize.y -= mInsets.top + mInsets.bottom;
+ outLargestSize.y -= mInsets.top + mInsets.bottom;
+ }
+}
diff --git a/robolectric_tests/src/com/android/launcher3/shadows/LShadowLauncherApps.java b/robolectric_tests/src/com/android/launcher3/shadows/LShadowLauncherApps.java
new file mode 100644
index 0000000000..6a6f0fbe70
--- /dev/null
+++ b/robolectric_tests/src/com/android/launcher3/shadows/LShadowLauncherApps.java
@@ -0,0 +1,136 @@
+/*
+ * 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.
+ */
+
+package com.android.launcher3.shadows;
+
+import static org.robolectric.util.ReflectionHelpers.ClassParameter;
+import static org.robolectric.util.ReflectionHelpers.callConstructor;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.LauncherActivityInfo;
+import android.content.pm.LauncherApps;
+import android.content.pm.PackageInstaller;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.content.pm.ShortcutInfo;
+import android.os.UserHandle;
+import android.util.ArraySet;
+
+import com.android.launcher3.util.ComponentKey;
+import com.android.launcher3.util.PackageUserKey;
+
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+import org.robolectric.shadows.ShadowLauncherApps;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.Executor;
+import java.util.stream.Collectors;
+
+/**
+ * Extension of {@link ShadowLauncherApps} with missing shadow methods
+ */
+@Implements(value = LauncherApps.class)
+public class LShadowLauncherApps extends ShadowLauncherApps {
+
+ public final ArraySet<PackageUserKey> disabledApps = new ArraySet<>();
+ public final ArraySet<ComponentKey> disabledActivities = new ArraySet<>();
+
+ @Implementation
+ @Override
+ protected List<ShortcutInfo> getShortcuts(LauncherApps.ShortcutQuery query, UserHandle user) {
+ try {
+ return super.getShortcuts(query, user);
+ } catch (UnsupportedOperationException e) {
+ return Collections.emptyList();
+ }
+ }
+
+ @Implementation
+ protected boolean isPackageEnabled(String packageName, UserHandle user) {
+ return !disabledApps.contains(new PackageUserKey(packageName, user));
+ }
+
+ @Implementation
+ protected boolean isActivityEnabled(ComponentName component, UserHandle user) {
+ return !disabledActivities.contains(new ComponentKey(component, user));
+ }
+
+ @Implementation
+ protected LauncherActivityInfo resolveActivity(Intent intent, UserHandle user) {
+ ResolveInfo ri = RuntimeEnvironment.application.getPackageManager()
+ .resolveActivity(intent, 0);
+ return ri == null ? null : getLauncherActivityInfo(ri.activityInfo, user);
+ }
+
+ public LauncherActivityInfo getLauncherActivityInfo(
+ ActivityInfo activityInfo, UserHandle user) {
+ return callConstructor(LauncherActivityInfo.class,
+ ClassParameter.from(Context.class, RuntimeEnvironment.application),
+ ClassParameter.from(ActivityInfo.class, activityInfo),
+ ClassParameter.from(UserHandle.class, user));
+ }
+
+ @Implementation
+ public ApplicationInfo getApplicationInfo(String packageName, int flags, UserHandle user)
+ throws PackageManager.NameNotFoundException {
+ return RuntimeEnvironment.application.getPackageManager()
+ .getApplicationInfo(packageName, flags);
+ }
+
+ @Implementation
+ public List<LauncherActivityInfo> getActivityList(String packageName, UserHandle user) {
+ Intent intent = new Intent(Intent.ACTION_MAIN)
+ .addCategory(Intent.CATEGORY_LAUNCHER)
+ .setPackage(packageName);
+ return RuntimeEnvironment.application.getPackageManager().queryIntentActivities(intent, 0)
+ .stream()
+ .map(ri -> getLauncherActivityInfo(ri.activityInfo, user))
+ .collect(Collectors.toList());
+ }
+
+ @Implementation
+ public boolean hasShortcutHostPermission() {
+ return true;
+ }
+
+ @Implementation
+ public List<PackageInstaller.SessionInfo> getAllPackageInstallerSessions() {
+ return RuntimeEnvironment.application.getPackageManager().getPackageInstaller()
+ .getAllSessions();
+ }
+
+ @Implementation
+ public void registerPackageInstallerSessionCallback(
+ Executor executor, PackageInstaller.SessionCallback callback) {
+ }
+
+ @Override
+ protected List<LauncherActivityInfo> getShortcutConfigActivityList(String packageName,
+ UserHandle user) {
+ Intent intent = new Intent(Intent.ACTION_CREATE_SHORTCUT).setPackage(packageName);
+ return RuntimeEnvironment.application.getPackageManager().queryIntentActivities(intent, 0)
+ .stream()
+ .map(ri -> getLauncherActivityInfo(ri.activityInfo, user))
+ .collect(Collectors.toList());
+ }
+}
diff --git a/robolectric_tests/src/com/android/launcher3/shadows/ShadowDeviceFlag.java b/robolectric_tests/src/com/android/launcher3/shadows/ShadowDeviceFlag.java
new file mode 100644
index 0000000000..b58e4b7074
--- /dev/null
+++ b/robolectric_tests/src/com/android/launcher3/shadows/ShadowDeviceFlag.java
@@ -0,0 +1,62 @@
+/*
+ * 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.
+ */
+
+package com.android.launcher3.shadows;
+
+import android.content.Context;
+
+import androidx.annotation.Nullable;
+
+import com.android.launcher3.uioverrides.DeviceFlag;
+import com.android.launcher3.util.LooperExecutor;
+
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+import org.robolectric.annotation.RealObject;
+import org.robolectric.shadow.api.Shadow;
+
+/**
+ * Shadow for {@link LooperExecutor} to provide reset functionality for static executors.
+ */
+@Implements(value = DeviceFlag.class, isInAndroidSdk = false)
+public class ShadowDeviceFlag {
+
+ @RealObject private DeviceFlag mRealObject;
+ @Nullable private Boolean mValue;
+
+ /**
+ * Mock change listener as it uses internal system classes not available to robolectric
+ */
+ @Implementation
+ protected void addChangeListener(Context context, Runnable r) { }
+
+ @Implementation
+ protected static boolean getDeviceValue(String key, boolean defaultValue) {
+ return defaultValue;
+ }
+
+ @Implementation
+ public boolean get() {
+ if (mValue != null) {
+ return mValue;
+ }
+ return Shadow.directlyOn(mRealObject, DeviceFlag.class, "get");
+ }
+
+ public void setValue(boolean value) {
+ mValue = new Boolean(value);
+ }
+}
diff --git a/robolectric_tests/src/com/android/launcher3/shadows/ShadowLooperExecutor.java b/robolectric_tests/src/com/android/launcher3/shadows/ShadowLooperExecutor.java
new file mode 100644
index 0000000000..57eda7eae8
--- /dev/null
+++ b/robolectric_tests/src/com/android/launcher3/shadows/ShadowLooperExecutor.java
@@ -0,0 +1,63 @@
+/*
+ * 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.
+ */
+
+package com.android.launcher3.shadows;
+
+import static com.android.launcher3.util.Executors.createAndStartNewLooper;
+
+import static org.robolectric.shadow.api.Shadow.directlyOn;
+import static org.robolectric.util.ReflectionHelpers.setField;
+
+import android.os.Handler;
+
+import androidx.annotation.Nullable;
+
+import com.android.launcher3.util.LooperExecutor;
+
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+import org.robolectric.annotation.RealObject;
+
+/**
+ * Shadow for {@link LooperExecutor} to provide reset functionality for static executors.
+ */
+@Implements(value = LooperExecutor.class, isInAndroidSdk = false)
+public class ShadowLooperExecutor {
+
+ @RealObject private LooperExecutor mRealExecutor;
+
+ private Handler mOverriddenHandler;
+
+ @Implementation
+ protected Handler getHandler() {
+ if (mOverriddenHandler != null) {
+ return mOverriddenHandler;
+ }
+ Handler handler = directlyOn(mRealExecutor, LooperExecutor.class, "getHandler");
+ Thread thread = handler.getLooper().getThread();
+ if (!thread.isAlive()) {
+ // Robolectric destroys all loopers at the end of every test. Since Launcher maintains
+ // some static threads, they need to be reinitialized in case they were destroyed.
+ setField(mRealExecutor, "mHandler",
+ new Handler(createAndStartNewLooper(thread.getName())));
+ }
+ return directlyOn(mRealExecutor, LooperExecutor.class, "getHandler");
+ }
+
+ public void setHandler(@Nullable Handler handler) {
+ mOverriddenHandler = handler;
+ }
+}
diff --git a/robolectric_tests/src/com/android/launcher3/shadows/ShadowMainThreadInitializedObject.java b/robolectric_tests/src/com/android/launcher3/shadows/ShadowMainThreadInitializedObject.java
new file mode 100644
index 0000000000..6e2ccf809f
--- /dev/null
+++ b/robolectric_tests/src/com/android/launcher3/shadows/ShadowMainThreadInitializedObject.java
@@ -0,0 +1,61 @@
+/*
+ * 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.
+ */
+
+package com.android.launcher3.shadows;
+
+import static org.robolectric.shadow.api.Shadow.invokeConstructor;
+import static org.robolectric.util.ReflectionHelpers.ClassParameter.from;
+
+import com.android.launcher3.util.MainThreadInitializedObject;
+import com.android.launcher3.util.MainThreadInitializedObject.ObjectProvider;
+
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+import org.robolectric.annotation.RealObject;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Set;
+import java.util.WeakHashMap;
+
+/**
+ * Shadow for {@link MainThreadInitializedObject} to provide reset functionality for static sObjects
+ */
+@Implements(value = MainThreadInitializedObject.class, isInAndroidSdk = false)
+public class ShadowMainThreadInitializedObject {
+
+ // Keep reference to all created MainThreadInitializedObject so they can be cleared after test
+ private static Set<MainThreadInitializedObject> sObjects =
+ Collections.synchronizedSet(Collections.newSetFromMap(new WeakHashMap<>()));
+
+ @RealObject private MainThreadInitializedObject mRealObject;
+
+ @Implementation
+ protected void __constructor__(ObjectProvider provider) {
+ invokeConstructor(MainThreadInitializedObject.class, mRealObject,
+ from(ObjectProvider.class, provider));
+ sObjects.add(mRealObject);
+ }
+
+ /**
+ * Resets all the initialized sObjects to be null
+ */
+ public static void resetInitializedObjects() {
+ for (MainThreadInitializedObject object : new ArrayList<>(sObjects)) {
+ object.initializeForTesting(null);
+ }
+ }
+}
diff --git a/robolectric_tests/src/com/android/launcher3/shadows/ShadowOverrides.java b/robolectric_tests/src/com/android/launcher3/shadows/ShadowOverrides.java
new file mode 100644
index 0000000000..131f69136c
--- /dev/null
+++ b/robolectric_tests/src/com/android/launcher3/shadows/ShadowOverrides.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2020 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.launcher3.shadows;
+
+import android.content.Context;
+
+import com.android.launcher3.util.MainThreadInitializedObject.ObjectProvider;
+import com.android.launcher3.util.ResourceBasedOverride;
+import com.android.launcher3.util.ResourceBasedOverride.Overrides;
+
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+import org.robolectric.shadow.api.Shadow;
+import org.robolectric.util.ReflectionHelpers.ClassParameter;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Shadow for {@link Overrides} to provide custom overrides for test
+ */
+@Implements(value = Overrides.class, isInAndroidSdk = false)
+public class ShadowOverrides {
+
+ private static Map<Class, ObjectProvider> sProviderMap = new HashMap<>();
+
+ @Implementation
+ public static <T extends ResourceBasedOverride> T getObject(
+ Class<T> clazz, Context context, int resId) {
+ ObjectProvider<T> provider = sProviderMap.get(clazz);
+ if (provider != null) {
+ return provider.get(context);
+ }
+ return Shadow.directlyOn(Overrides.class, "getObject",
+ ClassParameter.from(Class.class, clazz),
+ ClassParameter.from(Context.class, context),
+ ClassParameter.from(int.class, resId));
+ }
+
+ public static <T> void setProvider(Class<T> clazz, ObjectProvider<T> provider) {
+ sProviderMap.put(clazz, provider);
+ }
+
+ public static void clearProvider() {
+ sProviderMap.clear();
+ }
+}
diff --git a/robolectric_tests/src/com/android/launcher3/shadows/ShadowSurfaceTransactionApplier.java b/robolectric_tests/src/com/android/launcher3/shadows/ShadowSurfaceTransactionApplier.java
new file mode 100644
index 0000000000..a9f2f270a3
--- /dev/null
+++ b/robolectric_tests/src/com/android/launcher3/shadows/ShadowSurfaceTransactionApplier.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2020 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.launcher3.shadows;
+
+import static org.robolectric.shadow.api.Shadow.invokeConstructor;
+import static org.robolectric.util.ReflectionHelpers.ClassParameter.from;
+
+import android.view.View;
+
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+import org.robolectric.annotation.RealObject;
+
+/**
+ * Shadow for SurfaceTransactionApplier to override default functionality
+ */
+@Implements(className = "com.android.quickstep.util.SurfaceTransactionApplier",
+ isInAndroidSdk = false)
+public class ShadowSurfaceTransactionApplier {
+
+ @RealObject
+ private Object mRealObject;
+
+ @Implementation
+ protected void __constructor__(View view) {
+ invokeConstructor(mRealObject.getClass(), mRealObject, from(View.class, null));
+ }
+}
diff --git a/robolectric_tests/src/com/android/launcher3/testing/TestActivity.java b/robolectric_tests/src/com/android/launcher3/testing/TestActivity.java
new file mode 100644
index 0000000000..17d0ac1a9f
--- /dev/null
+++ b/robolectric_tests/src/com/android/launcher3/testing/TestActivity.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2021 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.launcher3.testing;
+
+import com.android.launcher3.BaseActivity;
+import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.views.ActivityContext;
+import com.android.launcher3.views.BaseDragLayer;
+
+/** An empty activity for {@link android.app.Fragment}s, {@link android.view.View}s testing. */
+public class TestActivity extends BaseActivity implements ActivityContext {
+
+ private DeviceProfile mDeviceProfile;
+
+ @Override
+ public BaseDragLayer getDragLayer() {
+ return new BaseDragLayer(this, /* attrs= */ null, /* alphaChannelCount= */ 1) {
+ @Override
+ public void recreateControllers() {
+ // Do nothing.
+ }
+ };
+ }
+
+ @Override
+ public DeviceProfile getDeviceProfile() {
+ return mDeviceProfile;
+ }
+
+ public void setDeviceProfile(DeviceProfile deviceProfile) {
+ mDeviceProfile = deviceProfile;
+ }
+}
diff --git a/robolectric_tests/src/com/android/launcher3/ui/LauncherUIScrollTest.java b/robolectric_tests/src/com/android/launcher3/ui/LauncherUIScrollTest.java
new file mode 100644
index 0000000000..ea755484c1
--- /dev/null
+++ b/robolectric_tests/src/com/android/launcher3/ui/LauncherUIScrollTest.java
@@ -0,0 +1,181 @@
+/*
+ * Copyright (C) 2020 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.launcher3.ui;
+
+import static com.android.launcher3.util.LauncherModelHelper.TEST_PACKAGE;
+import static com.android.launcher3.util.LauncherUIHelper.buildAndBindLauncher;
+import static com.android.launcher3.util.LauncherUIHelper.doLayout;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+
+import android.content.Context;
+import android.os.SystemClock;
+import android.provider.Settings;
+import android.view.InputDevice;
+import android.view.MotionEvent;
+import android.view.MotionEvent.PointerProperties;
+
+import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.InvariantDeviceProfile;
+import com.android.launcher3.Launcher;
+import com.android.launcher3.LauncherState;
+import com.android.launcher3.folder.Folder;
+import com.android.launcher3.folder.FolderIcon;
+import com.android.launcher3.folder.FolderPagedView;
+import com.android.launcher3.util.LauncherLayoutBuilder;
+import com.android.launcher3.util.LauncherLayoutBuilder.FolderBuilder;
+import com.android.launcher3.util.LauncherModelHelper;
+import com.android.launcher3.widget.picker.WidgetsFullSheet;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.LooperMode;
+import org.robolectric.annotation.LooperMode.Mode;
+import org.robolectric.shadows.ShadowLooper;
+
+/**
+ * Tests scroll behavior at various Launcher UI components
+ */
+@RunWith(RobolectricTestRunner.class)
+@LooperMode(Mode.PAUSED)
+@org.junit.Ignore
+public class LauncherUIScrollTest {
+
+ private Context mTargetContext;
+ private InvariantDeviceProfile mIdp;
+ private LauncherModelHelper mModelHelper;
+
+ private LauncherLayoutBuilder mLayoutBuilder;
+
+ @Before
+ public void setup() throws Exception {
+ mModelHelper = new LauncherModelHelper();
+ mTargetContext = RuntimeEnvironment.application;
+ mIdp = InvariantDeviceProfile.INSTANCE.get(mTargetContext);
+
+ Settings.Global.putFloat(mTargetContext.getContentResolver(),
+ Settings.Global.WINDOW_ANIMATION_SCALE, 0);
+
+ mModelHelper.installApp(TEST_PACKAGE);
+ // LayoutBuilder with 3 workspace pages
+ mLayoutBuilder = new LauncherLayoutBuilder()
+ .atWorkspace(0, mIdp.numRows - 1, 0).putApp(TEST_PACKAGE, TEST_PACKAGE)
+ .atWorkspace(0, mIdp.numRows - 1, 1).putApp(TEST_PACKAGE, TEST_PACKAGE)
+ .atWorkspace(0, mIdp.numRows - 1, 2).putApp(TEST_PACKAGE, TEST_PACKAGE);
+ }
+
+ @Test
+ public void testWorkspacePagesBound() throws Exception {
+ // Verify that the workspace if bound synchronously
+ Launcher launcher = loadLauncher();
+ assertEquals(3, launcher.getWorkspace().getPageCount());
+ assertEquals(0, launcher.getWorkspace().getCurrentPage());
+
+ launcher.dispatchGenericMotionEvent(createScrollEvent(-1));
+ assertNotEquals("Workspace was not scrolled",
+ 0, launcher.getWorkspace().getNextPage());
+ }
+
+ @Test
+ public void testAllAppsScroll() throws Exception {
+ // Install 100 apps
+ for (int i = 0; i < 100; i++) {
+ mModelHelper.installApp(TEST_PACKAGE + i);
+ }
+
+ // Bind and open all-apps
+ Launcher launcher = loadLauncher();
+ launcher.getStateManager().goToState(LauncherState.ALL_APPS, false);
+ doLayout(launcher);
+
+ int currentScroll = launcher.getAppsView().getActiveRecyclerView().getCurrentScrollY();
+ launcher.dispatchGenericMotionEvent(createScrollEvent(-1));
+ int newScroll = launcher.getAppsView().getActiveRecyclerView().getCurrentScrollY();
+
+ assertNotEquals("All Apps was not scrolled", currentScroll, newScroll);
+ assertEquals("Workspace was scrolled", 0, launcher.getWorkspace().getNextPage());
+ }
+
+ @Test
+ public void testWidgetsListScroll() throws Exception {
+ // Install 100 widgets
+ for (int i = 0; i < 100; i++) {
+ mModelHelper.installCustomShortcut(TEST_PACKAGE + i, "shortcutProvider");
+ }
+
+ // Bind and open widgets
+ Launcher launcher = loadLauncher();
+ WidgetsFullSheet widgets = WidgetsFullSheet.show(launcher, false);
+ doLayout(launcher);
+
+ int currentScroll = widgets.getRecyclerView().getCurrentScrollY();
+ launcher.dispatchGenericMotionEvent(createScrollEvent(-1));
+ int newScroll = widgets.getRecyclerView().getCurrentScrollY();
+ assertNotEquals("Widgets was not scrolled", currentScroll, newScroll);
+ assertEquals("Workspace was scrolled", 0, launcher.getWorkspace().getNextPage());
+ }
+
+ @Test
+ public void testFolderPageScroll() throws Exception {
+ // Add a folder with multiple icons
+ FolderBuilder fb = mLayoutBuilder.atWorkspace(mIdp.numColumns / 2, mIdp.numRows / 2, 0)
+ .putFolder(0);
+ for (int i = 0; i < 100; i++) {
+ fb.addApp(TEST_PACKAGE, TEST_PACKAGE);
+ }
+
+ // Bind and open folder
+ Launcher launcher = loadLauncher();
+ doLayout(launcher);
+ launcher.getWorkspace().getFirstMatch((i, v) -> v instanceof FolderIcon).performClick();
+ ShadowLooper.idleMainLooper();
+ doLayout(launcher);
+ FolderPagedView folderPages = Folder.getOpen(launcher).getContent();
+
+ assertEquals(0, folderPages.getNextPage());
+ launcher.dispatchGenericMotionEvent(createScrollEvent(-1));
+ assertNotEquals("Folder page was not scrolled", 0, folderPages.getNextPage());
+ assertEquals("Workspace was scrolled", 0, launcher.getWorkspace().getNextPage());
+ }
+
+ private Launcher loadLauncher() throws Exception {
+ mModelHelper.setupDefaultLayoutProvider(mLayoutBuilder).loadModelSync();
+ return buildAndBindLauncher();
+ }
+
+ private static MotionEvent createScrollEvent(int scroll) {
+ DeviceProfile dp = InvariantDeviceProfile.INSTANCE
+ .get(RuntimeEnvironment.application).supportedProfiles.get(0);
+
+ final PointerProperties[] pointerProperties = new PointerProperties[1];
+ pointerProperties[0] = new PointerProperties();
+ pointerProperties[0].id = 0;
+ final MotionEvent.PointerCoords[] coords = new MotionEvent.PointerCoords[1];
+ coords[0] = new MotionEvent.PointerCoords();
+ coords[0].setAxisValue(MotionEvent.AXIS_VSCROLL, scroll);
+ coords[0].x = dp.widthPx / 2;
+ coords[0].y = dp.heightPx / 2;
+
+ final long time = SystemClock.uptimeMillis();
+ return MotionEvent.obtain(time, time, MotionEvent.ACTION_SCROLL, 1,
+ pointerProperties, coords, 0, 0, 1.0f, 1.0f, 0, 0,
+ InputDevice.SOURCE_CLASS_POINTER, 0);
+ }
+
+}
diff --git a/tests/src/com/android/launcher3/util/GridOccupancyTest.java b/robolectric_tests/src/com/android/launcher3/util/GridOccupancyTest.java
index b498077d53..2f3fc3764d 100644
--- a/tests/src/com/android/launcher3/util/GridOccupancyTest.java
+++ b/robolectric_tests/src/com/android/launcher3/util/GridOccupancyTest.java
@@ -4,17 +4,14 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
-
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
/**
* Unit tests for {@link GridOccupancy}
*/
-@SmallTest
-@RunWith(AndroidJUnit4.class)
+@RunWith(RobolectricTestRunner.class)
public class GridOccupancyTest {
@Test
diff --git a/tests/src/com/android/launcher3/util/IntArrayTest.java b/robolectric_tests/src/com/android/launcher3/util/IntArrayTest.java
index a3c70076cd..c08e198a8c 100644
--- a/tests/src/com/android/launcher3/util/IntArrayTest.java
+++ b/robolectric_tests/src/com/android/launcher3/util/IntArrayTest.java
@@ -17,17 +17,14 @@ package com.android.launcher3.util;
import static com.google.common.truth.Truth.assertThat;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
-
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
/**
- * Unit tests for {@link IntArray}
+ * Robolectric unit tests for {@link IntArray}
*/
-@SmallTest
-@RunWith(AndroidJUnit4.class)
+@RunWith(RobolectricTestRunner.class)
public class IntArrayTest {
@Test
diff --git a/tests/src/com/android/launcher3/util/IntSetTest.java b/robolectric_tests/src/com/android/launcher3/util/IntSetTest.java
index cdb2891c9d..7a8c00b3c7 100644
--- a/tests/src/com/android/launcher3/util/IntSetTest.java
+++ b/robolectric_tests/src/com/android/launcher3/util/IntSetTest.java
@@ -21,17 +21,14 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
-
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
/**
- * Unit tests for {@link IntSet}
+ * Robolectric unit tests for {@link IntSet}
*/
-@SmallTest
-@RunWith(AndroidJUnit4.class)
+@RunWith(RobolectricTestRunner.class)
public class IntSetTest {
@Test
diff --git a/tests/src/com/android/launcher3/util/LauncherLayoutBuilder.java b/robolectric_tests/src/com/android/launcher3/util/LauncherLayoutBuilder.java
index 4e21dce021..4e21dce021 100644
--- a/tests/src/com/android/launcher3/util/LauncherLayoutBuilder.java
+++ b/robolectric_tests/src/com/android/launcher3/util/LauncherLayoutBuilder.java
diff --git a/tests/src/com/android/launcher3/util/LauncherModelHelper.java b/robolectric_tests/src/com/android/launcher3/util/LauncherModelHelper.java
index 33249592c2..846e2019a0 100644
--- a/tests/src/com/android/launcher3/util/LauncherModelHelper.java
+++ b/robolectric_tests/src/com/android/launcher3/util/LauncherModelHelper.java
@@ -15,40 +15,26 @@
*/
package com.android.launcher3.util;
-import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
-import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
+import static android.content.Intent.ACTION_CREATE_SHORTCUT;
import static com.android.launcher3.LauncherSettings.Favorites.CONTENT_URI;
import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.atLeast;
-import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
+import static org.robolectric.Shadows.shadowOf;
import android.content.ComponentName;
-import android.content.ContentProvider;
-import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.content.pm.ProviderInfo;
-import android.content.res.Resources;
+import android.content.IntentFilter;
+import android.content.pm.PackageManager.NameNotFoundException;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
-import android.os.ParcelFileDescriptor;
-import android.os.ParcelFileDescriptor.AutoCloseOutputStream;
import android.os.Process;
import android.provider.Settings;
-import android.test.mock.MockContentResolver;
-import android.util.ArrayMap;
-
-import androidx.test.core.app.ApplicationProvider;
-import androidx.test.uiautomator.UiDevice;
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.LauncherAppState;
@@ -59,30 +45,27 @@ import com.android.launcher3.LauncherSettings;
import com.android.launcher3.model.AllAppsList;
import com.android.launcher3.model.BgDataModel;
import com.android.launcher3.model.BgDataModel.Callbacks;
-import com.android.launcher3.model.ItemInstallQueue;
import com.android.launcher3.model.data.AppInfo;
import com.android.launcher3.model.data.ItemInfo;
-import com.android.launcher3.pm.InstallSessionHelper;
import com.android.launcher3.pm.UserCache;
-import com.android.launcher3.testing.TestInformationProvider;
-import com.android.launcher3.uioverrides.plugins.PluginManagerWrapper;
-import com.android.launcher3.util.MainThreadInitializedObject.SandboxContext;
-import com.android.launcher3.util.window.WindowManagerProxy;
-import com.android.launcher3.widget.custom.CustomWidgetManager;
+import com.android.launcher3.shadows.ShadowLooperExecutor;
import org.mockito.ArgumentCaptor;
+import org.robolectric.Robolectric;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.shadow.api.Shadow;
+import org.robolectric.shadows.ShadowContentResolver;
+import org.robolectric.shadows.ShadowPackageManager;
+import org.robolectric.util.ReflectionHelpers;
import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileNotFoundException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.List;
-import java.util.UUID;
-import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
import java.util.function.Function;
@@ -98,9 +81,7 @@ public class LauncherModelHelper {
public static final int APP_ICON = LauncherSettings.Favorites.ITEM_TYPE_APPLICATION;
public static final int SHORTCUT = LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT;
public static final int NO__ICON = -1;
-
- public static final String TEST_PACKAGE = testContext().getPackageName();
- public static final String TEST_ACTIVITY = "com.android.launcher3.tests.Activity2";
+ public static final String TEST_PACKAGE = "com.android.launcher3.validpackage";
// Authority for providing a test default-workspace-layout data.
private static final String TEST_PROVIDER_AUTHORITY =
@@ -109,42 +90,21 @@ public class LauncherModelHelper {
private static final int DEFAULT_GRID_SIZE = 4;
private final HashMap<Class, HashMap<String, Field>> mFieldCache = new HashMap<>();
- private final MockContentResolver mMockResolver = new MockContentResolver();
public final TestLauncherProvider provider;
- public final SanboxModelContext sandboxContext;
-
- public final long defaultProfileId;
+ private final long mDefaultProfileId;
private BgDataModel mDataModel;
private AllAppsList mAllAppsList;
public LauncherModelHelper() {
- Context context = getApplicationContext();
- // System settings cache content provider. Ensure that they are statically initialized
- Settings.Secure.getString(context.getContentResolver(), "test");
- Settings.System.getString(context.getContentResolver(), "test");
- Settings.Global.getString(context.getContentResolver(), "test");
-
- provider = new TestLauncherProvider();
- sandboxContext = new SanboxModelContext();
- defaultProfileId = UserCache.INSTANCE.get(sandboxContext)
+ provider = Robolectric.setupContentProvider(TestLauncherProvider.class);
+ mDefaultProfileId = UserCache.INSTANCE.get(RuntimeEnvironment.application)
.getSerialNumberForUser(Process.myUserHandle());
- setupProvider(LauncherProvider.AUTHORITY, provider);
- }
-
- protected void setupProvider(String authority, ContentProvider provider) {
- ProviderInfo providerInfo = new ProviderInfo();
- providerInfo.authority = authority;
- providerInfo.applicationInfo = sandboxContext.getApplicationInfo();
- provider.attachInfo(sandboxContext, providerInfo);
- mMockResolver.addProvider(providerInfo.authority, provider);
- doReturn(providerInfo)
- .when(sandboxContext.mPm)
- .resolveContentProvider(eq(authority), anyInt());
+ ShadowContentResolver.registerProviderInternal(LauncherProvider.AUTHORITY, provider);
}
public LauncherModel getModel() {
- return LauncherAppState.getInstance(sandboxContext).getModel();
+ return LauncherAppState.getInstance(RuntimeEnvironment.application).getModel();
}
public synchronized BgDataModel getBgDataModel() {
@@ -161,28 +121,6 @@ public class LauncherModelHelper {
return mAllAppsList;
}
- public void destroy() {
- // When destroying the context, make sure that the model thread is blocked, so that no
- // new jobs get posted while we are cleaning up
- CountDownLatch l1 = new CountDownLatch(1);
- CountDownLatch l2 = new CountDownLatch(1);
- MODEL_EXECUTOR.execute(() -> {
- l1.countDown();
- waitOrThrow(l2);
- });
- waitOrThrow(l1);
- sandboxContext.onDestroy();
- l2.countDown();
- }
-
- private void waitOrThrow(CountDownLatch latch) {
- try {
- latch.await();
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- }
-
/**
* Synchronously executes the task and returns all the UI callbacks posted.
*/
@@ -223,16 +161,13 @@ public class LauncherModelHelper {
* Initializes mock data for the test.
*/
public void initializeData(String resourceName) throws Exception {
+ Context targetContext = RuntimeEnvironment.application;
BgDataModel bgDataModel = getBgDataModel();
AllAppsList allAppsList = getAllAppsList();
MODEL_EXECUTOR.submit(() -> {
- // Copy apk from resources to a local file and install from there.
- Resources resources = testContext().getResources();
- int resId = resources.getIdentifier(
- resourceName, "raw", testContext().getPackageName());
try (BufferedReader reader = new BufferedReader(new InputStreamReader(
- resources.openRawResource(resId)))) {
+ this.getClass().getResourceAsStream(resourceName)))) {
String line;
HashMap<String, Class> classMap = new HashMap<>();
while ((line = reader.readLine()) != null) {
@@ -246,7 +181,7 @@ public class LauncherModelHelper {
classMap.put(commands[1], Class.forName(commands[2]));
break;
case "bgItem":
- bgDataModel.addItem(sandboxContext,
+ bgDataModel.addItem(targetContext,
(ItemInfo) initItem(classMap.get(commands[1]), commands, 2),
false);
break;
@@ -301,7 +236,7 @@ public class LauncherModelHelper {
}
public int addItem(int type, int screen, int container, int x, int y) {
- return addItem(type, screen, container, x, y, defaultProfileId, TEST_PACKAGE);
+ return addItem(type, screen, container, x, y, mDefaultProfileId, TEST_PACKAGE);
}
public int addItem(int type, int screen, int container, int x, int y, long profileId) {
@@ -309,12 +244,12 @@ public class LauncherModelHelper {
}
public int addItem(int type, int screen, int container, int x, int y, String packageName) {
- return addItem(type, screen, container, x, y, defaultProfileId, packageName);
+ return addItem(type, screen, container, x, y, mDefaultProfileId, packageName);
}
public int addItem(int type, int screen, int container, int x, int y, String packageName,
int id, Uri contentUri) {
- addItem(type, screen, container, x, y, defaultProfileId, packageName, id, contentUri);
+ addItem(type, screen, container, x, y, mDefaultProfileId, packageName, id, contentUri);
return id;
}
@@ -325,7 +260,8 @@ public class LauncherModelHelper {
*/
public int addItem(int type, int screen, int container, int x, int y, long profileId,
String packageName) {
- int id = LauncherSettings.Settings.call(sandboxContext.getContentResolver(),
+ Context context = RuntimeEnvironment.application;
+ int id = LauncherSettings.Settings.call(context.getContentResolver(),
LauncherSettings.Settings.METHOD_NEW_ITEM_ID)
.getInt(LauncherSettings.Settings.EXTRA_VALUE);
addItem(type, screen, container, x, y, profileId, packageName, id, CONTENT_URI);
@@ -334,6 +270,8 @@ public class LauncherModelHelper {
public void addItem(int type, int screen, int container, int x, int y, long profileId,
String packageName, int id, Uri contentUri) {
+ Context context = RuntimeEnvironment.application;
+
ContentValues values = new ContentValues();
values.put(LauncherSettings.Favorites._ID, id);
values.put(LauncherSettings.Favorites.CONTAINER, container);
@@ -357,7 +295,7 @@ public class LauncherModelHelper {
}
}
- sandboxContext.getContentResolver().insert(contentUri, values);
+ context.getContentResolver().insert(contentUri, values);
}
public int[][][] createGrid(int[][][] typeArray) {
@@ -365,11 +303,12 @@ public class LauncherModelHelper {
}
public int[][][] createGrid(int[][][] typeArray, int startScreen) {
- LauncherSettings.Settings.call(sandboxContext.getContentResolver(),
+ final Context context = RuntimeEnvironment.application;
+ LauncherSettings.Settings.call(context.getContentResolver(),
LauncherSettings.Settings.METHOD_CREATE_EMPTY_DB);
- LauncherSettings.Settings.call(sandboxContext.getContentResolver(),
+ LauncherSettings.Settings.call(context.getContentResolver(),
LauncherSettings.Settings.METHOD_CLEAR_EMPTY_DB_FLAG);
- return createGrid(typeArray, startScreen, defaultProfileId);
+ return createGrid(typeArray, startScreen, mDefaultProfileId);
}
/**
@@ -381,13 +320,14 @@ public class LauncherModelHelper {
* @return the same grid representation where each entry is the corresponding item id.
*/
public int[][][] createGrid(int[][][] typeArray, int startScreen, long profileId) {
+ Context context = RuntimeEnvironment.application;
int[][][] ids = new int[typeArray.length][][];
for (int i = 0; i < typeArray.length; i++) {
// Add screen to DB
int screenId = startScreen + i;
// Keep the screen id counter up to date
- LauncherSettings.Settings.call(sandboxContext.getContentResolver(),
+ LauncherSettings.Settings.call(context.getContentResolver(),
LauncherSettings.Settings.METHOD_NEW_SCREEN_ID);
ids[i] = new int[typeArray[i].length][];
@@ -413,45 +353,69 @@ public class LauncherModelHelper {
*/
public LauncherModelHelper setupDefaultLayoutProvider(LauncherLayoutBuilder builder)
throws Exception {
- InvariantDeviceProfile idp = InvariantDeviceProfile.INSTANCE.get(sandboxContext);
+ Context context = RuntimeEnvironment.application;
+ InvariantDeviceProfile idp = InvariantDeviceProfile.INSTANCE.get(context);
idp.numRows = idp.numColumns = idp.numDatabaseHotseatIcons = DEFAULT_GRID_SIZE;
idp.iconBitmapSize = DEFAULT_BITMAP_SIZE;
- UiDevice.getInstance(getInstrumentation()).executeShellCommand(
- "settings put secure launcher3.layout.provider " + TEST_PROVIDER_AUTHORITY);
- ContentProvider cp = new TestInformationProvider() {
+ Settings.Secure.putString(context.getContentResolver(),
+ "launcher3.layout.provider", TEST_PROVIDER_AUTHORITY);
- @Override
- public ParcelFileDescriptor openFile(Uri uri, String mode)
- throws FileNotFoundException {
- try {
- ParcelFileDescriptor[] pipe = ParcelFileDescriptor.createPipe();
- AutoCloseOutputStream outputStream = new AutoCloseOutputStream(pipe[1]);
- ByteArrayOutputStream bos = new ByteArrayOutputStream();
- builder.build(new OutputStreamWriter(bos));
- outputStream.write(bos.toByteArray());
- outputStream.flush();
- outputStream.close();
- return pipe[0];
- } catch (Exception e) {
- throw new FileNotFoundException(e.getMessage());
- }
- }
- };
- setupProvider(TEST_PROVIDER_AUTHORITY, cp);
+ shadowOf(context.getPackageManager())
+ .addProviderIfNotPresent(new ComponentName("com.test", "Mock")).authority =
+ TEST_PROVIDER_AUTHORITY;
+
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ builder.build(new OutputStreamWriter(bos));
+ Uri layoutUri = LauncherProvider.getLayoutUri(TEST_PROVIDER_AUTHORITY, context);
+ shadowOf(context.getContentResolver()).registerInputStream(layoutUri,
+ new ByteArrayInputStream(bos.toByteArray()));
return this;
}
/**
+ * Simulates an apk install with a default main activity with same class and package name
+ */
+ public void installApp(String component) throws NameNotFoundException {
+ IntentFilter filter = new IntentFilter(Intent.ACTION_MAIN);
+ filter.addCategory(Intent.CATEGORY_LAUNCHER);
+ installApp(component, component, filter);
+ }
+
+ /**
+ * Simulates a custom shortcut install
+ */
+ public void installCustomShortcut(String pkg, String clazz) throws NameNotFoundException {
+ installApp(pkg, clazz, new IntentFilter(ACTION_CREATE_SHORTCUT));
+ }
+
+ private void installApp(String pkg, String clazz, IntentFilter filter)
+ throws NameNotFoundException {
+ ShadowPackageManager spm = shadowOf(RuntimeEnvironment.application.getPackageManager());
+ ComponentName cn = new ComponentName(pkg, clazz);
+ spm.addActivityIfNotPresent(cn);
+
+ filter.addCategory(Intent.CATEGORY_DEFAULT);
+ spm.addIntentFilterForActivity(cn, filter);
+ }
+
+ /**
* Loads the model in memory synchronously
*/
public void loadModelSync() throws ExecutionException, InterruptedException {
- Callbacks mockCb = new Callbacks() { };
- Executors.MAIN_EXECUTOR.submit(() -> getModel().addCallbacksAndLoad(mockCb)).get();
+ // Since robolectric tests run on main thread, we run the loader-UI calls on a temp thread,
+ // so that we can wait appropriately for the loader to complete.
+ ShadowLooperExecutor sle = Shadow.extract(Executors.MAIN_EXECUTOR);
+ sle.setHandler(Executors.UI_HELPER_EXECUTOR.getHandler());
+
+ Callbacks mockCb = mock(Callbacks.class);
+ getModel().addCallbacksAndLoad(mockCb);
Executors.MODEL_EXECUTOR.submit(() -> { }).get();
- Executors.MAIN_EXECUTOR.submit(() -> { }).get();
- Executors.MAIN_EXECUTOR.submit(() -> getModel().removeCallbacks(mockCb)).get();
+ Executors.UI_HELPER_EXECUTOR.submit(() -> { }).get();
+
+ sle.setHandler(null);
+ getModel().removeCallbacks(mockCb);
}
/**
@@ -473,91 +437,4 @@ public class LauncherModelHelper {
return mOpenHelper;
}
}
-
- public static boolean deleteContents(File dir) {
- File[] files = dir.listFiles();
- boolean success = true;
- if (files != null) {
- for (File file : files) {
- if (file.isDirectory()) {
- success &= deleteContents(file);
- }
- if (!file.delete()) {
- success = false;
- }
- }
- }
- return success;
- }
-
- public class SanboxModelContext extends SandboxContext {
-
- private final ArrayMap<String, Object> mSpiedServices = new ArrayMap<>();
- private final PackageManager mPm;
- private final File mDbDir;
-
- SanboxModelContext() {
- super(ApplicationProvider.getApplicationContext(),
- UserCache.INSTANCE, InstallSessionHelper.INSTANCE,
- LauncherAppState.INSTANCE, InvariantDeviceProfile.INSTANCE,
- DisplayController.INSTANCE, CustomWidgetManager.INSTANCE,
- SettingsCache.INSTANCE, PluginManagerWrapper.INSTANCE,
- ItemInstallQueue.INSTANCE, WindowManagerProxy.INSTANCE);
- mPm = spy(getBaseContext().getPackageManager());
- mDbDir = new File(getCacheDir(), UUID.randomUUID().toString());
- }
-
- public SanboxModelContext allow(MainThreadInitializedObject object) {
- mAllowedObjects.add(object);
- return this;
- }
-
- @Override
- public File getDatabasePath(String name) {
- if (!mDbDir.exists()) {
- mDbDir.mkdirs();
- }
- return new File(mDbDir, name);
- }
-
- @Override
- public ContentResolver getContentResolver() {
- return mMockResolver;
- }
-
- @Override
- public void onDestroy() {
- if (deleteContents(mDbDir)) {
- mDbDir.delete();
- }
- super.onDestroy();
- }
-
- @Override
- public PackageManager getPackageManager() {
- return mPm;
- }
-
- @Override
- public Object getSystemService(String name) {
- Object service = mSpiedServices.get(name);
- return service != null ? service : super.getSystemService(name);
- }
-
- public <T> T spyService(Class<T> tClass) {
- String name = getSystemServiceName(tClass);
- Object service = mSpiedServices.get(name);
- if (service != null) {
- return (T) service;
- }
-
- T result = spy(getSystemService(tClass));
- mSpiedServices.put(name, result);
- return result;
- }
- }
-
- private static Context testContext() {
- return getInstrumentation().getContext();
- }
}
diff --git a/robolectric_tests/src/com/android/launcher3/util/LauncherTestApplication.java b/robolectric_tests/src/com/android/launcher3/util/LauncherTestApplication.java
new file mode 100644
index 0000000000..efac15098c
--- /dev/null
+++ b/robolectric_tests/src/com/android/launcher3/util/LauncherTestApplication.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2020 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.launcher3.util;
+
+import static org.mockito.Mockito.mock;
+
+import android.app.Application;
+
+import com.android.launcher3.shadows.ShadowMainThreadInitializedObject;
+import com.android.launcher3.shadows.ShadowOverrides;
+import com.android.launcher3.uioverrides.plugins.PluginManagerWrapper;
+
+import org.robolectric.TestLifecycleApplication;
+import org.robolectric.shadows.ShadowLog;
+
+import java.lang.reflect.Method;
+
+public class LauncherTestApplication extends Application implements TestLifecycleApplication {
+
+ @Override
+ public void beforeTest(Method method) {
+ ShadowLog.stream = System.out;
+
+ // Disable plugins
+ PluginManagerWrapper.INSTANCE.initializeForTesting(mock(PluginManagerWrapper.class));
+ }
+
+ @Override
+ public void prepareTest(Object test) { }
+
+ @Override
+ public void afterTest(Method method) {
+ ShadowLog.stream = null;
+ ShadowMainThreadInitializedObject.resetInitializedObjects();
+ ShadowOverrides.clearProvider();
+ }
+}
diff --git a/robolectric_tests/src/com/android/launcher3/util/LauncherUIHelper.java b/robolectric_tests/src/com/android/launcher3/util/LauncherUIHelper.java
new file mode 100644
index 0000000000..fdddab49ce
--- /dev/null
+++ b/robolectric_tests/src/com/android/launcher3/util/LauncherUIHelper.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2020 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.launcher3.util;
+
+import static android.view.View.MeasureSpec.EXACTLY;
+import static android.view.View.MeasureSpec.makeMeasureSpec;
+
+import static com.android.launcher3.Utilities.createHomeIntent;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ResolveInfo;
+import android.graphics.Point;
+import android.view.View;
+import android.view.WindowManager;
+
+import com.android.launcher3.Launcher;
+
+import org.robolectric.Robolectric;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.android.controller.ActivityController;
+import org.robolectric.shadows.ShadowLooper;
+import org.robolectric.util.ReflectionHelpers;
+
+import java.util.List;
+
+/**
+ * Utility class to help manage Launcher UI and related objects for test.
+ */
+public class LauncherUIHelper {
+
+ /**
+ * Returns the class name for the Launcher activity as defined in the manifest
+ */
+ public static String getLauncherClassName() {
+ Context context = RuntimeEnvironment.application;
+ Intent homeIntent = createHomeIntent().setPackage(context.getPackageName());
+
+ List<ResolveInfo> launchers = context.getPackageManager()
+ .queryIntentActivities(homeIntent, 0);
+ if (launchers.size() != 1) {
+ return null;
+ }
+ return launchers.get(0).activityInfo.name;
+ }
+
+ /**
+ * Returns an activity controller for Launcher activity defined in the manifest
+ */
+ public static <T extends Launcher> ActivityController<T> buildLauncher() {
+ try {
+ Class<T> tClass = (Class<T>) Class.forName(getLauncherClassName());
+ return Robolectric.buildActivity(tClass);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * Creates and binds a Launcher activity defined in the manifest.
+ * Note that the model must be bound before calling this
+ */
+ public static <T extends Launcher> T buildAndBindLauncher() {
+ ActivityController<T> controller = buildLauncher();
+
+ T launcher = controller.setup().get();
+ doLayout(launcher);
+ ViewOnDrawExecutor executor = ReflectionHelpers.getField(launcher, "mPendingExecutor");
+ if (executor != null) {
+ executor.runAllTasks();
+ }
+ return launcher;
+ }
+
+ /**
+ * Performs a measure and layout pass for the given activity
+ */
+ public static void doLayout(Activity activity) {
+ Point size = new Point();
+ RuntimeEnvironment.application.getSystemService(WindowManager.class)
+ .getDefaultDisplay().getSize(size);
+ View view = activity.getWindow().getDecorView();
+ view.measure(makeMeasureSpec(size.x, EXACTLY), makeMeasureSpec(size.y, EXACTLY));
+ view.layout(0, 0, size.x, size.y);
+ ShadowLooper.idleMainLooper();
+ }
+}
diff --git a/robolectric_tests/src/com/android/launcher3/widget/CachingWidgetPreviewLoaderTest.java b/robolectric_tests/src/com/android/launcher3/widget/CachingWidgetPreviewLoaderTest.java
new file mode 100644
index 0000000000..1090d1e69b
--- /dev/null
+++ b/robolectric_tests/src/com/android/launcher3/widget/CachingWidgetPreviewLoaderTest.java
@@ -0,0 +1,409 @@
+/*
+ * Copyright (C) 2021 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.launcher3.widget;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.when;
+
+import android.content.ComponentName;
+import android.graphics.Bitmap;
+import android.os.CancellationSignal;
+import android.os.UserHandle;
+import android.util.Size;
+
+import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.InvariantDeviceProfile;
+import com.android.launcher3.icons.IconCache;
+import com.android.launcher3.model.WidgetItem;
+import com.android.launcher3.testing.TestActivity;
+import com.android.launcher3.widget.WidgetPreviewLoader.WidgetPreviewLoadedCallback;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.Robolectric;
+import org.robolectric.RobolectricTestRunner;
+
+import java.util.Arrays;
+import java.util.Collections;
+
+@RunWith(RobolectricTestRunner.class)
+public class CachingWidgetPreviewLoaderTest {
+ private final Size SIZE_10_10 = new Size(10, 10);
+ private final Size SIZE_20_20 = new Size(20, 20);
+ private static final String TEST_PACKAGE = "com.example.test";
+ private final ComponentName TEST_PROVIDER =
+ new ComponentName(TEST_PACKAGE, ".WidgetProvider");
+ private final ComponentName TEST_PROVIDER2 =
+ new ComponentName(TEST_PACKAGE, ".WidgetProvider2");
+ private final Bitmap BITMAP = Bitmap.createBitmap(10, 10, Bitmap.Config.ARGB_8888);
+ private final Bitmap BITMAP2 = Bitmap.createBitmap(20, 20, Bitmap.Config.ARGB_8888);
+
+
+ @Mock private CancellationSignal mCancellationSignal;
+ @Mock private WidgetPreviewLoader mDelegate;
+ @Mock private IconCache mIconCache;
+ @Mock private DeviceProfile mDeviceProfile;
+ @Mock private LauncherAppWidgetProviderInfo mProviderInfo;
+ @Mock private LauncherAppWidgetProviderInfo mProviderInfo2;
+ @Mock private WidgetPreviewLoadedCallback mPreviewLoadedCallback;
+ @Mock private WidgetPreviewLoadedCallback mPreviewLoadedCallback2;
+ @Captor private ArgumentCaptor<WidgetPreviewLoadedCallback> mCallbackCaptor;
+
+ private TestActivity mTestActivity;
+ private CachingWidgetPreviewLoader mLoader;
+ private WidgetItem mWidgetItem;
+ private WidgetItem mWidgetItem2;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ mLoader = new CachingWidgetPreviewLoader(mDelegate);
+
+ mTestActivity = Robolectric.buildActivity(TestActivity.class).setup().get();
+ mTestActivity.setDeviceProfile(mDeviceProfile);
+
+ when(mDelegate.loadPreview(any(), any(), any(), any())).thenReturn(mCancellationSignal);
+
+ mProviderInfo.provider = TEST_PROVIDER;
+ when(mProviderInfo.getProfile()).thenReturn(new UserHandle(0));
+
+ mProviderInfo2.provider = TEST_PROVIDER2;
+ when(mProviderInfo2.getProfile()).thenReturn(new UserHandle(0));
+
+ InvariantDeviceProfile testProfile = new InvariantDeviceProfile();
+ testProfile.numRows = 5;
+ testProfile.numColumns = 5;
+
+ mWidgetItem = new WidgetItem(mProviderInfo, testProfile, mIconCache);
+ mWidgetItem2 = new WidgetItem(mProviderInfo2, testProfile, mIconCache);
+ }
+
+ @Test
+ public void getPreview_notInCache_shouldReturnNull() {
+ assertThat(mLoader.getPreview(mWidgetItem, SIZE_10_10)).isNull();
+ }
+
+ @Test
+ public void getPreview_notInCache_shouldNotCallDelegate() {
+ mLoader.getPreview(mWidgetItem, SIZE_10_10);
+
+ verifyZeroInteractions(mDelegate);
+ }
+
+ @Test
+ public void getPreview_inCache_shouldReturnCachedBitmap() {
+ loadPreviewIntoCache(mWidgetItem, SIZE_10_10, BITMAP);
+
+ assertThat(mLoader.getPreview(mWidgetItem, SIZE_10_10)).isEqualTo(BITMAP);
+ }
+
+ @Test
+ public void getPreview_otherSizeInCache_shouldReturnNull() {
+ loadPreviewIntoCache(mWidgetItem, SIZE_10_10, BITMAP);
+
+ assertThat(mLoader.getPreview(mWidgetItem, SIZE_20_20)).isNull();
+ }
+
+ @Test
+ public void getPreview_otherItemInCache_shouldReturnNull() {
+ loadPreviewIntoCache(mWidgetItem, SIZE_10_10, BITMAP);
+
+ assertThat(mLoader.getPreview(mWidgetItem2, SIZE_10_10)).isNull();
+ }
+
+ @Test
+ public void getPreview_shouldStoreMultipleSizesPerItem() {
+ loadPreviewIntoCache(mWidgetItem, SIZE_10_10, BITMAP);
+ loadPreviewIntoCache(mWidgetItem, SIZE_20_20, BITMAP2);
+
+ assertThat(mLoader.getPreview(mWidgetItem, SIZE_10_10)).isEqualTo(BITMAP);
+ assertThat(mLoader.getPreview(mWidgetItem, SIZE_20_20)).isEqualTo(BITMAP2);
+ }
+
+ @Test
+ public void loadPreview_notInCache_shouldStartLoading() {
+ mLoader.loadPreview(mTestActivity, mWidgetItem, SIZE_10_10, mPreviewLoadedCallback);
+
+ verify(mDelegate).loadPreview(eq(mTestActivity), eq(mWidgetItem), eq(SIZE_10_10), any());
+ verifyZeroInteractions(mPreviewLoadedCallback);
+ }
+
+ @Test
+ public void loadPreview_thenLoaded_shouldCallBack() {
+ mLoader.loadPreview(mTestActivity, mWidgetItem, SIZE_10_10, mPreviewLoadedCallback);
+ verify(mDelegate).loadPreview(any(), any(), any(), mCallbackCaptor.capture());
+ WidgetPreviewLoadedCallback loaderCallback = mCallbackCaptor.getValue();
+
+ loaderCallback.onPreviewLoaded(BITMAP);
+
+ verify(mPreviewLoadedCallback).onPreviewLoaded(BITMAP);
+ }
+
+ @Test
+ public void loadPreview_thenCancelled_shouldCancelDelegateRequest() {
+ CancellationSignal cancellationSignal =
+ mLoader.loadPreview(mTestActivity, mWidgetItem, SIZE_10_10, mPreviewLoadedCallback);
+
+ cancellationSignal.cancel();
+
+ verify(mCancellationSignal).cancel();
+ verifyZeroInteractions(mPreviewLoadedCallback);
+ assertThat(mLoader.getPreview(mWidgetItem, SIZE_10_10)).isNull();
+ }
+
+ @Test
+ public void loadPreview_thenCancelled_otherCallListening_shouldNotCancelDelegateRequest() {
+ CancellationSignal cancellationSignal1 =
+ mLoader.loadPreview(mTestActivity, mWidgetItem, SIZE_10_10, mPreviewLoadedCallback);
+ mLoader.loadPreview(mTestActivity, mWidgetItem, SIZE_10_10, mPreviewLoadedCallback2);
+
+ cancellationSignal1.cancel();
+
+ verifyZeroInteractions(mCancellationSignal);
+ }
+
+ @Test
+ public void loadPreview_thenCancelled_otherCallListening_loaded_shouldCallBackToNonCancelled() {
+ CancellationSignal cancellationSignal1 =
+ mLoader.loadPreview(mTestActivity, mWidgetItem, SIZE_10_10, mPreviewLoadedCallback);
+ mLoader.loadPreview(mTestActivity, mWidgetItem, SIZE_10_10, mPreviewLoadedCallback2);
+ verify(mDelegate).loadPreview(any(), any(), any(), mCallbackCaptor.capture());
+ WidgetPreviewLoadedCallback loaderCallback = mCallbackCaptor.getValue();
+
+ cancellationSignal1.cancel();
+ loaderCallback.onPreviewLoaded(BITMAP);
+
+ verifyZeroInteractions(mPreviewLoadedCallback);
+ verify(mPreviewLoadedCallback2).onPreviewLoaded(BITMAP);
+ assertThat(mLoader.getPreview(mWidgetItem, SIZE_10_10)).isEqualTo(BITMAP);
+ }
+
+ @Test
+ public void loadPreview_thenCancelled_bothCallsCancelled_shouldCancelDelegateRequest() {
+ CancellationSignal cancellationSignal1 =
+ mLoader.loadPreview(mTestActivity, mWidgetItem, SIZE_10_10, mPreviewLoadedCallback);
+ CancellationSignal cancellationSignal2 =
+ mLoader.loadPreview(
+ mTestActivity, mWidgetItem, SIZE_10_10, mPreviewLoadedCallback2);
+
+ cancellationSignal1.cancel();
+ cancellationSignal2.cancel();
+
+ verify(mCancellationSignal).cancel();
+ verifyZeroInteractions(mPreviewLoadedCallback);
+ verifyZeroInteractions(mPreviewLoadedCallback2);
+ assertThat(mLoader.getPreview(mWidgetItem, SIZE_10_10)).isNull();
+ }
+
+ @Test
+ public void loadPreview_multipleCallbacks_shouldOnlyCallDelegateOnce() {
+ mLoader.loadPreview(mTestActivity, mWidgetItem, SIZE_10_10, mPreviewLoadedCallback);
+ mLoader.loadPreview(mTestActivity, mWidgetItem, SIZE_10_10, mPreviewLoadedCallback2);
+
+ verify(mDelegate).loadPreview(any(), any(), any(), any());
+ }
+
+ @Test
+ public void loadPreview_multipleCallbacks_shouldForwardResultToEachCallback() {
+ mLoader.loadPreview(mTestActivity, mWidgetItem, SIZE_10_10, mPreviewLoadedCallback);
+ mLoader.loadPreview(mTestActivity, mWidgetItem, SIZE_10_10, mPreviewLoadedCallback2);
+
+ verify(mDelegate).loadPreview(any(), any(), any(), mCallbackCaptor.capture());
+ WidgetPreviewLoadedCallback loaderCallback = mCallbackCaptor.getValue();
+
+ loaderCallback.onPreviewLoaded(BITMAP);
+
+ verify(mPreviewLoadedCallback).onPreviewLoaded(BITMAP);
+ verify(mPreviewLoadedCallback2).onPreviewLoaded(BITMAP);
+ }
+
+ @Test
+ public void loadPreview_inCache_shouldCallBackImmediately() {
+ loadPreviewIntoCache(mWidgetItem, SIZE_10_10, BITMAP);
+ reset(mDelegate);
+
+ mLoader.loadPreview(mTestActivity, mWidgetItem, SIZE_10_10, mPreviewLoadedCallback);
+
+ verify(mPreviewLoadedCallback).onPreviewLoaded(BITMAP);
+ verifyZeroInteractions(mDelegate);
+ }
+
+ @Test
+ public void loadPreview_thenLoaded_thenCancelled_shouldNotRemovePreviewFromCache() {
+ CancellationSignal cancellationSignal =
+ mLoader.loadPreview(mTestActivity, mWidgetItem, SIZE_10_10, mPreviewLoadedCallback);
+ verify(mDelegate).loadPreview(any(), any(), any(), mCallbackCaptor.capture());
+ WidgetPreviewLoadedCallback loaderCallback = mCallbackCaptor.getValue();
+ loaderCallback.onPreviewLoaded(BITMAP);
+
+ cancellationSignal.cancel();
+
+ assertThat(mLoader.getPreview(mWidgetItem, SIZE_10_10)).isEqualTo(BITMAP);
+ }
+
+ @Test
+ public void isPreviewLoaded_notLoaded_shouldReturnFalse() {
+ assertThat(mLoader.isPreviewLoaded(mWidgetItem, SIZE_10_10)).isFalse();
+ }
+
+ @Test
+ public void isPreviewLoaded_otherSizeLoaded_shouldReturnFalse() {
+ loadPreviewIntoCache(mWidgetItem, SIZE_20_20, BITMAP);
+
+ assertThat(mLoader.isPreviewLoaded(mWidgetItem, SIZE_10_10)).isFalse();
+ }
+
+ @Test
+ public void isPreviewLoaded_otherItemLoaded_shouldReturnFalse() {
+ loadPreviewIntoCache(mWidgetItem2, SIZE_10_10, BITMAP);
+
+ assertThat(mLoader.isPreviewLoaded(mWidgetItem, SIZE_10_10)).isFalse();
+ }
+
+ @Test
+ public void isPreviewLoaded_loaded_shouldReturnTrue() {
+ loadPreviewIntoCache(mWidgetItem, SIZE_10_10, BITMAP);
+
+ assertThat(mLoader.isPreviewLoaded(mWidgetItem, SIZE_10_10)).isTrue();
+ }
+
+ @Test
+ public void clearPreviews_notInCache_shouldBeNoOp() {
+ mLoader.clearPreviews(Collections.singletonList(mWidgetItem));
+
+ assertThat(mLoader.isPreviewLoaded(mWidgetItem, SIZE_10_10)).isFalse();
+ }
+
+ @Test
+ public void clearPreviews_inCache_shouldRemovePreview() {
+ loadPreviewIntoCache(mWidgetItem, SIZE_10_10, BITMAP);
+
+ mLoader.clearPreviews(Collections.singletonList(mWidgetItem));
+
+ assertThat(mLoader.isPreviewLoaded(mWidgetItem, SIZE_10_10)).isFalse();
+ }
+
+ @Test
+ public void clearPreviews_inCache_multipleSizes_shouldRemoveAllSizes() {
+ loadPreviewIntoCache(mWidgetItem, SIZE_10_10, BITMAP);
+ loadPreviewIntoCache(mWidgetItem, SIZE_20_20, BITMAP);
+
+ mLoader.clearPreviews(Collections.singletonList(mWidgetItem));
+
+ assertThat(mLoader.isPreviewLoaded(mWidgetItem, SIZE_10_10)).isFalse();
+ assertThat(mLoader.isPreviewLoaded(mWidgetItem, SIZE_20_20)).isFalse();
+ }
+
+ @Test
+ public void clearPreviews_inCache_otherItems_shouldOnlyRemoveSpecifiedItems() {
+ loadPreviewIntoCache(mWidgetItem, SIZE_10_10, BITMAP);
+ loadPreviewIntoCache(mWidgetItem2, SIZE_10_10, BITMAP);
+
+ mLoader.clearPreviews(Collections.singletonList(mWidgetItem));
+
+ assertThat(mLoader.isPreviewLoaded(mWidgetItem, SIZE_10_10)).isFalse();
+ assertThat(mLoader.isPreviewLoaded(mWidgetItem2, SIZE_10_10)).isTrue();
+ }
+
+ @Test
+ public void clearPreviews_inCache_otherItems_shouldRemoveAllSpecifiedItems() {
+ loadPreviewIntoCache(mWidgetItem, SIZE_10_10, BITMAP);
+ loadPreviewIntoCache(mWidgetItem2, SIZE_10_10, BITMAP);
+
+ mLoader.clearPreviews(Arrays.asList(mWidgetItem, mWidgetItem2));
+
+ assertThat(mLoader.isPreviewLoaded(mWidgetItem, SIZE_10_10)).isFalse();
+ assertThat(mLoader.isPreviewLoaded(mWidgetItem2, SIZE_10_10)).isFalse();
+ }
+
+ @Test
+ public void clearPreviews_loading_shouldCancelLoad() {
+ mLoader.loadPreview(mTestActivity, mWidgetItem, SIZE_10_10, mPreviewLoadedCallback);
+
+ mLoader.clearPreviews(Collections.singletonList(mWidgetItem));
+
+ verify(mCancellationSignal).cancel();
+ }
+
+ @Test
+ public void clearAll_cacheEmpty_shouldBeNoOp() {
+ mLoader.clearAll();
+
+ assertThat(mLoader.isPreviewLoaded(mWidgetItem, SIZE_10_10)).isFalse();
+ }
+
+ @Test
+ public void clearAll_inCache_shouldRemovePreview() {
+ loadPreviewIntoCache(mWidgetItem, SIZE_10_10, BITMAP);
+
+ mLoader.clearAll();
+
+ assertThat(mLoader.isPreviewLoaded(mWidgetItem, SIZE_10_10)).isFalse();
+ }
+
+ @Test
+ public void clearAll_inCache_multipleSizes_shouldRemoveAllSizes() {
+ loadPreviewIntoCache(mWidgetItem, SIZE_10_10, BITMAP);
+ loadPreviewIntoCache(mWidgetItem, SIZE_20_20, BITMAP);
+
+ mLoader.clearAll();
+
+ assertThat(mLoader.isPreviewLoaded(mWidgetItem, SIZE_10_10)).isFalse();
+ assertThat(mLoader.isPreviewLoaded(mWidgetItem, SIZE_20_20)).isFalse();
+ }
+
+ @Test
+ public void clearAll_inCache_multipleItems_shouldRemoveAll() {
+ loadPreviewIntoCache(mWidgetItem, SIZE_10_10, BITMAP);
+ loadPreviewIntoCache(mWidgetItem, SIZE_20_20, BITMAP);
+ loadPreviewIntoCache(mWidgetItem2, SIZE_20_20, BITMAP);
+
+ mLoader.clearAll();
+
+ assertThat(mLoader.isPreviewLoaded(mWidgetItem, SIZE_10_10)).isFalse();
+ assertThat(mLoader.isPreviewLoaded(mWidgetItem, SIZE_20_20)).isFalse();
+ assertThat(mLoader.isPreviewLoaded(mWidgetItem2, SIZE_20_20)).isFalse();
+ }
+
+ @Test
+ public void clearAll_loading_shouldCancelLoad() {
+ mLoader.loadPreview(mTestActivity, mWidgetItem, SIZE_10_10, mPreviewLoadedCallback);
+
+ mLoader.clearAll();
+
+ verify(mCancellationSignal).cancel();
+ }
+
+ private void loadPreviewIntoCache(WidgetItem widgetItem, Size size, Bitmap bitmap) {
+ reset(mDelegate);
+ mLoader.loadPreview(mTestActivity, widgetItem, size, ignored -> {});
+ verify(mDelegate).loadPreview(any(), any(), any(), mCallbackCaptor.capture());
+ WidgetPreviewLoadedCallback loaderCallback = mCallbackCaptor.getValue();
+
+ loaderCallback.onPreviewLoaded(bitmap);
+ }
+}
diff --git a/tests/src/com/android/launcher3/widget/LauncherAppWidgetProviderInfoTest.java b/robolectric_tests/src/com/android/launcher3/widget/LauncherAppWidgetProviderInfoTest.java
index b534a41175..a6f892c048 100644
--- a/tests/src/com/android/launcher3/widget/LauncherAppWidgetProviderInfoTest.java
+++ b/robolectric_tests/src/com/android/launcher3/widget/LauncherAppWidgetProviderInfoTest.java
@@ -15,8 +15,6 @@
*/
package com.android.launcher3.widget;
-import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
-
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
@@ -27,9 +25,6 @@ import android.content.Context;
import android.graphics.Point;
import android.graphics.Rect;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
-
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.InvariantDeviceProfile;
@@ -37,16 +32,17 @@ import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
-@SmallTest
-@RunWith(AndroidJUnit4.class)
+@RunWith(RobolectricTestRunner.class)
public final class LauncherAppWidgetProviderInfoTest {
- private static final int SPACE_SIZE = 10;
private static final int CELL_SIZE = 50;
private static final int NUM_OF_COLS = 4;
private static final int NUM_OF_ROWS = 5;
@@ -55,7 +51,8 @@ public final class LauncherAppWidgetProviderInfoTest {
@Before
public void setUp() {
- mContext = getApplicationContext();
+ MockitoAnnotations.initMocks(this);
+ mContext = RuntimeEnvironment.application;
}
@Test
@@ -160,7 +157,7 @@ public final class LauncherAppWidgetProviderInfoTest {
AppWidgetHostView.getDefaultPaddingForWidget(mContext, null, padding);
int maxPadding = Math.max(Math.max(padding.left, padding.right),
Math.max(padding.top, padding.bottom));
- dp.cellLayoutBorderSpacePx.x = dp.cellLayoutBorderSpacePx.y = maxPadding + 1;
+ dp.cellLayoutBorderSpacingPx = maxPadding + 1;
Mockito.when(dp.shouldInsetWidgets()).thenReturn(true);
LauncherAppWidgetProviderInfo info = new LauncherAppWidgetProviderInfo();
@@ -183,7 +180,7 @@ public final class LauncherAppWidgetProviderInfoTest {
AppWidgetHostView.getDefaultPaddingForWidget(mContext, null, padding);
int maxPadding = Math.max(Math.max(padding.left, padding.right),
Math.max(padding.top, padding.bottom));
- dp.cellLayoutBorderSpacePx.x = dp.cellLayoutBorderSpacePx.y = maxPadding - 1;
+ dp.cellLayoutBorderSpacingPx = maxPadding - 1;
Mockito.when(dp.shouldInsetWidgets()).thenReturn(false);
LauncherAppWidgetProviderInfo info = new LauncherAppWidgetProviderInfo();
info.minWidth = CELL_SIZE * 3;
@@ -263,8 +260,6 @@ public final class LauncherAppWidgetProviderInfoTest {
return null;
}).when(profile).getCellSize(any(Point.class));
Mockito.when(profile.getCellSize()).thenReturn(new Point(CELL_SIZE, CELL_SIZE));
- profile.cellLayoutBorderSpacePx = new Point(SPACE_SIZE, SPACE_SIZE);
- Mockito.when(profile.shouldInsetWidgets()).thenReturn(true);
InvariantDeviceProfile idp = new InvariantDeviceProfile();
List<DeviceProfile> supportedProfiles = new ArrayList<>(idp.supportedProfiles);
diff --git a/tests/src/com/android/launcher3/widget/picker/WidgetsDiffReporterTest.java b/robolectric_tests/src/com/android/launcher3/widget/picker/WidgetsDiffReporterTest.java
index b480a4c002..b9f183c713 100644
--- a/tests/src/com/android/launcher3/widget/picker/WidgetsDiffReporterTest.java
+++ b/robolectric_tests/src/com/android/launcher3/widget/picker/WidgetsDiffReporterTest.java
@@ -15,16 +15,13 @@
*/
package com.android.launcher3.widget.picker;
-import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
-
-import static com.android.launcher3.util.WidgetUtils.createAppWidgetProviderInfo;
-
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.robolectric.Shadows.shadowOf;
import android.appwidget.AppWidgetProviderInfo;
import android.content.ComponentName;
@@ -33,8 +30,6 @@ import android.graphics.Bitmap;
import android.os.UserHandle;
import androidx.recyclerview.widget.RecyclerView;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.icons.BitmapInfo;
@@ -53,12 +48,15 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.shadows.ShadowPackageManager;
+import org.robolectric.util.ReflectionHelpers;
import java.util.ArrayList;
import java.util.List;
-@SmallTest
-@RunWith(AndroidJUnit4.class)
+@RunWith(RobolectricTestRunner.class)
public final class WidgetsDiffReporterTest {
private static final String TEST_PACKAGE_PREFIX = "com.android.test";
private static final WidgetListBaseRowEntryComparator COMPARATOR =
@@ -89,7 +87,7 @@ public final class WidgetsDiffReporterTest {
.getComponent().getPackageName())
.when(mIconCache).getTitleNoCache(any());
- mContext = getApplicationContext();
+ mContext = RuntimeEnvironment.application;
mWidgetsDiffReporter = new WidgetsDiffReporter(mIconCache, mAdapter);
mHeaderA = createWidgetsHeaderEntry(TEST_PACKAGE_PREFIX + "A",
/* appName= */ "A", /* numOfWidgets= */ 3);
@@ -288,17 +286,22 @@ public final class WidgetsDiffReporterTest {
private PackageItemInfo createPackageItemInfo(String packageName, String appName,
UserHandle userHandle) {
- PackageItemInfo pInfo = new PackageItemInfo(packageName, userHandle);
+ PackageItemInfo pInfo = new PackageItemInfo(packageName);
pInfo.title = appName;
+ pInfo.user = userHandle;
pInfo.bitmap = BitmapInfo.of(Bitmap.createBitmap(10, 10, Bitmap.Config.ALPHA_8), 0);
return pInfo;
}
private List<WidgetItem> generateWidgetItems(String packageName, int numOfWidgets) {
+ ShadowPackageManager packageManager = shadowOf(mContext.getPackageManager());
ArrayList<WidgetItem> widgetItems = new ArrayList<>();
for (int i = 0; i < numOfWidgets; i++) {
ComponentName cn = ComponentName.createRelative(packageName, ".SampleWidget" + i);
- AppWidgetProviderInfo widgetInfo = createAppWidgetProviderInfo(cn);
+ AppWidgetProviderInfo widgetInfo = new AppWidgetProviderInfo();
+ widgetInfo.provider = cn;
+ ReflectionHelpers.setField(widgetInfo, "providerInfo",
+ packageManager.addReceiverIfNotPresent(cn));
WidgetItem widgetItem = new WidgetItem(
LauncherAppWidgetProviderInfo.fromProviderInfo(mContext, widgetInfo),
diff --git a/tests/src/com/android/launcher3/widget/picker/WidgetsListAdapterTest.java b/robolectric_tests/src/com/android/launcher3/widget/picker/WidgetsListAdapterTest.java
index 4e0bddac0c..c730fc0d00 100644
--- a/tests/src/com/android/launcher3/widget/picker/WidgetsListAdapterTest.java
+++ b/robolectric_tests/src/com/android/launcher3/widget/picker/WidgetsListAdapterTest.java
@@ -15,13 +15,12 @@
*/
package com.android.launcher3.widget.picker;
-import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
-
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Matchers.eq;
import static org.mockito.Matchers.isNull;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.verify;
+import static org.robolectric.Shadows.shadowOf;
import android.appwidget.AppWidgetProviderInfo;
import android.content.ComponentName;
@@ -32,8 +31,6 @@ import android.os.UserHandle;
import android.view.LayoutInflater;
import androidx.recyclerview.widget.RecyclerView;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.icons.BitmapInfo;
@@ -41,9 +38,8 @@ import com.android.launcher3.icons.ComponentWithLabel;
import com.android.launcher3.icons.IconCache;
import com.android.launcher3.model.WidgetItem;
import com.android.launcher3.model.data.PackageItemInfo;
-import com.android.launcher3.util.ActivityContextWrapper;
import com.android.launcher3.util.PackageUserKey;
-import com.android.launcher3.util.WidgetUtils;
+import com.android.launcher3.widget.DatabaseWidgetPreviewLoader;
import com.android.launcher3.widget.LauncherAppWidgetProviderInfo;
import com.android.launcher3.widget.model.WidgetsListBaseEntry;
import com.android.launcher3.widget.model.WidgetsListContentEntry;
@@ -55,20 +51,20 @@ import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.shadows.ShadowPackageManager;
+import org.robolectric.util.ReflectionHelpers;
import java.util.ArrayList;
import java.util.List;
-/**
- * Unit tests for WidgetsListAdapter
- * Note that all indices matching are shifted by 1 to account for the empty space at the start.
- */
-@SmallTest
-@RunWith(AndroidJUnit4.class)
+@RunWith(RobolectricTestRunner.class)
public final class WidgetsListAdapterTest {
private static final String TEST_PACKAGE_PLACEHOLDER = "com.google.test";
@Mock private LayoutInflater mMockLayoutInflater;
+ @Mock private DatabaseWidgetPreviewLoader mMockWidgetCache;
@Mock private RecyclerView.AdapterDataObserver mListener;
@Mock private IconCache mIconCache;
@@ -80,13 +76,13 @@ public final class WidgetsListAdapterTest {
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
- mContext = new ActivityContextWrapper(getApplicationContext());
+ mContext = RuntimeEnvironment.application;
mTestProfile = new InvariantDeviceProfile();
mTestProfile.numRows = 5;
mTestProfile.numColumns = 5;
mUserHandle = Process.myUserHandle();
- mAdapter = new WidgetsListAdapter(mContext, mMockLayoutInflater,
- mIconCache, () -> 0, null, null);
+ mAdapter = new WidgetsListAdapter(mContext, mMockLayoutInflater, mMockWidgetCache,
+ mIconCache, null, null);
mAdapter.registerAdapterDataObserver(mListener);
doAnswer(invocation -> ((ComponentWithLabel) invocation.getArgument(0))
@@ -106,7 +102,7 @@ public final class WidgetsListAdapterTest {
mAdapter.setWidgets(generateSampleMap(1));
mAdapter.setWidgets(generateSampleMap(2));
- verify(mListener).onItemRangeInserted(eq(2), eq(1));
+ verify(mListener).onItemRangeInserted(eq(1), eq(1));
}
@Test
@@ -114,7 +110,7 @@ public final class WidgetsListAdapterTest {
mAdapter.setWidgets(generateSampleMap(2));
mAdapter.setWidgets(generateSampleMap(1));
- verify(mListener).onItemRangeRemoved(eq(2), eq(1));
+ verify(mListener).onItemRangeRemoved(eq(1), eq(1));
}
@Test
@@ -122,7 +118,7 @@ public final class WidgetsListAdapterTest {
mAdapter.setWidgets(generateSampleMap(1));
mAdapter.setWidgets(generateSampleMap(1));
- verify(mListener).onItemRangeChanged(eq(1), eq(1), isNull());
+ verify(mListener).onItemRangeChanged(eq(0), eq(1), isNull());
}
@Test
@@ -141,7 +137,7 @@ public final class WidgetsListAdapterTest {
// THEN the visible entries list becomes:
// [com.google.test0, com.google.test1, com.google.test1 content, com.google.test2]
// com.google.test.1 content is inserted into position 2.
- verify(mListener).onItemRangeInserted(eq(3), eq(1));
+ verify(mListener).onItemRangeInserted(eq(2), eq(1));
}
@Test
@@ -169,7 +165,7 @@ public final class WidgetsListAdapterTest {
mAdapter.setWidgets(allEntries);
// THEN the onItemRangeChanged is invoked for "com.google.test1 content" at index 2.
- verify(mListener).onItemRangeChanged(eq(3), eq(1), isNull());
+ verify(mListener).onItemRangeChanged(eq(2), eq(1), isNull());
}
@Test
@@ -200,38 +196,28 @@ public final class WidgetsListAdapterTest {
allAppsWithWidgets.get(6), allAppsWithWidgets.get(7));
mAdapter.setWidgets(newList);
- // Account for 1st items as empty space
// Computation logic | [Intermediate list during computation]
// THEN B <> C < 0, removed B from index 1 | [A, E]
- verify(mListener).onItemRangeRemoved(/* positionStart= */ 2, /* itemCount= */ 1);
+ verify(mListener).onItemRangeRemoved(/* positionStart= */ 1, /* itemCount= */ 1);
// THEN E <> C > 0, C inserted to index 1 | [A, C, E]
- verify(mListener).onItemRangeInserted(/* positionStart= */ 2, /* itemCount= */ 1);
+ verify(mListener).onItemRangeInserted(/* positionStart= */ 1, /* itemCount= */ 1);
// THEN E <> D > 0, D inserted to index 2 | [A, C, D, E]
- verify(mListener).onItemRangeInserted(/* positionStart= */ 3, /* itemCount= */ 1);
+ verify(mListener).onItemRangeInserted(/* positionStart= */ 2, /* itemCount= */ 1);
// THEN E <> null = -1, E deleted from index 3 | [A, C, D]
- verify(mListener).onItemRangeRemoved(/* positionStart= */ 4, /* itemCount= */ 1);
+ verify(mListener).onItemRangeRemoved(/* positionStart= */ 3, /* itemCount= */ 1);
}
@Test
public void setWidgetsOnSearch_expandedApp_shouldResetExpandedApp() {
// GIVEN a list of widgets entries:
- // [Empty item
- // com.google.test0,
- // com.google.test0 content,
- // com.google.test1,
- // com.google.test1 content,
- // com.google.test2,
- // com.google.test2 content]
- // The visible widgets entries:
- // [Empty item,
- // com.google.test0,
- // com.google.test1,
- // com.google.test2].
- ArrayList<WidgetsListBaseEntry> allEntries = generateSampleMap(3);
+ // [com.google.test0, com.google.test0 content,
+ // com.google.test1, com.google.test1 content,
+ // com.google.test2, com.google.test2 content]
+ // The visible widgets entries: [com.google.test0, com.google.test1, com.google.test2].
+ ArrayList<WidgetsListBaseEntry> allEntries = generateSampleMap(2);
mAdapter.setWidgetsOnSearch(allEntries);
// GIVEN com.google.test.1 header is expanded. The visible entries list becomes:
- // [Empty item, com.google.test0, com.google.test1, com.google.test1 content,
- // com.google.test2]
+ // [com.google.test0, com.google.test1, com.google.test1 content, com.google.test2]
mAdapter.onHeaderClicked(/* showWidgets= */ true,
new PackageUserKey(TEST_PACKAGE_PLACEHOLDER + 1, mUserHandle));
Mockito.reset(mListener);
@@ -240,9 +226,9 @@ public final class WidgetsListAdapterTest {
mAdapter.setWidgetsOnSearch(allEntries);
// THEN expanded app is reset and the visible entries list becomes:
- // [Empty item, com.google.test0, com.google.test1, com.google.test2]
- verify(mListener).onItemRangeChanged(eq(2), eq(1), isNull());
- verify(mListener).onItemRangeRemoved(/* positionStart= */ 3, /* itemCount= */ 1);
+ // [com.google.test0, com.google.test1, com.google.test2]
+ verify(mListener).onItemRangeChanged(eq(1), eq(1), isNull());
+ verify(mListener).onItemRangeRemoved(/* positionStart= */ 2, /* itemCount= */ 1);
}
/**
@@ -266,8 +252,9 @@ public final class WidgetsListAdapterTest {
List<WidgetItem> widgetItems = generateWidgetItems(packageName, /* numOfWidgets= */ 1);
- PackageItemInfo pInfo = new PackageItemInfo(packageName, widgetItems.get(0).user);
+ PackageItemInfo pInfo = new PackageItemInfo(packageName);
pInfo.title = pInfo.packageName;
+ pInfo.user = widgetItems.get(0).user;
pInfo.bitmap = BitmapInfo.of(Bitmap.createBitmap(10, 10, Bitmap.Config.ALPHA_8), 0);
result.add(new WidgetsListHeaderEntry(pInfo, /* titleSectionName= */ "", widgetItems));
@@ -278,10 +265,14 @@ public final class WidgetsListAdapterTest {
}
private List<WidgetItem> generateWidgetItems(String packageName, int numOfWidgets) {
+ ShadowPackageManager packageManager = shadowOf(mContext.getPackageManager());
ArrayList<WidgetItem> widgetItems = new ArrayList<>();
for (int i = 0; i < numOfWidgets; i++) {
ComponentName cn = ComponentName.createRelative(packageName, ".SampleWidget" + i);
- AppWidgetProviderInfo widgetInfo = WidgetUtils.createAppWidgetProviderInfo(cn);
+ AppWidgetProviderInfo widgetInfo = new AppWidgetProviderInfo();
+ widgetInfo.provider = cn;
+ ReflectionHelpers.setField(widgetInfo, "providerInfo",
+ packageManager.addReceiverIfNotPresent(cn));
widgetItems.add(new WidgetItem(
LauncherAppWidgetProviderInfo.fromProviderInfo(mContext, widgetInfo),
diff --git a/tests/src/com/android/launcher3/widget/picker/WidgetsListHeaderViewHolderBinderTest.java b/robolectric_tests/src/com/android/launcher3/widget/picker/WidgetsListHeaderViewHolderBinderTest.java
index 211318cf12..81b0c5f89c 100644
--- a/tests/src/com/android/launcher3/widget/picker/WidgetsListHeaderViewHolderBinderTest.java
+++ b/robolectric_tests/src/com/android/launcher3/widget/picker/WidgetsListHeaderViewHolderBinderTest.java
@@ -15,29 +15,23 @@
*/
package com.android.launcher3.widget.picker;
-import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
-
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.verify;
-
-import static java.util.Collections.EMPTY_LIST;
+import static org.robolectric.Shadows.shadowOf;
import android.appwidget.AppWidgetProviderInfo;
import android.content.ComponentName;
import android.content.Context;
import android.graphics.Bitmap;
-import android.os.UserHandle;
import android.view.LayoutInflater;
import android.widget.FrameLayout;
import android.widget.TextView;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
-
+import com.android.launcher3.DeviceProfile;
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.R;
import com.android.launcher3.icons.BitmapInfo;
@@ -45,23 +39,29 @@ import com.android.launcher3.icons.ComponentWithLabel;
import com.android.launcher3.icons.IconCache;
import com.android.launcher3.model.WidgetItem;
import com.android.launcher3.model.data.PackageItemInfo;
-import com.android.launcher3.util.ActivityContextWrapper;
+import com.android.launcher3.testing.TestActivity;
import com.android.launcher3.util.PackageUserKey;
-import com.android.launcher3.util.WidgetUtils;
+import com.android.launcher3.widget.DatabaseWidgetPreviewLoader;
import com.android.launcher3.widget.LauncherAppWidgetProviderInfo;
import com.android.launcher3.widget.model.WidgetsListHeaderEntry;
+import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import org.robolectric.Robolectric;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.android.controller.ActivityController;
+import org.robolectric.shadows.ShadowPackageManager;
+import org.robolectric.util.ReflectionHelpers;
import java.util.ArrayList;
import java.util.List;
-@SmallTest
-@RunWith(AndroidJUnit4.class)
+@RunWith(RobolectricTestRunner.class)
public final class WidgetsListHeaderViewHolderBinderTest {
private static final String TEST_PACKAGE = "com.google.test";
private static final String APP_NAME = "Test app";
@@ -69,41 +69,65 @@ public final class WidgetsListHeaderViewHolderBinderTest {
private Context mContext;
private WidgetsListHeaderViewHolderBinder mViewHolderBinder;
private InvariantDeviceProfile mTestProfile;
+ // Replace ActivityController with ActivityScenario, which is the recommended way for activity
+ // testing.
+ private ActivityController<TestActivity> mActivityController;
+ private TestActivity mTestActivity;
@Mock
private IconCache mIconCache;
@Mock
+ private DeviceProfile mDeviceProfile;
+ @Mock
+ private DatabaseWidgetPreviewLoader mWidgetPreviewLoader;
+ @Mock
private OnHeaderClickListener mOnHeaderClickListener;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
-
- mContext = new ActivityContextWrapper(getApplicationContext());
+ mContext = RuntimeEnvironment.application;
mTestProfile = new InvariantDeviceProfile();
mTestProfile.numRows = 5;
mTestProfile.numColumns = 5;
+ mActivityController = Robolectric.buildActivity(TestActivity.class);
+ mTestActivity = mActivityController.setup().get();
+ mTestActivity.setDeviceProfile(mDeviceProfile);
+
doAnswer(invocation -> {
ComponentWithLabel componentWithLabel = (ComponentWithLabel) invocation.getArgument(0);
return componentWithLabel.getComponent().getShortClassName();
}).when(mIconCache).getTitleNoCache(any());
+
+ WidgetsListAdapter widgetsListAdapter = new WidgetsListAdapter(mContext,
+ LayoutInflater.from(mTestActivity),
+ mWidgetPreviewLoader,
+ mIconCache,
+ /* iconClickListener= */ view -> {},
+ /* iconLongClickListener= */ view -> false);
mViewHolderBinder = new WidgetsListHeaderViewHolderBinder(
- LayoutInflater.from(mContext),
+ LayoutInflater.from(mTestActivity),
mOnHeaderClickListener,
- new WidgetsListDrawableFactory(mContext));
+ new WidgetsListDrawableFactory(mTestActivity),
+ widgetsListAdapter);
+ }
+
+ @After
+ public void tearDown() {
+ mActivityController.destroy();
}
@Test
public void bindViewHolder_appWith3Widgets_shouldShowTheCorrectAppNameAndSubtitle() {
WidgetsListHeaderHolder viewHolder = mViewHolderBinder.newViewHolder(
- new FrameLayout(mContext));
+ new FrameLayout(mTestActivity));
WidgetsListHeader widgetsListHeader = viewHolder.mWidgetsListHeader;
WidgetsListHeaderEntry entry = generateSampleAppHeader(
APP_NAME,
TEST_PACKAGE,
/* numOfWidgets= */ 3);
- mViewHolderBinder.bindViewHolder(viewHolder, entry, /* position= */ 0, EMPTY_LIST);
+ mViewHolderBinder.bindViewHolder(viewHolder, entry, /* position= */ 0);
TextView appTitle = widgetsListHeader.findViewById(R.id.app_title);
TextView appSubtitle = widgetsListHeader.findViewById(R.id.app_subtitle);
@@ -114,23 +138,23 @@ public final class WidgetsListHeaderViewHolderBinderTest {
@Test
public void bindViewHolder_shouldAttachOnHeaderClickListener() {
WidgetsListHeaderHolder viewHolder = mViewHolderBinder.newViewHolder(
- new FrameLayout(mContext));
+ new FrameLayout(mTestActivity));
WidgetsListHeader widgetsListHeader = viewHolder.mWidgetsListHeader;
WidgetsListHeaderEntry entry = generateSampleAppHeader(
APP_NAME,
TEST_PACKAGE,
/* numOfWidgets= */ 3);
- mViewHolderBinder.bindViewHolder(viewHolder, entry, /* position= */ 0, EMPTY_LIST);
+ mViewHolderBinder.bindViewHolder(viewHolder, entry, /* position= */ 0);
widgetsListHeader.callOnClick();
verify(mOnHeaderClickListener).onHeaderClicked(eq(true),
- eq(PackageUserKey.fromPackageItemInfo(entry.mPkgItem)));
+ eq(new PackageUserKey(entry.mPkgItem.packageName, entry.mPkgItem.user)));
}
private WidgetsListHeaderEntry generateSampleAppHeader(String appName, String packageName,
int numOfWidgets) {
- PackageItemInfo appInfo = new PackageItemInfo(packageName, UserHandle.CURRENT);
+ PackageItemInfo appInfo = new PackageItemInfo(packageName);
appInfo.title = appName;
appInfo.bitmap = BitmapInfo.of(Bitmap.createBitmap(10, 10, Bitmap.Config.ALPHA_8), 0);
@@ -140,10 +164,14 @@ public final class WidgetsListHeaderViewHolderBinderTest {
}
private List<WidgetItem> generateWidgetItems(String packageName, int numOfWidgets) {
+ ShadowPackageManager packageManager = shadowOf(mContext.getPackageManager());
ArrayList<WidgetItem> widgetItems = new ArrayList<>();
for (int i = 0; i < numOfWidgets; i++) {
ComponentName cn = ComponentName.createRelative(packageName, ".SampleWidget" + i);
- AppWidgetProviderInfo widgetInfo = WidgetUtils.createAppWidgetProviderInfo(cn);
+ AppWidgetProviderInfo widgetInfo = new AppWidgetProviderInfo();
+ widgetInfo.provider = cn;
+ ReflectionHelpers.setField(widgetInfo, "providerInfo",
+ packageManager.addReceiverIfNotPresent(cn));
widgetItems.add(new WidgetItem(
LauncherAppWidgetProviderInfo.fromProviderInfo(mContext, widgetInfo),
diff --git a/tests/src/com/android/launcher3/widget/picker/WidgetsListSearchHeaderViewHolderBinderTest.java b/robolectric_tests/src/com/android/launcher3/widget/picker/WidgetsListSearchHeaderViewHolderBinderTest.java
index 66c2f3638a..a0ba7c3307 100644
--- a/tests/src/com/android/launcher3/widget/picker/WidgetsListSearchHeaderViewHolderBinderTest.java
+++ b/robolectric_tests/src/com/android/launcher3/widget/picker/WidgetsListSearchHeaderViewHolderBinderTest.java
@@ -15,29 +15,23 @@
*/
package com.android.launcher3.widget.picker;
-import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
-
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.verify;
-
-import static java.util.Collections.EMPTY_LIST;
+import static org.robolectric.Shadows.shadowOf;
import android.appwidget.AppWidgetProviderInfo;
import android.content.ComponentName;
import android.content.Context;
import android.graphics.Bitmap;
-import android.os.UserHandle;
import android.view.LayoutInflater;
import android.widget.FrameLayout;
import android.widget.TextView;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
-
+import com.android.launcher3.DeviceProfile;
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.R;
import com.android.launcher3.icons.BitmapInfo;
@@ -45,23 +39,29 @@ import com.android.launcher3.icons.ComponentWithLabel;
import com.android.launcher3.icons.IconCache;
import com.android.launcher3.model.WidgetItem;
import com.android.launcher3.model.data.PackageItemInfo;
-import com.android.launcher3.util.ActivityContextWrapper;
+import com.android.launcher3.testing.TestActivity;
import com.android.launcher3.util.PackageUserKey;
-import com.android.launcher3.util.WidgetUtils;
+import com.android.launcher3.widget.DatabaseWidgetPreviewLoader;
import com.android.launcher3.widget.LauncherAppWidgetProviderInfo;
import com.android.launcher3.widget.model.WidgetsListSearchHeaderEntry;
+import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import org.robolectric.Robolectric;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.android.controller.ActivityController;
+import org.robolectric.shadows.ShadowPackageManager;
+import org.robolectric.util.ReflectionHelpers;
import java.util.ArrayList;
import java.util.List;
-@SmallTest
-@RunWith(AndroidJUnit4.class)
+@RunWith(RobolectricTestRunner.class)
public final class WidgetsListSearchHeaderViewHolderBinderTest {
private static final String TEST_PACKAGE = "com.google.test";
private static final String APP_NAME = "Test app";
@@ -69,40 +69,65 @@ public final class WidgetsListSearchHeaderViewHolderBinderTest {
private Context mContext;
private WidgetsListSearchHeaderViewHolderBinder mViewHolderBinder;
private InvariantDeviceProfile mTestProfile;
+ // Replace ActivityController with ActivityScenario, which is the recommended way for activity
+ // testing.
+ private ActivityController<TestActivity> mActivityController;
+ private TestActivity mTestActivity;
@Mock
private IconCache mIconCache;
@Mock
+ private DeviceProfile mDeviceProfile;
+ @Mock
+ private DatabaseWidgetPreviewLoader mWidgetPreviewLoader;
+ @Mock
private OnHeaderClickListener mOnHeaderClickListener;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
- mContext = new ActivityContextWrapper(getApplicationContext());
+ mContext = RuntimeEnvironment.application;
mTestProfile = new InvariantDeviceProfile();
mTestProfile.numRows = 5;
mTestProfile.numColumns = 5;
+ mActivityController = Robolectric.buildActivity(TestActivity.class);
+ mTestActivity = mActivityController.setup().get();
+ mTestActivity.setDeviceProfile(mDeviceProfile);
+
doAnswer(invocation -> {
ComponentWithLabel componentWithLabel = (ComponentWithLabel) invocation.getArgument(0);
return componentWithLabel.getComponent().getShortClassName();
}).when(mIconCache).getTitleNoCache(any());
+
+ WidgetsListAdapter widgetsListAdapter = new WidgetsListAdapter(mContext,
+ LayoutInflater.from(mTestActivity),
+ mWidgetPreviewLoader,
+ mIconCache,
+ /* iconClickListener= */ view -> {},
+ /* iconLongClickListener= */ view -> false);
mViewHolderBinder = new WidgetsListSearchHeaderViewHolderBinder(
- LayoutInflater.from(mContext),
+ LayoutInflater.from(mTestActivity),
mOnHeaderClickListener,
- new WidgetsListDrawableFactory(mContext));
+ new WidgetsListDrawableFactory(mTestActivity),
+ widgetsListAdapter);
+ }
+
+ @After
+ public void tearDown() {
+ mActivityController.destroy();
}
@Test
public void bindViewHolder_appWith3Widgets_shouldShowTheCorrectAppNameAndSubtitle() {
WidgetsListSearchHeaderHolder viewHolder = mViewHolderBinder.newViewHolder(
- new FrameLayout(mContext));
+ new FrameLayout(mTestActivity));
WidgetsListHeader widgetsListHeader = viewHolder.mWidgetsListHeader;
WidgetsListSearchHeaderEntry entry = generateSampleSearchHeader(
APP_NAME,
TEST_PACKAGE,
/* numOfWidgets= */ 3);
- mViewHolderBinder.bindViewHolder(viewHolder, entry, /* position= */ 0, EMPTY_LIST);
+ mViewHolderBinder.bindViewHolder(viewHolder, entry, /* position= */ 0);
TextView appTitle = widgetsListHeader.findViewById(R.id.app_title);
TextView appSubtitle = widgetsListHeader.findViewById(R.id.app_subtitle);
@@ -114,23 +139,23 @@ public final class WidgetsListSearchHeaderViewHolderBinderTest {
@Test
public void bindViewHolder_shouldAttachOnHeaderClickListener() {
WidgetsListSearchHeaderHolder viewHolder = mViewHolderBinder.newViewHolder(
- new FrameLayout(mContext));
+ new FrameLayout(mTestActivity));
WidgetsListHeader widgetsListHeader = viewHolder.mWidgetsListHeader;
WidgetsListSearchHeaderEntry entry = generateSampleSearchHeader(
APP_NAME,
TEST_PACKAGE,
/* numOfWidgets= */ 3);
- mViewHolderBinder.bindViewHolder(viewHolder, entry, /* position= */ 0, EMPTY_LIST);
+ mViewHolderBinder.bindViewHolder(viewHolder, entry, /* position= */ 0);
widgetsListHeader.callOnClick();
verify(mOnHeaderClickListener).onHeaderClicked(eq(true),
- eq(PackageUserKey.fromPackageItemInfo(entry.mPkgItem)));
+ eq(new PackageUserKey(entry.mPkgItem.packageName, entry.mPkgItem.user)));
}
private WidgetsListSearchHeaderEntry generateSampleSearchHeader(String appName,
String packageName, int numOfWidgets) {
- PackageItemInfo appInfo = new PackageItemInfo(packageName, UserHandle.CURRENT);
+ PackageItemInfo appInfo = new PackageItemInfo(packageName);
appInfo.title = appName;
appInfo.bitmap = BitmapInfo.of(Bitmap.createBitmap(10, 10, Bitmap.Config.ALPHA_8), 0);
@@ -140,10 +165,14 @@ public final class WidgetsListSearchHeaderViewHolderBinderTest {
}
private List<WidgetItem> generateWidgetItems(String packageName, int numOfWidgets) {
+ ShadowPackageManager packageManager = shadowOf(mContext.getPackageManager());
ArrayList<WidgetItem> widgetItems = new ArrayList<>();
for (int i = 0; i < numOfWidgets; i++) {
ComponentName cn = ComponentName.createRelative(packageName, ".SampleWidget" + i);
- AppWidgetProviderInfo widgetInfo = WidgetUtils.createAppWidgetProviderInfo(cn);
+ AppWidgetProviderInfo widgetInfo = new AppWidgetProviderInfo();
+ widgetInfo.provider = cn;
+ ReflectionHelpers.setField(widgetInfo, "providerInfo",
+ packageManager.addReceiverIfNotPresent(cn));
widgetItems.add(new WidgetItem(
LauncherAppWidgetProviderInfo.fromProviderInfo(mContext, widgetInfo),
diff --git a/tests/src/com/android/launcher3/widget/picker/WidgetsListTableViewHolderBinderTest.java b/robolectric_tests/src/com/android/launcher3/widget/picker/WidgetsListTableViewHolderBinderTest.java
index 7ec4d20bc8..8f9d132866 100644
--- a/tests/src/com/android/launcher3/widget/picker/WidgetsListTableViewHolderBinderTest.java
+++ b/robolectric_tests/src/com/android/launcher3/widget/picker/WidgetsListTableViewHolderBinderTest.java
@@ -15,20 +15,18 @@
*/
package com.android.launcher3.widget.picker;
-import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
+import static android.os.Looper.getMainLooper;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doAnswer;
-
-import static java.util.Collections.EMPTY_LIST;
+import static org.robolectric.Shadows.shadowOf;
import android.appwidget.AppWidgetProviderInfo;
import android.content.ComponentName;
import android.content.Context;
import android.graphics.Bitmap;
-import android.os.UserHandle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
@@ -37,9 +35,7 @@ import android.widget.FrameLayout;
import android.widget.TableRow;
import android.widget.TextView;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
-
+import com.android.launcher3.DeviceProfile;
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.R;
import com.android.launcher3.icons.BitmapInfo;
@@ -47,24 +43,30 @@ import com.android.launcher3.icons.ComponentWithLabel;
import com.android.launcher3.icons.IconCache;
import com.android.launcher3.model.WidgetItem;
import com.android.launcher3.model.data.PackageItemInfo;
-import com.android.launcher3.util.ActivityContextWrapper;
-import com.android.launcher3.util.Executors;
-import com.android.launcher3.util.WidgetUtils;
+import com.android.launcher3.testing.TestActivity;
+import com.android.launcher3.widget.CachingWidgetPreviewLoader;
+import com.android.launcher3.widget.DatabaseWidgetPreviewLoader;
import com.android.launcher3.widget.LauncherAppWidgetProviderInfo;
import com.android.launcher3.widget.WidgetCell;
import com.android.launcher3.widget.model.WidgetsListContentEntry;
+import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import org.robolectric.Robolectric;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.android.controller.ActivityController;
+import org.robolectric.shadows.ShadowPackageManager;
+import org.robolectric.util.ReflectionHelpers;
import java.util.ArrayList;
import java.util.List;
-@SmallTest
-@RunWith(AndroidJUnit4.class)
+@RunWith(RobolectricTestRunner.class)
public final class WidgetsListTableViewHolderBinderTest {
private static final String TEST_PACKAGE = "com.google.test";
private static final String APP_NAME = "Test app";
@@ -72,6 +74,10 @@ public final class WidgetsListTableViewHolderBinderTest {
private Context mContext;
private WidgetsListTableViewHolderBinder mViewHolderBinder;
private InvariantDeviceProfile mTestProfile;
+ // Replace ActivityController with ActivityScenario, which is the recommended way for activity
+ // testing.
+ private ActivityController<TestActivity> mActivityController;
+ private TestActivity mTestActivity;
@Mock
private OnLongClickListener mOnLongClickListener;
@@ -79,42 +85,63 @@ public final class WidgetsListTableViewHolderBinderTest {
private OnClickListener mOnIconClickListener;
@Mock
private IconCache mIconCache;
+ @Mock
+ private DatabaseWidgetPreviewLoader mWidgetPreviewLoader;
+ @Mock
+ private DeviceProfile mDeviceProfile;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
- mContext = new ActivityContextWrapper(getApplicationContext());
+ mContext = RuntimeEnvironment.application;
mTestProfile = new InvariantDeviceProfile();
mTestProfile.numRows = 5;
mTestProfile.numColumns = 5;
+ mActivityController = Robolectric.buildActivity(TestActivity.class);
+ mTestActivity = mActivityController.setup().get();
+ mTestActivity.setDeviceProfile(mDeviceProfile);
+
doAnswer(invocation -> {
ComponentWithLabel componentWithLabel = (ComponentWithLabel) invocation.getArgument(0);
return componentWithLabel.getComponent().getShortClassName();
}).when(mIconCache).getTitleNoCache(any());
+ WidgetsListAdapter widgetsListAdapter = new WidgetsListAdapter(mContext,
+ LayoutInflater.from(mTestActivity),
+ mWidgetPreviewLoader,
+ mIconCache,
+ /* iconClickListener= */ view -> {},
+ /* iconLongClickListener= */ view -> false);
mViewHolderBinder = new WidgetsListTableViewHolderBinder(
- LayoutInflater.from(mContext),
+ LayoutInflater.from(mTestActivity),
mOnIconClickListener,
mOnLongClickListener,
- new WidgetsListDrawableFactory(mContext));
+ new CachingWidgetPreviewLoader(mWidgetPreviewLoader),
+ new WidgetsListDrawableFactory(mTestActivity),
+ widgetsListAdapter);
+ }
+
+ @After
+ public void tearDown() {
+ mActivityController.destroy();
}
@Test
- public void bindViewHolder_appWith3Widgets_shouldHave3Widgets() throws Exception {
+ public void bindViewHolder_appWith3Widgets_shouldHave3Widgets() {
WidgetsRowViewHolder viewHolder = mViewHolderBinder.newViewHolder(
- new FrameLayout(mContext));
+ new FrameLayout(mTestActivity));
WidgetsListContentEntry entry = generateSampleAppWithWidgets(
APP_NAME,
TEST_PACKAGE,
/* numOfWidgets= */ 3);
- mViewHolderBinder.bindViewHolder(viewHolder, entry, /* position= */ 0, EMPTY_LIST);
- Executors.MAIN_EXECUTOR.submit(() -> { }).get();
+ mViewHolderBinder.bindViewHolder(viewHolder, entry, /* position= */ 0);
+ shadowOf(getMainLooper()).idle();
// THEN the table container has one row, which contains 3 widgets.
// View: .SampleWidget0 | .SampleWidget1 | .SampleWidget2
- assertThat(viewHolder.tableContainer.getChildCount()).isEqualTo(1);
- TableRow row = (TableRow) viewHolder.tableContainer.getChildAt(0);
+ assertThat(viewHolder.mTableContainer.getChildCount()).isEqualTo(1);
+ TableRow row = (TableRow) viewHolder.mTableContainer.getChildAt(0);
assertThat(row.getChildCount()).isEqualTo(3);
// Widget 0 label is .SampleWidget0.
assertWidgetCellWithLabel(row.getChildAt(0), ".SampleWidget0");
@@ -126,21 +153,24 @@ public final class WidgetsListTableViewHolderBinderTest {
private WidgetsListContentEntry generateSampleAppWithWidgets(String appName, String packageName,
int numOfWidgets) {
- PackageItemInfo appInfo = new PackageItemInfo(packageName, UserHandle.CURRENT);
+ PackageItemInfo appInfo = new PackageItemInfo(packageName);
appInfo.title = appName;
appInfo.bitmap = BitmapInfo.of(Bitmap.createBitmap(10, 10, Bitmap.Config.ALPHA_8), 0);
return new WidgetsListContentEntry(appInfo,
/* titleSectionName= */ "",
- generateWidgetItems(packageName, numOfWidgets),
- Integer.MAX_VALUE);
+ generateWidgetItems(packageName, numOfWidgets));
}
private List<WidgetItem> generateWidgetItems(String packageName, int numOfWidgets) {
+ ShadowPackageManager packageManager = shadowOf(mContext.getPackageManager());
ArrayList<WidgetItem> widgetItems = new ArrayList<>();
for (int i = 0; i < numOfWidgets; i++) {
ComponentName cn = ComponentName.createRelative(packageName, ".SampleWidget" + i);
- AppWidgetProviderInfo widgetInfo = WidgetUtils.createAppWidgetProviderInfo(cn);
+ AppWidgetProviderInfo widgetInfo = new AppWidgetProviderInfo();
+ widgetInfo.provider = cn;
+ ReflectionHelpers.setField(widgetInfo, "providerInfo",
+ packageManager.addReceiverIfNotPresent(cn));
widgetItems.add(new WidgetItem(
LauncherAppWidgetProviderInfo.fromProviderInfo(mContext, widgetInfo),
diff --git a/tests/src/com/android/launcher3/widget/picker/model/WidgetsListContentEntryTest.java b/robolectric_tests/src/com/android/launcher3/widget/picker/model/WidgetsListContentEntryTest.java
index d8f1f14de6..106cac0fdf 100644
--- a/tests/src/com/android/launcher3/widget/picker/model/WidgetsListContentEntryTest.java
+++ b/robolectric_tests/src/com/android/launcher3/widget/picker/model/WidgetsListContentEntryTest.java
@@ -15,21 +15,15 @@
*/
package com.android.launcher3.widget.picker.model;
-import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
-
-import static com.android.launcher3.util.WidgetUtils.createAppWidgetProviderInfo;
-
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doAnswer;
+import static org.robolectric.Shadows.shadowOf;
import android.appwidget.AppWidgetProviderInfo;
import android.content.ComponentName;
-import android.os.UserHandle;
-
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
+import android.content.Context;
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.icons.ComponentWithLabel;
@@ -44,20 +38,21 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.shadows.ShadowPackageManager;
+import org.robolectric.util.ReflectionHelpers;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-@SmallTest
-@RunWith(AndroidJUnit4.class)
+@RunWith(RobolectricTestRunner.class)
public final class WidgetsListContentEntryTest {
private static final String PACKAGE_NAME = "com.android.test";
private static final String PACKAGE_NAME_2 = "com.android.test2";
- private final PackageItemInfo mPackageItemInfo1 = new PackageItemInfo(PACKAGE_NAME,
- UserHandle.CURRENT);
- private final PackageItemInfo mPackageItemInfo2 = new PackageItemInfo(PACKAGE_NAME_2,
- UserHandle.CURRENT);
+ private final PackageItemInfo mPackageItemInfo1 = new PackageItemInfo(PACKAGE_NAME);
+ private final PackageItemInfo mPackageItemInfo2 = new PackageItemInfo(PACKAGE_NAME_2);
private final ComponentName mWidget1 = ComponentName.createRelative(PACKAGE_NAME, ".mWidget1");
private final ComponentName mWidget2 = ComponentName.createRelative(PACKAGE_NAME, ".mWidget2");
private final ComponentName mWidget3 = ComponentName.createRelative(PACKAGE_NAME, ".mWidget3");
@@ -65,6 +60,7 @@ public final class WidgetsListContentEntryTest {
@Mock private IconCache mIconCache;
+ private Context mContext;
private InvariantDeviceProfile mTestProfile;
@Before
@@ -75,6 +71,7 @@ public final class WidgetsListContentEntryTest {
mWidgetsToLabels.put(mWidget2, "Dog");
mWidgetsToLabels.put(mWidget3, "Bird");
+ mContext = RuntimeEnvironment.application;
mTestProfile = new InvariantDeviceProfile();
mTestProfile.numRows = 5;
mTestProfile.numColumns = 5;
@@ -245,12 +242,17 @@ public final class WidgetsListContentEntryTest {
assertThat(widgetsListRowEntry1.equals(widgetsListRowEntry2)).isTrue();
}
+
private WidgetItem createWidgetItem(ComponentName componentName, int spanX, int spanY) {
String label = mWidgetsToLabels.get(componentName);
- AppWidgetProviderInfo widgetInfo = createAppWidgetProviderInfo(componentName);
+ ShadowPackageManager packageManager = shadowOf(mContext.getPackageManager());
+ AppWidgetProviderInfo widgetInfo = new AppWidgetProviderInfo();
+ widgetInfo.provider = componentName;
+ ReflectionHelpers.setField(widgetInfo, "providerInfo",
+ packageManager.addReceiverIfNotPresent(componentName));
LauncherAppWidgetProviderInfo launcherAppWidgetProviderInfo =
- LauncherAppWidgetProviderInfo.fromProviderInfo(getApplicationContext(), widgetInfo);
+ LauncherAppWidgetProviderInfo.fromProviderInfo(mContext, widgetInfo);
launcherAppWidgetProviderInfo.spanX = spanX;
launcherAppWidgetProviderInfo.spanY = spanY;
launcherAppWidgetProviderInfo.label = label;
diff --git a/tests/src/com/android/launcher3/widget/picker/search/SimpleWidgetsSearchAlgorithmTest.java b/robolectric_tests/src/com/android/launcher3/widget/picker/search/SimpleWidgetsSearchAlgorithmTest.java
index d812ab012e..36b6f01dc0 100644
--- a/tests/src/com/android/launcher3/widget/picker/search/SimpleWidgetsSearchAlgorithmTest.java
+++ b/robolectric_tests/src/com/android/launcher3/widget/picker/search/SimpleWidgetsSearchAlgorithmTest.java
@@ -16,10 +16,7 @@
package com.android.launcher3.widget.picker.search;
-import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
-
-import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
-import static com.android.launcher3.util.WidgetUtils.createAppWidgetProviderInfo;
+import static android.os.Looper.getMainLooper;
import static org.junit.Assert.assertEquals;
import static org.mockito.ArgumentMatchers.any;
@@ -28,6 +25,7 @@ import static org.mockito.ArgumentMatchers.matches;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.verify;
+import static org.robolectric.Shadows.shadowOf;
import android.appwidget.AppWidgetProviderInfo;
import android.content.ComponentName;
@@ -35,9 +33,6 @@ import android.content.Context;
import android.graphics.Bitmap;
import android.os.UserHandle;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
-
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.icons.BitmapInfo;
import com.android.launcher3.icons.ComponentWithLabel;
@@ -57,13 +52,16 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.shadows.ShadowPackageManager;
+import org.robolectric.util.ReflectionHelpers;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
-@SmallTest
-@RunWith(AndroidJUnit4.class)
+@RunWith(RobolectricTestRunner.class)
public class SimpleWidgetsSearchAlgorithmTest {
@Mock private IconCache mIconCache;
@@ -84,7 +82,7 @@ public class SimpleWidgetsSearchAlgorithmTest {
private SearchCallback<WidgetsListBaseEntry> mSearchCallback;
@Before
- public void setUp() throws Exception {
+ public void setUp() {
MockitoAnnotations.initMocks(this);
doAnswer(invocation -> {
ComponentWithLabel componentWithLabel = (ComponentWithLabel) invocation.getArgument(0);
@@ -93,7 +91,7 @@ public class SimpleWidgetsSearchAlgorithmTest {
mTestProfile = new InvariantDeviceProfile();
mTestProfile.numRows = 5;
mTestProfile.numColumns = 5;
- mContext = getApplicationContext();
+ mContext = RuntimeEnvironment.application;
mCalendarHeaderEntry =
createWidgetsHeaderEntry("com.example.android.Calendar", "Calendar", 2);
@@ -104,8 +102,8 @@ public class SimpleWidgetsSearchAlgorithmTest {
mClockHeaderEntry = createWidgetsHeaderEntry("com.example.android.Clock", "Clock", 3);
mClockContentEntry = createWidgetsContentEntry("com.example.android.Clock", "Clock", 3);
- mSimpleWidgetsSearchAlgorithm = MAIN_EXECUTOR.submit(
- () -> new SimpleWidgetsSearchAlgorithm(mDataProvider)).get();
+
+ mSimpleWidgetsSearchAlgorithm = new SimpleWidgetsSearchAlgorithm(mDataProvider);
doReturn(Collections.EMPTY_LIST).when(mDataProvider).getAllWidgets();
}
@@ -158,13 +156,13 @@ public class SimpleWidgetsSearchAlgorithmTest {
}
@Test
- public void doSearch_shouldInformCallback() throws Exception {
+ public void doSearch_shouldInformCallback() {
doReturn(List.of(mCalendarHeaderEntry, mCalendarContentEntry, mCameraHeaderEntry,
mCameraContentEntry, mClockHeaderEntry, mClockContentEntry))
.when(mDataProvider)
.getAllWidgets();
mSimpleWidgetsSearchAlgorithm.doSearch("Ca", mSearchCallback);
- MAIN_EXECUTOR.submit(() -> { }).get();
+ shadowOf(getMainLooper()).idle();
verify(mSearchCallback).onSearchResult(
matches("Ca"), argThat(a -> a != null && !a.isEmpty()));
}
@@ -189,17 +187,22 @@ public class SimpleWidgetsSearchAlgorithmTest {
private PackageItemInfo createPackageItemInfo(String packageName, String appName,
UserHandle userHandle) {
- PackageItemInfo pInfo = new PackageItemInfo(packageName, userHandle);
+ PackageItemInfo pInfo = new PackageItemInfo(packageName);
pInfo.title = appName;
+ pInfo.user = userHandle;
pInfo.bitmap = BitmapInfo.of(Bitmap.createBitmap(10, 10, Bitmap.Config.ALPHA_8), 0);
return pInfo;
}
private List<WidgetItem> generateWidgetItems(String packageName, int numOfWidgets) {
+ ShadowPackageManager packageManager = shadowOf(mContext.getPackageManager());
ArrayList<WidgetItem> widgetItems = new ArrayList<>();
for (int i = 0; i < numOfWidgets; i++) {
ComponentName cn = ComponentName.createRelative(packageName, ".SampleWidget" + i);
- AppWidgetProviderInfo widgetInfo = createAppWidgetProviderInfo(cn);
+ AppWidgetProviderInfo widgetInfo = new AppWidgetProviderInfo();
+ widgetInfo.provider = cn;
+ ReflectionHelpers.setField(widgetInfo, "providerInfo",
+ packageManager.addReceiverIfNotPresent(cn));
WidgetItem widgetItem = new WidgetItem(
LauncherAppWidgetProviderInfo.fromProviderInfo(mContext, widgetInfo),
diff --git a/tests/src/com/android/launcher3/widget/picker/search/WidgetsSearchBarControllerTest.java b/robolectric_tests/src/com/android/launcher3/widget/picker/search/WidgetsSearchBarControllerTest.java
index 583d37fe0d..7ac879aa44 100644
--- a/tests/src/com/android/launcher3/widget/picker/search/WidgetsSearchBarControllerTest.java
+++ b/robolectric_tests/src/com/android/launcher3/widget/picker/search/WidgetsSearchBarControllerTest.java
@@ -16,38 +16,39 @@
package com.android.launcher3.widget.picker.search;
-import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
-
import static org.junit.Assert.assertEquals;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
-import android.content.Context;
import android.view.View;
import android.widget.ImageButton;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
-
import com.android.launcher3.ExtendedEditText;
import com.android.launcher3.search.SearchAlgorithm;
+import com.android.launcher3.testing.TestActivity;
import com.android.launcher3.widget.model.WidgetsListBaseEntry;
+import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import org.robolectric.Robolectric;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.android.controller.ActivityController;
import java.util.ArrayList;
-@SmallTest
-@RunWith(AndroidJUnit4.class)
+@RunWith(RobolectricTestRunner.class)
public class WidgetsSearchBarControllerTest {
private WidgetsSearchBarController mController;
+ // TODO: Replace ActivityController with ActivityScenario, which is the recommended way for
+ // activity testing.
+ private ActivityController<TestActivity> mActivityController;
private ExtendedEditText mEditText;
private ImageButton mCancelButton;
@Mock
@@ -58,14 +59,20 @@ public class WidgetsSearchBarControllerTest {
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
- Context context = getApplicationContext();
+ mActivityController = Robolectric.buildActivity(TestActivity.class);
+ TestActivity testActivity = mActivityController.setup().get();
- mEditText = new ExtendedEditText(context);
- mCancelButton = new ImageButton(context);
+ mEditText = new ExtendedEditText(testActivity);
+ mCancelButton = new ImageButton(testActivity);
mController = new WidgetsSearchBarController(
mSearchAlgorithm, mEditText, mCancelButton, mSearchModeListener);
}
+ @After
+ public void tearDown() {
+ mActivityController.destroy();
+ }
+
@Test
public void onSearchResult_shouldInformSearchModeListener() {
ArrayList<WidgetsListBaseEntry> entries = new ArrayList<>();
diff --git a/tests/src/com/android/launcher3/widget/picker/util/WidgetsTableUtilsTest.java b/robolectric_tests/src/com/android/launcher3/widget/picker/util/WidgetsTableUtilsTest.java
index 715dcca588..56d7d68731 100644
--- a/tests/src/com/android/launcher3/widget/picker/util/WidgetsTableUtilsTest.java
+++ b/robolectric_tests/src/com/android/launcher3/widget/picker/util/WidgetsTableUtilsTest.java
@@ -15,14 +15,11 @@
*/
package com.android.launcher3.widget.picker.util;
-import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
-
-import static com.android.launcher3.util.WidgetUtils.createAppWidgetProviderInfo;
-
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doAnswer;
+import static org.robolectric.Shadows.shadowOf;
import android.appwidget.AppWidgetProviderInfo;
import android.content.ComponentName;
@@ -32,9 +29,6 @@ import android.graphics.Point;
import android.graphics.drawable.Drawable;
import android.os.UserHandle;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
-
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.icons.ComponentWithLabel;
import com.android.launcher3.icons.IconCache;
@@ -48,12 +42,15 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.shadows.ShadowPackageManager;
+import org.robolectric.util.ReflectionHelpers;
import java.util.ArrayList;
import java.util.List;
-@SmallTest
-@RunWith(AndroidJUnit4.class)
+@RunWith(RobolectricTestRunner.class)
public final class WidgetsTableUtilsTest {
private static final String TEST_PACKAGE = "com.google.test";
@@ -76,7 +73,7 @@ public final class WidgetsTableUtilsTest {
public void setUp() {
MockitoAnnotations.initMocks(this);
- mContext = getApplicationContext();
+ mContext = RuntimeEnvironment.application;
mTestProfile = new InvariantDeviceProfile();
mTestProfile.numRows = 5;
@@ -92,13 +89,12 @@ public final class WidgetsTableUtilsTest {
@Test
- public void groupWidgetItemsIntoTableWithReordering_widgetsOnly_maxSpansPerRow5_shouldGroupWidgetsInTable() {
+ public void groupWidgetItemsIntoTable_widgetsOnly_maxSpansPerRow5_shouldGroupWidgetsInTable() {
List<WidgetItem> widgetItems = List.of(mWidget4x4, mWidget2x3, mWidget1x1, mWidget2x4,
mWidget2x2);
- List<ArrayList<WidgetItem>> widgetItemInTable =
- WidgetsTableUtils.groupWidgetItemsIntoTableWithReordering(
- widgetItems, /* maxSpansPerRow= */ 5);
+ List<ArrayList<WidgetItem>> widgetItemInTable = WidgetsTableUtils.groupWidgetItemsIntoTable(
+ widgetItems, /* maxSpansPerRow= */ 5);
// Row 0: 1x1, 2x2
// Row 1: 2x3, 2x4
@@ -110,13 +106,12 @@ public final class WidgetsTableUtilsTest {
}
@Test
- public void groupWidgetItemsIntoTableWithReordering_widgetsOnly_maxSpansPerRow4_shouldGroupWidgetsInTable() {
+ public void groupWidgetItemsIntoTable_widgetsOnly_maxSpansPerRow4_shouldGroupWidgetsInTable() {
List<WidgetItem> widgetItems = List.of(mWidget4x4, mWidget2x3, mWidget1x1, mWidget2x4,
mWidget2x2);
- List<ArrayList<WidgetItem>> widgetItemInTable =
- WidgetsTableUtils.groupWidgetItemsIntoTableWithReordering(
- widgetItems, /* maxSpansPerRow= */ 4);
+ List<ArrayList<WidgetItem>> widgetItemInTable = WidgetsTableUtils.groupWidgetItemsIntoTable(
+ widgetItems, /* maxSpansPerRow= */ 4);
// Row 0: 1x1, 2x2
// Row 1: 2x3,
@@ -130,13 +125,12 @@ public final class WidgetsTableUtilsTest {
}
@Test
- public void groupWidgetItemsIntoTableWithReordering_mixItems_maxSpansPerRow4_shouldGroupWidgetsInTable() {
+ public void groupWidgetItemsIntoTable_mixItems_maxSpansPerRow4_shouldGroupWidgetsInTable() {
List<WidgetItem> widgetItems = List.of(mWidget4x4, mShortcut3, mWidget2x3, mShortcut1,
mWidget1x1, mShortcut2, mWidget2x4, mWidget2x2);
- List<ArrayList<WidgetItem>> widgetItemInTable =
- WidgetsTableUtils.groupWidgetItemsIntoTableWithReordering(
- widgetItems, /* maxSpansPerRow= */ 4);
+ List<ArrayList<WidgetItem>> widgetItemInTable = WidgetsTableUtils.groupWidgetItemsIntoTable(
+ widgetItems, /* maxSpansPerRow= */ 4);
// Row 0: 1x1, 2x2
// Row 1: 2x3,
@@ -151,24 +145,6 @@ public final class WidgetsTableUtilsTest {
assertThat(widgetItemInTable.get(4)).containsExactly(mShortcut3, mShortcut2, mShortcut1);
}
- @Test
- public void groupWidgetItemsIntoTableWithoutReordering_shouldMaintainTheOrder() {
- List<WidgetItem> widgetItems =
- List.of(mWidget4x4, mWidget2x3, mWidget1x1, mWidget2x4, mWidget2x2);
-
- List<ArrayList<WidgetItem>> widgetItemInTable =
- WidgetsTableUtils.groupWidgetItemsIntoTableWithoutReordering(
- widgetItems, /* maxSpansPerRow= */ 5);
-
- // Row 0: 4x4
- // Row 1: 2x3, 1x1
- // Row 2: 2x4, 2x2
- assertThat(widgetItemInTable).hasSize(3);
- assertThat(widgetItemInTable.get(0)).containsExactly(mWidget4x4);
- assertThat(widgetItemInTable.get(1)).containsExactly(mWidget2x3, mWidget1x1);
- assertThat(widgetItemInTable.get(2)).containsExactly(mWidget2x4, mWidget2x2);
- }
-
private void initTestWidgets() {
List<Point> widgetSizes = List.of(new Point(1, 1), new Point(2, 2), new Point(2, 3),
new Point(2, 4), new Point(4, 4));
@@ -176,14 +152,16 @@ public final class WidgetsTableUtilsTest {
ArrayList<WidgetItem> widgetItems = new ArrayList<>();
widgetSizes.stream().forEach(
widgetSize -> {
- AppWidgetProviderInfo info = createAppWidgetProviderInfo(
- ComponentName.createRelative(
- TEST_PACKAGE,
- ".WidgetProvider_" + widgetSize.x + "x" + widgetSize.y));
+ ShadowPackageManager packageManager = shadowOf(mContext.getPackageManager());
+ AppWidgetProviderInfo info = new AppWidgetProviderInfo();
+ info.provider = ComponentName.createRelative(TEST_PACKAGE,
+ ".WidgetProvider_" + widgetSize.x + "x" + widgetSize.y);
LauncherAppWidgetProviderInfo widgetInfo =
LauncherAppWidgetProviderInfo.fromProviderInfo(mContext, info);
widgetInfo.spanX = widgetSize.x;
widgetInfo.spanY = widgetSize.y;
+ ReflectionHelpers.setField(widgetInfo, "providerInfo",
+ packageManager.addReceiverIfNotPresent(widgetInfo.provider));
widgetItems.add(new WidgetItem(widgetInfo, mTestProfile, mIconCache));
}
);
diff --git a/robolectric_tests/unstaged/SettingsCacheTest.java b/robolectric_tests/unstaged/SettingsCacheTest.java
new file mode 100644
index 0000000000..fbf4c63e65
--- /dev/null
+++ b/robolectric_tests/unstaged/SettingsCacheTest.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2021 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.launcher3.util;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import android.content.Context;
+import android.net.Uri;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+
+import java.util.Collections;
+
+@RunWith(RobolectricTestRunner.class)
+public class SettingsCacheTest {
+
+ public static final Uri KEY_SYSTEM_URI_TEST1 = Uri.parse("content://settings/system/test1");
+ public static final Uri KEY_SYSTEM_URI_TEST2 = Uri.parse("content://settings/system/test2");;
+
+ private SettingsCache.OnChangeListener mChangeListener;
+ private SettingsCache mSettingsCache;
+
+ @Before
+ public void setup() {
+ mChangeListener = mock(SettingsCache.OnChangeListener.class);
+ Context targetContext = RuntimeEnvironment.application;
+ mSettingsCache = SettingsCache.INSTANCE.get(targetContext);
+ mSettingsCache.register(KEY_SYSTEM_URI_TEST1, mChangeListener);
+ }
+
+ @Test
+ public void listenerCalledOnChange() {
+ mSettingsCache.onChange(true, KEY_SYSTEM_URI_TEST1);
+ verify(mChangeListener, times(1)).onSettingsChanged(true);
+ }
+
+ @Test
+ public void getValueRespectsDefaultValue() {
+ // Case of key not found
+ boolean val = mSettingsCache.getValue(KEY_SYSTEM_URI_TEST1, 0);
+ assertFalse(val);
+ }
+
+ @Test
+ public void getValueHitsCache() {
+ mSettingsCache.setKeyCache(Collections.singletonMap(KEY_SYSTEM_URI_TEST1, true));
+ boolean val = mSettingsCache.getValue(KEY_SYSTEM_URI_TEST1, 0);
+ assertTrue(val);
+ }
+
+ @Test
+ public void getValueUpdatedCache() {
+ // First ensure there's nothing in cache
+ boolean val = mSettingsCache.getValue(KEY_SYSTEM_URI_TEST1, 0);
+ assertFalse(val);
+
+ mSettingsCache.setKeyCache(Collections.singletonMap(KEY_SYSTEM_URI_TEST1, true));
+ val = mSettingsCache.getValue(KEY_SYSTEM_URI_TEST1, 0);
+ assertTrue(val);
+ }
+
+ @Test
+ public void multipleListenersSingleKey() {
+ SettingsCache.OnChangeListener secondListener = mock(SettingsCache.OnChangeListener.class);
+ mSettingsCache.register(KEY_SYSTEM_URI_TEST1, secondListener);
+
+ mSettingsCache.onChange(true, KEY_SYSTEM_URI_TEST1);
+ verify(mChangeListener, times(1)).onSettingsChanged(true);
+ verify(secondListener, times(1)).onSettingsChanged(true);
+ }
+
+ @Test
+ public void singleListenerMultipleKeys() {
+ SettingsCache.OnChangeListener secondListener = mock(SettingsCache.OnChangeListener.class);
+ mSettingsCache.register(KEY_SYSTEM_URI_TEST2, secondListener);
+
+ mSettingsCache.onChange(true, KEY_SYSTEM_URI_TEST1);
+ mSettingsCache.onChange(true, KEY_SYSTEM_URI_TEST2);
+ verify(mChangeListener, times(1)).onSettingsChanged(true);
+ verify(secondListener, times(1)).onSettingsChanged(true);
+ }
+
+ @Test
+ public void sameListenerMultipleKeys() {
+ SettingsCache.OnChangeListener secondListener = mock(SettingsCache.OnChangeListener.class);
+ mSettingsCache.register(KEY_SYSTEM_URI_TEST2, mChangeListener);
+
+ mSettingsCache.onChange(true, KEY_SYSTEM_URI_TEST1);
+ mSettingsCache.onChange(true, KEY_SYSTEM_URI_TEST2);
+ verify(mChangeListener, times(2)).onSettingsChanged(true);
+ verify(secondListener, times(0)).onSettingsChanged(true);
+ }
+}
diff --git a/src/com/android/launcher3/AbstractFloatingView.java b/src/com/android/launcher3/AbstractFloatingView.java
index 21dbc5f7e0..4979b40af5 100644
--- a/src/com/android/launcher3/AbstractFloatingView.java
+++ b/src/com/android/launcher3/AbstractFloatingView.java
@@ -64,10 +64,7 @@ public abstract class AbstractFloatingView extends LinearLayout implements Touch
TYPE_OPTIONS_POPUP,
TYPE_ICON_SURFACE,
TYPE_PIN_WIDGET_FROM_EXTERNAL_POPUP,
- TYPE_WIDGETS_EDUCATION_DIALOG,
- TYPE_TASKBAR_EDUCATION_DIALOG,
- TYPE_TASKBAR_ALL_APPS,
- TYPE_OPTIONS_POPUP_DIALOG
+ TYPE_WIDGETS_EDUCATION_DIALOG
})
@Retention(RetentionPolicy.SOURCE)
public @interface FloatingViewType {}
@@ -87,27 +84,21 @@ public abstract class AbstractFloatingView extends LinearLayout implements Touch
public static final int TYPE_TASK_MENU = 1 << 11;
public static final int TYPE_OPTIONS_POPUP = 1 << 12;
public static final int TYPE_ICON_SURFACE = 1 << 13;
- public static final int TYPE_OPTIONS_POPUP_DIALOG = 1 << 18;
public static final int TYPE_PIN_WIDGET_FROM_EXTERNAL_POPUP = 1 << 14;
public static final int TYPE_WIDGETS_EDUCATION_DIALOG = 1 << 15;
- public static final int TYPE_TASKBAR_EDUCATION_DIALOG = 1 << 16;
- public static final int TYPE_TASKBAR_ALL_APPS = 1 << 17;
- public static final int TYPE_ADD_TO_HOME_CONFIRMATION = 1 << 18;
public static final int TYPE_ALL = TYPE_FOLDER | TYPE_ACTION_POPUP
| TYPE_WIDGETS_BOTTOM_SHEET | TYPE_WIDGET_RESIZE_FRAME | TYPE_WIDGETS_FULL_SHEET
| TYPE_ON_BOARD_POPUP | TYPE_DISCOVERY_BOUNCE | TYPE_TASK_MENU
| TYPE_OPTIONS_POPUP | TYPE_SNACKBAR | TYPE_LISTENER | TYPE_ALL_APPS_EDU
| TYPE_ICON_SURFACE | TYPE_DRAG_DROP_POPUP | TYPE_PIN_WIDGET_FROM_EXTERNAL_POPUP
- | TYPE_WIDGETS_EDUCATION_DIALOG | TYPE_TASKBAR_EDUCATION_DIALOG | TYPE_TASKBAR_ALL_APPS
- | TYPE_OPTIONS_POPUP_DIALOG | TYPE_ADD_TO_HOME_CONFIRMATION;
+ | TYPE_WIDGETS_EDUCATION_DIALOG;
// Type of popups which should be kept open during launcher rebind
public static final int TYPE_REBIND_SAFE = TYPE_WIDGETS_FULL_SHEET
| TYPE_WIDGETS_BOTTOM_SHEET | TYPE_ON_BOARD_POPUP | TYPE_DISCOVERY_BOUNCE
- | TYPE_ALL_APPS_EDU | TYPE_ICON_SURFACE | TYPE_WIDGETS_EDUCATION_DIALOG
- | TYPE_TASKBAR_EDUCATION_DIALOG | TYPE_TASKBAR_ALL_APPS | TYPE_OPTIONS_POPUP_DIALOG;
+ | TYPE_ALL_APPS_EDU | TYPE_ICON_SURFACE | TYPE_WIDGETS_EDUCATION_DIALOG;
// Usually we show the back button when a floating view is open. Instead, hide for these types.
public static final int TYPE_HIDE_BACK_BUTTON = TYPE_ON_BOARD_POPUP | TYPE_DISCOVERY_BOUNCE
@@ -201,31 +192,10 @@ public abstract class AbstractFloatingView extends LinearLayout implements Touch
}
/**
- * Returns a view matching FloatingViewType and {@link #isOpen()} == true.
+ * Returns a view matching FloatingViewType
*/
public static <T extends AbstractFloatingView> T getOpenView(
ActivityContext activity, @FloatingViewType int type) {
- return getView(activity, type, true /* mustBeOpen */);
- }
-
- /**
- * Returns whether there is at least one view of the given type where {@link #isOpen()} == true.
- */
- public static boolean hasOpenView(ActivityContext activity, @FloatingViewType int type) {
- return getOpenView(activity, type) != null;
- }
-
- /**
- * Returns a view matching FloatingViewType, and {@link #isOpen()} may be false (if animating
- * closed).
- */
- public static <T extends AbstractFloatingView> T getAnyView(
- ActivityContext activity, @FloatingViewType int type) {
- return getView(activity, type, false /* mustBeOpen */);
- }
-
- private static <T extends AbstractFloatingView> T getView(
- ActivityContext activity, @FloatingViewType int type, boolean mustBeOpen) {
BaseDragLayer dragLayer = activity.getDragLayer();
if (dragLayer == null) return null;
// Iterate in reverse order. AbstractFloatingView is added later to the dragLayer,
@@ -234,7 +204,7 @@ public abstract class AbstractFloatingView extends LinearLayout implements Touch
View child = dragLayer.getChildAt(i);
if (child instanceof AbstractFloatingView) {
AbstractFloatingView view = (AbstractFloatingView) child;
- if (view.isOfType(type) && (!mustBeOpen || view.isOpen())) {
+ if (view.isOfType(type) && view.isOpen()) {
return (T) view;
}
}
diff --git a/src/com/android/launcher3/AppWidgetResizeFrame.java b/src/com/android/launcher3/AppWidgetResizeFrame.java
index 4b4a017c9d..ee711463d9 100644
--- a/src/com/android/launcher3/AppWidgetResizeFrame.java
+++ b/src/com/android/launcher3/AppWidgetResizeFrame.java
@@ -2,7 +2,6 @@ package com.android.launcher3;
import static android.appwidget.AppWidgetHostView.getDefaultPaddingForWidget;
-import static com.android.launcher3.CellLayout.SPRING_LOADED_PROGRESS;
import static com.android.launcher3.LauncherAnimUtils.LAYOUT_HEIGHT;
import static com.android.launcher3.LauncherAnimUtils.LAYOUT_WIDTH;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_WIDGET_RESIZE_COMPLETED;
@@ -10,8 +9,6 @@ import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCH
import static com.android.launcher3.views.BaseDragLayer.LAYOUT_X;
import static com.android.launcher3.views.BaseDragLayer.LAYOUT_Y;
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
@@ -32,7 +29,6 @@ import androidx.annotation.Px;
import com.android.launcher3.accessibility.DragViewStateAnnouncer;
import com.android.launcher3.dragndrop.DragLayer;
-import com.android.launcher3.keyboard.ViewGroupFocusHelper;
import com.android.launcher3.logging.InstanceId;
import com.android.launcher3.logging.InstanceIdSequence;
import com.android.launcher3.model.data.ItemInfo;
@@ -53,14 +49,12 @@ public class AppWidgetResizeFrame extends AbstractFloatingView implements View.O
private static final String KEY_RECONFIGURABLE_WIDGET_EDUCATION_TIP_SEEN =
"launcher.reconfigurable_widget_education_tip_seen";
private static final Rect sTmpRect = new Rect();
- private static final Rect sTmpRect2 = new Rect();
private static final int HANDLE_COUNT = 4;
private static final int INDEX_LEFT = 0;
private static final int INDEX_TOP = 1;
private static final int INDEX_RIGHT = 2;
private static final int INDEX_BOTTOM = 3;
- private static final float MIN_OPACITY_FOR_CELL_LAYOUT_DURING_INVALID_RESIZE = 0.5f;
private final Launcher mLauncher;
private final DragViewStateAnnouncer mStateAnnouncer;
@@ -109,16 +103,6 @@ public class AppWidgetResizeFrame extends AbstractFloatingView implements View.O
private final InstanceId logInstanceId = new InstanceIdSequence().newInstanceId();
- private final ViewGroupFocusHelper mDragLayerRelativeCoordinateHelper;
-
- /**
- * In the two panel UI, it is not possible to resize a widget to cross its host
- * {@link CellLayout}'s sibling. When this happens, we gradually reduce the opacity of the
- * sibling {@link CellLayout} from 1f to
- * {@link #MIN_OPACITY_FOR_CELL_LAYOUT_DURING_INVALID_RESIZE}.
- */
- private final float mDragAcrossTwoPanelOpacityMargin;
-
private boolean mLeftBorderActive;
private boolean mRightBorderActive;
private boolean mTopBorderActive;
@@ -165,10 +149,6 @@ public class AppWidgetResizeFrame extends AbstractFloatingView implements View.O
for (int i = 0; i < HANDLE_COUNT; i++) {
mSystemGestureExclusionRects.add(new Rect());
}
-
- mDragAcrossTwoPanelOpacityMargin = mLauncher.getResources().getDimensionPixelSize(
- R.dimen.resize_frame_invalid_drag_across_two_panel_opacity_margin);
- mDragLayerRelativeCoordinateHelper = new ViewGroupFocusHelper(mLauncher.getDragLayer());
}
@Override
@@ -215,7 +195,7 @@ public class AppWidgetResizeFrame extends AbstractFloatingView implements View.O
dl.addView(frame);
frame.mIsOpen = true;
- frame.post(() -> frame.snapToWidget(false));
+ frame.snapToWidget(false);
}
private void setupForWidget(LauncherAppWidgetHostView widgetView, CellLayout cellLayout,
@@ -241,15 +221,13 @@ public class AppWidgetResizeFrame extends AbstractFloatingView implements View.O
// Only show resize handles for the directions in which resizing is possible.
InvariantDeviceProfile idp = LauncherAppState.getIDP(cellLayout.getContext());
mVerticalResizeActive = (info.resizeMode & AppWidgetProviderInfo.RESIZE_VERTICAL) != 0
- && mMinVSpan < idp.numRows && mMaxVSpan > 1
- && mMinVSpan < mMaxVSpan;
+ && mMinVSpan < idp.numRows && mMaxVSpan > 1;
if (!mVerticalResizeActive) {
mDragHandles[INDEX_TOP].setVisibility(GONE);
mDragHandles[INDEX_BOTTOM].setVisibility(GONE);
}
mHorizontalResizeActive = (info.resizeMode & AppWidgetProviderInfo.RESIZE_HORIZONTAL) != 0
- && mMinHSpan < idp.numColumns && mMaxHSpan > 1
- && mMinHSpan < mMaxHSpan;
+ && mMinHSpan < idp.numColumns && mMaxHSpan > 1;
if (!mHorizontalResizeActive) {
mDragHandles[INDEX_LEFT].setVisibility(GONE);
mDragHandles[INDEX_RIGHT].setVisibility(GONE);
@@ -381,37 +359,6 @@ public class AppWidgetResizeFrame extends AbstractFloatingView implements View.O
lp.y = sTmpRect.top;
}
- // Handle invalid resize across CellLayouts in the two panel UI.
- if (mCellLayout.getParent() instanceof Workspace) {
- Workspace<?> workspace = (Workspace<?>) mCellLayout.getParent();
- CellLayout pairedCellLayout = workspace.getScreenPair(mCellLayout);
- if (pairedCellLayout != null) {
- Rect focusedCellLayoutBound = sTmpRect;
- mDragLayerRelativeCoordinateHelper.viewToRect(mCellLayout, focusedCellLayoutBound);
- Rect resizeFrameBound = sTmpRect2;
- findViewById(R.id.widget_resize_frame).getGlobalVisibleRect(resizeFrameBound);
- float progress = 1f;
- if (workspace.indexOfChild(pairedCellLayout) < workspace.indexOfChild(mCellLayout)
- && mDeltaX < 0
- && resizeFrameBound.left < focusedCellLayoutBound.left) {
- // Resize from right to left.
- progress = (mDragAcrossTwoPanelOpacityMargin + mDeltaX)
- / mDragAcrossTwoPanelOpacityMargin;
- } else if (workspace.indexOfChild(pairedCellLayout)
- > workspace.indexOfChild(mCellLayout)
- && mDeltaX > 0
- && resizeFrameBound.right > focusedCellLayoutBound.right) {
- // Resize from left to right.
- progress = (mDragAcrossTwoPanelOpacityMargin - mDeltaX)
- / mDragAcrossTwoPanelOpacityMargin;
- }
- float alpha = Math.max(MIN_OPACITY_FOR_CELL_LAYOUT_DURING_INVALID_RESIZE, progress);
- float springLoadedProgress = Math.min(1f, 1f - progress);
- updateInvalidResizeEffect(mCellLayout, pairedCellLayout, alpha,
- springLoadedProgress);
- }
- }
-
requestLayout();
}
@@ -424,8 +371,8 @@ public class AppWidgetResizeFrame extends AbstractFloatingView implements View.O
*/
private void resizeWidgetIfNeeded(boolean onDismiss) {
DeviceProfile dp = mLauncher.getDeviceProfile();
- float xThreshold = mCellLayout.getCellWidth() + dp.cellLayoutBorderSpacePx.x;
- float yThreshold = mCellLayout.getCellHeight() + dp.cellLayoutBorderSpacePx.y;
+ float xThreshold = mCellLayout.getCellWidth() + dp.cellLayoutBorderSpacingPx;
+ float yThreshold = mCellLayout.getCellHeight() + dp.cellLayoutBorderSpacingPx;
int hSpanInc = getSpanIncrement((mDeltaX + mDeltaXAddOn) / xThreshold - mRunningHInc);
int vSpanInc = getSpanIncrement((mDeltaY + mDeltaYAddOn) / yThreshold - mRunningVInc);
@@ -510,8 +457,8 @@ public class AppWidgetResizeFrame extends AbstractFloatingView implements View.O
private void onTouchUp() {
DeviceProfile dp = mLauncher.getDeviceProfile();
- int xThreshold = mCellLayout.getCellWidth() + dp.cellLayoutBorderSpacePx.x;
- int yThreshold = mCellLayout.getCellHeight() + dp.cellLayoutBorderSpacePx.y;
+ int xThreshold = mCellLayout.getCellWidth() + dp.cellLayoutBorderSpacingPx;
+ int yThreshold = mCellLayout.getCellHeight() + dp.cellLayoutBorderSpacingPx;
mDeltaXAddOn = mRunningHInc * xThreshold;
mDeltaYAddOn = mRunningVInc * yThreshold;
@@ -568,24 +515,13 @@ public class AppWidgetResizeFrame extends AbstractFloatingView implements View.O
}
final DragLayer.LayoutParams lp = (DragLayer.LayoutParams) getLayoutParams();
- final CellLayout pairedCellLayout;
- if (mCellLayout.getParent() instanceof Workspace) {
- Workspace<?> workspace = (Workspace<?>) mCellLayout.getParent();
- pairedCellLayout = workspace.getScreenPair(mCellLayout);
- } else {
- pairedCellLayout = null;
- }
if (!animate) {
lp.width = newWidth;
lp.height = newHeight;
lp.x = newX;
lp.y = newY;
for (int i = 0; i < HANDLE_COUNT; i++) {
- mDragHandles[i].setAlpha(1f);
- }
- if (pairedCellLayout != null) {
- updateInvalidResizeEffect(mCellLayout, pairedCellLayout, /* alpha= */ 1f,
- /* springLoadedProgress= */ 0f);
+ mDragHandles[i].setAlpha(1.0f);
}
requestLayout();
} else {
@@ -602,10 +538,6 @@ public class AppWidgetResizeFrame extends AbstractFloatingView implements View.O
set.play(mFirstFrameAnimatorHelper.addTo(
ObjectAnimator.ofFloat(mDragHandles[i], ALPHA, 1f)));
}
- if (pairedCellLayout != null) {
- updateInvalidResizeEffect(mCellLayout, pairedCellLayout, /* alpha= */ 1f,
- /* springLoadedProgress= */ 0f, /* animatorSet= */ set);
- }
set.setDuration(SNAP_DURATION);
set.start();
}
@@ -692,52 +624,6 @@ public class AppWidgetResizeFrame extends AbstractFloatingView implements View.O
}
}
- private void updateInvalidResizeEffect(CellLayout cellLayout, CellLayout pairedCellLayout,
- float alpha, float springLoadedProgress) {
- updateInvalidResizeEffect(cellLayout, pairedCellLayout, alpha,
- springLoadedProgress, /* animatorSet= */ null);
- }
-
- private void updateInvalidResizeEffect(CellLayout cellLayout, CellLayout pairedCellLayout,
- float alpha, float springLoadedProgress, @Nullable AnimatorSet animatorSet) {
- int childCount = pairedCellLayout.getChildCount();
- for (int i = 0; i < childCount; i++) {
- View child = pairedCellLayout.getChildAt(i);
- if (animatorSet != null) {
- animatorSet.play(
- mFirstFrameAnimatorHelper.addTo(
- ObjectAnimator.ofFloat(child, ALPHA, alpha)));
- } else {
- child.setAlpha(alpha);
- }
- }
- if (animatorSet != null) {
- animatorSet.play(mFirstFrameAnimatorHelper.addTo(
- ObjectAnimator.ofFloat(cellLayout, SPRING_LOADED_PROGRESS,
- springLoadedProgress)));
- animatorSet.play(mFirstFrameAnimatorHelper.addTo(
- ObjectAnimator.ofFloat(pairedCellLayout, SPRING_LOADED_PROGRESS,
- springLoadedProgress)));
- } else {
- cellLayout.setSpringLoadedProgress(springLoadedProgress);
- pairedCellLayout.setSpringLoadedProgress(springLoadedProgress);
- }
-
- boolean shouldShowCellLayoutBorder = springLoadedProgress > 0f;
- if (animatorSet != null) {
- animatorSet.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animator) {
- cellLayout.setIsDragOverlapping(shouldShowCellLayoutBorder);
- pairedCellLayout.setIsDragOverlapping(shouldShowCellLayoutBorder);
- }
- });
- } else {
- cellLayout.setIsDragOverlapping(shouldShowCellLayoutBorder);
- pairedCellLayout.setIsDragOverlapping(shouldShowCellLayoutBorder);
- }
- }
-
@Override
protected boolean isOfType(int type) {
return (type & TYPE_WIDGET_RESIZE_FRAME) != 0;
diff --git a/src/com/android/launcher3/AutoInstallsLayout.java b/src/com/android/launcher3/AutoInstallsLayout.java
index 64666b0041..5b655a4740 100644
--- a/src/com/android/launcher3/AutoInstallsLayout.java
+++ b/src/com/android/launcher3/AutoInstallsLayout.java
@@ -27,7 +27,9 @@ import android.content.res.Resources;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.drawable.Drawable;
import android.net.Uri;
+import android.os.Build.VERSION;
import android.os.Bundle;
+import android.os.Process;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.AttributeSet;
@@ -447,7 +449,7 @@ public class AutoInstallsLayout {
// Auto installs should always support the current platform version.
LauncherIcons li = LauncherIcons.obtain(mContext);
mValues.put(LauncherSettings.Favorites.ICON, GraphicsUtils.flattenBitmap(
- li.createBadgedIconBitmap(icon).icon));
+ li.createBadgedIconBitmap(icon, Process.myUserHandle(), VERSION.SDK_INT).icon));
li.recycle();
mValues.put(Favorites.ICON_PACKAGE, mIconRes.getResourcePackageName(iconId));
diff --git a/src/com/android/launcher3/BaseActivity.java b/src/com/android/launcher3/BaseActivity.java
index 73d3e3301c..9778b61854 100644
--- a/src/com/android/launcher3/BaseActivity.java
+++ b/src/com/android/launcher3/BaseActivity.java
@@ -16,6 +16,7 @@
package com.android.launcher3;
+import static com.android.launcher3.model.WidgetsModel.GO_DISABLE_WIDGETS;
import static com.android.launcher3.util.SystemUiController.UI_STATE_FULLSCREEN_TASK;
import static java.lang.annotation.RetentionPolicy.SOURCE;
@@ -24,28 +25,30 @@ import android.app.Activity;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.Intent;
+import android.content.pm.LauncherApps;
import android.content.res.Configuration;
+import android.graphics.Rect;
+import android.os.Bundle;
+import android.os.UserHandle;
+import android.util.Log;
import androidx.annotation.IntDef;
-import com.android.launcher3.DeviceProfile.DeviceProfileListenable;
import com.android.launcher3.DeviceProfile.OnDeviceProfileChangeListener;
import com.android.launcher3.logging.StatsLogManager;
import com.android.launcher3.util.SystemUiController;
import com.android.launcher3.util.ViewCache;
-import com.android.launcher3.views.AppLauncher;
+import com.android.launcher3.views.ActivityContext;
import com.android.launcher3.views.ScrimView;
import java.io.PrintWriter;
import java.lang.annotation.Retention;
import java.util.ArrayList;
-import java.util.List;
/**
* Launcher BaseActivity
*/
-public abstract class BaseActivity extends Activity implements AppLauncher,
- DeviceProfileListenable {
+public abstract class BaseActivity extends Activity implements ActivityContext {
private static final String TAG = "BaseActivity";
@@ -139,15 +142,9 @@ public abstract class BaseActivity extends Activity implements AppLauncher,
return mDeviceProfile;
}
- @Override
- public List<OnDeviceProfileChangeListener> getOnDeviceProfileChangeListeners() {
- return mDPChangeListeners;
- }
-
/**
* Returns {@link StatsLogManager} for user event logging.
*/
- @Override
public StatsLogManager getStatsLogManager() {
if (mStatsLogManager == null) {
mStatsLogManager = StatsLogManager.newInstance(this);
@@ -263,6 +260,20 @@ public abstract class BaseActivity extends Activity implements AppLauncher,
protected void onActivityFlagsChanged(int changeBits) { }
+ public void addOnDeviceProfileChangeListener(OnDeviceProfileChangeListener listener) {
+ mDPChangeListeners.add(listener);
+ }
+
+ public void removeOnDeviceProfileChangeListener(OnDeviceProfileChangeListener listener) {
+ mDPChangeListeners.remove(listener);
+ }
+
+ protected void dispatchDeviceProfileChanged() {
+ for (int i = mDPChangeListeners.size() - 1; i >= 0; i--) {
+ mDPChangeListeners.get(i).onDeviceProfileChanged(mDeviceProfile);
+ }
+ }
+
public void addMultiWindowModeChangedListener(MultiWindowModeChangedListener listener) {
mMultiWindowModeChangedListeners.add(listener);
}
@@ -308,6 +319,22 @@ public abstract class BaseActivity extends Activity implements AppLauncher,
writer.println(prefix + "mForceInvisible: " + mForceInvisible);
}
+ /**
+ * A wrapper around the platform method with Launcher specific checks
+ */
+ public void startShortcut(String packageName, String id, Rect sourceBounds,
+ Bundle startActivityOptions, UserHandle user) {
+ if (GO_DISABLE_WIDGETS) {
+ return;
+ }
+ try {
+ getSystemService(LauncherApps.class).startShortcut(packageName, id, sourceBounds,
+ startActivityOptions, user);
+ } catch (SecurityException | IllegalStateException e) {
+ Log.e(TAG, "Failed to start shortcut", e);
+ }
+ }
+
public static <T extends BaseActivity> T fromContext(Context context) {
if (context instanceof BaseActivity) {
return (T) context;
diff --git a/src/com/android/launcher3/BaseDraggingActivity.java b/src/com/android/launcher3/BaseDraggingActivity.java
index 6de3884b93..2c76e52c61 100644
--- a/src/com/android/launcher3/BaseDraggingActivity.java
+++ b/src/com/android/launcher3/BaseDraggingActivity.java
@@ -16,33 +16,53 @@
package com.android.launcher3;
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_APP_LAUNCH_TAP;
import static com.android.launcher3.util.DisplayController.CHANGE_ROTATION;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
+import android.app.ActivityOptions;
import android.app.WallpaperColors;
import android.app.WallpaperManager;
import android.app.WallpaperManager.OnColorsChangedListener;
+import android.content.ActivityNotFoundException;
import android.content.Context;
+import android.content.Intent;
+import android.content.pm.LauncherApps;
import android.content.res.Configuration;
+import android.graphics.Insets;
import android.graphics.Point;
import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
import android.os.Bundle;
+import android.os.Process;
+import android.os.StrictMode;
+import android.os.UserHandle;
+import android.util.Log;
import android.view.ActionMode;
import android.view.Display;
import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.WindowInsets.Type;
+import android.view.WindowMetrics;
+import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
-import com.android.launcher3.allapps.ActivityAllAppsContainerView;
+import com.android.launcher3.LauncherSettings.Favorites;
+import com.android.launcher3.allapps.AllAppsContainerView;
import com.android.launcher3.allapps.search.DefaultSearchAdapterProvider;
import com.android.launcher3.allapps.search.SearchAdapterProvider;
+import com.android.launcher3.logging.InstanceId;
+import com.android.launcher3.logging.InstanceIdSequence;
import com.android.launcher3.model.data.ItemInfo;
+import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.launcher3.touch.ItemClickHandler;
import com.android.launcher3.util.ActivityOptionsWrapper;
import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.DisplayController.DisplayInfoChangeListener;
import com.android.launcher3.util.DisplayController.Info;
+import com.android.launcher3.util.PackageManagerHelper;
import com.android.launcher3.util.RunnableList;
import com.android.launcher3.util.Themes;
import com.android.launcher3.util.TraceHelper;
@@ -145,12 +165,110 @@ public abstract class BaseDraggingActivity extends BaseActivity
// no-op
}
- @Override
+ public Rect getViewBounds(View v) {
+ int[] pos = new int[2];
+ v.getLocationOnScreen(pos);
+ return new Rect(pos[0], pos[1], pos[0] + v.getWidth(), pos[1] + v.getHeight());
+ }
+
@NonNull
public ActivityOptionsWrapper getActivityLaunchOptions(View v, @Nullable ItemInfo item) {
- ActivityOptionsWrapper wrapper = super.getActivityLaunchOptions(v, item);
- addOnResumeCallback(wrapper.onEndCallback::executeAllAndDestroy);
- return wrapper;
+ int left = 0, top = 0;
+ int width = v.getMeasuredWidth(), height = v.getMeasuredHeight();
+ if (v instanceof BubbleTextView) {
+ // Launch from center of icon, not entire view
+ Drawable icon = ((BubbleTextView) v).getIcon();
+ if (icon != null) {
+ Rect bounds = icon.getBounds();
+ left = (width - bounds.width()) / 2;
+ top = v.getPaddingTop();
+ width = bounds.width();
+ height = bounds.height();
+ }
+ }
+ ActivityOptions options =
+ ActivityOptions.makeClipRevealAnimation(v, left, top, width, height);
+ RunnableList callback = new RunnableList();
+ addOnResumeCallback(callback::executeAllAndDestroy);
+ return new ActivityOptionsWrapper(options, callback);
+ }
+
+ public boolean startActivitySafely(View v, Intent intent, @Nullable ItemInfo item) {
+ if (mIsSafeModeEnabled && !PackageManagerHelper.isSystemApp(this, intent)) {
+ Toast.makeText(this, R.string.safemode_shortcut_error, Toast.LENGTH_SHORT).show();
+ return false;
+ }
+
+ Bundle optsBundle = (v != null) ? getActivityLaunchOptions(v, item).toBundle() : null;
+ UserHandle user = item == null ? null : item.user;
+
+ // Prepare intent
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ if (v != null) {
+ intent.setSourceBounds(getViewBounds(v));
+ }
+ try {
+ boolean isShortcut = (item instanceof WorkspaceItemInfo)
+ && (item.itemType == Favorites.ITEM_TYPE_SHORTCUT
+ || item.itemType == Favorites.ITEM_TYPE_DEEP_SHORTCUT)
+ && !((WorkspaceItemInfo) item).isPromise();
+ if (isShortcut) {
+ // Shortcuts need some special checks due to legacy reasons.
+ startShortcutIntentSafely(intent, optsBundle, item);
+ } else if (user == null || user.equals(Process.myUserHandle())) {
+ // Could be launching some bookkeeping activity
+ startActivity(intent, optsBundle);
+ } else {
+ getSystemService(LauncherApps.class).startMainActivity(
+ intent.getComponent(), user, intent.getSourceBounds(), optsBundle);
+ }
+ if (item != null) {
+ InstanceId instanceId = new InstanceIdSequence().newInstanceId();
+ logAppLaunch(item, instanceId);
+ }
+ return true;
+ } catch (NullPointerException | ActivityNotFoundException | SecurityException e) {
+ Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();
+ Log.e(TAG, "Unable to launch. tag=" + item + " intent=" + intent, e);
+ }
+ return false;
+ }
+
+ protected void logAppLaunch(ItemInfo info, InstanceId instanceId) {
+ getStatsLogManager().logger().withItemInfo(info).withInstanceId(instanceId)
+ .log(LAUNCHER_APP_LAUNCH_TAP);
+ }
+
+ private void startShortcutIntentSafely(Intent intent, Bundle optsBundle, ItemInfo info) {
+ try {
+ StrictMode.VmPolicy oldPolicy = StrictMode.getVmPolicy();
+ try {
+ // Temporarily disable deathPenalty on all default checks. For eg, shortcuts
+ // containing file Uri's would cause a crash as penaltyDeathOnFileUriExposure
+ // is enabled by default on NYC.
+ StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder().detectAll()
+ .penaltyLog().build());
+
+ if (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT) {
+ String id = ((WorkspaceItemInfo) info).getDeepShortcutId();
+ String packageName = intent.getPackage();
+ startShortcut(packageName, id, intent.getSourceBounds(), optsBundle, info.user);
+ } else {
+ // Could be launching some bookkeeping activity
+ startActivity(intent, optsBundle);
+ }
+ } finally {
+ StrictMode.setVmPolicy(oldPolicy);
+ }
+ } catch (SecurityException e) {
+ if (!onErrorStartingShortcut(intent, info)) {
+ throw e;
+ }
+ }
+ }
+
+ protected boolean onErrorStartingShortcut(Intent intent, ItemInfo info) {
+ return false;
}
@Override
@@ -193,8 +311,7 @@ public abstract class BaseDraggingActivity extends BaseActivity
}
}
- @Override
- public View.OnClickListener getItemOnClickListener() {
+ public OnClickListener getItemOnClickListener() {
return ItemClickHandler.INSTANCE;
}
@@ -202,7 +319,11 @@ public abstract class BaseDraggingActivity extends BaseActivity
protected WindowBounds getMultiWindowDisplaySize() {
if (Utilities.ATLEAST_R) {
- return WindowBounds.fromWindowMetrics(getWindowManager().getCurrentWindowMetrics());
+ WindowMetrics wm = getWindowManager().getCurrentWindowMetrics();
+
+ Insets insets = wm.getWindowInsets().getInsets(Type.systemBars());
+ return new WindowBounds(wm.getBounds(),
+ new Rect(insets.left, insets.top, insets.right, insets.bottom));
}
// Note: Calls to getSize() can't rely on our cached DefaultDisplay since it can return
// the app window size
@@ -216,14 +337,7 @@ public abstract class BaseDraggingActivity extends BaseActivity
* Creates and returns {@link SearchAdapterProvider} for build variant specific search result
* views
*/
- @Override
- public SearchAdapterProvider<?> createSearchAdapterProvider(
- ActivityAllAppsContainerView<?> allApps) {
- return new DefaultSearchAdapterProvider(this);
- }
-
- @Override
- public boolean isAppBlockedForSafeMode() {
- return mIsSafeModeEnabled;
+ public SearchAdapterProvider createSearchAdapterProvider(AllAppsContainerView allapps) {
+ return new DefaultSearchAdapterProvider(this, allapps);
}
}
diff --git a/src/com/android/launcher3/FastScrollRecyclerView.java b/src/com/android/launcher3/BaseRecyclerView.java
index f117069144..9369bdc2fd 100644
--- a/src/com/android/launcher3/FastScrollRecyclerView.java
+++ b/src/com/android/launcher3/BaseRecyclerView.java
@@ -23,7 +23,7 @@ import android.view.View;
import android.view.ViewGroup;
import android.view.accessibility.AccessibilityNodeInfo;
-import androidx.annotation.Nullable;
+import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.android.launcher3.compat.AccessibilityManagerCompat;
@@ -37,19 +37,19 @@ import com.android.launcher3.views.RecyclerViewFastScroller;
* <li> Enable fast scroller.
* </ul>
*/
-public abstract class FastScrollRecyclerView extends RecyclerView {
+public abstract class BaseRecyclerView extends RecyclerView {
protected RecyclerViewFastScroller mScrollbar;
- public FastScrollRecyclerView(Context context) {
+ public BaseRecyclerView(Context context) {
this(context, null);
}
- public FastScrollRecyclerView(Context context, AttributeSet attrs) {
+ public BaseRecyclerView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
- public FastScrollRecyclerView(Context context, AttributeSet attrs, int defStyleAttr) {
+ public BaseRecyclerView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@@ -66,7 +66,6 @@ public abstract class FastScrollRecyclerView extends RecyclerView {
onUpdateScrollbar(0);
}
- @Nullable
public RecyclerViewFastScroller getScrollbar() {
return mScrollbar;
}
@@ -198,6 +197,13 @@ public abstract class FastScrollRecyclerView extends RecyclerView {
if (mScrollbar != null) {
mScrollbar.reattachThumbToScroll();
}
+ if (getLayoutManager() instanceof LinearLayoutManager) {
+ LinearLayoutManager layoutManager = (LinearLayoutManager) getLayoutManager();
+ if (layoutManager.findFirstCompletelyVisibleItemPosition() == 0) {
+ // We are at the top, so don't scrollToPosition (would cause unnecessary relayout).
+ return;
+ }
+ }
scrollToPosition(0);
}
-}
+} \ No newline at end of file
diff --git a/src/com/android/launcher3/BubbleTextView.java b/src/com/android/launcher3/BubbleTextView.java
index 5fb892554a..ddbd425b55 100644
--- a/src/com/android/launcher3/BubbleTextView.java
+++ b/src/com/android/launcher3/BubbleTextView.java
@@ -16,10 +16,7 @@
package com.android.launcher3;
-import static com.android.launcher3.config.FeatureFlags.ENABLE_ICON_LABEL_AUTO_SCALING;
import static com.android.launcher3.graphics.PreloadIconDrawable.newPendingIcon;
-import static com.android.launcher3.icons.BitmapInfo.FLAG_NO_BADGE;
-import static com.android.launcher3.icons.BitmapInfo.FLAG_THEMED;
import static com.android.launcher3.icons.GraphicsUtils.setColorAlphaBound;
import android.animation.Animator;
@@ -35,9 +32,6 @@ import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
-import android.icu.text.MessageFormat;
-import android.text.TextPaint;
-import android.text.TextUtils;
import android.text.TextUtils.TruncateAt;
import android.util.AttributeSet;
import android.util.Property;
@@ -51,11 +45,11 @@ import android.widget.TextView;
import androidx.annotation.Nullable;
import androidx.annotation.UiThread;
-import com.android.launcher3.accessibility.BaseAccessibilityDelegate;
+import com.android.launcher3.accessibility.LauncherAccessibilityDelegate;
import com.android.launcher3.dot.DotInfo;
-import com.android.launcher3.dragndrop.DragOptions.PreDragCondition;
import com.android.launcher3.dragndrop.DraggableView;
import com.android.launcher3.folder.FolderIcon;
+import com.android.launcher3.graphics.IconPalette;
import com.android.launcher3.graphics.IconShape;
import com.android.launcher3.graphics.PreloadIconDrawable;
import com.android.launcher3.icons.DotRenderer;
@@ -66,16 +60,14 @@ import com.android.launcher3.icons.cache.HandlerRunnable;
import com.android.launcher3.model.data.AppInfo;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.ItemInfoWithIcon;
+import com.android.launcher3.model.data.PackageItemInfo;
+import com.android.launcher3.model.data.SearchActionItemInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo;
-import com.android.launcher3.popup.PopupContainerWithArrow;
import com.android.launcher3.util.SafeCloseable;
-import com.android.launcher3.util.ShortcutUtil;
import com.android.launcher3.views.ActivityContext;
import com.android.launcher3.views.IconLabelDotView;
import java.text.NumberFormat;
-import java.util.HashMap;
-import java.util.Locale;
/**
* TextView that draws a bubble behind the text. We cannot use a LineBackgroundSpan
@@ -92,18 +84,12 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver,
private static final int DISPLAY_SEARCH_RESULT = 6;
private static final int DISPLAY_SEARCH_RESULT_SMALL = 7;
- private static final float MIN_LETTER_SPACING = -0.05f;
- private static final int MAX_SEARCH_LOOP_COUNT = 20;
-
private static final int[] STATE_PRESSED = new int[]{android.R.attr.state_pressed};
+ private static final float HIGHLIGHT_SCALE = 1.16f;
private final PointF mTranslationForReorderBounce = new PointF(0, 0);
private final PointF mTranslationForReorderPreview = new PointF(0, 0);
- private float mTranslationXForTaskbarAlignmentAnimation = 0f;
-
- private final PointF mTranslationForMoveFromCenterAnimation = new PointF(0, 0);
-
private float mScaleForReorderBounce = 1f;
private static final Property<BubbleTextView, Float> DOT_SCALE_PROPERTY
@@ -142,18 +128,13 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver,
private final CheckLongPressHelper mLongPressHelper;
private final boolean mLayoutHorizontal;
- private final boolean mIsRtl;
private final int mIconSize;
@ViewDebug.ExportedProperty(category = "launcher")
- private boolean mHideBadge = false;
- @ViewDebug.ExportedProperty(category = "launcher")
private boolean mIsIconVisible = true;
@ViewDebug.ExportedProperty(category = "launcher")
private int mTextColor;
@ViewDebug.ExportedProperty(category = "launcher")
- private ColorStateList mTextColorStateList;
- @ViewDebug.ExportedProperty(category = "launcher")
private float mTextAlpha = 1;
@ViewDebug.ExportedProperty(category = "launcher")
@@ -190,8 +171,6 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver,
TypedArray a = context.obtainStyledAttributes(attrs,
R.styleable.BubbleTextView, defStyle, 0);
mLayoutHorizontal = a.getBoolean(R.styleable.BubbleTextView_layoutHorizontal, false);
- mIsRtl = (getResources().getConfiguration().getLayoutDirection()
- == View.LAYOUT_DIRECTION_RTL);
DeviceProfile grid = mActivity.getDeviceProfile();
mDisplay = a.getInteger(R.styleable.BubbleTextView_iconDisplay, DISPLAY_WORKSPACE);
@@ -243,27 +222,16 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver,
super.onFocusChanged(focused, direction, previouslyFocusedRect);
}
- public void setHideBadge(boolean hideBadge) {
- mHideBadge = hideBadge;
- }
-
/**
* Resets the view so it can be recycled.
*/
public void reset() {
mDotInfo = null;
- mDotParams.dotColor = Color.TRANSPARENT;
- mDotParams.appColor = Color.TRANSPARENT;
+ mDotParams.color = Color.TRANSPARENT;
cancelDotScaleAnim();
mDotParams.scale = 0f;
mForceHideDot = false;
setBackground(null);
-
- setTag(null);
- if (mIconLoadRequest != null) {
- mIconLoadRequest.cancel();
- mIconLoadRequest = null;
- }
}
private void cancelDotScaleAnim() {
@@ -286,30 +254,12 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver,
@UiThread
public void applyFromWorkspaceItem(WorkspaceItemInfo info) {
- applyFromWorkspaceItem(info, /* animate = */ false, /* staggerIndex = */ 0);
- }
-
- @UiThread
- public void applyFromWorkspaceItem(WorkspaceItemInfo info, boolean animate, int staggerIndex) {
applyFromWorkspaceItem(info, false);
}
- /**
- * Returns whether the newInfo differs from the current getTag().
- */
- public boolean shouldAnimateIconChange(WorkspaceItemInfo newInfo) {
- WorkspaceItemInfo oldInfo = getTag() instanceof WorkspaceItemInfo
- ? (WorkspaceItemInfo) getTag()
- : null;
- boolean changedIcons = oldInfo != null && oldInfo.getTargetComponent() != null
- && newInfo.getTargetComponent() != null
- && !oldInfo.getTargetComponent().equals(newInfo.getTargetComponent());
- return changedIcons && isShown();
- }
-
@Override
public void setAccessibilityDelegate(AccessibilityDelegate delegate) {
- if (delegate instanceof BaseAccessibilityDelegate) {
+ if (delegate instanceof LauncherAccessibilityDelegate) {
super.setAccessibilityDelegate(delegate);
} else {
// NO-OP
@@ -322,7 +272,7 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver,
@UiThread
public void applyFromWorkspaceItem(WorkspaceItemInfo info, boolean promiseStateChanged) {
applyIconAndLabel(info);
- setItemInfo(info);
+ setTag(info);
applyLoadingState(promiseStateChanged);
applyDotState(info, false /* animate */);
setDownloadStateContentDescription(info, info.getProgressLevel());
@@ -333,8 +283,7 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver,
applyIconAndLabel(info);
// We don't need to check the info since it's not a WorkspaceItemInfo
- setItemInfo(info);
-
+ super.setTag(info);
// Verify high res immediately
verifyHighRes();
@@ -353,7 +302,7 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver,
public void applyFromItemInfoWithIcon(ItemInfoWithIcon info) {
applyIconAndLabel(info);
// We don't need to check the info since it's not a WorkspaceItemInfo
- setItemInfo(info);
+ super.setTag(info);
// Verify high res immediately
verifyHighRes();
@@ -361,22 +310,21 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver,
setDownloadStateContentDescription(info, info.getProgressLevel());
}
- protected void setItemInfo(ItemInfoWithIcon itemInfo) {
- setTag(itemInfo);
+ /**
+ * Apply label and tag using a {@link SearchActionItemInfo}
+ */
+ @UiThread
+ public void applyFromSearchActionItemInfo(SearchActionItemInfo searchActionItemInfo) {
+ applyIconAndLabel(searchActionItemInfo);
+ setTag(searchActionItemInfo);
}
@UiThread
protected void applyIconAndLabel(ItemInfoWithIcon info) {
- boolean useTheme = mDisplay == DISPLAY_WORKSPACE || mDisplay == DISPLAY_FOLDER
- || mDisplay == DISPLAY_TASKBAR;
- int flags = useTheme ? FLAG_THEMED : 0;
- if (mHideBadge) {
- flags |= FLAG_NO_BADGE;
- }
- FastBitmapDrawable iconDrawable = info.newIcon(getContext(), flags);
- mDotParams.appColor = iconDrawable.getIconColor();
- mDotParams.dotColor = getContext().getResources()
- .getColor(android.R.color.system_accent3_200, getContext().getTheme());
+ boolean useTheme = mDisplay == DISPLAY_WORKSPACE || mDisplay == DISPLAY_FOLDER;
+ FastBitmapDrawable iconDrawable = info.newIcon(getContext(), useTheme);
+ mDotParams.color = IconPalette.getMutedColor(iconDrawable.getIconColor(), 0.54f);
+
setIcon(iconDrawable);
applyLabel(info);
}
@@ -440,10 +388,6 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver,
* Returns true if the touch down at the provided position be ignored
*/
protected boolean shouldIgnoreTouchDown(float x, float y) {
- if (mDisplay == DISPLAY_TASKBAR) {
- // Allow touching within padding on taskbar, given icon sizes are smaller.
- return false;
- }
return y < getPaddingTop()
|| x < getPaddingLeft()
|| y > getHeight() - getPaddingBottom()
@@ -463,7 +407,7 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver,
}
}
- public void clearPressedBackground() {
+ void clearPressedBackground() {
setPressed(false);
setStayPressed(false);
}
@@ -480,75 +424,6 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver,
return result;
}
- @Override
- protected void onSizeChanged(int w, int h, int oldw, int oldh) {
- super.onSizeChanged(w, h, oldw, oldh);
- checkForEllipsis();
- }
-
- @Override
- protected void onTextChanged(CharSequence text, int start, int lengthBefore, int lengthAfter) {
- super.onTextChanged(text, start, lengthBefore, lengthAfter);
- checkForEllipsis();
- }
-
- private void checkForEllipsis() {
- if (!ENABLE_ICON_LABEL_AUTO_SCALING.get()) {
- return;
- }
- float width = getWidth() - getCompoundPaddingLeft() - getCompoundPaddingRight();
- if (width <= 0) {
- return;
- }
- setLetterSpacing(0);
-
- String text = getText().toString();
- TextPaint paint = getPaint();
- if (paint.measureText(text) < width) {
- return;
- }
-
- float spacing = findBestSpacingValue(paint, text, width, MIN_LETTER_SPACING);
- // Reset the paint value so that the call to TextView does appropriate diff.
- paint.setLetterSpacing(0);
- setLetterSpacing(spacing);
- }
-
- /**
- * Find the appropriate text spacing to display the provided text
- * @param paint the paint used by the text view
- * @param text the text to display
- * @param allowedWidthPx available space to render the text
- * @param minSpacingEm minimum spacing allowed between characters
- * @return the final textSpacing value
- *
- * @see #setLetterSpacing(float)
- */
- private float findBestSpacingValue(TextPaint paint, String text, float allowedWidthPx,
- float minSpacingEm) {
- paint.setLetterSpacing(minSpacingEm);
- if (paint.measureText(text) > allowedWidthPx) {
- // If there is no result at high limit, we can do anything more
- return minSpacingEm;
- }
-
- float lowLimit = 0;
- float highLimit = minSpacingEm;
-
- for (int i = 0; i < MAX_SEARCH_LOOP_COUNT; i++) {
- float value = (lowLimit + highLimit) / 2;
- paint.setLetterSpacing(value);
- if (paint.measureText(text) < allowedWidthPx) {
- highLimit = value;
- } else {
- lowLimit = value;
- }
- }
-
- // At the end error on the higher side
- return highLimit;
- }
-
@SuppressWarnings("wrongcall")
protected void drawWithoutDot(Canvas canvas) {
super.onDraw(canvas);
@@ -596,29 +471,19 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver,
return mDotInfo != null;
}
- /**
- * Get the icon bounds on the view depending on the layout type.
- */
public void getIconBounds(Rect outBounds) {
- getIconBounds(mIconSize, outBounds);
+ getIconBounds(this, outBounds, mIconSize);
}
- /**
- * Get the icon bounds on the view depending on the layout type.
- */
- public void getIconBounds(int iconSize, Rect outBounds) {
- Utilities.setRectToViewCenter(this, iconSize, outBounds);
- if (mLayoutHorizontal) {
- if (mIsRtl) {
- outBounds.offsetTo(getWidth() - iconSize - getPaddingRight(), outBounds.top);
- } else {
- outBounds.offsetTo(getPaddingLeft(), outBounds.top);
- }
- } else {
- outBounds.offsetTo(outBounds.left, getPaddingTop());
- }
+ public static void getIconBounds(View iconView, Rect outBounds, int iconSize) {
+ int top = iconView.getPaddingTop();
+ int left = (iconView.getWidth() - iconSize) / 2;
+ int right = left + iconSize;
+ int bottom = top + iconSize;
+ outBounds.set(left, top, right, bottom);
}
+
/**
* Sets whether to vertically center the content.
*/
@@ -642,14 +507,12 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver,
@Override
public void setTextColor(int color) {
mTextColor = color;
- mTextColorStateList = null;
super.setTextColor(getModifiedColor());
}
@Override
public void setTextColor(ColorStateList colors) {
mTextColor = colors.getDefaultColor();
- mTextColorStateList = colors;
if (Float.compare(mTextAlpha, 1) == 0) {
super.setTextColor(colors);
} else {
@@ -671,11 +534,7 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver,
private void setTextAlpha(float alpha) {
mTextAlpha = alpha;
- if (mTextColorStateList != null) {
- setTextColor(mTextColorStateList);
- } else {
- super.setTextColor(getModifiedColor());
- }
+ super.setTextColor(getModifiedColor());
}
private int getModifiedColor() {
@@ -803,14 +662,14 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver,
invalidate();
}
}
- if (!TextUtils.isEmpty(itemInfo.contentDescription)) {
+ if (itemInfo.contentDescription != null) {
if (itemInfo.isDisabled()) {
setContentDescription(getContext().getString(R.string.disabled_app_label,
itemInfo.contentDescription));
} else if (hasDot()) {
int count = mDotInfo.getNotificationCount();
- setContentDescription(
- getAppLabelPluralString(itemInfo.contentDescription.toString(), count));
+ setContentDescription(getContext().getResources().getQuantityString(
+ R.plurals.dotted_app_label, count, itemInfo.contentDescription, count));
} else {
setContentDescription(itemInfo.contentDescription);
}
@@ -864,11 +723,6 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver,
}
protected void applyCompoundDrawables(Drawable icon) {
- if (icon == null) {
- // Icon can be null when we use the BubbleTextView for text only.
- return;
- }
-
// If we had already set an icon before, disable relayout as the icon size is the
// same as before.
mDisableRelayout = mIcon != null;
@@ -912,8 +766,10 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver,
} else if (info instanceof WorkspaceItemInfo) {
applyFromWorkspaceItem((WorkspaceItemInfo) info);
mActivity.invalidateParent(info);
- } else if (info != null) {
- applyFromItemInfoWithIcon(info);
+ } else if (info instanceof PackageItemInfo) {
+ applyFromItemInfoWithIcon((PackageItemInfo) info);
+ } else if (info instanceof SearchActionItemInfo) {
+ applyFromSearchActionItemInfo((SearchActionItemInfo) info);
}
mDisableRelayout = false;
@@ -943,11 +799,8 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver,
}
private void updateTranslation() {
- super.setTranslationX(mTranslationForReorderBounce.x + mTranslationForReorderPreview.x
- + mTranslationForMoveFromCenterAnimation.x
- + mTranslationXForTaskbarAlignmentAnimation);
- super.setTranslationY(mTranslationForReorderBounce.y + mTranslationForReorderPreview.y
- + mTranslationForMoveFromCenterAnimation.y);
+ super.setTranslationX(mTranslationForReorderBounce.x + mTranslationForReorderPreview.x);
+ super.setTranslationY(mTranslationForReorderBounce.y + mTranslationForReorderPreview.y);
}
public void setReorderBounceOffset(float x, float y) {
@@ -980,29 +833,6 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver,
return mScaleForReorderBounce;
}
- /**
- * Sets translation values for move from center animation
- */
- public void setTranslationForMoveFromCenterAnimation(float x, float y) {
- mTranslationForMoveFromCenterAnimation.set(x, y);
- updateTranslation();
- }
-
- /**
- * Sets translationX for taskbar to launcher alignment animation
- */
- public void setTranslationXForTaskbarAlignmentAnimation(float translationX) {
- mTranslationXForTaskbarAlignmentAnimation = translationX;
- updateTranslation();
- }
-
- /**
- * Returns translationX value for taskbar to launcher alignment animation
- */
- public float getTranslationXForTaskbarAlignmentAnimation() {
- return mTranslationXForTaskbarAlignmentAnimation;
- }
-
public View getView() {
return this;
}
@@ -1014,11 +844,24 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver,
@Override
public void getWorkspaceVisualDragBounds(Rect bounds) {
- getIconBounds(mIconSize, bounds);
+ DeviceProfile grid = mActivity.getDeviceProfile();
+ BubbleTextView.getIconBounds(this, bounds, grid.iconSizePx);
+ }
+
+ private int getIconSizeForDisplay(int display) {
+ DeviceProfile grid = mActivity.getDeviceProfile();
+ switch (display) {
+ case DISPLAY_ALL_APPS:
+ return grid.allAppsIconSizePx;
+ case DISPLAY_WORKSPACE:
+ case DISPLAY_FOLDER:
+ default:
+ return grid.iconSizePx;
+ }
}
public void getSourceVisualDragBounds(Rect bounds) {
- getIconBounds(mIconSize, bounds);
+ BubbleTextView.getIconBounds(this, bounds, getIconSizeForDisplay(mDisplay));
}
@Override
@@ -1029,8 +872,8 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver,
}
private void resetIconScale() {
- if (mIcon != null) {
- mIcon.resetScale();
+ if (mIcon instanceof FastBitmapDrawable) {
+ ((FastBitmapDrawable) mIcon).resetScale();
}
}
@@ -1041,29 +884,4 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver,
setCompoundDrawables(null, newIcon, null, null);
}
}
-
- private String getAppLabelPluralString(String appName, int notificationCount) {
- MessageFormat icuCountFormat = new MessageFormat(
- getResources().getString(R.string.dotted_app_label),
- Locale.getDefault());
- HashMap<String, Object> args = new HashMap();
- args.put("app_name", appName);
- args.put("count", notificationCount);
- return icuCountFormat.format(args);
- }
-
- /**
- * Starts a long press action and returns the corresponding pre-drag condition
- */
- public PreDragCondition startLongPressAction() {
- PopupContainerWithArrow popup = PopupContainerWithArrow.showForIcon(this);
- return popup != null ? popup.createPreDragCondition(true) : null;
- }
-
- /**
- * Returns true if the view can show long-press popup
- */
- public boolean canShowLongPressPopup() {
- return getTag() instanceof ItemInfo && ShortcutUtil.supportsShortcuts((ItemInfo) getTag());
- }
}
diff --git a/src/com/android/launcher3/ButtonDropTarget.java b/src/com/android/launcher3/ButtonDropTarget.java
index 3b24df2f18..61b5564941 100644
--- a/src/com/android/launcher3/ButtonDropTarget.java
+++ b/src/com/android/launcher3/ButtonDropTarget.java
@@ -24,7 +24,6 @@ import android.content.Context;
import android.content.res.Resources;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
-import android.text.InputType;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.LayoutInflater;
@@ -50,8 +49,6 @@ public abstract class ButtonDropTarget extends TextView
private static final int[] sTempCords = new int[2];
private static final int DRAG_VIEW_DROP_DURATION = 285;
private static final float DRAG_VIEW_HOVER_OVER_OPACITY = 0.65f;
- private static final int MAX_LINES_TEXT_MULTI_LINE = 2;
- private static final int MAX_LINES_TEXT_SINGLE_LINE = 1;
public static final int TOOLTIP_DEFAULT = 0;
public static final int TOOLTIP_LEFT = 1;
@@ -69,14 +66,10 @@ public abstract class ButtonDropTarget extends TextView
private final int mDragDistanceThreshold;
/** The size of the drawable shown in the drop target. */
private final int mDrawableSize;
- /** The padding, in pixels, between the text and drawable. */
- private final int mDrawablePadding;
protected CharSequence mText;
protected Drawable mDrawable;
private boolean mTextVisible = true;
- private boolean mIconVisible = true;
- private boolean mTextMultiLine = true;
private PopupWindow mToolTip;
private int mToolTipLocation;
@@ -92,8 +85,6 @@ public abstract class ButtonDropTarget extends TextView
Resources resources = getResources();
mDragDistanceThreshold = resources.getDimensionPixelSize(R.dimen.drag_distanceThreshold);
mDrawableSize = resources.getDimensionPixelSize(R.dimen.drop_target_text_size);
- mDrawablePadding = resources.getDimensionPixelSize(
- R.dimen.drop_target_button_drawable_padding);
}
@Override
@@ -113,8 +104,9 @@ public abstract class ButtonDropTarget extends TextView
// We do not set the drawable in the xml as that inflates two drawables corresponding to
// drawableLeft and drawableStart.
mDrawable = getContext().getDrawable(resId).mutate();
+ mDrawable.setBounds(0, 0, mDrawableSize, mDrawableSize);
mDrawable.setTintList(getTextColors());
- updateIconVisibility();
+ setCompoundDrawablesRelative(mDrawable, null, null, null);
}
public void setDropTargetBar(DropTargetBar dropTargetBar) {
@@ -144,7 +136,7 @@ public abstract class ButtonDropTarget extends TextView
y = -getMeasuredHeight();
message.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
if (mToolTipLocation == TOOLTIP_LEFT) {
- x = -getMeasuredWidth() - message.getMeasuredWidth() / 2;
+ x = - getMeasuredWidth() - message.getMeasuredWidth() / 2;
} else {
x = getMeasuredWidth() / 2 + message.getMeasuredWidth() / 2;
}
@@ -179,12 +171,7 @@ public abstract class ButtonDropTarget extends TextView
@Override
public void onDragStart(DropTarget.DragObject dragObject, DragOptions options) {
- if (options.isKeyboardDrag) {
- mActive = false;
- } else {
- setupItemInfo(dragObject.dragInfo);
- mActive = supportsDrop(dragObject.dragInfo);
- }
+ mActive = !options.isKeyboardDrag && supportsDrop(dragObject.dragInfo);
setVisibility(mActive ? View.VISIBLE : View.GONE);
mAccessibleDrag = options.isAccessibleDrag;
@@ -196,11 +183,6 @@ public abstract class ButtonDropTarget extends TextView
return supportsDrop(dragObject.dragInfo);
}
- /**
- * Setups button for the specified ItemInfo.
- */
- protected abstract void setupItemInfo(ItemInfo info);
-
protected abstract boolean supportsDrop(ItemInfo info);
public abstract boolean supportsAccessibilityDrop(ItemInfo info, View view);
@@ -229,21 +211,27 @@ public abstract class ButtonDropTarget extends TextView
}
final DragLayer dragLayer = mLauncher.getDragLayer();
final DragView dragView = d.dragView;
+ final Rect from = new Rect();
+ dragLayer.getViewRectRelativeToSelf(d.dragView, from);
+
final Rect to = getIconRect(d);
- final float scale = (float) to.width() / dragView.getMeasuredWidth();
+ final float scale = (float) to.width() / from.width();
+ dragView.disableColorExtraction();
dragView.detachContentView(/* reattachToPreviousParent= */ true);
-
mDropTargetBar.deferOnDragEnd();
Runnable onAnimationEndRunnable = () -> {
completeDrop(d);
mDropTargetBar.onDragEnd();
mLauncher.getStateManager().goToState(NORMAL);
+ // Only re-enable updates once the workspace is back to normal, which will be after the
+ // current frame.
+ post(dragView::resumeColorExtraction);
};
- dragLayer.animateView(d.dragView, to, scale, 0.1f, 0.1f,
+ dragLayer.animateView(d.dragView, from, to, scale, 1f, 1f, 0.1f, 0.1f,
DRAG_VIEW_DROP_DURATION,
- Interpolators.DEACCEL_2, onAnimationEndRunnable,
+ Interpolators.DEACCEL_2, Interpolators.LINEAR, onAnimationEndRunnable,
DragLayer.ANIMATION_END_DISAPPEAR, null);
}
@@ -292,7 +280,7 @@ public abstract class ButtonDropTarget extends TextView
}
final int top = to.top + (getMeasuredHeight() - height) / 2;
- final int bottom = top + height;
+ final int bottom = top + height;
to.set(left, top, right, bottom);
@@ -304,12 +292,6 @@ public abstract class ButtonDropTarget extends TextView
return to;
}
- private void centerIcon() {
- int x = mTextVisible ? 0
- : (getWidth() - getPaddingLeft() - getPaddingRight()) / 2 - mDrawableSize / 2;
- mDrawable.setBounds(x, 0, x + mDrawableSize, mDrawableSize);
- }
-
@Override
public void onClick(View v) {
mLauncher.getAccessibilityDelegate().handleAccessibleDrop(this, null, null);
@@ -320,55 +302,10 @@ public abstract class ButtonDropTarget extends TextView
if (mTextVisible != isVisible || !TextUtils.equals(newText, getText())) {
mTextVisible = isVisible;
setText(newText);
- updateIconVisibility();
+ setCompoundDrawablesRelative(mDrawable, null, null, null);
}
}
- /**
- * Display button text over multiple lines when isMultiLine is true, single line otherwise.
- */
- public void setTextMultiLine(boolean isMultiLine) {
- if (mTextMultiLine != isMultiLine) {
- mTextMultiLine = isMultiLine;
- setSingleLine(!isMultiLine);
- setMaxLines(isMultiLine ? MAX_LINES_TEXT_MULTI_LINE : MAX_LINES_TEXT_SINGLE_LINE);
- int inputType = InputType.TYPE_CLASS_TEXT;
- if (isMultiLine) {
- inputType |= InputType.TYPE_TEXT_FLAG_MULTI_LINE;
-
- }
- setInputType(inputType);
- }
- }
-
- protected boolean isTextMultiLine() {
- return mTextMultiLine;
- }
-
- /**
- * Sets the button icon visible when isVisible is true, hides it otherwise.
- */
- public void setIconVisible(boolean isVisible) {
- if (mIconVisible != isVisible) {
- mIconVisible = isVisible;
- updateIconVisibility();
- }
- }
-
- private void updateIconVisibility() {
- if (mIconVisible) {
- centerIcon();
- }
- setCompoundDrawablesRelative(mIconVisible ? mDrawable : null, null, null, null);
- setCompoundDrawablePadding(mIconVisible && mTextVisible ? mDrawablePadding : 0);
- }
-
- @Override
- protected void onSizeChanged(int w, int h, int oldw, int oldh) {
- super.onSizeChanged(w, h, oldw, oldh);
- centerIcon();
- }
-
public void setToolTipLocation(int location) {
mToolTipLocation = location;
hideTooltip();
diff --git a/src/com/android/launcher3/CellLayout.java b/src/com/android/launcher3/CellLayout.java
index 300e7bfb11..a6adfc4bf6 100644
--- a/src/com/android/launcher3/CellLayout.java
+++ b/src/com/android/launcher3/CellLayout.java
@@ -18,9 +18,8 @@ package com.android.launcher3;
import static android.animation.ValueAnimator.areAnimatorsEnabled;
+import static com.android.launcher3.Utilities.getBoundsForViewInDragLayer;
import static com.android.launcher3.anim.Interpolators.DEACCEL_1_5;
-import static com.android.launcher3.dragndrop.DraggableView.DRAGGABLE_ICON;
-import static com.android.launcher3.icons.IconNormalizer.ICON_VISIBLE_AREA_FACTOR;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
@@ -39,6 +38,7 @@ import android.graphics.Point;
import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.RectF;
+import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.os.Parcelable;
import android.util.ArrayMap;
@@ -62,10 +62,8 @@ import com.android.launcher3.LauncherSettings.Favorites;
import com.android.launcher3.accessibility.DragAndDropAccessibilityDelegate;
import com.android.launcher3.anim.Interpolators;
import com.android.launcher3.config.FeatureFlags;
-import com.android.launcher3.dragndrop.DraggableView;
import com.android.launcher3.folder.PreviewBackground;
import com.android.launcher3.model.data.ItemInfo;
-import com.android.launcher3.model.data.LauncherAppWidgetInfo;
import com.android.launcher3.util.CellAndSpan;
import com.android.launcher3.util.GridOccupancy;
import com.android.launcher3.util.ParcelableSparseArray;
@@ -94,7 +92,7 @@ public class CellLayout extends ViewGroup {
private int mFixedCellWidth;
private int mFixedCellHeight;
@ViewDebug.ExportedProperty(category = "launcher")
- private Point mBorderSpace;
+ private final int mBorderSpacing;
@ViewDebug.ExportedProperty(category = "launcher")
private int mCountX;
@@ -149,6 +147,7 @@ public class CellLayout extends ViewGroup {
private boolean mVisualizeDropLocation = true;
private RectF mVisualizeGridRect = new RectF();
private Paint mVisualizeGridPaint = new Paint();
+ private int mGridVisualizationPadding;
private int mGridVisualizationRoundingRadius;
private float mGridAlpha = 0f;
private int mGridColor = 0;
@@ -238,7 +237,12 @@ public class CellLayout extends ViewGroup {
mActivity = ActivityContext.lookupContext(context);
DeviceProfile deviceProfile = mActivity.getDeviceProfile();
- resetCellSizeInternal(deviceProfile);
+ mBorderSpacing = mContainerType == FOLDER
+ ? deviceProfile.folderCellLayoutBorderSpacingPx
+ : deviceProfile.cellLayoutBorderSpacingPx;
+
+ mCellWidth = mCellHeight = -1;
+ mFixedCellWidth = mFixedCellHeight = -1;
mCountX = deviceProfile.inv.numColumns;
mCountY = deviceProfile.inv.numRows;
@@ -260,6 +264,8 @@ public class CellLayout extends ViewGroup {
mBackground.setAlpha(0);
mGridColor = Themes.getAttrColor(getContext(), R.attr.workspaceAccentColor);
+ mGridVisualizationPadding =
+ res.getDimensionPixelSize(R.dimen.grid_visualization_cell_spacing);
mGridVisualizationRoundingRadius =
res.getDimensionPixelSize(R.dimen.grid_visualization_rounding_radius);
mReorderPreviewAnimationMagnitude = (REORDER_PREVIEW_MAGNITUDE * deviceProfile.iconSizePx);
@@ -285,7 +291,7 @@ public class CellLayout extends ViewGroup {
for (int i = 0; i < mDragOutlineAnims.length; i++) {
final InterruptibleInOutAnimator anim =
- new InterruptibleInOutAnimator(duration, fromAlphaValue, toAlphaValue);
+ new InterruptibleInOutAnimator(duration, fromAlphaValue, toAlphaValue);
anim.getAnimator().setInterpolator(mEaseOutInterpolator);
final int thisIndex = i;
anim.getAnimator().addUpdateListener(new AnimatorUpdateListener() {
@@ -303,7 +309,7 @@ public class CellLayout extends ViewGroup {
mShortcutsAndWidgets = new ShortcutAndWidgetContainer(context, mContainerType);
mShortcutsAndWidgets.setCellDimensions(mCellWidth, mCellHeight, mCountX, mCountY,
- mBorderSpace);
+ mBorderSpacing);
addView(mShortcutsAndWidgets);
}
@@ -359,44 +365,11 @@ public class CellLayout extends ViewGroup {
return mShortcutsAndWidgets.getLayerType() == LAYER_TYPE_HARDWARE;
}
- /**
- * Change sizes of cells
- *
- * @param width the new width of the cells
- * @param height the new height of the cells
- */
public void setCellDimensions(int width, int height) {
mFixedCellWidth = mCellWidth = width;
mFixedCellHeight = mCellHeight = height;
mShortcutsAndWidgets.setCellDimensions(mCellWidth, mCellHeight, mCountX, mCountY,
- mBorderSpace);
- }
-
- private void resetCellSizeInternal(DeviceProfile deviceProfile) {
- switch (mContainerType) {
- case FOLDER:
- mBorderSpace = new Point(deviceProfile.folderCellLayoutBorderSpacePx);
- break;
- case HOTSEAT:
- mBorderSpace = new Point(deviceProfile.hotseatBorderSpace,
- deviceProfile.hotseatBorderSpace);
- break;
- case WORKSPACE:
- default:
- mBorderSpace = new Point(deviceProfile.cellLayoutBorderSpacePx);
- break;
- }
-
- mCellWidth = mCellHeight = -1;
- mFixedCellWidth = mFixedCellHeight = -1;
- }
-
- /**
- * Reset the cell sizes and border space
- */
- public void resetCellSize(DeviceProfile deviceProfile) {
- resetCellSizeInternal(deviceProfile);
- requestLayout();
+ mBorderSpacing);
}
public void setGridSize(int x, int y) {
@@ -406,7 +379,7 @@ public class CellLayout extends ViewGroup {
mTmpOccupied = new GridOccupancy(mCountX, mCountY);
mTempRectStack.clear();
mShortcutsAndWidgets.setCellDimensions(mCellWidth, mCellHeight, mCountX, mCountY,
- mBorderSpace);
+ mBorderSpacing);
requestLayout();
}
@@ -470,43 +443,18 @@ public class CellLayout extends ViewGroup {
}
if (DEBUG_VISUALIZE_OCCUPIED) {
- Rect cellBounds = new Rect();
- // Will contain the bounds of the cell including spacing between cells.
- Rect cellBoundsWithSpacing = new Rect();
- int[] targetCell = new int[2];
- int[] cellCenter = new int[2];
- Paint debugPaint = new Paint();
- debugPaint.setStrokeWidth(Utilities.dpToPx(1));
- for (int x = 0; x < mCountX; x++) {
- for (int y = 0; y < mCountY; y++) {
- if (!mOccupied.cells[x][y]) {
- continue;
- }
- targetCell[0] = x;
- targetCell[1] = y;
-
- boolean canCreateFolder = canCreateFolder(getChildAt(x, y));
- cellToRect(x, y, 1, 1, cellBounds);
- cellBoundsWithSpacing.set(cellBounds);
- cellBoundsWithSpacing.inset(-mBorderSpace.x / 2, -mBorderSpace.y / 2);
- getWorkspaceCellVisualCenter(x, y, cellCenter);
-
- canvas.save();
- canvas.clipRect(cellBoundsWithSpacing);
-
- // Draw reorder drag target.
- debugPaint.setColor(Color.RED);
- canvas.drawCircle(cellCenter[0], cellCenter[1], getReorderRadius(targetCell),
- debugPaint);
-
- // Draw folder creation drag target.
- if (canCreateFolder) {
- debugPaint.setColor(Color.GREEN);
- canvas.drawCircle(cellCenter[0], cellCenter[1],
- getFolderCreationRadius(targetCell), debugPaint);
+ int[] pt = new int[2];
+ ColorDrawable cd = new ColorDrawable(Color.RED);
+ cd.setBounds(0, 0, mCellWidth, mCellHeight);
+ for (int i = 0; i < mCountX; i++) {
+ for (int j = 0; j < mCountY; j++) {
+ if (mOccupied.cells[i][j]) {
+ cellToPoint(i, j, pt);
+ canvas.save();
+ canvas.translate(pt[0], pt[1]);
+ cd.draw(canvas);
+ canvas.restore();
}
-
- canvas.restore();
}
}
}
@@ -535,14 +483,6 @@ public class CellLayout extends ViewGroup {
}
/**
- * Returns whether dropping an icon on the given View can create (or add to) a folder.
- */
- private boolean canCreateFolder(View child) {
- return child instanceof DraggableView
- && ((DraggableView) child).getViewType() == DRAGGABLE_ICON;
- }
-
- /**
* Indicates the progress of the Workspace entering the SpringLoaded state; allows the
* CellLayout to update various visuals for this state.
*
@@ -589,8 +529,8 @@ public class CellLayout extends ViewGroup {
protected void visualizeGrid(Canvas canvas) {
DeviceProfile dp = mActivity.getDeviceProfile();
- int paddingX = Math.min((mCellWidth - dp.iconSizePx) / 2, dp.gridVisualizationPaddingX);
- int paddingY = Math.min((mCellHeight - dp.iconSizePx) / 2, dp.gridVisualizationPaddingY);
+ int paddingX = (int) Math.min((mCellWidth - dp.iconSizePx) / 2, mGridVisualizationPadding);
+ int paddingY = (int) Math.min((mCellHeight - dp.iconSizePx) / 2, mGridVisualizationPadding);
mVisualizeGridRect.set(paddingX, paddingY,
mCellWidth - paddingX,
mCellHeight - paddingY);
@@ -602,9 +542,9 @@ public class CellLayout extends ViewGroup {
if (mVisualizeCells) {
for (int i = 0; i < mCountX; i++) {
for (int j = 0; j < mCountY; j++) {
- int transX = i * mCellWidth + (i * mBorderSpace.x) + getPaddingLeft()
+ int transX = i * mCellWidth + (i * mBorderSpacing) + getPaddingLeft()
+ paddingX;
- int transY = j * mCellHeight + (j * mBorderSpace.y) + getPaddingTop()
+ int transY = j * mCellHeight + (j * mBorderSpacing) + getPaddingTop()
+ paddingY;
mVisualizeGridRect.offsetTo(transX, transY);
@@ -628,12 +568,12 @@ public class CellLayout extends ViewGroup {
// TODO b/194414754 clean this up, reconcile with cellToRect
mVisualizeGridRect.set(paddingX, paddingY,
- mCellWidth * spanX + mBorderSpace.x * (spanX - 1) - paddingX,
- mCellHeight * spanY + mBorderSpace.y * (spanY - 1) - paddingY);
+ mCellWidth * spanX + mBorderSpacing * (spanX - 1) - paddingX,
+ mCellHeight * spanY + mBorderSpacing * (spanY - 1) - paddingY);
- int transX = x * mCellWidth + (x * mBorderSpace.x)
+ int transX = x * mCellWidth + (x * mBorderSpacing)
+ getPaddingLeft() + paddingX;
- int transY = y * mCellHeight + (y * mBorderSpace.y)
+ int transY = y * mCellHeight + (y * mBorderSpacing)
+ getPaddingTop() + paddingY;
mVisualizeGridRect.offsetTo(transX, transY);
@@ -878,7 +818,7 @@ public class CellLayout extends ViewGroup {
}
/**
- * Given a cell coordinate and span return the point that represents the center of the region
+ * Given a cell coordinate and span return the point that represents the center of the regio
*
* @param cellX X coordinate of the cell
* @param cellY Y coordinate of the cell
@@ -891,65 +831,11 @@ public class CellLayout extends ViewGroup {
result[1] = mTempRect.centerY();
}
- /**
- * Returns the distance between the given coordinate and the visual center of the given cell.
- */
- public float getDistanceFromWorkspaceCellVisualCenter(float x, float y, int[] cell) {
- getWorkspaceCellVisualCenter(cell[0], cell[1], mTmpPoint);
+ public float getDistanceFromCell(float x, float y, int[] cell) {
+ cellToCenterPoint(cell[0], cell[1], mTmpPoint);
return (float) Math.hypot(x - mTmpPoint[0], y - mTmpPoint[1]);
}
- private void getWorkspaceCellVisualCenter(int cellX, int cellY, int[] outPoint) {
- View child = getChildAt(cellX, cellY);
- if (child instanceof DraggableView) {
- DraggableView draggableChild = (DraggableView) child;
- if (draggableChild.getViewType() == DRAGGABLE_ICON) {
- cellToPoint(cellX, cellY, outPoint);
- draggableChild.getWorkspaceVisualDragBounds(mTempRect);
- mTempRect.offset(outPoint[0], outPoint[1]);
- outPoint[0] = mTempRect.centerX();
- outPoint[1] = mTempRect.centerY();
- return;
- }
- }
- cellToCenterPoint(cellX, cellY, outPoint);
- }
-
- /**
- * Returns the max distance from the center of a cell that can accept a drop to create a folder.
- */
- public float getFolderCreationRadius(int[] targetCell) {
- DeviceProfile grid = mActivity.getDeviceProfile();
- float iconVisibleRadius = ICON_VISIBLE_AREA_FACTOR * grid.iconSizePx / 2;
- // Halfway between reorder radius and icon.
- return (getReorderRadius(targetCell) + iconVisibleRadius) / 2;
- }
-
- /**
- * Returns the max distance from the center of a cell that will start to reorder on drag over.
- */
- public float getReorderRadius(int[] targetCell) {
- int[] centerPoint = mTmpPoint;
- getWorkspaceCellVisualCenter(targetCell[0], targetCell[1], centerPoint);
-
- Rect cellBoundsWithSpacing = mTempRect;
- cellToRect(targetCell[0], targetCell[1], 1, 1, cellBoundsWithSpacing);
- cellBoundsWithSpacing.inset(-mBorderSpace.x / 2, -mBorderSpace.y / 2);
-
- if (canCreateFolder(getChildAt(targetCell[0], targetCell[1]))) {
- // Take only the circle in the smaller dimension, to ensure we don't start reordering
- // too soon before accepting a folder drop.
- int minRadius = centerPoint[0] - cellBoundsWithSpacing.left;
- minRadius = Math.min(minRadius, centerPoint[1] - cellBoundsWithSpacing.top);
- minRadius = Math.min(minRadius, cellBoundsWithSpacing.right - centerPoint[0]);
- minRadius = Math.min(minRadius, cellBoundsWithSpacing.bottom - centerPoint[1]);
- return minRadius;
- }
- // Take up the entire cell, including space between this cell and the adjacent ones.
- return (float) Math.hypot(cellBoundsWithSpacing.width() / 2f,
- cellBoundsWithSpacing.height() / 2f);
- }
-
public int getCellWidth() {
return mCellWidth;
}
@@ -973,15 +859,15 @@ public class CellLayout extends ViewGroup {
int childHeightSize = heightSize - (getPaddingTop() + getPaddingBottom());
if (mFixedCellWidth < 0 || mFixedCellHeight < 0) {
- int cw = DeviceProfile.calculateCellWidth(childWidthSize, mBorderSpace.x,
+ int cw = DeviceProfile.calculateCellWidth(childWidthSize, mBorderSpacing,
mCountX);
- int ch = DeviceProfile.calculateCellHeight(childHeightSize, mBorderSpace.y,
+ int ch = DeviceProfile.calculateCellHeight(childHeightSize, mBorderSpacing,
mCountY);
if (cw != mCellWidth || ch != mCellHeight) {
mCellWidth = cw;
mCellHeight = ch;
mShortcutsAndWidgets.setCellDimensions(mCellWidth, mCellHeight, mCountX, mCountY,
- mBorderSpace);
+ mBorderSpacing);
}
}
@@ -1035,7 +921,7 @@ public class CellLayout extends ViewGroup {
*/
public int getUnusedHorizontalSpace() {
return getMeasuredWidth() - getPaddingLeft() - getPaddingRight() - (mCountX * mCellWidth)
- - ((mCountX - 1) * mBorderSpace.x);
+ - ((mCountX - 1) * mBorderSpacing);
}
@Override
@@ -1185,10 +1071,18 @@ public class CellLayout extends ViewGroup {
// Apply local extracted color if the DragView is an AppWidgetHostViewDrawable.
View view = dragObject.dragView.getContentView();
if (view instanceof LauncherAppWidgetHostView) {
- int screenId = getWorkspace().getIdForScreen(this);
+ Launcher launcher = Launcher.getLauncher(dragObject.dragView.getContext());
+ Workspace workspace = launcher.getWorkspace();
+ int screenId = workspace.getIdForScreen(this);
+ int pageId = workspace.getPageIndexForScreenId(screenId);
cellToRect(targetCell[0], targetCell[1], spanX, spanY, mTempRect);
- ((LauncherAppWidgetHostView) view).handleDrag(mTempRect, this, screenId);
+ // Now get the rect in drag layer coordinates.
+ getBoundsForViewInDragLayer(launcher.getDragLayer(), this, mTempRect, true,
+ mTmpFloatArray, mTempRectF);
+ Utilities.setRect(mTempRectF, mTempRect);
+
+ ((LauncherAppWidgetHostView) view).handleDrag(mTempRect, pageId);
}
}
@@ -1198,24 +1092,11 @@ public class CellLayout extends ViewGroup {
return getContext().getString(R.string.move_to_hotseat_position,
Math.max(cellX, cellY) + 1);
} else {
- Workspace<?> workspace = getWorkspace();
- int row = cellY + 1;
- int col = workspace.mIsRtl ? mCountX - cellX : cellX + 1;
- int panelCount = workspace.getPanelCount();
- if (panelCount > 1) {
- // Increment the column if the target is on the right side of a two panel home
- int screenId = workspace.getIdForScreen(this);
- int pageIndex = workspace.getPageIndexForScreenId(screenId);
- col += (pageIndex % panelCount) * mCountX;
- }
- return getContext().getString(R.string.move_to_empty_cell, row, col);
+ return getContext().getString(R.string.move_to_empty_cell,
+ cellY + 1, cellX + 1);
}
}
- private Workspace<?> getWorkspace() {
- return Launcher.cast(mActivity).getWorkspace();
- }
-
public void clearDragOutlines() {
final int oldIndex = mDragOutlineCurrent;
mDragOutlineAnims[oldIndex].animateOut();
@@ -2267,10 +2148,10 @@ public class CellLayout extends ViewGroup {
mShakeAnimators.clear();
}
- private void commitTempPlacement(View dragView) {
+ private void commitTempPlacement() {
mTmpOccupied.copyTo(mOccupied);
- int screenId = getWorkspace().getIdForScreen(this);
+ int screenId = Launcher.cast(mActivity).getWorkspace().getIdForScreen(this);
int container = Favorites.CONTAINER_DESKTOP;
if (mContainerType == HOTSEAT) {
@@ -2285,7 +2166,7 @@ public class CellLayout extends ViewGroup {
ItemInfo info = (ItemInfo) child.getTag();
// We do a null check here because the item info can be null in the case of the
// AllApps button in the hotseat.
- if (info != null && child != dragView) {
+ if (info != null) {
final boolean requiresDbUpdate = (info.cellX != lp.tmpCellX
|| info.cellY != lp.tmpCellY || info.spanX != lp.cellHSpan
|| info.spanY != lp.cellVSpan);
@@ -2435,7 +2316,7 @@ public class CellLayout extends ViewGroup {
// First we determine if things have moved enough to cause a different layout
ItemConfiguration swapSolution = findReorderSolution(pixelXY[0], pixelXY[1], spanX, spanY,
- spanX, spanY, direction, dragView, true, new ItemConfiguration());
+ spanX, spanY, direction, dragView, true, new ItemConfiguration());
setUseTempCoords(true);
if (swapSolution != null && swapSolution.isSolution) {
@@ -2447,7 +2328,7 @@ public class CellLayout extends ViewGroup {
animateItemsToSolution(swapSolution, dragView, commit);
if (commit) {
- commitTempPlacement(null);
+ commitTempPlacement();
completeAndClearReorderPreviewAnimations();
setItemPlacementDirty(false);
} else {
@@ -2472,7 +2353,7 @@ public class CellLayout extends ViewGroup {
// direction vector, since we want the solution to match the preview, and it's possible
// that the exact position of the item has changed to result in a new reordering outcome.
if ((mode == MODE_ON_DROP || mode == MODE_ON_DROP_EXTERNAL || mode == MODE_ACCEPT_DROP)
- && mPreviousReorderDirection[0] != INVALID_DIRECTION) {
+ && mPreviousReorderDirection[0] != INVALID_DIRECTION) {
mDirectionVector[0] = mPreviousReorderDirection[0];
mDirectionVector[1] = mPreviousReorderDirection[1];
// We reset this vector after drop
@@ -2488,7 +2369,7 @@ public class CellLayout extends ViewGroup {
// Find a solution involving pushing / displacing any items in the way
ItemConfiguration swapSolution = findReorderSolution(pixelX, pixelY, minSpanX, minSpanY,
- spanX, spanY, mDirectionVector, dragView, true, new ItemConfiguration());
+ spanX, spanY, mDirectionVector, dragView, true, new ItemConfiguration());
// We attempt the approach which doesn't shuffle views at all
ItemConfiguration noShuffleSolution = findConfigurationNoShuffle(pixelX, pixelY, minSpanX,
@@ -2541,8 +2422,7 @@ public class CellLayout extends ViewGroup {
if (!DESTRUCTIVE_REORDER &&
(mode == MODE_ON_DROP || mode == MODE_ON_DROP_EXTERNAL)) {
- // Since the temp solution didn't update dragView, don't commit it either
- commitTempPlacement(dragView);
+ commitTempPlacement();
completeAndClearReorderPreviewAnimations();
setItemPlacementDirty(false);
} else {
@@ -2718,34 +2598,22 @@ public class CellLayout extends ViewGroup {
+ (int) Math.ceil(getUnusedHorizontalSpace() / 2f);
final int vStartPadding = getPaddingTop();
- int x = hStartPadding + (cellX * mBorderSpace.x) + (cellX * cellWidth);
- int y = vStartPadding + (cellY * mBorderSpace.y) + (cellY * cellHeight);
+ int x = hStartPadding + (cellX * mBorderSpacing) + (cellX * cellWidth);
+ int y = vStartPadding + (cellY * mBorderSpacing) + (cellY * cellHeight);
- int width = cellHSpan * cellWidth + ((cellHSpan - 1) * mBorderSpace.x);
- int height = cellVSpan * cellHeight + ((cellVSpan - 1) * mBorderSpace.y);
+ int width = cellHSpan * cellWidth + ((cellHSpan - 1) * mBorderSpacing);
+ int height = cellVSpan * cellHeight + ((cellVSpan - 1) * mBorderSpacing);
resultRect.set(x, y, x + width, y + height);
}
public void markCellsAsOccupiedForView(View view) {
- if (view instanceof LauncherAppWidgetHostView
- && view.getTag() instanceof LauncherAppWidgetInfo) {
- LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) view.getTag();
- mOccupied.markCells(info.cellX, info.cellY, info.spanX, info.spanY, true);
- return;
- }
if (view == null || view.getParent() != mShortcutsAndWidgets) return;
LayoutParams lp = (LayoutParams) view.getLayoutParams();
mOccupied.markCells(lp.cellX, lp.cellY, lp.cellHSpan, lp.cellVSpan, true);
}
public void markCellsAsUnoccupiedForView(View view) {
- if (view instanceof LauncherAppWidgetHostView
- && view.getTag() instanceof LauncherAppWidgetInfo) {
- LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) view.getTag();
- mOccupied.markCells(info.cellX, info.cellY, info.spanX, info.spanY, false);
- return;
- }
if (view == null || view.getParent() != mShortcutsAndWidgets) return;
LayoutParams lp = (LayoutParams) view.getLayoutParams();
mOccupied.markCells(lp.cellX, lp.cellY, lp.cellHSpan, lp.cellVSpan, false);
@@ -2753,12 +2621,12 @@ public class CellLayout extends ViewGroup {
public int getDesiredWidth() {
return getPaddingLeft() + getPaddingRight() + (mCountX * mCellWidth)
- + ((mCountX - 1) * mBorderSpace.x);
+ + ((mCountX - 1) * mBorderSpacing);
}
public int getDesiredHeight() {
return getPaddingTop() + getPaddingBottom() + (mCountY * mCellHeight)
- + ((mCountY - 1) * mBorderSpace.y);
+ + ((mCountY - 1) * mBorderSpacing);
}
public boolean isOccupied(int x, int y) {
@@ -2874,20 +2742,20 @@ public class CellLayout extends ViewGroup {
}
public void setup(int cellWidth, int cellHeight, boolean invertHorizontally, int colCount,
- int rowCount, Point borderSpace, @Nullable Rect inset) {
+ int rowCount, int borderSpacing, @Nullable Rect inset) {
setup(cellWidth, cellHeight, invertHorizontally, colCount, rowCount, 1.0f, 1.0f,
- borderSpace, inset);
+ borderSpacing, inset);
}
/**
- * Use this method, as opposed to {@link #setup(int, int, boolean, int, int, Point, Rect)},
+ * Use this method, as opposed to {@link #setup(int, int, boolean, int, int, int, Rect)},
* if the view needs to be scaled.
*
* ie. In multi-window mode, we setup widgets so that they are measured and laid out
* using their full/invariant device profile sizes.
*/
public void setup(int cellWidth, int cellHeight, boolean invertHorizontally, int colCount,
- int rowCount, float cellScaleX, float cellScaleY, Point borderSpace,
+ int rowCount, float cellScaleX, float cellScaleY, int borderSpacing,
@Nullable Rect inset) {
if (isLockedToGrid) {
final int myCellHSpan = cellHSpan;
@@ -2899,16 +2767,16 @@ public class CellLayout extends ViewGroup {
myCellX = colCount - myCellX - cellHSpan;
}
- int hBorderSpacing = (myCellHSpan - 1) * borderSpace.x;
- int vBorderSpacing = (myCellVSpan - 1) * borderSpace.y;
+ int hBorderSpacing = (myCellHSpan - 1) * borderSpacing;
+ int vBorderSpacing = (myCellVSpan - 1) * borderSpacing;
float myCellWidth = ((myCellHSpan * cellWidth) + hBorderSpacing) / cellScaleX;
float myCellHeight = ((myCellVSpan * cellHeight) + vBorderSpacing) / cellScaleY;
width = Math.round(myCellWidth) - leftMargin - rightMargin;
height = Math.round(myCellHeight) - topMargin - bottomMargin;
- x = leftMargin + (myCellX * cellWidth) + (myCellX * borderSpace.x);
- y = topMargin + (myCellY * cellHeight) + (myCellY * borderSpace.y);
+ x = leftMargin + (myCellX * cellWidth) + (myCellX * borderSpacing);
+ y = topMargin + (myCellY * cellHeight) + (myCellY * borderSpacing);
if (inset != null) {
x -= inset.left;
@@ -3010,7 +2878,7 @@ public class CellLayout extends ViewGroup {
directionVector, null, false, configuration).isSolution) {
if (commitConfig) {
copySolutionToTempState(configuration, null);
- commitTempPlacement(null);
+ commitTempPlacement();
// undo marking cells occupied since there is actually nothing being placed yet.
mOccupied.markCells(0, mCountY - 1, mCountX, 1, false);
}
diff --git a/src/com/android/launcher3/DefaultLayoutParser.java b/src/com/android/launcher3/DefaultLayoutParser.java
index 4daca8b109..af85594779 100644
--- a/src/com/android/launcher3/DefaultLayoutParser.java
+++ b/src/com/android/launcher3/DefaultLayoutParser.java
@@ -7,19 +7,15 @@ import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
-import android.content.pm.LauncherApps;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.res.Resources;
import android.os.Bundle;
-import android.os.Process;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.Log;
import com.android.launcher3.LauncherSettings.Favorites;
-import com.android.launcher3.model.data.WorkspaceItemInfo;
-import com.android.launcher3.shortcuts.ShortcutKey;
import com.android.launcher3.util.Thunk;
import org.xmlpull.v1.XmlPullParser;
@@ -27,7 +23,6 @@ import org.xmlpull.v1.XmlPullParserException;
import java.io.IOException;
import java.net.URISyntaxException;
-import java.util.Collections;
import java.util.List;
/**
@@ -48,8 +43,6 @@ public class DefaultLayoutParser extends AutoInstallsLayout {
private static final String ATTR_CONTAINER = "container";
private static final String ATTR_SCREEN = "screen";
private static final String ATTR_FOLDER_ITEMS = "folderItems";
- private static final String ATTR_SHORTCUT_ID = "shortcutId";
- private static final String ATTR_PACKAGE_NAME = "packageName";
// TODO: Remove support for this broadcast, instead use widget options to send bind time options
private static final String ACTION_APPWIDGET_DEFAULT_WORKSPACE_CONFIGURE =
@@ -185,6 +178,7 @@ public class DefaultLayoutParser extends AutoInstallsLayout {
}
}
+
/**
* Shortcut parser which allows any uri and not just web urls.
*/
@@ -195,35 +189,6 @@ public class DefaultLayoutParser extends AutoInstallsLayout {
}
@Override
- public int parseAndAdd(XmlPullParser parser) {
- final String packageName = getAttributeValue(parser, ATTR_PACKAGE_NAME);
- final String shortcutId = getAttributeValue(parser, ATTR_SHORTCUT_ID);
- if (!TextUtils.isEmpty(packageName) && !TextUtils.isEmpty(shortcutId)) {
- return parseAndAddDeepShortcut(shortcutId, packageName);
- }
- return super.parseAndAdd(parser);
- }
-
- /**
- * This method parses and adds a deep shortcut.
- * @return item id if the shortcut is successfully added else -1
- */
- private int parseAndAddDeepShortcut(String shortcutId, String packageName) {
- try {
- LauncherApps launcherApps = mContext.getSystemService(LauncherApps.class);
- launcherApps.pinShortcuts(packageName, Collections.singletonList(shortcutId),
- Process.myUserHandle());
- Intent intent = ShortcutKey.makeIntent(shortcutId, packageName);
- mValues.put(Favorites.RESTORED, WorkspaceItemInfo.FLAG_RESTORED_ICON);
- return addShortcut(null, intent, Favorites.ITEM_TYPE_DEEP_SHORTCUT);
- } catch (Exception e) {
- Log.e(TAG, "Unable to pin the shortcut for shortcut id = " + shortcutId
- + " and package name = " + packageName);
- }
- return -1;
- }
-
- @Override
protected Intent parseIntent(XmlPullParser parser) {
String uri = null;
try {
diff --git a/src/com/android/launcher3/DeleteDropTarget.java b/src/com/android/launcher3/DeleteDropTarget.java
index 95d3ad9dbb..80ec19281a 100644
--- a/src/com/android/launcher3/DeleteDropTarget.java
+++ b/src/com/android/launcher3/DeleteDropTarget.java
@@ -25,7 +25,6 @@ import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.View;
-import com.android.launcher3.LauncherSettings.Favorites;
import com.android.launcher3.accessibility.LauncherAccessibilityDelegate;
import com.android.launcher3.dragndrop.DragOptions;
import com.android.launcher3.logging.StatsLogManager;
@@ -34,7 +33,6 @@ import com.android.launcher3.model.data.FolderInfo;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.LauncherAppWidgetInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo;
-import com.android.launcher3.util.IntSet;
import com.android.launcher3.views.Snackbar;
public class DeleteDropTarget extends ButtonDropTarget {
@@ -85,9 +83,6 @@ public class DeleteDropTarget extends ButtonDropTarget {
}
@Override
- protected void setupItemInfo(ItemInfo info) {}
-
- @Override
protected boolean supportsDrop(ItemInfo info) {
return true;
}
@@ -132,21 +127,11 @@ public class DeleteDropTarget extends ButtonDropTarget {
public void completeDrop(DragObject d) {
ItemInfo item = d.dragInfo;
if (canRemove(item)) {
- ItemInfo pageItem = item;
- if (item.container <= 0) {
- View v = mLauncher.getWorkspace().getHomescreenIconByItemId(item.container);
- if (v != null) {
- pageItem = (ItemInfo) v.getTag();
- }
- }
- IntSet pageIds = pageItem.container == Favorites.CONTAINER_DESKTOP
- ? IntSet.wrap(pageItem.screenId)
- : mLauncher.getWorkspace().getCurrentPageScreenIds();
-
+ int itemPage = mLauncher.getWorkspace().getCurrentPage();
onAccessibilityDrop(null, item);
ModelWriter modelWriter = mLauncher.getModelWriter();
Runnable onUndoClicked = () -> {
- mLauncher.setPagesToBindSynchronously(pageIds);
+ mLauncher.setPageToBindSynchronously(itemPage);
modelWriter.abortDelete();
mLauncher.getStatsLogManager().logger().log(LAUNCHER_UNDO);
};
@@ -163,7 +148,7 @@ public class DeleteDropTarget extends ButtonDropTarget {
// Remove the item from launcher and the db, we can ignore the containerInfo in this call
// because we already remove the drag view from the folder (if the drag originated from
// a folder) in Folder.beginDrag()
- mLauncher.removeItem(view, item, true /* deleteFromDb */, "removed by accessibility drop");
+ mLauncher.removeItem(view, item, true /* deleteFromDb */);
mLauncher.getWorkspace().stripEmptyScreens();
mLauncher.getDragLayer()
.announceForAccessibility(getContext().getString(R.string.item_removed));
diff --git a/src/com/android/launcher3/DevicePaddings.java b/src/com/android/launcher3/DevicePaddings.java
index 08fb47b2cf..7c387b1efe 100644
--- a/src/com/android/launcher3/DevicePaddings.java
+++ b/src/com/android/launcher3/DevicePaddings.java
@@ -36,12 +36,12 @@ import java.util.ArrayList;
* The unused or "extra" height is allocated to three different variable heights:
* - The space above the workspace
* - The space between the workspace and hotseat
- * - The space below the hotseat
+ * - The espace below the hotseat
*/
public class DevicePaddings {
- private static final String DEVICE_PADDINGS = "device-paddings";
- private static final String DEVICE_PADDING = "device-padding";
+ private static final String DEVICE_PADDING = "device-paddings";
+ private static final String DEVICE_PADDINGS = "device-padding";
private static final String WORKSPACE_TOP_PADDING = "workspaceTopPadding";
private static final String WORKSPACE_BOTTOM_PADDING = "workspaceBottomPadding";
@@ -58,13 +58,13 @@ public class DevicePaddings {
int type;
while (((type = parser.next()) != XmlPullParser.END_TAG ||
parser.getDepth() > depth) && type != XmlPullParser.END_DOCUMENT) {
- if ((type == XmlPullParser.START_TAG) && DEVICE_PADDINGS.equals(parser.getName())) {
+ if ((type == XmlPullParser.START_TAG) && DEVICE_PADDING.equals(parser.getName())) {
final int displayDepth = parser.getDepth();
while (((type = parser.next()) != XmlPullParser.END_TAG ||
parser.getDepth() > displayDepth)
&& type != XmlPullParser.END_DOCUMENT) {
if ((type == XmlPullParser.START_TAG)
- && DEVICE_PADDING.equals(parser.getName())) {
+ && DEVICE_PADDINGS.equals(parser.getName())) {
TypedArray a = context.obtainStyledAttributes(
Xml.asAttributeSet(parser), R.styleable.DevicePadding);
int maxWidthPx = a.getDimensionPixelSize(
diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java
index b2763977ca..81eda10a15 100644
--- a/src/com/android/launcher3/DeviceProfile.java
+++ b/src/com/android/launcher3/DeviceProfile.java
@@ -16,14 +16,14 @@
package com.android.launcher3;
-import static com.android.launcher3.InvariantDeviceProfile.INDEX_DEFAULT;
-import static com.android.launcher3.InvariantDeviceProfile.INDEX_LANDSCAPE;
-import static com.android.launcher3.InvariantDeviceProfile.INDEX_TWO_PANEL_LANDSCAPE;
-import static com.android.launcher3.InvariantDeviceProfile.INDEX_TWO_PANEL_PORTRAIT;
+import static android.util.DisplayMetrics.DENSITY_DEVICE_STABLE;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
+
import static com.android.launcher3.ResourceUtils.pxFromDp;
import static com.android.launcher3.Utilities.dpiFromPx;
import static com.android.launcher3.Utilities.pxFromSp;
import static com.android.launcher3.folder.ClippedFolderIconLayoutRule.ICON_OVERLAP_FACTOR;
+import static com.android.launcher3.util.WindowManagerCompat.MIN_TABLET_WIDTH;
import android.annotation.SuppressLint;
import android.content.Context;
@@ -33,28 +33,28 @@ import android.graphics.Path;
import android.graphics.Point;
import android.graphics.PointF;
import android.graphics.Rect;
+import android.hardware.display.DisplayManager;
import android.util.DisplayMetrics;
import android.view.Surface;
+import android.view.WindowInsets;
+import android.view.WindowManager;
import com.android.launcher3.CellLayout.ContainerType;
import com.android.launcher3.DevicePaddings.DevicePadding;
+import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.icons.DotRenderer;
import com.android.launcher3.icons.GraphicsUtils;
import com.android.launcher3.icons.IconNormalizer;
-import com.android.launcher3.uioverrides.ApiWrapper;
import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.DisplayController.Info;
import com.android.launcher3.util.WindowBounds;
import java.io.PrintWriter;
-import java.util.List;
@SuppressLint("NewApi")
public class DeviceProfile {
private static final int DEFAULT_DOT_SIZE = 100;
- // Ratio of empty space, qsb should take up to appear visually centered.
- private final float mQsbCenterFactor;
public final InvariantDeviceProfile inv;
private final Info mInfo;
@@ -65,12 +65,11 @@ public class DeviceProfile {
public final boolean isPhone;
public final boolean transposeLayoutWithOrientation;
public final boolean isTwoPanels;
- public final boolean isQsbInline;
+ public final boolean allowRotation;
// Device properties in current orientation
public final boolean isLandscape;
public final boolean isMultiWindowMode;
- public final boolean isGestureMode;
public final int windowX;
public final int windowY;
@@ -78,12 +77,10 @@ public class DeviceProfile {
public final int heightPx;
public final int availableWidthPx;
public final int availableHeightPx;
- public final int rotationHint;
public final float aspectRatio;
public final boolean isScalableGrid;
- private final int mTypeIndex;
/**
* The maximum amount of left/right workspace padding as a percentage of the screen width.
@@ -97,20 +94,19 @@ public class DeviceProfile {
private static final float TALL_DEVICE_EXTRA_SPACE_THRESHOLD_DP = 252;
private static final float TALL_DEVICE_MORE_EXTRA_SPACE_THRESHOLD_DP = 268;
- // Workspace
- public final int desiredWorkspaceHorizontalMarginOriginalPx;
- public int desiredWorkspaceHorizontalMarginPx;
- public int gridVisualizationPaddingX;
- public int gridVisualizationPaddingY;
- public Point cellLayoutBorderSpaceOriginalPx;
- public Point cellLayoutBorderSpacePx;
- public Rect cellLayoutPaddingPx = new Rect();
+ // To evenly space the icons, increase the left/right margins for tablets in portrait mode.
+ private static final int PORTRAIT_TABLET_LEFT_RIGHT_PADDING_MULTIPLIER = 4;
+ // Workspace
+ public final int desiredWorkspaceLeftRightOriginalPx;
+ public int desiredWorkspaceLeftRightMarginPx;
+ public final int cellLayoutBorderSpacingOriginalPx;
+ public int cellLayoutBorderSpacingPx;
+ public final int cellLayoutPaddingLeftRightPx;
+ public final int cellLayoutBottomPaddingPx;
public final int edgeMarginPx;
- public float workspaceSpringLoadShrunkTop;
- public float workspaceSpringLoadShrunkBottom;
+ public float workspaceSpringLoadShrinkFactor;
public final int workspaceSpringLoadedBottomSpace;
- public final int workspaceSpringLoadedMinNextPageVisiblePx;
private final int extraSpace;
public int workspaceTopPadding;
@@ -142,8 +138,7 @@ public class DeviceProfile {
public int folderIconOffsetYPx;
// Folder content
- public Point folderCellLayoutBorderSpacePx;
- public int folderCellLayoutBorderSpaceOriginalPx;
+ public int folderCellLayoutBorderSpacingPx;
public int folderContentPaddingLeftRight;
public int folderContentPaddingTop;
@@ -161,63 +156,40 @@ public class DeviceProfile {
public final int numShownHotseatIcons;
public int hotseatCellHeightPx;
private final int hotseatExtraVerticalSize;
- private final boolean areNavButtonsInline;
// In portrait: size = height, in landscape: size = width
public int hotseatBarSizePx;
public int hotseatBarTopPaddingPx;
public final int hotseatBarBottomPaddingPx;
- public int springLoadedHotseatBarTopMarginPx;
// Start is the side next to the nav bar, end is the side next to the workspace
public final int hotseatBarSidePaddingStartPx;
public final int hotseatBarSidePaddingEndPx;
- public final int hotseatQsbHeight;
- public int hotseatBorderSpace;
public final float qsbBottomMarginOriginalPx;
public int qsbBottomMarginPx;
- public int qsbWidth; // only used when isQsbInline
// All apps
- public Point allAppsBorderSpacePx;
- public int allAppsShiftRange;
- public int allAppsTopPadding;
- public int bottomSheetTopPadding;
+ public int allAppsOpenVerticalTranslate;
public int allAppsCellHeightPx;
public int allAppsCellWidthPx;
public int allAppsIconSizePx;
public int allAppsIconDrawablePaddingPx;
- public int allAppsLeftRightPadding;
- public int allAppsLeftRightMargin;
public final int numShownAllAppsColumns;
public float allAppsIconTextSizePx;
// Overview
public int overviewTaskMarginPx;
- public int overviewTaskMarginGridPx;
public int overviewTaskIconSizePx;
- public int overviewTaskIconDrawableSizePx;
- public int overviewTaskIconDrawableSizeGridPx;
public int overviewTaskThumbnailTopMarginPx;
- public final int overviewActionsHeight;
- public final int overviewActionsTopMarginPx;
- public final int overviewActionsButtonSpacing;
- public int overviewPageSpacing;
- public int overviewRowSpacing;
- public int overviewGridSideMargin;
+ public final int overviewActionsMarginThreeButtonPx;
+ public final int overviewActionsMarginGesturePx;
// Widgets
public final PointF appWidgetScale = new PointF(1.0f, 1.0f);
// Drop Target
public int dropTargetBarSizePx;
- public int dropTargetBarTopMarginPx;
- public int dropTargetBarBottomMarginPx;
public int dropTargetDragPaddingPx;
public int dropTargetTextSizePx;
- public int dropTargetHorizontalPaddingPx;
- public int dropTargetVerticalPaddingPx;
- public int dropTargetGapPx;
- public int dropTargetButtonWorkspaceEdgeGapPx;
// Insets
private final Rect mInsets = new Rect();
@@ -230,106 +202,109 @@ public class DeviceProfile {
public DotRenderer mDotRendererWorkSpace;
public DotRenderer mDotRendererAllApps;
- // Taskbar
+ // Taskbar
public boolean isTaskbarPresent;
- // Whether Taskbar will inset the bottom of apps by taskbarSize.
- public boolean isTaskbarPresentInApps;
public int taskbarSize;
- public int stashedTaskbarSize;
+ // How much of the bottom inset is due to Taskbar rather than other system elements.
+ public int nonOverlappingTaskbarInset;
// DragController
public int flingToDeleteThresholdVelocity;
- /** TODO: Once we fully migrate to staged split, remove "isMultiWindowMode" */
DeviceProfile(Context context, InvariantDeviceProfile inv, Info info, WindowBounds windowBounds,
boolean isMultiWindowMode, boolean transposeLayoutWithOrientation,
- boolean useTwoPanels, boolean isGestureMode) {
+ boolean useTwoPanels) {
this.inv = inv;
this.isLandscape = windowBounds.isLandscape();
this.isMultiWindowMode = isMultiWindowMode;
this.transposeLayoutWithOrientation = transposeLayoutWithOrientation;
- this.isGestureMode = isGestureMode;
windowX = windowBounds.bounds.left;
windowY = windowBounds.bounds.top;
- this.rotationHint = windowBounds.rotationHint;
- mInsets.set(windowBounds.insets);
isScalableGrid = inv.isScalable && !isVerticalBarLayout() && !isMultiWindowMode;
- // Determine device posture.
- mInfo = info;
- isTablet = info.isTablet(windowBounds);
- isPhone = !isTablet;
- isTwoPanels = isTablet && useTwoPanels;
- isTaskbarPresent = isTablet && ApiWrapper.TASKBAR_DRAWN_IN_PROCESS;
-
- // Some more constants.
- context = getContext(context, info, isVerticalBarLayout() || (isTablet && isLandscape)
- ? Configuration.ORIENTATION_LANDSCAPE
- : Configuration.ORIENTATION_PORTRAIT,
- windowBounds);
- final Resources res = context.getResources();
- mMetrics = res.getDisplayMetrics();
// Determine sizes.
widthPx = windowBounds.bounds.width();
heightPx = windowBounds.bounds.height();
availableWidthPx = windowBounds.availableSize.x;
- availableHeightPx = windowBounds.availableSize.y;
+ int nonFinalAvailableHeightPx = windowBounds.availableSize.y;
+
+ mInfo = info;
+ // If the device's pixel density was scaled (usually via settings for A11y), use the
+ // original dimensions to determine if rotation is allowed of not.
+ float originalSmallestWidth = dpiFromPx(Math.min(widthPx, heightPx), DENSITY_DEVICE_STABLE);
+ allowRotation = originalSmallestWidth >= MIN_TABLET_WIDTH;
+ // Tablet UI does not support emulated landscape.
+ isTablet = allowRotation && info.isTablet(windowBounds);
+ isPhone = !isTablet;
+ isTwoPanels = isTablet && useTwoPanels;
aspectRatio = ((float) Math.max(widthPx, heightPx)) / Math.min(widthPx, heightPx);
boolean isTallDevice = Float.compare(aspectRatio, TALL_DEVICE_ASPECT_RATIO_THRESHOLD) >= 0;
- mQsbCenterFactor = res.getFloat(R.dimen.qsb_center_factor);
- if (isTwoPanels) {
- if (isLandscape) {
- mTypeIndex = INDEX_TWO_PANEL_LANDSCAPE;
- } else {
- mTypeIndex = INDEX_TWO_PANEL_PORTRAIT;
- }
- } else {
- if (isLandscape) {
- mTypeIndex = INDEX_LANDSCAPE;
- } else {
- mTypeIndex = INDEX_DEFAULT;
- }
- }
+ // Some more constants
+ context = getContext(context, info, isVerticalBarLayout()
+ ? Configuration.ORIENTATION_LANDSCAPE
+ : Configuration.ORIENTATION_PORTRAIT);
+ mMetrics = context.getResources().getDisplayMetrics();
+ final Resources res = context.getResources();
+ isTaskbarPresent = isTablet && FeatureFlags.ENABLE_TASKBAR.get();
if (isTaskbarPresent) {
+ // Taskbar will be added later, but provides bottom insets that we should subtract
+ // from availableHeightPx.
taskbarSize = res.getDimensionPixelSize(R.dimen.taskbar_size);
- stashedTaskbarSize = res.getDimensionPixelSize(R.dimen.taskbar_stashed_size);
+ WindowInsets windowInsets =
+ context.createWindowContext(
+ context.getSystemService(DisplayManager.class).getDisplay(mInfo.id),
+ TYPE_APPLICATION, null)
+ .getSystemService(WindowManager.class)
+ .getCurrentWindowMetrics().getWindowInsets();
+ nonOverlappingTaskbarInset = taskbarSize - windowInsets.getSystemWindowInsetBottom();
+ if (nonOverlappingTaskbarInset > 0) {
+ nonFinalAvailableHeightPx -= nonOverlappingTaskbarInset;
+ }
}
+ availableHeightPx = nonFinalAvailableHeightPx;
edgeMarginPx = res.getDimensionPixelSize(R.dimen.dynamic_grid_edge_margin);
- desiredWorkspaceHorizontalMarginPx = getHorizontalMarginPx(inv, res);
- desiredWorkspaceHorizontalMarginOriginalPx = desiredWorkspaceHorizontalMarginPx;
- gridVisualizationPaddingX = res.getDimensionPixelSize(
- R.dimen.grid_visualization_horizontal_cell_spacing);
- gridVisualizationPaddingY = res.getDimensionPixelSize(
- R.dimen.grid_visualization_vertical_cell_spacing);
-
- bottomSheetTopPadding = mInsets.top // statusbar height
- + res.getDimensionPixelSize(R.dimen.bottom_sheet_extra_top_padding)
- + (isTablet ? 0 : edgeMarginPx); // phones need edgeMarginPx additional padding
-
- allAppsTopPadding = isTablet ? bottomSheetTopPadding : 0;
- allAppsShiftRange = isTablet
- ? heightPx - allAppsTopPadding
- : res.getDimensionPixelSize(R.dimen.all_apps_starting_vertical_translate);
+ desiredWorkspaceLeftRightMarginPx = isVerticalBarLayout() ? 0 : isScalableGrid
+ ? res.getDimensionPixelSize(R.dimen.scalable_grid_left_right_margin)
+ : res.getDimensionPixelSize(R.dimen.dynamic_grid_left_right_margin);
+ desiredWorkspaceLeftRightOriginalPx = desiredWorkspaceLeftRightMarginPx;
+
+
+ allAppsOpenVerticalTranslate = res.getDimensionPixelSize(
+ R.dimen.all_apps_open_vertical_translate);
+
folderLabelTextScale = res.getFloat(R.dimen.folder_label_text_scale);
folderContentPaddingLeftRight =
res.getDimensionPixelSize(R.dimen.folder_content_padding_left_right);
folderContentPaddingTop = res.getDimensionPixelSize(R.dimen.folder_content_padding_top);
- cellLayoutBorderSpacePx = getCellLayoutBorderSpace(inv);
- allAppsBorderSpacePx = new Point(
- pxFromDp(inv.allAppsBorderSpaces[mTypeIndex].x, mMetrics),
- pxFromDp(inv.allAppsBorderSpaces[mTypeIndex].y, mMetrics));
- cellLayoutBorderSpaceOriginalPx = new Point(cellLayoutBorderSpacePx);
- folderCellLayoutBorderSpaceOriginalPx = pxFromDp(inv.folderBorderSpace, mMetrics);
- folderCellLayoutBorderSpacePx = new Point(folderCellLayoutBorderSpaceOriginalPx,
- folderCellLayoutBorderSpaceOriginalPx);
+ setCellLayoutBorderSpacing(pxFromDp(inv.borderSpacing, mMetrics, 1f));
+ cellLayoutBorderSpacingOriginalPx = cellLayoutBorderSpacingPx;
+ folderCellLayoutBorderSpacingPx = cellLayoutBorderSpacingPx;
+
+ int cellLayoutPaddingLeftRightMultiplier = !isVerticalBarLayout() && isTablet
+ ? PORTRAIT_TABLET_LEFT_RIGHT_PADDING_MULTIPLIER : 1;
+ int cellLayoutPadding = isScalableGrid
+ ? 0
+ : res.getDimensionPixelSize(R.dimen.dynamic_grid_cell_layout_padding);
+
+ if (isTwoPanels) {
+ cellLayoutPaddingLeftRightPx =
+ res.getDimensionPixelSize(R.dimen.two_panel_home_side_padding);
+ cellLayoutBottomPaddingPx = 0;
+ } else if (isLandscape) {
+ cellLayoutPaddingLeftRightPx = 0;
+ cellLayoutBottomPaddingPx = cellLayoutPadding;
+ } else {
+ cellLayoutPaddingLeftRightPx = cellLayoutPaddingLeftRightMultiplier * cellLayoutPadding;
+ cellLayoutBottomPaddingPx = 0;
+ }
workspacePageIndicatorHeight = res.getDimensionPixelSize(
R.dimen.workspace_page_indicator_height);
@@ -340,96 +315,46 @@ public class DeviceProfile {
res.getDimensionPixelSize(R.dimen.dynamic_grid_icon_drawable_padding);
dropTargetBarSizePx = res.getDimensionPixelSize(R.dimen.dynamic_grid_drop_target_size);
- dropTargetBarTopMarginPx = res.getDimensionPixelSize(R.dimen.drop_target_top_margin);
- dropTargetBarBottomMarginPx = res.getDimensionPixelSize(R.dimen.drop_target_bottom_margin);
dropTargetDragPaddingPx = res.getDimensionPixelSize(R.dimen.drop_target_drag_padding);
dropTargetTextSizePx = res.getDimensionPixelSize(R.dimen.drop_target_text_size);
- dropTargetHorizontalPaddingPx = res.getDimensionPixelSize(
- R.dimen.drop_target_button_drawable_horizontal_padding);
- dropTargetVerticalPaddingPx = res.getDimensionPixelSize(
- R.dimen.drop_target_button_drawable_vertical_padding);
- dropTargetGapPx = res.getDimensionPixelSize(R.dimen.drop_target_button_gap);
- dropTargetButtonWorkspaceEdgeGapPx = res.getDimensionPixelSize(
- R.dimen.drop_target_button_workspace_edge_gap);
workspaceSpringLoadedBottomSpace =
res.getDimensionPixelSize(R.dimen.dynamic_grid_min_spring_loaded_space);
- workspaceSpringLoadedMinNextPageVisiblePx = res.getDimensionPixelSize(
- R.dimen.dynamic_grid_spring_loaded_min_next_space_visible);
workspaceCellPaddingXPx = res.getDimensionPixelSize(R.dimen.dynamic_grid_cell_padding_x);
- hotseatQsbHeight = res.getDimensionPixelSize(R.dimen.qsb_widget_height);
- // Whether QSB might be inline in appropriate orientation (e.g. landscape).
- boolean canQsbInline = (isTwoPanels ? inv.inlineQsb[INDEX_TWO_PANEL_PORTRAIT]
- || inv.inlineQsb[INDEX_TWO_PANEL_LANDSCAPE]
- : inv.inlineQsb[INDEX_DEFAULT] || inv.inlineQsb[INDEX_LANDSCAPE])
- && hotseatQsbHeight > 0;
- isQsbInline = inv.inlineQsb[mTypeIndex] && canQsbInline;
-
- // We shrink hotseat sizes regardless of orientation, if nav buttons are inline and QSB
- // might be inline in either orientations, to keep hotseat size consistent across rotation.
- areNavButtonsInline = isTaskbarPresent && !isGestureMode;
- if (areNavButtonsInline && canQsbInline) {
- numShownHotseatIcons = inv.numShrunkenHotseatIcons;
- } else {
- numShownHotseatIcons =
- isTwoPanels ? inv.numDatabaseHotseatIcons : inv.numShownHotseatIcons;
- }
-
+ numShownHotseatIcons =
+ isTwoPanels ? inv.numDatabaseHotseatIcons : inv.numShownHotseatIcons;
numShownAllAppsColumns =
isTwoPanels ? inv.numDatabaseAllAppsColumns : inv.numAllAppsColumns;
hotseatBarSizeExtraSpacePx = 0;
hotseatBarTopPaddingPx =
res.getDimensionPixelSize(R.dimen.dynamic_grid_hotseat_top_padding);
- if (isQsbInline) {
- hotseatBarBottomPaddingPx = res.getDimensionPixelSize(R.dimen.inline_qsb_bottom_margin);
- } else {
- hotseatBarBottomPaddingPx = (isTallDevice ? res.getDimensionPixelSize(
- R.dimen.dynamic_grid_hotseat_bottom_tall_padding)
- : res.getDimensionPixelSize(
- R.dimen.dynamic_grid_hotseat_bottom_non_tall_padding))
- + res.getDimensionPixelSize(R.dimen.dynamic_grid_hotseat_bottom_padding);
- }
-
- springLoadedHotseatBarTopMarginPx = res.getDimensionPixelSize(
- R.dimen.spring_loaded_hotseat_top_margin);
+ hotseatBarBottomPaddingPx = (isTallDevice ? 0
+ : res.getDimensionPixelSize(R.dimen.dynamic_grid_hotseat_bottom_non_tall_padding))
+ + res.getDimensionPixelSize(R.dimen.dynamic_grid_hotseat_bottom_padding);
hotseatBarSidePaddingEndPx =
res.getDimensionPixelSize(R.dimen.dynamic_grid_hotseat_side_padding);
// Add a bit of space between nav bar and hotseat in vertical bar layout.
hotseatBarSidePaddingStartPx = isVerticalBarLayout() ? workspacePageIndicatorHeight : 0;
hotseatExtraVerticalSize =
res.getDimensionPixelSize(R.dimen.dynamic_grid_hotseat_extra_vertical_size);
- updateHotseatIconSize(pxFromDp(inv.iconSize[INDEX_DEFAULT], mMetrics));
+ updateHotseatIconSize(pxFromDp(inv.iconSize, mMetrics, 1f));
qsbBottomMarginOriginalPx = isScalableGrid
? res.getDimensionPixelSize(R.dimen.scalable_grid_qsb_bottom_margin)
: 0;
overviewTaskMarginPx = res.getDimensionPixelSize(R.dimen.overview_task_margin);
- overviewTaskMarginGridPx = res.getDimensionPixelSize(R.dimen.overview_task_margin_grid);
- overviewTaskIconSizePx = res.getDimensionPixelSize(R.dimen.task_thumbnail_icon_size);
- overviewTaskIconDrawableSizePx =
- res.getDimensionPixelSize(R.dimen.task_thumbnail_icon_drawable_size);
- overviewTaskIconDrawableSizeGridPx =
- res.getDimensionPixelSize(R.dimen.task_thumbnail_icon_drawable_size_grid);
+ overviewTaskIconSizePx =
+ isTablet && FeatureFlags.ENABLE_OVERVIEW_GRID.get() ? res.getDimensionPixelSize(
+ R.dimen.task_thumbnail_icon_size_grid) : res.getDimensionPixelSize(
+ R.dimen.task_thumbnail_icon_size);
overviewTaskThumbnailTopMarginPx = overviewTaskIconSizePx + overviewTaskMarginPx * 2;
- // In vertical bar, use the smaller task margin for the top regardless of mode.
- overviewActionsTopMarginPx = isVerticalBarLayout()
- ? overviewTaskMarginPx
- : res.getDimensionPixelSize(R.dimen.overview_actions_top_margin);
- overviewPageSpacing = res.getDimensionPixelSize(R.dimen.overview_page_spacing);
- overviewActionsButtonSpacing = res.getDimensionPixelSize(
- R.dimen.overview_actions_button_spacing);
- overviewActionsHeight = res.getDimensionPixelSize(R.dimen.overview_actions_height);
- // Grid task's top margin is only overviewTaskIconSizePx + overviewTaskMarginGridPx, but
- // overviewTaskThumbnailTopMarginPx is applied to all TaskThumbnailView, so exclude the
- // extra margin when calculating row spacing.
- int extraTopMargin = overviewTaskThumbnailTopMarginPx - overviewTaskIconSizePx
- - overviewTaskMarginGridPx;
- overviewRowSpacing = res.getDimensionPixelSize(R.dimen.overview_grid_row_spacing)
- - extraTopMargin;
- overviewGridSideMargin = res.getDimensionPixelSize(R.dimen.overview_grid_side_margin);
+ overviewActionsMarginGesturePx = res.getDimensionPixelSize(
+ R.dimen.overview_actions_bottom_margin_gesture);
+ overviewActionsMarginThreeButtonPx = res.getDimensionPixelSize(
+ R.dimen.overview_actions_bottom_margin_three_button);
// Calculate all of the remaining variables.
extraSpace = updateAvailableDimensions(res);
@@ -483,18 +408,8 @@ public class DeviceProfile {
// Recalculate the available dimensions using the new hotseat size.
updateAvailableDimensions(res);
}
-
- int cellLayoutPadding =
- isTwoPanels ? cellLayoutBorderSpacePx.x / 2 : res.getDimensionPixelSize(
- R.dimen.cell_layout_padding);
- cellLayoutPaddingPx = new Rect(cellLayoutPadding, cellLayoutPadding, cellLayoutPadding,
- cellLayoutPadding);
updateWorkspacePadding();
- // Hotseat and QSB width depends on updated cellSize and workspace padding
- hotseatBorderSpace = calculateHotseatBorderSpace();
- qsbWidth = calculateQsbWidth();
-
flingToDeleteThresholdVelocity = res.getDimensionPixelSize(
R.dimen.drag_flingToDeleteMinVelocity);
@@ -505,38 +420,6 @@ public class DeviceProfile {
new DotRenderer(allAppsIconSizePx, dotPath, DEFAULT_DOT_SIZE);
}
- /**
- * QSB width is always calculated because when in 3 button nav the width doesn't follow the
- * width of the hotseat.
- */
- private int calculateQsbWidth() {
- if (isQsbInline) {
- int columns = getPanelCount() * inv.numColumns;
- return getIconToIconWidthForColumns(columns)
- - iconSizePx * numShownHotseatIcons
- - hotseatBorderSpace * numShownHotseatIcons;
- } else {
- int columns = inv.hotseatColumnSpan[mTypeIndex];
- return getIconToIconWidthForColumns(columns);
- }
- }
-
- private int getIconToIconWidthForColumns(int columns) {
- return columns * getCellSize().x
- + (columns - 1) * cellLayoutBorderSpacePx.x
- - (getCellSize().x - iconSizePx); // left and right cell space
- }
-
- private int getHorizontalMarginPx(InvariantDeviceProfile idp, Resources res) {
- if (isVerticalBarLayout()) {
- return 0;
- }
-
- return isScalableGrid
- ? pxFromDp(idp.horizontalMargin[mTypeIndex], mMetrics)
- : res.getDimensionPixelSize(R.dimen.dynamic_grid_left_right_margin);
- }
-
private void updateHotseatIconSize(int hotseatIconSizePx) {
// Ensure there is enough space for folder icons, which have a slightly larger radius.
hotseatCellHeightPx = (int) Math.ceil(hotseatIconSizePx * ICON_OVERLAP_FACTOR);
@@ -550,24 +433,8 @@ public class DeviceProfile {
}
}
- private Point getCellLayoutBorderSpace(InvariantDeviceProfile idp) {
- return getCellLayoutBorderSpace(idp, 1f);
-
- }
-
- private Point getCellLayoutBorderSpace(InvariantDeviceProfile idp, float scale) {
- if (!isScalableGrid) {
- return new Point(0, 0);
- }
-
- int horizontalSpacePx = pxFromDp(idp.borderSpaces[mTypeIndex].x, mMetrics, scale);
- int verticalSpacePx = pxFromDp(idp.borderSpaces[mTypeIndex].y, mMetrics, scale);
-
- return new Point(horizontalSpacePx, verticalSpacePx);
- }
-
- public Info getDisplayInfo() {
- return mInfo;
+ private void setCellLayoutBorderSpacing(int borderSpacing) {
+ cellLayoutBorderSpacingPx = isScalableGrid ? borderSpacing : 0;
}
/**
@@ -580,22 +447,20 @@ public class DeviceProfile {
// Check all sides to ensure that the widget won't overlap into another cell, or into
// status bar.
return workspaceTopPadding > widgetPadding.top
- && cellLayoutBorderSpacePx.x > widgetPadding.left
- && cellLayoutBorderSpacePx.y > widgetPadding.top
- && cellLayoutBorderSpacePx.x > widgetPadding.right
- && cellLayoutBorderSpacePx.y > widgetPadding.bottom;
+ && cellLayoutBorderSpacingPx > widgetPadding.left
+ && cellLayoutBorderSpacingPx > widgetPadding.top
+ && cellLayoutBorderSpacingPx > widgetPadding.right
+ && cellLayoutBorderSpacingPx > widgetPadding.bottom;
}
public Builder toBuilder(Context context) {
- WindowBounds bounds = new WindowBounds(
- widthPx, heightPx, availableWidthPx, availableHeightPx, rotationHint);
+ WindowBounds bounds =
+ new WindowBounds(widthPx, heightPx, availableWidthPx, availableHeightPx);
bounds.bounds.offsetTo(windowX, windowY);
- bounds.insets.set(mInsets);
return new Builder(context, inv, mInfo)
.setWindowBounds(bounds)
.setUseTwoPanels(isTwoPanels)
- .setMultiWindowMode(isMultiWindowMode)
- .setGestureMode(isGestureMode);
+ .setMultiWindowMode(isMultiWindowMode);
}
public DeviceProfile copy(Context context) {
@@ -618,6 +483,7 @@ public class DeviceProfile {
float appWidgetScaleX = (float) profile.getCellSize().x / getCellSize().x;
float appWidgetScaleY = (float) profile.getCellSize().y / getCellSize().y;
profile.appWidgetScale.set(appWidgetScaleX, appWidgetScaleY);
+ profile.updateWorkspacePadding();
return profile;
}
@@ -651,34 +517,17 @@ public class DeviceProfile {
+ textHeight + (topBottomPadding * 2);
}
- private void updateAllAppsContainerWidth(Resources res) {
- int cellLayoutHorizontalPadding =
- (cellLayoutPaddingPx.left + cellLayoutPaddingPx.right) / 2;
- if (isTablet) {
- allAppsLeftRightPadding =
- res.getDimensionPixelSize(R.dimen.all_apps_bottom_sheet_horizontal_padding);
-
- int usedWidth = (allAppsCellWidthPx * numShownAllAppsColumns)
- + (allAppsBorderSpacePx.x * (numShownAllAppsColumns - 1))
- + allAppsLeftRightPadding * 2;
- allAppsLeftRightMargin = Math.max(1, (availableWidthPx - usedWidth) / 2);
- } else {
- allAppsLeftRightPadding =
- desiredWorkspaceHorizontalMarginPx + cellLayoutHorizontalPadding;
- }
- }
-
/**
* Returns the amount of extra (or unused) vertical space.
*/
private int updateAvailableDimensions(Resources res) {
updateIconSize(1f, res);
- updateWorkspacePadding();
+ Point workspacePadding = getTotalWorkspacePadding();
// Check to see if the icons fit within the available height.
- float usedHeight = getCellLayoutHeightSpecification();
- final int maxHeight = getCellLayoutHeight();
+ float usedHeight = getCellLayoutHeight();
+ final int maxHeight = availableHeightPx - workspacePadding.y;
float extraHeight = Math.max(0, maxHeight - usedHeight);
float scaleY = maxHeight / usedHeight;
boolean shouldScale = scaleY < 1f;
@@ -688,8 +537,9 @@ public class DeviceProfile {
// We scale to fit the cellWidth and cellHeight in the available space.
// The benefit of scalable grids is that we can get consistent aspect ratios between
// devices.
- float usedWidth =
- getCellLayoutWidthSpecification() + (desiredWorkspaceHorizontalMarginPx * 2);
+ float usedWidth = (cellWidthPx * inv.numColumns)
+ + (cellLayoutBorderSpacingPx * (inv.numColumns - 1))
+ + (desiredWorkspaceLeftRightMarginPx * 2);
// We do not subtract padding here, as we also scale the workspace padding if needed.
scaleX = availableWidthPx / usedWidth;
shouldScale = true;
@@ -698,22 +548,15 @@ public class DeviceProfile {
if (shouldScale) {
float scale = Math.min(scaleX, scaleY);
updateIconSize(scale, res);
- extraHeight = Math.max(0, maxHeight - getCellLayoutHeightSpecification());
+ extraHeight = Math.max(0, maxHeight - getCellLayoutHeight());
}
updateAvailableFolderCellDimensions(res);
return Math.round(extraHeight);
}
- private int getCellLayoutHeightSpecification() {
- return (cellHeightPx * inv.numRows) + (cellLayoutBorderSpacePx.y * (inv.numRows - 1))
- + cellLayoutPaddingPx.top + cellLayoutPaddingPx.bottom;
- }
-
- private int getCellLayoutWidthSpecification() {
- int numColumns = getPanelCount() * inv.numColumns;
- return (cellWidthPx * numColumns) + (cellLayoutBorderSpacePx.x * (numColumns - 1))
- + cellLayoutPaddingPx.left + cellLayoutPaddingPx.right;
+ private int getCellLayoutHeight() {
+ return (cellHeightPx * inv.numRows) + (cellLayoutBorderSpacingPx * (inv.numRows - 1));
}
/**
@@ -726,25 +569,24 @@ public class DeviceProfile {
iconScale = Math.min(1f, scale);
cellScaleToFit = scale;
+
// Workspace
final boolean isVerticalLayout = isVerticalBarLayout();
- float invIconSizeDp = inv.iconSize[mTypeIndex];
- float invIconTextSizeSp = inv.iconTextSize[mTypeIndex];
-
+ float invIconSizeDp = isLandscape ? inv.landscapeIconSize : inv.iconSize;
iconSizePx = Math.max(1, pxFromDp(invIconSizeDp, mMetrics, iconScale));
+ float invIconTextSizeSp = isLandscape ? inv.landscapeIconTextSize : inv.iconTextSize;
iconTextSizePx = (int) (pxFromSp(invIconTextSizeSp, mMetrics) * iconScale);
iconDrawablePaddingPx = (int) (iconDrawablePaddingOriginalPx * iconScale);
- cellLayoutBorderSpacePx = getCellLayoutBorderSpace(inv, scale);
+ setCellLayoutBorderSpacing((int) (cellLayoutBorderSpacingOriginalPx * scale));
if (isScalableGrid) {
- cellWidthPx = pxFromDp(inv.minCellSize[mTypeIndex].x, mMetrics, scale);
- cellHeightPx = pxFromDp(inv.minCellSize[mTypeIndex].y, mMetrics, scale);
+ cellWidthPx = pxFromDp(inv.minCellWidth, mMetrics, scale);
+ cellHeightPx = pxFromDp(inv.minCellHeight, mMetrics, scale);
int cellContentHeight = iconSizePx + iconDrawablePaddingPx
+ Utilities.calculateTextHeight(iconTextSizePx);
cellYPaddingPx = Math.max(0, cellHeightPx - cellContentHeight) / 2;
- desiredWorkspaceHorizontalMarginPx =
- (int) (desiredWorkspaceHorizontalMarginOriginalPx * scale);
+ desiredWorkspaceLeftRightMarginPx = (int) (desiredWorkspaceLeftRightOriginalPx * scale);
} else {
cellWidthPx = iconSizePx + iconDrawablePaddingPx;
cellHeightPx = (int) Math.ceil(iconSizePx * ICON_OVERLAP_FACTOR)
@@ -762,66 +604,41 @@ public class DeviceProfile {
}
// All apps
- updateAllAppsIconSize(scale, res);
-
- updateHotseatIconSize(iconSizePx);
-
- // Folder icon
- folderIconSizePx = IconNormalizer.getNormalizedCircleSize(iconSizePx);
- folderIconOffsetYPx = (iconSizePx - folderIconSizePx) / 2;
- }
-
- /**
- * Hotseat width spans a certain number of columns on scalable grids.
- * This method calculates the space between the icons to achieve that width.
- */
- private int calculateHotseatBorderSpace() {
- if (!isScalableGrid) return 0;
- //TODO(http://b/228998082) remove this when 3 button spaces are fixed
- if (areNavButtonsInline) {
- return pxFromDp(inv.hotseatBorderSpaces[mTypeIndex], mMetrics);
+ if (numShownAllAppsColumns != inv.numColumns) {
+ allAppsIconSizePx = pxFromDp(inv.allAppsIconSize, mMetrics);
+ allAppsIconTextSizePx = pxFromSp(inv.allAppsIconTextSize, mMetrics);
+ allAppsIconDrawablePaddingPx = iconDrawablePaddingOriginalPx;
+ autoResizeAllAppsCells();
} else {
- int columns = inv.hotseatColumnSpan[mTypeIndex];
- float hotseatWidthPx = getIconToIconWidthForColumns(columns);
- float hotseatIconsTotalPx = iconSizePx * numShownHotseatIcons;
- return (int) (hotseatWidthPx - hotseatIconsTotalPx) / (numShownHotseatIcons - 1);
+ allAppsIconSizePx = iconSizePx;
+ allAppsIconTextSizePx = iconTextSizePx;
+ allAppsIconDrawablePaddingPx = iconDrawablePaddingPx;
+ allAppsCellHeightPx = getCellSize().y;
+ }
+ allAppsCellWidthPx = allAppsIconSizePx + allAppsIconDrawablePaddingPx;
+
+ if (isVerticalLayout) {
+ hideWorkspaceLabelsIfNotEnoughSpace();
}
- }
+ // Hotseat
+ updateHotseatIconSize(iconSizePx);
- /**
- * Updates the iconSize for allApps* variants.
- */
- private void updateAllAppsIconSize(float scale, Resources res) {
- allAppsBorderSpacePx = new Point(
- pxFromDp(inv.allAppsBorderSpaces[mTypeIndex].x, mMetrics, scale),
- pxFromDp(inv.allAppsBorderSpaces[mTypeIndex].y, mMetrics, scale));
- // AllApps cells don't have real space between cells,
- // so we add the border space to the cell height
- allAppsCellHeightPx = pxFromDp(inv.allAppsCellSize[mTypeIndex].y, mMetrics, scale)
- + allAppsBorderSpacePx.y;
- // but width is just the cell,
- // the border is added in #updateAllAppsContainerWidth
- allAppsCellWidthPx = pxFromDp(inv.allAppsCellSize[mTypeIndex].x, mMetrics, scale);
- if (isScalableGrid) {
- allAppsIconSizePx =
- pxFromDp(inv.allAppsIconSize[mTypeIndex], mMetrics, scale);
- allAppsIconTextSizePx =
- pxFromSp(inv.allAppsIconTextSize[mTypeIndex], mMetrics, scale);
- allAppsIconDrawablePaddingPx = iconDrawablePaddingOriginalPx;
+ if (!isVerticalLayout) {
+ int expectedWorkspaceHeight = availableHeightPx - hotseatBarSizePx
+ - workspacePageIndicatorHeight - edgeMarginPx;
+ float minRequiredHeight = dropTargetBarSizePx + workspaceSpringLoadedBottomSpace;
+ workspaceSpringLoadShrinkFactor = Math.min(
+ res.getInteger(R.integer.config_workspaceSpringLoadShrinkPercentage) / 100.0f,
+ 1 - (minRequiredHeight / expectedWorkspaceHeight));
} else {
- float invIconSizeDp = inv.allAppsIconSize[mTypeIndex];
- float invIconTextSizeSp = inv.allAppsIconTextSize[mTypeIndex];
- allAppsIconSizePx = Math.max(1, pxFromDp(invIconSizeDp, mMetrics, scale));
- allAppsIconTextSizePx = (int) (pxFromSp(invIconTextSizeSp, mMetrics) * scale);
- allAppsIconDrawablePaddingPx =
- res.getDimensionPixelSize(R.dimen.all_apps_icon_drawable_padding);
+ workspaceSpringLoadShrinkFactor =
+ res.getInteger(R.integer.config_workspaceSpringLoadShrinkPercentage) / 100.0f;
}
- updateAllAppsContainerWidth(res);
- if (isVerticalBarLayout()) {
- hideWorkspaceLabelsIfNotEnoughSpace();
- }
+ // Folder icon
+ folderIconSizePx = IconNormalizer.getNormalizedCircleSize(iconSizePx);
+ folderIconOffsetYPx = (iconSizePx - folderIconSizePx) / 2;
}
private void updateAvailableFolderCellDimensions(Resources res) {
@@ -835,14 +652,14 @@ public class DeviceProfile {
// Check if the icons fit within the available height.
float contentUsedHeight = folderCellHeightPx * inv.numFolderRows
- + ((inv.numFolderRows - 1) * folderCellLayoutBorderSpacePx.y);
+ + ((inv.numFolderRows - 1) * folderCellLayoutBorderSpacingPx);
int contentMaxHeight = availableHeightPx - totalWorkspacePadding.y - folderBottomPanelSize
- folderMargin - folderContentPaddingTop;
float scaleY = contentMaxHeight / contentUsedHeight;
// Check if the icons fit within the available width.
float contentUsedWidth = folderCellWidthPx * inv.numFolderColumns
- + ((inv.numFolderColumns - 1) * folderCellLayoutBorderSpacePx.x);
+ + ((inv.numFolderColumns - 1) * folderCellLayoutBorderSpacingPx);
int contentMaxWidth = availableWidthPx - totalWorkspacePadding.x - folderMargin
- folderContentPaddingLeftRight * 2;
float scaleX = contentMaxWidth / contentUsedWidth;
@@ -854,12 +671,9 @@ public class DeviceProfile {
}
private void updateFolderCellSize(float scale, Resources res) {
- float invIconSizeDp = isVerticalBarLayout()
- ? inv.iconSize[INDEX_LANDSCAPE]
- : inv.iconSize[INDEX_DEFAULT];
+ float invIconSizeDp = isVerticalBarLayout() ? inv.landscapeIconSize : inv.iconSize;
folderChildIconSizePx = Math.max(1, pxFromDp(invIconSizeDp, mMetrics, scale));
- folderChildTextSizePx =
- pxFromSp(inv.iconTextSize[INDEX_DEFAULT], mMetrics, scale);
+ folderChildTextSizePx = pxFromSp(inv.iconTextSize, mMetrics, scale);
folderLabelTextSizePx = (int) (folderChildTextSizePx * folderLabelTextScale);
int textHeight = Utilities.calculateTextHeight(folderChildTextSizePx);
@@ -871,10 +685,10 @@ public class DeviceProfile {
folderCellWidthPx = (int) Math.max(minWidth, cellWidthPx * scale);
folderCellHeightPx = (int) Math.max(minHeight, cellHeightPx * scale);
- int scaledSpace = (int) (folderCellLayoutBorderSpaceOriginalPx * scale);
- folderCellLayoutBorderSpacePx = new Point(scaledSpace, scaledSpace);
- folderContentPaddingLeftRight = scaledSpace;
- folderContentPaddingTop = scaledSpace;
+ int borderSpacing = (int) (cellLayoutBorderSpacingOriginalPx * scale);
+ folderCellLayoutBorderSpacingPx = borderSpacing;
+ folderContentPaddingLeftRight = borderSpacing;
+ folderContentPaddingTop = borderSpacing;
} else {
int cellPaddingX = (int) (res.getDimensionPixelSize(R.dimen.folder_cell_x_padding)
* scale);
@@ -891,6 +705,7 @@ public class DeviceProfile {
public void updateInsets(Rect insets) {
mInsets.set(insets);
+ updateWorkspacePadding();
}
/**
@@ -909,98 +724,18 @@ public class DeviceProfile {
if (result == null) {
result = new Point();
}
-
- int shortcutAndWidgetContainerWidth =
- getCellLayoutWidth() - (cellLayoutPaddingPx.left + cellLayoutPaddingPx.right);
- result.x = calculateCellWidth(shortcutAndWidgetContainerWidth, cellLayoutBorderSpacePx.x,
- inv.numColumns);
- int shortcutAndWidgetContainerHeight =
- getCellLayoutHeight() - (cellLayoutPaddingPx.top + cellLayoutPaddingPx.bottom);
- result.y = calculateCellHeight(shortcutAndWidgetContainerHeight, cellLayoutBorderSpacePx.y,
- inv.numRows);
+ // Since we are only concerned with the overall padding, layout direction does
+ // not matter.
+ Point padding = getTotalWorkspacePadding();
+ result.x = calculateCellWidth(availableWidthPx - padding.x
+ - cellLayoutPaddingLeftRightPx * 2, cellLayoutBorderSpacingPx, inv.numColumns);
+ result.y = calculateCellHeight(availableHeightPx - padding.y
+ - cellLayoutBottomPaddingPx, cellLayoutBorderSpacingPx, inv.numRows);
return result;
}
- /**
- * Gets the number of panels within the workspace.
- */
- public int getPanelCount() {
- return isTwoPanels ? 2 : 1;
- }
-
- /**
- * Gets the space in px from the bottom of last item in the vertical-bar hotseat to the
- * bottom of the screen.
- */
- public int getVerticalHotseatLastItemBottomOffset() {
- int cellHeight = calculateCellHeight(
- heightPx - mHotseatPadding.top - mHotseatPadding.bottom, hotseatBorderSpace,
- numShownHotseatIcons);
- int hotseatSize = (cellHeight * numShownHotseatIcons)
- + (hotseatBorderSpace * (numShownHotseatIcons - 1));
- int extraHotseatEndSpacing = (heightPx - hotseatSize) / 2;
- int extraIconEndSpacing = (cellHeight - iconSizePx) / 2;
- return extraHotseatEndSpacing + extraIconEndSpacing + mHotseatPadding.bottom;
- }
-
- /**
- * Gets the scaled top of the workspace in px for the spring-loaded edit state.
- */
- public float getCellLayoutSpringLoadShrunkTop() {
- workspaceSpringLoadShrunkTop = mInsets.top + dropTargetBarTopMarginPx + dropTargetBarSizePx
- + dropTargetBarBottomMarginPx;
- return workspaceSpringLoadShrunkTop;
- }
-
- /**
- * Gets the scaled bottom of the workspace in px for the spring-loaded edit state.
- */
- private float getCellLayoutSpringLoadShrunkBottom() {
- int topOfHotseat = hotseatBarSizePx + springLoadedHotseatBarTopMarginPx;
- workspaceSpringLoadShrunkBottom =
- heightPx - (isVerticalBarLayout() ? getVerticalHotseatLastItemBottomOffset()
- : topOfHotseat);
- return workspaceSpringLoadShrunkBottom;
- }
-
- /**
- * Gets the scale of the workspace for the spring-loaded edit state.
- */
- public float getWorkspaceSpringLoadScale() {
- float scale = (getCellLayoutSpringLoadShrunkBottom() - getCellLayoutSpringLoadShrunkTop())
- / getCellLayoutHeight();
- scale = Math.min(scale, 1f);
-
- // Reduce scale if next pages would not be visible after scaling the workspace
- int workspaceWidth = availableWidthPx;
- float scaledWorkspaceWidth = workspaceWidth * scale;
- float maxAvailableWidth = workspaceWidth - (2 * workspaceSpringLoadedMinNextPageVisiblePx);
- if (scaledWorkspaceWidth > maxAvailableWidth) {
- scale *= maxAvailableWidth / scaledWorkspaceWidth;
- }
- return scale;
- }
-
- /**
- * Gets the width of a single Cell Layout, aka a single panel within a Workspace.
- *
- * <p>This is the width of a Workspace, less its horizontal padding. Note that two-panel
- * layouts have two Cell Layouts per workspace.
- */
- public int getCellLayoutWidth() {
- return (availableWidthPx - getTotalWorkspacePadding().x) / getPanelCount();
- }
-
- /**
- * Gets the height of a single Cell Layout, aka a single panel within a Workspace.
- *
- * <p>This is the height of a Workspace, less its vertical padding.
- */
- public int getCellLayoutHeight() {
- return availableHeightPx - getTotalWorkspacePadding().y;
- }
-
public Point getTotalWorkspacePadding() {
+ updateWorkspacePadding();
return new Point(workspacePadding.left + workspacePadding.right,
workspacePadding.top + workspacePadding.bottom);
}
@@ -1022,93 +757,46 @@ public class DeviceProfile {
padding.right = hotseatBarSizePx;
}
} else {
- // Pad the bottom of the workspace with search/hotseat bar sizes
- int hotseatTop = hotseatBarSizePx;
+ int hotseatTop = isTaskbarPresent ? taskbarSize : hotseatBarSizePx;
int paddingBottom = hotseatTop + workspacePageIndicatorHeight
+ workspaceBottomPadding - mWorkspacePageIndicatorOverlapWorkspace;
- int paddingTop = workspaceTopPadding + (isScalableGrid ? 0 : edgeMarginPx);
- int paddingSide = desiredWorkspaceHorizontalMarginPx;
-
- padding.set(paddingSide, paddingTop, paddingSide, paddingBottom);
+ if (isTablet) {
+ // Pad the left and right of the workspace to ensure consistent spacing
+ // between all icons
+ // The amount of screen space available for left/right padding.
+ int availablePaddingX = Math.max(0, widthPx - ((inv.numColumns * cellWidthPx) +
+ ((inv.numColumns - 1) * cellWidthPx)));
+ availablePaddingX = (int) Math.min(availablePaddingX,
+ widthPx * MAX_HORIZONTAL_PADDING_PERCENT);
+ int hotseatVerticalPadding = isTaskbarPresent ? 0
+ : hotseatBarTopPaddingPx + hotseatBarBottomPaddingPx;
+ int availablePaddingY = Math.max(0, heightPx - edgeMarginPx - paddingBottom
+ - (2 * inv.numRows * cellHeightPx) - hotseatVerticalPadding);
+ padding.set(availablePaddingX / 2, edgeMarginPx + availablePaddingY / 2,
+ availablePaddingX / 2, paddingBottom + availablePaddingY / 2);
+
+ if (isTwoPanels) {
+ padding.set(0, padding.top, 0, padding.bottom);
+ }
+ } else {
+ // Pad the top and bottom of the workspace with search/hotseat bar sizes
+ padding.set(desiredWorkspaceLeftRightMarginPx,
+ workspaceTopPadding + (isScalableGrid ? 0 : edgeMarginPx),
+ desiredWorkspaceLeftRightMarginPx,
+ paddingBottom);
+ }
}
- insetPadding(workspacePadding, cellLayoutPaddingPx);
}
- private void insetPadding(Rect paddings, Rect insets) {
- insets.left = Math.min(insets.left, paddings.left);
- paddings.left -= insets.left;
-
- insets.top = Math.min(insets.top, paddings.top);
- paddings.top -= insets.top;
-
- insets.right = Math.min(insets.right, paddings.right);
- paddings.right -= insets.right;
-
- insets.bottom = Math.min(insets.bottom, paddings.bottom);
- paddings.bottom -= insets.bottom;
- }
-
- /**
- * Returns the padding for hotseat view
- */
- public Rect getHotseatLayoutPadding(Context context) {
+ public Rect getHotseatLayoutPadding() {
if (isVerticalBarLayout()) {
- // The hotseat icons will be placed in the middle of the hotseat cells.
- // Changing the hotseatCellHeightPx is not affecting hotseat icon positions
- // in vertical bar layout.
- // Workspace icons are moved up by a small factor. The variable diffOverlapFactor
- // is set to account for that difference.
- float diffOverlapFactor = iconSizePx * (ICON_OVERLAP_FACTOR - 1) / 2;
- int paddingTop = Math.max((int) (mInsets.top + cellLayoutPaddingPx.top
- - diffOverlapFactor), 0);
- int paddingBottom = Math.max((int) (mInsets.bottom + cellLayoutPaddingPx.bottom
- + diffOverlapFactor), 0);
-
if (isSeascape()) {
- mHotseatPadding.set(mInsets.left + hotseatBarSidePaddingStartPx, paddingTop,
- hotseatBarSidePaddingEndPx, paddingBottom);
- } else {
- mHotseatPadding.set(hotseatBarSidePaddingEndPx, paddingTop,
- mInsets.right + hotseatBarSidePaddingStartPx, paddingBottom);
- }
- } else if (isTaskbarPresent) {
- // Center the QSB vertically with hotseat
- int hotseatBottomPadding = getHotseatBottomPadding();
- int hotseatTopPadding =
- workspacePadding.bottom - hotseatBottomPadding - hotseatCellHeightPx;
-
- // Push icons to the side
- int additionalQsbSpace = isQsbInline ? qsbWidth + hotseatBorderSpace : 0;
- int requiredWidth = iconSizePx * numShownHotseatIcons
- + hotseatBorderSpace * (numShownHotseatIcons - 1)
- + additionalQsbSpace;
- int endOffset = ApiWrapper.getHotseatEndOffset(context);
- int hotseatWidth = Math.min(requiredWidth, availableWidthPx - endOffset);
- int sideSpacing = (availableWidthPx - hotseatWidth) / 2;
-
- mHotseatPadding.set(sideSpacing, hotseatTopPadding, sideSpacing, hotseatBottomPadding);
-
- boolean isRtl = Utilities.isRtl(context.getResources());
- if (isRtl) {
- mHotseatPadding.right += additionalQsbSpace;
+ mHotseatPadding.set(mInsets.left + hotseatBarSidePaddingStartPx,
+ mInsets.top, hotseatBarSidePaddingEndPx, mInsets.bottom);
} else {
- mHotseatPadding.left += additionalQsbSpace;
- }
-
- if (endOffset > sideSpacing) {
- int diff = isRtl
- ? sideSpacing - endOffset
- : endOffset - sideSpacing;
- mHotseatPadding.left -= diff;
- mHotseatPadding.right += diff;
+ mHotseatPadding.set(hotseatBarSidePaddingEndPx, mInsets.top,
+ mInsets.right + hotseatBarSidePaddingStartPx, mInsets.bottom);
}
- } else if (isScalableGrid) {
- int sideSpacing = (availableWidthPx - qsbWidth) / 2;
- mHotseatPadding.set(sideSpacing,
- hotseatBarTopPaddingPx,
- sideSpacing,
- hotseatBarSizePx - hotseatCellHeightPx - hotseatBarTopPaddingPx
- + mInsets.bottom);
} else {
// We want the edges of the hotseat to line up with the edges of the workspace, but the
// icons in the hotseat are a different size, and so don't line up perfectly. To account
@@ -1117,74 +805,19 @@ public class DeviceProfile {
float workspaceCellWidth = (float) widthPx / inv.numColumns;
float hotseatCellWidth = (float) widthPx / numShownHotseatIcons;
int hotseatAdjustment = Math.round((workspaceCellWidth - hotseatCellWidth) / 2);
- mHotseatPadding.set(hotseatAdjustment + workspacePadding.left + cellLayoutPaddingPx.left
- + mInsets.left, hotseatBarTopPaddingPx,
- hotseatAdjustment + workspacePadding.right + cellLayoutPaddingPx.right
+ mHotseatPadding.set(
+ hotseatAdjustment + workspacePadding.left + cellLayoutPaddingLeftRightPx
+ + mInsets.left,
+ hotseatBarTopPaddingPx,
+ hotseatAdjustment + workspacePadding.right + cellLayoutPaddingLeftRightPx
+ mInsets.right,
hotseatBarSizePx - hotseatCellHeightPx - hotseatBarTopPaddingPx
- + mInsets.bottom);
+ + cellLayoutBottomPaddingPx + mInsets.bottom);
}
return mHotseatPadding;
}
/**
- * Returns the number of pixels the QSB is translated from the bottom of the screen.
- */
- public int getQsbOffsetY() {
- if (isQsbInline) {
- return hotseatBarBottomPaddingPx;
- }
-
- int freeSpace = isTaskbarPresent
- ? workspacePadding.bottom
- : hotseatBarSizePx - hotseatCellHeightPx - hotseatQsbHeight;
-
- if (isScalableGrid && qsbBottomMarginPx > mInsets.bottom) {
- // Note that taskbarSize = 0 unless isTaskbarPresent.
- return Math.min(qsbBottomMarginPx + taskbarSize, freeSpace);
- } else {
- return (int) (freeSpace * mQsbCenterFactor)
- + (isTaskbarPresent ? taskbarSize : mInsets.bottom);
- }
- }
-
- private int getHotseatBottomPadding() {
- if (isQsbInline) {
- return getQsbOffsetY() - (Math.abs(hotseatQsbHeight - hotseatCellHeightPx) / 2);
- } else {
- return (getQsbOffsetY() - taskbarSize) / 2;
- }
- }
-
- /**
- * Returns the number of pixels the taskbar is translated from the bottom of the screen.
- */
- public int getTaskbarOffsetY() {
- int taskbarIconBottomSpace = (taskbarSize - iconSizePx) / 2;
- int launcherIconBottomSpace =
- Math.min((hotseatCellHeightPx - iconSizePx) / 2, gridVisualizationPaddingY);
- return getHotseatBottomPadding() + launcherIconBottomSpace - taskbarIconBottomSpace;
- }
-
- /**
- * Returns the number of pixels required below OverviewActions excluding insets.
- */
- public int getOverviewActionsClaimedSpaceBelow() {
- if (isTaskbarPresent && !isGestureMode) {
- // Align vertically to where nav buttons are.
- return ((taskbarSize - overviewActionsHeight) / 2) + getTaskbarOffsetY();
- }
-
- return isTaskbarPresent ? stashedTaskbarSize : mInsets.bottom;
- }
-
- /** Gets the space that the overview actions will take, including bottom margin. */
- public int getOverviewActionsClaimedSpace() {
- return overviewActionsTopMarginPx + overviewActionsHeight
- + getOverviewActionsClaimedSpaceBelow();
- }
-
- /**
* @return the bounds for which the open folders should be contained within
*/
public Rect getAbsoluteOpenFolderBounds() {
@@ -1208,7 +841,6 @@ public class DeviceProfile {
public static int calculateCellWidth(int width, int borderSpacing, int countX) {
return (width - ((countX - 1) * borderSpacing)) / countX;
}
-
public static int calculateCellHeight(int height, int borderSpacing, int countY) {
return (height - ((countY - 1) * borderSpacing)) / countY;
}
@@ -1231,8 +863,6 @@ public class DeviceProfile {
.getInfo().rotation == Surface.ROTATION_270;
if (mIsSeascape != isSeascape) {
mIsSeascape = isSeascape;
- // Hotseat changing sides requires updating workspace left/right paddings
- updateWorkspacePadding();
return true;
}
}
@@ -1271,11 +901,11 @@ public class DeviceProfile {
writer.println(prefix + "DeviceProfile:");
writer.println(prefix + "\t1 dp = " + mMetrics.density + " px");
+ writer.println(prefix + "\tallowRotation:" + allowRotation);
writer.println(prefix + "\tisTablet:" + isTablet);
writer.println(prefix + "\tisPhone:" + isPhone);
writer.println(prefix + "\ttransposeLayoutWithOrientation:"
+ transposeLayoutWithOrientation);
- writer.println(prefix + "\tisGestureMode:" + isGestureMode);
writer.println(prefix + "\tisLandscape:" + isLandscape);
writer.println(prefix + "\tisMultiWindowMode:" + isMultiWindowMode);
@@ -1285,23 +915,19 @@ public class DeviceProfile {
writer.println(prefix + pxToDpStr("windowY", windowY));
writer.println(prefix + pxToDpStr("widthPx", widthPx));
writer.println(prefix + pxToDpStr("heightPx", heightPx));
+
writer.println(prefix + pxToDpStr("availableWidthPx", availableWidthPx));
writer.println(prefix + pxToDpStr("availableHeightPx", availableHeightPx));
- writer.println(prefix + pxToDpStr("mInsets.left", mInsets.left));
- writer.println(prefix + pxToDpStr("mInsets.top", mInsets.top));
- writer.println(prefix + pxToDpStr("mInsets.right", mInsets.right));
- writer.println(prefix + pxToDpStr("mInsets.bottom", mInsets.bottom));
writer.println(prefix + "\taspectRatio:" + aspectRatio);
writer.println(prefix + "\tisScalableGrid:" + isScalableGrid);
- writer.println(prefix + "\tinv.numRows: " + inv.numRows);
- writer.println(prefix + "\tinv.numColumns: " + inv.numColumns);
- writer.println(prefix + "\tinv.numSearchContainerColumns: "
- + inv.numSearchContainerColumns);
+ writer.println(prefix + "\tinv.minCellWidth:" + inv.minCellWidth + "dp");
+ writer.println(prefix + "\tinv.minCellHeight:" + inv.minCellHeight + "dp");
- writer.println(prefix + "\tminCellSize: " + inv.minCellSize[mTypeIndex] + "dp");
+ writer.println(prefix + "\tinv.numColumns:" + inv.numColumns);
+ writer.println(prefix + "\tinv.numRows:" + inv.numRows);
writer.println(prefix + pxToDpStr("cellWidthPx", cellWidthPx));
writer.println(prefix + pxToDpStr("cellHeightPx", cellHeightPx));
@@ -1309,16 +935,7 @@ public class DeviceProfile {
writer.println(prefix + pxToDpStr("getCellSize().x", getCellSize().x));
writer.println(prefix + pxToDpStr("getCellSize().y", getCellSize().y));
- writer.println(prefix + pxToDpStr("cellLayoutBorderSpacePx Horizontal",
- cellLayoutBorderSpacePx.x));
- writer.println(prefix + pxToDpStr("cellLayoutBorderSpacePx Vertical",
- cellLayoutBorderSpacePx.y));
- writer.println(prefix + pxToDpStr("cellLayoutPaddingPx.left", cellLayoutPaddingPx.left));
- writer.println(prefix + pxToDpStr("cellLayoutPaddingPx.top", cellLayoutPaddingPx.top));
- writer.println(prefix + pxToDpStr("cellLayoutPaddingPx.right", cellLayoutPaddingPx.right));
- writer.println(
- prefix + pxToDpStr("cellLayoutPaddingPx.bottom", cellLayoutPaddingPx.bottom));
-
+ writer.println(prefix + "\tinv.iconSize:" + inv.iconSize + "dp");
writer.println(prefix + pxToDpStr("iconSizePx", iconSizePx));
writer.println(prefix + pxToDpStr("iconTextSizePx", iconTextSizePx));
writer.println(prefix + pxToDpStr("iconDrawablePaddingPx", iconDrawablePaddingPx));
@@ -1329,30 +946,22 @@ public class DeviceProfile {
writer.println(prefix + pxToDpStr("folderChildTextSizePx", folderChildTextSizePx));
writer.println(prefix + pxToDpStr("folderChildDrawablePaddingPx",
folderChildDrawablePaddingPx));
- writer.println(prefix + pxToDpStr("folderCellLayoutBorderSpaceOriginalPx",
- folderCellLayoutBorderSpaceOriginalPx));
- writer.println(prefix + pxToDpStr("folderCellLayoutBorderSpacePx Horizontal",
- folderCellLayoutBorderSpacePx.x));
- writer.println(prefix + pxToDpStr("folderCellLayoutBorderSpacePx Vertical",
- folderCellLayoutBorderSpacePx.y));
+ writer.println(prefix + pxToDpStr("folderCellLayoutBorderSpacingPx",
+ folderCellLayoutBorderSpacingPx));
- writer.println(prefix + pxToDpStr("bottomSheetTopPadding", bottomSheetTopPadding));
+ writer.println(prefix + pxToDpStr("cellLayoutBorderSpacingPx",
+ cellLayoutBorderSpacingPx));
+ writer.println(prefix + pxToDpStr("desiredWorkspaceLeftRightMarginPx",
+ desiredWorkspaceLeftRightMarginPx));
- writer.println(prefix + pxToDpStr("allAppsShiftRange", allAppsShiftRange));
- writer.println(prefix + pxToDpStr("allAppsTopPadding", allAppsTopPadding));
writer.println(prefix + pxToDpStr("allAppsIconSizePx", allAppsIconSizePx));
writer.println(prefix + pxToDpStr("allAppsIconTextSizePx", allAppsIconTextSizePx));
writer.println(prefix + pxToDpStr("allAppsIconDrawablePaddingPx",
allAppsIconDrawablePaddingPx));
writer.println(prefix + pxToDpStr("allAppsCellHeightPx", allAppsCellHeightPx));
- writer.println(prefix + pxToDpStr("allAppsCellWidthPx", allAppsCellWidthPx));
- writer.println(prefix + pxToDpStr("allAppsBorderSpacePx", allAppsBorderSpacePx.x));
writer.println(prefix + "\tnumShownAllAppsColumns: " + numShownAllAppsColumns);
- writer.println(prefix + pxToDpStr("allAppsLeftRightPadding", allAppsLeftRightPadding));
- writer.println(prefix + pxToDpStr("allAppsLeftRightMargin", allAppsLeftRightMargin));
writer.println(prefix + pxToDpStr("hotseatBarSizePx", hotseatBarSizePx));
- writer.println(prefix + "\tinv.hotseatColumnSpan: " + inv.hotseatColumnSpan[mTypeIndex]);
writer.println(prefix + pxToDpStr("hotseatCellHeightPx", hotseatCellHeightPx));
writer.println(prefix + pxToDpStr("hotseatBarTopPaddingPx", hotseatBarTopPaddingPx));
writer.println(prefix + pxToDpStr("hotseatBarBottomPaddingPx", hotseatBarBottomPaddingPx));
@@ -1360,23 +969,14 @@ public class DeviceProfile {
hotseatBarSidePaddingStartPx));
writer.println(prefix + pxToDpStr("hotseatBarSidePaddingEndPx",
hotseatBarSidePaddingEndPx));
- writer.println(prefix + pxToDpStr("springLoadedHotseatBarTopMarginPx",
- springLoadedHotseatBarTopMarginPx));
- writer.println(prefix + pxToDpStr("mHotseatPadding.top", mHotseatPadding.top));
- writer.println(prefix + pxToDpStr("mHotseatPadding.bottom", mHotseatPadding.bottom));
- writer.println(prefix + pxToDpStr("mHotseatPadding.left", mHotseatPadding.left));
- writer.println(prefix + pxToDpStr("mHotseatPadding.right", mHotseatPadding.right));
writer.println(prefix + "\tnumShownHotseatIcons: " + numShownHotseatIcons);
- writer.println(prefix + pxToDpStr("hotseatBorderSpace", hotseatBorderSpace));
- writer.println(prefix + "\tisQsbInline: " + isQsbInline);
- writer.println(prefix + pxToDpStr("qsbWidth", qsbWidth));
writer.println(prefix + "\tisTaskbarPresent:" + isTaskbarPresent);
- writer.println(prefix + "\tisTaskbarPresentInApps:" + isTaskbarPresentInApps);
+
writer.println(prefix + pxToDpStr("taskbarSize", taskbarSize));
+ writer.println(prefix + pxToDpStr("nonOverlappingTaskbarInset",
+ nonOverlappingTaskbarInset));
- writer.println(prefix + pxToDpStr("desiredWorkspaceHorizontalMarginPx",
- desiredWorkspaceHorizontalMarginPx));
writer.println(prefix + pxToDpStr("workspacePadding.left", workspacePadding.left));
writer.println(prefix + pxToDpStr("workspacePadding.top", workspacePadding.top));
writer.println(prefix + pxToDpStr("workspacePadding.right", workspacePadding.right));
@@ -1385,7 +985,6 @@ public class DeviceProfile {
writer.println(prefix + pxToDpStr("iconScale", iconScale));
writer.println(prefix + pxToDpStr("cellScaleToFit ", cellScaleToFit));
writer.println(prefix + pxToDpStr("extraSpace", extraSpace));
- writer.println(prefix + pxToDpStr("unscaled extraSpace", extraSpace / iconScale));
if (inv.devicePaddings != null) {
int unscaledExtraSpace = (int) (extraSpace / iconScale);
@@ -1395,48 +994,12 @@ public class DeviceProfile {
writer.println(prefix + pxToDpStr("workspaceTopPadding", workspaceTopPadding));
writer.println(prefix + pxToDpStr("workspaceBottomPadding", workspaceBottomPadding));
writer.println(prefix + pxToDpStr("extraHotseatBottomPadding", extraHotseatBottomPadding));
-
- writer.println(prefix + pxToDpStr("overviewTaskMarginPx", overviewTaskMarginPx));
- writer.println(prefix + pxToDpStr("overviewTaskMarginGridPx", overviewTaskMarginGridPx));
- writer.println(prefix + pxToDpStr("overviewTaskIconSizePx", overviewTaskIconSizePx));
- writer.println(prefix + pxToDpStr("overviewTaskIconDrawableSizePx",
- overviewTaskIconDrawableSizePx));
- writer.println(prefix + pxToDpStr("overviewTaskIconDrawableSizeGridPx",
- overviewTaskIconDrawableSizeGridPx));
- writer.println(prefix + pxToDpStr("overviewTaskThumbnailTopMarginPx",
- overviewTaskThumbnailTopMarginPx));
- writer.println(prefix + pxToDpStr("overviewActionsTopMarginPx",
- overviewActionsTopMarginPx));
- writer.println(prefix + pxToDpStr("overviewActionsHeight",
- overviewActionsHeight));
- writer.println(prefix + pxToDpStr("overviewActionsButtonSpacing",
- overviewActionsButtonSpacing));
- writer.println(prefix + pxToDpStr("overviewPageSpacing", overviewPageSpacing));
- writer.println(prefix + pxToDpStr("overviewRowSpacing", overviewRowSpacing));
- writer.println(prefix + pxToDpStr("overviewGridSideMargin", overviewGridSideMargin));
-
- writer.println(prefix + pxToDpStr("dropTargetBarTopMarginPx", dropTargetBarTopMarginPx));
- writer.println(prefix + pxToDpStr("dropTargetBarSizePx", dropTargetBarSizePx));
- writer.println(
- prefix + pxToDpStr("dropTargetBarBottomMarginPx", dropTargetBarBottomMarginPx));
-
- writer.println(
- prefix + pxToDpStr("workspaceSpringLoadShrunkTop", workspaceSpringLoadShrunkTop));
- writer.println(prefix + pxToDpStr("workspaceSpringLoadShrunkBottom",
- workspaceSpringLoadShrunkBottom));
- writer.println(prefix + pxToDpStr("workspaceSpringLoadedBottomSpace",
- workspaceSpringLoadedBottomSpace));
- writer.println(prefix + pxToDpStr("workspaceSpringLoadedMinNextPageVisiblePx",
- workspaceSpringLoadedMinNextPageVisiblePx));
- writer.println(
- prefix + pxToDpStr("getWorkspaceSpringLoadScale()", getWorkspaceSpringLoadScale()));
}
- private static Context getContext(Context c, Info info, int orientation, WindowBounds bounds) {
+ private static Context getContext(Context c, Info info, int orientation) {
Configuration config = new Configuration(c.getResources().getConfiguration());
config.orientation = orientation;
- config.densityDpi = info.getDensityDpi();
- config.smallestScreenWidthDp = (int) info.smallestSizeDp(bounds);
+ config.densityDpi = info.densityDpi;
return c.createConfigurationContext(config);
}
@@ -1454,35 +1017,6 @@ public class DeviceProfile {
void onDeviceProfileChanged(DeviceProfile dp);
}
- /** Allows registering listeners for {@link DeviceProfile} changes. */
- public interface DeviceProfileListenable {
-
- /** The current device profile. */
- DeviceProfile getDeviceProfile();
-
- /** Registered {@link OnDeviceProfileChangeListener} instances. */
- List<OnDeviceProfileChangeListener> getOnDeviceProfileChangeListeners();
-
- /** Notifies listeners of a {@link DeviceProfile} change. */
- default void dispatchDeviceProfileChanged() {
- DeviceProfile deviceProfile = getDeviceProfile();
- List<OnDeviceProfileChangeListener> listeners = getOnDeviceProfileChangeListeners();
- for (int i = listeners.size() - 1; i >= 0; i--) {
- listeners.get(i).onDeviceProfileChanged(deviceProfile);
- }
- }
-
- /** Register listener for {@link DeviceProfile} changes. */
- default void addOnDeviceProfileChangeListener(OnDeviceProfileChangeListener listener) {
- getOnDeviceProfileChangeListeners().add(listener);
- }
-
- /** Unregister listener for {@link DeviceProfile} changes. */
- default void removeOnDeviceProfileChangeListener(OnDeviceProfileChangeListener listener) {
- getOnDeviceProfileChangeListeners().remove(listener);
- }
- }
-
public static class Builder {
private Context mContext;
private InvariantDeviceProfile mInv;
@@ -1493,7 +1027,6 @@ public class DeviceProfile {
private boolean mIsMultiWindowMode = false;
private Boolean mTransposeLayoutWithOrientation;
- private Boolean mIsGestureMode;
public Builder(Context context, InvariantDeviceProfile inv, Info info) {
mContext = context;
@@ -1522,11 +1055,6 @@ public class DeviceProfile {
return this;
}
- public Builder setGestureMode(boolean isGestureMode) {
- mIsGestureMode = isGestureMode;
- return this;
- }
-
public DeviceProfile build() {
if (mWindowBounds == null) {
throw new IllegalArgumentException("Window bounds not set");
@@ -1534,11 +1062,8 @@ public class DeviceProfile {
if (mTransposeLayoutWithOrientation == null) {
mTransposeLayoutWithOrientation = !mInfo.isTablet(mWindowBounds);
}
- if (mIsGestureMode == null) {
- mIsGestureMode = DisplayController.getNavigationMode(mContext).hasGestures;
- }
- return new DeviceProfile(mContext, mInv, mInfo, mWindowBounds, mIsMultiWindowMode,
- mTransposeLayoutWithOrientation, mUseTwoPanels, mIsGestureMode);
+ return new DeviceProfile(mContext, mInv, mInfo, mWindowBounds,
+ mIsMultiWindowMode, mTransposeLayoutWithOrientation, mUseTwoPanels);
}
}
diff --git a/src/com/android/launcher3/DropTargetBar.java b/src/com/android/launcher3/DropTargetBar.java
index d908440bc8..88f6c498aa 100644
--- a/src/com/android/launcher3/DropTargetBar.java
+++ b/src/com/android/launcher3/DropTargetBar.java
@@ -17,13 +17,14 @@
package com.android.launcher3;
import static com.android.launcher3.ButtonDropTarget.TOOLTIP_DEFAULT;
+import static com.android.launcher3.ButtonDropTarget.TOOLTIP_LEFT;
+import static com.android.launcher3.ButtonDropTarget.TOOLTIP_RIGHT;
import static com.android.launcher3.anim.AlphaUpdateListener.updateVisibility;
import android.animation.TimeInterpolator;
import android.content.Context;
import android.graphics.Rect;
import android.util.AttributeSet;
-import android.util.Log;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.View;
@@ -31,13 +32,10 @@ import android.view.ViewDebug;
import android.view.ViewPropertyAnimator;
import android.widget.FrameLayout;
-import androidx.annotation.NonNull;
-
import com.android.launcher3.anim.Interpolators;
import com.android.launcher3.dragndrop.DragController;
import com.android.launcher3.dragndrop.DragController.DragListener;
import com.android.launcher3.dragndrop.DragOptions;
-import com.android.launcher3.testing.TestProtocol;
/*
* The top bar containing various drop targets: Delete/App Info/Uninstall.
@@ -51,8 +49,6 @@ public class DropTargetBar extends FrameLayout
private final Runnable mFadeAnimationEndRunnable =
() -> updateVisibility(DropTargetBar.this);
- private final Launcher mLauncher;
-
@ViewDebug.ExportedProperty(category = "launcher")
protected boolean mDeferOnDragEnd;
@@ -60,19 +56,16 @@ public class DropTargetBar extends FrameLayout
protected boolean mVisible = false;
private ButtonDropTarget[] mDropTargets;
- private ButtonDropTarget[] mTempTargets;
private ViewPropertyAnimator mCurrentAnimation;
private boolean mIsVertical = true;
public DropTargetBar(Context context, AttributeSet attrs) {
super(context, attrs);
- mLauncher = Launcher.getLauncher(context);
}
public DropTargetBar(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
- mLauncher = Launcher.getLauncher(context);
}
@Override
@@ -83,13 +76,12 @@ public class DropTargetBar extends FrameLayout
mDropTargets[i] = (ButtonDropTarget) getChildAt(i);
mDropTargets[i].setDropTargetBar(this);
}
- mTempTargets = new ButtonDropTarget[getChildCount()];
}
@Override
public void setInsets(Rect insets) {
FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) getLayoutParams();
- DeviceProfile grid = mLauncher.getDeviceProfile();
+ DeviceProfile grid = Launcher.getLauncher(getContext()).getDeviceProfile();
mIsVertical = grid.isVerticalBarLayout();
lp.leftMargin = insets.left;
@@ -98,37 +90,34 @@ public class DropTargetBar extends FrameLayout
lp.rightMargin = insets.right;
int tooltipLocation = TOOLTIP_DEFAULT;
- int horizontalMargin;
- if (grid.isTablet) {
- // XXX: If the icon size changes across orientations, we will have to take
- // that into account here too.
- horizontalMargin = ((grid.widthPx - 2 * grid.edgeMarginPx
- - (grid.inv.numColumns * grid.cellWidthPx))
- / (2 * (grid.inv.numColumns + 1)))
- + grid.edgeMarginPx;
+ if (grid.isVerticalBarLayout()) {
+ lp.width = grid.dropTargetBarSizePx;
+ lp.height = grid.availableHeightPx - 2 * grid.edgeMarginPx;
+ lp.gravity = grid.isSeascape() ? Gravity.RIGHT : Gravity.LEFT;
+ tooltipLocation = grid.isSeascape() ? TOOLTIP_LEFT : TOOLTIP_RIGHT;
} else {
- horizontalMargin = getContext().getResources()
- .getDimensionPixelSize(R.dimen.drop_target_bar_margin_horizontal);
- }
- lp.topMargin += grid.dropTargetBarTopMarginPx;
- lp.bottomMargin += grid.dropTargetBarBottomMarginPx;
- lp.width = grid.availableWidthPx - 2 * horizontalMargin;
- if (mIsVertical) {
- lp.leftMargin = (grid.widthPx - lp.width) / 2;
- lp.rightMargin = (grid.widthPx - lp.width) / 2;
- }
- lp.height = grid.dropTargetBarSizePx;
- lp.gravity = Gravity.CENTER_HORIZONTAL | Gravity.TOP;
+ int gap;
+ if (grid.isTablet) {
+ // XXX: If the icon size changes across orientations, we will have to take
+ // that into account here too.
+ gap = ((grid.widthPx - 2 * grid.edgeMarginPx
+ - (grid.inv.numColumns * grid.cellWidthPx))
+ / (2 * (grid.inv.numColumns + 1)))
+ + grid.edgeMarginPx;
+ } else {
+ gap = getContext().getResources()
+ .getDimensionPixelSize(R.dimen.drop_target_bar_margin_horizontal);
+ }
+ lp.width = grid.availableWidthPx - 2 * gap;
- DeviceProfile dp = mLauncher.getDeviceProfile();
- int horizontalPadding = dp.dropTargetHorizontalPaddingPx;
- int verticalPadding = dp.dropTargetVerticalPaddingPx;
+ lp.topMargin += grid.edgeMarginPx;
+ lp.height = grid.dropTargetBarSizePx;
+ lp.gravity = Gravity.CENTER_HORIZONTAL | Gravity.TOP;
+ }
setLayoutParams(lp);
for (ButtonDropTarget button : mDropTargets) {
button.setTextSize(TypedValue.COMPLEX_UNIT_PX, grid.dropTargetTextSizePx);
button.setToolTipLocation(tooltipLocation);
- button.setPadding(horizontalPadding, verticalPadding, horizontalPadding,
- verticalPadding);
}
}
@@ -144,76 +133,35 @@ public class DropTargetBar extends FrameLayout
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int width = MeasureSpec.getSize(widthMeasureSpec);
int height = MeasureSpec.getSize(heightMeasureSpec);
- int heightSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
-
- int visibleCount = getVisibleButtons(mTempTargets);
- if (visibleCount == 1) {
- int widthSpec = MeasureSpec.makeMeasureSpec(width, MeasureSpec.AT_MOST);
-
- ButtonDropTarget firstButton = mTempTargets[0];
- firstButton.setTextVisible(true);
- firstButton.setIconVisible(true);
- firstButton.measure(widthSpec, heightSpec);
- } else if (visibleCount == 2) {
- DeviceProfile dp = mLauncher.getDeviceProfile();
- int verticalPadding = dp.dropTargetVerticalPaddingPx;
- int horizontalPadding = dp.dropTargetHorizontalPaddingPx;
-
- ButtonDropTarget firstButton = mTempTargets[0];
- firstButton.setTextVisible(true);
- firstButton.setIconVisible(true);
- firstButton.setTextMultiLine(false);
- // Reset second button padding in case it was previously changed to multi-line text.
- firstButton.setPadding(horizontalPadding, verticalPadding, horizontalPadding,
- verticalPadding);
-
- ButtonDropTarget secondButton = mTempTargets[1];
- secondButton.setTextVisible(true);
- secondButton.setIconVisible(true);
- secondButton.setTextMultiLine(false);
- // Reset second button padding in case it was previously changed to multi-line text.
- secondButton.setPadding(horizontalPadding, verticalPadding, horizontalPadding,
- verticalPadding);
-
- float scale = dp.getWorkspaceSpringLoadScale();
- int scaledPanelWidth = (int) (dp.getCellLayoutWidth() * scale);
-
- int availableWidth;
- if (dp.isTwoPanels) {
- // Both buttons for two panel fit to the width of one Cell Layout (less
- // half of the center gap between the buttons).
- int halfButtonGap = dp.dropTargetGapPx / 2;
- availableWidth = scaledPanelWidth - halfButtonGap / 2;
- } else {
- // Both buttons plus the button gap do not display past the edge of the scaled
- // workspace, less a pre-defined gap from the edge of the workspace.
- availableWidth = scaledPanelWidth - dp.dropTargetGapPx
- - 2 * dp.dropTargetButtonWorkspaceEdgeGapPx;
- }
- int widthSpec = MeasureSpec.makeMeasureSpec(availableWidth, MeasureSpec.AT_MOST);
- firstButton.measure(widthSpec, heightSpec);
- if (!mIsVertical) {
- // Remove icons and put the button's text on two lines if text is truncated.
- if (firstButton.isTextTruncated(availableWidth)) {
- firstButton.setIconVisible(false);
- firstButton.setTextMultiLine(true);
- firstButton.setPadding(horizontalPadding, verticalPadding / 2,
- horizontalPadding, verticalPadding / 2);
+ int visibleCount = getVisibleButtonsCount();
+ if (visibleCount == 0) {
+ // do nothing
+ } else if (mIsVertical) {
+ int widthSpec = MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY);
+ int heightSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.AT_MOST);
+
+ for (ButtonDropTarget button : mDropTargets) {
+ if (button.getVisibility() != GONE) {
+ button.setTextVisible(false);
+ button.measure(widthSpec, heightSpec);
}
}
-
- if (!dp.isTwoPanels) {
- availableWidth -= firstButton.getMeasuredWidth() + dp.dropTargetGapPx;
- widthSpec = MeasureSpec.makeMeasureSpec(availableWidth, MeasureSpec.AT_MOST);
+ } else {
+ int availableWidth = width / visibleCount;
+ boolean textVisible = true;
+ for (ButtonDropTarget buttons : mDropTargets) {
+ if (buttons.getVisibility() != GONE) {
+ textVisible = textVisible && !buttons.isTextTruncated(availableWidth);
+ }
}
- secondButton.measure(widthSpec, heightSpec);
- if (!mIsVertical) {
- if (secondButton.isTextTruncated(availableWidth)) {
- secondButton.setIconVisible(false);
- secondButton.setTextMultiLine(true);
- secondButton.setPadding(horizontalPadding, verticalPadding / 2,
- horizontalPadding, verticalPadding / 2);
+
+ int widthSpec = MeasureSpec.makeMeasureSpec(availableWidth, MeasureSpec.AT_MOST);
+ int heightSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
+ for (ButtonDropTarget button : mDropTargets) {
+ if (button.getVisibility() != GONE) {
+ button.setTextVisible(textVisible);
+ button.measure(widthSpec, heightSpec);
}
}
}
@@ -222,66 +170,41 @@ public class DropTargetBar extends FrameLayout
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
- int visibleCount = getVisibleButtons(mTempTargets);
+ int visibleCount = getVisibleButtonsCount();
if (visibleCount == 0) {
- return;
- }
-
- DeviceProfile dp = mLauncher.getDeviceProfile();
- // Center vertical bar over scaled workspace, accounting for hotseat offset.
- float scale = dp.getWorkspaceSpringLoadScale();
- Workspace<?> ws = mLauncher.getWorkspace();
- int barCenter;
- if (dp.isTwoPanels) {
- barCenter = (right - left) / 2;
+ // do nothing
+ } else if (mIsVertical) {
+ int gap = getResources().getDimensionPixelSize(R.dimen.drop_target_vertical_gap);
+ int start = gap;
+ int end;
+
+ for (ButtonDropTarget button : mDropTargets) {
+ if (button.getVisibility() != GONE) {
+ end = start + button.getMeasuredHeight();
+ button.layout(0, start, button.getMeasuredWidth(), end);
+ start = end + gap;
+ }
+ }
} else {
- int workspaceCenter = (ws.getLeft() + ws.getRight()) / 2;
- int cellLayoutCenter = ((dp.getInsets().left + dp.workspacePadding.left) + (dp.widthPx
- - dp.getInsets().right - dp.workspacePadding.right)) / 2;
- int cellLayoutCenterOffset = (int) ((cellLayoutCenter - workspaceCenter) * scale);
- barCenter = workspaceCenter + cellLayoutCenterOffset - left;
- }
-
- if (visibleCount == 1) {
- ButtonDropTarget button = mTempTargets[0];
- button.layout(barCenter - (button.getMeasuredWidth() / 2), 0,
- barCenter + (button.getMeasuredWidth() / 2), button.getMeasuredHeight());
- } else if (visibleCount == 2) {
- int buttonGap = dp.dropTargetGapPx;
-
- ButtonDropTarget leftButton = mTempTargets[0];
- ButtonDropTarget rightButton = mTempTargets[1];
- if (dp.isTwoPanels) {
- leftButton.layout(barCenter - leftButton.getMeasuredWidth() - (buttonGap / 2), 0,
- barCenter - (buttonGap / 2), leftButton.getMeasuredHeight());
- rightButton.layout(barCenter + (buttonGap / 2), 0,
- barCenter + (buttonGap / 2) + rightButton.getMeasuredWidth(),
- rightButton.getMeasuredHeight());
- } else {
- int scaledPanelWidth = (int) (dp.getCellLayoutWidth() * scale);
-
- int leftButtonWidth = leftButton.getMeasuredWidth();
- int rightButtonWidth = rightButton.getMeasuredWidth();
- int extraSpace = scaledPanelWidth - leftButtonWidth - rightButtonWidth - buttonGap;
-
- int leftButtonStart = barCenter - (scaledPanelWidth / 2) + extraSpace / 2;
- int leftButtonEnd = leftButtonStart + leftButtonWidth;
- int rightButtonStart = leftButtonEnd + buttonGap;
- int rightButtonEnd = rightButtonStart + rightButtonWidth;
-
- leftButton.layout(leftButtonStart, 0, leftButtonEnd,
- leftButton.getMeasuredHeight());
- rightButton.layout(rightButtonStart, 0, rightButtonEnd,
- rightButton.getMeasuredHeight());
+ int frameSize = (right - left) / visibleCount;
+
+ int start = frameSize / 2;
+ int halfWidth;
+ for (ButtonDropTarget button : mDropTargets) {
+ if (button.getVisibility() != GONE) {
+ halfWidth = button.getMeasuredWidth() / 2;
+ button.layout(start - halfWidth, 0,
+ start + halfWidth, button.getMeasuredHeight());
+ start = start + frameSize;
+ }
}
}
}
- private int getVisibleButtons(ButtonDropTarget[] outVisibleButtons) {
+ private int getVisibleButtonsCount() {
int visibleCount = 0;
- for (ButtonDropTarget button : mDropTargets) {
- if (button.getVisibility() != GONE) {
- outVisibleButtons[visibleCount] = button;
+ for (ButtonDropTarget buttons : mDropTargets) {
+ if (buttons.getVisibility() != GONE) {
visibleCount++;
}
}
@@ -289,9 +212,6 @@ public class DropTargetBar extends FrameLayout
}
public void animateToVisibility(boolean isVisible) {
- if (TestProtocol.sDebugTracing) {
- Log.d(TestProtocol.NO_DROP_TARGET, "8");
- }
if (mVisible != isVisible) {
mVisible = isVisible;
@@ -318,9 +238,6 @@ public class DropTargetBar extends FrameLayout
*/
@Override
public void onDragStart(DropTarget.DragObject dragObject, DragOptions options) {
- if (TestProtocol.sDebugTracing) {
- Log.d(TestProtocol.NO_DROP_TARGET, "7");
- }
animateToVisibility(true);
}
@@ -342,18 +259,6 @@ public class DropTargetBar extends FrameLayout
}
public ButtonDropTarget[] getDropTargets() {
- return getVisibility() == View.VISIBLE ? mDropTargets : new ButtonDropTarget[0];
- }
-
- @Override
- protected void onVisibilityChanged(@NonNull View changedView, int visibility) {
- super.onVisibilityChanged(changedView, visibility);
- if (TestProtocol.sDebugTracing) {
- if (visibility == VISIBLE) {
- Log.d(TestProtocol.NO_DROP_TARGET, "9");
- } else {
- Log.d(TestProtocol.NO_DROP_TARGET, "Hiding drop target", new Exception());
- }
- }
+ return mDropTargets;
}
}
diff --git a/src/com/android/launcher3/ExtendedEditText.java b/src/com/android/launcher3/ExtendedEditText.java
index 4629ca7a2b..a4e1af6fb3 100644
--- a/src/com/android/launcher3/ExtendedEditText.java
+++ b/src/com/android/launcher3/ExtendedEditText.java
@@ -22,9 +22,11 @@ import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.DragEvent;
import android.view.KeyEvent;
+import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
+import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.views.ActivityContext;
@@ -97,6 +99,8 @@ public class ExtendedEditText extends EditText {
}
}
+ // inherited class can override to change the appearance of the edit text.
+ public void show() {}
public void showKeyboard() {
mShowImeAfterFirstLayout = !showSoftInput();
@@ -104,7 +108,6 @@ public class ExtendedEditText extends EditText {
public void hideKeyboard() {
hideKeyboardAsync(ActivityContext.lookupContext(getContext()), getWindowToken());
- clearFocus();
}
private boolean showSoftInput() {
@@ -137,5 +140,15 @@ public class ExtendedEditText extends EditText {
if (!TextUtils.isEmpty(getText())) {
setText("");
}
+ if (FeatureFlags.ENABLE_DEVICE_SEARCH.get()) {
+ return;
+ }
+ if (isFocused()) {
+ View nextFocus = focusSearch(View.FOCUS_DOWN);
+ if (nextFocus != null) {
+ nextFocus.requestFocus();
+ }
+ }
+ hideKeyboard();
}
}
diff --git a/src/com/android/launcher3/FirstFrameAnimatorHelper.java b/src/com/android/launcher3/FirstFrameAnimatorHelper.java
index fdf0101e66..a199a5779a 100644
--- a/src/com/android/launcher3/FirstFrameAnimatorHelper.java
+++ b/src/com/android/launcher3/FirstFrameAnimatorHelper.java
@@ -15,7 +15,7 @@
*/
package com.android.launcher3;
-import static com.android.launcher3.util.window.RefreshRateTracker.getSingleFrameMs;
+import static com.android.launcher3.util.DisplayController.getSingleFrameMs;
import android.animation.ValueAnimator;
import android.animation.ValueAnimator.AnimatorUpdateListener;
diff --git a/src/com/android/launcher3/GestureNavContract.java b/src/com/android/launcher3/GestureNavContract.java
index c782dca4ca..2a7e629247 100644
--- a/src/com/android/launcher3/GestureNavContract.java
+++ b/src/com/android/launcher3/GestureNavContract.java
@@ -18,30 +18,20 @@ package com.android.launcher3;
import static android.content.Intent.EXTRA_COMPONENT_NAME;
import static android.content.Intent.EXTRA_USER;
-import static com.android.launcher3.AbstractFloatingView.TYPE_ICON_SURFACE;
-
import android.annotation.TargetApi;
import android.content.ComponentName;
import android.content.Intent;
import android.graphics.RectF;
import android.os.Build;
import android.os.Bundle;
-import android.os.Handler;
-import android.os.Looper;
import android.os.Message;
-import android.os.Messenger;
import android.os.RemoteException;
import android.os.UserHandle;
import android.util.Log;
import android.view.SurfaceControl;
-import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
-import com.android.launcher3.views.ActivityContext;
-
-import java.lang.ref.WeakReference;
-
/**
* Class to encapsulate the handshake protocol between Launcher and gestureNav.
*/
@@ -53,7 +43,6 @@ public class GestureNavContract {
public static final String EXTRA_ICON_POSITION = "gesture_nav_contract_icon_position";
public static final String EXTRA_ICON_SURFACE = "gesture_nav_contract_surface_control";
public static final String EXTRA_REMOTE_CALLBACK = "android.intent.extra.REMOTE_CALLBACK";
- public static final String EXTRA_ON_FINISH_CALLBACK = "gesture_nav_contract_finish_callback";
public final ComponentName componentName;
public final UserHandle user;
@@ -70,15 +59,10 @@ public class GestureNavContract {
* Sends the position information to the receiver
*/
@TargetApi(Build.VERSION_CODES.R)
- public void sendEndPosition(RectF position, ActivityContext context,
- @Nullable SurfaceControl surfaceControl) {
+ public void sendEndPosition(RectF position, @Nullable SurfaceControl surfaceControl) {
Bundle result = new Bundle();
result.putParcelable(EXTRA_ICON_POSITION, position);
result.putParcelable(EXTRA_ICON_SURFACE, surfaceControl);
- if (sMessageReceiver == null) {
- sMessageReceiver = new StaticMessageReceiver();
- }
- result.putParcelable(EXTRA_ON_FINISH_CALLBACK, sMessageReceiver.setCurrentContext(context));
Message callback = Message.obtain();
callback.copyFrom(mCallback);
@@ -114,42 +98,4 @@ public class GestureNavContract {
}
return null;
}
-
- /**
- * Message used for receiving gesture nav contract information. We use a static messenger to
- * avoid leaking too make binders in case the receiving launcher does not handle the contract
- * properly.
- */
- private static StaticMessageReceiver sMessageReceiver = null;
-
- private static class StaticMessageReceiver implements Handler.Callback {
-
- private static final int MSG_CLOSE_LAST_TARGET = 0;
-
- private final Messenger mMessenger =
- new Messenger(new Handler(Looper.getMainLooper(), this));
-
- private WeakReference<ActivityContext> mLastTarget = new WeakReference<>(null);
-
- public Message setCurrentContext(ActivityContext context) {
- mLastTarget = new WeakReference<>(context);
-
- Message msg = Message.obtain();
- msg.replyTo = mMessenger;
- msg.what = MSG_CLOSE_LAST_TARGET;
- return msg;
- }
-
- @Override
- public boolean handleMessage(@NonNull Message message) {
- if (message.what == MSG_CLOSE_LAST_TARGET) {
- ActivityContext lastContext = mLastTarget.get();
- if (lastContext != null) {
- AbstractFloatingView.closeOpenViews(lastContext, false, TYPE_ICON_SURFACE);
- }
- return true;
- }
- return false;
- }
- }
}
diff --git a/src/com/android/launcher3/Hotseat.java b/src/com/android/launcher3/Hotseat.java
index 76106fc58d..eaca162e82 100644
--- a/src/com/android/launcher3/Hotseat.java
+++ b/src/com/android/launcher3/Hotseat.java
@@ -41,7 +41,7 @@ public class Hotseat extends CellLayout implements Insettable {
@ViewDebug.ExportedProperty(category = "launcher")
private boolean mHasVerticalHotseat;
- private Workspace<?> mWorkspace;
+ private Workspace mWorkspace;
private boolean mSendTouchToWorkspace;
@Nullable
private Consumer<Boolean> mOnVisibilityAggregatedCallback;
@@ -49,6 +49,8 @@ public class Hotseat extends CellLayout implements Insettable {
private final View mQsb;
private final int mQsbHeight;
+ private final int mTaskbarViewHeight;
+
public Hotseat(Context context) {
this(context, null);
}
@@ -61,9 +63,10 @@ public class Hotseat extends CellLayout implements Insettable {
super(context, attrs, defStyle);
mQsb = LayoutInflater.from(context).inflate(R.layout.search_container_hotseat, this, false);
+ mQsbHeight = mQsb.getLayoutParams().height;
addView(mQsb);
- mQsbHeight = getResources().getDimensionPixelSize(R.dimen.qsb_widget_height);
+ mTaskbarViewHeight = context.getResources().getDimensionPixelSize(R.dimen.taskbar_size);
}
/**
@@ -84,7 +87,6 @@ public class Hotseat extends CellLayout implements Insettable {
removeAllViewsInLayout();
mHasVerticalHotseat = hasVerticalHotseat;
DeviceProfile dp = mActivity.getDeviceProfile();
- resetCellSize(dp);
if (hasVerticalHotseat) {
setGridSize(1, dp.numShownHotseatIcons);
} else {
@@ -111,18 +113,24 @@ public class Hotseat extends CellLayout implements Insettable {
mQsb.setVisibility(View.VISIBLE);
lp.gravity = Gravity.BOTTOM;
lp.width = ViewGroup.LayoutParams.MATCH_PARENT;
- lp.height = grid.isTaskbarPresent
- ? grid.workspacePadding.bottom
- : grid.hotseatBarSizePx + insets.bottom;
+ lp.height = (grid.isTaskbarPresent
+ ? grid.workspacePadding.bottom
+ : grid.hotseatBarSizePx)
+ + (grid.isTaskbarPresent ? grid.taskbarSize : insets.bottom);
+ }
+
+ if (!grid.isTaskbarPresent) {
+ // When taskbar is present, we set the padding separately to ensure a seamless visual
+ // handoff between taskbar and hotseat during drag and drop.
+ Rect padding = grid.getHotseatLayoutPadding();
+ setPadding(padding.left, padding.top, padding.right, padding.bottom);
}
- Rect padding = grid.getHotseatLayoutPadding(getContext());
- setPadding(padding.left, padding.top, padding.right, padding.bottom);
setLayoutParams(lp);
InsettableFrameLayout.dispatchInsets(this, insets);
}
- public void setWorkspace(Workspace<?> w) {
+ public void setWorkspace(Workspace w) {
mWorkspace = w;
}
@@ -151,8 +159,7 @@ public class Hotseat extends CellLayout implements Insettable {
}
return mWorkspace.onTouchEvent(event);
}
- // Always let touch follow through to Workspace.
- return false;
+ return event.getY() > getCellHeight();
}
@Override
@@ -173,9 +180,8 @@ public class Hotseat extends CellLayout implements Insettable {
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
- int qsbWidth = mActivity.getDeviceProfile().qsbWidth;
-
- mQsb.measure(MeasureSpec.makeMeasureSpec(qsbWidth, MeasureSpec.EXACTLY),
+ int width = getShortcutsAndWidgets().getMeasuredWidth();
+ mQsb.measure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
MeasureSpec.makeMeasureSpec(mQsbHeight, MeasureSpec.EXACTLY));
}
@@ -184,32 +190,46 @@ public class Hotseat extends CellLayout implements Insettable {
super.onLayout(changed, l, t, r, b);
int qsbWidth = mQsb.getMeasuredWidth();
- int left;
- if (mActivity.getDeviceProfile().isQsbInline) {
- int qsbSpace = mActivity.getDeviceProfile().hotseatBorderSpace;
- left = Utilities.isRtl(getResources()) ? r - getPaddingRight() + qsbSpace
- : l + getPaddingLeft() - qsbWidth - qsbSpace;
- } else {
- left = (r - l - qsbWidth) / 2;
- }
+ int left = (r - l - qsbWidth) / 2;
int right = left + qsbWidth;
- int bottom = b - t - mActivity.getDeviceProfile().getQsbOffsetY();
+ int bottom = b - t - getQsbOffsetY();
int top = bottom - mQsbHeight;
mQsb.layout(left, top, right, bottom);
}
/**
+ * Returns the number of pixels the QSB is translated from the bottom of the screen.
+ */
+ private int getQsbOffsetY() {
+ DeviceProfile dp = mActivity.getDeviceProfile();
+ int freeSpace = dp.isTaskbarPresent
+ ? dp.workspacePadding.bottom
+ : dp.hotseatBarSizePx - dp.hotseatCellHeightPx - mQsbHeight;
+
+ if (dp.isScalableGrid && dp.qsbBottomMarginPx > dp.getInsets().bottom) {
+ return Math.min(dp.qsbBottomMarginPx, freeSpace);
+ } else {
+ return (int) (freeSpace * QSB_CENTER_FACTOR) + (dp.isTaskbarPresent
+ ? dp.taskbarSize
+ : dp.getInsets().bottom);
+ }
+ }
+
+ /**
+ * Returns the number of pixels the taskbar is translated from the bottom of the screen.
+ */
+ public int getTaskbarOffsetY() {
+ return (getQsbOffsetY() - mTaskbarViewHeight) / 2;
+ }
+
+ /**
* Sets the alpha value of just our ShortcutAndWidgetContainer.
*/
public void setIconsAlpha(float alpha) {
getShortcutsAndWidgets().setAlpha(alpha);
}
- public float getIconsAlpha() {
- return getShortcutsAndWidgets().getAlpha();
- }
-
/**
* Returns the QSB inside hotseat
*/
diff --git a/src/com/android/launcher3/InvariantDeviceProfile.java b/src/com/android/launcher3/InvariantDeviceProfile.java
index db43b44f72..29a0223612 100644
--- a/src/com/android/launcher3/InvariantDeviceProfile.java
+++ b/src/com/android/launcher3/InvariantDeviceProfile.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright (C) 2015 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.
@@ -17,9 +17,9 @@
package com.android.launcher3;
import static com.android.launcher3.Utilities.dpiFromPx;
+import static com.android.launcher3.Utilities.getPointString;
import static com.android.launcher3.config.FeatureFlags.ENABLE_TWO_PANEL_HOME;
import static com.android.launcher3.util.DisplayController.CHANGE_DENSITY;
-import static com.android.launcher3.util.DisplayController.CHANGE_NAVIGATION_MODE;
import static com.android.launcher3.util.DisplayController.CHANGE_SUPPORTED_BOUNDS;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
@@ -32,7 +32,6 @@ import android.content.res.Resources;
import android.content.res.TypedArray;
import android.content.res.XmlResourceParser;
import android.graphics.Point;
-import android.graphics.PointF;
import android.graphics.Rect;
import android.text.TextUtils;
import android.util.AttributeSet;
@@ -43,30 +42,22 @@ import android.util.TypedValue;
import android.util.Xml;
import android.view.Display;
-import androidx.annotation.IntDef;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
-import com.android.launcher3.model.DeviceGridState;
-import com.android.launcher3.provider.RestoreDbTask;
+import com.android.launcher3.testing.TestProtocol;
import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.DisplayController.Info;
import com.android.launcher3.util.IntArray;
import com.android.launcher3.util.MainThreadInitializedObject;
import com.android.launcher3.util.Themes;
import com.android.launcher3.util.WindowBounds;
-import com.android.launcher3.util.window.WindowManagerProxy;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import java.io.IOException;
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Collections;
import java.util.List;
@@ -77,12 +68,11 @@ public class InvariantDeviceProfile {
public static final MainThreadInitializedObject<InvariantDeviceProfile> INSTANCE =
new MainThreadInitializedObject<>(InvariantDeviceProfile::new);
- @Retention(RetentionPolicy.SOURCE)
- @IntDef({TYPE_PHONE, TYPE_MULTI_DISPLAY, TYPE_TABLET})
- public @interface DeviceType{}
- public static final int TYPE_PHONE = 0;
- public static final int TYPE_MULTI_DISPLAY = 1;
- public static final int TYPE_TABLET = 2;
+ public static final String KEY_MIGRATION_SRC_WORKSPACE_SIZE = "migration_src_workspace_size";
+ public static final String KEY_MIGRATION_SRC_HOTSEAT_COUNT = "migration_src_hotseat_count";
+
+ private static final int DEFAULT_TRUE = -1;
+ private static final int DEFAULT_SPLIT_DISPLAY = 2;
private static final String KEY_IDP_GRID_NAME = "idp_grid_name";
@@ -96,56 +86,36 @@ public class InvariantDeviceProfile {
// used to offset float not being able to express extremely small weights in extreme cases.
private static final float WEIGHT_EFFICIENT = 100000f;
- // Used for arrays to specify different sizes (e.g. border spaces, width/height) in different
- // constraints
- static final int COUNT_SIZES = 4;
- static final int INDEX_DEFAULT = 0;
- static final int INDEX_LANDSCAPE = 1;
- static final int INDEX_TWO_PANEL_PORTRAIT = 2;
- static final int INDEX_TWO_PANEL_LANDSCAPE = 3;
-
/**
* Number of icons per row and column in the workspace.
*/
public int numRows;
public int numColumns;
- public int numSearchContainerColumns;
/**
* Number of icons per row and column in the folder.
*/
public int numFolderRows;
public int numFolderColumns;
- public float[] iconSize;
- public float[] iconTextSize;
+ public float iconSize;
+ public float landscapeIconSize;
+ public float landscapeIconTextSize;
public int iconBitmapSize;
public int fillResIconDpi;
- public @DeviceType int deviceType;
-
- public PointF[] minCellSize;
-
- public PointF[] borderSpaces;
- public float folderBorderSpace;
- public float[] hotseatBorderSpaces;
-
- public float[] horizontalMargin;
+ public float iconTextSize;
+ public float allAppsIconSize;
+ public float allAppsIconTextSize;
- public PointF[] allAppsCellSize;
- public float[] allAppsIconSize;
- public float[] allAppsIconTextSize;
- public PointF[] allAppsBorderSpaces;
+ public float minCellHeight;
+ public float minCellWidth;
+ public float borderSpacing;
private SparseArray<TypedValue> mExtraAttrs;
/**
* Number of icons inside the hotseat area.
*/
- public int numShownHotseatIcons;
-
- /**
- * Number of icons inside the hotseat area when using 3 buttons navigation.
- */
- public int numShrunkenHotseatIcons;
+ protected int numShownHotseatIcons;
/**
* Number of icons inside the hotseat area that is stored in the database. This is greater than
@@ -154,8 +124,6 @@ public class InvariantDeviceProfile {
*/
public int numDatabaseHotseatIcons;
- public int[] hotseatColumnSpan;
-
/**
* Number of columns in the all apps list.
*/
@@ -171,15 +139,13 @@ public class InvariantDeviceProfile {
public String dbFile;
public int defaultLayoutId;
int demoModeLayoutId;
- boolean[] inlineQsb = new boolean[COUNT_SIZES];
/**
* An immutable list of supported profiles.
*/
public List<DeviceProfile> supportedProfiles = Collections.EMPTY_LIST;
- @Nullable
- public DevicePaddings devicePaddings;
+ @Nullable public DevicePaddings devicePaddings;
public Point defaultWallpaperSize;
public Rect defaultWidgetPadding;
@@ -187,7 +153,35 @@ public class InvariantDeviceProfile {
private final ArrayList<OnIDPChangeListener> mChangeListeners = new ArrayList<>();
@VisibleForTesting
- public InvariantDeviceProfile() { }
+ public InvariantDeviceProfile() {}
+
+ private InvariantDeviceProfile(InvariantDeviceProfile p) {
+ numRows = p.numRows;
+ numColumns = p.numColumns;
+ numFolderRows = p.numFolderRows;
+ numFolderColumns = p.numFolderColumns;
+ iconSize = p.iconSize;
+ landscapeIconSize = p.landscapeIconSize;
+ iconBitmapSize = p.iconBitmapSize;
+ iconTextSize = p.iconTextSize;
+ landscapeIconTextSize = p.landscapeIconTextSize;
+ numShownHotseatIcons = p.numShownHotseatIcons;
+ numDatabaseHotseatIcons = p.numDatabaseHotseatIcons;
+ numAllAppsColumns = p.numAllAppsColumns;
+ numDatabaseAllAppsColumns = p.numDatabaseAllAppsColumns;
+ isScalable = p.isScalable;
+ devicePaddingId = p.devicePaddingId;
+ minCellHeight = p.minCellHeight;
+ minCellWidth = p.minCellWidth;
+ borderSpacing = p.borderSpacing;
+ dbFile = p.dbFile;
+ allAppsIconSize = p.allAppsIconSize;
+ allAppsIconTextSize = p.allAppsIconTextSize;
+ defaultLayoutId = p.defaultLayoutId;
+ demoModeLayoutId = p.demoModeLayoutId;
+ mExtraAttrs = p.mExtraAttrs;
+ devicePaddings = p.devicePaddings;
+ }
@TargetApi(23)
private InvariantDeviceProfile(Context context) {
@@ -196,12 +190,14 @@ public class InvariantDeviceProfile {
if (!newGridName.equals(gridName)) {
Utilities.getPrefs(context).edit().putString(KEY_IDP_GRID_NAME, newGridName).apply();
}
- new DeviceGridState(this).writeToPrefs(context);
+ Utilities.getPrefs(context).edit()
+ .putInt(KEY_MIGRATION_SRC_HOTSEAT_COUNT, numDatabaseHotseatIcons)
+ .putString(KEY_MIGRATION_SRC_WORKSPACE_SIZE, getPointString(numColumns, numRows))
+ .apply();
- DisplayController.INSTANCE.get(context).setPriorityListener(
+ DisplayController.INSTANCE.get(context).addChangeListener(
(displayContext, info, flags) -> {
- if ((flags & (CHANGE_DENSITY | CHANGE_SUPPORTED_BOUNDS
- | CHANGE_NAVIGATION_MODE)) != 0) {
+ if ((flags & (CHANGE_DENSITY | CHANGE_SUPPORTED_BOUNDS)) != 0) {
onConfigChanged(displayContext);
}
});
@@ -226,80 +222,28 @@ public class InvariantDeviceProfile {
String gridName = getCurrentGridName(context);
// Get the display info based on default display and interpolate it to existing display
- Info defaultInfo = DisplayController.INSTANCE.get(context).getInfo();
- @DeviceType int defaultDeviceType = getDeviceType(defaultInfo);
DisplayOption defaultDisplayOption = invDistWeightedInterpolate(
- defaultInfo,
- getPredefinedDeviceProfiles(context, gridName, defaultDeviceType,
- /*allowDisabledGrid=*/false),
- defaultDeviceType);
+ DisplayController.INSTANCE.get(context).getInfo(),
+ getPredefinedDeviceProfiles(context, gridName, false), false);
Info myInfo = new Info(context, display);
- @DeviceType int deviceType = getDeviceType(myInfo);
DisplayOption myDisplayOption = invDistWeightedInterpolate(
- myInfo,
- getPredefinedDeviceProfiles(context, gridName, deviceType,
- /*allowDisabledGrid=*/false),
- deviceType);
+ myInfo, getPredefinedDeviceProfiles(context, gridName, false), false);
DisplayOption result = new DisplayOption(defaultDisplayOption.grid)
.add(myDisplayOption);
- result.iconSizes[INDEX_DEFAULT] =
- defaultDisplayOption.iconSizes[INDEX_DEFAULT];
- for (int i = 1; i < COUNT_SIZES; i++) {
- result.iconSizes[i] = Math.min(
- defaultDisplayOption.iconSizes[i], myDisplayOption.iconSizes[i]);
- }
-
- System.arraycopy(defaultDisplayOption.minCellSize, 0, result.minCellSize, 0,
- COUNT_SIZES);
- System.arraycopy(defaultDisplayOption.borderSpaces, 0, result.borderSpaces, 0,
- COUNT_SIZES);
- System.arraycopy(defaultDisplayOption.inlineQsb, 0, result.inlineQsb, 0,
- COUNT_SIZES);
-
- initGrid(context, myInfo, result, deviceType);
- }
-
- /**
- * Reinitialize the current grid after a restore, where some grids might now be disabled.
- */
- public void reinitializeAfterRestore(Context context) {
- String currentGridName = getCurrentGridName(context);
- String currentDbFile = dbFile;
- String newGridName = initGrid(context, currentGridName);
- String newDbFile = dbFile;
- if (!newDbFile.equals(currentDbFile)) {
- Log.d(TAG, "Restored grid is disabled : " + currentGridName
- + ", migrating to: " + newGridName
- + ", removing all other grid db files");
- for (String gridDbFile : LauncherFiles.GRID_DB_FILES) {
- if (gridDbFile.equals(currentDbFile)) {
- continue;
- }
- if (context.getDatabasePath(gridDbFile).delete()) {
- Log.d(TAG, "Removed old grid db file: " + gridDbFile);
- }
- }
- setCurrentGrid(context, newGridName);
- }
- }
-
- private static @DeviceType int getDeviceType(Info displayInfo) {
- int flagPhone = 1 << 0;
- int flagTablet = 1 << 1;
-
- int type = displayInfo.supportedBounds.stream()
- .mapToInt(bounds -> displayInfo.isTablet(bounds) ? flagTablet : flagPhone)
- .reduce(0, (a, b) -> a | b);
- if ((type == (flagPhone | flagTablet)) && ENABLE_TWO_PANEL_HOME.get()) {
- // device has profiles supporting both phone and table modes
- return TYPE_MULTI_DISPLAY;
- } else if (type == flagTablet) {
- return TYPE_TABLET;
+ result.iconSize = defaultDisplayOption.iconSize;
+ result.landscapeIconSize = defaultDisplayOption.landscapeIconSize;
+ if (defaultDisplayOption.allAppsIconSize < myDisplayOption.allAppsIconSize) {
+ result.allAppsIconSize = defaultDisplayOption.allAppsIconSize;
} else {
- return TYPE_PHONE;
+ result.allAppsIconSize = myDisplayOption.allAppsIconSize;
}
+ result.minCellHeight = defaultDisplayOption.minCellHeight;
+ result.minCellWidth = defaultDisplayOption.minCellWidth;
+ result.borderSpacing = defaultDisplayOption.borderSpacing;
+
+ initGrid(context, myInfo, result, false);
}
public static String getCurrentGridName(Context context) {
@@ -309,24 +253,33 @@ public class InvariantDeviceProfile {
private String initGrid(Context context, String gridName) {
Info displayInfo = DisplayController.INSTANCE.get(context).getInfo();
- @DeviceType int deviceType = getDeviceType(displayInfo);
+ // Determine if we have split display
+
+ boolean isTablet = false, isPhone = false;
+ for (WindowBounds bounds : displayInfo.supportedBounds) {
+ if (displayInfo.isTablet(bounds)) {
+ isTablet = true;
+ } else {
+ isPhone = true;
+ }
+ }
+ boolean isSplitDisplay = isPhone && isTablet && ENABLE_TWO_PANEL_HOME.get();
ArrayList<DisplayOption> allOptions =
- getPredefinedDeviceProfiles(context, gridName, deviceType,
- RestoreDbTask.isPending(context));
+ getPredefinedDeviceProfiles(context, gridName, isSplitDisplay);
DisplayOption displayOption =
- invDistWeightedInterpolate(displayInfo, allOptions, deviceType);
- initGrid(context, displayInfo, displayOption, deviceType);
+ invDistWeightedInterpolate(displayInfo, allOptions, isSplitDisplay);
+ initGrid(context, displayInfo, displayOption, isSplitDisplay);
return displayOption.grid.name;
}
- private void initGrid(Context context, Info displayInfo, DisplayOption displayOption,
- @DeviceType int deviceType) {
+ private void initGrid(
+ Context context, Info displayInfo, DisplayOption displayOption,
+ boolean isSplitDisplay) {
DisplayMetrics metrics = context.getResources().getDisplayMetrics();
GridOption closestProfile = displayOption.grid;
numRows = closestProfile.numRows;
numColumns = closestProfile.numColumns;
- numSearchContainerColumns = closestProfile.numSearchContainerColumns;
dbFile = closestProfile.dbFile;
defaultLayoutId = closestProfile.defaultLayoutId;
demoModeLayoutId = closestProfile.demoModeLayoutId;
@@ -334,43 +287,32 @@ public class InvariantDeviceProfile {
numFolderColumns = closestProfile.numFolderColumns;
isScalable = closestProfile.isScalable;
devicePaddingId = closestProfile.devicePaddingId;
- this.deviceType = deviceType;
mExtraAttrs = closestProfile.extraAttrs;
- iconSize = displayOption.iconSizes;
- float maxIconSize = iconSize[0];
- for (int i = 1; i < iconSize.length; i++) {
- maxIconSize = Math.max(maxIconSize, iconSize[i]);
- }
- iconBitmapSize = ResourceUtils.pxFromDp(maxIconSize, metrics);
+ iconSize = displayOption.iconSize;
+ landscapeIconSize = displayOption.landscapeIconSize;
+ iconBitmapSize = ResourceUtils.pxFromDp(iconSize, metrics);
+ iconTextSize = displayOption.iconTextSize;
+ landscapeIconTextSize = displayOption.landscapeIconTextSize;
fillResIconDpi = getLauncherIconDensity(iconBitmapSize);
- iconTextSize = displayOption.textSizes;
-
- minCellSize = displayOption.minCellSize;
-
- borderSpaces = displayOption.borderSpaces;
- folderBorderSpace = displayOption.folderBorderSpace;
-
- horizontalMargin = displayOption.horizontalMargin;
+ minCellHeight = displayOption.minCellHeight;
+ minCellWidth = displayOption.minCellWidth;
+ borderSpacing = displayOption.borderSpacing;
numShownHotseatIcons = closestProfile.numHotseatIcons;
- numShrunkenHotseatIcons = closestProfile.numShrunkenHotseatIcons;
- numDatabaseHotseatIcons = deviceType == TYPE_MULTI_DISPLAY
+ numDatabaseHotseatIcons = isSplitDisplay
? closestProfile.numDatabaseHotseatIcons : closestProfile.numHotseatIcons;
- hotseatColumnSpan = closestProfile.hotseatColumnSpan;
- hotseatBorderSpaces = displayOption.hotseatBorderSpaces;
numAllAppsColumns = closestProfile.numAllAppsColumns;
- numDatabaseAllAppsColumns = deviceType == TYPE_MULTI_DISPLAY
+ numDatabaseAllAppsColumns = isSplitDisplay
? closestProfile.numDatabaseAllAppsColumns : closestProfile.numAllAppsColumns;
- allAppsCellSize = displayOption.allAppsCellSize;
- allAppsBorderSpaces = displayOption.allAppsBorderSpaces;
- allAppsIconSize = displayOption.allAppsIconSizes;
- allAppsIconTextSize = displayOption.allAppsIconTextSizes;
- if (!Utilities.isGridOptionsEnabled(context)) {
+ if (Utilities.isGridOptionsEnabled(context)) {
+ allAppsIconSize = displayOption.allAppsIconSize;
+ allAppsIconTextSize = displayOption.allAppsIconTextSize;
+ } else {
allAppsIconSize = iconSize;
allAppsIconTextSize = iconTextSize;
}
@@ -379,8 +321,6 @@ public class InvariantDeviceProfile {
devicePaddings = new DevicePaddings(context, devicePaddingId);
}
- inlineQsb = displayOption.inlineQsb;
-
// If the partner customization apk contains any grid overrides, apply them
// Supported overrides: numRows, numColumns, iconSize
applyPartnerDeviceProfileOverrides(context, metrics);
@@ -389,9 +329,8 @@ public class InvariantDeviceProfile {
defaultWallpaperSize = new Point(displayInfo.currentSize);
for (WindowBounds bounds : displayInfo.supportedBounds) {
localSupportedProfiles.add(new DeviceProfile.Builder(context, this, displayInfo)
- .setUseTwoPanels(deviceType == TYPE_MULTI_DISPLAY)
- .setWindowBounds(bounds)
- .build());
+ .setUseTwoPanels(isSplitDisplay)
+ .setWindowBounds(bounds).build());
// Wallpaper size should be the maximum of the all possible sizes Launcher expects
int displayWidth = bounds.bounds.width();
@@ -401,8 +340,7 @@ public class InvariantDeviceProfile {
// We need to ensure that there is enough extra space in the wallpaper
// for the intended parallax effects
float parallaxFactor =
- dpiFromPx(Math.min(displayWidth, displayHeight), displayInfo.getDensityDpi())
- < 720
+ dpiFromPx(Math.min(displayWidth, displayHeight), displayInfo.densityDpi) < 720
? 2
: wallpaperTravelToScreenWidthRatio(displayWidth, displayHeight);
defaultWallpaperSize.x =
@@ -414,6 +352,11 @@ public class InvariantDeviceProfile {
defaultWidgetPadding = AppWidgetHostView.getDefaultPaddingForWidget(context, cn, null);
}
+ @Nullable
+ public TypedValue getAttrValue(int attr) {
+ return mExtraAttrs == null ? null : mExtraAttrs.get(attr);
+ }
+
public void addOnChangeListener(OnIDPChangeListener listener) {
mChangeListeners.add(listener);
}
@@ -429,29 +372,19 @@ public class InvariantDeviceProfile {
MAIN_EXECUTOR.execute(() -> onConfigChanged(appContext));
}
- private Object[] toModelState() {
- return new Object[]{
- numColumns, numRows, numSearchContainerColumns, numDatabaseHotseatIcons,
- iconBitmapSize, fillResIconDpi, numDatabaseAllAppsColumns, dbFile};
- }
-
private void onConfigChanged(Context context) {
- Object[] oldState = toModelState();
-
// Re-init grid
String gridName = getCurrentGridName(context);
initGrid(context, gridName);
- boolean modelPropsChanged = !Arrays.equals(oldState, toModelState());
for (OnIDPChangeListener listener : mChangeListeners) {
- listener.onIdpChanged(modelPropsChanged);
+ listener.onIdpChanged(this);
}
}
- private static ArrayList<DisplayOption> getPredefinedDeviceProfiles(Context context,
- String gridName, @DeviceType int deviceType, boolean allowDisabledGrid) {
+ private static ArrayList<DisplayOption> getPredefinedDeviceProfiles(
+ Context context, String gridName, boolean isSplitDisplay) {
ArrayList<DisplayOption> profiles = new ArrayList<>();
-
try (XmlResourceParser parser = context.getResources().getXml(R.xml.device_profiles)) {
final int depth = parser.getDepth();
int type;
@@ -460,31 +393,28 @@ public class InvariantDeviceProfile {
if ((type == XmlPullParser.START_TAG)
&& GridOption.TAG_NAME.equals(parser.getName())) {
- GridOption gridOption = new GridOption(context, Xml.asAttributeSet(parser),
- deviceType);
- if (gridOption.isEnabled || allowDisabledGrid) {
- final int displayDepth = parser.getDepth();
- while (((type = parser.next()) != XmlPullParser.END_TAG
- || parser.getDepth() > displayDepth)
- && type != XmlPullParser.END_DOCUMENT) {
- if ((type == XmlPullParser.START_TAG) && "display-option".equals(
- parser.getName())) {
- profiles.add(new DisplayOption(gridOption, context,
- Xml.asAttributeSet(parser)));
- }
+ GridOption gridOption = new GridOption(context, Xml.asAttributeSet(parser));
+ final int displayDepth = parser.getDepth();
+ while (((type = parser.next()) != XmlPullParser.END_TAG ||
+ parser.getDepth() > displayDepth)
+ && type != XmlPullParser.END_DOCUMENT) {
+ if ((type == XmlPullParser.START_TAG) && "display-option".equals(
+ parser.getName())) {
+ profiles.add(new DisplayOption(gridOption, context,
+ Xml.asAttributeSet(parser),
+ isSplitDisplay ? DEFAULT_SPLIT_DISPLAY : DEFAULT_TRUE));
}
}
}
}
- } catch (IOException | XmlPullParserException e) {
+ } catch (IOException|XmlPullParserException e) {
throw new RuntimeException(e);
}
ArrayList<DisplayOption> filteredProfiles = new ArrayList<>();
if (!TextUtils.isEmpty(gridName)) {
for (DisplayOption option : profiles) {
- if (gridName.equals(option.grid.name)
- && (option.grid.isEnabled || allowDisabledGrid)) {
+ if (gridName.equals(option.grid.name)) {
filteredProfiles.add(option);
}
}
@@ -503,36 +433,9 @@ public class InvariantDeviceProfile {
return filteredProfiles;
}
- /**
- * @return all the grid options that can be shown on the device
- */
- public List<GridOption> parseAllGridOptions(Context context) {
- List<GridOption> result = new ArrayList<>();
-
- try (XmlResourceParser parser = context.getResources().getXml(R.xml.device_profiles)) {
- final int depth = parser.getDepth();
- int type;
- while (((type = parser.next()) != XmlPullParser.END_TAG
- || parser.getDepth() > depth) && type != XmlPullParser.END_DOCUMENT) {
- if ((type == XmlPullParser.START_TAG)
- && GridOption.TAG_NAME.equals(parser.getName())) {
- GridOption option =
- new GridOption(context, Xml.asAttributeSet(parser), deviceType);
- if (option.isEnabled) {
- result.add(option);
- }
- }
- }
- } catch (IOException | XmlPullParserException e) {
- Log.e(TAG, "Error parsing device profile", e);
- return Collections.emptyList();
- }
- return result;
- }
-
private int getLauncherIconDensity(int requiredSize) {
// Densities typically defined by an app.
- int[] densityBuckets = new int[]{
+ int[] densityBuckets = new int[] {
DisplayMetrics.DENSITY_LOW,
DisplayMetrics.DENSITY_MEDIUM,
DisplayMetrics.DENSITY_TV,
@@ -571,12 +474,12 @@ public class InvariantDeviceProfile {
}
private static DisplayOption invDistWeightedInterpolate(
- Info displayInfo, ArrayList<DisplayOption> points, @DeviceType int deviceType) {
+ Info displayInfo, ArrayList<DisplayOption> points, boolean isSplitDisplay) {
int minWidthPx = Integer.MAX_VALUE;
int minHeightPx = Integer.MAX_VALUE;
for (WindowBounds bounds : displayInfo.supportedBounds) {
boolean isTablet = displayInfo.isTablet(bounds);
- if (isTablet && deviceType == TYPE_MULTI_DISPLAY) {
+ if (isTablet && isSplitDisplay) {
// For split displays, take half width per page
minWidthPx = Math.min(minWidthPx, bounds.availableSize.x / 2);
minHeightPx = Math.min(minHeightPx, bounds.availableSize.y);
@@ -591,78 +494,48 @@ public class InvariantDeviceProfile {
}
}
- float width = dpiFromPx(minWidthPx, displayInfo.getDensityDpi());
- float height = dpiFromPx(minHeightPx, displayInfo.getDensityDpi());
+ float width = dpiFromPx(minWidthPx, displayInfo.densityDpi);
+ float height = dpiFromPx(minHeightPx, displayInfo.densityDpi);
// Sort the profiles based on the closeness to the device size
Collections.sort(points, (a, b) ->
Float.compare(dist(width, height, a.minWidthDps, a.minHeightDps),
dist(width, height, b.minWidthDps, b.minHeightDps)));
- DisplayOption closestPoint = points.get(0);
- GridOption closestOption = closestPoint.grid;
+ GridOption closestOption = points.get(0).grid;
float weights = 0;
- if (dist(width, height, closestPoint.minWidthDps, closestPoint.minHeightDps) == 0) {
- return closestPoint;
+ DisplayOption p = points.get(0);
+ if (dist(width, height, p.minWidthDps, p.minHeightDps) == 0) {
+ return p;
}
DisplayOption out = new DisplayOption(closestOption);
for (int i = 0; i < points.size() && i < KNEARESTNEIGHBOR; ++i) {
- DisplayOption p = points.get(i);
+ p = points.get(i);
float w = weight(width, height, p.minWidthDps, p.minHeightDps, WEIGHT_POWER);
weights += w;
out.add(new DisplayOption().add(p).multiply(w));
}
- out.multiply(1.0f / weights);
-
- // Since the bitmaps are persisted, ensure that all bitmap sizes are not larger than
- // predefined size to avoid cache invalidation
- for (int i = INDEX_DEFAULT; i < COUNT_SIZES; i++) {
- out.iconSizes[i] = Math.min(out.iconSizes[i], closestPoint.iconSizes[i]);
- }
-
- return out;
+ return out.multiply(1.0f / weights);
}
public DeviceProfile getDeviceProfile(Context context) {
Resources res = context.getResources();
Configuration config = context.getResources().getConfiguration();
- float screenWidth = config.screenWidthDp * res.getDisplayMetrics().density;
- float screenHeight = config.screenHeightDp * res.getDisplayMetrics().density;
- int rotation = WindowManagerProxy.INSTANCE.get(context).getRotation(context);
-
- if (Utilities.IS_DEBUG_DEVICE) {
- StringWriter stringWriter = new StringWriter();
- PrintWriter printWriter = new PrintWriter(stringWriter);
- DisplayController.INSTANCE.get(context).dump(printWriter);
- printWriter.flush();
- Log.d("b/231312158", "getDeviceProfile -"
- + "\nconfig: " + config
- + "\ndisplayMetrics: " + res.getDisplayMetrics()
- + "\nrotation: " + rotation
- + "\n" + stringWriter.toString(),
- new Exception());
- }
- return getBestMatch(screenWidth, screenHeight, rotation);
- }
+ float availableWidth = config.screenWidthDp * res.getDisplayMetrics().density;
+ float availableHeight = config.screenHeightDp * res.getDisplayMetrics().density;
- /**
- * Returns the device profile matching the provided screen configuration
- */
- public DeviceProfile getBestMatch(float screenWidth, float screenHeight, int rotation) {
DeviceProfile bestMatch = supportedProfiles.get(0);
float minDiff = Float.MAX_VALUE;
for (DeviceProfile profile : supportedProfiles) {
- float diff = Math.abs(profile.widthPx - screenWidth)
- + Math.abs(profile.heightPx - screenHeight);
+ float diff = Math.abs(profile.availableWidthPx - availableWidth)
+ + Math.abs(profile.availableHeightPx - availableHeight);
if (diff < minDiff) {
minDiff = diff;
bestMatch = profile;
- } else if (diff == minDiff && profile.rotationHint == rotation) {
- bestMatch = profile;
}
}
return bestMatch;
@@ -688,8 +561,8 @@ public class InvariantDeviceProfile {
// We will use these two data points to extrapolate how much the wallpaper parallax effect
// to span (ie travel) at any aspect ratio:
- final float ASPECT_RATIO_LANDSCAPE = 16 / 10f;
- final float ASPECT_RATIO_PORTRAIT = 10 / 16f;
+ final float ASPECT_RATIO_LANDSCAPE = 16/10f;
+ final float ASPECT_RATIO_PORTRAIT = 10/16f;
final float WALLPAPER_WIDTH_TO_SCREEN_RATIO_LANDSCAPE = 1.5f;
final float WALLPAPER_WIDTH_TO_SCREEN_RATIO_PORTRAIT = 1.2f;
@@ -699,8 +572,7 @@ public class InvariantDeviceProfile {
// (10/16)x + y = 1.2
// We solve for x and y and end up with a final formula:
final float x =
- (WALLPAPER_WIDTH_TO_SCREEN_RATIO_LANDSCAPE
- - WALLPAPER_WIDTH_TO_SCREEN_RATIO_PORTRAIT) /
+ (WALLPAPER_WIDTH_TO_SCREEN_RATIO_LANDSCAPE - WALLPAPER_WIDTH_TO_SCREEN_RATIO_PORTRAIT) /
(ASPECT_RATIO_LANDSCAPE - ASPECT_RATIO_PORTRAIT);
final float y = WALLPAPER_WIDTH_TO_SCREEN_RATIO_PORTRAIT - x * ASPECT_RATIO_PORTRAIT;
return x * aspectRatio + y;
@@ -711,7 +583,7 @@ public class InvariantDeviceProfile {
/**
* Called when the device provide changes
*/
- void onIdpChanged(boolean modelPropertiesChanged);
+ void onIdpChanged(InvariantDeviceProfile profile);
}
@@ -719,17 +591,9 @@ public class InvariantDeviceProfile {
public static final String TAG_NAME = "grid-option";
- private static final int DEVICE_CATEGORY_PHONE = 1 << 0;
- private static final int DEVICE_CATEGORY_TABLET = 1 << 1;
- private static final int DEVICE_CATEGORY_MULTI_DISPLAY = 1 << 2;
- private static final int DEVICE_CATEGORY_ALL =
- DEVICE_CATEGORY_PHONE | DEVICE_CATEGORY_TABLET | DEVICE_CATEGORY_MULTI_DISPLAY;
-
public final String name;
public final int numRows;
public final int numColumns;
- public final int numSearchContainerColumns;
- public final boolean isEnabled;
private final int numFolderRows;
private final int numFolderColumns;
@@ -737,9 +601,7 @@ public class InvariantDeviceProfile {
private final int numAllAppsColumns;
private final int numDatabaseAllAppsColumns;
private final int numHotseatIcons;
- private final int numShrunkenHotseatIcons;
private final int numDatabaseHotseatIcons;
- private final int[] hotseatColumnSpan = new int[COUNT_SIZES];
private final String dbFile;
@@ -751,20 +613,16 @@ public class InvariantDeviceProfile {
private final SparseArray<TypedValue> extraAttrs;
- public GridOption(Context context, AttributeSet attrs, @DeviceType int deviceType) {
+ public GridOption(Context context, AttributeSet attrs) {
TypedArray a = context.obtainStyledAttributes(
attrs, R.styleable.GridDisplayOption);
name = a.getString(R.styleable.GridDisplayOption_name);
numRows = a.getInt(R.styleable.GridDisplayOption_numRows, 0);
numColumns = a.getInt(R.styleable.GridDisplayOption_numColumns, 0);
- numSearchContainerColumns = a.getInt(
- R.styleable.GridDisplayOption_numSearchContainerColumns, numColumns);
dbFile = a.getString(R.styleable.GridDisplayOption_dbFile);
- defaultLayoutId = a.getResourceId(deviceType == TYPE_MULTI_DISPLAY && a.hasValue(
- R.styleable.GridDisplayOption_defaultSplitDisplayLayoutId)
- ? R.styleable.GridDisplayOption_defaultSplitDisplayLayoutId
- : R.styleable.GridDisplayOption_defaultLayoutId, 0);
+ defaultLayoutId = a.getResourceId(
+ R.styleable.GridDisplayOption_defaultLayoutId, 0);
demoModeLayoutId = a.getResourceId(
R.styleable.GridDisplayOption_demoModeLayoutId, defaultLayoutId);
@@ -775,20 +633,8 @@ public class InvariantDeviceProfile {
numHotseatIcons = a.getInt(
R.styleable.GridDisplayOption_numHotseatIcons, numColumns);
- numShrunkenHotseatIcons = a.getInt(
- R.styleable.GridDisplayOption_numShrunkenHotseatIcons, numHotseatIcons / 2);
numDatabaseHotseatIcons = a.getInt(
R.styleable.GridDisplayOption_numExtendedHotseatIcons, 2 * numHotseatIcons);
- hotseatColumnSpan[INDEX_DEFAULT] = a.getInt(
- R.styleable.GridDisplayOption_hotseatColumnSpan, numColumns);
- hotseatColumnSpan[INDEX_LANDSCAPE] = a.getInt(
- R.styleable.GridDisplayOption_hotseatColumnSpanLandscape, numColumns);
- hotseatColumnSpan[INDEX_TWO_PANEL_LANDSCAPE] = a.getInt(
- R.styleable.GridDisplayOption_hotseatColumnSpanTwoPanelLandscape,
- numColumns);
- hotseatColumnSpan[INDEX_TWO_PANEL_PORTRAIT] = a.getInt(
- R.styleable.GridDisplayOption_hotseatColumnSpanTwoPanelPortrait,
- numColumns);
numFolderRows = a.getInt(
R.styleable.GridDisplayOption_numFolderRows, numRows);
@@ -800,16 +646,6 @@ public class InvariantDeviceProfile {
devicePaddingId = a.getResourceId(
R.styleable.GridDisplayOption_devicePaddingId, 0);
- int deviceCategory = a.getInt(R.styleable.GridDisplayOption_deviceCategory,
- DEVICE_CATEGORY_ALL);
- isEnabled = (deviceType == TYPE_PHONE
- && ((deviceCategory & DEVICE_CATEGORY_PHONE) == DEVICE_CATEGORY_PHONE))
- || (deviceType == TYPE_TABLET
- && ((deviceCategory & DEVICE_CATEGORY_TABLET) == DEVICE_CATEGORY_TABLET))
- || (deviceType == TYPE_MULTI_DISPLAY
- && ((deviceCategory & DEVICE_CATEGORY_MULTI_DISPLAY)
- == DEVICE_CATEGORY_MULTI_DISPLAY));
-
a.recycle();
extraAttrs = Themes.createValueMap(context, attrs,
IntArray.wrap(R.styleable.GridDisplayOption));
@@ -818,251 +654,51 @@ public class InvariantDeviceProfile {
@VisibleForTesting
static final class DisplayOption {
- private static final int INLINE_QSB_FOR_PORTRAIT = 1 << 0;
- private static final int INLINE_QSB_FOR_LANDSCAPE = 1 << 1;
- private static final int INLINE_QSB_FOR_TWO_PANEL_PORTRAIT = 1 << 2;
- private static final int INLINE_QSB_FOR_TWO_PANEL_LANDSCAPE = 1 << 3;
- private static final int DONT_INLINE_QSB = 0;
public final GridOption grid;
private final float minWidthDps;
private final float minHeightDps;
private final boolean canBeDefault;
- private final boolean[] inlineQsb = new boolean[COUNT_SIZES];
-
- private final PointF[] minCellSize = new PointF[COUNT_SIZES];
- private float folderBorderSpace;
- private final PointF[] borderSpaces = new PointF[COUNT_SIZES];
- private final float[] horizontalMargin = new float[COUNT_SIZES];
- //TODO(http://b/228998082) remove this when 3 button spaces are fixed
- private final float[] hotseatBorderSpaces = new float[COUNT_SIZES];
+ private float minCellHeight;
+ private float minCellWidth;
+ private float borderSpacing;
- private final float[] iconSizes = new float[COUNT_SIZES];
- private final float[] textSizes = new float[COUNT_SIZES];
+ private float iconSize;
+ private float iconTextSize;
+ private float landscapeIconSize;
+ private float landscapeIconTextSize;
+ private float allAppsIconSize;
+ private float allAppsIconTextSize;
- private final PointF[] allAppsCellSize = new PointF[COUNT_SIZES];
- private final float[] allAppsIconSizes = new float[COUNT_SIZES];
- private final float[] allAppsIconTextSizes = new float[COUNT_SIZES];
- private final PointF[] allAppsBorderSpaces = new PointF[COUNT_SIZES];
-
- DisplayOption(GridOption grid, Context context, AttributeSet attrs) {
+ DisplayOption(GridOption grid, Context context, AttributeSet attrs, int defaultFlagValue) {
this.grid = grid;
- TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ProfileDisplayOption);
+ TypedArray a = context.obtainStyledAttributes(
+ attrs, R.styleable.ProfileDisplayOption);
minWidthDps = a.getFloat(R.styleable.ProfileDisplayOption_minWidthDps, 0);
minHeightDps = a.getFloat(R.styleable.ProfileDisplayOption_minHeightDps, 0);
- canBeDefault = a.getBoolean(R.styleable.ProfileDisplayOption_canBeDefault, false);
-
- int inlineForRotation = a.getInt(R.styleable.ProfileDisplayOption_inlineQsb,
- DONT_INLINE_QSB);
- inlineQsb[INDEX_DEFAULT] =
- (inlineForRotation & INLINE_QSB_FOR_PORTRAIT) == INLINE_QSB_FOR_PORTRAIT;
- inlineQsb[INDEX_LANDSCAPE] =
- (inlineForRotation & INLINE_QSB_FOR_LANDSCAPE) == INLINE_QSB_FOR_LANDSCAPE;
- inlineQsb[INDEX_TWO_PANEL_PORTRAIT] =
- (inlineForRotation & INLINE_QSB_FOR_TWO_PANEL_PORTRAIT)
- == INLINE_QSB_FOR_TWO_PANEL_PORTRAIT;
- inlineQsb[INDEX_TWO_PANEL_LANDSCAPE] =
- (inlineForRotation & INLINE_QSB_FOR_TWO_PANEL_LANDSCAPE)
- == INLINE_QSB_FOR_TWO_PANEL_LANDSCAPE;
-
- float x;
- float y;
-
- x = a.getFloat(R.styleable.ProfileDisplayOption_minCellWidth, 0);
- y = a.getFloat(R.styleable.ProfileDisplayOption_minCellHeight, 0);
- minCellSize[INDEX_DEFAULT] = new PointF(x, y);
-
- x = a.getFloat(R.styleable.ProfileDisplayOption_minCellWidthLandscape,
- minCellSize[INDEX_DEFAULT].x);
- y = a.getFloat(R.styleable.ProfileDisplayOption_minCellHeightLandscape,
- minCellSize[INDEX_DEFAULT].y);
- minCellSize[INDEX_LANDSCAPE] = new PointF(x, y);
-
- x = a.getFloat(R.styleable.ProfileDisplayOption_minCellWidthTwoPanelPortrait,
- minCellSize[INDEX_DEFAULT].x);
- y = a.getFloat(R.styleable.ProfileDisplayOption_minCellHeightTwoPanelPortrait,
- minCellSize[INDEX_DEFAULT].y);
- minCellSize[INDEX_TWO_PANEL_PORTRAIT] = new PointF(x, y);
-
- x = a.getFloat(R.styleable.ProfileDisplayOption_minCellWidthTwoPanelLandscape,
- minCellSize[INDEX_DEFAULT].x);
- y = a.getFloat(R.styleable.ProfileDisplayOption_minCellHeightTwoPanelLandscape,
- minCellSize[INDEX_DEFAULT].y);
- minCellSize[INDEX_TWO_PANEL_LANDSCAPE] = new PointF(x, y);
-
- float borderSpace = a.getFloat(R.styleable.ProfileDisplayOption_borderSpace, 0);
- float borderSpaceLandscape = a.getFloat(
- R.styleable.ProfileDisplayOption_borderSpaceLandscape, borderSpace);
- float borderSpaceTwoPanelPortrait = a.getFloat(
- R.styleable.ProfileDisplayOption_borderSpaceTwoPanelPortrait, borderSpace);
- float borderSpaceTwoPanelLandscape = a.getFloat(
- R.styleable.ProfileDisplayOption_borderSpaceTwoPanelLandscape, borderSpace);
-
- x = a.getFloat(R.styleable.ProfileDisplayOption_borderSpaceHorizontal, borderSpace);
- y = a.getFloat(R.styleable.ProfileDisplayOption_borderSpaceVertical, borderSpace);
- borderSpaces[INDEX_DEFAULT] = new PointF(x, y);
-
- x = a.getFloat(R.styleable.ProfileDisplayOption_borderSpaceLandscapeHorizontal,
- borderSpaceLandscape);
- y = a.getFloat(R.styleable.ProfileDisplayOption_borderSpaceLandscapeVertical,
- borderSpaceLandscape);
- borderSpaces[INDEX_LANDSCAPE] = new PointF(x, y);
-
- x = a.getFloat(
- R.styleable.ProfileDisplayOption_borderSpaceTwoPanelPortraitHorizontal,
- borderSpaceTwoPanelPortrait);
- y = a.getFloat(
- R.styleable.ProfileDisplayOption_borderSpaceTwoPanelPortraitVertical,
- borderSpaceTwoPanelPortrait);
- borderSpaces[INDEX_TWO_PANEL_PORTRAIT] = new PointF(x, y);
-
- x = a.getFloat(
- R.styleable.ProfileDisplayOption_borderSpaceTwoPanelLandscapeHorizontal,
- borderSpaceTwoPanelLandscape);
- y = a.getFloat(
- R.styleable.ProfileDisplayOption_borderSpaceTwoPanelLandscapeVertical,
- borderSpaceTwoPanelLandscape);
- borderSpaces[INDEX_TWO_PANEL_LANDSCAPE] = new PointF(x, y);
-
- folderBorderSpace = borderSpace;
-
- x = a.getFloat(R.styleable.ProfileDisplayOption_allAppsCellWidth,
- minCellSize[INDEX_DEFAULT].x);
- y = a.getFloat(R.styleable.ProfileDisplayOption_allAppsCellHeight,
- minCellSize[INDEX_DEFAULT].y);
- allAppsCellSize[INDEX_DEFAULT] = new PointF(x, y);
-
- x = a.getFloat(R.styleable.ProfileDisplayOption_allAppsCellWidthLandscape,
- allAppsCellSize[INDEX_DEFAULT].x);
- y = a.getFloat(R.styleable.ProfileDisplayOption_allAppsCellHeightLandscape,
- allAppsCellSize[INDEX_DEFAULT].y);
- allAppsCellSize[INDEX_LANDSCAPE] = new PointF(x, y);
-
- x = a.getFloat(R.styleable.ProfileDisplayOption_allAppsCellWidthTwoPanelPortrait,
- allAppsCellSize[INDEX_DEFAULT].x);
- y = a.getFloat(R.styleable.ProfileDisplayOption_allAppsCellHeightTwoPanelPortrait,
- allAppsCellSize[INDEX_DEFAULT].y);
- allAppsCellSize[INDEX_TWO_PANEL_PORTRAIT] = new PointF(x, y);
-
- x = a.getFloat(R.styleable.ProfileDisplayOption_allAppsCellWidthTwoPanelLandscape,
- allAppsCellSize[INDEX_DEFAULT].x);
- y = a.getFloat(R.styleable.ProfileDisplayOption_allAppsCellHeightTwoPanelLandscape,
- allAppsCellSize[INDEX_DEFAULT].y);
- allAppsCellSize[INDEX_TWO_PANEL_LANDSCAPE] = new PointF(x, y);
-
- float allAppsBorderSpace = a.getFloat(
- R.styleable.ProfileDisplayOption_allAppsBorderSpace, borderSpace);
- float allAppsBorderSpaceLandscape = a.getFloat(
- R.styleable.ProfileDisplayOption_allAppsBorderSpaceLandscape,
- allAppsBorderSpace);
- float allAppsBorderSpaceTwoPanelPortrait = a.getFloat(
- R.styleable.ProfileDisplayOption_allAppsBorderSpaceTwoPanelPortrait,
- allAppsBorderSpace);
- float allAppsBorderSpaceTwoPanelLandscape = a.getFloat(
- R.styleable.ProfileDisplayOption_allAppsBorderSpaceTwoPanelLandscape,
- allAppsBorderSpace);
-
- x = a.getFloat(R.styleable.ProfileDisplayOption_allAppsBorderSpaceHorizontal,
- allAppsBorderSpace);
- y = a.getFloat(R.styleable.ProfileDisplayOption_allAppsBorderSpaceVertical,
- allAppsBorderSpace);
- allAppsBorderSpaces[INDEX_DEFAULT] = new PointF(x, y);
-
- x = a.getFloat(R.styleable.ProfileDisplayOption_allAppsBorderSpaceLandscapeHorizontal,
- allAppsBorderSpaceLandscape);
- y = a.getFloat(R.styleable.ProfileDisplayOption_allAppsBorderSpaceLandscapeVertical,
- allAppsBorderSpaceLandscape);
- allAppsBorderSpaces[INDEX_LANDSCAPE] = new PointF(x, y);
-
- x = a.getFloat(
- R.styleable.ProfileDisplayOption_allAppsBorderSpaceTwoPanelPortraitHorizontal,
- allAppsBorderSpaceTwoPanelPortrait);
- y = a.getFloat(
- R.styleable.ProfileDisplayOption_allAppsBorderSpaceTwoPanelPortraitVertical,
- allAppsBorderSpaceTwoPanelPortrait);
- allAppsBorderSpaces[INDEX_TWO_PANEL_PORTRAIT] = new PointF(x, y);
-
- x = a.getFloat(
- R.styleable.ProfileDisplayOption_allAppsBorderSpaceTwoPanelLandscapeHorizontal,
- allAppsBorderSpaceTwoPanelLandscape);
- y = a.getFloat(
- R.styleable.ProfileDisplayOption_allAppsBorderSpaceTwoPanelLandscapeVertical,
- allAppsBorderSpaceTwoPanelLandscape);
- allAppsBorderSpaces[INDEX_TWO_PANEL_LANDSCAPE] = new PointF(x, y);
-
- iconSizes[INDEX_DEFAULT] =
- a.getFloat(R.styleable.ProfileDisplayOption_iconImageSize, 0);
- iconSizes[INDEX_LANDSCAPE] =
- a.getFloat(R.styleable.ProfileDisplayOption_iconSizeLandscape,
- iconSizes[INDEX_DEFAULT]);
- iconSizes[INDEX_TWO_PANEL_PORTRAIT] =
- a.getFloat(R.styleable.ProfileDisplayOption_iconSizeTwoPanelPortrait,
- iconSizes[INDEX_DEFAULT]);
- iconSizes[INDEX_TWO_PANEL_LANDSCAPE] =
- a.getFloat(R.styleable.ProfileDisplayOption_iconSizeTwoPanelLandscape,
- iconSizes[INDEX_DEFAULT]);
-
- allAppsIconSizes[INDEX_DEFAULT] = a.getFloat(
- R.styleable.ProfileDisplayOption_allAppsIconSize, iconSizes[INDEX_DEFAULT]);
- allAppsIconSizes[INDEX_LANDSCAPE] = allAppsIconSizes[INDEX_DEFAULT];
- allAppsIconSizes[INDEX_TWO_PANEL_PORTRAIT] = a.getFloat(
- R.styleable.ProfileDisplayOption_allAppsIconSizeTwoPanelPortrait,
- allAppsIconSizes[INDEX_DEFAULT]);
- allAppsIconSizes[INDEX_TWO_PANEL_LANDSCAPE] = a.getFloat(
- R.styleable.ProfileDisplayOption_allAppsIconSizeTwoPanelLandscape,
- allAppsIconSizes[INDEX_DEFAULT]);
-
- textSizes[INDEX_DEFAULT] =
- a.getFloat(R.styleable.ProfileDisplayOption_iconTextSize, 0);
- textSizes[INDEX_LANDSCAPE] =
- a.getFloat(R.styleable.ProfileDisplayOption_iconTextSizeLandscape,
- textSizes[INDEX_DEFAULT]);
- textSizes[INDEX_TWO_PANEL_PORTRAIT] =
- a.getFloat(R.styleable.ProfileDisplayOption_iconTextSizeTwoPanelPortrait,
- textSizes[INDEX_DEFAULT]);
- textSizes[INDEX_TWO_PANEL_LANDSCAPE] =
- a.getFloat(R.styleable.ProfileDisplayOption_iconTextSizeTwoPanelLandscape,
- textSizes[INDEX_DEFAULT]);
-
- allAppsIconTextSizes[INDEX_DEFAULT] = a.getFloat(
- R.styleable.ProfileDisplayOption_allAppsIconTextSize, textSizes[INDEX_DEFAULT]);
- allAppsIconTextSizes[INDEX_LANDSCAPE] = allAppsIconTextSizes[INDEX_DEFAULT];
- allAppsIconTextSizes[INDEX_TWO_PANEL_PORTRAIT] = a.getFloat(
- R.styleable.ProfileDisplayOption_allAppsIconTextSizeTwoPanelPortrait,
- allAppsIconTextSizes[INDEX_DEFAULT]);
- allAppsIconTextSizes[INDEX_TWO_PANEL_LANDSCAPE] = a.getFloat(
- R.styleable.ProfileDisplayOption_allAppsIconTextSizeTwoPanelLandscape,
- allAppsIconTextSizes[INDEX_DEFAULT]);
-
- horizontalMargin[INDEX_DEFAULT] = a.getFloat(
- R.styleable.ProfileDisplayOption_horizontalMargin, 0);
- horizontalMargin[INDEX_LANDSCAPE] = a.getFloat(
- R.styleable.ProfileDisplayOption_horizontalMarginLandscape,
- horizontalMargin[INDEX_DEFAULT]);
- horizontalMargin[INDEX_TWO_PANEL_LANDSCAPE] = a.getFloat(
- R.styleable.ProfileDisplayOption_horizontalMarginTwoPanelLandscape,
- horizontalMargin[INDEX_DEFAULT]);
- horizontalMargin[INDEX_TWO_PANEL_PORTRAIT] = a.getFloat(
- R.styleable.ProfileDisplayOption_horizontalMarginTwoPanelPortrait,
- horizontalMargin[INDEX_DEFAULT]);
-
- hotseatBorderSpaces[INDEX_DEFAULT] = a.getFloat(
- R.styleable.ProfileDisplayOption_hotseatBorderSpace, borderSpace);
- hotseatBorderSpaces[INDEX_LANDSCAPE] = a.getFloat(
- R.styleable.ProfileDisplayOption_hotseatBorderSpaceLandscape,
- hotseatBorderSpaces[INDEX_DEFAULT]);
- hotseatBorderSpaces[INDEX_TWO_PANEL_LANDSCAPE] = a.getFloat(
- R.styleable.ProfileDisplayOption_hotseatBorderSpaceTwoPanelLandscape,
- hotseatBorderSpaces[INDEX_DEFAULT]);
- hotseatBorderSpaces[INDEX_TWO_PANEL_PORTRAIT] = a.getFloat(
- R.styleable.ProfileDisplayOption_hotseatBorderSpaceTwoPanelPortrait,
- hotseatBorderSpaces[INDEX_DEFAULT]);
+ canBeDefault = a.getInt(R.styleable.ProfileDisplayOption_canBeDefault, 0)
+ == defaultFlagValue;
+ minCellHeight = a.getFloat(R.styleable.ProfileDisplayOption_minCellHeightDps, 0);
+ minCellWidth = a.getFloat(R.styleable.ProfileDisplayOption_minCellWidthDps, 0);
+ borderSpacing = a.getFloat(R.styleable.ProfileDisplayOption_borderSpacingDps, 0);
+
+ iconSize = a.getFloat(R.styleable.ProfileDisplayOption_iconImageSize, 0);
+ landscapeIconSize = a.getFloat(R.styleable.ProfileDisplayOption_landscapeIconSize,
+ iconSize);
+ iconTextSize = a.getFloat(R.styleable.ProfileDisplayOption_iconTextSize, 0);
+ landscapeIconTextSize = a.getFloat(
+ R.styleable.ProfileDisplayOption_landscapeIconTextSize, iconTextSize);
+
+ allAppsIconSize = a.getFloat(R.styleable.ProfileDisplayOption_allAppsIconSize,
+ iconSize);
+ allAppsIconTextSize = a.getFloat(R.styleable.ProfileDisplayOption_allAppsIconTextSize,
+ iconTextSize);
a.recycle();
}
@@ -1075,63 +711,34 @@ public class InvariantDeviceProfile {
minWidthDps = 0;
minHeightDps = 0;
canBeDefault = false;
- for (int i = 0; i < COUNT_SIZES; i++) {
- iconSizes[i] = 0;
- textSizes[i] = 0;
- borderSpaces[i] = new PointF();
- minCellSize[i] = new PointF();
- allAppsCellSize[i] = new PointF();
- allAppsIconSizes[i] = 0;
- allAppsIconTextSizes[i] = 0;
- allAppsBorderSpaces[i] = new PointF();
- inlineQsb[i] = false;
- }
+ minCellHeight = 0;
+ minCellWidth = 0;
+ borderSpacing = 0;
}
private DisplayOption multiply(float w) {
- for (int i = 0; i < COUNT_SIZES; i++) {
- iconSizes[i] *= w;
- textSizes[i] *= w;
- borderSpaces[i].x *= w;
- borderSpaces[i].y *= w;
- minCellSize[i].x *= w;
- minCellSize[i].y *= w;
- horizontalMargin[i] *= w;
- hotseatBorderSpaces[i] *= w;
- allAppsCellSize[i].x *= w;
- allAppsCellSize[i].y *= w;
- allAppsIconSizes[i] *= w;
- allAppsIconTextSizes[i] *= w;
- allAppsBorderSpaces[i].x *= w;
- allAppsBorderSpaces[i].y *= w;
- }
-
- folderBorderSpace *= w;
-
+ iconSize *= w;
+ landscapeIconSize *= w;
+ allAppsIconSize *= w;
+ iconTextSize *= w;
+ landscapeIconTextSize *= w;
+ allAppsIconTextSize *= w;
+ minCellHeight *= w;
+ minCellWidth *= w;
+ borderSpacing *= w;
return this;
}
private DisplayOption add(DisplayOption p) {
- for (int i = 0; i < COUNT_SIZES; i++) {
- iconSizes[i] += p.iconSizes[i];
- textSizes[i] += p.textSizes[i];
- borderSpaces[i].x += p.borderSpaces[i].x;
- borderSpaces[i].y += p.borderSpaces[i].y;
- minCellSize[i].x += p.minCellSize[i].x;
- minCellSize[i].y += p.minCellSize[i].y;
- horizontalMargin[i] += p.horizontalMargin[i];
- hotseatBorderSpaces[i] += p.hotseatBorderSpaces[i];
- allAppsCellSize[i].x += p.allAppsCellSize[i].x;
- allAppsCellSize[i].y += p.allAppsCellSize[i].y;
- allAppsIconSizes[i] += p.allAppsIconSizes[i];
- allAppsIconTextSizes[i] += p.allAppsIconTextSizes[i];
- allAppsBorderSpaces[i].x += p.allAppsBorderSpaces[i].x;
- allAppsBorderSpaces[i].y += p.allAppsBorderSpaces[i].y;
- inlineQsb[i] |= p.inlineQsb[i];
- }
-
- folderBorderSpace += p.folderBorderSpace;
-
+ iconSize += p.iconSize;
+ landscapeIconSize += p.landscapeIconSize;
+ allAppsIconSize += p.allAppsIconSize;
+ iconTextSize += p.iconTextSize;
+ landscapeIconTextSize += p.landscapeIconTextSize;
+ allAppsIconTextSize += p.allAppsIconTextSize;
+ minCellHeight += p.minCellHeight;
+ minCellWidth += p.minCellWidth;
+ borderSpacing += p.borderSpacing;
return this;
}
}
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index ebed31bd54..099f256982 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -16,8 +16,6 @@
package com.android.launcher3;
-import static android.app.PendingIntent.FLAG_IMMUTABLE;
-import static android.app.PendingIntent.FLAG_UPDATE_CURRENT;
import static android.content.pm.ActivityInfo.CONFIG_ORIENTATION;
import static android.content.pm.ActivityInfo.CONFIG_SCREEN_SIZE;
import static android.content.pm.ActivityInfo.CONFIG_UI_MODE;
@@ -25,13 +23,10 @@ import static android.view.View.IMPORTANT_FOR_ACCESSIBILITY_NO;
import static android.view.accessibility.AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED;
import static com.android.launcher3.AbstractFloatingView.TYPE_ALL;
-import static com.android.launcher3.AbstractFloatingView.TYPE_FOLDER;
import static com.android.launcher3.AbstractFloatingView.TYPE_ICON_SURFACE;
import static com.android.launcher3.AbstractFloatingView.TYPE_REBIND_SAFE;
import static com.android.launcher3.AbstractFloatingView.TYPE_SNACKBAR;
-import static com.android.launcher3.AbstractFloatingView.getTopOpenViewWithType;
import static com.android.launcher3.LauncherAnimUtils.SPRING_LOADED_EXIT_DELAY;
-import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_APPLICATION;
import static com.android.launcher3.LauncherState.ALL_APPS;
import static com.android.launcher3.LauncherState.FLAG_CLOSE_POPUPS;
import static com.android.launcher3.LauncherState.FLAG_MULTI_PAGE;
@@ -42,7 +37,7 @@ import static com.android.launcher3.LauncherState.NO_SCALE;
import static com.android.launcher3.LauncherState.SPRING_LOADED;
import static com.android.launcher3.Utilities.postAsyncCallback;
import static com.android.launcher3.accessibility.LauncherAccessibilityDelegate.getSupportedActions;
-import static com.android.launcher3.logging.StatsLogManager.EventEnum;
+import static com.android.launcher3.dragndrop.DragLayer.ALPHA_INDEX_LAUNCHER_LOAD;
import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_BACKGROUND;
import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_HOME;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ALLAPPS_ENTRY;
@@ -53,17 +48,17 @@ import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCH
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_WIDGET_RECONFIGURED;
import static com.android.launcher3.model.ItemInstallQueue.FLAG_ACTIVITY_PAUSED;
import static com.android.launcher3.model.ItemInstallQueue.FLAG_DRAG_AND_DROP;
+import static com.android.launcher3.model.ItemInstallQueue.FLAG_LOADER_RUNNING;
import static com.android.launcher3.popup.SystemShortcut.APP_INFO;
import static com.android.launcher3.popup.SystemShortcut.INSTALL;
import static com.android.launcher3.popup.SystemShortcut.WIDGETS;
import static com.android.launcher3.states.RotationHelper.REQUEST_LOCK;
import static com.android.launcher3.states.RotationHelper.REQUEST_NONE;
-import static com.android.launcher3.testing.TestProtocol.BAD_STATE;
-import static com.android.launcher3.util.ItemInfoMatcher.forFolderMatch;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
+import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.annotation.TargetApi;
import android.app.Notification;
@@ -85,7 +80,6 @@ import android.content.res.Configuration;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.Bitmap;
import android.graphics.Rect;
-import android.graphics.RectF;
import android.os.Build;
import android.os.Bundle;
import android.os.CancellationSignal;
@@ -93,8 +87,6 @@ import android.os.Parcelable;
import android.os.Process;
import android.os.StrictMode;
import android.os.SystemClock;
-import android.os.Trace;
-import android.os.UserHandle;
import android.text.TextUtils;
import android.text.method.TextKeyListener;
import android.util.Log;
@@ -107,7 +99,6 @@ import android.view.Menu;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
-import android.view.ViewTreeObserver.OnPreDrawListener;
import android.view.WindowManager.LayoutParams;
import android.view.accessibility.AccessibilityEvent;
import android.view.animation.OvershootInterpolator;
@@ -115,19 +106,16 @@ import android.widget.ImageView;
import android.widget.Toast;
import androidx.annotation.CallSuper;
-import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
import androidx.annotation.VisibleForTesting;
import com.android.launcher3.DropTarget.DragObject;
-import com.android.launcher3.accessibility.BaseAccessibilityDelegate.LauncherAction;
import com.android.launcher3.accessibility.LauncherAccessibilityDelegate;
-import com.android.launcher3.allapps.ActivityAllAppsContainerView;
-import com.android.launcher3.allapps.AllAppsRecyclerView;
+import com.android.launcher3.accessibility.LauncherAccessibilityDelegate.LauncherAction;
+import com.android.launcher3.allapps.AllAppsContainerView;
import com.android.launcher3.allapps.AllAppsStore;
import com.android.launcher3.allapps.AllAppsTransitionController;
-import com.android.launcher3.allapps.BaseAllAppsContainerView;
import com.android.launcher3.allapps.DiscoveryBounce;
import com.android.launcher3.anim.PropertyListBuilder;
import com.android.launcher3.compat.AccessibilityManagerCompat;
@@ -144,8 +132,6 @@ import com.android.launcher3.icons.BitmapRenderer;
import com.android.launcher3.icons.IconCache;
import com.android.launcher3.keyboard.ViewGroupFocusHelper;
import com.android.launcher3.logger.LauncherAtom;
-import com.android.launcher3.logger.LauncherAtom.ContainerInfo;
-import com.android.launcher3.logger.LauncherAtom.WorkspaceContainer;
import com.android.launcher3.logging.FileLog;
import com.android.launcher3.logging.InstanceId;
import com.android.launcher3.logging.InstanceIdSequence;
@@ -154,7 +140,6 @@ import com.android.launcher3.model.BgDataModel.Callbacks;
import com.android.launcher3.model.ItemInstallQueue;
import com.android.launcher3.model.ModelUtils;
import com.android.launcher3.model.ModelWriter;
-import com.android.launcher3.model.StringCache;
import com.android.launcher3.model.WidgetsModel;
import com.android.launcher3.model.data.AppInfo;
import com.android.launcher3.model.data.FolderInfo;
@@ -164,7 +149,6 @@ import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.launcher3.notification.NotificationListener;
import com.android.launcher3.pm.PinRequestHelper;
import com.android.launcher3.pm.UserCache;
-import com.android.launcher3.popup.ArrowPopup;
import com.android.launcher3.popup.PopupContainerWithArrow;
import com.android.launcher3.popup.PopupDataProvider;
import com.android.launcher3.popup.SystemShortcut;
@@ -182,12 +166,13 @@ import com.android.launcher3.util.ActivityResultInfo;
import com.android.launcher3.util.ActivityTracker;
import com.android.launcher3.util.ComponentKey;
import com.android.launcher3.util.IntArray;
-import com.android.launcher3.util.IntSet;
+import com.android.launcher3.util.ItemInfoMatcher;
+import com.android.launcher3.util.MultiValueAlpha;
+import com.android.launcher3.util.MultiValueAlpha.AlphaProperty;
import com.android.launcher3.util.OnboardingPrefs;
import com.android.launcher3.util.PackageManagerHelper;
import com.android.launcher3.util.PackageUserKey;
import com.android.launcher3.util.PendingRequestArgs;
-import com.android.launcher3.util.RunnableList;
import com.android.launcher3.util.SafeCloseable;
import com.android.launcher3.util.SystemUiController;
import com.android.launcher3.util.Themes;
@@ -197,7 +182,6 @@ import com.android.launcher3.util.TraceHelper;
import com.android.launcher3.util.UiThreadHelper;
import com.android.launcher3.util.ViewOnDrawExecutor;
import com.android.launcher3.views.ActivityContext;
-import com.android.launcher3.views.FloatingIconView;
import com.android.launcher3.views.FloatingSurfaceView;
import com.android.launcher3.views.OptionsPopupView;
import com.android.launcher3.views.ScrimView;
@@ -212,7 +196,7 @@ import com.android.launcher3.widget.WidgetManagerHelper;
import com.android.launcher3.widget.custom.CustomWidgetManager;
import com.android.launcher3.widget.model.WidgetsListBaseEntry;
import com.android.launcher3.widget.picker.WidgetsFullSheet;
-import com.android.systemui.plugins.LauncherOverlayPlugin;
+import com.android.systemui.plugins.OverlayPlugin;
import com.android.systemui.plugins.PluginListener;
import com.android.systemui.plugins.shared.LauncherExterns;
import com.android.systemui.plugins.shared.LauncherOverlayManager;
@@ -223,11 +207,9 @@ import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collection;
-import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
-import java.util.Optional;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.stream.Stream;
@@ -235,9 +217,8 @@ import java.util.stream.Stream;
/**
* Default launcher application.
*/
-public class Launcher extends StatefulActivity<LauncherState>
- implements LauncherExterns, Callbacks, InvariantDeviceProfile.OnIDPChangeListener,
- PluginListener<LauncherOverlayPlugin>, LauncherOverlayCallbacks {
+public class Launcher extends StatefulActivity<LauncherState> implements LauncherExterns,
+ Callbacks, InvariantDeviceProfile.OnIDPChangeListener, PluginListener<OverlayPlugin> {
public static final String TAG = "Launcher";
public static final ActivityTracker<Launcher> ACTIVITY_TRACKER = new ActivityTracker<>();
@@ -266,6 +247,8 @@ public class Launcher extends StatefulActivity<LauncherState>
protected static final int REQUEST_LAST = 100;
// Type: int
+ private static final String RUNTIME_STATE_CURRENT_SCREEN = "launcher.current_screen";
+ // Type: int
private static final String RUNTIME_STATE = "launcher.state";
// Type: PendingRequestArgs
private static final String RUNTIME_STATE_PENDING_REQUEST_ARGS = "launcher.request_args";
@@ -275,8 +258,6 @@ public class Launcher extends StatefulActivity<LauncherState>
private static final String RUNTIME_STATE_PENDING_ACTIVITY_RESULT = "launcher.activity_result";
// Type: SparseArray<Parcelable>
private static final String RUNTIME_STATE_WIDGET_PANEL = "launcher.widget_panel";
- // Type int[]
- private static final String RUNTIME_STATE_CURRENT_SCREEN_IDS = "launcher.current_screen_ids";
public static final String ON_CREATE_EVT = "Launcher.onCreate";
public static final String ON_START_EVT = "Launcher.onStart";
@@ -294,15 +275,10 @@ public class Launcher extends StatefulActivity<LauncherState>
private static final int THEME_CROSS_FADE_ANIMATION_DURATION = 375;
- private static final String DISPLAY_WORKSPACE_TRACE_METHOD_NAME = "DisplayWorkspaceFirstFrame";
- private static final String DISPLAY_ALL_APPS_TRACE_METHOD_NAME = "DisplayAllApps";
- public static final int DISPLAY_WORKSPACE_TRACE_COOKIE = 0;
- public static final int DISPLAY_ALL_APPS_TRACE_COOKIE = 1;
-
private Configuration mOldConfig;
@Thunk
- Workspace<?> mWorkspace;
+ Workspace mWorkspace;
@Thunk
DragLayer mDragLayer;
private DragController mDragController;
@@ -319,7 +295,7 @@ public class Launcher extends StatefulActivity<LauncherState>
// Main container view for the all apps screen.
@Thunk
- ActivityAllAppsContainerView<Launcher> mAppsView;
+ AllAppsContainerView mAppsView;
AllAppsTransitionController mAllAppsController;
// Scrim view for the all apps and overview state.
@@ -337,7 +313,6 @@ public class Launcher extends StatefulActivity<LauncherState>
private Runnable mOnDeferredActivityLaunchCallback;
private ViewOnDrawExecutor mPendingExecutor;
- private OnPreDrawListener mOnInitialBindListener;
private LauncherModel mModel;
private ModelWriter mModelWriter;
@@ -346,13 +321,13 @@ public class Launcher extends StatefulActivity<LauncherState>
private PopupDataProvider mPopupDataProvider;
- private IntSet mSynchronouslyBoundPages = new IntSet();
- @NonNull private IntSet mPagesToBindSynchronously = new IntSet();
+ private int mSynchronouslyBoundPage = PagedView.INVALID_PAGE;
+ private int mPageToBindSynchronously = PagedView.INVALID_PAGE;
// We only want to get the SharedPreferences once since it does an FS stat each time we get
// it from the context.
private SharedPreferences mSharedPrefs;
- private OnboardingPrefs<? extends Launcher> mOnboardingPrefs;
+ private OnboardingPrefs mOnboardingPrefs;
// Activity result which needs to be processed after workspace has loaded.
private ActivityResultInfo mPendingActivityResult;
@@ -385,18 +360,8 @@ public class Launcher extends StatefulActivity<LauncherState>
protected InstanceId mAllAppsSessionLogId;
private LauncherState mPrevLauncherState;
- private StringCache mStringCache;
-
@Override
- @TargetApi(Build.VERSION_CODES.S)
protected void onCreate(Bundle savedInstanceState) {
- // Only use a hard-coded cookie since we only want to trace this once.
- if (Utilities.ATLEAST_S) {
- Trace.beginAsyncSection(
- DISPLAY_WORKSPACE_TRACE_METHOD_NAME, DISPLAY_WORKSPACE_TRACE_COOKIE);
- Trace.beginAsyncSection(DISPLAY_ALL_APPS_TRACE_METHOD_NAME,
- DISPLAY_ALL_APPS_TRACE_COOKIE);
- }
Object traceToken = TraceHelper.INSTANCE.beginSection(ON_CREATE_EVT,
TraceHelper.FLAG_UI_EVENT);
if (DEBUG_STRICT_MODE) {
@@ -433,7 +398,8 @@ public class Launcher extends StatefulActivity<LauncherState>
shareIntent.putExtra(Intent.EXTRA_TEXT, stackTrace);
shareIntent = Intent.createChooser(shareIntent, null);
PendingIntent sharePendingIntent = PendingIntent.getActivity(
- this, 0, shareIntent, FLAG_UPDATE_CURRENT | FLAG_IMMUTABLE);
+ this, 0, shareIntent, PendingIntent.FLAG_UPDATE_CURRENT
+ );
Notification notification = new Notification.Builder(this, notificationChannelId)
.setSmallIcon(android.R.drawable.ic_menu_close_clear_cancel)
@@ -491,19 +457,19 @@ public class Launcher extends StatefulActivity<LauncherState>
restoreState(savedInstanceState);
mStateManager.reapplyState();
+ // We only load the page synchronously if the user rotates (or triggers a
+ // configuration change) while launcher is in the foreground
+ int currentScreen = PagedView.INVALID_PAGE;
if (savedInstanceState != null) {
- int[] pageIds = savedInstanceState.getIntArray(RUNTIME_STATE_CURRENT_SCREEN_IDS);
- if (pageIds != null) {
- mPagesToBindSynchronously = IntSet.wrap(pageIds);
- }
+ currentScreen = savedInstanceState.getInt(RUNTIME_STATE_CURRENT_SCREEN, currentScreen);
}
+ mPageToBindSynchronously = currentScreen;
if (!mModel.addCallbacksAndLoad(this)) {
if (!internalStateHandled) {
- Log.d(BAD_STATE, "Launcher onCreate not binding sync, prevent drawing");
- // If we are not binding synchronously, pause drawing until initial bind complete,
- // so that the system could continue to show the device loading prompt
- mOnInitialBindListener = Boolean.FALSE::booleanValue;
+ // If we are not binding synchronously, show a fade in animation when
+ // the first page bind completes.
+ mDragLayer.getAlphaProperty(ALPHA_INDEX_LAUNCHER_LOAD).setValue(0);
}
}
@@ -511,9 +477,6 @@ public class Launcher extends StatefulActivity<LauncherState>
setDefaultKeyMode(DEFAULT_KEYS_SEARCH_LOCAL);
setContentView(getRootView());
- if (mOnInitialBindListener != null) {
- getRootView().getViewTreeObserver().addOnPreDrawListener(mOnInitialBindListener);
- }
getRootView().dispatchInsets();
// Listen for broadcasts
@@ -527,7 +490,7 @@ public class Launcher extends StatefulActivity<LauncherState>
}
mOverlayManager = getDefaultOverlay();
PluginManagerWrapper.INSTANCE.get(this).addPluginListener(this,
- LauncherOverlayPlugin.class, false /* allowedMultiple */);
+ OverlayPlugin.class, false /* allowedMultiple */);
mRotationHelper.initialize();
TraceHelper.INSTANCE.endSection(traceToken);
@@ -538,29 +501,27 @@ public class Launcher extends StatefulActivity<LauncherState>
if (Utilities.ATLEAST_R) {
getWindow().setSoftInputMode(LayoutParams.SOFT_INPUT_ADJUST_NOTHING);
}
- setTitle(R.string.home_screen);
}
protected LauncherOverlayManager getDefaultOverlay() {
return new LauncherOverlayManager() { };
}
- protected OnboardingPrefs<? extends Launcher> createOnboardingPrefs(
- SharedPreferences sharedPrefs) {
+ protected OnboardingPrefs createOnboardingPrefs(SharedPreferences sharedPrefs) {
return new OnboardingPrefs<>(this, sharedPrefs);
}
- public OnboardingPrefs<? extends Launcher> getOnboardingPrefs() {
+ public OnboardingPrefs getOnboardingPrefs() {
return mOnboardingPrefs;
}
@Override
- public void onPluginConnected(LauncherOverlayPlugin overlayManager, Context context) {
+ public void onPluginConnected(OverlayPlugin overlayManager, Context context) {
switchOverlay(() -> overlayManager.createOverlayManager(this, this));
}
@Override
- public void onPluginDisconnected(LauncherOverlayPlugin plugin) {
+ public void onPluginDisconnected(OverlayPlugin plugin) {
switchOverlay(this::getDefaultOverlay);
}
@@ -577,7 +538,7 @@ public class Launcher extends StatefulActivity<LauncherState>
}
@Override
- public void dispatchDeviceProfileChanged() {
+ protected void dispatchDeviceProfileChanged() {
super.dispatchDeviceProfileChanged();
mOverlayManager.onDeviceProvideChanged();
}
@@ -586,28 +547,14 @@ public class Launcher extends StatefulActivity<LauncherState>
public void onEnterAnimationComplete() {
super.onEnterAnimationComplete();
mRotationHelper.setCurrentTransitionRequest(REQUEST_NONE);
- // Starting with Android S, onEnterAnimationComplete is sent immediately
- // causing the surface to get removed before the animation completed (b/175345344).
- // Instead we rely on next user touch event to remove the view and optionally a callback
- // from system from Android T onwards.
- if (!Utilities.ATLEAST_S) {
- AbstractFloatingView.closeOpenViews(this, false, TYPE_ICON_SURFACE);
- }
- }
-
- @Override
- public void onMultiWindowModeChanged(boolean isInMultiWindowMode, Configuration newConfig) {
- super.onMultiWindowModeChanged(isInMultiWindowMode, newConfig);
- // Always update device profile when multi window mode changed.
- initDeviceProfile(mDeviceProfile.inv);
- dispatchDeviceProfileChanged();
+ AbstractFloatingView.closeOpenViews(this, false, TYPE_ICON_SURFACE);
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
int diff = newConfig.diff(mOldConfig);
if ((diff & (CONFIG_ORIENTATION | CONFIG_SCREEN_SIZE)) != 0) {
- onIdpChanged(false);
+ onIdpChanged(mDeviceProfile.inv);
}
mOldConfig.setTo(newConfig);
@@ -615,8 +562,8 @@ public class Launcher extends StatefulActivity<LauncherState>
}
@Override
- public void onIdpChanged(boolean modelPropertiesChanged) {
- initDeviceProfile(mDeviceProfile.inv);
+ public void onIdpChanged(InvariantDeviceProfile idp) {
+ initDeviceProfile(idp);
dispatchDeviceProfileChanged();
reapplyUi();
mDragLayer.recreateControllers();
@@ -639,7 +586,7 @@ public class Launcher extends StatefulActivity<LauncherState>
mDragLayer.onOneHandedModeStateChanged(activated);
}
- protected void initDeviceProfile(InvariantDeviceProfile idp) {
+ private void initDeviceProfile(InvariantDeviceProfile idp) {
// Load configuration-specific DeviceProfile
mDeviceProfile = idp.getDeviceProfile(this);
if (isInMultiWindowMode()) {
@@ -648,7 +595,7 @@ public class Launcher extends StatefulActivity<LauncherState>
}
onDeviceProfileInitiated();
- mModelWriter = mModel.getWriter(getDeviceProfile().isVerticalBarLayout(), true, this);
+ mModelWriter = mModel.getWriter(getDeviceProfile().isVerticalBarLayout(), true);
}
public RotationHelper getRotationHelper() {
@@ -672,7 +619,7 @@ public class Launcher extends StatefulActivity<LauncherState>
@Override
public void setLauncherOverlay(LauncherOverlay overlay) {
if (overlay != null) {
- overlay.setOverlayCallbacks(this);
+ overlay.setOverlayCallbacks(new LauncherOverlayCallbacksImpl());
}
mWorkspace.setLauncherOverlay(overlay);
}
@@ -693,8 +640,6 @@ public class Launcher extends StatefulActivity<LauncherState>
return !isWorkspaceLoading();
}
- @NonNull
- @Override
public PopupDataProvider getPopupDataProvider() {
return mPopupDataProvider;
}
@@ -922,11 +867,11 @@ public class Launcher extends StatefulActivity<LauncherState>
if (dropLayout == null) {
// it's possible that the add screen was removed because it was
// empty and a re-bind occurred
- mWorkspace.addExtraEmptyScreens();
- IntSet emptyPagesAdded = mWorkspace.commitExtraEmptyScreens();
- return emptyPagesAdded.isEmpty() ? -1 : emptyPagesAdded.getArray().get(0);
+ mWorkspace.addExtraEmptyScreen();
+ return mWorkspace.commitExtraEmptyScreen();
+ } else {
+ return screenId;
}
- return screenId;
}
@Thunk
@@ -974,7 +919,7 @@ public class Launcher extends StatefulActivity<LauncherState>
hideKeyboard();
logStopAndResume(false /* isResume */);
mAppWidgetHost.setActivityStarted(false);
- NotificationListener.removeNotificationsChangedListener(getPopupDataProvider());
+ NotificationListener.removeNotificationsChangedListener();
}
@Override
@@ -1003,7 +948,7 @@ public class Launcher extends StatefulActivity<LauncherState>
mModel.validateModelDataOnResume();
// Set the notification listener and fetch updated notifications when we resume
- NotificationListener.addNotificationsChangedListener(mPopupDataProvider);
+ NotificationListener.setNotificationsChangedListener(mPopupDataProvider);
DiscoveryBounce.showForHomeIfNeeded(this);
mAppWidgetHost.setActivityResumed(true);
@@ -1102,25 +1047,14 @@ public class Launcher extends StatefulActivity<LauncherState>
&& mAllAppsSessionLogId == null) {
// creates new instance ID since new all apps session is started.
mAllAppsSessionLogId = new InstanceIdSequence().newInstanceId();
- if (getAllAppsEntryEvent().isPresent()) {
- getStatsLogManager().logger()
- .withContainerInfo(ContainerInfo.newBuilder()
- .setWorkspace(WorkspaceContainer.newBuilder()
- .setPageIndex(getWorkspace().getCurrentPage())).build())
- .log(getAllAppsEntryEvent().get());
- }
+ getStatsLogManager()
+ .logger()
+ .log(FeatureFlags.ENABLE_DEVICE_SEARCH.get()
+ ? LAUNCHER_ALLAPPS_ENTRY_WITH_DEVICE_SEARCH
+ : LAUNCHER_ALLAPPS_ENTRY);
}
}
- /**
- * Returns {@link EventEnum} that should be logged when Launcher enters into AllApps state.
- */
- protected Optional<EventEnum> getAllAppsEntryEvent() {
- return Optional.of(FeatureFlags.ENABLE_DEVICE_SEARCH.get()
- ? LAUNCHER_ALLAPPS_ENTRY_WITH_DEVICE_SEARCH
- : LAUNCHER_ALLAPPS_ENTRY);
- }
-
@Override
public void onStateSetEnd(LauncherState state) {
super.onStateSetEnd(state);
@@ -1147,18 +1081,17 @@ public class Launcher extends StatefulActivity<LauncherState>
// Making sure mAllAppsSessionLogId is not null to avoid double logging.
&& mAllAppsSessionLogId != null) {
getAppsView().reset(false);
- getAllAppsExitEvent().ifPresent(getStatsLogManager().logger()::log);
+ getStatsLogManager().logger()
+ .withContainerInfo(LauncherAtom.ContainerInfo.newBuilder()
+ .setWorkspace(
+ LauncherAtom.WorkspaceContainer.newBuilder()
+ .setPageIndex(getWorkspace().getCurrentPage()))
+ .build())
+ .log(LAUNCHER_ALLAPPS_EXIT);
mAllAppsSessionLogId = null;
}
}
- /**
- * Returns {@link EventEnum} that should be logged when Launcher exists from AllApps state.
- */
- protected Optional<EventEnum> getAllAppsExitEvent() {
- return Optional.of(LAUNCHER_ALLAPPS_EXIT);
- }
-
@Override
protected void onResume() {
Object traceToken = TraceHelper.INSTANCE.beginSection(ON_RESUME_EVT,
@@ -1171,8 +1104,6 @@ public class Launcher extends StatefulActivity<LauncherState>
mOverlayManager.onActivityResumed(this);
}
- AbstractFloatingView.closeAllOpenViewsExcept(this, false, TYPE_REBIND_SAFE);
- DragView.removeAllViews(this);
TraceHelper.INSTANCE.endSection(traceToken);
}
@@ -1192,15 +1123,12 @@ public class Launcher extends StatefulActivity<LauncherState>
mAppWidgetHost.setActivityResumed(false);
}
- /**
- * {@code LauncherOverlayCallbacks} scroll amount.
- * Indicates transition progress to -1 screen.
- * @param progress From 0 to 1.
- */
- @Override
- public void onScrollChanged(float progress) {
- if (mWorkspace != null) {
- mWorkspace.onOverlayScrollChanged(progress);
+ class LauncherOverlayCallbacksImpl implements LauncherOverlayCallbacks {
+
+ public void onScrollChanged(float progress) {
+ if (mWorkspace != null) {
+ mWorkspace.onOverlayScrollChanged(progress);
+ }
}
}
@@ -1260,7 +1188,7 @@ public class Launcher extends StatefulActivity<LauncherState>
// Until the workspace is bound, ensure that we keep the wallpaper offset locked to the
// default state, otherwise we will update to the wrong offsets in RTL
mWorkspace.lockWallpaperToDefaultPage();
- mWorkspace.bindAndInitFirstWorkspaceScreen();
+ mWorkspace.bindAndInitFirstWorkspaceScreen(null /* recycled qsb */);
mDragController.addDragListener(mWorkspace);
// Get the search/delete/uninstall bar
@@ -1283,16 +1211,13 @@ public class Launcher extends StatefulActivity<LauncherState>
* @param info The data structure describing the shortcut.
*/
View createShortcut(WorkspaceItemInfo info) {
- // This can be called before PagedView#pageScrollsInitialized returns true, so use the
- // first page, which we always assume to be present.
- return createShortcut((ViewGroup) mWorkspace.getChildAt(0), info);
+ return createShortcut((ViewGroup) mWorkspace.getChildAt(mWorkspace.getCurrentPage()), info);
}
/**
* Creates a view representing a shortcut inflated from the specified resource.
*
- * @param parent The group the shortcut belongs to. This is not necessarily the group where
- * the shortcut should be added.
+ * @param parent The group the shortcut belongs to.
* @param info The data structure describing the shortcut.
* @return A View inflated from layoutResId.
*/
@@ -1310,7 +1235,7 @@ public class Launcher extends StatefulActivity<LauncherState>
*
* @param data The intent describing the shortcut.
*/
- protected void completeAddShortcut(Intent data, int container, int screenId, int cellX,
+ private void completeAddShortcut(Intent data, int container, int screenId, int cellX,
int cellY, PendingRequestArgs args) {
if (args.getRequestCode() != REQUEST_CREATE_SHORTCUT
|| args.getPendingIntent().getComponent() == null) {
@@ -1365,7 +1290,7 @@ public class Launcher extends StatefulActivity<LauncherState>
}
if (!foundCellSpan) {
- mWorkspace.onNoCellFound(layout, info, /* logInstanceId= */ null);
+ mWorkspace.onNoCellFound(layout);
return;
}
@@ -1383,8 +1308,7 @@ public class Launcher extends StatefulActivity<LauncherState>
}
}
- @Override
- public @Nullable FolderIcon findFolderIcon(final int folderIconId) {
+ public FolderIcon findFolderIcon(final int folderIconId) {
return (FolderIcon) mWorkspace.getHomescreenIconByItemId(folderIconId);
}
@@ -1435,7 +1359,22 @@ public class Launcher extends StatefulActivity<LauncherState>
final LauncherAppWidgetHostView launcherHostView = (LauncherAppWidgetHostView) hostView;
CellLayout cellLayout = getCellLayout(launcherInfo.container, launcherInfo.screenId);
if (mStateManager.getState() == NORMAL) {
- AppWidgetResizeFrame.showForWidget(launcherHostView, cellLayout);
+ // Show resize frame once the widget layout is drawn.
+ View.OnLayoutChangeListener onLayoutChangeListener =
+ new View.OnLayoutChangeListener() {
+ @Override
+ public void onLayoutChange(View view, int left, int top, int right,
+ int bottom, int oldLeft, int oldTop, int oldRight,
+ int oldBottom) {
+ AppWidgetResizeFrame.showForWidget(launcherHostView, cellLayout);
+ launcherHostView.removeOnLayoutChangeListener(this);
+ }
+ };
+ launcherHostView.addOnLayoutChangeListener(onLayoutChangeListener);
+ // There is a small chance that the layout was already drawn before the layout
+ // change listener was registered, which means that the resize frame wouldn't be
+ // shown. Directly call requestLayout to force a layout change.
+ launcherHostView.requestLayout();
} else {
mStateManager.addStateListener(new StateManager.StateListener<LauncherState>() {
@Override
@@ -1508,12 +1447,11 @@ public class Launcher extends StatefulActivity<LauncherState>
return mDragLayer;
}
- @Override
- public ActivityAllAppsContainerView<Launcher> getAppsView() {
+ public AllAppsContainerView getAppsView() {
return mAppsView;
}
- public Workspace<?> getWorkspace() {
+ public Workspace getWorkspace() {
return mWorkspace;
}
@@ -1583,7 +1521,6 @@ public class Launcher extends StatefulActivity<LauncherState>
boolean isActionMain = Intent.ACTION_MAIN.equals(intent.getAction());
boolean internalStateHandled = ACTIVITY_TRACKER.handleNewIntent(this);
hideKeyboard();
-
if (isActionMain) {
if (!internalStateHandled) {
// In all these cases, only animate if we're already on home
@@ -1612,8 +1549,6 @@ public class Launcher extends StatefulActivity<LauncherState>
handleGestureContract(intent);
} else if (Intent.ACTION_ALL_APPS.equals(intent.getAction())) {
showAllAppsFromIntent(alreadyOnHome);
- } else if (Intent.ACTION_SHOW_WORK_APPS.equals(intent.getAction())) {
- showAllAppsWorkTabFromIntent(alreadyOnHome);
}
TraceHelper.INSTANCE.endSection(traceToken);
@@ -1624,11 +1559,6 @@ public class Launcher extends StatefulActivity<LauncherState>
getStateManager().goToState(ALL_APPS, alreadyOnHome);
}
- private void showAllAppsWorkTabFromIntent(boolean alreadyOnHome) {
- showAllAppsFromIntent(alreadyOnHome);
- mAppsView.switchToTab(BaseAllAppsContainerView.AdapterHolder.WORK);
- }
-
/**
* Handles gesture nav contract
*/
@@ -1653,22 +1583,18 @@ public class Launcher extends StatefulActivity<LauncherState>
@Override
public void onRestoreInstanceState(Bundle state) {
super.onRestoreInstanceState(state);
- if (mSynchronouslyBoundPages != null) {
- mSynchronouslyBoundPages.forEach(screenId -> {
- int pageIndex = mWorkspace.getPageIndexForScreenId(screenId);
- if (pageIndex != PagedView.INVALID_PAGE) {
- mWorkspace.restoreInstanceStateForChild(pageIndex);
- }
- });
- }
+ mWorkspace.restoreInstanceStateForChild(mSynchronouslyBoundPage);
}
@Override
protected void onSaveInstanceState(Bundle outState) {
- outState.putIntArray(RUNTIME_STATE_CURRENT_SCREEN_IDS,
- mWorkspace.getCurrentPageScreenIds().getArray().toArray());
+ if (mWorkspace.getChildCount() > 0) {
+ outState.putInt(RUNTIME_STATE_CURRENT_SCREEN, mWorkspace.getNextPage());
+
+ }
outState.putInt(RUNTIME_STATE, mStateManager.getState().ordinal);
+
AbstractFloatingView widgets = AbstractFloatingView
.getOpenView(this, AbstractFloatingView.TYPE_WIDGETS_FULL_SHEET);
if (widgets != null) {
@@ -1679,6 +1605,9 @@ public class Launcher extends StatefulActivity<LauncherState>
outState.remove(RUNTIME_STATE_WIDGET_PANEL);
}
+ // We close any open folders and shortcut containers that are not safe for rebind,
+ // and we need to make sure this state is reflected.
+ AbstractFloatingView.closeOpenViews(this, false, TYPE_ALL & ~TYPE_REBIND_SAFE);
finishAutoCancelActionMode();
if (mPendingRequestArgs != null) {
@@ -1780,11 +1709,6 @@ public class Launcher extends StatefulActivity<LauncherState>
return mWorkspaceLoading;
}
- @Override
- public boolean isBindingItems() {
- return mWorkspaceLoading;
- }
-
private void setWorkspaceLoading(boolean value) {
mWorkspaceLoading = value;
}
@@ -1959,19 +1883,6 @@ public class Launcher extends StatefulActivity<LauncherState>
* @param deleteFromDb whether or not to delete this item from the db.
*/
public boolean removeItem(View v, final ItemInfo itemInfo, boolean deleteFromDb) {
- return removeItem(v, itemInfo, deleteFromDb, null);
- }
-
- /**
- * Unbinds the view for the specified item, and removes the item and all its children.
- *
- * @param v the view being removed.
- * @param itemInfo the {@link ItemInfo} for this view.
- * @param deleteFromDb whether or not to delete this item from the db.
- * @param reason the resaon for removal.
- */
- public boolean removeItem(View v, final ItemInfo itemInfo, boolean deleteFromDb,
- @Nullable final String reason) {
if (itemInfo instanceof WorkspaceItemInfo) {
// Remove the shortcut from the folder before removing it from launcher
View folderIcon = mWorkspace.getHomescreenIconByItemId(itemInfo.container);
@@ -1981,7 +1892,7 @@ public class Launcher extends StatefulActivity<LauncherState>
mWorkspace.removeWorkspaceItem(v);
}
if (deleteFromDb) {
- getModelWriter().deleteItemFromDatabase(itemInfo, reason);
+ getModelWriter().deleteItemFromDatabase(itemInfo);
}
} else if (itemInfo instanceof FolderInfo) {
final FolderInfo folderInfo = (FolderInfo) itemInfo;
@@ -1996,7 +1907,7 @@ public class Launcher extends StatefulActivity<LauncherState>
final LauncherAppWidgetInfo widgetInfo = (LauncherAppWidgetInfo) itemInfo;
mWorkspace.removeWorkspaceItem(v);
if (deleteFromDb) {
- getModelWriter().deleteWidgetInfo(widgetInfo, getAppWidgetHost(), reason);
+ getModelWriter().deleteWidgetInfo(widgetInfo, getAppWidgetHost());
}
} else {
return false;
@@ -2006,7 +1917,7 @@ public class Launcher extends StatefulActivity<LauncherState>
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
- TestLogging.recordKeyEvent(TestProtocol.SEQUENCE_MAIN, "Key event", event);
+ TestLogging.recordEvent(TestProtocol.SEQUENCE_MAIN, "Key event", event);
return (event.getKeyCode() == KeyEvent.KEYCODE_HOME) || super.dispatchKeyEvent(event);
}
@@ -2048,16 +1959,13 @@ public class Launcher extends StatefulActivity<LauncherState>
// Note: There should be at most one log per method call. This is enforced implicitly
// by using if-else statements.
AbstractFloatingView topView = AbstractFloatingView.getTopOpenView(this);
- if (topView == null || !topView.onBackPressed()) {
- // Not handled by the floating view.
- onStateBack();
+ if (topView != null && topView.onBackPressed()) {
+ // Handled by the floating view.
+ } else {
+ mStateManager.getState().onBackPressed(this);
}
}
- protected void onStateBack() {
- mStateManager.getState().onBackPressed(this);
- }
-
protected void onScreenOff() {
// Reset AllApps to its initial state only if we are not in the middle of
// processing a multi-step drop
@@ -2071,7 +1979,7 @@ public class Launcher extends StatefulActivity<LauncherState>
@TargetApi(Build.VERSION_CODES.M)
@Override
- public boolean onErrorStartingShortcut(Intent intent, ItemInfo info) {
+ protected boolean onErrorStartingShortcut(Intent intent, ItemInfo info) {
// Due to legacy reasons, direct call shortcuts require Launchers to have the
// corresponding permission. Show the appropriate permission prompt if that
// is the case.
@@ -2165,58 +2073,25 @@ public class Launcher extends StatefulActivity<LauncherState>
}
/**
- * Sets the next pages to bind synchronously on next bind.
- * @param pages should not be null.
+ * Sets the next page to bind synchronously on next bind.
+ * @param page
*/
- public void setPagesToBindSynchronously(@NonNull IntSet pages) {
- mPagesToBindSynchronously = pages;
+ public void setPageToBindSynchronously(int page) {
+ mPageToBindSynchronously = page;
}
+ /**
+ * Implementation of the method from LauncherModel.Callbacks.
+ */
@Override
- public IntSet getPagesToBindSynchronously(IntArray orderedScreenIds) {
- IntSet visibleIds;
- if (!mPagesToBindSynchronously.isEmpty()) {
- visibleIds = mPagesToBindSynchronously;
- } else if (!mWorkspaceLoading) {
- visibleIds = mWorkspace.getCurrentPageScreenIds();
+ public int getPageToBindSynchronously() {
+ if (mPageToBindSynchronously != PagedView.INVALID_PAGE) {
+ return mPageToBindSynchronously;
+ } else if (mWorkspace != null) {
+ return mWorkspace.getCurrentPage();
} else {
- // If workspace binding is still in progress, getCurrentPageScreenIds won't be accurate,
- // and we should use mSynchronouslyBoundPages that's set during initial binding.
- visibleIds = mSynchronouslyBoundPages;
- }
- IntArray actualIds = new IntArray();
-
- IntSet result = new IntSet();
- if (visibleIds.isEmpty()) {
- if (TestProtocol.sDebugTracing) {
- Log.d(TestProtocol.NULL_INT_SET, "getPagesToBindSynchronously (1): "
- + result);
- }
- return result;
- }
- for (int id : orderedScreenIds.toArray()) {
- actualIds.add(id);
- }
- int firstId = visibleIds.getArray().get(0);
- int pairId = mWorkspace.getScreenPair(firstId);
- // Double check that actual screenIds contains the visibleId, as empty screens are hidden
- // in single panel.
- if (actualIds.contains(firstId)) {
- result.add(firstId);
- if (mDeviceProfile.isTwoPanels && actualIds.contains(pairId)) {
- result.add(pairId);
- }
- } else if (LauncherAppState.getIDP(this).supportedProfiles.stream().anyMatch(
- deviceProfile -> deviceProfile.isTwoPanels) && actualIds.contains(pairId)) {
- // Add the right panel if left panel is hidden when switching display, due to empty
- // pages being hidden in single panel.
- result.add(pairId);
- }
- if (TestProtocol.sDebugTracing) {
- Log.d(TestProtocol.NULL_INT_SET, "getPagesToBindSynchronously (2): "
- + result);
+ return 0;
}
- return result;
}
/**
@@ -2226,7 +2101,7 @@ public class Launcher extends StatefulActivity<LauncherState>
@Override
public void clearPendingBinds() {
if (mPendingExecutor != null) {
- mPendingExecutor.cancel();
+ mPendingExecutor.markCompleted();
mPendingExecutor = null;
// We might have set this flag previously and forgot to clear it.
@@ -2264,14 +2139,14 @@ public class Launcher extends StatefulActivity<LauncherState>
@Override
public void bindScreens(IntArray orderedScreenIds) {
- int firstScreenPosition = 0;
+ // Make sure the first screen is always at the start.
if (FeatureFlags.QSB_ON_FIRST_SCREEN &&
- orderedScreenIds.indexOf(Workspace.FIRST_SCREEN_ID) != firstScreenPosition) {
+ orderedScreenIds.indexOf(Workspace.FIRST_SCREEN_ID) != 0) {
orderedScreenIds.removeValue(Workspace.FIRST_SCREEN_ID);
- orderedScreenIds.add(firstScreenPosition, Workspace.FIRST_SCREEN_ID);
+ orderedScreenIds.add(0, Workspace.FIRST_SCREEN_ID);
} else if (!FeatureFlags.QSB_ON_FIRST_SCREEN && orderedScreenIds.isEmpty()) {
// If there are no screens, we need to have an empty screen
- mWorkspace.addExtraEmptyScreens();
+ mWorkspace.addExtraEmptyScreen();
}
bindAddScreens(orderedScreenIds);
@@ -2282,22 +2157,13 @@ public class Launcher extends StatefulActivity<LauncherState>
}
private void bindAddScreens(IntArray orderedScreenIds) {
- if (mDeviceProfile.isTwoPanels) {
- // Some empty pages might have been removed while the phone was in a single panel
- // mode, so we want to add those empty pages back.
- IntSet screenIds = IntSet.wrap(orderedScreenIds);
- orderedScreenIds.forEach(screenId -> screenIds.add(mWorkspace.getScreenPair(screenId)));
- orderedScreenIds = screenIds.getArray();
- }
-
int count = orderedScreenIds.size();
for (int i = 0; i < count; i++) {
int screenId = orderedScreenIds.get(i);
- if (FeatureFlags.QSB_ON_FIRST_SCREEN && screenId == Workspace.FIRST_SCREEN_ID) {
+ if (!FeatureFlags.QSB_ON_FIRST_SCREEN || screenId != Workspace.FIRST_SCREEN_ID) {
// No need to bind the first screen, as its always bound.
- continue;
+ mWorkspace.insertNewWorkspaceScreenBeforeEmptyScreen(screenId);
}
- mWorkspace.insertNewWorkspaceScreenBeforeEmptyScreen(screenId);
}
}
@@ -2317,9 +2183,6 @@ public class Launcher extends StatefulActivity<LauncherState>
ArrayList<ItemInfo> addAnimated) {
// Add the new screens
if (newScreens != null) {
- // newScreens can contain an empty right panel that is already bound, but not known
- // by BgDataModel.
- newScreens.removeAllValues(mWorkspace.mScreenOrder);
bindAddScreens(newScreens);
}
@@ -2361,8 +2224,8 @@ public class Launcher extends StatefulActivity<LauncherState>
final boolean focusFirstItemForAccessibility) {
// Get the list of added items and intersect them with the set of items here
final Collection<Animator> bounceAnims = new ArrayList<>();
- boolean canAnimatePageChange = canAnimatePageChange();
- Workspace<?> workspace = mWorkspace;
+ final boolean animateIcons = forceAnimateIcons && canRunNewAppsAnimation();
+ Workspace workspace = mWorkspace;
int newItemsScreenId = -1;
int end = items.size();
View newView = null;
@@ -2409,26 +2272,20 @@ public class Launcher extends StatefulActivity<LauncherState>
CellLayout cl = mWorkspace.getScreenWithId(item.screenId);
if (cl != null && cl.isOccupied(item.cellX, item.cellY)) {
View v = cl.getChildAt(item.cellX, item.cellY);
- if (v == null) {
- Log.e(TAG, "bindItems failed when removing colliding item=" + item);
- }
Object tag = v.getTag();
String desc = "Collision while binding workspace item: " + item
+ ". Collides with " + tag;
if (FeatureFlags.IS_STUDIO_BUILD) {
throw (new RuntimeException(desc));
} else {
- getModelWriter().deleteItemFromDatabase(item, desc);
- if (TestProtocol.sDebugTracing) {
- Log.d(TestProtocol.MISSING_PROMISE_ICON,
- TAG + "bindItems failed for item=" + item);
- }
+ Log.d(TAG, desc);
+ getModelWriter().deleteItemFromDatabase(item);
continue;
}
}
}
workspace.addInScreenFromBind(view, item);
- if (forceAnimateIcons) {
+ if (animateIcons) {
// Animate all the applications up now
view.setAlpha(0f);
view.setScaleX(0f);
@@ -2444,7 +2301,7 @@ public class Launcher extends StatefulActivity<LauncherState>
View viewToFocus = newView;
// Animate to the correct pager
- if (forceAnimateIcons && newItemsScreenId > -1) {
+ if (animateIcons && newItemsScreenId > -1) {
AnimatorSet anim = new AnimatorSet();
anim.playTogether(bounceAnims);
if (focusFirstItemForAccessibility && viewToFocus != null) {
@@ -2460,7 +2317,7 @@ public class Launcher extends StatefulActivity<LauncherState>
final int newScreenIndex = mWorkspace.getPageIndexForScreenId(newItemsScreenId);
final Runnable startBounceAnimRunnable = anim::start;
- if (canAnimatePageChange && newItemsScreenId != currentScreenId) {
+ if (newItemsScreenId != currentScreenId) {
// We post the animation slightly delayed to prevent slowdowns
// when we are loading right after we return to launcher.
mWorkspace.postDelayed(new Runnable() {
@@ -2498,8 +2355,7 @@ public class Launcher extends StatefulActivity<LauncherState>
if (item.hasOptionFlag(LauncherAppWidgetInfo.OPTION_SEARCH_WIDGET)) {
item.providerName = QsbContainerView.getSearchComponentName(this);
if (item.providerName == null) {
- getModelWriter().deleteItemFromDatabase(item,
- "search widget removed because search component cannot be found");
+ getModelWriter().deleteItemFromDatabase(item);
return null;
}
}
@@ -2550,10 +2406,10 @@ public class Launcher extends StatefulActivity<LauncherState>
if (!item.hasRestoreFlag(LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY)
&& (item.restoreStatus != LauncherAppWidgetInfo.RESTORE_COMPLETED)) {
if (appWidgetInfo == null) {
- getModelWriter().deleteItemFromDatabase(item,
- "Removing restored widget: id=" + item.appWidgetId
+ FileLog.d(TAG, "Removing restored widget: id=" + item.appWidgetId
+ " belongs to component " + item.providerName + " user " + item.user
+ ", as the provider is null and " + removalReason);
+ getModelWriter().deleteItemFromDatabase(item);
return null;
}
@@ -2623,7 +2479,7 @@ public class Launcher extends StatefulActivity<LauncherState>
// Verify that we own the widget
if (appWidgetInfo == null) {
FileLog.e(TAG, "Removing invalid widget: id=" + item.appWidgetId);
- getModelWriter().deleteWidgetInfo(item, getAppWidgetHost(), removalReason);
+ getModelWriter().deleteWidgetInfo(item, getAppWidgetHost());
return null;
}
@@ -2672,37 +2528,47 @@ public class Launcher extends StatefulActivity<LauncherState>
return info;
}
- public void clearPendingExecutor(ViewOnDrawExecutor executor) {
- if (mPendingExecutor == executor) {
- mPendingExecutor = null;
- }
+ public void onPageBoundSynchronously(int page) {
+ mSynchronouslyBoundPage = page;
+ mWorkspace.setCurrentPage(page);
+ mPageToBindSynchronously = PagedView.INVALID_PAGE;
}
@Override
- @TargetApi(Build.VERSION_CODES.S)
- public void onInitialBindComplete(IntSet boundPages, RunnableList pendingTasks) {
- mSynchronouslyBoundPages = boundPages;
- mPagesToBindSynchronously = new IntSet();
-
+ public void executeOnNextDraw(ViewOnDrawExecutor executor) {
clearPendingBinds();
- ViewOnDrawExecutor executor = new ViewOnDrawExecutor(pendingTasks);
mPendingExecutor = executor;
if (!isInState(ALL_APPS)) {
mAppsView.getAppsStore().enableDeferUpdates(AllAppsStore.DEFER_UPDATES_NEXT_DRAW);
- pendingTasks.add(() -> mAppsView.getAppsStore().disableDeferUpdates(
+ mPendingExecutor.execute(() -> mAppsView.getAppsStore().disableDeferUpdates(
AllAppsStore.DEFER_UPDATES_NEXT_DRAW));
}
- if (mOnInitialBindListener != null) {
- getRootView().getViewTreeObserver().removeOnPreDrawListener(mOnInitialBindListener);
- mOnInitialBindListener = null;
+ executor.attachTo(this);
+ }
+
+ public void clearPendingExecutor(ViewOnDrawExecutor executor) {
+ if (mPendingExecutor == executor) {
+ mPendingExecutor = null;
}
+ }
- executor.onLoadAnimationCompleted();
- executor.attachTo(this);
- if (Utilities.ATLEAST_S) {
- Trace.endAsyncSection(DISPLAY_WORKSPACE_TRACE_METHOD_NAME,
- DISPLAY_WORKSPACE_TRACE_COOKIE);
+ @Override
+ public void finishFirstPageBind(final ViewOnDrawExecutor executor) {
+ AlphaProperty property = mDragLayer.getAlphaProperty(ALPHA_INDEX_LAUNCHER_LOAD);
+ if (property.getValue() < 1) {
+ ObjectAnimator anim = ObjectAnimator.ofFloat(property, MultiValueAlpha.VALUE, 1);
+ if (executor != null) {
+ anim.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ executor.onLoadAnimationCompleted();
+ }
+ });
+ }
+ anim.start();
+ } else if (executor != null) {
+ executor.onLoadAnimationCompleted();
}
}
@@ -2711,7 +2577,7 @@ public class Launcher extends StatefulActivity<LauncherState>
*
* Implementation of the method from LauncherModel.Callbacks.
*/
- public void finishBindingItems(IntSet pagesBoundFirst) {
+ public void finishBindingItems(int pageBoundFirst) {
Object traceToken = TraceHelper.INSTANCE.beginSection("finishBindingItems");
mWorkspace.restoreInstanceStateForRemainingPages();
@@ -2723,14 +2589,14 @@ public class Launcher extends StatefulActivity<LauncherState>
mPendingActivityResult = null;
}
- int currentPage = pagesBoundFirst != null && !pagesBoundFirst.isEmpty()
- ? mWorkspace.getPageIndexForScreenId(pagesBoundFirst.getArray().get(0))
- : PagedView.INVALID_PAGE;
+ ItemInstallQueue.INSTANCE.get(this)
+ .resumeModelPush(FLAG_LOADER_RUNNING);
+
// When undoing the removal of the last item on a page, return to that page.
// Since we are just resetting the current page without user interaction,
// override the previous page so we don't log the page switch.
- mWorkspace.setCurrentPage(currentPage, currentPage /* overridePrevPage */);
- mPagesToBindSynchronously = new IntSet();
+ mWorkspace.setCurrentPage(pageBoundFirst, pageBoundFirst /* overridePrevPage */);
+ mPageToBindSynchronously = PagedView.INVALID_PAGE;
// Cache one page worth of icons
getViewCache().setCacheSize(R.layout.folder_application,
@@ -2740,7 +2606,7 @@ public class Launcher extends StatefulActivity<LauncherState>
TraceHelper.INSTANCE.endSection(traceToken);
}
- private boolean canAnimatePageChange() {
+ private boolean canRunNewAppsAnimation() {
if (mDragController.isDragging()) {
return false;
} else {
@@ -2749,91 +2615,6 @@ public class Launcher extends StatefulActivity<LauncherState>
}
}
- /**
- * Similar to {@link #getFirstMatch} but optimized to finding a suitable view for the app close
- * animation.
- *
- * @param preferredItemId The id of the preferred item to match to if it exists.
- * @param packageName The package name of the app to match.
- * @param user The user of the app to match.
- * @param supportsAllAppsState If true and we are in All Apps state, looks for view in All Apps.
- * Else we only looks on the workspace.
- */
- public @Nullable View getFirstMatchForAppClose(int preferredItemId, String packageName,
- UserHandle user, boolean supportsAllAppsState) {
- final Predicate<ItemInfo> preferredItem = info ->
- info != null && info.id == preferredItemId;
- final Predicate<ItemInfo> packageAndUserAndApp = info ->
- info != null
- && info.itemType == ITEM_TYPE_APPLICATION
- && info.user.equals(user)
- && info.getTargetComponent() != null
- && TextUtils.equals(info.getTargetComponent().getPackageName(),
- packageName);
-
- if (supportsAllAppsState && isInState(LauncherState.ALL_APPS)) {
- AllAppsRecyclerView activeRecyclerView = mAppsView.getActiveRecyclerView();
- View v = getFirstMatch(Collections.singletonList(activeRecyclerView),
- preferredItem, packageAndUserAndApp);
-
- if (v != null && activeRecyclerView.getCurrentScrollY() > 0) {
- RectF locationBounds = new RectF();
- FloatingIconView.getLocationBoundsForView(this, v, false, locationBounds,
- new Rect());
- if (locationBounds.top < mAppsView.getHeaderBottom()) {
- // Icon is covered by scrim, return null to play fallback animation.
- return null;
- }
- }
-
- return v;
- } else {
- List<ViewGroup> containers = new ArrayList<>(mWorkspace.getPanelCount() + 1);
- containers.add(mWorkspace.getHotseat().getShortcutsAndWidgets());
- mWorkspace.forEachVisiblePage(page
- -> containers.add(((CellLayout) page).getShortcutsAndWidgets()));
-
- // Order: Preferred item by itself or in folder, then by matching package/user
- return getFirstMatch(containers, preferredItem, forFolderMatch(preferredItem),
- packageAndUserAndApp, forFolderMatch(packageAndUserAndApp));
- }
- }
-
- /**
- * Finds the first view matching the ordered operators across the given viewgroups in order.
- * @param containers List of ViewGroups to scan, in order of preference.
- * @param operators List of operators, in order starting from best matching operator.
- */
- @Nullable
- private static View getFirstMatch(Iterable<ViewGroup> containers,
- final Predicate<ItemInfo>... operators) {
- for (Predicate<ItemInfo> operator : operators) {
- for (ViewGroup container : containers) {
- View match = mapOverViewGroup(container, operator);
- if (match != null) {
- return match;
- }
- }
- }
- return null;
- }
-
- /**
- * Returns the first view matching the operator in the given ViewGroups, or null if none.
- * Forward iteration matters.
- */
- @Nullable
- private static View mapOverViewGroup(ViewGroup container, Predicate<ItemInfo> op) {
- final int itemCount = container.getChildCount();
- for (int itemIdx = 0; itemIdx < itemCount; itemIdx++) {
- View item = container.getChildAt(itemIdx);
- if (op.test((ItemInfo) item.getTag())) {
- return item;
- }
- }
- return null;
- }
-
private ValueAnimator createNewAppBounceAnimation(View v, int i) {
ValueAnimator bounceAnim = new PropertyListBuilder().alpha(1).scale(1).build(v)
.setDuration(ItemInstallQueue.NEW_SHORTCUT_BOUNCE_DURATION);
@@ -2847,30 +2628,14 @@ public class Launcher extends StatefulActivity<LauncherState>
}
/**
- * Informs us that the overlay (-1 screen, typically), has either become visible or invisible.
- */
- public void onOverlayVisibilityChanged(boolean visible) {}
-
- /**
- * Informs us that the page transition has ended, so that we can react to the newly selected
- * page if we want to.
- */
- public void onPageEndTransition() {}
-
- /**
* Add the icons for all apps.
*
* Implementation of the method from LauncherModel.Callbacks.
*/
@Override
- @TargetApi(Build.VERSION_CODES.S)
public void bindAllApplications(AppInfo[] apps, int flags) {
mAppsView.getAppsStore().setApps(apps, flags);
PopupContainerWithArrow.dismissInvalidPopup(this);
- if (Utilities.ATLEAST_S) {
- Trace.endAsyncSection(DISPLAY_ALL_APPS_TRACE_METHOD_NAME,
- DISPLAY_ALL_APPS_TRACE_COOKIE);
- }
}
/**
@@ -2901,7 +2666,7 @@ public class Launcher extends StatefulActivity<LauncherState>
@Override
public void bindWorkspaceItemsChanged(List<WorkspaceItemInfo> updated) {
if (!updated.isEmpty()) {
- mWorkspace.updateWorkspaceItems(updated, this);
+ mWorkspace.updateShortcuts(updated);
PopupContainerWithArrow.dismissInvalidPopup(this);
}
}
@@ -2913,7 +2678,7 @@ public class Launcher extends StatefulActivity<LauncherState>
*/
@Override
public void bindRestoreItemsChange(HashSet<ItemInfo> updates) {
- mWorkspace.updateRestoreItems(updates, this);
+ mWorkspace.updateRestoreItems(updates);
}
/**
@@ -2924,7 +2689,7 @@ public class Launcher extends StatefulActivity<LauncherState>
* package-removal should clear all items by package name.
*/
@Override
- public void bindWorkspaceComponentsRemoved(Predicate<ItemInfo> matcher) {
+ public void bindWorkspaceComponentsRemoved(final ItemInfoMatcher matcher) {
mWorkspace.removeItemsByMatcher(matcher);
mDragController.onAppsRemoved(matcher);
PopupContainerWithArrow.dismissInvalidPopup(this);
@@ -2935,16 +2700,6 @@ public class Launcher extends StatefulActivity<LauncherState>
mPopupDataProvider.setAllWidgets(allWidgets);
}
- @Override
- public void bindStringCache(StringCache cache) {
- mStringCache = cache;
- }
-
- @Override
- public StringCache getStringCache() {
- return mStringCache;
- }
-
/**
* @param packageUser if null, refreshes all widgets and shortcuts, otherwise only
* refreshes the widgets and shortcuts associated with the given package/user
@@ -3075,39 +2830,13 @@ public class Launcher extends StatefulActivity<LauncherState>
if (Utilities.IS_RUNNING_IN_TEST_HARNESS) {
Log.d(TestProtocol.PERMANENT_DIAG_TAG, "Opening options popup on key up");
}
- showDefaultOptions(-1, -1);
+ OptionsPopupView.showDefaultOptions(this, -1, -1);
}
return true;
}
return super.onKeyUp(keyCode, event);
}
- /**
- * Shows the default options popup
- */
- public void showDefaultOptions(float x, float y) {
- OptionsPopupView.show(this, getPopupTarget(x, y), OptionsPopupView.getOptions(this),
- false);
- }
-
- /**
- * Returns target rectangle for anchoring a popup menu.
- */
- protected RectF getPopupTarget(float x, float y) {
- float halfSize = getResources().getDimension(R.dimen.options_menu_thumb_size) / 2;
- if (x < 0 || y < 0) {
- x = mDragLayer.getWidth() / 2;
- y = mDragLayer.getHeight() / 2;
- }
- return new RectF(x - halfSize, y - halfSize, x + halfSize, y + halfSize);
- }
-
- @Override
- public boolean shouldUseColorExtractionForPopup() {
- return getTopOpenViewWithType(this, TYPE_FOLDER) == null
- && getStateManager().getState() != LauncherState.ALL_APPS;
- }
-
@Override
protected void collectStateHandlers(List<StateHandler> out) {
out.add(getAllAppsController());
@@ -3151,6 +2880,13 @@ public class Launcher extends StatefulActivity<LauncherState>
return new float[] {NO_SCALE, NO_OFFSET};
}
+ /**
+ * @see LauncherState#getTaskbarScale(Launcher)
+ */
+ public float getNormalTaskbarScale() {
+ return 1f;
+ }
+
public static Launcher getLauncher(Context context) {
return fromContext(context);
}
@@ -3205,24 +2941,6 @@ public class Launcher extends StatefulActivity<LauncherState>
return new DragOptions();
}
- /**
- * Animates Launcher elements during a transition to the All Apps page.
- *
- * @param progress Transition progress from 0 to 1; where 0 => home and 1 => all apps.
- */
- public void onAllAppsTransition(float progress) {
- // No-Op
- }
-
- /**
- * Animates Launcher elements during a transition to the Widgets pages.
- *
- * @param progress Transition progress from 0 to 1; where 0 => home and 1 => widgets.
- */
- public void onWidgetsTransition(float progress) {
- // No-Op
- }
-
private static class NonConfigInstance {
public Configuration config;
public Bitmap snapshot;
@@ -3232,38 +2950,4 @@ public class Launcher extends StatefulActivity<LauncherState>
public StatsLogManager getStatsLogManager() {
return super.getStatsLogManager().withDefaultInstanceId(mAllAppsSessionLogId);
}
-
- /**
- * Returns the current popup for testing, if any.
- */
- @VisibleForTesting
- @Nullable
- public ArrowPopup<?> getOptionsPopup() {
- return findViewById(R.id.popup_container);
- }
-
- /** Pauses view updates that should not be run during the app launch animation. */
- public void pauseExpensiveViewUpdates() {
- // Pause page indicator animations as they lead to layer trashing.
- getWorkspace().getPageIndicator().pauseAnimations();
-
- getWorkspace().mapOverItems((info, view) -> {
- if (view instanceof LauncherAppWidgetHostView) {
- ((LauncherAppWidgetHostView) view).beginDeferringUpdates();
- }
- return false; // Return false to continue iterating through all the items.
- });
- }
-
- /** Resumes view updates at the end of the app launch animation. */
- public void resumeExpensiveViewUpdates() {
- getWorkspace().getPageIndicator().skipAnimationsToEnd();
-
- getWorkspace().mapOverItems((info, view) -> {
- if (view instanceof LauncherAppWidgetHostView) {
- ((LauncherAppWidgetHostView) view).endDeferringUpdates();
- }
- return false; // Return false to continue iterating through all the items.
- });
- }
}
diff --git a/src/com/android/launcher3/LauncherAnimUtils.java b/src/com/android/launcher3/LauncherAnimUtils.java
index 808bf96f9f..b56c0127ff 100644
--- a/src/com/android/launcher3/LauncherAnimUtils.java
+++ b/src/com/android/launcher3/LauncherAnimUtils.java
@@ -27,8 +27,6 @@ import android.util.IntProperty;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
-import com.android.launcher3.util.MultiScalePropertyFactory;
-
public class LauncherAnimUtils {
/**
* Durations for various state animations. These are not defined in resources to allow
@@ -38,7 +36,6 @@ public class LauncherAnimUtils {
// Progress after which the transition is assumed to be a success
public static final float SUCCESS_TRANSITION_PROGRESS = 0.5f;
- public static final float TABLET_BOTTOM_SHEET_SUCCESS_TRANSITION_PROGRESS = 0.3f;
public static final IntProperty<Drawable> DRAWABLE_ALPHA =
new IntProperty<Drawable>("drawableAlpha") {
@@ -67,23 +64,6 @@ public class LauncherAnimUtils {
}
};
- /**
- * Property to set the scale of workspace. The value is based on a combination
- * of all the ones set, to have a smooth experience even in the case of overlapping scaling
- * animation.
- */
- public static final MultiScalePropertyFactory<Workspace<?>> WORKSPACE_SCALE_PROPERTY_FACTORY =
- new MultiScalePropertyFactory<Workspace<?>>("workspace_scale_property");
-
- /** Property to set the scale of hotseat. */
- public static final MultiScalePropertyFactory<Hotseat> HOTSEAT_SCALE_PROPERTY_FACTORY =
- new MultiScalePropertyFactory<Hotseat>("hotseat_scale_property");
-
- public static final int SCALE_INDEX_UNFOLD_ANIMATION = 1;
- public static final int SCALE_INDEX_UNLOCK_ANIMATION = 2;
- public static final int SCALE_INDEX_WORKSPACE_STATE = 3;
- public static final int SCALE_INDEX_REVEAL_ANIM = 4;
-
/** Increase the duration if we prevented the fling, as we are going against a high velocity. */
public static int blockedFlingDurationFactor(float velocity) {
return (int) Utilities.boundToRange(Math.abs(velocity) / 2, 2f, 6f);
diff --git a/src/com/android/launcher3/LauncherAppState.java b/src/com/android/launcher3/LauncherAppState.java
index 597bc8da3a..3d6be696bb 100644
--- a/src/com/android/launcher3/LauncherAppState.java
+++ b/src/com/android/launcher3/LauncherAppState.java
@@ -16,8 +16,6 @@
package com.android.launcher3;
-import static android.app.admin.DevicePolicyManager.ACTION_DEVICE_POLICY_RESOURCE_UPDATED;
-
import static com.android.launcher3.Utilities.getDevicePrefs;
import static com.android.launcher3.config.FeatureFlags.ENABLE_THEMED_ICONS;
import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
@@ -38,7 +36,6 @@ import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.graphics.IconShape;
import com.android.launcher3.icons.IconCache;
import com.android.launcher3.icons.IconProvider;
-import com.android.launcher3.icons.LauncherIconProvider;
import com.android.launcher3.icons.LauncherIcons;
import com.android.launcher3.notification.NotificationListener;
import com.android.launcher3.pm.InstallSessionHelper;
@@ -51,9 +48,10 @@ import com.android.launcher3.util.SafeCloseable;
import com.android.launcher3.util.SettingsCache;
import com.android.launcher3.util.SimpleBroadcastReceiver;
import com.android.launcher3.util.Themes;
+import com.android.launcher3.widget.DatabaseWidgetPreviewLoader;
import com.android.launcher3.widget.custom.CustomWidgetManager;
-public class LauncherAppState implements SafeCloseable {
+public class LauncherAppState {
public static final String ACTION_FORCE_ROLOAD = "force-reload-launcher";
private static final String KEY_ICON_STATE = "pref_icon_shape_path";
@@ -64,8 +62,9 @@ public class LauncherAppState implements SafeCloseable {
private final Context mContext;
private final LauncherModel mModel;
- private final LauncherIconProvider mIconProvider;
+ private final IconProvider mIconProvider;
private final IconCache mIconCache;
+ private final DatabaseWidgetPreviewLoader mWidgetCache;
private final InvariantDeviceProfile mInvariantDeviceProfile;
private final RunnableList mOnTerminateCallback = new RunnableList();
@@ -86,11 +85,7 @@ public class LauncherAppState implements SafeCloseable {
Log.v(Launcher.TAG, "LauncherAppState initiated");
Preconditions.assertUIThread();
- mInvariantDeviceProfile.addOnChangeListener(modelPropertiesChanged -> {
- if (modelPropertiesChanged) {
- refreshAndReloadLauncher();
- }
- });
+ mInvariantDeviceProfile.addOnChangeListener(idp -> refreshAndReloadLauncher());
mContext.getSystemService(LauncherApps.class).registerCallback(mModel);
@@ -99,10 +94,9 @@ public class LauncherAppState implements SafeCloseable {
modelChangeReceiver.register(mContext, Intent.ACTION_LOCALE_CHANGED,
Intent.ACTION_MANAGED_PROFILE_AVAILABLE,
Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE,
- Intent.ACTION_MANAGED_PROFILE_UNLOCKED,
- ACTION_DEVICE_POLICY_RESOURCE_UPDATED);
+ Intent.ACTION_MANAGED_PROFILE_UNLOCKED);
if (FeatureFlags.IS_STUDIO_BUILD) {
- modelChangeReceiver.register(mContext, Context.RECEIVER_EXPORTED, ACTION_FORCE_ROLOAD);
+ modelChangeReceiver.register(mContext, ACTION_FORCE_ROLOAD);
}
mOnTerminateCallback.add(() -> mContext.unregisterReceiver(modelChangeReceiver));
@@ -142,11 +136,11 @@ public class LauncherAppState implements SafeCloseable {
mContext = context;
mInvariantDeviceProfile = InvariantDeviceProfile.INSTANCE.get(context);
- mIconProvider = new LauncherIconProvider(context);
+ mIconProvider = new IconProvider(context, Themes.isThemedIconEnabled(context));
mIconCache = new IconCache(mContext, mInvariantDeviceProfile,
iconCacheFileName, mIconProvider);
- mModel = new LauncherModel(context, this, mIconCache, new AppFilter(mContext),
- iconCacheFileName != null);
+ mWidgetCache = new DatabaseWidgetPreviewLoader(mContext, mIconCache);
+ mModel = new LauncherModel(context, this, mIconCache, new AppFilter(mContext));
mOnTerminateCallback.add(mIconCache::close);
}
@@ -161,14 +155,14 @@ public class LauncherAppState implements SafeCloseable {
LauncherIcons.clearPool();
mIconCache.updateIconParams(
mInvariantDeviceProfile.fillResIconDpi, mInvariantDeviceProfile.iconBitmapSize);
+ mWidgetCache.refresh();
mModel.forceReload();
}
/**
* Call from Application.onTerminate(), which is not guaranteed to ever be called.
*/
- @Override
- public void close() {
+ public void onTerminate() {
mModel.destroy();
mContext.getSystemService(LauncherApps.class).unregisterCallback(mModel);
CustomWidgetManager.INSTANCE.get(mContext).setWidgetRefreshCallback(null);
@@ -187,6 +181,10 @@ public class LauncherAppState implements SafeCloseable {
return mModel;
}
+ public DatabaseWidgetPreviewLoader getWidgetCache() {
+ return mWidgetCache;
+ }
+
public InvariantDeviceProfile getInvariantDeviceProfile() {
return mInvariantDeviceProfile;
}
diff --git a/src/com/android/launcher3/LauncherBackupAgent.java b/src/com/android/launcher3/LauncherBackupAgent.java
index 3d2700de40..140794b074 100644
--- a/src/com/android/launcher3/LauncherBackupAgent.java
+++ b/src/com/android/launcher3/LauncherBackupAgent.java
@@ -8,13 +8,8 @@ import android.os.ParcelFileDescriptor;
import com.android.launcher3.logging.FileLog;
import com.android.launcher3.provider.RestoreDbTask;
-import java.io.File;
-import java.io.IOException;
-
public class LauncherBackupAgent extends BackupAgent {
- private static final String TAG = "LauncherBackupAgent";
-
@Override
public void onCreate() {
super.onCreate();
@@ -29,17 +24,6 @@ public class LauncherBackupAgent extends BackupAgent {
}
@Override
- public void onRestoreFile(ParcelFileDescriptor data, long size, File destination, int type,
- long mode, long mtime) throws IOException {
- // Remove old files which might contain obsolete attributes like idp_grid_name in shared
- // preference that will obstruct backup's attribute from writing to shared preferences.
- if (destination.delete()) {
- FileLog.d("LauncherBackupAgent", "Removed obsolete file: " + destination);
- }
- super.onRestoreFile(data, size, destination, type, mode, mtime);
- }
-
- @Override
public void onBackup(
ParcelFileDescriptor oldState, BackupDataOutput data, ParcelFileDescriptor newState) {
// Doesn't do incremental backup/restore
@@ -47,6 +31,6 @@ public class LauncherBackupAgent extends BackupAgent {
@Override
public void onRestoreFinished() {
- RestoreDbTask.setPending(this);
+ RestoreDbTask.setPending(this, true);
}
}
diff --git a/src/com/android/launcher3/LauncherFiles.java b/src/com/android/launcher3/LauncherFiles.java
index e59eac8dd2..6c0daa4da9 100644
--- a/src/com/android/launcher3/LauncherFiles.java
+++ b/src/com/android/launcher3/LauncherFiles.java
@@ -1,6 +1,5 @@
package com.android.launcher3;
-import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
@@ -16,7 +15,6 @@ public class LauncherFiles {
private static final String XML = ".xml";
public static final String LAUNCHER_DB = "launcher.db";
- public static final String LAUNCHER_6_BY_5_DB = "launcher_6_by_5.db";
public static final String LAUNCHER_4_BY_5_DB = "launcher_4_by_5.db";
public static final String LAUNCHER_4_BY_4_DB = "launcher_4_by_4.db";
public static final String LAUNCHER_3_BY_3_DB = "launcher_3_by_3.db";
@@ -31,25 +29,16 @@ public class LauncherFiles {
public static final String WIDGET_PREVIEWS_DB = "widgetpreviews.db";
public static final String APP_ICONS_DB = "app_icons.db";
- public static final List<String> GRID_DB_FILES = Collections.unmodifiableList(Arrays.asList(
+ public static final List<String> ALL_FILES = Collections.unmodifiableList(Arrays.asList(
LAUNCHER_DB,
- LAUNCHER_6_BY_5_DB,
LAUNCHER_4_BY_5_DB,
LAUNCHER_4_BY_4_DB,
LAUNCHER_3_BY_3_DB,
- LAUNCHER_2_BY_2_DB));
-
- public static final List<String> OTHER_FILES = Collections.unmodifiableList(Arrays.asList(
+ LAUNCHER_2_BY_2_DB,
BACKUP_DB,
SHARED_PREFERENCES_KEY + XML,
WIDGET_PREVIEWS_DB,
MANAGED_USER_PREFERENCES_KEY + XML,
DEVICE_PREFERENCES_KEY + XML,
APP_ICONS_DB));
-
- public static final List<String> ALL_FILES = Collections.unmodifiableList(
- new ArrayList<String>() {{
- addAll(GRID_DB_FILES);
- addAll(OTHER_FILES);
- }});
}
diff --git a/src/com/android/launcher3/LauncherModel.java b/src/com/android/launcher3/LauncherModel.java
index de0d3002e7..545f4c3999 100644
--- a/src/com/android/launcher3/LauncherModel.java
+++ b/src/com/android/launcher3/LauncherModel.java
@@ -16,8 +16,6 @@
package com.android.launcher3;
-import static android.app.admin.DevicePolicyManager.ACTION_DEVICE_POLICY_RESOURCE_UPDATED;
-
import static com.android.launcher3.LauncherAppState.ACTION_FORCE_ROLOAD;
import static com.android.launcher3.config.FeatureFlags.IS_STUDIO_BUILD;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
@@ -53,7 +51,6 @@ import com.android.launcher3.model.ModelWriter;
import com.android.launcher3.model.PackageIncrementalDownloadUpdatedTask;
import com.android.launcher3.model.PackageInstallStateChangedTask;
import com.android.launcher3.model.PackageUpdatedTask;
-import com.android.launcher3.model.ReloadStringCacheTask;
import com.android.launcher3.model.ShortcutsChangedTask;
import com.android.launcher3.model.UserLockStateChangedTask;
import com.android.launcher3.model.data.AppInfo;
@@ -63,7 +60,6 @@ import com.android.launcher3.pm.InstallSessionTracker;
import com.android.launcher3.pm.PackageInstallInfo;
import com.android.launcher3.pm.UserCache;
import com.android.launcher3.shortcuts.ShortcutRequest;
-import com.android.launcher3.testing.TestProtocol;
import com.android.launcher3.util.IntSet;
import com.android.launcher3.util.ItemInfoMatcher;
import com.android.launcher3.util.PackageUserKey;
@@ -100,10 +96,9 @@ public class LauncherModel extends LauncherApps.Callback implements InstallSessi
// our monitoring of the package manager provides all updates and we never
// need to do a requery. This is only ever touched from the loader thread.
private boolean mModelLoaded;
- private boolean mModelDestroyed = false;
public boolean isModelLoaded() {
synchronized (mLock) {
- return mModelLoaded && mLoaderTask == null && !mModelDestroyed;
+ return mModelLoaded && mLoaderTask == null;
}
}
@@ -130,12 +125,10 @@ public class LauncherModel extends LauncherApps.Callback implements InstallSessi
}
};
- LauncherModel(Context context, LauncherAppState app, IconCache iconCache, AppFilter appFilter,
- boolean isPrimaryInstance) {
+ LauncherModel(Context context, LauncherAppState app, IconCache iconCache, AppFilter appFilter) {
mApp = app;
mBgAllAppsList = new AllAppsList(iconCache, appFilter);
- mModelDelegate = ModelDelegate.newInstance(context, app, mBgAllAppsList, mBgDataModel,
- isPrimaryInstance);
+ mModelDelegate = ModelDelegate.newInstance(context, app, mBgAllAppsList, mBgDataModel);
}
public ModelDelegate getModelDelegate() {
@@ -152,10 +145,9 @@ public class LauncherModel extends LauncherApps.Callback implements InstallSessi
enqueueModelUpdateTask(new AddWorkspaceItemsTask(itemList));
}
- public ModelWriter getWriter(boolean hasVerticalHotseat, boolean verifyChanges,
- @Nullable Callbacks owner) {
+ public ModelWriter getWriter(boolean hasVerticalHotseat, boolean verifyChanges) {
return new ModelWriter(mApp.getContext(), this, mBgDataModel,
- hasVerticalHotseat, verifyChanges, owner);
+ hasVerticalHotseat, verifyChanges);
}
@Override
@@ -252,7 +244,6 @@ public class LauncherModel extends LauncherApps.Callback implements InstallSessi
* Called when the model is destroyed
*/
public void destroy() {
- mModelDestroyed = true;
MODEL_EXECUTOR.execute(mModelDelegate::destroy);
}
@@ -281,8 +272,6 @@ public class LauncherModel extends LauncherApps.Callback implements InstallSessi
user, Intent.ACTION_MANAGED_PROFILE_UNLOCKED.equals(action)));
}
}
- } else if (ACTION_DEVICE_POLICY_RESOURCE_UPDATED.equals(action)) {
- enqueueModelUpdateTask(new ReloadStringCacheTask(mModelDelegate));
} else if (IS_STUDIO_BUILD && ACTION_FORCE_ROLOAD.equals(action)) {
for (Callbacks cb : getCallbacks()) {
if (cb instanceof Launcher) {
@@ -341,7 +330,7 @@ public class LauncherModel extends LauncherApps.Callback implements InstallSessi
public boolean addCallbacksAndLoad(Callbacks callbacks) {
synchronized (mLock) {
addCallbacks(callbacks);
- return startLoader(new Callbacks[] { callbacks });
+ return startLoader();
}
}
@@ -352,12 +341,6 @@ public class LauncherModel extends LauncherApps.Callback implements InstallSessi
public void addCallbacks(Callbacks callbacks) {
Preconditions.assertUIThread();
synchronized (mCallbacksList) {
- if (TestProtocol.sDebugTracing) {
- Log.d(TestProtocol.NULL_INT_SET, "addCallbacks pointer: "
- + callbacks
- + ", name: "
- + callbacks.getClass().getName(), new Exception());
- }
mCallbacksList.add(callbacks);
}
}
@@ -367,32 +350,26 @@ public class LauncherModel extends LauncherApps.Callback implements InstallSessi
* @return true if the page could be bound synchronously.
*/
public boolean startLoader() {
- return startLoader(new Callbacks[0]);
- }
-
- private boolean startLoader(Callbacks[] newCallbacks) {
// Enable queue before starting loader. It will get disabled in Launcher#finishBindingItems
ItemInstallQueue.INSTANCE.get(mApp.getContext())
.pauseModelPush(ItemInstallQueue.FLAG_LOADER_RUNNING);
synchronized (mLock) {
- // If there is already one running, tell it to stop.
- boolean wasRunning = stopLoader();
- boolean bindDirectly = mModelLoaded && !mIsLoaderTaskRunning;
- boolean bindAllCallbacks = wasRunning || !bindDirectly || newCallbacks.length == 0;
- final Callbacks[] callbacksList = bindAllCallbacks ? getCallbacks() : newCallbacks;
-
+ // Don't bother to start the thread if we know it's not going to do anything
+ final Callbacks[] callbacksList = getCallbacks();
if (callbacksList.length > 0) {
// Clear any pending bind-runnables from the synchronized load process.
for (Callbacks cb : callbacksList) {
MAIN_EXECUTOR.execute(cb::clearPendingBinds);
}
+ // If there is already one running, tell it to stop.
+ stopLoader();
LoaderResults loaderResults = new LoaderResults(
mApp, mBgDataModel, mBgAllAppsList, callbacksList);
- if (bindDirectly) {
+ if (mModelLoaded && !mIsLoaderTaskRunning) {
// Divide the set of loaded items into those that we are binding synchronously,
// and everything else that is to be bound normally (asynchronously).
- loaderResults.bindWorkspace(bindAllCallbacks);
+ loaderResults.bindWorkspace();
// For now, continue posting the binding of AllApps as there are other
// issues that arise from that.
loaderResults.bindAllApps();
@@ -417,7 +394,7 @@ public class LauncherModel extends LauncherApps.Callback implements InstallSessi
* If there is already a loader task running, tell it to stop.
* @return true if an existing loader was stopped.
*/
- private boolean stopLoader() {
+ public boolean stopLoader() {
synchronized (mLock) {
LoaderTask oldTask = mLoaderTask;
mLoaderTask = null;
@@ -477,9 +454,7 @@ public class LauncherModel extends LauncherApps.Callback implements InstallSessi
}
if (!removedIds.isEmpty()) {
- deleteAndBindComponentsRemoved(
- ItemInfoMatcher.ofItemIds(removedIds),
- "removed because install session failed");
+ deleteAndBindComponentsRemoved(ItemInfoMatcher.ofItemIds(removedIds));
}
}
});
@@ -575,9 +550,6 @@ public class LauncherModel extends LauncherApps.Callback implements InstallSessi
}
public void enqueueModelUpdateTask(ModelUpdateTask task) {
- if (mModelDestroyed) {
- return;
- }
task.init(mApp, this, mBgDataModel, mBgAllAppsList, MAIN_EXECUTOR);
MODEL_EXECUTOR.execute(task);
}
diff --git a/src/com/android/launcher3/LauncherProvider.java b/src/com/android/launcher3/LauncherProvider.java
index 5aa8a46695..440e9e38dd 100644
--- a/src/com/android/launcher3/LauncherProvider.java
+++ b/src/com/android/launcher3/LauncherProvider.java
@@ -16,6 +16,7 @@
package com.android.launcher3;
+import static com.android.launcher3.config.FeatureFlags.MULTI_DB_GRID_MIRATION_ALGO;
import static com.android.launcher3.provider.LauncherDbUtils.copyTable;
import static com.android.launcher3.provider.LauncherDbUtils.dropTable;
import static com.android.launcher3.provider.LauncherDbUtils.tableExists;
@@ -60,6 +61,7 @@ import com.android.launcher3.LauncherSettings.Favorites;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.logging.FileLog;
import com.android.launcher3.model.DbDowngradeHelper;
+import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.pm.UserCache;
import com.android.launcher3.provider.LauncherDbUtils;
import com.android.launcher3.provider.LauncherDbUtils.SQLiteTransaction;
@@ -97,13 +99,11 @@ public class LauncherProvider extends ContentProvider {
* Represents the schema of the database. Changes in scheme need not be backwards compatible.
* When increasing the scheme version, ensure that downgrade_schema.json is updated
*/
- public static final int SCHEMA_VERSION = 31;
+ public static final int SCHEMA_VERSION = 29;
public static final String AUTHORITY = BuildConfig.APPLICATION_ID + ".settings";
public static final String KEY_LAYOUT_PROVIDER_AUTHORITY = "KEY_LAYOUT_PROVIDER_AUTHORITY";
- private static final int TEST_WORKSPACE_LAYOUT_RES_XML = R.xml.default_test_workspace;
-
static final String EMPTY_DATABASE_CREATED = "EMPTY_DATABASE_CREATED";
protected DatabaseHelper mOpenHelper;
@@ -111,8 +111,6 @@ public class LauncherProvider extends ContentProvider {
private long mLastRestoreTimestamp = 0L;
- private boolean mUseTestWorkspaceLayout;
-
/**
* $ adb shell dumpsys activity provider com.android.launcher3
*/
@@ -155,14 +153,21 @@ public class LauncherProvider extends ContentProvider {
mOpenHelper = DatabaseHelper.createDatabaseHelper(
getContext(), false /* forMigration */);
- RestoreDbTask.restoreIfNeeded(getContext(), mOpenHelper);
+ if (RestoreDbTask.isPending(getContext())) {
+ if (!RestoreDbTask.performRestore(getContext(), mOpenHelper,
+ new BackupManager(getContext()))) {
+ mOpenHelper.createEmptyDB(mOpenHelper.getWritableDatabase());
+ }
+ // Set is pending to false irrespective of the result, so that it doesn't get
+ // executed again.
+ RestoreDbTask.setPending(getContext(), false);
+ }
}
}
private synchronized boolean prepForMigration(String dbFile, String targetTableName,
Supplier<DatabaseHelper> src, Supplier<DatabaseHelper> dst) {
if (TextUtils.equals(dbFile, mOpenHelper.getDatabaseName())) {
- Log.e("b/198965093", "prepForMigration - target db is same as current: " + dbFile);
return false;
}
@@ -388,21 +393,13 @@ public class LauncherProvider extends ContentProvider {
case LauncherSettings.Settings.METHOD_NEW_SCREEN_ID: {
Bundle result = new Bundle();
result.putInt(LauncherSettings.Settings.EXTRA_VALUE,
- mOpenHelper.getNewScreenId());
+ mOpenHelper.generateNewScreenId());
return result;
}
case LauncherSettings.Settings.METHOD_CREATE_EMPTY_DB: {
mOpenHelper.createEmptyDB(mOpenHelper.getWritableDatabase());
return null;
}
- case LauncherSettings.Settings.METHOD_SET_USE_TEST_WORKSPACE_LAYOUT_FLAG: {
- mUseTestWorkspaceLayout = true;
- return null;
- }
- case LauncherSettings.Settings.METHOD_CLEAR_USE_TEST_WORKSPACE_LAYOUT_FLAG: {
- mUseTestWorkspaceLayout = false;
- return null;
- }
case LauncherSettings.Settings.METHOD_LOAD_DEFAULT_FAVORITES: {
loadDefaultFavoritesIfNecessary();
return null;
@@ -437,26 +434,32 @@ public class LauncherProvider extends ContentProvider {
return null;
}
case LauncherSettings.Settings.METHOD_UPDATE_CURRENT_OPEN_HELPER: {
- Bundle result = new Bundle();
- result.putBoolean(LauncherSettings.Settings.EXTRA_VALUE,
- prepForMigration(
- arg /* dbFile */,
- Favorites.TMP_TABLE,
- () -> mOpenHelper,
- () -> DatabaseHelper.createDatabaseHelper(
- getContext(), true /* forMigration */)));
- return result;
+ if (MULTI_DB_GRID_MIRATION_ALGO.get()) {
+ Bundle result = new Bundle();
+ result.putBoolean(LauncherSettings.Settings.EXTRA_VALUE,
+ prepForMigration(
+ InvariantDeviceProfile.INSTANCE.get(getContext()).dbFile,
+ Favorites.TMP_TABLE,
+ () -> mOpenHelper,
+ () -> DatabaseHelper.createDatabaseHelper(
+ getContext(), true /* forMigration */)));
+ return result;
+ }
+ return null;
}
case LauncherSettings.Settings.METHOD_PREP_FOR_PREVIEW: {
- Bundle result = new Bundle();
- result.putBoolean(LauncherSettings.Settings.EXTRA_VALUE,
- prepForMigration(
- arg /* dbFile */,
- Favorites.PREVIEW_TABLE_NAME,
- () -> DatabaseHelper.createDatabaseHelper(
- getContext(), arg, true /* forMigration */),
- () -> mOpenHelper));
- return result;
+ if (MULTI_DB_GRID_MIRATION_ALGO.get()) {
+ Bundle result = new Bundle();
+ result.putBoolean(LauncherSettings.Settings.EXTRA_VALUE,
+ prepForMigration(
+ arg /* dbFile */,
+ Favorites.PREVIEW_TABLE_NAME,
+ () -> DatabaseHelper.createDatabaseHelper(
+ getContext(), arg, true /* forMigration */),
+ () -> mOpenHelper));
+ return result;
+ }
+ return null;
}
case LauncherSettings.Settings.METHOD_SWITCH_DATABASE: {
if (TextUtils.equals(arg, mOpenHelper.getDatabaseName())) return null;
@@ -496,7 +499,7 @@ public class LauncherProvider extends ContentProvider {
LauncherSettings.Favorites.CONTAINER + " FROM "
+ Favorites.TABLE_NAME + ")";
- IntArray folderIds = LauncherDbUtils.queryIntArray(false, db, Favorites.TABLE_NAME,
+ IntArray folderIds = LauncherDbUtils.queryIntArray(db, Favorites.TABLE_NAME,
Favorites._ID, selection, null, null);
if (!folderIds.isEmpty()) {
db.delete(Favorites.TABLE_NAME, Utilities.createDbSelectionQuery(
@@ -622,8 +625,7 @@ public class LauncherProvider extends ContentProvider {
private DefaultLayoutParser getDefaultLayoutParser(AppWidgetHost widgetHost) {
InvariantDeviceProfile idp = LauncherAppState.getIDP(getContext());
- int defaultLayout = mUseTestWorkspaceLayout
- ? TEST_WORKSPACE_LAYOUT_RES_XML : idp.defaultLayoutId;
+ int defaultLayout = idp.defaultLayoutId;
if (getContext().getSystemService(UserManager.class).isDemoUser()
&& idp.demoModeLayoutId != 0) {
@@ -642,6 +644,7 @@ public class LauncherProvider extends ContentProvider {
private final Context mContext;
private final boolean mForMigration;
private int mMaxItemId = -1;
+ private int mMaxScreenId = -1;
private boolean mBackupTableExists;
private boolean mHotseatRestoreTableExists;
@@ -652,7 +655,8 @@ public class LauncherProvider extends ContentProvider {
static DatabaseHelper createDatabaseHelper(Context context, String dbName,
boolean forMigration) {
if (dbName == null) {
- dbName = InvariantDeviceProfile.INSTANCE.get(context).dbFile;
+ dbName = MULTI_DB_GRID_MIRATION_ALGO.get() ? InvariantDeviceProfile.INSTANCE.get(
+ context).dbFile : LauncherFiles.LAUNCHER_DB;
}
DatabaseHelper databaseHelper = new DatabaseHelper(context, dbName, forMigration);
// Table creation sometimes fails silently, which leads to a crash loop.
@@ -663,6 +667,10 @@ public class LauncherProvider extends ContentProvider {
// This operation is a no-op if the table already exists.
databaseHelper.addFavoritesTable(databaseHelper.getWritableDatabase(), true);
}
+ if (!MULTI_DB_GRID_MIRATION_ALGO.get()) {
+ databaseHelper.mBackupTableExists = tableExists(
+ databaseHelper.getReadableDatabase(), Favorites.BACKUP_TABLE_NAME);
+ }
databaseHelper.mHotseatRestoreTableExists = tableExists(
databaseHelper.getReadableDatabase(), Favorites.HYBRID_HOTSEAT_BACKUP_TABLE);
@@ -685,6 +693,9 @@ public class LauncherProvider extends ContentProvider {
if (mMaxItemId == -1) {
mMaxItemId = initializeMaxItemId(getWritableDatabase());
}
+ if (mMaxScreenId == -1) {
+ mMaxScreenId = initializeMaxScreenId(getWritableDatabase());
+ }
}
@Override
@@ -692,6 +703,7 @@ public class LauncherProvider extends ContentProvider {
if (LOGD) Log.d(TAG, "creating new launcher database");
mMaxItemId = 1;
+ mMaxScreenId = 0;
addFavoritesTable(db, false);
@@ -840,12 +852,16 @@ public class LauncherProvider extends ContentProvider {
case 25:
convertShortcutsToLauncherActivities(db);
case 26:
- // QSB was moved to the grid. Ignore overlapping items
+ // QSB was moved to the grid. Clear the first row on screen 0.
+ if (FeatureFlags.QSB_ON_FIRST_SCREEN &&
+ !LauncherDbUtils.prepareScreenZeroToHostQsb(mContext, db)) {
+ break;
+ }
case 27: {
// Update the favorites table so that the screen ids are ordered based on
// workspace page rank.
- IntArray finalScreens = LauncherDbUtils.queryIntArray(false, db,
- "workspaceScreens", BaseColumns._ID, null, null, "screenRank");
+ IntArray finalScreens = LauncherDbUtils.queryIntArray(db, "workspaceScreens",
+ BaseColumns._ID, null, null, "screenRank");
int[] original = finalScreens.toArray();
Arrays.sort(original);
String updatemap = "";
@@ -873,24 +889,6 @@ public class LauncherProvider extends ContentProvider {
}
}
case 29: {
- // Remove widget panel related leftover workspace items
- db.delete(Favorites.TABLE_NAME, Utilities.createDbSelectionQuery(
- Favorites.SCREEN, IntArray.wrap(-777, -778)), null);
- }
- case 30: {
- if (FeatureFlags.QSB_ON_FIRST_SCREEN) {
- // Clean up first row in screen 0 as it might contain junk data.
- Log.d(TAG, "Cleaning up first row");
- db.delete(Favorites.TABLE_NAME,
- String.format(Locale.ENGLISH,
- "%1$s = %2$d AND %3$s = %4$d AND %5$s = %6$d",
- Favorites.SCREEN, 0,
- Favorites.CONTAINER, Favorites.CONTAINER_DESKTOP,
- Favorites.CELLY, 0), null);
- }
- return;
- }
- case 31: {
// DB Upgraded successfully
return;
}
@@ -941,7 +939,7 @@ public class LauncherProvider extends ContentProvider {
Log.e(TAG, "getAppWidgetIds not supported", e);
return;
}
- final IntSet validWidgets = IntSet.wrap(LauncherDbUtils.queryIntArray(false, db,
+ final IntSet validWidgets = IntSet.wrap(LauncherDbUtils.queryIntArray(db,
Favorites.TABLE_NAME, Favorites.APPWIDGET_ID,
"itemType=" + Favorites.ITEM_TYPE_APPWIDGET, null, null));
for (int widgetId : allWidgets) {
@@ -1065,19 +1063,36 @@ public class LauncherProvider extends ContentProvider {
public void checkId(ContentValues values) {
int id = values.getAsInteger(Favorites._ID);
mMaxItemId = Math.max(id, mMaxItemId);
+
+ Integer screen = values.getAsInteger(Favorites.SCREEN);
+ Integer container = values.getAsInteger(Favorites.CONTAINER);
+ if (screen != null && container != null
+ && container.intValue() == Favorites.CONTAINER_DESKTOP) {
+ mMaxScreenId = Math.max(screen, mMaxScreenId);
+ }
}
private int initializeMaxItemId(SQLiteDatabase db) {
return getMaxId(db, "SELECT MAX(%1$s) FROM %2$s", Favorites._ID, Favorites.TABLE_NAME);
}
- // Returns a new ID to use for an workspace screen in your database that is greater than all
- // existing screen IDs.
- private int getNewScreenId() {
- return getMaxId(getWritableDatabase(),
- "SELECT MAX(%1$s) FROM %2$s WHERE %3$s = %4$d AND %1$s >= 0",
+ // Generates a new ID to use for an workspace screen in your database. This method
+ // should be only called from the main UI thread. As an exception, we do call it when we
+ // call the constructor from the worker thread; however, this doesn't extend until after the
+ // constructor is called, and we only pass a reference to LauncherProvider to LauncherApp
+ // after that point
+ public int generateNewScreenId() {
+ if (mMaxScreenId < 0) {
+ throw new RuntimeException("Error: max screen id was not initialized");
+ }
+ mMaxScreenId += 1;
+ return mMaxScreenId;
+ }
+
+ private int initializeMaxScreenId(SQLiteDatabase db) {
+ return getMaxId(db, "SELECT MAX(%1$s) FROM %2$s WHERE %3$s = %4$d",
Favorites.SCREEN, Favorites.TABLE_NAME, Favorites.CONTAINER,
- Favorites.CONTAINER_DESKTOP) + 1;
+ Favorites.CONTAINER_DESKTOP);
}
@Thunk int loadFavorites(SQLiteDatabase db, AutoInstallsLayout loader) {
@@ -1086,6 +1101,7 @@ public class LauncherProvider extends ContentProvider {
// Ensure that the max ids are initialized
mMaxItemId = initializeMaxItemId(db);
+ mMaxScreenId = initializeMaxScreenId(db);
return count;
}
}
diff --git a/src/com/android/launcher3/LauncherRootView.java b/src/com/android/launcher3/LauncherRootView.java
index a5c5c02735..f26cfe872e 100644
--- a/src/com/android/launcher3/LauncherRootView.java
+++ b/src/com/android/launcher3/LauncherRootView.java
@@ -13,7 +13,6 @@ import android.view.WindowInsets;
import com.android.launcher3.graphics.SysUiScrim;
import com.android.launcher3.statemanager.StatefulActivity;
-import com.android.launcher3.util.window.WindowManagerProxy;
import java.util.Collections;
import java.util.List;
@@ -43,8 +42,15 @@ public class LauncherRootView extends InsettableFrameLayout {
}
private void handleSystemWindowInsets(Rect insets) {
+ DeviceProfile dp = mActivity.getDeviceProfile();
+
+ // Taskbar provides insets, but we don't want that for most Launcher elements so remove it.
+ mTempRect.set(insets);
+ insets = mTempRect;
+ insets.bottom = Math.max(0, insets.bottom - dp.nonOverlappingTaskbarInset);
+
// Update device profile before notifying the children.
- mActivity.getDeviceProfile().updateInsets(insets);
+ dp.updateInsets(insets);
boolean resetState = !insets.equals(mInsets);
setInsets(insets);
@@ -55,8 +61,8 @@ public class LauncherRootView extends InsettableFrameLayout {
@Override
public WindowInsets onApplyWindowInsets(WindowInsets insets) {
- insets = WindowManagerProxy.INSTANCE.get(getContext())
- .normalizeWindowInsets(getContext(), insets, mTempRect);
+ mTempRect.set(insets.getSystemWindowInsetLeft(), insets.getSystemWindowInsetTop(),
+ insets.getSystemWindowInsetRight(), insets.getSystemWindowInsetBottom());
handleSystemWindowInsets(mTempRect);
return insets;
}
diff --git a/src/com/android/launcher3/LauncherSettings.java b/src/com/android/launcher3/LauncherSettings.java
index 66195f3a1d..d663480a35 100644
--- a/src/com/android/launcher3/LauncherSettings.java
+++ b/src/com/android/launcher3/LauncherSettings.java
@@ -95,12 +95,6 @@ public class LauncherSettings {
public static final int ITEM_TYPE_DEEP_SHORTCUT = 6;
/**
- * The favroite is a search action
- */
- public static final int ITEM_TYPE_SEARCH_ACTION = 7;
-
-
- /**
* Type of the item is recents task.
* TODO(hyunyoungs): move constants not related to Favorites DB to a better location.
*/
@@ -205,7 +199,6 @@ public class LauncherSettings {
public static final int CONTAINER_WIDGETS_TRAY = -105;
public static final int CONTAINER_BOTTOM_WIDGETS_TRAY = -112;
public static final int CONTAINER_PIN_WIDGETS = -113;
- public static final int CONTAINER_WALLPAPERS = -114;
// Represents search results view.
public static final int CONTAINER_SEARCH_RESULTS = -106;
public static final int CONTAINER_SHORTCUTS = -107;
@@ -374,12 +367,6 @@ public class LauncherSettings {
public static final String METHOD_CREATE_EMPTY_DB = "create_empty_db";
- public static final String METHOD_SET_USE_TEST_WORKSPACE_LAYOUT_FLAG =
- "set_use_test_workspace_layout_flag";
-
- public static final String METHOD_CLEAR_USE_TEST_WORKSPACE_LAYOUT_FLAG =
- "clear_use_test_workspace_layout_flag";
-
public static final String METHOD_LOAD_DEFAULT_FAVORITES = "load_default_favorites";
public static final String METHOD_REMOVE_GHOST_WIDGETS = "remove_ghost_widgets";
diff --git a/src/com/android/launcher3/LauncherState.java b/src/com/android/launcher3/LauncherState.java
index ea6a9199d7..3399ce9cd6 100644
--- a/src/com/android/launcher3/LauncherState.java
+++ b/src/com/android/launcher3/LauncherState.java
@@ -16,7 +16,6 @@
package com.android.launcher3;
import static com.android.launcher3.anim.Interpolators.ACCEL_2;
-import static com.android.launcher3.anim.Interpolators.DEACCEL_2;
import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_HOME;
import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_OVERVIEW;
import static com.android.launcher3.testing.TestProtocol.ALL_APPS_STATE_ORDINAL;
@@ -58,9 +57,10 @@ public abstract class LauncherState implements BaseState<LauncherState> {
public static final int ALL_APPS_CONTENT = 1 << 1;
public static final int VERTICAL_SWIPE_INDICATOR = 1 << 2;
public static final int OVERVIEW_ACTIONS = 1 << 3;
- public static final int CLEAR_ALL_BUTTON = 1 << 4;
- public static final int WORKSPACE_PAGE_INDICATOR = 1 << 5;
- public static final int SPLIT_PLACHOLDER_VIEW = 1 << 6;
+ public static final int TASKBAR = 1 << 4;
+ public static final int CLEAR_ALL_BUTTON = 1 << 5;
+ public static final int WORKSPACE_PAGE_INDICATOR = 1 << 6;
+ public static final int SPLIT_PLACHOLDER_VIEW = 1 << 7;
// Flag indicating workspace has multiple pages visible.
public static final int FLAG_MULTI_PAGE = BaseState.getFlag(0);
@@ -80,9 +80,6 @@ public abstract class LauncherState implements BaseState<LauncherState> {
public static final int FLAG_CLOSE_POPUPS = BaseState.getFlag(6);
public static final int FLAG_OVERVIEW_UI = BaseState.getFlag(7);
- // Flag indicating that hotseat and its contents are not accessible.
- public static final int FLAG_HOTSEAT_INACCESSIBLE = BaseState.getFlag(8);
-
public static final float NO_OFFSET = 0;
public static final float NO_SCALE = 1;
@@ -95,14 +92,6 @@ public abstract class LauncherState implements BaseState<LauncherState> {
}
};
- protected static final PageTranslationProvider DEFAULT_PAGE_TRANSLATION_PROVIDER =
- new PageTranslationProvider(DEACCEL_2) {
- @Override
- public float getPageTranslation(int pageIndex) {
- return 0;
- }
- };
-
private static final LauncherState[] sAllStates = new LauncherState[10];
/**
@@ -113,7 +102,7 @@ public abstract class LauncherState implements BaseState<LauncherState> {
FLAG_DISABLE_RESTORE | FLAG_WORKSPACE_ICONS_CAN_BE_DRAGGED | FLAG_HIDE_BACK_BUTTON |
FLAG_HAS_SYS_UI_SCRIM) {
@Override
- public int getTransitionDuration(Context context, boolean isToState) {
+ public int getTransitionDuration(Context context) {
// Arbitrary duration, when going to NORMAL we use the state we're coming from instead.
return 0;
}
@@ -192,12 +181,20 @@ public abstract class LauncherState implements BaseState<LauncherState> {
return launcher.getNormalOverviewScaleAndOffset();
}
+ public float getTaskbarScale(Launcher launcher) {
+ return launcher.getNormalTaskbarScale();
+ }
+
+ public float getTaskbarTranslationY(Launcher launcher) {
+ return -launcher.getHotseat().getTaskbarOffsetY();
+ }
+
public float getOverviewFullscreenProgress() {
return 0;
}
public int getVisibleElements(Launcher launcher) {
- return HOTSEAT_ICONS | WORKSPACE_PAGE_INDICATOR | VERTICAL_SWIPE_INDICATOR;
+ return HOTSEAT_ICONS | WORKSPACE_PAGE_INDICATOR | VERTICAL_SWIPE_INDICATOR | TASKBAR;
}
/**
@@ -208,16 +205,6 @@ public abstract class LauncherState implements BaseState<LauncherState> {
return (getVisibleElements(launcher) & elements) == elements;
}
- /** Returns whether taskbar is stashed and thus should replace hotseat with a handle */
- public boolean isTaskbarStashed(Launcher launcher) {
- return false;
- }
-
- /** Returns whether taskbar is aligned with the hotseat vs position inside apps */
- public boolean isTaskbarAlignedWithHotseat(Launcher launcher) {
- return !isTaskbarStashed(launcher);
- }
-
/**
* Fraction shift in the vertical translation UI and related properties
*
@@ -300,25 +287,6 @@ public abstract class LauncherState implements BaseState<LauncherState> {
};
}
- /**
- * Gets the translation provider for workspace pages.
- */
- public PageTranslationProvider getWorkspacePageTranslationProvider(Launcher launcher) {
- if (this != SPRING_LOADED || !launcher.getDeviceProfile().isTwoPanels) {
- return DEFAULT_PAGE_TRANSLATION_PROVIDER;
- }
- final float quarterPageSpacing = launcher.getWorkspace().getPageSpacing() / 4f;
- return new PageTranslationProvider(DEACCEL_2) {
- @Override
- public float getPageTranslation(int pageIndex) {
- boolean isRtl = launcher.getWorkspace().mIsRtl;
- boolean isFirstPage = pageIndex % 2 == 0;
- return ((isFirstPage && !isRtl) || (!isFirstPage && isRtl)) ? -quarterPageSpacing
- : quarterPageSpacing;
- }
- };
- }
-
@Override
public LauncherState getHistoryForState(LauncherState previousState) {
// No history is supported
@@ -349,23 +317,6 @@ public abstract class LauncherState implements BaseState<LauncherState> {
public abstract float getPageAlpha(int pageIndex);
}
- /**
- * Provider for the translation and animation interpolation of workspace pages.
- */
- public abstract static class PageTranslationProvider {
-
- public final Interpolator interpolator;
-
- public PageTranslationProvider(Interpolator interpolator) {
- this.interpolator = interpolator;
- }
-
- /**
- * Gets the translation of the workspace page at the provided page index.
- */
- public abstract float getPageTranslation(int pageIndex);
- }
-
public static class ScaleAndTranslation {
public float scale;
public float translationX;
diff --git a/src/com/android/launcher3/PagedView.java b/src/com/android/launcher3/PagedView.java
index cba0b7d709..b423871259 100644
--- a/src/com/android/launcher3/PagedView.java
+++ b/src/com/android/launcher3/PagedView.java
@@ -16,8 +16,6 @@
package com.android.launcher3;
-import static androidx.annotation.VisibleForTesting.PACKAGE_PRIVATE;
-
import static com.android.launcher3.anim.Interpolators.SCROLL;
import static com.android.launcher3.compat.AccessibilityManagerCompat.isAccessibilityEnabled;
import static com.android.launcher3.compat.AccessibilityManagerCompat.isObservedEventType;
@@ -28,8 +26,6 @@ import static com.android.launcher3.touch.PagedOrientationHandler.VIEW_SCROLL_TO
import android.animation.LayoutTransition;
import android.annotation.SuppressLint;
import android.content.Context;
-import android.content.res.Configuration;
-import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Rect;
@@ -52,7 +48,6 @@ import android.widget.OverScroller;
import android.widget.ScrollView;
import androidx.annotation.Nullable;
-import androidx.annotation.VisibleForTesting;
import com.android.launcher3.compat.AccessibilityManagerCompat;
import com.android.launcher3.config.FeatureFlags;
@@ -60,7 +55,6 @@ import com.android.launcher3.pageindicators.PageIndicator;
import com.android.launcher3.touch.PagedOrientationHandler;
import com.android.launcher3.touch.PagedOrientationHandler.ChildBounds;
import com.android.launcher3.util.EdgeEffectCompat;
-import com.android.launcher3.util.IntSet;
import com.android.launcher3.util.Thunk;
import com.android.launcher3.views.ActivityContext;
@@ -80,30 +74,32 @@ public abstract class PagedView<T extends View & PageIndicator> extends ViewGrou
public static final int INVALID_PAGE = -1;
protected static final ComputePageScrollsLogic SIMPLE_SCROLL_LOGIC = (v) -> v.getVisibility() != GONE;
+ public static final int PAGE_SNAP_ANIMATION_DURATION = 750;
+
private static final float RETURN_TO_ORIGINAL_PAGE_THRESHOLD = 0.33f;
// The page is moved more than halfway, automatically move to the next page on touch up.
private static final float SIGNIFICANT_MOVE_THRESHOLD = 0.4f;
private static final float MAX_SCROLL_PROGRESS = 1.0f;
+ // The following constants need to be scaled based on density. The scaled versions will be
+ // assigned to the corresponding member variables below.
+ private static final int FLING_THRESHOLD_VELOCITY = 500;
+ private static final int EASY_FLING_THRESHOLD_VELOCITY = 400;
+ private static final int MIN_SNAP_VELOCITY = 1500;
+ private static final int MIN_FLING_VELOCITY = 250;
+
private boolean mFreeScroll = false;
- private int mFlingThresholdVelocity;
- private int mEasyFlingThresholdVelocity;
- private int mMinFlingVelocity;
- private int mMinSnapVelocity;
- private int mPageSnapAnimationDuration;
+ protected final int mFlingThresholdVelocity;
+ protected final int mEasyFlingThresholdVelocity;
+ protected final int mMinFlingVelocity;
+ protected final int mMinSnapVelocity;
protected boolean mFirstLayout = true;
@ViewDebug.ExportedProperty(category = "launcher")
protected int mCurrentPage;
- // Difference between current scroll position and mCurrentPage's page scroll. Used to maintain
- // relative scroll position unchanged in updateCurrentPageScroll. Cleared when snapping to a
- // page.
- protected int mCurrentPageScrollDiff;
- // The current page the PagedView is scrolling over on it's way to the destination page.
- protected int mCurrentScrollOverPage;
@ViewDebug.ExportedProperty(category = "launcher")
protected int mNextPage = INVALID_PAGE;
@@ -123,10 +119,7 @@ public abstract class PagedView<T extends View & PageIndicator> extends ViewGrou
private boolean mAllowEasyFling;
protected PagedOrientationHandler mOrientationHandler = PagedOrientationHandler.PORTRAIT;
- private final ArrayList<Runnable> mOnPageScrollsInitializedCallbacks = new ArrayList<>();
-
- // We should always check pageScrollsInitialized() is true when using mPageScrolls.
- @Nullable protected int[] mPageScrolls = null;
+ protected int[] mPageScrolls;
private boolean mIsBeingDragged;
// The amount of movement to begin scrolling
@@ -179,14 +172,17 @@ public abstract class PagedView<T extends View & PageIndicator> extends ViewGrou
mScroller = new OverScroller(context, SCROLL);
mCurrentPage = 0;
- mCurrentScrollOverPage = 0;
final ViewConfiguration configuration = ViewConfiguration.get(context);
mTouchSlop = configuration.getScaledTouchSlop();
mPageSlop = configuration.getScaledPagingTouchSlop();
mMaximumVelocity = configuration.getScaledMaximumFlingVelocity();
- updateVelocityValues();
+ float density = getResources().getDisplayMetrics().density;
+ mFlingThresholdVelocity = (int) (FLING_THRESHOLD_VELOCITY * density);
+ mEasyFlingThresholdVelocity = (int) (EASY_FLING_THRESHOLD_VELOCITY * density);
+ mMinFlingVelocity = (int) (MIN_FLING_VELOCITY * density);
+ mMinSnapVelocity = (int) (MIN_SNAP_VELOCITY * density);
initEdgeEffect();
setDefaultFocusHighlightEnabled(false);
@@ -201,7 +197,7 @@ public abstract class PagedView<T extends View & PageIndicator> extends ViewGrou
public void initParentViews(View parent) {
if (mPageIndicatorViewId > -1) {
mPageIndicator = parent.findViewById(mPageIndicatorViewId);
- mPageIndicator.setMarkersCount(getChildCount() / getPanelCount());
+ mPageIndicator.setMarkersCount(getChildCount());
}
}
@@ -234,6 +230,10 @@ public abstract class PagedView<T extends View & PageIndicator> extends ViewGrou
return getChildAt(index);
}
+ protected int indexToPage(int index) {
+ return index;
+ }
+
/**
* Updates the scroll of the current page immediately to its final scroll position. We use this
* in CustomizePagedView to allow tabs to share the same PagedView while resetting the scroll of
@@ -243,11 +243,11 @@ public abstract class PagedView<T extends View & PageIndicator> extends ViewGrou
// If the current page is invalid, just reset the scroll position to zero
int newPosition = 0;
if (0 <= mCurrentPage && mCurrentPage < getPageCount()) {
- newPosition = getScrollForPage(mCurrentPage) + mCurrentPageScrollDiff;
+ newPosition = getScrollForPage(mCurrentPage);
}
- mOrientationHandler.setPrimary(this, VIEW_SCROLL_TO, newPosition);
+ mOrientationHandler.set(this, VIEW_SCROLL_TO, newPosition);
mScroller.startScroll(mScroller.getCurrX(), 0, newPosition - mScroller.getCurrX(), 0);
- forceFinishScroller();
+ forceFinishScroller(true);
}
/**
@@ -269,16 +269,14 @@ public abstract class PagedView<T extends View & PageIndicator> extends ViewGrou
}
}
- /**
- * Immediately finishes any in-progress scroll, maintaining the current position. Also sets
- * mNextPage = INVALID_PAGE and calls pageEndTransition().
- */
- public void forceFinishScroller() {
+ private void forceFinishScroller(boolean resetNextPage) {
mScroller.forceFinished(true);
// We need to clean up the next page here to avoid computeScrollHelper from
// updating current page on the pass.
- mNextPage = INVALID_PAGE;
- pageEndTransition();
+ if (resetNextPage) {
+ mNextPage = INVALID_PAGE;
+ pageEndTransition();
+ }
}
private int validateNewPage(int newPage) {
@@ -287,21 +285,15 @@ public abstract class PagedView<T extends View & PageIndicator> extends ViewGrou
newPage = Utilities.boundToRange(newPage, 0, getPageCount() - 1);
if (getPanelCount() > 1) {
- // Always return left most panel as new page
+ // Always return left panel as new page
newPage = getLeftmostVisiblePageForIndex(newPage);
}
return newPage;
}
- /**
- * In most cases where panelCount is 1, this method will just return the page index that was
- * passed in.
- * But for example when two panel home is enabled we might need the leftmost visible page index
- * because that page is the current page.
- */
- public int getLeftmostVisiblePageForIndex(int pageIndex) {
+ private int getLeftmostVisiblePageForIndex(int pageIndex) {
int panelCount = getPanelCount();
- return pageIndex - pageIndex % panelCount;
+ return (pageIndex / panelCount) * panelCount;
}
/**
@@ -312,81 +304,23 @@ public abstract class PagedView<T extends View & PageIndicator> extends ViewGrou
}
/**
- * Returns an IntSet with the indices of the currently visible pages
- */
- @VisibleForTesting(otherwise = PACKAGE_PRIVATE)
- public IntSet getVisiblePageIndices() {
- return getPageIndices(mCurrentPage);
- }
-
- /**
- * In case the panelCount is 1 this just returns the same page index in an IntSet.
- * But in cases where the panelCount > 1 this will return all the page indices that belong
- * together, i.e. on the Workspace they are next to each other and shown at the same time.
- */
- private IntSet getPageIndices(int pageIndex) {
- // we want to make sure the pageIndex is the leftmost page
- pageIndex = getLeftmostVisiblePageForIndex(pageIndex);
-
- IntSet pageIndices = new IntSet();
- int panelCount = getPanelCount();
- int pageCount = getPageCount();
- for (int page = pageIndex; page < pageIndex + panelCount && page < pageCount; page++) {
- pageIndices.add(page);
- }
- return pageIndices;
- }
-
- /**
- * Returns an IntSet with the indices of the neighbour pages that are in the focus direction.
- */
- private IntSet getNeighbourPageIndices(int focus) {
- int panelCount = getPanelCount();
- // getNextPage is more reliable than getCurrentPage
- int currentPage = getNextPage();
-
- int nextPage;
- if (focus == View.FOCUS_LEFT) {
- nextPage = currentPage - panelCount;
- } else if (focus == View.FOCUS_RIGHT) {
- nextPage = currentPage + panelCount;
- } else {
- // no neighbours to other directions
- return new IntSet();
- }
- nextPage = validateNewPage(nextPage);
- if (nextPage == currentPage) {
- // We reached the end of the pages
- return new IntSet();
- }
-
- return getPageIndices(nextPage);
- }
-
- /**
* Executes the callback against each visible page
*/
public void forEachVisiblePage(Consumer<View> callback) {
- getVisiblePageIndices().forEach(pageIndex -> {
- View page = getPageAt(pageIndex);
+ int panelCount = getPanelCount();
+ for (int i = mCurrentPage; i < mCurrentPage + panelCount; i++) {
+ View page = getPageAt(i);
if (page != null) {
callback.accept(page);
}
- });
+ }
}
/**
* Returns true if the view is on one of the current pages, false otherwise.
*/
public boolean isVisible(View child) {
- return isVisible(indexOfChild(child));
- }
-
- /**
- * Returns true if the page with the given index is currently visible, false otherwise.
- */
- private boolean isVisible(int pageIndex) {
- return getLeftmostVisiblePageForIndex(pageIndex) == mCurrentPage;
+ return getLeftmostVisiblePageForIndex(indexOfChild(child)) == mCurrentPage;
}
/**
@@ -435,7 +369,6 @@ public abstract class PagedView<T extends View & PageIndicator> extends ViewGrou
}
int prevPage = overridePrevPage != INVALID_PAGE ? overridePrevPage : mCurrentPage;
mCurrentPage = validateNewPage(currentPage);
- mCurrentScrollOverPage = mCurrentPage;
updateCurrentPageScroll();
notifyPageSwitchListener(prevPage);
invalidate();
@@ -491,7 +424,6 @@ public abstract class PagedView<T extends View & PageIndicator> extends ViewGrou
* to provide custom behavior during animation.
*/
protected void onPageEndTransition() {
- mCurrentPageScrollDiff = 0;
AccessibilityManagerCompat.sendScrollFinishedEventToTest(getContext());
AccessibilityManagerCompat.sendCustomAccessibilityEvent(getPageAt(mCurrentPage),
AccessibilityEvent.TYPE_VIEW_FOCUSED, null);
@@ -549,18 +481,16 @@ public abstract class PagedView<T extends View & PageIndicator> extends ViewGrou
int oldPos = mOrientationHandler.getPrimaryScroll(this);
int newPos = mScroller.getCurrX();
if (oldPos != newPos) {
- mOrientationHandler.setPrimary(this, VIEW_SCROLL_TO, mScroller.getCurrX());
+ mOrientationHandler.set(this, VIEW_SCROLL_TO, mScroller.getCurrX());
}
if (mAllowOverScroll) {
if (newPos < mMinScroll && oldPos >= mMinScroll) {
mEdgeGlowLeft.onAbsorb((int) mScroller.getCurrVelocity());
mScroller.abortAnimation();
- onEdgeAbsorbingScroll();
} else if (newPos > mMaxScroll && oldPos <= mMaxScroll) {
mEdgeGlowRight.onAbsorb((int) mScroller.getCurrVelocity());
mScroller.abortAnimation();
- onEdgeAbsorbingScroll();
}
}
@@ -578,7 +508,6 @@ public abstract class PagedView<T extends View & PageIndicator> extends ViewGrou
sendScrollAccessibilityEvent();
int prevPage = mCurrentPage;
mCurrentPage = validateNewPage(mNextPage);
- mCurrentScrollOverPage = mCurrentPage;
mNextPage = INVALID_PAGE;
notifyPageSwitchListener(prevPage);
@@ -618,22 +547,6 @@ public abstract class PagedView<T extends View & PageIndicator> extends ViewGrou
- mInsets.left - mInsets.right;
}
- private void updateVelocityValues() {
- Resources res = getResources();
- mFlingThresholdVelocity = res.getDimensionPixelSize(R.dimen.fling_threshold_velocity);
- mEasyFlingThresholdVelocity =
- res.getDimensionPixelSize(R.dimen.easy_fling_threshold_velocity);
- mMinFlingVelocity = res.getDimensionPixelSize(R.dimen.min_fling_velocity);
- mMinSnapVelocity = res.getDimensionPixelSize(R.dimen.min_page_snap_velocity);
- mPageSnapAnimationDuration = res.getInteger(R.integer.config_pageSnapAnimationDuration);
- }
-
- @Override
- protected void onConfigurationChanged(Configuration newConfig) {
- super.onConfigurationChanged(newConfig);
- updateVelocityValues();
- }
-
@Override
public void requestLayout() {
mIsLayoutValid = false;
@@ -647,10 +560,7 @@ public abstract class PagedView<T extends View & PageIndicator> extends ViewGrou
}
private int getPageWidthSize(int widthSize) {
- // It's necessary to add the padding back because it is remove when measuring children,
- // like when MeasureSpec.getSize in CellLayout.
- return (widthSize - mInsets.left - mInsets.right - getPaddingLeft() - getPaddingRight())
- / getPanelCount() + getPaddingLeft() + getPaddingRight();
+ return (widthSize - mInsets.left - mInsets.right) / getPanelCount();
}
@Override
@@ -693,50 +603,28 @@ public abstract class PagedView<T extends View & PageIndicator> extends ViewGrou
setMeasuredDimension(widthSize, heightSize);
}
- /** Returns true iff this PagedView's scroll amounts are initialized to each page index. */
- protected boolean pageScrollsInitialized() {
- return mPageScrolls != null && mPageScrolls.length == getChildCount();
- }
-
- /**
- * Queues the given callback to be run once {@code mPageScrolls} has been initialized.
- */
- public void runOnPageScrollsInitialized(Runnable callback) {
- mOnPageScrollsInitializedCallbacks.add(callback);
- if (pageScrollsInitialized()) {
- onPageScrollsInitialized();
- }
- }
-
- private void onPageScrollsInitialized() {
- for (Runnable callback : mOnPageScrollsInitializedCallbacks) {
- callback.run();
- }
- mOnPageScrollsInitializedCallbacks.clear();
- }
-
@SuppressLint("DrawAllocation")
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
mIsLayoutValid = true;
final int childCount = getChildCount();
- int[] pageScrolls = mPageScrolls;
boolean pageScrollChanged = false;
- if (!pageScrollsInitialized()) {
- pageScrolls = new int[childCount];
+ if (mPageScrolls == null || childCount != mPageScrolls.length) {
+ mPageScrolls = new int[childCount];
pageScrollChanged = true;
}
- if (DEBUG) Log.d(TAG, "PagedView.onLayout()");
-
- pageScrollChanged |= getPageScrolls(pageScrolls, true, SIMPLE_SCROLL_LOGIC);
- mPageScrolls = pageScrolls;
-
if (childCount == 0) {
- onPageScrollsInitialized();
return;
}
+ if (DEBUG) Log.d(TAG, "PagedView.onLayout()");
+
+ boolean isScrollChanged = getPageScrolls(mPageScrolls, true, SIMPLE_SCROLL_LOGIC);
+ if (isScrollChanged) {
+ pageScrollChanged = true;
+ }
+
final LayoutTransition transition = getLayoutTransition();
// If the transition is running defer updating max scroll, as some empty pages could
// still be present, and a max scroll change could cause sudden jumps in scroll.
@@ -769,7 +657,6 @@ public abstract class PagedView<T extends View & PageIndicator> extends ViewGrou
if (mScroller.isFinished() && pageScrollChanged) {
setCurrentPage(getNextPage());
}
- onPageScrollsInitialized();
}
/**
@@ -789,7 +676,6 @@ public abstract class PagedView<T extends View & PageIndicator> extends ViewGrou
final int scrollOffsetStart = mOrientationHandler.getScrollOffsetStart(this, mInsets);
final int scrollOffsetEnd = mOrientationHandler.getScrollOffsetEnd(this, mInsets);
boolean pageScrollChanged = false;
- int panelCount = getPanelCount();
for (int i = startIndex, childStart = scrollOffsetStart; i != endIndex; i += delta) {
final View child = getPageAt(i);
@@ -807,19 +693,14 @@ public abstract class PagedView<T extends View & PageIndicator> extends ViewGrou
pageScrollChanged = true;
outPageScrolls[i] = pageScroll;
}
- childStart += primaryDimension + getChildGap(i, i + delta);
-
- // This makes sure that the space is added after the page, not after each panel
- int lastPanel = mIsRtl ? 0 : panelCount - 1;
- if (i % panelCount == lastPanel) {
- childStart += mPageSpacing;
- }
+ childStart += primaryDimension + mPageSpacing + getChildGap();
}
}
+ int panelCount = getPanelCount();
if (panelCount > 1) {
for (int i = 0; i < childCount; i++) {
- // In case we have multiple panels, always use left most panel's page scroll for all
+ // In case we have multiple panels, always use left panel's page scroll for all
// panels on the screen.
int adjustedScroll = outPageScrolls[getLeftmostVisiblePageForIndex(i)];
if (outPageScrolls[i] != adjustedScroll) {
@@ -831,7 +712,7 @@ public abstract class PagedView<T extends View & PageIndicator> extends ViewGrou
return pageScrollChanged;
}
- protected int getChildGap(int fromIndex, int toIndex) {
+ protected int getChildGap() {
return 0;
}
@@ -865,7 +746,7 @@ public abstract class PagedView<T extends View & PageIndicator> extends ViewGrou
private void dispatchPageCountChanged() {
if (mPageIndicator != null) {
- mPageIndicator.setMarkersCount(getChildCount() / getPanelCount());
+ mPageIndicator.setMarkersCount(getChildCount());
}
// This ensures that when children are added, they get the correct transforms / alphas
// in accordance with any scroll effects.
@@ -881,10 +762,7 @@ public abstract class PagedView<T extends View & PageIndicator> extends ViewGrou
@Override
public void onViewRemoved(View child) {
super.onViewRemoved(child);
- runOnPageScrollsInitialized(() -> {
- mCurrentPage = validateNewPage(mCurrentPage);
- mCurrentScrollOverPage = mCurrentPage;
- });
+ mCurrentPage = validateNewPage(mCurrentPage);
dispatchPageCountChanged();
}
@@ -901,8 +779,8 @@ public abstract class PagedView<T extends View & PageIndicator> extends ViewGrou
@Override
public boolean requestChildRectangleOnScreen(View child, Rect rectangle, boolean immediate) {
- int page = indexOfChild(child);
- if (!isVisible(page) || !mScroller.isFinished()) {
+ int page = indexToPage(indexOfChild(child));
+ if (page != mCurrentPage || !mScroller.isFinished()) {
if (immediate) {
setCurrentPage(page);
} else {
@@ -941,25 +819,21 @@ public abstract class PagedView<T extends View & PageIndicator> extends ViewGrou
direction = View.FOCUS_LEFT;
}
}
-
- int currentPage = getNextPage();
- int closestNeighbourIndex = -1;
- int closestNeighbourDistance = Integer.MAX_VALUE;
- // Find the closest neighbour page
- for (int neighbourPageIndex : getNeighbourPageIndices(direction)) {
- int distance = Math.abs(neighbourPageIndex - currentPage);
- if (closestNeighbourDistance > distance) {
- closestNeighbourDistance = distance;
- closestNeighbourIndex = neighbourPageIndex;
+ if (direction == View.FOCUS_LEFT) {
+ if (getCurrentPage() > 0) {
+ int nextPage = validateNewPage(getCurrentPage() - 1);
+ snapToPage(nextPage);
+ getChildAt(nextPage).requestFocus(direction);
+ return true;
+ }
+ } else if (direction == View.FOCUS_RIGHT) {
+ if (getCurrentPage() < getPageCount() - 1) {
+ int nextPage = validateNewPage(getCurrentPage() + 1);
+ snapToPage(nextPage);
+ getChildAt(nextPage).requestFocus(direction);
+ return true;
}
}
- if (closestNeighbourIndex != -1) {
- View page = getPageAt(closestNeighbourIndex);
- snapToPage(closestNeighbourIndex);
- page.requestFocus(direction);
- return true;
- }
-
return false;
}
@@ -969,12 +843,28 @@ public abstract class PagedView<T extends View & PageIndicator> extends ViewGrou
return;
}
- // nextPage is more reliable when multiple control movements have been done in a short
- // period of time
- getPageIndices(getNextPage())
- .addAll(getNeighbourPageIndices(direction))
- .forEach(pageIndex ->
- getPageAt(pageIndex).addFocusables(views, direction, focusableMode));
+ // Add the current page's views as focusable and the next possible page's too. If the
+ // last focus change action was left then the left neighbour's views will be added, and
+ // if it was right then the right neighbour's views will be added.
+ // Unfortunately mCurrentPage can be outdated if there were multiple control actions in a
+ // short period of time, but mNextPage is up to date because it is always updated by
+ // method snapToPage.
+ int nextPage = getNextPage();
+ // XXX-RTL: This will be fixed in a future CL
+ if (nextPage >= 0 && nextPage < getPageCount()) {
+ getPageAt(nextPage).addFocusables(views, direction, focusableMode);
+ }
+ if (direction == View.FOCUS_LEFT) {
+ if (nextPage > 0) {
+ nextPage = validateNewPage(nextPage - 1);
+ getPageAt(nextPage).addFocusables(views, direction, focusableMode);
+ }
+ } else if (direction == View.FOCUS_RIGHT) {
+ if (nextPage < getPageCount() - 1) {
+ nextPage = validateNewPage(nextPage + 1);
+ getPageAt(nextPage).addFocusables(views, direction, focusableMode);
+ }
+ }
}
/**
@@ -1094,7 +984,7 @@ public abstract class PagedView<T extends View & PageIndicator> extends ViewGrou
/**
* If being flinged and user touches the screen, initiate drag; otherwise don't.
*/
- protected void updateIsBeingDraggedOnTouchDown(MotionEvent ev) {
+ private void updateIsBeingDraggedOnTouchDown(MotionEvent ev) {
// mScroller.isFinished should be false when being flinged.
final int xDist = Math.abs(mScroller.getFinalX() - mScroller.getCurrX());
final boolean finishedScrolling = (mScroller.isFinished() || xDist < mPageSlop / 3);
@@ -1164,31 +1054,30 @@ public abstract class PagedView<T extends View & PageIndicator> extends ViewGrou
protected float getScrollProgress(int screenCenter, View v, int page) {
final int halfScreenSize = getMeasuredWidth() / 2;
+
int delta = screenCenter - (getScrollForPage(page) + halfScreenSize);
- int panelCount = getPanelCount();
- int pageCount = getChildCount();
+ int count = getChildCount();
+
+ final int totalDistance;
- int adjacentPage = page + panelCount;
+ int adjacentPage = page + 1;
if ((delta < 0 && !mIsRtl) || (delta > 0 && mIsRtl)) {
- adjacentPage = page - panelCount;
+ adjacentPage = page - 1;
}
- final int totalDistance;
- if (adjacentPage < 0 || adjacentPage > pageCount - 1) {
- totalDistance = (v.getMeasuredWidth() + mPageSpacing) * panelCount;
+ if (adjacentPage < 0 || adjacentPage > count - 1) {
+ totalDistance = v.getMeasuredWidth() + mPageSpacing;
} else {
totalDistance = Math.abs(getScrollForPage(adjacentPage) - getScrollForPage(page));
}
float scrollProgress = delta / (totalDistance * 1.0f);
scrollProgress = Math.min(scrollProgress, MAX_SCROLL_PROGRESS);
- scrollProgress = Math.max(scrollProgress, -MAX_SCROLL_PROGRESS);
+ scrollProgress = Math.max(scrollProgress, - MAX_SCROLL_PROGRESS);
return scrollProgress;
}
public int getScrollForPage(int index) {
- // TODO(b/233112195): Use !pageScrollsInitialized() instead of mPageScrolls == null, once we
- // root cause where we should be using runOnPageScrollsInitialized().
if (mPageScrolls == null || index >= mPageScrolls.length || index < 0) {
return 0;
} else {
@@ -1199,7 +1088,7 @@ public abstract class PagedView<T extends View & PageIndicator> extends ViewGrou
// While layout transitions are occurring, a child's position may stray from its baseline
// position. This method returns the magnitude of this stray at any given time.
public int getLayoutTransitionOffsetForPage(int index) {
- if (!pageScrollsInitialized() || index >= mPageScrolls.length || index < 0) {
+ if (mPageScrolls == null || index >= mPageScrolls.length || index < 0) {
return 0;
} else {
View child = getChildAt(index);
@@ -1231,10 +1120,6 @@ public abstract class PagedView<T extends View & PageIndicator> extends ViewGrou
mAllowOverScroll = enable;
}
- protected boolean isSignificantMove(float absoluteDelta, int pageOrientedSize) {
- return absoluteDelta > pageOrientedSize * SIGNIFICANT_MOVE_THRESHOLD;
- }
-
@Override
public boolean onTouchEvent(MotionEvent ev) {
// Skip touch handling if there are no pages to swipe
@@ -1306,7 +1191,6 @@ public abstract class PagedView<T extends View & PageIndicator> extends ViewGrou
}
delta -= consumed;
}
- delta /= mOrientationHandler.getPrimaryScale(this);
// Only scroll and update mLastMotionX if we have moved some discrete amount. We
// keep the remainder because we are actually testing if we've moved from the last
@@ -1316,7 +1200,7 @@ public abstract class PagedView<T extends View & PageIndicator> extends ViewGrou
mLastMotionRemainder = delta - movedDelta;
if (delta != 0) {
- mOrientationHandler.setPrimary(this, VIEW_SCROLL_BY, movedDelta);
+ mOrientationHandler.set(this, VIEW_SCROLL_BY, movedDelta);
if (mAllowOverScroll) {
final float pulledToX = oldScroll + delta;
@@ -1358,12 +1242,12 @@ public abstract class PagedView<T extends View & PageIndicator> extends ViewGrou
velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
int velocity = (int) mOrientationHandler.getPrimaryVelocity(velocityTracker,
- mActivePointerId);
- float delta = primaryDirection - mDownMotionPrimary;
- int pageOrientedSize = (int) (mOrientationHandler.getMeasuredSize(
- getPageAt(mCurrentPage))
- * mOrientationHandler.getPrimaryScale(this));
- boolean isSignificantMove = isSignificantMove(Math.abs(delta), pageOrientedSize);
+ mActivePointerId);
+ int delta = (int) (primaryDirection - mDownMotionPrimary);
+ int pageOrientedSize = mOrientationHandler.getMeasuredSize(getPageAt(mCurrentPage));
+
+ boolean isSignificantMove = Math.abs(delta) > pageOrientedSize *
+ SIGNIFICANT_MOVE_THRESHOLD;
mTotalMotion += Math.abs(mLastMotion + mLastMotionRemainder - primaryDirection);
boolean passedSlop = mAllowEasyFling || mTotalMotion > mPageSlop;
@@ -1457,26 +1341,12 @@ public abstract class PagedView<T extends View & PageIndicator> extends ViewGrou
protected void onNotSnappingToPageInFreeScroll() { }
- /**
- * Called when the view edges absorb part of the scroll. Subclasses can override this
- * to provide custom behavior during animation.
- */
- protected void onEdgeAbsorbingScroll() {
- }
-
- /**
- * Called when the current page closest to the center of the screen changes as part of the
- * scroll. Subclasses can override this to provide custom behavior during scroll.
- */
- protected void onScrollOverPageChanged() {
- }
-
protected boolean shouldFlingForVelocity(int velocity) {
float threshold = mAllowEasyFling ? mEasyFlingThresholdVelocity : mFlingThresholdVelocity;
return Math.abs(velocity) > threshold;
}
- protected void resetTouchState() {
+ private void resetTouchState() {
releaseVelocityTracker();
mIsBeingDragged = false;
mActivePointerId = INVALID_POINTER;
@@ -1569,8 +1439,8 @@ public abstract class PagedView<T extends View & PageIndicator> extends ViewGrou
setCurrentPage(nextPage);
}
- int page = indexOfChild(child);
- if (page >= 0 && !isVisible(page) && !isInTouchMode()) {
+ int page = indexToPage(indexOfChild(child));
+ if (page >= 0 && page != getCurrentPage() && !isInTouchMode()) {
snapToPage(page);
}
}
@@ -1616,7 +1486,7 @@ public abstract class PagedView<T extends View & PageIndicator> extends ViewGrou
return getDisplacementFromScreenCenter(childIndex, screenCenter);
}
- protected int getScreenCenter(int primaryScroll) {
+ private int getScreenCenter(int primaryScroll) {
float primaryScale = mOrientationHandler.getPrimaryScale(this);
float primaryPivot = mOrientationHandler.getPrimaryValue(getPivotX(), getPivotY());
int pageOrientationSize = mOrientationHandler.getMeasuredSize(this);
@@ -1625,7 +1495,7 @@ public abstract class PagedView<T extends View & PageIndicator> extends ViewGrou
}
protected void snapToDestination() {
- snapToPage(getDestinationPage(), mPageSnapAnimationDuration);
+ snapToPage(getDestinationPage(), PAGE_SNAP_ANIMATION_DURATION);
}
// We want the duration of the page snap animation to be influenced by the distance that
@@ -1649,7 +1519,7 @@ public abstract class PagedView<T extends View & PageIndicator> extends ViewGrou
if (Math.abs(velocity) < mMinFlingVelocity) {
// If the velocity is low enough, then treat this more as an automatic page advance
// as opposed to an apparent physical response to flinging
- return snapToPage(whichPage, mPageSnapAnimationDuration);
+ return snapToPage(whichPage, PAGE_SNAP_ANIMATION_DURATION);
}
// Here we compute a "distance" that will be used in the computation of the overall
@@ -1672,11 +1542,11 @@ public abstract class PagedView<T extends View & PageIndicator> extends ViewGrou
}
public boolean snapToPage(int whichPage) {
- return snapToPage(whichPage, mPageSnapAnimationDuration);
+ return snapToPage(whichPage, PAGE_SNAP_ANIMATION_DURATION);
}
public boolean snapToPageImmediately(int whichPage) {
- return snapToPage(whichPage, mPageSnapAnimationDuration, true);
+ return snapToPage(whichPage, PAGE_SNAP_ANIMATION_DURATION, true);
}
public boolean snapToPage(int whichPage, int duration) {
@@ -1701,7 +1571,7 @@ public abstract class PagedView<T extends View & PageIndicator> extends ViewGrou
return false;
}
- if (FeatureFlags.IS_STUDIO_BUILD && !Utilities.IS_RUNNING_IN_TEST_HARNESS) {
+ if (FeatureFlags.IS_STUDIO_BUILD) {
duration *= Settings.Global.getFloat(getContext().getContentResolver(),
Settings.Global.WINDOW_ANIMATION_SCALE, 1);
}
@@ -1740,7 +1610,7 @@ public abstract class PagedView<T extends View & PageIndicator> extends ViewGrou
public boolean scrollLeft() {
if (getNextPage() > 0) {
- snapToPage(getNextPage() - getPanelCount());
+ snapToPage(getNextPage() - 1);
return true;
}
return mAllowOverScroll;
@@ -1748,26 +1618,13 @@ public abstract class PagedView<T extends View & PageIndicator> extends ViewGrou
public boolean scrollRight() {
if (getNextPage() < getChildCount() - 1) {
- snapToPage(getNextPage() + getPanelCount());
+ snapToPage(getNextPage() + 1);
return true;
}
return mAllowOverScroll;
}
@Override
- protected void onScrollChanged(int l, int t, int oldl, int oldt) {
- if (mScroller.isFinished()) {
- // This was not caused by the scroller, skip it.
- return;
- }
- int newDestinationPage = getDestinationPage();
- if (newDestinationPage >= 0 && newDestinationPage != mCurrentScrollOverPage) {
- mCurrentScrollOverPage = newDestinationPage;
- onScrollOverPageChanged();
- }
- }
-
- @Override
public CharSequence getAccessibilityClassName() {
// Some accessibility services have special logic for ScrollView. Since we provide same
// accessibility info as ScrollView, inform the service to handle use the same way.
@@ -1784,23 +1641,20 @@ public abstract class PagedView<T extends View & PageIndicator> extends ViewGrou
public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
super.onInitializeAccessibilityNodeInfo(info);
final boolean pagesFlipped = isPageOrderFlipped();
- info.setScrollable(getPageCount() > 0);
- int primaryScroll = mOrientationHandler.getPrimaryScroll(this);
- if (getCurrentPage() < getPageCount() - getPanelCount()
- || (getCurrentPage() == getPageCount() - getPanelCount()
- && primaryScroll != getScrollForPage(getPageCount() - getPanelCount()))) {
+ int offset = (mAllowOverScroll ? 0 : 1);
+ info.setScrollable(getPageCount() > offset);
+ if (getCurrentPage() < getPageCount() - offset) {
info.addAction(pagesFlipped ?
- AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_BACKWARD
- : AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_FORWARD);
+ AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_BACKWARD
+ : AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_FORWARD);
info.addAction(mIsRtl ?
AccessibilityNodeInfo.AccessibilityAction.ACTION_PAGE_LEFT
: AccessibilityNodeInfo.AccessibilityAction.ACTION_PAGE_RIGHT);
}
- if (getCurrentPage() > 0
- || (getCurrentPage() == 0 && primaryScroll != getScrollForPage(0))) {
+ if (getCurrentPage() >= offset) {
info.addAction(pagesFlipped ?
- AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_FORWARD
- : AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_BACKWARD);
+ AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_FORWARD
+ : AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_BACKWARD);
info.addAction(mIsRtl ?
AccessibilityNodeInfo.AccessibilityAction.ACTION_PAGE_RIGHT
: AccessibilityNodeInfo.AccessibilityAction.ACTION_PAGE_LEFT);
@@ -1845,16 +1699,16 @@ public abstract class PagedView<T extends View & PageIndicator> extends ViewGrou
} break;
case android.R.id.accessibilityActionPageRight: {
if (!mIsRtl) {
- return scrollRight();
+ return scrollRight();
} else {
- return scrollLeft();
+ return scrollLeft();
}
}
case android.R.id.accessibilityActionPageLeft: {
if (!mIsRtl) {
- return scrollLeft();
+ return scrollLeft();
} else {
- return scrollRight();
+ return scrollRight();
}
}
}
diff --git a/src/com/android/launcher3/Partner.java b/src/com/android/launcher3/Partner.java
index 2e27f32226..0bdb37c076 100644
--- a/src/com/android/launcher3/Partner.java
+++ b/src/com/android/launcher3/Partner.java
@@ -142,7 +142,7 @@ public class Partner {
}
if (iconSize > 0) {
- inv.iconSize[InvariantDeviceProfile.INDEX_DEFAULT] = iconSize;
+ inv.iconSize = iconSize;
}
}
}
diff --git a/src/com/android/launcher3/ResourceUtils.java b/src/com/android/launcher3/ResourceUtils.java
index f709acabed..ece123dc62 100644
--- a/src/com/android/launcher3/ResourceUtils.java
+++ b/src/com/android/launcher3/ResourceUtils.java
@@ -28,13 +28,6 @@ public class ResourceUtils {
public static final String NAVBAR_BOTTOM_GESTURE_LARGER_SIZE =
"navigation_bar_gesture_larger_height";
- public static final String NAVBAR_HEIGHT = "navigation_bar_height";
- public static final String NAVBAR_HEIGHT_LANDSCAPE = "navigation_bar_height_landscape";
-
- public static final String STATUS_BAR_HEIGHT = "status_bar_height";
- public static final String STATUS_BAR_HEIGHT_LANDSCAPE = "status_bar_height_landscape";
- public static final String STATUS_BAR_HEIGHT_PORTRAIT = "status_bar_height_portrait";
-
public static int getNavbarSize(String resName, Resources res) {
return getDimenByName(resName, res, DEFAULT_NAVBAR_VALUE);
}
diff --git a/src/com/android/launcher3/SecondaryDropTarget.java b/src/com/android/launcher3/SecondaryDropTarget.java
index f8bc1f4e6e..cd06414d3f 100644
--- a/src/com/android/launcher3/SecondaryDropTarget.java
+++ b/src/com/android/launcher3/SecondaryDropTarget.java
@@ -6,10 +6,8 @@ import static android.appwidget.AppWidgetProviderInfo.WIDGET_FEATURE_RECONFIGURA
import static com.android.launcher3.Launcher.REQUEST_RECONFIGURE_APPWIDGET;
import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_DESKTOP;
import static com.android.launcher3.accessibility.LauncherAccessibilityDelegate.DISMISS_PREDICTION;
-import static com.android.launcher3.accessibility.LauncherAccessibilityDelegate.INVALID;
import static com.android.launcher3.accessibility.LauncherAccessibilityDelegate.RECONFIGURE;
import static com.android.launcher3.accessibility.LauncherAccessibilityDelegate.UNINSTALL;
-import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_DISMISS_PREDICTION_UNDO;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ITEM_DROPPED_ON_DONT_SUGGEST;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ITEM_DROPPED_ON_UNINSTALL;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ITEM_UNINSTALL_CANCELLED;
@@ -48,7 +46,6 @@ import com.android.launcher3.model.data.ItemInfoWithIcon;
import com.android.launcher3.model.data.LauncherAppWidgetInfo;
import com.android.launcher3.util.PackageManagerHelper;
import com.android.launcher3.util.PendingRequestArgs;
-import com.android.launcher3.views.Snackbar;
import com.android.launcher3.widget.LauncherAppWidgetProviderInfo;
import java.net.URISyntaxException;
@@ -70,7 +67,6 @@ public class SecondaryDropTarget extends ButtonDropTarget implements OnAlarmList
private boolean mHadPendingAlarm;
protected int mCurrentAccessibilityAction = -1;
-
public SecondaryDropTarget(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
@@ -136,33 +132,24 @@ public class SecondaryDropTarget extends ButtonDropTarget implements OnAlarmList
}
@Override
- protected void setupItemInfo(ItemInfo info) {
- int buttonType = getButtonType(info, getViewUnderDrag(info));
- if (buttonType != INVALID) {
- setupUi(buttonType);
- }
- }
-
- @Override
protected boolean supportsDrop(ItemInfo info) {
- return getButtonType(info, getViewUnderDrag(info)) != INVALID;
+ return supportsAccessibilityDrop(info, getViewUnderDrag(info));
}
@Override
public boolean supportsAccessibilityDrop(ItemInfo info, View view) {
- return getButtonType(info, view) != INVALID;
- }
-
- private int getButtonType(ItemInfo info, View view) {
if (view instanceof AppWidgetHostView) {
if (getReconfigurableWidgetId(view) != INVALID_APPWIDGET_ID) {
- return RECONFIGURE;
+ setupUi(RECONFIGURE);
+ return true;
}
- return INVALID;
+ return false;
} else if (FeatureFlags.ENABLE_PREDICTION_DISMISS.get() && info.isPredictedItem()) {
- return DISMISS_PREDICTION;
+ setupUi(DISMISS_PREDICTION);
+ return true;
}
+ setupUi(UNINSTALL);
Boolean uninstallDisabled = mUninstallDisabledCache.get(info.user);
if (uninstallDisabled == null) {
UserManager userManager =
@@ -176,20 +163,16 @@ public class SecondaryDropTarget extends ButtonDropTarget implements OnAlarmList
mCacheExpireAlarm.setAlarm(CACHE_EXPIRE_TIMEOUT);
mCacheExpireAlarm.setOnAlarmListener(this);
if (uninstallDisabled) {
- return INVALID;
+ return false;
}
if (info instanceof ItemInfoWithIcon) {
ItemInfoWithIcon iconInfo = (ItemInfoWithIcon) info;
- if ((iconInfo.runtimeStatusFlags & FLAG_SYSTEM_MASK) != 0
- && (iconInfo.runtimeStatusFlags & FLAG_SYSTEM_NO) == 0) {
- return INVALID;
+ if ((iconInfo.runtimeStatusFlags & FLAG_SYSTEM_MASK) != 0) {
+ return (iconInfo.runtimeStatusFlags & FLAG_SYSTEM_NO) != 0;
}
}
- if (getUninstallTarget(info) == null) {
- return INVALID;
- }
- return UNINSTALL;
+ return getUninstallTarget(info) != null;
}
/**
@@ -237,8 +220,7 @@ public class SecondaryDropTarget extends ButtonDropTarget implements OnAlarmList
@Override
public void completeDrop(final DragObject d) {
- ComponentName target = performDropAction(getViewUnderDrag(d.dragInfo), d.dragInfo,
- d.logInstanceId);
+ ComponentName target = performDropAction(getViewUnderDrag(d.dragInfo), d.dragInfo);
if (d.dragSource instanceof DeferredOnComplete) {
DeferredOnComplete deferred = (DeferredOnComplete) d.dragSource;
if (target != null) {
@@ -282,7 +264,7 @@ public class SecondaryDropTarget extends ButtonDropTarget implements OnAlarmList
* Performs the drop action and returns the target component for the dragObject or null if
* the action was not performed.
*/
- protected ComponentName performDropAction(View view, ItemInfo info, InstanceId instanceId) {
+ protected ComponentName performDropAction(View view, ItemInfo info) {
if (mCurrentAccessibilityAction == RECONFIGURE) {
int widgetId = getReconfigurableWidgetId(view);
if (widgetId != INVALID_APPWIDGET_ID) {
@@ -294,16 +276,7 @@ public class SecondaryDropTarget extends ButtonDropTarget implements OnAlarmList
return null;
}
if (mCurrentAccessibilityAction == DISMISS_PREDICTION) {
- if (FeatureFlags.ENABLE_DISMISS_PREDICTION_UNDO.get()) {
- mLauncher.getDragLayer()
- .announceForAccessibility(getContext().getString(R.string.item_removed));
- Snackbar.show(mLauncher, R.string.item_removed, R.string.undo, () -> { }, () -> {
- mStatsLogManager.logger()
- .withInstanceId(instanceId)
- .withItemInfo(info)
- .log(LAUNCHER_DISMISS_PREDICTION_UNDO);
- });
- }
+ // We sent the log event, nothing else left to do
return null;
}
// else: mCurrentAccessibilityAction == UNINSTALL
@@ -330,9 +303,8 @@ public class SecondaryDropTarget extends ButtonDropTarget implements OnAlarmList
@Override
public void onAccessibilityDrop(View view, ItemInfo item) {
- InstanceId instanceId = new InstanceIdSequence().newInstanceId();
- doLog(instanceId, item);
- performDropAction(view, item, instanceId);
+ doLog(new InstanceIdSequence().newInstanceId(), item);
+ performDropAction(view, item);
}
/**
diff --git a/src/com/android/launcher3/SessionCommitReceiver.java b/src/com/android/launcher3/SessionCommitReceiver.java
index b81637f670..558538c48a 100644
--- a/src/com/android/launcher3/SessionCommitReceiver.java
+++ b/src/com/android/launcher3/SessionCommitReceiver.java
@@ -24,14 +24,12 @@ import android.content.pm.PackageInstaller.SessionInfo;
import android.content.pm.PackageManager;
import android.os.UserHandle;
import android.text.TextUtils;
-import android.util.Log;
import androidx.annotation.WorkerThread;
import com.android.launcher3.logging.FileLog;
import com.android.launcher3.model.ItemInstallQueue;
import com.android.launcher3.pm.InstallSessionHelper;
-import com.android.launcher3.testing.TestProtocol;
import com.android.launcher3.util.Executors;
/**
@@ -53,9 +51,6 @@ public class SessionCommitReceiver extends BroadcastReceiver {
private static void processIntent(Context context, Intent intent) {
if (!isEnabled(context)) {
// User has decided to not add icons on homescreen.
- if (TestProtocol.sDebugTracing) {
- Log.d(TestProtocol.MISSING_PROMISE_ICON, LOG + " not enabled");
- }
return;
}
@@ -64,9 +59,6 @@ public class SessionCommitReceiver extends BroadcastReceiver {
if (!PackageInstaller.ACTION_SESSION_COMMITTED.equals(intent.getAction())
|| info == null || user == null) {
// Invalid intent.
- if (TestProtocol.sDebugTracing) {
- Log.d(TestProtocol.MISSING_PROMISE_ICON, LOG + " invalid intent");
- }
return;
}
@@ -76,15 +68,6 @@ public class SessionCommitReceiver extends BroadcastReceiver {
|| info.getInstallReason() != PackageManager.INSTALL_REASON_USER
|| packageInstallerCompat.promiseIconAddedForId(info.getSessionId())) {
packageInstallerCompat.removePromiseIconId(info.getSessionId());
- if (TestProtocol.sDebugTracing) {
- int id = info.getSessionId();
- Log.d(TestProtocol.MISSING_PROMISE_ICON, LOG
- + ", TextUtils.isEmpty=" + TextUtils.isEmpty(info.getAppPackageName())
- + ", info.getInstallReason()=" + info.getInstallReason()
- + ", INSTALL_REASON_USER=" + PackageManager.INSTALL_REASON_USER
- + ", icon added=" + packageInstallerCompat.promiseIconAddedForId(id)
- );
- }
return;
}
diff --git a/src/com/android/launcher3/ShortcutAndWidgetContainer.java b/src/com/android/launcher3/ShortcutAndWidgetContainer.java
index 5583eaeba9..519b63d58e 100644
--- a/src/com/android/launcher3/ShortcutAndWidgetContainer.java
+++ b/src/com/android/launcher3/ShortcutAndWidgetContainer.java
@@ -19,12 +19,10 @@ package com.android.launcher3;
import static android.view.MotionEvent.ACTION_DOWN;
import static com.android.launcher3.CellLayout.FOLDER;
-import static com.android.launcher3.CellLayout.HOTSEAT;
import static com.android.launcher3.CellLayout.WORKSPACE;
import android.app.WallpaperManager;
import android.content.Context;
-import android.graphics.Point;
import android.graphics.Rect;
import android.view.MotionEvent;
import android.view.View;
@@ -33,7 +31,7 @@ import android.view.ViewGroup;
import com.android.launcher3.CellLayout.ContainerType;
import com.android.launcher3.folder.FolderIcon;
import com.android.launcher3.views.ActivityContext;
-import com.android.launcher3.widget.NavigableAppWidgetHostView;
+import com.android.launcher3.widget.LauncherAppWidgetHostView;
public class ShortcutAndWidgetContainer extends ViewGroup implements FolderIcon.FolderIconParent {
static final String TAG = "ShortcutAndWidgetContainer";
@@ -50,7 +48,7 @@ public class ShortcutAndWidgetContainer extends ViewGroup implements FolderIcon.
private int mCellWidth;
private int mCellHeight;
- private Point mBorderSpace;
+ private int mBorderSpacing;
private int mCountX;
private int mCountY;
@@ -66,12 +64,12 @@ public class ShortcutAndWidgetContainer extends ViewGroup implements FolderIcon.
}
public void setCellDimensions(int cellWidth, int cellHeight, int countX, int countY,
- Point borderSpace) {
+ int borderSpacing) {
mCellWidth = cellWidth;
mCellHeight = cellHeight;
mCountX = countX;
mCountY = countY;
- mBorderSpace = borderSpace;
+ mBorderSpacing = borderSpacing;
}
public View getChildAt(int cellX, int cellY) {
@@ -106,14 +104,14 @@ public class ShortcutAndWidgetContainer extends ViewGroup implements FolderIcon.
public void setupLp(View child) {
CellLayout.LayoutParams lp = (CellLayout.LayoutParams) child.getLayoutParams();
- if (child instanceof NavigableAppWidgetHostView) {
+ if (child instanceof LauncherAppWidgetHostView) {
DeviceProfile profile = mActivity.getDeviceProfile();
- ((NavigableAppWidgetHostView) child).getWidgetInset(profile, mTempRect);
+ ((LauncherAppWidgetHostView) child).getWidgetInset(profile, mTempRect);
lp.setup(mCellWidth, mCellHeight, invertLayoutHorizontally(), mCountX, mCountY,
- profile.appWidgetScale.x, profile.appWidgetScale.y, mBorderSpace, mTempRect);
+ profile.appWidgetScale.x, profile.appWidgetScale.y, mBorderSpacing, mTempRect);
} else {
lp.setup(mCellWidth, mCellHeight, invertLayoutHorizontally(), mCountX, mCountY,
- mBorderSpace, null);
+ mBorderSpacing, null);
}
}
@@ -131,13 +129,13 @@ public class ShortcutAndWidgetContainer extends ViewGroup implements FolderIcon.
CellLayout.LayoutParams lp = (CellLayout.LayoutParams) child.getLayoutParams();
final DeviceProfile dp = mActivity.getDeviceProfile();
- if (child instanceof NavigableAppWidgetHostView) {
- ((NavigableAppWidgetHostView) child).getWidgetInset(dp, mTempRect);
+ if (child instanceof LauncherAppWidgetHostView) {
+ ((LauncherAppWidgetHostView) child).getWidgetInset(dp, mTempRect);
lp.setup(mCellWidth, mCellHeight, invertLayoutHorizontally(), mCountX, mCountY,
- dp.appWidgetScale.x, dp.appWidgetScale.y, mBorderSpace, mTempRect);
+ dp.appWidgetScale.x, dp.appWidgetScale.y, mBorderSpacing, mTempRect);
} else {
lp.setup(mCellWidth, mCellHeight, invertLayoutHorizontally(), mCountX, mCountY,
- mBorderSpace, null);
+ mBorderSpacing, null);
// Center the icon/folder
int cHeight = getCellContentHeight();
int cellPaddingY = dp.isScalableGrid && mContainerType == WORKSPACE
@@ -145,10 +143,8 @@ public class ShortcutAndWidgetContainer extends ViewGroup implements FolderIcon.
: (int) Math.max(0, ((lp.height - cHeight) / 2f));
// No need to add padding when cell layout border spacing is present.
- boolean noPaddingX =
- (dp.cellLayoutBorderSpacePx.x > 0 && mContainerType == WORKSPACE)
- || (dp.folderCellLayoutBorderSpacePx.x > 0 && mContainerType == FOLDER)
- || (dp.hotseatBorderSpace > 0 && mContainerType == HOTSEAT);
+ boolean noPaddingX = (dp.cellLayoutBorderSpacingPx > 0 && mContainerType == WORKSPACE)
+ || (dp.folderCellLayoutBorderSpacingPx > 0 && mContainerType == FOLDER);
int cellPaddingX = noPaddingX
? 0
: mContainerType == WORKSPACE
@@ -182,16 +178,16 @@ public class ShortcutAndWidgetContainer extends ViewGroup implements FolderIcon.
*/
public void layoutChild(View child) {
CellLayout.LayoutParams lp = (CellLayout.LayoutParams) child.getLayoutParams();
- if (child instanceof NavigableAppWidgetHostView) {
- NavigableAppWidgetHostView nahv = (NavigableAppWidgetHostView) child;
+ if (child instanceof LauncherAppWidgetHostView) {
+ LauncherAppWidgetHostView lahv = (LauncherAppWidgetHostView) child;
// Scale and center the widget to fit within its cells.
DeviceProfile profile = mActivity.getDeviceProfile();
float scaleX = profile.appWidgetScale.x;
float scaleY = profile.appWidgetScale.y;
- nahv.setScaleToFit(Math.min(scaleX, scaleY));
- nahv.setTranslationForCentering(-(lp.width - (lp.width * scaleX)) / 2.0f,
+ lahv.setScaleToFit(Math.min(scaleX, scaleY));
+ lahv.setTranslationForCentering(-(lp.width - (lp.width * scaleX)) / 2.0f,
-(lp.height - (lp.height * scaleY)) / 2.0f);
}
@@ -253,7 +249,7 @@ public class ShortcutAndWidgetContainer extends ViewGroup implements FolderIcon.
CellLayout.LayoutParams lp = (CellLayout.LayoutParams) child.getLayoutParams();
// While the folder is open, the position of the icon cannot change.
lp.canReorder = false;
- if (mContainerType == HOTSEAT) {
+ if (mContainerType == CellLayout.HOTSEAT) {
CellLayout cl = (CellLayout) getParent();
cl.setFolderLeaveBehindCell(lp.cellX, lp.cellY);
}
@@ -262,7 +258,7 @@ public class ShortcutAndWidgetContainer extends ViewGroup implements FolderIcon.
@Override
public void clearFolderLeaveBehind(FolderIcon child) {
((CellLayout.LayoutParams) child.getLayoutParams()).canReorder = true;
- if (mContainerType == HOTSEAT) {
+ if (mContainerType == CellLayout.HOTSEAT) {
CellLayout cl = (CellLayout) getParent();
cl.clearFolderLeaveBehind();
}
diff --git a/src/com/android/launcher3/Utilities.java b/src/com/android/launcher3/Utilities.java
index 7b96838dbb..75f6278a47 100644
--- a/src/com/android/launcher3/Utilities.java
+++ b/src/com/android/launcher3/Utilities.java
@@ -16,11 +16,7 @@
package com.android.launcher3;
-import static com.android.launcher3.icons.BitmapInfo.FLAG_THEMED;
import static com.android.launcher3.model.data.ItemInfoWithIcon.FLAG_ICON_BADGED;
-import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_BOTTOM_OR_RIGHT;
-import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT;
-import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_TYPE_MAIN;
import android.annotation.TargetApi;
import android.app.ActivityManager;
@@ -40,6 +36,7 @@ import android.content.pm.ShortcutInfo;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.database.ContentObserver;
+import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.ColorFilter;
import android.graphics.LightingColorFilter;
@@ -48,16 +45,14 @@ import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.RectF;
-import android.graphics.drawable.AdaptiveIconDrawable;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
+import android.graphics.drawable.InsetDrawable;
import android.net.Uri;
import android.os.Build;
-import android.os.Build.VERSION_CODES;
import android.os.DeadObjectException;
import android.os.Handler;
import android.os.Message;
-import android.os.Process;
import android.os.TransactionTooLargeException;
import android.provider.Settings;
import android.text.Spannable;
@@ -73,31 +68,27 @@ import android.view.ViewConfiguration;
import android.view.animation.Interpolator;
import android.widget.LinearLayout;
-import androidx.annotation.ChecksSdkIntAtLeast;
-import androidx.annotation.NonNull;
import androidx.core.graphics.ColorUtils;
+import androidx.core.os.BuildCompat;
import com.android.launcher3.dragndrop.FolderAdaptiveIcon;
import com.android.launcher3.graphics.GridCustomizationsProvider;
import com.android.launcher3.graphics.TintedDrawableSpan;
+import com.android.launcher3.icons.BitmapInfo;
+import com.android.launcher3.icons.FastBitmapDrawable;
+import com.android.launcher3.icons.LauncherIcons;
import com.android.launcher3.icons.ShortcutCachingLogic;
-import com.android.launcher3.icons.ThemedIconDrawable;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.ItemInfoWithIcon;
-import com.android.launcher3.model.data.SearchActionItemInfo;
import com.android.launcher3.pm.ShortcutConfigActivityInfo;
import com.android.launcher3.shortcuts.ShortcutKey;
import com.android.launcher3.shortcuts.ShortcutRequest;
import com.android.launcher3.util.IntArray;
import com.android.launcher3.util.PackageManagerHelper;
-import com.android.launcher3.util.SplitConfigurationOptions.SplitPositionOption;
-import com.android.launcher3.util.Themes;
-import com.android.launcher3.views.ActivityContext;
import com.android.launcher3.views.BaseDragLayer;
import com.android.launcher3.widget.PendingAddShortcutInfo;
import java.lang.reflect.Method;
-import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
@@ -115,6 +106,8 @@ public final class Utilities {
private static final Pattern sTrimPattern =
Pattern.compile("^[\\s|\\p{javaSpaceChar}]*(.*)[\\s|\\p{javaSpaceChar}]*$");
+ private static final float[] sTmpFloatArray = new float[4];
+
private static final int[] sLoc0 = new int[2];
private static final int[] sLoc1 = new int[2];
private static final Matrix sMatrix = new Matrix();
@@ -123,20 +116,14 @@ public final class Utilities {
public static final String[] EMPTY_STRING_ARRAY = new String[0];
public static final Person[] EMPTY_PERSON_ARRAY = new Person[0];
- @ChecksSdkIntAtLeast(api = VERSION_CODES.P)
public static final boolean ATLEAST_P = Build.VERSION.SDK_INT >= Build.VERSION_CODES.P;
- @ChecksSdkIntAtLeast(api = VERSION_CODES.Q)
public static final boolean ATLEAST_Q = Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q;
- @ChecksSdkIntAtLeast(api = VERSION_CODES.R)
public static final boolean ATLEAST_R = Build.VERSION.SDK_INT >= Build.VERSION_CODES.R;
- @ChecksSdkIntAtLeast(api = VERSION_CODES.S)
- public static final boolean ATLEAST_S = Build.VERSION.SDK_INT >= Build.VERSION_CODES.S;
-
- @ChecksSdkIntAtLeast(api = VERSION_CODES.TIRAMISU, codename = "T")
- public static final boolean ATLEAST_T = Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU;
+ public static final boolean ATLEAST_S = BuildCompat.isAtLeastS()
+ || Build.VERSION.SDK_INT >= Build.VERSION_CODES.S;
/**
* Set on a motion event dispatched from the nav bar. See {@link MotionEvent#setEdgeFlags(int)}.
@@ -240,7 +227,7 @@ public final class Utilities {
offsetPoints(coord, v.getLeft(), v.getTop());
scale *= v.getScaleX();
- v = v.getParent() instanceof View ? (View) v.getParent() : null;
+ v = (View) v.getParent();
}
return scale;
}
@@ -273,16 +260,6 @@ public final class Utilities {
}
/**
- * Similar to {@link #mapCoordInSelfToDescendant(View descendant, View root, float[] coord)}
- * but accepts a Rect instead of float[].
- */
- public static void mapRectInSelfToDescendant(View descendant, View root, Rect rect) {
- float[] coords = new float[]{rect.left, rect.top, rect.right, rect.bottom};
- mapCoordInSelfToDescendant(descendant, root, coords);
- rect.set((int) coords[0], (int) coords[1], (int) coords[2], (int) coords[3]);
- }
-
- /**
* Inverse of {@link #getDescendantCoordRelativeToAncestor(View, View, float[], boolean)}.
*/
public static void mapCoordInSelfToDescendant(View descendant, View root, float[] coord) {
@@ -403,21 +380,6 @@ public final class Utilities {
}
/**
- * Similar to {@link #scaleRectAboutCenter(Rect, float)} except this allows different scales
- * for X and Y
- */
- public static void scaleRectFAboutCenter(RectF r, float scaleX, float scaleY) {
- float px = r.centerX();
- float py = r.centerY();
- r.offset(-px, -py);
- r.left = r.left * scaleX;
- r.top = r.top * scaleY;
- r.right = r.right * scaleX;
- r.bottom = r.bottom * scaleY;
- r.offset(px, py);
- }
-
- /**
* Maps t from one range to another range.
* @param t The value to map.
* @param fromMin The lower bound of the range that t is being mapped from.
@@ -479,10 +441,9 @@ public final class Utilities {
* Trims the string, removing all whitespace at the beginning and end of the string.
* Non-breaking whitespaces are also removed.
*/
- @NonNull
public static String trim(CharSequence s) {
if (s == null) {
- return "";
+ return null;
}
// Just strip any sequence of whitespace or java space characters from the beginning and end
@@ -504,11 +465,6 @@ public final class Utilities {
return res.getConfiguration().getLayoutDirection() == View.LAYOUT_DIRECTION_RTL;
}
- /** Converts a pixel value (px) to scale pixel value (SP) for the current device. */
- public static float pxToSp(float size) {
- return size / Resources.getSystem().getDisplayMetrics().scaledDensity;
- }
-
public static float dpiFromPx(float size, int densityDpi) {
float densityRatio = (float) densityDpi / DisplayMetrics.DENSITY_DEFAULT;
return (size / densityRatio);
@@ -552,18 +508,6 @@ public final class Utilities {
}
/**
- * Using the view's bounds and icon size, calculate where the icon bounds will
- * be if it was positioned at the center of the view.
- */
- public static void setRectToViewCenter(View iconView, int iconSize, Rect outBounds) {
- int top = (iconView.getHeight() - iconSize) / 2;
- int left = (iconView.getWidth() - iconSize) / 2;
- int right = left + iconSize;
- int bottom = top + iconSize;
- outBounds.set(left, top, right, bottom);
- }
-
- /**
* Ensures that a value is within given bounds. Specifically:
* If value is less than lowerBound, return lowerBound; else if value is greater than upperBound,
* return upperBound; else return value unchanged.
@@ -634,10 +578,6 @@ public final class Utilities {
LauncherFiles.DEVICE_PREFERENCES_KEY, Context.MODE_PRIVATE);
}
- public static boolean isWallpaperSupported(Context context) {
- return context.getSystemService(WallpaperManager.class).isWallpaperSupported();
- }
-
public static boolean isWallpaperAllowed(Context context) {
return context.getSystemService(WallpaperManager.class).isSetWallpaperAllowed();
}
@@ -692,6 +632,21 @@ public final class Utilities {
handler.sendMessage(msg);
}
+ /**
+ * Parses a string encoded using {@link #getPointString(int, int)}
+ */
+ public static Point parsePoint(String point) {
+ String[] split = point.split(",");
+ return new Point(Integer.parseInt(split[0]), Integer.parseInt(split[1]));
+ }
+
+ /**
+ * Encodes a point to string to that it can be persisted atomically.
+ */
+ public static String getPointString(int x, int y) {
+ return String.format(Locale.ENGLISH, "%d,%d", x, y);
+ }
+
public static void unregisterReceiverSafely(Context context, BroadcastReceiver receiver) {
try {
context.unregisterReceiver(receiver);
@@ -701,38 +656,28 @@ public final class Utilities {
/**
* Returns the full drawable for info without any flattening or pre-processing.
*
- * @param shouldThemeIcon If true, will theme icons when applicable
- * @param outObj this is set to the internal data associated with {@code info},
+ * @param outObj this is set to the internal data associated with {@param info},
* eg {@link LauncherActivityInfo} or {@link ShortcutInfo}.
*/
- @TargetApi(Build.VERSION_CODES.TIRAMISU)
- public static Drawable getFullDrawable(Context context, ItemInfo info, int width, int height,
- boolean shouldThemeIcon, Object[] outObj) {
- Drawable icon = loadFullDrawableWithoutTheme(context, info, width, height, outObj);
- if (ATLEAST_T && icon instanceof AdaptiveIconDrawable && shouldThemeIcon) {
- AdaptiveIconDrawable aid = (AdaptiveIconDrawable) icon.mutate();
- Drawable mono = aid.getMonochrome();
- if (mono != null && Themes.isThemedIconEnabled(context)) {
- int[] colors = ThemedIconDrawable.getColors(context);
- mono = mono.mutate();
- mono.setTint(colors[1]);
- return new AdaptiveIconDrawable(new ColorDrawable(colors[0]), mono);
- }
+ public static Drawable getFullDrawable(Launcher launcher, ItemInfo info, int width, int height,
+ Object[] outObj) {
+ Drawable icon = loadFullDrawableWithoutTheme(launcher, info, width, height, outObj);
+ if (icon instanceof BitmapInfo.Extender) {
+ icon = ((BitmapInfo.Extender) icon).getThemedDrawable(launcher);
}
return icon;
}
- private static Drawable loadFullDrawableWithoutTheme(Context context, ItemInfo info,
+ private static Drawable loadFullDrawableWithoutTheme(Launcher launcher, ItemInfo info,
int width, int height, Object[] outObj) {
- ActivityContext activity = ActivityContext.lookupContext(context);
- LauncherAppState appState = LauncherAppState.getInstance(context);
+ LauncherAppState appState = LauncherAppState.getInstance(launcher);
if (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION) {
- LauncherActivityInfo activityInfo = context.getSystemService(LauncherApps.class)
+ LauncherActivityInfo activityInfo = launcher.getSystemService(LauncherApps.class)
.resolveActivity(info.getIntent(), info.user);
outObj[0] = activityInfo;
- return activityInfo == null ? null : LauncherAppState.getInstance(context)
+ return activityInfo == null ? null : LauncherAppState.getInstance(launcher)
.getIconProvider().getIcon(
- activityInfo, activity.getDeviceProfile().inv.fillResIconDpi);
+ activityInfo, launcher.getDeviceProfile().inv.fillResIconDpi);
} else if (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT) {
if (info instanceof PendingAddShortcutInfo) {
ShortcutConfigActivityInfo activityInfo =
@@ -741,26 +686,23 @@ public final class Utilities {
return activityInfo.getFullResIcon(appState.getIconCache());
}
List<ShortcutInfo> si = ShortcutKey.fromItemInfo(info)
- .buildRequest(context)
+ .buildRequest(launcher)
.query(ShortcutRequest.ALL);
if (si.isEmpty()) {
return null;
} else {
outObj[0] = si.get(0);
- return ShortcutCachingLogic.getIcon(context, si.get(0),
+ return ShortcutCachingLogic.getIcon(launcher, si.get(0),
appState.getInvariantDeviceProfile().fillResIconDpi);
}
} else if (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_FOLDER) {
FolderAdaptiveIcon icon = FolderAdaptiveIcon.createFolderAdaptiveIcon(
- activity, info.id, new Point(width, height));
+ launcher, info.id, new Point(width, height));
if (icon == null) {
return null;
}
outObj[0] = icon;
return icon;
- } else if (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_SEARCH_ACTION
- && info instanceof SearchActionItemInfo) {
- return ((SearchActionItemInfo) info).bitmap.newIcon(context);
} else {
return null;
}
@@ -773,25 +715,29 @@ public final class Utilities {
* badge. When dragged from workspace or folder, it may contain app AND/OR work profile badge
**/
@TargetApi(Build.VERSION_CODES.O)
- public static Drawable getBadge(Context context, ItemInfo info, Object obj) {
- LauncherAppState appState = LauncherAppState.getInstance(context);
+ public static Drawable getBadge(Launcher launcher, ItemInfo info, Object obj) {
+ LauncherAppState appState = LauncherAppState.getInstance(launcher);
+ int iconSize = appState.getInvariantDeviceProfile().iconBitmapSize;
if (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT) {
boolean iconBadged = (info instanceof ItemInfoWithIcon)
&& (((ItemInfoWithIcon) info).runtimeStatusFlags & FLAG_ICON_BADGED) > 0;
if ((info.id == ItemInfo.NO_ID && !iconBadged)
|| !(obj instanceof ShortcutInfo)) {
// The item is not yet added on home screen.
- return new ColorDrawable(Color.TRANSPARENT);
+ return new FixedSizeEmptyDrawable(iconSize);
}
ShortcutInfo si = (ShortcutInfo) obj;
- return LauncherAppState.getInstance(appState.getContext())
- .getIconCache().getShortcutInfoBadge(si).newIcon(context, FLAG_THEMED);
+ Bitmap badge = LauncherAppState.getInstance(appState.getContext())
+ .getIconCache().getShortcutInfoBadge(si).icon;
+ float badgeSize = LauncherIcons.getBadgeSizeForIconSize(iconSize);
+ float insetFraction = (iconSize - badgeSize) / iconSize;
+ return new InsetDrawable(new FastBitmapDrawable(badge),
+ insetFraction, insetFraction, 0, 0);
} else if (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_FOLDER) {
return ((FolderAdaptiveIcon) obj).getBadge();
} else {
- return Process.myUserHandle().equals(info.user)
- ? new ColorDrawable(Color.TRANSPARENT)
- : context.getDrawable(R.drawable.ic_work_app_badge);
+ return launcher.getPackageManager()
+ .getUserBadgedIcon(new FixedSizeEmptyDrawable(iconSize), info.user);
}
}
@@ -892,44 +838,23 @@ public final class Utilities {
view.setLayoutParams(lp);
}
- public static Rect getViewBounds(@NonNull View v) {
- int[] pos = new int[2];
- v.getLocationOnScreen(pos);
- return new Rect(pos[0], pos[1], pos[0] + v.getWidth(), pos[1] + v.getHeight());
- }
+ private static class FixedSizeEmptyDrawable extends ColorDrawable {
- /**
- * Returns a list of screen-splitting options depending on the device orientation (split top for
- * portrait, split left for landscape, split left and right for landscape tablets, etc.)
- */
- public static List<SplitPositionOption> getSplitPositionOptions(
- DeviceProfile dp) {
- List<SplitPositionOption> options = new ArrayList<>();
- // Add both left and right options if we're in tablet mode
- if (dp.isTablet && dp.isLandscape) {
- options.add(new SplitPositionOption(
- R.drawable.ic_split_left, R.string.split_screen_position_left,
- STAGE_POSITION_TOP_OR_LEFT, STAGE_TYPE_MAIN));
- options.add(new SplitPositionOption(
- R.drawable.ic_split_right, R.string.split_screen_position_right,
- STAGE_POSITION_BOTTOM_OR_RIGHT, STAGE_TYPE_MAIN));
- } else {
- if (dp.isSeascape()) {
- // Add left/right options
- options.add(new SplitPositionOption(
- R.drawable.ic_split_right, R.string.split_screen_position_right,
- STAGE_POSITION_BOTTOM_OR_RIGHT, STAGE_TYPE_MAIN));
- } else if (dp.isLandscape) {
- options.add(new SplitPositionOption(
- R.drawable.ic_split_left, R.string.split_screen_position_left,
- STAGE_POSITION_TOP_OR_LEFT, STAGE_TYPE_MAIN));
- } else {
- // Only add top option
- options.add(new SplitPositionOption(
- R.drawable.ic_split_top, R.string.split_screen_position_top,
- STAGE_POSITION_TOP_OR_LEFT, STAGE_TYPE_MAIN));
- }
+ private final int mSize;
+
+ public FixedSizeEmptyDrawable(int size) {
+ super(Color.TRANSPARENT);
+ mSize = size;
+ }
+
+ @Override
+ public int getIntrinsicHeight() {
+ return mSize;
+ }
+
+ @Override
+ public int getIntrinsicWidth() {
+ return mSize;
}
- return options;
}
}
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index 4903d7758a..5bdc4022c2 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -26,11 +26,11 @@ import static com.android.launcher3.LauncherState.HINT_STATE;
import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.launcher3.LauncherState.SPRING_LOADED;
import static com.android.launcher3.anim.AnimatorListeners.forSuccessCallback;
+import static com.android.launcher3.config.FeatureFlags.ADAPTIVE_ICON_WINDOW_ANIM;
import static com.android.launcher3.dragndrop.DragLayer.ALPHA_INDEX_OVERLAY;
import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_HOME;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_SWIPELEFT;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_SWIPERIGHT;
-import static com.android.launcher3.testing.TestProtocol.BAD_STATE;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
@@ -50,6 +50,8 @@ import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.Message;
import android.os.Parcelable;
+import android.os.UserHandle;
+import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.util.SparseArray;
@@ -61,8 +63,6 @@ import android.view.ViewTreeObserver;
import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.Toast;
-import androidx.annotation.Nullable;
-
import com.android.launcher3.accessibility.AccessibleDragListenerAdapter;
import com.android.launcher3.accessibility.WorkspaceAccessibilityHelper;
import com.android.launcher3.anim.Interpolators;
@@ -79,18 +79,19 @@ import com.android.launcher3.folder.Folder;
import com.android.launcher3.folder.FolderIcon;
import com.android.launcher3.folder.PreviewBackground;
import com.android.launcher3.graphics.DragPreviewProvider;
+import com.android.launcher3.graphics.PreloadIconDrawable;
import com.android.launcher3.icons.BitmapRenderer;
import com.android.launcher3.icons.FastBitmapDrawable;
import com.android.launcher3.logger.LauncherAtom;
-import com.android.launcher3.logging.InstanceId;
import com.android.launcher3.logging.StatsLogManager;
import com.android.launcher3.logging.StatsLogManager.LauncherEvent;
+import com.android.launcher3.model.data.AppInfo;
import com.android.launcher3.model.data.FolderInfo;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.LauncherAppWidgetInfo;
-import com.android.launcher3.model.data.WorkspaceItemFactory;
import com.android.launcher3.model.data.WorkspaceItemInfo;
-import com.android.launcher3.pageindicators.PageIndicator;
+import com.android.launcher3.pageindicators.WorkspacePageIndicator;
+import com.android.launcher3.popup.PopupContainerWithArrow;
import com.android.launcher3.statemanager.StateManager;
import com.android.launcher3.statemanager.StateManager.StateHandler;
import com.android.launcher3.states.StateAnimationConfig;
@@ -98,9 +99,8 @@ import com.android.launcher3.touch.WorkspaceTouchListener;
import com.android.launcher3.util.EdgeEffectCompat;
import com.android.launcher3.util.Executors;
import com.android.launcher3.util.IntArray;
-import com.android.launcher3.util.IntSet;
import com.android.launcher3.util.IntSparseArrayMap;
-import com.android.launcher3.util.LauncherBindableItemsContainer;
+import com.android.launcher3.util.ItemInfoMatcher;
import com.android.launcher3.util.OverlayEdgeEffect;
import com.android.launcher3.util.PackageUserKey;
import com.android.launcher3.util.RunnableList;
@@ -109,7 +109,6 @@ import com.android.launcher3.util.WallpaperOffsetInterpolator;
import com.android.launcher3.widget.LauncherAppWidgetHost;
import com.android.launcher3.widget.LauncherAppWidgetHost.ProviderChangedListener;
import com.android.launcher3.widget.LauncherAppWidgetHostView;
-import com.android.launcher3.widget.NavigableAppWidgetHostView;
import com.android.launcher3.widget.PendingAddShortcutInfo;
import com.android.launcher3.widget.PendingAddWidgetInfo;
import com.android.launcher3.widget.PendingAppWidgetHostView;
@@ -119,9 +118,9 @@ import com.android.launcher3.widget.util.WidgetSizes;
import com.android.systemui.plugins.shared.LauncherOverlayManager.LauncherOverlay;
import java.util.ArrayList;
-import java.util.Iterator;
+import java.util.Collections;
+import java.util.HashSet;
import java.util.List;
-import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.stream.Collectors;
@@ -129,12 +128,11 @@ import java.util.stream.Collectors;
* The workspace is a wide area with a wallpaper and a finite number of pages.
* Each page contains a number of icons, folders or widgets the user can
* interact with. A workspace is meant to be used with a fixed width only.
- * @param <T> Class that extends View and PageIndicator
*/
-public class Workspace<T extends View & PageIndicator> extends PagedView<T>
+public class Workspace extends PagedView<WorkspacePageIndicator>
implements DropTarget, DragSource, View.OnTouchListener,
DragController.DragListener, Insettable, StateHandler<LauncherState>,
- WorkspaceLayoutManager, LauncherBindableItemsContainer {
+ WorkspaceLayoutManager {
/** The value that {@link #mTransitionProgress} must be greater than for
* {@link #transitionStateShouldAllowDrop()} to return true. */
@@ -144,8 +142,6 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
* {@link #isFinishedSwitchingState()} ()} to return true. */
private static final float FINISHED_SWITCHING_STATE_TRANSITION_PROGRESS = 0.5f;
- private static final float SIGNIFICANT_MOVE_SCREEN_WIDTH_PERCENTAGE = 0.15f;
-
private static final boolean ENFORCE_DRAG_EVENT_ORDER = false;
private static final int ADJACENT_SCREEN_DROP_DURATION = 300;
@@ -197,8 +193,8 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
private final int[] mTempXY = new int[2];
private final float[] mTempFXY = new float[2];
- private final Rect mTempRect = new Rect();
@Thunk float[] mDragViewVisualCenter = new float[2];
+ private final float[] mTempTouchCoordinates = new float[2];
private SpringLoadedDragController mSpringLoadedDragController;
@@ -208,6 +204,8 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
private boolean mStripScreensOnPageStopMoving = false;
+ private DragPreviewProvider mOutlineProvider = null;
+
private boolean mWorkspaceFadeInAdjacentScreens;
final WallpaperOffsetInterpolator mWallpaperOffset;
@@ -219,13 +217,11 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
private FolderIcon mDragOverFolderIcon = null;
private boolean mCreateUserFolderOnDrop = false;
private boolean mAddToExistingFolderOnDrop = false;
+ private float mMaxDistanceForFolderCreation;
// Variables relating to touch disambiguation (scrolling workspace vs. scrolling a widget)
private float mXDown;
private float mYDown;
- private View mQsb;
- private boolean mIsEventOverQsb;
-
final static float START_DAMPING_TOUCH_SLOP_ANGLE = (float) Math.PI / 6;
final static float MAX_SWIPE_ANGLE = (float) Math.PI / 3;
final static float TOUCH_SLOP_DAMPING_FACTOR = 4;
@@ -306,13 +302,19 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
public void setInsets(Rect insets) {
DeviceProfile grid = mLauncher.getDeviceProfile();
+ mMaxDistanceForFolderCreation = grid.isTablet
+ ? 0.75f * grid.iconSizePx : 0.55f * grid.iconSizePx;
mWorkspaceFadeInAdjacentScreens = grid.shouldFadeAdjacentWorkspaceScreens();
Rect padding = grid.workspacePadding;
setPadding(padding.left, padding.top, padding.right, padding.bottom);
mInsets.set(insets);
+ // Increase our bottom insets so we don't overlap with the taskbar.
+ mInsets.bottom += grid.nonOverlappingTaskbarInset;
- if (mWorkspaceFadeInAdjacentScreens) {
+ if (isTwoPanelEnabled()) {
+ setPageSpacing(0); // we have two pages and we don't want any spacing
+ } else if (mWorkspaceFadeInAdjacentScreens) {
// In landscape mode the page spacing is set to the default.
setPageSpacing(grid.edgeMarginPx);
} else {
@@ -324,32 +326,30 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
setPageSpacing(Math.max(maxInsets, maxPadding));
}
- updateCellLayoutPadding();
- updateWorkspaceWidgetsSizes();
- }
+ int paddingLeftRight = grid.cellLayoutPaddingLeftRightPx;
+ int paddingBottom = grid.cellLayoutBottomPaddingPx;
+ int twoPanelLandscapeSidePadding = paddingLeftRight * 2;
+ int twoPanelPortraitSidePadding = paddingLeftRight / 2;
- private void updateCellLayoutPadding() {
- Rect padding = mLauncher.getDeviceProfile().cellLayoutPaddingPx;
- mWorkspaceScreens.forEach(
- s -> s.setPadding(padding.left, padding.top, padding.right, padding.bottom));
- }
-
- private void updateWorkspaceWidgetsSizes() {
- int numberOfScreens = mScreenOrder.size();
- for (int i = 0; i < numberOfScreens; i++) {
- ShortcutAndWidgetContainer shortcutAndWidgetContainer =
- mWorkspaceScreens.get(mScreenOrder.get(i)).getShortcutsAndWidgets();
- int shortcutsAndWidgetCount = shortcutAndWidgetContainer.getChildCount();
- for (int j = 0; j < shortcutsAndWidgetCount; j++) {
- View view = shortcutAndWidgetContainer.getChildAt(j);
- if (view instanceof LauncherAppWidgetHostView
- && view.getTag() instanceof LauncherAppWidgetInfo) {
- LauncherAppWidgetInfo launcherAppWidgetInfo =
- (LauncherAppWidgetInfo) view.getTag();
- WidgetSizes.updateWidgetSizeRanges((LauncherAppWidgetHostView) view,
- mLauncher, launcherAppWidgetInfo.spanX, launcherAppWidgetInfo.spanY);
+ int panelCount = getPanelCount();
+ for (int i = mWorkspaceScreens.size() - 1; i >= 0; i--) {
+ int paddingLeft = paddingLeftRight;
+ int paddingRight = paddingLeftRight;
+ if (panelCount > 1) {
+ if (i % panelCount == 0) { // left side panel
+ paddingLeft = grid.isLandscape ? twoPanelLandscapeSidePadding
+ : twoPanelPortraitSidePadding;
+ paddingRight = 0;
+ } else if (i % panelCount == panelCount - 1) { // right side panel
+ paddingLeft = 0;
+ paddingRight = grid.isLandscape ? twoPanelLandscapeSidePadding
+ : twoPanelPortraitSidePadding;
+ } else { // middle panel
+ paddingLeft = 0;
+ paddingRight = 0;
}
}
+ mWorkspaceScreens.valueAt(i).setPadding(paddingLeft, 0, paddingRight, paddingBottom);
}
}
@@ -462,7 +462,7 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
}
@Override
- public int getPanelCount() {
+ protected int getPanelCount() {
return isTwoPanelEnabled() ? 2 : super.getPanelCount();
}
@@ -491,6 +491,7 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
});
mDragInfo = null;
+ mOutlineProvider = null;
mDragSourceInternal = null;
}
@@ -545,30 +546,29 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
/**
* Initializes and binds the first page
+ * @param qsb an existing qsb to recycle or null.
*/
- public void bindAndInitFirstWorkspaceScreen() {
+ public void bindAndInitFirstWorkspaceScreen(View qsb) {
if (!FeatureFlags.QSB_ON_FIRST_SCREEN) {
return;
}
-
// Add the first page
- CellLayout firstPage = insertNewWorkspaceScreen(Workspace.FIRST_SCREEN_ID, getChildCount());
+ CellLayout firstPage = insertNewWorkspaceScreen(Workspace.FIRST_SCREEN_ID, 0);
// Always add a QSB on the first screen.
- if (mQsb == null) {
+ if (qsb == null) {
// In transposed layout, we add the QSB in the Grid. As workspace does not touch the
// edges, we do not need a full width QSB.
- mQsb = LayoutInflater.from(getContext())
+ qsb = LayoutInflater.from(getContext())
.inflate(R.layout.search_container_workspace, firstPage, false);
}
int cellVSpan = FeatureFlags.EXPANDED_SMARTSPACE.get()
? EXPANDED_SMARTSPACE_HEIGHT : DEFAULT_SMARTSPACE_HEIGHT;
- int cellHSpan = mLauncher.getDeviceProfile().inv.numSearchContainerColumns;
- CellLayout.LayoutParams lp = new CellLayout.LayoutParams(0, 0, cellHSpan, cellVSpan);
+ CellLayout.LayoutParams lp = new CellLayout.LayoutParams(0, 0, firstPage.getCountX(),
+ cellVSpan);
lp.canReorder = false;
- if (!firstPage.addViewToCellLayout(mQsb, 0, R.id.search_container_workspace, lp, true)) {
+ if (!firstPage.addViewToCellLayout(qsb, 0, R.id.search_container_workspace, lp, true)) {
Log.e(TAG, "Failed to add to item at (0, 0) to CellLayout");
- mQsb = null;
}
}
@@ -578,8 +578,9 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
disableLayoutTransitions();
// Recycle the QSB widget
- if (mQsb != null) {
- ((ViewGroup) mQsb.getParent()).removeView(mQsb);
+ View qsb = findViewById(R.id.search_container_workspace);
+ if (qsb != null) {
+ ((ViewGroup) qsb.getParent()).removeView(qsb);
}
// Remove the pages and clear the screen models
@@ -592,7 +593,7 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
mLauncher.mHandler.removeCallbacksAndMessages(DeferredWidgetRefresh.class);
// Ensure that the first page is always present
- bindAndInitFirstWorkspaceScreen();
+ bindAndInitFirstWorkspaceScreen(qsb);
// Re-enable the layout transitions
enableLayoutTransitions();
@@ -621,6 +622,10 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
// created CellLayout.
CellLayout newScreen = (CellLayout) LayoutInflater.from(getContext()).inflate(
R.layout.workspace_screen, this, false /* attachToRoot */);
+ DeviceProfile grid = mLauncher.getDeviceProfile();
+ int paddingLeftRight = grid.cellLayoutPaddingLeftRightPx;
+ int paddingBottom = grid.cellLayoutBottomPaddingPx;
+ newScreen.setPadding(paddingLeftRight, 0, paddingLeftRight, paddingBottom);
mWorkspaceScreens.put(screenId, newScreen);
mScreenOrder.add(insertIndex, screenId);
@@ -629,7 +634,6 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
mLauncher.getStateManager().getState(), newScreen, insertIndex);
updatePageScrollValues();
- updateCellLayoutPadding();
return newScreen;
}
@@ -638,28 +642,18 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
boolean childOnFinalScreen = false;
if (mDragSourceInternal != null) {
- int dragSourceChildCount = mDragSourceInternal.getChildCount();
-
- // If the icon was dragged from Hotseat, there is no page pair
- if (isTwoPanelEnabled() && !(mDragSourceInternal.getParent() instanceof Hotseat)) {
- int pagePairScreenId = getScreenPair(dragObject.dragInfo.screenId);
- CellLayout pagePair = mWorkspaceScreens.get(pagePairScreenId);
- dragSourceChildCount += pagePair.getShortcutsAndWidgets().getChildCount();
- }
-
// When the drag view content is a LauncherAppWidgetHostView, we should increment the
// drag source child count by 1 because the widget in drag has been detached from its
// original parent, ShortcutAndWidgetContainer, and reattached to the DragView.
- if (dragObject.dragView.getContentView() instanceof LauncherAppWidgetHostView) {
- dragSourceChildCount++;
- }
-
+ int dragSourceChildCount =
+ dragObject.dragView.getContentView() instanceof LauncherAppWidgetHostView
+ ? mDragSourceInternal.getChildCount() + 1
+ : mDragSourceInternal.getChildCount();
if (dragSourceChildCount == 1) {
lastChildOnScreen = true;
}
CellLayout cl = (CellLayout) mDragSourceInternal.getParent();
- if (getLeftmostVisiblePageForIndex(indexOfChild(cl))
- == getLeftmostVisiblePageForIndex(getPageCount() - 1)) {
+ if (indexOfChild(cl) == getChildCount() - 1) {
childOnFinalScreen = true;
}
}
@@ -668,83 +662,39 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
if (lastChildOnScreen && childOnFinalScreen) {
return;
}
-
- forEachExtraEmptyPageId(extraEmptyPageId -> {
- if (!mWorkspaceScreens.containsKey(extraEmptyPageId)) {
- insertNewWorkspaceScreen(extraEmptyPageId);
- }
- });
- }
-
- /**
- * Inserts extra empty pages to the end of the existing workspaces.
- * Usually we add one extra empty screen, but when two panel home is enabled we add
- * two extra screens.
- **/
- public void addExtraEmptyScreens() {
- forEachExtraEmptyPageId(extraEmptyPageId -> {
- if (!mWorkspaceScreens.containsKey(extraEmptyPageId)) {
- insertNewWorkspaceScreen(extraEmptyPageId);
- }
- });
+ if (!mWorkspaceScreens.containsKey(EXTRA_EMPTY_SCREEN_ID)) {
+ insertNewWorkspaceScreen(EXTRA_EMPTY_SCREEN_ID);
+ }
}
- /**
- * Calls the consumer with all the necessary extra empty page IDs.
- * On a normal one panel Workspace that means only EXTRA_EMPTY_SCREEN_ID,
- * but in a two panel scenario this also includes EXTRA_EMPTY_SCREEN_SECOND_ID.
- */
- private void forEachExtraEmptyPageId(Consumer<Integer> callback) {
- callback.accept(EXTRA_EMPTY_SCREEN_ID);
- if (isTwoPanelEnabled()) {
- callback.accept(EXTRA_EMPTY_SCREEN_SECOND_ID);
+ public boolean addExtraEmptyScreen() {
+ if (!mWorkspaceScreens.containsKey(EXTRA_EMPTY_SCREEN_ID)) {
+ insertNewWorkspaceScreen(EXTRA_EMPTY_SCREEN_ID);
+ return true;
}
+ return false;
}
- /**
- * If two panel home is enabled we convert the last two screens that are visible at the same
- * time. In other cases we only convert the last page.
- */
private void convertFinalScreenToEmptyScreenIfNecessary() {
if (mLauncher.isWorkspaceLoading()) {
// Invalid and dangerous operation if workspace is loading
return;
}
- int panelCount = getPanelCount();
- if (hasExtraEmptyScreens() || mScreenOrder.size() < panelCount) {
- return;
- }
-
- SparseArray<CellLayout> finalScreens = new SparseArray<>();
+ if (hasExtraEmptyScreen() || mScreenOrder.size() == 0) return;
+ int finalScreenId = mScreenOrder.get(mScreenOrder.size() - 1);
- int pageCount = mScreenOrder.size();
- // First we add the last page(s) to the finalScreens collection. The number of final pages
- // depends on the panel count.
- for (int pageIndex = pageCount - panelCount; pageIndex < pageCount; pageIndex++) {
- int screenId = mScreenOrder.get(pageIndex);
- CellLayout screen = mWorkspaceScreens.get(screenId);
- if (screen == null || screen.getShortcutsAndWidgets().getChildCount() != 0
- || screen.isDropPending()) {
- // Final screen doesn't exist or it isn't empty or there's a pending drop
- return;
- }
- finalScreens.append(screenId, screen);
- }
+ CellLayout finalScreen = mWorkspaceScreens.get(finalScreenId);
- // Then we remove the final screens from the collections (but not from the view hierarchy)
- // and we store them as extra empty screens.
- for (int i = 0; i < finalScreens.size(); i++) {
- int screenId = finalScreens.keyAt(i);
- CellLayout screen = finalScreens.get(screenId);
+ // If the final screen is empty, convert it to the extra empty screen
+ if (finalScreen.getShortcutsAndWidgets().getChildCount() == 0 &&
+ !finalScreen.isDropPending()) {
+ mWorkspaceScreens.remove(finalScreenId);
+ mScreenOrder.removeValue(finalScreenId);
- mWorkspaceScreens.remove(screenId);
- mScreenOrder.removeValue(screenId);
-
- int newScreenId = mWorkspaceScreens.containsKey(EXTRA_EMPTY_SCREEN_ID)
- ? EXTRA_EMPTY_SCREEN_SECOND_ID : EXTRA_EMPTY_SCREEN_ID;
- mWorkspaceScreens.put(newScreenId, screen);
- mScreenOrder.add(newScreenId);
+ // if this is the last screen, convert it to the empty screen
+ mWorkspaceScreens.put(EXTRA_EMPTY_SCREEN_ID, finalScreen);
+ mScreenOrder.add(EXTRA_EMPTY_SCREEN_ID);
}
}
@@ -752,23 +702,6 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
removeExtraEmptyScreenDelayed(0, stripEmptyScreens, null);
}
- /**
- * The purpose of this method is to remove empty pages from Workspace.
- * Empty page(s) from the end of mWorkspaceScreens will always be removed. The pages with
- * ID = Workspace.EXTRA_EMPTY_SCREEN_IDS will be removed if there are other non-empty pages.
- * If there are no more non-empty pages left, extra empty page(s) will either stay or get added.
- *
- * If stripEmptyScreens is true, all empty pages (not just the ones on the end) will be removed
- * from the Workspace, and if there are no more pages left then extra empty page(s) will be
- * added.
- *
- * The number of extra empty pages is equal to what getPanelCount() returns.
- *
- * After the method returns the possible pages are:
- * stripEmptyScreens = true : [non-empty pages, extra empty page(s) alone]
- * stripEmptyScreens = false : [non-empty pages, empty pages (not in the end),
- * extra empty page(s) alone]
- */
public void removeExtraEmptyScreenDelayed(
int delay, boolean stripEmptyScreens, Runnable onComplete) {
if (mLauncher.isWorkspaceLoading()) {
@@ -782,26 +715,18 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
return;
}
- // First we convert the last page to an extra page if the last page is empty
- // and we don't already have an extra page.
convertFinalScreenToEmptyScreenIfNecessary();
- // Then we remove the extra page(s) if they are not the only pages left in Workspace.
- if (hasExtraEmptyScreens()) {
- forEachExtraEmptyPageId(extraEmptyPageId -> {
- removeView(mWorkspaceScreens.get(extraEmptyPageId));
- mWorkspaceScreens.remove(extraEmptyPageId);
- mScreenOrder.removeValue(extraEmptyPageId);
- });
-
+ if (hasExtraEmptyScreen()) {
+ removeView(mWorkspaceScreens.get(EXTRA_EMPTY_SCREEN_ID));
setCurrentPage(getNextPage());
+ mWorkspaceScreens.remove(EXTRA_EMPTY_SCREEN_ID);
+ mScreenOrder.removeValue(EXTRA_EMPTY_SCREEN_ID);
// Update the page indicator to reflect the removed page.
showPageIndicatorAtCurrentScroll();
}
if (stripEmptyScreens) {
- // This will remove all empty pages from the Workspace. If there are no more pages left,
- // it will add extra page(s) so that users can put items on at least one page.
stripEmptyScreens();
}
@@ -810,51 +735,27 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
}
}
- public boolean hasExtraEmptyScreens() {
- return mWorkspaceScreens.containsKey(EXTRA_EMPTY_SCREEN_ID)
- && getChildCount() > getPanelCount()
- && (!isTwoPanelEnabled()
- || mWorkspaceScreens.containsKey(EXTRA_EMPTY_SCREEN_SECOND_ID));
+ public boolean hasExtraEmptyScreen() {
+ return mWorkspaceScreens.containsKey(EXTRA_EMPTY_SCREEN_ID) && getChildCount() > 1;
}
- /**
- * Commits the extra empty pages then returns the screen ids of those new screens.
- * Usually there's only one extra empty screen, but when two panel home is enabled we commit
- * two extra screens.
- *
- * Returns an empty IntSet in case we cannot commit any new screens.
- */
- public IntSet commitExtraEmptyScreens() {
+ public int commitExtraEmptyScreen() {
if (mLauncher.isWorkspaceLoading()) {
// Invalid and dangerous operation if workspace is loading
- return new IntSet();
+ return -1;
}
- IntSet extraEmptyPageIds = new IntSet();
- forEachExtraEmptyPageId(extraEmptyPageId ->
- extraEmptyPageIds.add(commitExtraEmptyScreen(extraEmptyPageId)));
+ CellLayout cl = mWorkspaceScreens.get(EXTRA_EMPTY_SCREEN_ID);
+ mWorkspaceScreens.remove(EXTRA_EMPTY_SCREEN_ID);
+ mScreenOrder.removeValue(EXTRA_EMPTY_SCREEN_ID);
- return extraEmptyPageIds;
- }
-
- private int commitExtraEmptyScreen(int emptyScreenId) {
- CellLayout cl = mWorkspaceScreens.get(emptyScreenId);
- mWorkspaceScreens.remove(emptyScreenId);
- mScreenOrder.removeValue(emptyScreenId);
-
- int newScreenId = LauncherSettings.Settings.call(getContext().getContentResolver(),
+ int newId = LauncherSettings.Settings.call(getContext().getContentResolver(),
LauncherSettings.Settings.METHOD_NEW_SCREEN_ID)
.getInt(LauncherSettings.Settings.EXTRA_VALUE);
- // Launcher database isn't aware of empty pages that are already bound, so we need to
- // skip those IDs manually.
- while (mWorkspaceScreens.containsKey(newScreenId)) {
- newScreenId++;
- }
-
- mWorkspaceScreens.put(newScreenId, cl);
- mScreenOrder.add(newScreenId);
+ mWorkspaceScreens.put(newId, cl);
+ mScreenOrder.add(newId);
- return newScreenId;
+ return newId;
}
@Override
@@ -884,10 +785,6 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
return indexOfChild(mWorkspaceScreens.get(screenId));
}
- public IntSet getCurrentPageScreenIds() {
- return IntSet.wrap(getScreenIdForPageIndex(getCurrentPage()));
- }
-
public int getScreenIdForPageIndex(int index) {
if (0 <= index && index < mScreenOrder.size()) {
return mScreenOrder.get(index);
@@ -899,38 +796,6 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
return mScreenOrder;
}
- /**
- * Returns the screen ID of a page that is shown together with the given page screen ID when the
- * two panel UI is enabled.
- */
- public int getScreenPair(int screenId) {
- if (screenId == EXTRA_EMPTY_SCREEN_ID) {
- return EXTRA_EMPTY_SCREEN_SECOND_ID;
- } else if (screenId == EXTRA_EMPTY_SCREEN_SECOND_ID) {
- return EXTRA_EMPTY_SCREEN_ID;
- } else if (screenId % 2 == 0) {
- return screenId + 1;
- } else {
- return screenId - 1;
- }
- }
-
- /**
- * Returns {@link CellLayout} that is shown together with the given {@link CellLayout} when the
- * two panel UI is enabled.
- */
- @Nullable
- public CellLayout getScreenPair(CellLayout cellLayout) {
- if (!isTwoPanelEnabled()) {
- return null;
- }
- int screenId = getIdForScreen(cellLayout);
- if (screenId == -1) {
- return null;
- }
- return getScreenWithId(getScreenPair(screenId));
- }
-
public void stripEmptyScreens() {
if (mLauncher.isWorkspaceLoading()) {
// Don't strip empty screens if the workspace is still loading.
@@ -956,26 +821,9 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
}
}
- // When two panel home is enabled we only remove an empty page if both visible pages are
- // empty.
- if (isTwoPanelEnabled()) {
- // We go through all the pages that were marked as removable and check their page pair
- Iterator<Integer> removeScreensIterator = removeScreens.iterator();
- while (removeScreensIterator.hasNext()) {
- int pageToRemove = removeScreensIterator.next();
- int pagePair = getScreenPair(pageToRemove);
- if (!removeScreens.contains(pagePair)) {
- // The page pair isn't empty so we want to remove the current page from the
- // removable pages' collection
- removeScreensIterator.remove();
- }
- }
- }
-
- // We enforce at least one page (two pages on two panel home) to add new items to.
- // In the case that we remove the last such screen(s), we convert the last screen(s)
- // to the empty screen(s)
- int minScreens = getPanelCount();
+ // We enforce at least one page to add new items to. In the case that we remove the last
+ // such screen, we convert the last screen to the empty screen
+ int minScreens = 1;
int pageShift = 0;
for (int i = 0; i < removeScreens.size(); i++) {
@@ -985,21 +833,14 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
mScreenOrder.removeValue(id);
if (getChildCount() > minScreens) {
- // If this isn't the last page, just remove it
if (indexOfChild(cl) < currentPage) {
pageShift++;
}
removeView(cl);
} else {
- // The last page(s) should be converted into extra empty page(s)
- int extraScreenId = isTwoPanelEnabled() && id % 2 == 1
- // This is the right panel in a two panel scenario
- ? EXTRA_EMPTY_SCREEN_SECOND_ID
- // This is either the last screen in a one panel scenario, or the left panel
- // in a two panel scenario when there are only two empty pages left
- : EXTRA_EMPTY_SCREEN_ID;
- mWorkspaceScreens.put(extraScreenId, cl);
- mScreenOrder.add(extraScreenId);
+ // if this is the last screen, convert it to the empty screen
+ mWorkspaceScreens.put(EXTRA_EMPTY_SCREEN_ID, cl);
+ mScreenOrder.add(EXTRA_EMPTY_SCREEN_ID);
}
}
@@ -1045,25 +886,17 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
}
@Override
- protected void updateIsBeingDraggedOnTouchDown(MotionEvent ev) {
- super.updateIsBeingDraggedOnTouchDown(ev);
-
- mXDown = ev.getX();
- mYDown = ev.getY();
- if (mQsb != null) {
- mTempFXY[0] = mXDown + getScrollX();
- mTempFXY[1] = mYDown + getScrollY();
- Utilities.mapCoordInSelfToDescendant(mQsb, this, mTempFXY);
- mIsEventOverQsb = mQsb.getLeft() <= mTempFXY[0] && mQsb.getRight() >= mTempFXY[0]
- && mQsb.getTop() <= mTempFXY[1] && mQsb.getBottom() >= mTempFXY[1];
- } else {
- mIsEventOverQsb = false;
+ public boolean onInterceptTouchEvent(MotionEvent ev) {
+ if (ev.getActionMasked() == MotionEvent.ACTION_DOWN) {
+ mXDown = ev.getX();
+ mYDown = ev.getY();
}
+ return super.onInterceptTouchEvent(ev);
}
@Override
protected void determineScrollingStart(MotionEvent ev) {
- if (!isFinishedSwitchingState() || mIsEventOverQsb) return;
+ if (!isFinishedSwitchingState()) return;
float deltaX = ev.getX() - mXDown;
float absDeltaX = Math.abs(deltaX);
@@ -1117,10 +950,6 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
stripEmptyScreens();
mStripScreensOnPageStopMoving = false;
}
-
- // Inform the Launcher activity that the page transition ended so that it can react to the
- // newly visible page if it wants to.
- mLauncher.onPageEndTransition();
}
public void setLauncherOverlay(LauncherOverlay overlay) {
@@ -1197,10 +1026,6 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
.log(LAUNCHER_SWIPELEFT);
}
mOverlayShown = true;
-
- // Let the Launcher activity know that the overlay is now visible.
- mLauncher.onOverlayVisibilityChanged(mOverlayShown);
-
// Not announcing the overlay page for accessibility since it announces itself.
} else if (Float.compare(scroll, 0f) == 0) {
if (mOverlayShown) {
@@ -1224,10 +1049,6 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
announcePageForAccessibility();
}
mOverlayShown = false;
-
- // Let the Launcher activity know that the overlay is no longer visible.
- mLauncher.onOverlayVisibilityChanged(mOverlayShown);
-
tryRunOverlayCallback();
}
@@ -1248,7 +1069,6 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
// different effects based on device performance. On at least one relatively high-end
// device I've tried, translating the launcher causes things to get quite laggy.
mLauncher.getDragLayer().setTranslationX(transX);
- Log.d(BAD_STATE, "Workspace onOverlayScrollChanged DragLayer ALPHA_INDEX_OVERLAY=" + alpha);
mLauncher.getDragLayer().getAlphaProperty(ALPHA_INDEX_OVERLAY).setValue(alpha);
}
@@ -1502,7 +1322,11 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
position[0], position[1], 0, null);
}
- private void onStartStateTransition() {
+ public void prepareDragWithProvider(DragPreviewProvider outlineProvider) {
+ mOutlineProvider = outlineProvider;
+ }
+
+ private void onStartStateTransition(LauncherState state) {
mIsSwitchingState = true;
mTransitionProgress = 0;
@@ -1523,7 +1347,7 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
*/
@Override
public void setState(LauncherState toState) {
- onStartStateTransition();
+ onStartStateTransition(toState);
mStateTransitionAnimation.setState(toState);
onEndStateTransition();
}
@@ -1534,7 +1358,7 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
@Override
public void setStateWithAnimation(
LauncherState toState, StateAnimationConfig config, PendingAnimation animation) {
- StateTransitionListener listener = new StateTransitionListener();
+ StateTransitionListener listener = new StateTransitionListener(toState);
mStateTransitionAnimation.setStateWithAnimation(toState, config, animation);
// Invalidate the pages now, so that we have the visible pages before the
@@ -1643,6 +1467,8 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
icon.clearPressedBackground();
}
+ mOutlineProvider = previewProvider;
+
if (draggableView == null && child instanceof DraggableView) {
draggableView = (DraggableView) child;
}
@@ -1678,7 +1504,11 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
}
if (child instanceof BubbleTextView && !dragOptions.isAccessibleDrag) {
- dragOptions.preDragCondition = ((BubbleTextView) child).startLongPressAction();
+ PopupContainerWithArrow popupContainer = PopupContainerWithArrow
+ .showForIcon((BubbleTextView) child);
+ if (popupContainer != null) {
+ dragOptions.preDragCondition = popupContainer.createPreDragCondition();
+ }
}
final DragView dv;
@@ -1728,7 +1558,7 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
// If it's an external drop (e.g. from All Apps), check if it should be accepted
CellLayout dropTargetLayout = mDropToLayout;
if (d.dragSource != this) {
- // Don't accept the drop if we're not over a valid drop target at time of drop
+ // Don't accept the drop if we're not over a screen at time of drop
if (dropTargetLayout == null) {
return false;
}
@@ -1760,8 +1590,8 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
mTargetCell = findNearestArea((int) mDragViewVisualCenter[0],
(int) mDragViewVisualCenter[1], minSpanX, minSpanY, dropTargetLayout,
mTargetCell);
- float distance = dropTargetLayout.getDistanceFromWorkspaceCellVisualCenter(
- mDragViewVisualCenter[0], mDragViewVisualCenter[1], mTargetCell);
+ float distance = dropTargetLayout.getDistanceFromCell(mDragViewVisualCenter[0],
+ mDragViewVisualCenter[1], mTargetCell);
if (mCreateUserFolderOnDrop && willCreateUserFolder(d.dragInfo,
dropTargetLayout, mTargetCell, distance, true)) {
return true;
@@ -1780,14 +1610,14 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
// Don't accept the drop if there's no room for the item
if (!foundCell) {
- onNoCellFound(dropTargetLayout, d.dragInfo, d.logInstanceId);
+ onNoCellFound(dropTargetLayout);
return false;
}
}
int screenId = getIdForScreen(dropTargetLayout);
- if (Workspace.EXTRA_EMPTY_SCREEN_IDS.contains(screenId)) {
- commitExtraEmptyScreens();
+ if (screenId == EXTRA_EMPTY_SCREEN_ID) {
+ commitExtraEmptyScreen();
}
return true;
@@ -1795,7 +1625,7 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
boolean willCreateUserFolder(ItemInfo info, CellLayout target, int[] targetCell,
float distance, boolean considerTimeout) {
- if (distance > target.getFolderCreationRadius(targetCell)) return false;
+ if (distance > mMaxDistanceForFolderCreation) return false;
View dropOverView = target.getChildAt(targetCell[0], targetCell[1]);
return willCreateUserFolder(info, dropOverView, considerTimeout);
}
@@ -1830,7 +1660,7 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
boolean willAddToExistingUserFolder(ItemInfo dragInfo, CellLayout target, int[] targetCell,
float distance) {
- if (distance > target.getFolderCreationRadius(targetCell)) return false;
+ if (distance > mMaxDistanceForFolderCreation) return false;
View dropOverView = target.getChildAt(targetCell[0], targetCell[1]);
return willAddToExistingUserFolder(dragInfo, dropOverView);
@@ -1854,7 +1684,7 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
boolean createUserFolderIfNecessary(View newView, int container, CellLayout target,
int[] targetCell, float distance, boolean external, DragObject d) {
- if (distance > target.getFolderCreationRadius(targetCell)) return false;
+ if (distance > mMaxDistanceForFolderCreation) return false;
View v = target.getChildAt(targetCell[0], targetCell[1]);
boolean hasntMoved = false;
@@ -1911,7 +1741,7 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
boolean addToExistingFolderIfNecessary(View newView, CellLayout target, int[] targetCell,
float distance, DragObject d, boolean external) {
- if (distance > target.getFolderCreationRadius(targetCell)) return false;
+ if (distance > mMaxDistanceForFolderCreation) return false;
View dropOverView = target.getChildAt(targetCell[0], targetCell[1]);
if (!mAddToExistingFolderOnDrop) return false;
@@ -1948,16 +1778,19 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
boolean droppedOnOriginalCell = false;
- boolean snappedToNewPage = false;
+ int snapScreen = -1;
boolean resizeOnDrop = false;
- Runnable onCompleteRunnable = null;
if (d.dragSource != this || mDragInfo == null) {
final int[] touchXY = new int[] { (int) mDragViewVisualCenter[0],
(int) mDragViewVisualCenter[1] };
onDropExternal(touchXY, dropTargetLayout, d);
} else {
final View cell = mDragInfo.cell;
+ final DragView dragView = d.dragView;
boolean droppedOnOriginalCellDuringTransition = false;
+ Runnable onCompleteRunnable = dragView::resumeColorExtraction;
+
+ dragView.disableColorExtraction();
if (dropTargetLayout != null && !d.cancelled) {
// Move internally
@@ -1975,8 +1808,8 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
mTargetCell = findNearestArea((int) mDragViewVisualCenter[0], (int)
mDragViewVisualCenter[1], spanX, spanY, dropTargetLayout, mTargetCell);
- float distance = dropTargetLayout.getDistanceFromWorkspaceCellVisualCenter(
- mDragViewVisualCenter[0], mDragViewVisualCenter[1], mTargetCell);
+ float distance = dropTargetLayout.getDistanceFromCell(mDragViewVisualCenter[0],
+ mDragViewVisualCenter[1], mTargetCell);
// If the item being dropped is a shortcut and the nearest drop
// cell also contains a shortcut, then create a folder with the two shortcuts.
@@ -2030,14 +1863,11 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
}
if (foundCell) {
- int targetScreenIndex = getPageIndexForScreenId(screenId);
- int snapScreen = getLeftmostVisiblePageForIndex(targetScreenIndex);
- // On large screen devices two pages can be shown at the same time, and snap
- // isn't needed if the source and target screens appear at the same time
- if (snapScreen != mCurrentPage && !hasMovedIntoHotseat) {
+ if (getScreenIdForPageIndex(mCurrentPage) != screenId && !hasMovedIntoHotseat) {
+ snapScreen = getPageIndexForScreenId(screenId);
snapToPage(snapScreen);
- snappedToNewPage = true;
}
+
final ItemInfo info = (ItemInfo) cell.getTag();
if (hasMovedLayouts) {
// Reparent the view
@@ -2071,7 +1901,9 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
AppWidgetProviderInfo pInfo = hostView.getAppWidgetInfo();
if (pInfo != null && pInfo.resizeMode != AppWidgetProviderInfo.RESIZE_NONE
&& !options.isAccessibleDrag) {
+ final Runnable previousRunnable = onCompleteRunnable;
onCompleteRunnable = () -> {
+ previousRunnable.run();
if (!isPageInTransition()) {
AppWidgetResizeFrame.showForWidget(hostView, cellLayout);
}
@@ -2082,7 +1914,7 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
lp.cellX, lp.cellY, item.spanX, item.spanY);
} else {
if (!returnToOriginalCellToPreventShuffling) {
- onNoCellFound(dropTargetLayout, d.dragInfo, d.logInstanceId);
+ onNoCellFound(dropTargetLayout);
}
if (mDragInfo.cell instanceof LauncherAppWidgetHostView) {
d.dragView.detachContentView(/* reattachToPreviousParent= */ true);
@@ -2111,7 +1943,7 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
final Runnable onCompleteCallback = onCompleteRunnable;
mLauncher.getDragController().animateDragViewToOriginalPosition(
/* onComplete= */ callbackList::executeAllAndDestroy, cell,
- SPRING_LOADED.getTransitionDuration(mLauncher, true /* isToState */));
+ SPRING_LOADED.getTransitionDuration(mLauncher));
mLauncher.getStateManager().goToState(NORMAL, /* delay= */ 0,
onCompleteCallback == null
? null
@@ -2129,7 +1961,7 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
ANIMATE_INTO_POSITION_AND_DISAPPEAR;
animateWidgetDrop(info, parent, d.dragView, null, animationType, cell, false);
} else {
- int duration = snappedToNewPage ? ADJACENT_SCREEN_DROP_DURATION : -1;
+ int duration = snapScreen < 0 ? -1 : ADJACENT_SCREEN_DROP_DURATION;
mLauncher.getDragLayer().animateViewIntoPosition(d.dragView, cell, duration,
this);
}
@@ -2140,7 +1972,7 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
parent.onDropChild(cell);
mLauncher.getStateManager().goToState(NORMAL, SPRING_LOADED_EXIT_DELAY,
- onCompleteRunnable == null ? null : forSuccessCallback(onCompleteRunnable));
+ forSuccessCallback(onCompleteRunnable));
mStatsLogManager.logger().withItemInfo(d.dragInfo).withInstanceId(d.logInstanceId)
.log(LauncherEvent.LAUNCHER_ITEM_DROP_COMPLETED);
}
@@ -2150,16 +1982,10 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
}
}
- public void onNoCellFound(
- View dropTargetLayout, ItemInfo itemInfo, @Nullable InstanceId logInstanceId) {
+ public void onNoCellFound(View dropTargetLayout) {
int strId = mLauncher.isHotseatLayout(dropTargetLayout)
? R.string.hotseat_out_of_space : R.string.out_of_space;
Toast.makeText(mLauncher, mLauncher.getString(strId), Toast.LENGTH_SHORT).show();
- StatsLogManager.StatsLogger logger = mStatsLogManager.logger().withItemInfo(itemInfo);
- if (logInstanceId != null) {
- logger = logger.withInstanceId(logInstanceId);
- }
- logger.log(LauncherEvent.LAUNCHER_ITEM_DROP_FAILED_INSUFFICIENT_SPACE);
}
/**
@@ -2329,6 +2155,17 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
xy[1] = xy[1] - v.getTop();
}
+ boolean isPointInSelfOverHotseat(int x, int y) {
+ mTempFXY[0] = x;
+ mTempFXY[1] = y;
+ mLauncher.getDragLayer().getDescendantCoordRelativeToSelf(this, mTempFXY, true);
+ View hotseat = mLauncher.getHotseat();
+ return mTempFXY[0] >= hotseat.getLeft()
+ && mTempFXY[0] <= hotseat.getRight()
+ && mTempFXY[1] >= hotseat.getTop()
+ && mTempFXY[1] <= hotseat.getBottom();
+ }
+
/**
* Updates the point in {@param xy} to point to the co-ordinate space of {@param layout}
* @param layout either hotseat of a page in workspace
@@ -2366,7 +2203,7 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
final View child = (mDragInfo == null) ? null : mDragInfo.cell;
if (setDropLayoutForDragObject(d, mDragViewVisualCenter[0], mDragViewVisualCenter[1])) {
- if (mDragTargetLayout == null || mLauncher.isHotseatLayout(mDragTargetLayout)) {
+ if (mLauncher.isHotseatLayout(mDragTargetLayout)) {
mSpringLoadedDragController.cancel();
} else {
mSpringLoadedDragController.setAlarm(mDragTargetLayout);
@@ -2393,7 +2230,7 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
setCurrentDropOverCell(mTargetCell[0], mTargetCell[1]);
- float targetCellDistance = mDragTargetLayout.getDistanceFromWorkspaceCellVisualCenter(
+ float targetCellDistance = mDragTargetLayout.getDistanceFromCell(
mDragViewVisualCenter[0], mDragViewVisualCenter[1], mTargetCell);
manageFolderFeedback(targetCellDistance, d);
@@ -2406,9 +2243,8 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
mDragTargetLayout.visualizeDropLocation(mTargetCell[0], mTargetCell[1],
item.spanX, item.spanY, d);
} else if ((mDragMode == DRAG_MODE_NONE || mDragMode == DRAG_MODE_REORDER)
- && !mReorderAlarm.alarmPending()
- && (mLastReorderX != reorderX || mLastReorderY != reorderY)
- && targetCellDistance < mDragTargetLayout.getReorderRadius(mTargetCell)) {
+ && !mReorderAlarm.alarmPending() && (mLastReorderX != reorderX ||
+ mLastReorderY != reorderY)) {
int[] resultSpan = new int[2];
mDragTargetLayout.performReorder((int) mDragViewVisualCenter[0],
@@ -2445,104 +2281,57 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
*/
private boolean setDropLayoutForDragObject(DragObject d, float centerX, float centerY) {
CellLayout layout = null;
- if (shouldUseHotseatAsDropLayout(d)) {
- layout = mLauncher.getHotseat();
- } else if (!isDragObjectOverSmartSpace(d)) {
- // If the object is over qsb/smartspace, we don't want to highlight anything.
-
- // Check neighbour pages
- layout = checkDragObjectIsOverNeighbourPages(d, centerX);
-
- if (layout == null) {
- // Check visible pages
- IntSet visiblePageIndices = getVisiblePageIndices();
- for (int visiblePageIndex : visiblePageIndices) {
- layout = verifyInsidePage(visiblePageIndex, d.x, d.y);
- if (layout != null) break;
- }
+ // Test to see if we are over the hotseat first
+ if (mLauncher.getHotseat() != null && !isDragWidget(d)) {
+ if (isPointInSelfOverHotseat(d.x, d.y)) {
+ layout = mLauncher.getHotseat();
}
}
- // Update the current drop layout if the target changed
- if (layout != mDragTargetLayout) {
- setCurrentDropLayout(layout);
- setCurrentDragOverlappingLayout(layout);
- return true;
+ int nextPage = getNextPage();
+ if (layout == null && !isPageInTransition()) {
+ // Check if the item is dragged over currentPage - 1 page
+ mTempTouchCoordinates[0] = Math.min(centerX, d.x);
+ mTempTouchCoordinates[1] = d.y;
+ layout = verifyInsidePage(nextPage + (mIsRtl ? 1 : -1), mTempTouchCoordinates);
}
- return false;
- }
- private boolean shouldUseHotseatAsDropLayout(DragObject dragObject) {
- if (mLauncher.getHotseat() == null
- || mLauncher.getHotseat().getShortcutsAndWidgets() == null
- || isDragWidget(dragObject)) {
- return false;
+ if (layout == null && !isPageInTransition()) {
+ // Check if the item is dragged over currentPage + 1 page
+ mTempTouchCoordinates[0] = Math.max(centerX, d.x);
+ mTempTouchCoordinates[1] = d.y;
+ layout = verifyInsidePage(nextPage + (mIsRtl ? -1 : 1), mTempTouchCoordinates);
}
- View hotseatShortcuts = mLauncher.getHotseat().getShortcutsAndWidgets();
- getViewBoundsRelativeToWorkspace(hotseatShortcuts, mTempRect);
- return mTempRect.contains(dragObject.x, dragObject.y);
- }
- private boolean isDragObjectOverSmartSpace(DragObject dragObject) {
- if (mQsb == null) {
- return false;
+ // If two panel is enabled, users can also drag items to currentPage + 2
+ if (isTwoPanelEnabled() && layout == null && !isPageInTransition()) {
+ // Check if the item is dragged over currentPage + 2 page
+ mTempTouchCoordinates[0] = Math.max(centerX, d.x);
+ mTempTouchCoordinates[1] = d.y;
+ layout = verifyInsidePage(nextPage + (mIsRtl ? -2 : 2), mTempTouchCoordinates);
}
- getViewBoundsRelativeToWorkspace(mQsb, mTempRect);
- return mTempRect.contains(dragObject.x, dragObject.y);
- }
- private CellLayout checkDragObjectIsOverNeighbourPages(DragObject d, float centerX) {
- if (isPageInTransition()) {
- return null;
+ // Always pick the current page.
+ if (layout == null && nextPage >= 0 && nextPage < getPageCount()) {
+ layout = (CellLayout) getChildAt(nextPage);
}
-
- // Check the workspace pages whether the object is over any of them
-
- // Note, centerX represents the center of the object that is being dragged, visually.
- // d.x represents the location of the finger within the dragged item.
- float touchX;
- float touchY = d.y;
-
- // Go through the pages and check if the dragged item is inside one of them. This block
- // is responsible for determining whether we need to snap to a different screen.
- int nextPage = getNextPage();
- IntSet pageIndexesToVerify = IntSet.wrap(nextPage - 1,
- nextPage + (isTwoPanelEnabled() ? 2 : 1));
-
- for (int pageIndex : pageIndexesToVerify) {
- // When deciding whether to perform a page switch, we need to consider the most
- // extreme X coordinate between the finger location and the center of the object
- // being dragged. This is either the max or the min of the two depending on whether
- // dragging to the left / right, respectively.
- touchX = (((pageIndex < nextPage) && !mIsRtl) || (pageIndex > nextPage && mIsRtl))
- ? Math.min(d.x, centerX) : Math.max(d.x, centerX);
- CellLayout layout = verifyInsidePage(pageIndex, touchX, touchY);
- if (layout != null) {
- return layout;
- }
+ if (layout != mDragTargetLayout) {
+ setCurrentDropLayout(layout);
+ setCurrentDragOverlappingLayout(layout);
+ return true;
}
- return null;
- }
-
- /**
- * Gets the given view's bounds relative to Workspace
- */
- private void getViewBoundsRelativeToWorkspace(View view, Rect outRect) {
- mLauncher.getDragLayer()
- .getDescendantRectRelativeToSelf(view, mTempRect);
- // map draglayer relative bounds to workspace
- mLauncher.getDragLayer().mapRectInSelfToDescendant(this, mTempRect);
- outRect.set(mTempRect);
+ return false;
}
/**
* Returns the child CellLayout if the point is inside the page coordinates, null otherwise.
*/
- private CellLayout verifyInsidePage(int pageNo, float x, float y) {
+ private CellLayout verifyInsidePage(int pageNo, float[] touchXy) {
if (pageNo >= 0 && pageNo < getPageCount()) {
CellLayout cl = (CellLayout) getChildAt(pageNo);
- if (x >= cl.getLeft() && x <= cl.getRight()
- && y >= cl.getTop() && y <= cl.getBottom()) {
+ mapPointFromSelfToChild(cl, touchXy);
+ if (touchXy[0] >= 0 && touchXy[0] <= cl.getWidth() &&
+ touchXy[1] >= 0 && touchXy[1] <= cl.getHeight()) {
// This point is inside the cell layout
return cl;
}
@@ -2551,7 +2340,7 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
}
private void manageFolderFeedback(float distance, DragObject dragObject) {
- if (distance > mDragTargetLayout.getFolderCreationRadius(mTargetCell)) {
+ if (distance > mMaxDistanceForFolderCreation) {
if ((mDragMode == DRAG_MODE_ADD_TO_FOLDER
|| mDragMode == DRAG_MODE_CREATE_FOLDER)) {
setDragMode(DRAG_MODE_NONE);
@@ -2696,8 +2485,8 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
if (pendingInfo.itemType == LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT) {
mTargetCell = findNearestArea(touchXY[0], touchXY[1], spanX, spanY,
cellLayout, mTargetCell);
- float distance = cellLayout.getDistanceFromWorkspaceCellVisualCenter(
- mDragViewVisualCenter[0], mDragViewVisualCenter[1], mTargetCell);
+ float distance = cellLayout.getDistanceFromCell(mDragViewVisualCenter[0],
+ mDragViewVisualCenter[1], mTargetCell);
if (willCreateUserFolder(d.dragInfo, cellLayout, mTargetCell, distance, true)
|| willAddToExistingUserFolder(
d.dragInfo, cellLayout, mTargetCell, distance)) {
@@ -2770,16 +2559,9 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
case ITEM_TYPE_APPLICATION:
case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:
case LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT:
- case LauncherSettings.Favorites.ITEM_TYPE_SEARCH_ACTION:
- if (info instanceof WorkspaceItemFactory) {
+ if (info instanceof AppInfo) {
// Came from all apps -- make a copy
- info = ((WorkspaceItemFactory) info).makeWorkspaceItem(mLauncher);
- d.dragInfo = info;
- }
- if (info instanceof WorkspaceItemInfo
- && info.container == LauncherSettings.Favorites.CONTAINER_PREDICTION) {
- // Came from all apps prediction row -- make a copy
- info = new WorkspaceItemInfo((WorkspaceItemInfo) info);
+ info = ((AppInfo) info).makeWorkspaceItem();
d.dragInfo = info;
}
view = mLauncher.createShortcut(cellLayout, (WorkspaceItemInfo) info);
@@ -2797,8 +2579,8 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
if (touchXY != null) {
mTargetCell = findNearestArea(touchXY[0], touchXY[1], spanX, spanY,
cellLayout, mTargetCell);
- float distance = cellLayout.getDistanceFromWorkspaceCellVisualCenter(
- mDragViewVisualCenter[0], mDragViewVisualCenter[1], mTargetCell);
+ float distance = cellLayout.getDistanceFromCell(mDragViewVisualCenter[0],
+ mDragViewVisualCenter[1], mTargetCell);
if (createUserFolderIfNecessary(view, container, cellLayout, mTargetCell, distance,
true, d)) {
return;
@@ -2857,8 +2639,7 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
}
private void getFinalPositionForDropAnimation(int[] loc, float[] scaleXY,
- DragView dragView, CellLayout layout, ItemInfo info, int[] targetCell, boolean scale,
- final View finalView) {
+ DragView dragView, CellLayout layout, ItemInfo info, int[] targetCell, boolean scale) {
// Now we animate the dragView, (ie. the widget or shortcut preview) into its final
// location and size on the home screen.
int spanX = info.spanX;
@@ -2867,14 +2648,6 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
Rect r = estimateItemPosition(layout, targetCell[0], targetCell[1], spanX, spanY);
if (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET) {
DeviceProfile profile = mLauncher.getDeviceProfile();
- if (profile.shouldInsetWidgets() && finalView instanceof NavigableAppWidgetHostView) {
- Rect widgetPadding = new Rect();
- ((NavigableAppWidgetHostView) finalView).getWidgetInset(profile, widgetPadding);
- r.left -= widgetPadding.left;
- r.right += widgetPadding.right;
- r.top -= widgetPadding.top;
- r.bottom += widgetPadding.bottom;
- }
Utilities.shrinkRect(r, profile.appWidgetScale.x, profile.appWidgetScale.y);
}
@@ -2917,11 +2690,14 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
public void animateWidgetDrop(ItemInfo info, CellLayout cellLayout, final DragView dragView,
final Runnable onCompleteRunnable, int animationType, final View finalView,
boolean external) {
+ Rect from = new Rect();
+ mLauncher.getDragLayer().getViewRectRelativeToSelf(dragView, from);
+
int[] finalPos = new int[2];
float scaleXY[] = new float[2];
boolean scalePreview = !(info instanceof PendingAddShortcutInfo);
getFinalPositionForDropAnimation(finalPos, scaleXY, dragView, cellLayout, info, mTargetCell,
- scalePreview, finalView);
+ scalePreview);
Resources res = mLauncher.getResources();
final int duration = res.getInteger(R.integer.config_dropAnimMaxDuration) - 200;
@@ -2960,8 +2736,8 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
}
}
};
- dragLayer.animateViewIntoPosition(dragView, finalPos[0],
- finalPos[1], 1, scaleXY[0], scaleXY[1], onComplete, endStyle,
+ dragLayer.animateViewIntoPosition(dragView, from.left, from.top, finalPos[0],
+ finalPos[1], 1, 1, 1, scaleXY[0], scaleXY[1], onComplete, endStyle,
duration, this);
}
}
@@ -3068,8 +2844,7 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
if (info instanceof LauncherAppWidgetInfo) {
LauncherAppWidgetInfo appWidgetInfo = (LauncherAppWidgetInfo) info;
if (appWidgetInfo.appWidgetId == appWidgetId) {
- mLauncher.removeItem(view, appWidgetInfo, true,
- "widget is removed in response to widget remove broadcast");
+ mLauncher.removeItem(view, appWidgetInfo, true);
return true;
}
}
@@ -3181,6 +2956,62 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
return layouts;
}
+ /**
+ * Similar to {@link #getFirstMatch} but optimized to finding a suitable view for the app close
+ * animation.
+ *
+ * @param preferredItemId The id of the preferred item to match to if it exists.
+ * @param packageName The package name of the app to match.
+ * @param user The user of the app to match.
+ */
+ public View getFirstMatchForAppClose(int preferredItemId, String packageName, UserHandle user) {
+ final Workspace.ItemOperator preferredItem = (ItemInfo info, View view) ->
+ info != null && info.id == preferredItemId;
+ final Workspace.ItemOperator preferredItemInFolder = (info, view) -> {
+ if (info instanceof FolderInfo) {
+ FolderInfo folderInfo = (FolderInfo) info;
+ for (WorkspaceItemInfo shortcutInfo : folderInfo.contents) {
+ if (preferredItem.evaluate(shortcutInfo, view)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ };
+ final Workspace.ItemOperator packageAndUserAndApp = (ItemInfo info, View view) ->
+ info != null
+ && info.itemType == ITEM_TYPE_APPLICATION
+ && info.user.equals(user)
+ && info.getTargetComponent() != null
+ && TextUtils.equals(info.getTargetComponent().getPackageName(),
+ packageName);
+ final Workspace.ItemOperator packageAndUserAndAppInFolder = (info, view) -> {
+ if (info instanceof FolderInfo) {
+ FolderInfo folderInfo = (FolderInfo) info;
+ for (WorkspaceItemInfo shortcutInfo : folderInfo.contents) {
+ if (packageAndUserAndApp.evaluate(shortcutInfo, view)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ };
+
+ List<CellLayout> cellLayouts = new ArrayList<>(getPanelCount() + 1);
+ cellLayouts.add(getHotseat());
+ forEachVisiblePage(page -> cellLayouts.add((CellLayout) page));
+
+ // Order: Preferred item, App icons in hotseat/workspace, app in folder in hotseat/workspace
+ if (ADAPTIVE_ICON_WINDOW_ANIM.get()) {
+ return getFirstMatch(cellLayouts, preferredItem, preferredItemInFolder,
+ packageAndUserAndApp, packageAndUserAndAppInFolder);
+ } else {
+ // Do not use Folder as a criteria, since it'll cause a crash when trying to draw
+ // FolderAdaptiveIcon as the background.
+ return getFirstMatch(cellLayouts, preferredItem, packageAndUserAndApp);
+ }
+ }
+
public View getHomescreenIconByItemId(final int id) {
return getFirstMatch((info, v) -> info != null && info.id == id);
}
@@ -3206,6 +3037,23 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
return value[0];
}
+ /**
+ * Finds the first view matching the ordered operators across the given cell layouts by order.
+ * @param cellLayouts List of CellLayouts to scan, in order of preference.
+ * @param operators List of operators, in order starting from best matching operator.
+ */
+ View getFirstMatch(Iterable<CellLayout> cellLayouts, final ItemOperator... operators) {
+ for (ItemOperator operator : operators) {
+ for (CellLayout cellLayout : cellLayouts) {
+ View match = mapOverCellLayout(cellLayout, operator);
+ if (match != null) {
+ return match;
+ }
+ }
+ }
+ return null;
+ }
+
void clearDropTargets() {
mapOverItems(new ItemOperator() {
@Override
@@ -3224,7 +3072,7 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
* as a part of an update, this is called to ensure that other widgets and application
* shortcuts are not removed.
*/
- public void removeItemsByMatcher(final Predicate<ItemInfo> matcher) {
+ public void removeItemsByMatcher(final ItemInfoMatcher matcher) {
for (CellLayout layout : getWorkspaceAndHotseatCellLayouts()) {
ShortcutAndWidgetContainer container = layout.getShortcutsAndWidgets();
// Iterate in reverse order as we are removing items
@@ -3232,7 +3080,7 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
View child = container.getChildAt(i);
ItemInfo info = (ItemInfo) child.getTag();
- if (matcher.test(info)) {
+ if (matcher.matchesInfo(info)) {
layout.removeViewInLayout(child);
if (child instanceof DropTarget) {
mDragController.removeDropTarget((DropTarget) child);
@@ -3240,7 +3088,7 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
} else if (child instanceof FolderIcon) {
FolderInfo folderInfo = (FolderInfo) info;
List<WorkspaceItemInfo> matches = folderInfo.contents.stream()
- .filter(matcher)
+ .filter(matcher::matchesInfo)
.collect(Collectors.toList());
if (!matches.isEmpty()) {
folderInfo.removeAll(matches, false);
@@ -3256,7 +3104,22 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
stripEmptyScreens();
}
- @Override
+ public interface ItemOperator {
+ /**
+ * Process the next itemInfo, possibly with side-effect on the next item.
+ *
+ * @param info info for the shortcut
+ * @param view view for the shortcut
+ * @return true if done, false to continue the map
+ */
+ boolean evaluate(ItemInfo info, View view);
+ }
+
+ /**
+ * Map the operator over the shortcuts and widgets, return the first-non-null value.
+ *
+ * @param op the operator to map over the shortcuts
+ */
public void mapOverItems(ItemOperator op) {
for (CellLayout layout : getWorkspaceAndHotseatCellLayouts()) {
if (mapOverCellLayout(layout, op) != null) {
@@ -3265,11 +3128,7 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
}
}
- /**
- * Perform {param operator} over all the items in a given {param layout}.
- * @return The first item that satisfies the operator or null.
- */
- public View mapOverCellLayout(CellLayout layout, ItemOperator operator) {
+ private View mapOverCellLayout(CellLayout layout, ItemOperator op) {
// TODO(b/128460496) Potential race condition where layout is not yet loaded
if (layout == null) {
return null;
@@ -3279,13 +3138,38 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
final int itemCount = container.getChildCount();
for (int itemIdx = 0; itemIdx < itemCount; itemIdx++) {
View item = container.getChildAt(itemIdx);
- if (operator.evaluate((ItemInfo) item.getTag(), item)) {
+ if (op.evaluate((ItemInfo) item.getTag(), item)) {
return item;
}
}
return null;
}
+ void updateShortcuts(List<WorkspaceItemInfo> shortcuts) {
+ final HashSet<WorkspaceItemInfo> updates = new HashSet<>(shortcuts);
+ ItemOperator op = (info, v) -> {
+ if (v instanceof BubbleTextView && updates.contains(info)) {
+ WorkspaceItemInfo si = (WorkspaceItemInfo) info;
+ BubbleTextView shortcut = (BubbleTextView) v;
+ Drawable oldIcon = shortcut.getIcon();
+ boolean oldPromiseState = (oldIcon instanceof PreloadIconDrawable)
+ && ((PreloadIconDrawable) oldIcon).hasNotCompleted();
+ shortcut.applyFromWorkspaceItem(si, si.isPromise() != oldPromiseState);
+ } else if (info instanceof FolderInfo && v instanceof FolderIcon) {
+ ((FolderIcon) v).updatePreviewItems(updates::contains);
+ }
+
+ // Iterate all items
+ return false;
+ };
+
+ mapOverItems(op);
+ Folder openFolder = Folder.getOpen(mLauncher);
+ if (openFolder != null) {
+ openFolder.iterateOverItems(op);
+ }
+ }
+
public void updateNotificationDots(Predicate<PackageUserKey> updatedDots) {
final PackageUserKey packageUserKey = new PackageUserKey(null, null);
Predicate<ItemInfo> matcher = info -> !packageUserKey.updateFromItemInfo(info)
@@ -3318,17 +3202,35 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
}
}
- /**
- * Remove workspace icons & widget information related to items in matcher.
- *
- * @param matcher the matcher generated by the caller.
- */
- public void persistRemoveItemsByMatcher(Predicate<ItemInfo> matcher,
- @Nullable final String reason) {
- mLauncher.getModelWriter().deleteItemsFromDatabase(matcher, reason);
+ public void removeAbandonedPromise(String packageName, UserHandle user) {
+ ItemInfoMatcher matcher = ItemInfoMatcher.ofPackages(
+ Collections.singleton(packageName), user);
+ mLauncher.getModelWriter().deleteItemsFromDatabase(matcher);
removeItemsByMatcher(matcher);
}
+ public void updateRestoreItems(final HashSet<ItemInfo> updates) {
+ ItemOperator op = (info, v) -> {
+ if (info instanceof WorkspaceItemInfo && v instanceof BubbleTextView
+ && updates.contains(info)) {
+ ((BubbleTextView) v).applyLoadingState(false /* promiseStateChanged */);
+ } else if (v instanceof PendingAppWidgetHostView
+ && info instanceof LauncherAppWidgetInfo
+ && updates.contains(info)) {
+ ((PendingAppWidgetHostView) v).applyState();
+ } else if (v instanceof FolderIcon && info instanceof FolderInfo) {
+ ((FolderIcon) v).updatePreviewItems(updates::contains);
+ }
+ // process all the shortcuts
+ return false;
+ };
+ mapOverItems(op);
+ Folder folder = Folder.getOpen(mLauncher);
+ if (folder != null) {
+ folder.iterateOverItems(op);
+ }
+ }
+
public void widgetsRestored(final ArrayList<LauncherAppWidgetInfo> changedInfo) {
if (!changedInfo.isEmpty()) {
DeferredWidgetRefresh widgetRefresh = new DeferredWidgetRefresh(changedInfo,
@@ -3431,21 +3333,7 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
// When the workspace is not loaded, we do not know how many screen will be bound.
return getContext().getString(R.string.home_screen);
}
- int panelCount = getPanelCount();
- int currentPage = (page / panelCount) + 1;
- int totalPages = nScreens / panelCount + nScreens % panelCount;
- return getContext().getString(R.string.workspace_scroll_format, currentPage, totalPages);
- }
-
- @Override
- protected boolean isSignificantMove(float absoluteDelta, int pageOrientedSize) {
- DeviceProfile deviceProfile = mLauncher.getDeviceProfile();
- if (!deviceProfile.isTablet) {
- return super.isSignificantMove(absoluteDelta, pageOrientedSize);
- }
-
- return absoluteDelta
- > deviceProfile.availableWidthPx * SIGNIFICANT_MOVE_SCREEN_WIDTH_PERCENTAGE;
+ return getContext().getString(R.string.workspace_scroll_format, page + 1, nScreens);
}
/**
@@ -3507,6 +3395,12 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
private class StateTransitionListener extends AnimatorListenerAdapter
implements AnimatorUpdateListener {
+ private final LauncherState mToState;
+
+ StateTransitionListener(LauncherState toState) {
+ mToState = toState;
+ }
+
@Override
public void onAnimationUpdate(ValueAnimator anim) {
mTransitionProgress = anim.getAnimatedFraction();
@@ -3514,7 +3408,7 @@ public class Workspace<T extends View & PageIndicator> extends PagedView<T>
@Override
public void onAnimationStart(Animator animation) {
- onStartStateTransition();
+ onStartStateTransition(mToState);
}
@Override
diff --git a/src/com/android/launcher3/WorkspaceLayoutManager.java b/src/com/android/launcher3/WorkspaceLayoutManager.java
index 7e6e1b60de..d6302ce580 100644
--- a/src/com/android/launcher3/WorkspaceLayoutManager.java
+++ b/src/com/android/launcher3/WorkspaceLayoutManager.java
@@ -23,7 +23,6 @@ import com.android.launcher3.folder.Folder;
import com.android.launcher3.folder.FolderIcon;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.touch.ItemLongClickListener;
-import com.android.launcher3.util.IntSet;
public interface WorkspaceLayoutManager {
@@ -31,16 +30,8 @@ public interface WorkspaceLayoutManager {
// The screen id used for the empty screen always present at the end.
int EXTRA_EMPTY_SCREEN_ID = -201;
- // The screen id used for the second empty screen always present at the end for two panel home.
- int EXTRA_EMPTY_SCREEN_SECOND_ID = -200;
- // The screen ids used for the empty screens at the end of the workspaces.
- IntSet EXTRA_EMPTY_SCREEN_IDS =
- IntSet.wrap(EXTRA_EMPTY_SCREEN_ID, EXTRA_EMPTY_SCREEN_SECOND_ID);
-
// The is the first screen. It is always present, even if its empty.
int FIRST_SCREEN_ID = 0;
- // This is the second page. On two panel home it is always present, even if its empty.
- int SECOND_SCREEN_ID = 1;
/**
* At bind time, we use the rank (screenId) to compute x and y for hotseat items.
@@ -88,9 +79,9 @@ public interface WorkspaceLayoutManager {
return;
}
}
- if (EXTRA_EMPTY_SCREEN_IDS.contains(screenId)) {
+ if (screenId == EXTRA_EMPTY_SCREEN_ID) {
// This should never happen
- throw new RuntimeException("Screen id should not be extra empty screen: " + screenId);
+ throw new RuntimeException("Screen id should not be EXTRA_EMPTY_SCREEN_ID");
}
final CellLayout layout;
diff --git a/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java b/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java
index a991c2f959..1b9647afc0 100644
--- a/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java
+++ b/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java
@@ -18,14 +18,11 @@ package com.android.launcher3;
import static androidx.dynamicanimation.animation.DynamicAnimation.MIN_VISIBLE_CHANGE_SCALE;
-import static com.android.launcher3.LauncherAnimUtils.HOTSEAT_SCALE_PROPERTY_FACTORY;
-import static com.android.launcher3.LauncherAnimUtils.SCALE_INDEX_WORKSPACE_STATE;
+import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY;
import static com.android.launcher3.LauncherAnimUtils.VIEW_ALPHA;
import static com.android.launcher3.LauncherAnimUtils.VIEW_TRANSLATE_X;
import static com.android.launcher3.LauncherAnimUtils.VIEW_TRANSLATE_Y;
-import static com.android.launcher3.LauncherAnimUtils.WORKSPACE_SCALE_PROPERTY_FACTORY;
import static com.android.launcher3.LauncherState.FLAG_HAS_SYS_UI_SCRIM;
-import static com.android.launcher3.LauncherState.FLAG_HOTSEAT_INACCESSIBLE;
import static com.android.launcher3.LauncherState.HINT_STATE;
import static com.android.launcher3.LauncherState.HOTSEAT_ICONS;
import static com.android.launcher3.LauncherState.NORMAL;
@@ -36,23 +33,19 @@ import static com.android.launcher3.anim.Interpolators.ZOOM_OUT;
import static com.android.launcher3.anim.PropertySetter.NO_ANIM_PROPERTY_SETTER;
import static com.android.launcher3.graphics.Scrim.SCRIM_PROGRESS;
import static com.android.launcher3.graphics.SysUiScrim.SYSUI_PROGRESS;
-import static com.android.launcher3.states.StateAnimationConfig.ANIM_HOTSEAT_FADE;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_HOTSEAT_SCALE;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_HOTSEAT_TRANSLATE;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_SCRIM_FADE;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_FADE;
-import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_PAGE_TRANSLATE_X;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_SCALE;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_TRANSLATE;
import static com.android.launcher3.states.StateAnimationConfig.SKIP_SCRIM;
import android.animation.ValueAnimator;
-import android.util.FloatProperty;
import android.view.View;
import android.view.animation.Interpolator;
import com.android.launcher3.LauncherState.PageAlphaProvider;
-import com.android.launcher3.LauncherState.PageTranslationProvider;
import com.android.launcher3.LauncherState.ScaleAndTranslation;
import com.android.launcher3.anim.PendingAnimation;
import com.android.launcher3.anim.PropertySetter;
@@ -69,18 +62,12 @@ import com.android.systemui.plugins.ResourceProvider;
*/
public class WorkspaceStateTransitionAnimation {
- private static final FloatProperty<Workspace<?>> WORKSPACE_SCALE_PROPERTY =
- WORKSPACE_SCALE_PROPERTY_FACTORY.get(SCALE_INDEX_WORKSPACE_STATE);
-
- private static final FloatProperty<Hotseat> HOTSEAT_SCALE_PROPERTY =
- HOTSEAT_SCALE_PROPERTY_FACTORY.get(SCALE_INDEX_WORKSPACE_STATE);
-
private final Launcher mLauncher;
- private final Workspace<?> mWorkspace;
+ private final Workspace mWorkspace;
private float mNewScale;
- public WorkspaceStateTransitionAnimation(Launcher launcher, Workspace<?> workspace) {
+ public WorkspaceStateTransitionAnimation(Launcher launcher, Workspace workspace) {
mLauncher = launcher;
mWorkspace = workspace;
}
@@ -118,6 +105,8 @@ public class WorkspaceStateTransitionAnimation {
}
int elements = state.getVisibleElements(mLauncher);
+ Interpolator fadeInterpolator = config.getInterpolator(ANIM_WORKSPACE_FADE,
+ pageAlphaProvider.interpolator);
Hotseat hotseat = mWorkspace.getHotseat();
Interpolator scaleInterpolator = config.getInterpolator(ANIM_WORKSPACE_SCALE, ZOOM_OUT);
LauncherState fromState = mLauncher.getStateManager().getState();
@@ -126,40 +115,28 @@ public class WorkspaceStateTransitionAnimation {
&& fromState == HINT_STATE && state == NORMAL;
if (shouldSpring) {
((PendingAnimation) propertySetter).add(getSpringScaleAnimator(mLauncher,
- mWorkspace, mNewScale, WORKSPACE_SCALE_PROPERTY));
+ mWorkspace, mNewScale));
} else {
- propertySetter.setFloat(mWorkspace, WORKSPACE_SCALE_PROPERTY, mNewScale,
- scaleInterpolator);
+ propertySetter.setFloat(mWorkspace, SCALE_PROPERTY, mNewScale, scaleInterpolator);
}
mWorkspace.setPivotToScaleWithSelf(hotseat);
float hotseatScale = hotseatScaleAndTranslation.scale;
if (shouldSpring) {
PendingAnimation pa = (PendingAnimation) propertySetter;
- pa.add(getSpringScaleAnimator(mLauncher, hotseat, hotseatScale,
- HOTSEAT_SCALE_PROPERTY));
+ pa.add(getSpringScaleAnimator(mLauncher, hotseat, hotseatScale));
} else {
Interpolator hotseatScaleInterpolator = config.getInterpolator(ANIM_HOTSEAT_SCALE,
scaleInterpolator);
- propertySetter.setFloat(hotseat, HOTSEAT_SCALE_PROPERTY, hotseatScale,
+ propertySetter.setFloat(hotseat, SCALE_PROPERTY, hotseatScale,
hotseatScaleInterpolator);
}
- Interpolator workspaceFadeInterpolator = config.getInterpolator(ANIM_WORKSPACE_FADE,
- pageAlphaProvider.interpolator);
+ float hotseatIconsAlpha = (elements & HOTSEAT_ICONS) != 0 ? 1 : 0;
+ propertySetter.setViewAlpha(hotseat, hotseatIconsAlpha, fadeInterpolator);
float workspacePageIndicatorAlpha = (elements & WORKSPACE_PAGE_INDICATOR) != 0 ? 1 : 0;
propertySetter.setViewAlpha(mLauncher.getWorkspace().getPageIndicator(),
- workspacePageIndicatorAlpha, workspaceFadeInterpolator);
- Interpolator hotseatFadeInterpolator = config.getInterpolator(ANIM_HOTSEAT_FADE,
- workspaceFadeInterpolator);
- float hotseatIconsAlpha = (elements & HOTSEAT_ICONS) != 0 ? 1 : 0;
- propertySetter.setViewAlpha(hotseat, hotseatIconsAlpha, hotseatFadeInterpolator);
-
- // Update the accessibility flags for hotseat based on launcher state.
- hotseat.setImportantForAccessibility(
- state.hasFlag(FLAG_HOTSEAT_INACCESSIBLE)
- ? View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS
- : View.IMPORTANT_FOR_ACCESSIBILITY_AUTO);
+ workspacePageIndicatorAlpha, fadeInterpolator);
Interpolator translationInterpolator =
config.getInterpolator(ANIM_WORKSPACE_TRANSLATE, ZOOM_OUT);
@@ -167,12 +144,6 @@ public class WorkspaceStateTransitionAnimation {
scaleAndTranslation.translationX, translationInterpolator);
propertySetter.setFloat(mWorkspace, VIEW_TRANSLATE_Y,
scaleAndTranslation.translationY, translationInterpolator);
- PageTranslationProvider pageTranslationProvider = state.getWorkspacePageTranslationProvider(
- mLauncher);
- for (int i = 0; i < childCount; i++) {
- applyPageTranslation((CellLayout) mWorkspace.getChildAt(i), i, pageTranslationProvider,
- propertySetter, config);
- }
Interpolator hotseatTranslationInterpolator = config.getInterpolator(
ANIM_HOTSEAT_TRANSLATE, translationInterpolator);
@@ -220,29 +191,10 @@ public class WorkspaceStateTransitionAnimation {
pageAlpha, fadeInterpolator);
}
- private void applyPageTranslation(CellLayout cellLayout, int childIndex,
- PageTranslationProvider pageTranslationProvider, PropertySetter propertySetter,
- StateAnimationConfig config) {
- float pageTranslation = pageTranslationProvider.getPageTranslation(childIndex);
- Interpolator translationInterpolator = config.getInterpolator(
- ANIM_WORKSPACE_PAGE_TRANSLATE_X, pageTranslationProvider.interpolator);
- propertySetter.setFloat(cellLayout, VIEW_TRANSLATE_X, pageTranslation,
- translationInterpolator);
- }
-
- /**
- * Returns a spring based animator for the scale property of {@param workspace}.
- */
- public static ValueAnimator getWorkspaceSpringScaleAnimator(Launcher launcher,
- Workspace<?> workspace, float scale) {
- return getSpringScaleAnimator(launcher, workspace, scale, WORKSPACE_SCALE_PROPERTY);
- }
-
/**
* Returns a spring based animator for the scale property of {@param v}.
*/
- public static <T extends View> ValueAnimator getSpringScaleAnimator(Launcher launcher, T v,
- float scale, FloatProperty<T> property) {
+ public static ValueAnimator getSpringScaleAnimator(Launcher launcher, View v, float scale) {
ResourceProvider rp = DynamicResource.provider(launcher);
float damping = rp.getFloat(R.dimen.hint_scale_damping_ratio);
float stiffness = rp.getFloat(R.dimen.hint_scale_stiffness);
@@ -253,9 +205,9 @@ public class WorkspaceStateTransitionAnimation {
.setDampingRatio(damping)
.setMinimumVisibleChange(MIN_VISIBLE_CHANGE_SCALE)
.setEndValue(scale)
- .setStartValue(property.get(v))
+ .setStartValue(SCALE_PROPERTY.get(v))
.setStartVelocity(velocityPxPerS)
- .build(v, property);
+ .build(v, SCALE_PROPERTY);
}
} \ No newline at end of file
diff --git a/src/com/android/launcher3/accessibility/BaseAccessibilityDelegate.java b/src/com/android/launcher3/accessibility/BaseAccessibilityDelegate.java
deleted file mode 100644
index 19d042147b..0000000000
--- a/src/com/android/launcher3/accessibility/BaseAccessibilityDelegate.java
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * Copyright (C) 2021 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.launcher3.accessibility;
-
-import android.content.Context;
-import android.graphics.Rect;
-import android.os.Bundle;
-import android.text.TextUtils;
-import android.util.SparseArray;
-import android.view.View;
-import android.view.accessibility.AccessibilityNodeInfo;
-
-import com.android.launcher3.BubbleTextView;
-import com.android.launcher3.DropTarget;
-import com.android.launcher3.LauncherSettings;
-import com.android.launcher3.dragndrop.DragController;
-import com.android.launcher3.dragndrop.DragOptions;
-import com.android.launcher3.model.data.FolderInfo;
-import com.android.launcher3.model.data.ItemInfo;
-import com.android.launcher3.model.data.LauncherAppWidgetInfo;
-import com.android.launcher3.model.data.WorkspaceItemInfo;
-import com.android.launcher3.util.Thunk;
-import com.android.launcher3.views.ActivityContext;
-import com.android.launcher3.views.BubbleTextHolder;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public abstract class BaseAccessibilityDelegate<T extends Context & ActivityContext>
- extends View.AccessibilityDelegate implements DragController.DragListener {
-
- public enum DragType {
- ICON,
- FOLDER,
- WIDGET
- }
-
- public static class DragInfo {
- public DragType dragType;
- public ItemInfo info;
- public View item;
- }
-
- protected final SparseArray<LauncherAction> mActions = new SparseArray<>();
- protected final T mContext;
-
- protected DragInfo mDragInfo = null;
-
- protected BaseAccessibilityDelegate(T context) {
- mContext = context;
- }
-
- @Override
- public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) {
- super.onInitializeAccessibilityNodeInfo(host, info);
- if (host.getTag() instanceof ItemInfo) {
- ItemInfo item = (ItemInfo) host.getTag();
-
- List<LauncherAction> actions = new ArrayList<>();
- getSupportedActions(host, item, actions);
- actions.forEach(la -> info.addAction(la.accessibilityAction));
-
- if (!itemSupportsLongClick(host)) {
- info.setLongClickable(false);
- info.removeAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_LONG_CLICK);
- }
- }
- }
-
- /**
- * Adds all the accessibility actions that can be handled.
- */
- protected abstract void getSupportedActions(View host, ItemInfo item, List<LauncherAction> out);
-
- private boolean itemSupportsLongClick(View host) {
- if (host instanceof BubbleTextView) {
- return ((BubbleTextView) host).canShowLongPressPopup();
- } else if (host instanceof BubbleTextHolder) {
- BubbleTextHolder holder = (BubbleTextHolder) host;
- return holder.getBubbleText() != null && holder.getBubbleText().canShowLongPressPopup();
- } else {
- return false;
- }
- }
-
- protected boolean itemSupportsAccessibleDrag(ItemInfo item) {
- if (item instanceof WorkspaceItemInfo) {
- // Support the action unless the item is in a context menu.
- return item.screenId >= 0
- && item.container != LauncherSettings.Favorites.CONTAINER_HOTSEAT_PREDICTION;
- }
- return (item instanceof LauncherAppWidgetInfo)
- || (item instanceof FolderInfo);
- }
-
- @Override
- public boolean performAccessibilityAction(View host, int action, Bundle args) {
- if ((host.getTag() instanceof ItemInfo)
- && performAction(host, (ItemInfo) host.getTag(), action, false)) {
- return true;
- }
- return super.performAccessibilityAction(host, action, args);
- }
-
- protected abstract boolean performAction(
- View host, ItemInfo item, int action, boolean fromKeyboard);
-
- @Thunk
- protected void announceConfirmation(String confirmation) {
- mContext.getDragLayer().announceForAccessibility(confirmation);
- }
-
- public boolean isInAccessibleDrag() {
- return mDragInfo != null;
- }
-
- public DragInfo getDragInfo() {
- return mDragInfo;
- }
-
- /**
- * @param clickedTarget the actual view that was clicked
- * @param dropLocation relative to {@param clickedTarget}. If provided, its center is used
- * as the actual drop location otherwise the views center is used.
- */
- public void handleAccessibleDrop(View clickedTarget, Rect dropLocation,
- String confirmation) {
- if (!isInAccessibleDrag()) return;
-
- int[] loc = new int[2];
- if (dropLocation == null) {
- loc[0] = clickedTarget.getWidth() / 2;
- loc[1] = clickedTarget.getHeight() / 2;
- } else {
- loc[0] = dropLocation.centerX();
- loc[1] = dropLocation.centerY();
- }
-
- mContext.getDragLayer().getDescendantCoordRelativeToSelf(clickedTarget, loc);
- mContext.getDragController().completeAccessibleDrag(loc);
-
- if (!TextUtils.isEmpty(confirmation)) {
- announceConfirmation(confirmation);
- }
- }
-
- protected abstract boolean beginAccessibleDrag(View item, ItemInfo info, boolean fromKeyboard);
-
-
- @Override
- public void onDragEnd() {
- mContext.getDragController().removeDragListener(this);
- mDragInfo = null;
- }
-
- @Override
- public void onDragStart(DropTarget.DragObject dragObject, DragOptions options) {
- // No-op
- }
-
- public class LauncherAction {
- public final int keyCode;
- public final AccessibilityNodeInfo.AccessibilityAction accessibilityAction;
-
- private final BaseAccessibilityDelegate<T> mDelegate;
-
- public LauncherAction(int id, int labelRes, int keyCode) {
- this.keyCode = keyCode;
- accessibilityAction = new AccessibilityNodeInfo.AccessibilityAction(
- id, mContext.getString(labelRes));
- mDelegate = BaseAccessibilityDelegate.this;
- }
-
- /**
- * Invokes the action for the provided host
- */
- public boolean invokeFromKeyboard(View host) {
- if (host != null && host.getTag() instanceof ItemInfo) {
- return mDelegate.performAction(
- host, (ItemInfo) host.getTag(), accessibilityAction.getId(), true);
- } else {
- return false;
- }
- }
- }
-}
diff --git a/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java b/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java
index 79214e896a..9faac5b7ef 100644
--- a/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java
+++ b/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java
@@ -10,38 +10,43 @@ import android.appwidget.AppWidgetProviderInfo;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.RectF;
+import android.os.Bundle;
import android.os.Handler;
+import android.text.TextUtils;
import android.util.Log;
+import android.util.SparseArray;
import android.view.KeyEvent;
import android.view.View;
+import android.view.View.AccessibilityDelegate;
+import android.view.accessibility.AccessibilityNodeInfo;
+import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
import com.android.launcher3.BubbleTextView;
import com.android.launcher3.ButtonDropTarget;
import com.android.launcher3.CellLayout;
+import com.android.launcher3.DropTarget.DragObject;
import com.android.launcher3.Launcher;
-import com.android.launcher3.LauncherSettings;
+import com.android.launcher3.LauncherSettings.Favorites;
import com.android.launcher3.PendingAddItemInfo;
import com.android.launcher3.R;
import com.android.launcher3.Workspace;
+import com.android.launcher3.dragndrop.DragController.DragListener;
import com.android.launcher3.dragndrop.DragOptions;
-import com.android.launcher3.dragndrop.DragOptions.PreDragCondition;
import com.android.launcher3.dragndrop.DragView;
import com.android.launcher3.folder.Folder;
import com.android.launcher3.keyboard.KeyboardDragAndDropView;
+import com.android.launcher3.model.data.AppInfo;
import com.android.launcher3.model.data.FolderInfo;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.LauncherAppWidgetInfo;
-import com.android.launcher3.model.data.WorkspaceItemFactory;
import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.launcher3.notification.NotificationListener;
import com.android.launcher3.popup.ArrowPopup;
import com.android.launcher3.popup.PopupContainerWithArrow;
import com.android.launcher3.touch.ItemLongClickListener;
import com.android.launcher3.util.IntArray;
-import com.android.launcher3.util.IntSet;
import com.android.launcher3.util.ShortcutUtil;
import com.android.launcher3.util.Thunk;
-import com.android.launcher3.views.BubbleTextHolder;
import com.android.launcher3.views.OptionsPopupView;
import com.android.launcher3.views.OptionsPopupView.OptionItem;
import com.android.launcher3.widget.LauncherAppWidgetHostView;
@@ -51,7 +56,7 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
-public class LauncherAccessibilityDelegate extends BaseAccessibilityDelegate<Launcher> {
+public class LauncherAccessibilityDelegate extends AccessibilityDelegate implements DragListener {
private static final String TAG = "LauncherAccessibilityDelegate";
@@ -60,7 +65,6 @@ public class LauncherAccessibilityDelegate extends BaseAccessibilityDelegate<Lau
public static final int DISMISS_PREDICTION = R.id.action_dismiss_prediction;
public static final int PIN_PREDICTION = R.id.action_pin_prediction;
public static final int RECONFIGURE = R.id.action_reconfigure;
- public static final int INVALID = -1;
protected static final int ADD_TO_WORKSPACE = R.id.action_add_to_workspace;
protected static final int MOVE = R.id.action_move;
protected static final int MOVE_TO_WORKSPACE = R.id.action_move_to_workspace;
@@ -68,8 +72,25 @@ public class LauncherAccessibilityDelegate extends BaseAccessibilityDelegate<Lau
public static final int DEEP_SHORTCUTS = R.id.action_deep_shortcuts;
public static final int SHORTCUTS_AND_NOTIFICATIONS = R.id.action_shortcuts_and_notifications;
+ public enum DragType {
+ ICON,
+ FOLDER,
+ WIDGET
+ }
+
+ public static class DragInfo {
+ public DragType dragType;
+ public ItemInfo info;
+ public View item;
+ }
+
+ protected final SparseArray<LauncherAction> mActions = new SparseArray<>();
+ protected final Launcher mLauncher;
+
+ private DragInfo mDragInfo = null;
+
public LauncherAccessibilityDelegate(Launcher launcher) {
- super(launcher);
+ mLauncher = launcher;
mActions.put(REMOVE, new LauncherAction(
REMOVE, R.string.remove_drop_target_label, KeyEvent.KEYCODE_X));
@@ -94,6 +115,25 @@ public class LauncherAccessibilityDelegate extends BaseAccessibilityDelegate<Lau
}
@Override
+ public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) {
+ super.onInitializeAccessibilityNodeInfo(host, info);
+ if (host.getTag() instanceof ItemInfo) {
+ ItemInfo item = (ItemInfo) host.getTag();
+
+ List<LauncherAction> actions = new ArrayList<>();
+ getSupportedActions(host, item, actions);
+ actions.forEach(la -> info.addAction(la.accessibilityAction));
+
+ if (!itemSupportsLongClick(host, item)) {
+ info.setLongClickable(false);
+ info.removeAction(AccessibilityAction.ACTION_LONG_CLICK);
+ }
+ }
+ }
+
+ /**
+ * Adds all the accessibility actions that can be handled.
+ */
protected void getSupportedActions(View host, ItemInfo item, List<LauncherAction> out) {
// If the request came from keyboard, do not add custom shortcuts as that is already
// exposed as a direct shortcut
@@ -102,7 +142,7 @@ public class LauncherAccessibilityDelegate extends BaseAccessibilityDelegate<Lau
? SHORTCUTS_AND_NOTIFICATIONS : DEEP_SHORTCUTS));
}
- for (ButtonDropTarget target : mContext.getDropTargetBar().getDropTargets()) {
+ for (ButtonDropTarget target : mLauncher.getDropTargetBar().getDropTargets()) {
if (target.supportsAccessibilityDrop(item, host)) {
out.add(mActions.get(target.getAccessibilityAction()));
}
@@ -121,8 +161,7 @@ public class LauncherAccessibilityDelegate extends BaseAccessibilityDelegate<Lau
}
}
- if ((item instanceof WorkspaceItemFactory) || (item instanceof WorkspaceItemInfo)
- || (item instanceof PendingAddItemInfo)) {
+ if ((item instanceof AppInfo) || (item instanceof PendingAddItemInfo)) {
out.add(mActions.get(ADD_TO_WORKSPACE));
}
}
@@ -142,44 +181,99 @@ public class LauncherAccessibilityDelegate extends BaseAccessibilityDelegate<Lau
return result;
}
+ private boolean itemSupportsLongClick(View host, ItemInfo info) {
+ return PopupContainerWithArrow.canShow(host, info);
+ }
+
+ private boolean itemSupportsAccessibleDrag(ItemInfo item) {
+ if (item instanceof WorkspaceItemInfo) {
+ // Support the action unless the item is in a context menu.
+ return item.screenId >= 0 && item.container != Favorites.CONTAINER_HOTSEAT_PREDICTION;
+ }
+ return (item instanceof LauncherAppWidgetInfo)
+ || (item instanceof FolderInfo);
+ }
+
@Override
+ public boolean performAccessibilityAction(View host, int action, Bundle args) {
+ if ((host.getTag() instanceof ItemInfo)
+ && performAction(host, (ItemInfo) host.getTag(), action, false)) {
+ return true;
+ }
+ return super.performAccessibilityAction(host, action, args);
+ }
+
+ /**
+ * Performs the provided action on the host
+ */
protected boolean performAction(final View host, final ItemInfo item, int action,
boolean fromKeyboard) {
if (action == ACTION_LONG_CLICK) {
- PreDragCondition dragCondition = null;
- // Long press should be consumed for workspace items, and it should invoke the
- // Shortcuts / Notifications / Actions pop-up menu, and not start a drag as the
- // standard long press path does.
- if (host instanceof BubbleTextView) {
- dragCondition = ((BubbleTextView) host).startLongPressAction();
- } else if (host instanceof BubbleTextHolder) {
- BubbleTextHolder holder = (BubbleTextHolder) host;
- dragCondition = holder.getBubbleText() == null ? null
- : holder.getBubbleText().startLongPressAction();
+ if (PopupContainerWithArrow.canShow(host, item)) {
+ // Long press should be consumed for workspace items, and it should invoke the
+ // Shortcuts / Notifications / Actions pop-up menu, and not start a drag as the
+ // standard long press path does.
+ PopupContainerWithArrow.showForIcon((BubbleTextView) host);
+ return true;
}
- return dragCondition != null;
} else if (action == MOVE) {
return beginAccessibleDrag(host, item, fromKeyboard);
} else if (action == ADD_TO_WORKSPACE) {
- return addToWorkspace(item, true);
+ final int[] coordinates = new int[2];
+ final int screenId = findSpaceOnWorkspace(item, coordinates);
+ mLauncher.getStateManager().goToState(NORMAL, true, forSuccessCallback(() -> {
+ if (item instanceof AppInfo) {
+ WorkspaceItemInfo info = ((AppInfo) item).makeWorkspaceItem();
+ mLauncher.getModelWriter().addItemToDatabase(info,
+ Favorites.CONTAINER_DESKTOP,
+ screenId, coordinates[0], coordinates[1]);
+
+ mLauncher.bindItems(
+ Collections.singletonList(info),
+ /* forceAnimateIcons= */ true,
+ /* focusFirstItemForAccessibility= */ true);
+ announceConfirmation(R.string.item_added_to_workspace);
+ } else if (item instanceof PendingAddItemInfo) {
+ PendingAddItemInfo info = (PendingAddItemInfo) item;
+ Workspace workspace = mLauncher.getWorkspace();
+ workspace.snapToPage(workspace.getPageIndexForScreenId(screenId));
+ mLauncher.addPendingItem(info, Favorites.CONTAINER_DESKTOP,
+ screenId, coordinates, info.spanX, info.spanY);
+ }
+ }));
+ return true;
} else if (action == MOVE_TO_WORKSPACE) {
- return moveToWorkspace(item);
+ Folder folder = Folder.getOpen(mLauncher);
+ folder.close(true);
+ WorkspaceItemInfo info = (WorkspaceItemInfo) item;
+ folder.getInfo().remove(info, false);
+
+ final int[] coordinates = new int[2];
+ final int screenId = findSpaceOnWorkspace(item, coordinates);
+ mLauncher.getModelWriter().moveItemInDatabase(info,
+ Favorites.CONTAINER_DESKTOP,
+ screenId, coordinates[0], coordinates[1]);
+
+ // Bind the item in next frame so that if a new workspace page was created,
+ // it will get laid out.
+ new Handler().post(() -> {
+ mLauncher.bindItems(Collections.singletonList(item), true);
+ announceConfirmation(R.string.item_moved);
+ });
+ return true;
} else if (action == RESIZE) {
final LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) item;
List<OptionItem> actions = getSupportedResizeActions(host, info);
Rect pos = new Rect();
- mContext.getDragLayer().getDescendantRectRelativeToSelf(host, pos);
- ArrowPopup popup = OptionsPopupView.show(mContext, new RectF(pos), actions, false);
+ mLauncher.getDragLayer().getDescendantRectRelativeToSelf(host, pos);
+ ArrowPopup popup = OptionsPopupView.show(mLauncher, new RectF(pos), actions, false);
popup.requestFocus();
popup.setOnCloseCallback(host::requestFocus);
return true;
} else if (action == DEEP_SHORTCUTS || action == SHORTCUTS_AND_NOTIFICATIONS) {
- BubbleTextView btv = host instanceof BubbleTextView ? (BubbleTextView) host
- : (host instanceof BubbleTextHolder
- ? ((BubbleTextHolder) host).getBubbleText() : null);
- return btv != null && PopupContainerWithArrow.showForIcon(btv) != null;
+ return PopupContainerWithArrow.showForIcon((BubbleTextView) host) != null;
} else {
- for (ButtonDropTarget dropTarget : mContext.getDropTargetBar().getDropTargets()) {
+ for (ButtonDropTarget dropTarget : mLauncher.getDropTargetBar().getDropTargets()) {
if (dropTarget.supportsAccessibilityDrop(item, host)
&& action == dropTarget.getAccessibilityAction()) {
dropTarget.onAccessibilityDrop(host, item);
@@ -206,7 +300,7 @@ public class LauncherAccessibilityDelegate extends BaseAccessibilityDelegate<Lau
if ((providerInfo.resizeMode & AppWidgetProviderInfo.RESIZE_HORIZONTAL) != 0) {
if (layout.isRegionVacant(info.cellX + info.spanX, info.cellY, 1, info.spanY) ||
layout.isRegionVacant(info.cellX - 1, info.cellY, 1, info.spanY)) {
- actions.add(new OptionItem(mContext,
+ actions.add(new OptionItem(mLauncher,
R.string.action_increase_width,
R.drawable.ic_widget_width_increase,
IGNORE,
@@ -214,7 +308,7 @@ public class LauncherAccessibilityDelegate extends BaseAccessibilityDelegate<Lau
}
if (info.spanX > info.minSpanX && info.spanX > 1) {
- actions.add(new OptionItem(mContext,
+ actions.add(new OptionItem(mLauncher,
R.string.action_decrease_width,
R.drawable.ic_widget_width_decrease,
IGNORE,
@@ -225,7 +319,7 @@ public class LauncherAccessibilityDelegate extends BaseAccessibilityDelegate<Lau
if ((providerInfo.resizeMode & AppWidgetProviderInfo.RESIZE_VERTICAL) != 0) {
if (layout.isRegionVacant(info.cellX, info.cellY + info.spanY, info.spanX, 1) ||
layout.isRegionVacant(info.cellX, info.cellY - 1, info.spanX, 1)) {
- actions.add(new OptionItem(mContext,
+ actions.add(new OptionItem(mLauncher,
R.string.action_increase_height,
R.drawable.ic_widget_height_increase,
IGNORE,
@@ -233,7 +327,7 @@ public class LauncherAccessibilityDelegate extends BaseAccessibilityDelegate<Lau
}
if (info.spanY > info.minSpanY && info.spanY > 1) {
- actions.add(new OptionItem(mContext,
+ actions.add(new OptionItem(mLauncher,
R.string.action_decrease_height,
R.drawable.ic_widget_height_decrease,
IGNORE,
@@ -273,20 +367,58 @@ public class LauncherAccessibilityDelegate extends BaseAccessibilityDelegate<Lau
}
layout.markCellsAsOccupiedForView(host);
- WidgetSizes.updateWidgetSizeRanges(((LauncherAppWidgetHostView) host), mContext,
+ WidgetSizes.updateWidgetSizeRanges(((LauncherAppWidgetHostView) host), mLauncher,
info.spanX, info.spanY);
host.requestLayout();
- mContext.getModelWriter().updateItemInDatabase(info);
- announceConfirmation(mContext.getString(R.string.widget_resized, info.spanX, info.spanY));
+ mLauncher.getModelWriter().updateItemInDatabase(info);
+ announceConfirmation(mLauncher.getString(R.string.widget_resized, info.spanX, info.spanY));
return true;
}
@Thunk void announceConfirmation(int resId) {
- announceConfirmation(mContext.getResources().getString(resId));
+ announceConfirmation(mLauncher.getResources().getString(resId));
}
- @Override
- protected boolean beginAccessibleDrag(View item, ItemInfo info, boolean fromKeyboard) {
+ @Thunk void announceConfirmation(String confirmation) {
+ mLauncher.getDragLayer().announceForAccessibility(confirmation);
+
+ }
+
+ public boolean isInAccessibleDrag() {
+ return mDragInfo != null;
+ }
+
+ public DragInfo getDragInfo() {
+ return mDragInfo;
+ }
+
+ /**
+ * @param clickedTarget the actual view that was clicked
+ * @param dropLocation relative to {@param clickedTarget}. If provided, its center is used
+ * as the actual drop location otherwise the views center is used.
+ */
+ public void handleAccessibleDrop(View clickedTarget, Rect dropLocation,
+ String confirmation) {
+ if (!isInAccessibleDrag()) return;
+
+ int[] loc = new int[2];
+ if (dropLocation == null) {
+ loc[0] = clickedTarget.getWidth() / 2;
+ loc[1] = clickedTarget.getHeight() / 2;
+ } else {
+ loc[0] = dropLocation.centerX();
+ loc[1] = dropLocation.centerY();
+ }
+
+ mLauncher.getDragLayer().getDescendantCoordRelativeToSelf(clickedTarget, loc);
+ mLauncher.getDragController().completeAccessibleDrag(loc);
+
+ if (!TextUtils.isEmpty(confirmation)) {
+ announceConfirmation(confirmation);
+ }
+ }
+
+ private boolean beginAccessibleDrag(View item, ItemInfo info, boolean fromKeyboard) {
if (!itemSupportsAccessibleDrag(info)) {
return false;
}
@@ -302,8 +434,8 @@ public class LauncherAccessibilityDelegate extends BaseAccessibilityDelegate<Lau
}
Rect pos = new Rect();
- mContext.getDragLayer().getDescendantRectRelativeToSelf(item, pos);
- mContext.getDragController().addDragListener(this);
+ mLauncher.getDragLayer().getDescendantRectRelativeToSelf(item, pos);
+ mLauncher.getDragController().addDragListener(this);
DragOptions options = new DragOptions();
options.isAccessibleDrag = true;
@@ -311,20 +443,31 @@ public class LauncherAccessibilityDelegate extends BaseAccessibilityDelegate<Lau
options.simulatedDndStartPoint = new Point(pos.centerX(), pos.centerY());
if (fromKeyboard) {
- KeyboardDragAndDropView popup = (KeyboardDragAndDropView) mContext.getLayoutInflater()
- .inflate(R.layout.keyboard_drag_and_drop, mContext.getDragLayer(), false);
+ KeyboardDragAndDropView popup = (KeyboardDragAndDropView) mLauncher.getLayoutInflater()
+ .inflate(R.layout.keyboard_drag_and_drop, mLauncher.getDragLayer(), false);
popup.showForIcon(item, info, options);
} else {
- ItemLongClickListener.beginDrag(item, mContext, info, options);
+ ItemLongClickListener.beginDrag(item, mLauncher, info, options);
}
return true;
}
+ @Override
+ public void onDragStart(DragObject dragObject, DragOptions options) {
+ // No-op
+ }
+
+ @Override
+ public void onDragEnd() {
+ mLauncher.getDragController().removeDragListener(this);
+ mDragInfo = null;
+ }
+
/**
* Find empty space on the workspace and returns the screenId.
*/
protected int findSpaceOnWorkspace(ItemInfo info, int[] outCoordinates) {
- Workspace<?> workspace = mContext.getWorkspace();
+ Workspace workspace = mLauncher.getWorkspace();
IntArray workspaceScreens = workspace.getScreenOrder();
int screenId;
@@ -346,14 +489,8 @@ public class LauncherAccessibilityDelegate extends BaseAccessibilityDelegate<Lau
return screenId;
}
- workspace.addExtraEmptyScreens();
- IntSet emptyScreenIds = workspace.commitExtraEmptyScreens();
- if (emptyScreenIds.isEmpty()) {
- // Couldn't create extra empty screens for some reason (e.g. Workspace is loading)
- return -1;
- }
-
- screenId = emptyScreenIds.getArray().get(0);
+ workspace.addExtraEmptyScreen();
+ screenId = workspace.commitExtraEmptyScreen();
layout = workspace.getScreenWithId(screenId);
found = layout.findCellForSpan(outCoordinates, info.spanX, info.spanY);
@@ -363,75 +500,28 @@ public class LauncherAccessibilityDelegate extends BaseAccessibilityDelegate<Lau
return screenId;
}
- /**
- * Functionality to add the item {@link ItemInfo} to the workspace
- * @param item item to be added
- * @param accessibility true if the first item to be added to the workspace
- * should be focused for accessibility.
- *
- * @return true if the item could be successfully added
- */
- public boolean addToWorkspace(ItemInfo item, boolean accessibility) {
- final int[] coordinates = new int[2];
- final int screenId = findSpaceOnWorkspace(item, coordinates);
- if (screenId == -1) {
- return false;
+ public class LauncherAction {
+ public final int keyCode;
+ public final AccessibilityAction accessibilityAction;
+
+ private final LauncherAccessibilityDelegate mDelegate;
+
+ public LauncherAction(int id, int labelRes, int keyCode) {
+ this.keyCode = keyCode;
+ accessibilityAction = new AccessibilityAction(id, mLauncher.getString(labelRes));
+ mDelegate = LauncherAccessibilityDelegate.this;
}
- mContext.getStateManager().goToState(NORMAL, true, forSuccessCallback(() -> {
- if (item instanceof WorkspaceItemFactory) {
- WorkspaceItemInfo info = ((WorkspaceItemFactory) item).makeWorkspaceItem(mContext);
- mContext.getModelWriter().addItemToDatabase(info,
- LauncherSettings.Favorites.CONTAINER_DESKTOP,
- screenId, coordinates[0], coordinates[1]);
-
- mContext.bindItems(
- Collections.singletonList(info),
- /* forceAnimateIcons= */ true,
- /* focusFirstItemForAccessibility= */ accessibility);
- announceConfirmation(R.string.item_added_to_workspace);
- } else if (item instanceof PendingAddItemInfo) {
- PendingAddItemInfo info = (PendingAddItemInfo) item;
- Workspace<?> workspace = mContext.getWorkspace();
- workspace.snapToPage(workspace.getPageIndexForScreenId(screenId));
- mContext.addPendingItem(info, LauncherSettings.Favorites.CONTAINER_DESKTOP,
- screenId, coordinates, info.spanX, info.spanY);
- } else if (item instanceof WorkspaceItemInfo) {
- WorkspaceItemInfo info = ((WorkspaceItemInfo) item).clone();
- mContext.getModelWriter().addItemToDatabase(info,
- LauncherSettings.Favorites.CONTAINER_DESKTOP,
- screenId, coordinates[0], coordinates[1]);
- mContext.bindItems(Collections.singletonList(info), true, accessibility);
+
+ /**
+ * Invokes the action for the provided host
+ */
+ public boolean invokeFromKeyboard(View host) {
+ if (host != null && host.getTag() instanceof ItemInfo) {
+ return mDelegate.performAction(
+ host, (ItemInfo) host.getTag(), accessibilityAction.getId(), true);
+ } else {
+ return false;
}
- }));
- return true;
- }
- /**
- * Functionality to move the item {@link ItemInfo} to the workspace
- * @param item item to be moved
- *
- * @return true if the item could be successfully added
- */
- public boolean moveToWorkspace(ItemInfo item) {
- Folder folder = Folder.getOpen(mContext);
- folder.close(true);
- WorkspaceItemInfo info = (WorkspaceItemInfo) item;
- folder.getInfo().remove(info, false);
-
- final int[] coordinates = new int[2];
- final int screenId = findSpaceOnWorkspace(item, coordinates);
- if (screenId == -1) {
- return false;
}
- mContext.getModelWriter().moveItemInDatabase(info,
- LauncherSettings.Favorites.CONTAINER_DESKTOP,
- screenId, coordinates[0], coordinates[1]);
-
- // Bind the item in next frame so that if a new workspace page was created,
- // it will get laid out.
- new Handler().post(() -> {
- mContext.bindItems(Collections.singletonList(item), true);
- announceConfirmation(R.string.item_moved);
- });
- return true;
}
}
diff --git a/src/com/android/launcher3/accessibility/ShortcutMenuAccessibilityDelegate.java b/src/com/android/launcher3/accessibility/ShortcutMenuAccessibilityDelegate.java
index fb847ec9ae..f96afa856b 100644
--- a/src/com/android/launcher3/accessibility/ShortcutMenuAccessibilityDelegate.java
+++ b/src/com/android/launcher3/accessibility/ShortcutMenuAccessibilityDelegate.java
@@ -68,15 +68,12 @@ public class ShortcutMenuAccessibilityDelegate extends LauncherAccessibilityDele
final WorkspaceItemInfo info = ((DeepShortcutView) host.getParent()).getFinalInfo();
final int[] coordinates = new int[2];
final int screenId = findSpaceOnWorkspace(item, coordinates);
- if (screenId == -1) {
- return false;
- }
- mContext.getStateManager().goToState(NORMAL, true, forSuccessCallback(() -> {
- mContext.getModelWriter().addItemToDatabase(info,
+ mLauncher.getStateManager().goToState(NORMAL, true, forSuccessCallback(() -> {
+ mLauncher.getModelWriter().addItemToDatabase(info,
LauncherSettings.Favorites.CONTAINER_DESKTOP,
screenId, coordinates[0], coordinates[1]);
- mContext.bindItems(Collections.singletonList(info), true);
- AbstractFloatingView.closeAllOpenViews(mContext);
+ mLauncher.bindItems(Collections.singletonList(info), true);
+ AbstractFloatingView.closeAllOpenViews(mLauncher);
announceConfirmation(R.string.item_added_to_workspace);
}));
return true;
diff --git a/src/com/android/launcher3/accessibility/WorkspaceAccessibilityHelper.java b/src/com/android/launcher3/accessibility/WorkspaceAccessibilityHelper.java
index a8624dd17d..a331924f22 100644
--- a/src/com/android/launcher3/accessibility/WorkspaceAccessibilityHelper.java
+++ b/src/com/android/launcher3/accessibility/WorkspaceAccessibilityHelper.java
@@ -22,7 +22,7 @@ import android.view.View;
import com.android.launcher3.CellLayout;
import com.android.launcher3.R;
-import com.android.launcher3.accessibility.BaseAccessibilityDelegate.DragType;
+import com.android.launcher3.accessibility.LauncherAccessibilityDelegate.DragType;
import com.android.launcher3.model.data.AppInfo;
import com.android.launcher3.model.data.FolderInfo;
import com.android.launcher3.model.data.ItemInfo;
diff --git a/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java b/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java
deleted file mode 100644
index 53a6fd7edb..0000000000
--- a/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java
+++ /dev/null
@@ -1,306 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.launcher3.allapps;
-
-import android.content.Context;
-import android.content.Intent;
-import android.util.AttributeSet;
-import android.view.KeyEvent;
-import android.view.MotionEvent;
-import android.view.View;
-import android.widget.RelativeLayout;
-
-import androidx.core.graphics.ColorUtils;
-import androidx.recyclerview.widget.RecyclerView;
-
-import com.android.launcher3.DeviceProfile.DeviceProfileListenable;
-import com.android.launcher3.R;
-import com.android.launcher3.Utilities;
-import com.android.launcher3.allapps.BaseAllAppsAdapter.AdapterItem;
-import com.android.launcher3.allapps.search.SearchAdapterProvider;
-import com.android.launcher3.config.FeatureFlags;
-import com.android.launcher3.util.PackageManagerHelper;
-import com.android.launcher3.views.AppLauncher;
-
-import java.util.ArrayList;
-import java.util.Objects;
-
-/**
- * All apps container view with search support for use in a dragging activity.
- *
- * @param <T> Type of context inflating all apps.
- */
-public class ActivityAllAppsContainerView<T extends Context & AppLauncher
- & DeviceProfileListenable> extends BaseAllAppsContainerView<T> {
-
- protected SearchUiManager mSearchUiManager;
- /**
- * View that defines the search box. Result is rendered inside the recycler view defined in the
- * base class.
- */
- private View mSearchContainer;
- /** {@code true} when rendered view is in search state instead of the scroll state. */
- private boolean mIsSearching;
-
- public ActivityAllAppsContainerView(Context context) {
- this(context, null);
- }
-
- public ActivityAllAppsContainerView(Context context, AttributeSet attrs) {
- this(context, attrs, 0);
- }
-
- public ActivityAllAppsContainerView(Context context, AttributeSet attrs, int defStyleAttr) {
- super(context, attrs, defStyleAttr);
- }
-
- public SearchUiManager getSearchUiManager() {
- return mSearchUiManager;
- }
-
- public View getSearchView() {
- return mSearchContainer;
- }
-
- /** Updates all apps container with the latest search query. */
- public void setLastSearchQuery(String query) {
- Intent marketSearchIntent = PackageManagerHelper.getMarketSearchIntent(
- mActivityContext, query);
- OnClickListener marketSearchClickListener = (v) -> mActivityContext.startActivitySafely(v,
- marketSearchIntent, null);
- for (int i = 0; i < mAH.size(); i++) {
- mAH.get(i).mAdapter.setLastSearchQuery(query, marketSearchClickListener);
- }
- mIsSearching = true;
- rebindAdapters();
- mHeader.setCollapsed(true);
- }
-
- /** Invoke when the current search session is finished. */
- public void onClearSearchResult() {
- mIsSearching = false;
- mHeader.setCollapsed(false);
- rebindAdapters();
- mHeader.reset(false);
- }
-
- /**
- * Sets results list for search
- */
- public void setSearchResults(ArrayList<AdapterItem> results) {
- if (getSearchResultList().setSearchResults(results)) {
- for (int i = 0; i < mAH.size(); i++) {
- if (mAH.get(i).mRecyclerView != null) {
- mAH.get(i).mRecyclerView.onSearchResultsChanged();
- }
- }
- }
- }
-
- @Override
- protected final SearchAdapterProvider<?> createMainAdapterProvider() {
- return mActivityContext.createSearchAdapterProvider(this);
- }
-
- @Override
- public boolean shouldContainerScroll(MotionEvent ev) {
- // IF the MotionEvent is inside the search box, and the container keeps on receiving
- // touch input, container should move down.
- if (mActivityContext.getDragLayer().isEventOverView(mSearchContainer, ev)) {
- return true;
- }
- return super.shouldContainerScroll(ev);
- }
-
- @Override
- public void reset(boolean animate) {
- super.reset(animate);
- // Reset the search bar after transitioning home.
- mSearchUiManager.resetSearch();
- }
-
- @Override
- protected void onFinishInflate() {
- super.onFinishInflate();
- mSearchContainer = findViewById(R.id.search_container_all_apps);
- mSearchUiManager = (SearchUiManager) mSearchContainer;
- mSearchUiManager.initializeSearch(this);
- }
-
- @Override
- public boolean dispatchKeyEvent(KeyEvent event) {
- mSearchUiManager.preDispatchKeyEvent(event);
- return super.dispatchKeyEvent(event);
- }
-
- @Override
- public String getDescription() {
- if (!mUsingTabs && isSearching()) {
- return getContext().getString(R.string.all_apps_search_results);
- } else {
- return super.getDescription();
- }
- }
-
- @Override
- protected boolean shouldShowTabs() {
- return super.shouldShowTabs() && !isSearching();
- }
-
- @Override
- public boolean isSearching() {
- return mIsSearching;
- }
-
- @Override
- protected void rebindAdapters(boolean force) {
- super.rebindAdapters(force);
- if (!FeatureFlags.ENABLE_DEVICE_SEARCH.get()
- || getMainAdapterProvider().getDecorator() == null) {
- return;
- }
-
- RecyclerView.ItemDecoration decoration = getMainAdapterProvider().getDecorator();
- mAH.stream()
- .map(adapterHolder -> adapterHolder.mRecyclerView)
- .filter(Objects::nonNull)
- .forEach(v -> {
- v.removeItemDecoration(decoration); // Remove in case it is already added.
- v.addItemDecoration(decoration);
- });
- }
-
- @Override
- protected View replaceAppsRVContainer(boolean showTabs) {
- View rvContainer = super.replaceAppsRVContainer(showTabs);
-
- removeCustomRules(rvContainer);
- removeCustomRules(getSearchRecyclerView());
- if (FeatureFlags.ENABLE_FLOATING_SEARCH_BAR.get()) {
- alignParentTop(rvContainer, showTabs);
- alignParentTop(getSearchRecyclerView(), /* tabs= */ false);
- layoutAboveSearchContainer(rvContainer);
- layoutAboveSearchContainer(getSearchRecyclerView());
- } else {
- layoutBelowSearchContainer(rvContainer, showTabs);
- layoutBelowSearchContainer(getSearchRecyclerView(), /* tabs= */ false);
- }
-
- return rvContainer;
- }
-
- @Override
- void setupHeader() {
- super.setupHeader();
-
- removeCustomRules(mHeader);
- if (FeatureFlags.ENABLE_FLOATING_SEARCH_BAR.get()) {
- alignParentTop(mHeader, false /* includeTabsMargin */);
- } else {
- layoutBelowSearchContainer(mHeader, false /* includeTabsMargin */);
- }
- }
-
- @Override
- protected void updateHeaderScroll(int scrolledOffset) {
- super.updateHeaderScroll(scrolledOffset);
- if (mSearchUiManager.getEditText() == null) {
- return;
- }
-
- float prog = Utilities.boundToRange((float) scrolledOffset / mHeaderThreshold, 0f, 1f);
- boolean bgVisible = mSearchUiManager.getBackgroundVisibility();
- if (scrolledOffset == 0 && !isSearching()) {
- bgVisible = true;
- } else if (scrolledOffset > mHeaderThreshold) {
- bgVisible = false;
- }
- mSearchUiManager.setBackgroundVisibility(bgVisible, 1 - prog);
- }
-
- @Override
- protected int getHeaderColor(float blendRatio) {
- return ColorUtils.setAlphaComponent(
- super.getHeaderColor(blendRatio),
- (int) (mSearchContainer.getAlpha() * 255));
- }
-
- @Override
- public int getHeaderBottom() {
- if (FeatureFlags.ENABLE_FLOATING_SEARCH_BAR.get()) {
- return super.getHeaderBottom();
- }
- return super.getHeaderBottom() + mSearchContainer.getBottom();
- }
-
- private void layoutBelowSearchContainer(View v, boolean includeTabsMargin) {
- if (!(v.getLayoutParams() instanceof RelativeLayout.LayoutParams)) {
- return;
- }
-
- RelativeLayout.LayoutParams layoutParams = (LayoutParams) v.getLayoutParams();
- layoutParams.addRule(RelativeLayout.ALIGN_TOP, R.id.search_container_all_apps);
-
- int topMargin = getContext().getResources().getDimensionPixelSize(
- R.dimen.all_apps_header_top_margin);
- if (includeTabsMargin) {
- topMargin += getContext().getResources().getDimensionPixelSize(
- R.dimen.all_apps_header_pill_height);
- }
- layoutParams.topMargin = topMargin;
- }
-
- private void layoutAboveSearchContainer(View v) {
- if (!(v.getLayoutParams() instanceof RelativeLayout.LayoutParams)) {
- return;
- }
-
- RelativeLayout.LayoutParams layoutParams = (LayoutParams) v.getLayoutParams();
- layoutParams.addRule(RelativeLayout.ABOVE, R.id.search_container_all_apps);
- }
-
- private void alignParentTop(View v, boolean includeTabsMargin) {
- if (!(v.getLayoutParams() instanceof RelativeLayout.LayoutParams)) {
- return;
- }
-
- RelativeLayout.LayoutParams layoutParams = (LayoutParams) v.getLayoutParams();
- layoutParams.addRule(RelativeLayout.ALIGN_PARENT_TOP);
- layoutParams.topMargin =
- includeTabsMargin
- ? getContext().getResources().getDimensionPixelSize(
- R.dimen.all_apps_header_pill_height)
- : 0;
- }
-
- private void removeCustomRules(View v) {
- if (!(v.getLayoutParams() instanceof RelativeLayout.LayoutParams)) {
- return;
- }
-
- RelativeLayout.LayoutParams layoutParams = (LayoutParams) v.getLayoutParams();
- layoutParams.removeRule(RelativeLayout.ABOVE);
- layoutParams.removeRule(RelativeLayout.ALIGN_TOP);
- layoutParams.removeRule(RelativeLayout.ALIGN_PARENT_TOP);
- }
-
- @Override
- protected BaseAllAppsAdapter<T> createAdapter(AlphabeticalAppsList<T> appsList,
- BaseAdapterProvider[] adapterProviders) {
- return new AllAppsGridAdapter<>(mActivityContext, getLayoutInflater(), appsList,
- adapterProviders);
- }
-}
diff --git a/src/com/android/launcher3/allapps/AllAppsContainerView.java b/src/com/android/launcher3/allapps/AllAppsContainerView.java
new file mode 100644
index 0000000000..f420ec2f08
--- /dev/null
+++ b/src/com/android/launcher3/allapps/AllAppsContainerView.java
@@ -0,0 +1,820 @@
+/*
+ * Copyright (C) 2015 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.launcher3.allapps;
+
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ALLAPPS_TAP_ON_PERSONAL_TAB;
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ALLAPPS_TAP_ON_WORK_TAB;
+import static com.android.launcher3.model.BgDataModel.Callbacks.FLAG_HAS_SHORTCUT_PERMISSION;
+import static com.android.launcher3.model.BgDataModel.Callbacks.FLAG_QUIET_MODE_CHANGE_PERMISSION;
+import static com.android.launcher3.model.BgDataModel.Callbacks.FLAG_QUIET_MODE_ENABLED;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ValueAnimator;
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.Point;
+import android.graphics.Rect;
+import android.os.Bundle;
+import android.os.Parcelable;
+import android.os.Process;
+import android.text.Selection;
+import android.text.SpannableStringBuilder;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.util.SparseArray;
+import android.view.KeyEvent;
+import android.view.LayoutInflater;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.WindowInsets;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.StringRes;
+import androidx.annotation.VisibleForTesting;
+import androidx.core.graphics.ColorUtils;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.android.launcher3.BaseDraggingActivity;
+import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.DeviceProfile.OnDeviceProfileChangeListener;
+import com.android.launcher3.DragSource;
+import com.android.launcher3.DropTarget.DragObject;
+import com.android.launcher3.Insettable;
+import com.android.launcher3.InsettableFrameLayout;
+import com.android.launcher3.R;
+import com.android.launcher3.Utilities;
+import com.android.launcher3.allapps.search.SearchAdapterProvider;
+import com.android.launcher3.config.FeatureFlags;
+import com.android.launcher3.keyboard.FocusedItemDecorator;
+import com.android.launcher3.model.data.AppInfo;
+import com.android.launcher3.testing.TestProtocol;
+import com.android.launcher3.util.ItemInfoMatcher;
+import com.android.launcher3.util.Themes;
+import com.android.launcher3.views.RecyclerViewFastScroller;
+import com.android.launcher3.views.ScrimView;
+import com.android.launcher3.views.SpringRelativeLayout;
+import com.android.launcher3.workprofile.PersonalWorkSlidingTabStrip.OnActivePageChangedListener;
+
+/**
+ * The all apps view container.
+ */
+public class AllAppsContainerView extends SpringRelativeLayout implements DragSource,
+ Insettable, OnDeviceProfileChangeListener, OnActivePageChangedListener,
+ ScrimView.ScrimDrawingController {
+
+ private static final String BUNDLE_KEY_CURRENT_PAGE = "launcher.allapps.current_page";
+
+ public static final float PULL_MULTIPLIER = .02f;
+ public static final float FLING_VELOCITY_MULTIPLIER = 1200f;
+
+ private final Paint mHeaderPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+
+ protected final BaseDraggingActivity mLauncher;
+ protected final AdapterHolder[] mAH;
+ private final ItemInfoMatcher mPersonalMatcher = ItemInfoMatcher.ofUser(Process.myUserHandle());
+ private final ItemInfoMatcher mWorkMatcher = mPersonalMatcher.negate();
+ private final AllAppsStore mAllAppsStore = new AllAppsStore();
+
+ private final RecyclerView.OnScrollListener mScrollListener =
+ new RecyclerView.OnScrollListener() {
+ @Override
+ public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
+ updateHeaderScroll(((AllAppsRecyclerView) recyclerView).getCurrentScrollY());
+ }
+ };
+
+ private final Paint mNavBarScrimPaint;
+ private int mNavBarScrimHeight = 0;
+
+ protected SearchUiManager mSearchUiManager;
+ private View mSearchContainer;
+ private AllAppsPagedView mViewPager;
+
+ protected FloatingHeaderView mHeader;
+ private float mHeaderTop;
+ private WorkModeSwitch mWorkModeSwitch;
+
+
+ private SpannableStringBuilder mSearchQueryBuilder = null;
+
+ protected boolean mUsingTabs;
+ private boolean mSearchModeWhileUsingTabs = false;
+
+ protected RecyclerViewFastScroller mTouchHandler;
+ protected final Point mFastScrollerOffset = new Point();
+
+ private Rect mInsets = new Rect();
+
+ private SearchAdapterProvider mSearchAdapterProvider;
+ private WorkAdapterProvider mWorkAdapterProvider;
+ private final int mScrimColor;
+ private final int mHeaderProtectionColor;
+ private final float mHeaderThreshold;
+ private ScrimView mScrimView;
+ private int mHeaderColor;
+
+ public AllAppsContainerView(Context context) {
+ this(context, null);
+ }
+
+ public AllAppsContainerView(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public AllAppsContainerView(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+
+ mLauncher = BaseDraggingActivity.fromContext(context);
+
+ mScrimColor = Themes.getAttrColor(context, R.attr.allAppsScrimColor);
+ mHeaderThreshold = getResources().getDimensionPixelSize(
+ R.dimen.dynamic_grid_cell_border_spacing);
+ mHeaderProtectionColor = Themes.getAttrColor(context, R.attr.allappsHeaderProtectionColor);
+
+ mLauncher.addOnDeviceProfileChangeListener(this);
+
+ mSearchAdapterProvider = mLauncher.createSearchAdapterProvider(this);
+ mSearchQueryBuilder = new SpannableStringBuilder();
+ Selection.setSelection(mSearchQueryBuilder, 0);
+
+ mAH = new AdapterHolder[2];
+ mWorkAdapterProvider = new WorkAdapterProvider(mLauncher, () -> {
+ if (mAH[AdapterHolder.WORK] != null) {
+ mAH[AdapterHolder.WORK].appsList.updateAdapterItems();
+ }
+ });
+ mAH[AdapterHolder.MAIN] = new AdapterHolder(false /* isWork */);
+ mAH[AdapterHolder.WORK] = new AdapterHolder(true /* isWork */);
+
+ mNavBarScrimPaint = new Paint();
+ mNavBarScrimPaint.setColor(Themes.getAttrColor(context, R.attr.allAppsNavBarScrimColor));
+
+ mAllAppsStore.addUpdateListener(this::onAppsUpdated);
+ }
+
+ @Override
+ protected void dispatchRestoreInstanceState(SparseArray<Parcelable> sparseArray) {
+ try {
+ // Many slice view id is not properly assigned, and hence throws null
+ // pointer exception in the underneath method. Catching the exception
+ // simply doesn't restore these slice views. This doesn't have any
+ // user visible effect because because we query them again.
+ super.dispatchRestoreInstanceState(sparseArray);
+ } catch (Exception e) {
+ Log.e("AllAppsContainerView", "restoreInstanceState viewId = 0", e);
+ }
+
+ Bundle state = (Bundle) sparseArray.get(R.id.work_tab_state_id, null);
+ if (state != null) {
+ int currentPage = state.getInt(BUNDLE_KEY_CURRENT_PAGE, 0);
+ if (currentPage != 0 && mViewPager != null) {
+ mViewPager.setCurrentPage(currentPage);
+ rebindAdapters(true);
+ } else {
+ reset(true);
+ }
+ }
+
+ }
+
+ @Override
+ protected void dispatchSaveInstanceState(SparseArray<Parcelable> container) {
+ super.dispatchSaveInstanceState(container);
+ Bundle state = new Bundle();
+ state.putInt(BUNDLE_KEY_CURRENT_PAGE, getCurrentPage());
+ container.put(R.id.work_tab_state_id, state);
+ }
+
+ /**
+ * Sets the long click listener for icons
+ */
+ public void setOnIconLongClickListener(OnLongClickListener listener) {
+ for (AdapterHolder holder : mAH) {
+ holder.adapter.setOnIconLongClickListener(listener);
+ }
+ }
+
+ public AllAppsStore getAppsStore() {
+ return mAllAppsStore;
+ }
+
+ public WorkModeSwitch getWorkModeSwitch() {
+ return mWorkModeSwitch;
+ }
+
+ @Override
+ public void onDeviceProfileChanged(DeviceProfile dp) {
+ for (AdapterHolder holder : mAH) {
+ holder.adapter.setAppsPerRow(dp.numShownAllAppsColumns);
+ if (holder.recyclerView != null) {
+ // Remove all views and clear the pool, while keeping the data same. After this
+ // call, all the viewHolders will be recreated.
+ holder.recyclerView.swapAdapter(holder.recyclerView.getAdapter(), true);
+ holder.recyclerView.getRecycledViewPool().clear();
+ }
+ }
+ }
+
+ private void onAppsUpdated() {
+ boolean hasWorkApps = false;
+ for (AppInfo app : mAllAppsStore.getApps()) {
+ if (mWorkMatcher.matches(app, null)) {
+ hasWorkApps = true;
+ break;
+ }
+ }
+ if (!mAH[AdapterHolder.MAIN].appsList.hasFilter()) {
+ rebindAdapters(hasWorkApps);
+ if (hasWorkApps) {
+ resetWorkProfile();
+ }
+ }
+ }
+
+ private void resetWorkProfile() {
+ boolean isEnabled = !mAllAppsStore.hasModelFlag(FLAG_QUIET_MODE_ENABLED);
+ if (mWorkModeSwitch != null) {
+ mWorkModeSwitch.updateCurrentState(isEnabled);
+ }
+ mWorkAdapterProvider.updateCurrentState(isEnabled);
+ }
+
+ /**
+ * Returns whether the view itself will handle the touch event or not.
+ */
+ public boolean shouldContainerScroll(MotionEvent ev) {
+ // IF the MotionEvent is inside the search box, and the container keeps on receiving
+ // touch input, container should move down.
+ if (mLauncher.getDragLayer().isEventOverView(mSearchContainer, ev)) {
+ return true;
+ }
+ AllAppsRecyclerView rv = getActiveRecyclerView();
+ if (rv == null) {
+ return true;
+ }
+ if (rv.getScrollbar().getThumbOffsetY() >= 0 &&
+ mLauncher.getDragLayer().isEventOverView(rv.getScrollbar(), ev)) {
+ return false;
+ }
+ return rv.shouldContainerScroll(ev, mLauncher.getDragLayer());
+ }
+
+ @Override
+ public boolean onInterceptTouchEvent(MotionEvent ev) {
+ if (ev.getAction() == MotionEvent.ACTION_DOWN) {
+ AllAppsRecyclerView rv = getActiveRecyclerView();
+ if (rv != null &&
+ rv.getScrollbar().isHitInParent(ev.getX(), ev.getY(), mFastScrollerOffset)) {
+ mTouchHandler = rv.getScrollbar();
+ } else {
+ mTouchHandler = null;
+ }
+ }
+ if (mTouchHandler != null) {
+ return mTouchHandler.handleTouchEvent(ev, mFastScrollerOffset);
+ }
+ return false;
+ }
+
+ @Override
+ public boolean onTouchEvent(MotionEvent ev) {
+ if (ev.getAction() == MotionEvent.ACTION_DOWN) {
+ AllAppsRecyclerView rv = getActiveRecyclerView();
+ if (rv != null && rv.getScrollbar().isHitInParent(ev.getX(), ev.getY(),
+ mFastScrollerOffset)) {
+ mTouchHandler = rv.getScrollbar();
+ } else {
+ mTouchHandler = null;
+
+ }
+ }
+ if (mTouchHandler != null) {
+ mTouchHandler.handleTouchEvent(ev, mFastScrollerOffset);
+ return true;
+ }
+ return false;
+ }
+
+ public String getDescription() {
+ @StringRes int descriptionRes;
+ if (mUsingTabs) {
+ descriptionRes =
+ mViewPager.getNextPage() == 0
+ ? R.string.all_apps_button_personal_label
+ : R.string.all_apps_button_work_label;
+ } else {
+ descriptionRes = R.string.all_apps_button_label;
+ }
+ return getContext().getString(descriptionRes);
+ }
+
+ public AllAppsRecyclerView getActiveRecyclerView() {
+ if (!mUsingTabs || mViewPager.getNextPage() == 0) {
+ return mAH[AdapterHolder.MAIN].recyclerView;
+ } else {
+ return mAH[AdapterHolder.WORK].recyclerView;
+ }
+ }
+
+ public LayoutInflater getLayoutInflater() {
+ return LayoutInflater.from(getContext());
+ }
+
+ /**
+ * Resets the state of AllApps.
+ */
+ public void reset(boolean animate) {
+ for (int i = 0; i < mAH.length; i++) {
+ if (mAH[i].recyclerView != null) {
+ mAH[i].recyclerView.scrollToTop();
+ }
+ }
+ if (isHeaderVisible()) {
+ mHeader.reset(animate);
+ }
+ // Reset the search bar and base recycler view after transitioning home
+ mSearchUiManager.resetSearch();
+ updateHeaderScroll(0);
+ }
+
+ @Override
+ protected void onFinishInflate() {
+ super.onFinishInflate();
+
+ // This is a focus listener that proxies focus from a view into the list view. This is to
+ // work around the search box from getting first focus and showing the cursor.
+ setOnFocusChangeListener((v, hasFocus) -> {
+ if (hasFocus && getActiveRecyclerView() != null) {
+ getActiveRecyclerView().requestFocus();
+ }
+ });
+
+ mHeader = findViewById(R.id.all_apps_header);
+ rebindAdapters(mUsingTabs, true /* force */);
+
+ mSearchContainer = findViewById(R.id.search_container_all_apps);
+ mSearchUiManager = (SearchUiManager) mSearchContainer;
+ mSearchUiManager.initializeSearch(this);
+ }
+
+ public SearchUiManager getSearchUiManager() {
+ return mSearchUiManager;
+ }
+
+ @Override
+ public boolean dispatchKeyEvent(KeyEvent event) {
+ mSearchUiManager.preDispatchKeyEvent(event);
+ return super.dispatchKeyEvent(event);
+ }
+
+ @Override
+ public void onDropCompleted(View target, DragObject d, boolean success) {
+ }
+
+ @Override
+ public void setInsets(Rect insets) {
+ mInsets.set(insets);
+ DeviceProfile grid = mLauncher.getDeviceProfile();
+ int leftRightPadding = grid.desiredWorkspaceLeftRightMarginPx
+ + grid.cellLayoutPaddingLeftRightPx;
+
+ for (int i = 0; i < mAH.length; i++) {
+ mAH[i].padding.bottom = insets.bottom;
+ mAH[i].padding.left = mAH[i].padding.right = leftRightPadding;
+ mAH[i].applyPadding();
+ }
+
+ ViewGroup.MarginLayoutParams mlp = (MarginLayoutParams) getLayoutParams();
+ mlp.leftMargin = insets.left;
+ mlp.rightMargin = insets.right;
+ setLayoutParams(mlp);
+
+ if (grid.isVerticalBarLayout()) {
+ setPadding(grid.workspacePadding.left, 0, grid.workspacePadding.right, 0);
+ } else {
+ setPadding(0, 0, 0, 0);
+ }
+
+ InsettableFrameLayout.dispatchInsets(this, insets);
+ }
+
+ @Override
+ public WindowInsets dispatchApplyWindowInsets(WindowInsets insets) {
+ if (Utilities.ATLEAST_Q) {
+ mNavBarScrimHeight = insets.getTappableElementInsets().bottom
+ - mLauncher.getDeviceProfile().nonOverlappingTaskbarInset;
+ } else {
+ mNavBarScrimHeight = insets.getStableInsetBottom();
+ }
+ return super.dispatchApplyWindowInsets(insets);
+ }
+
+ @Override
+ protected void dispatchDraw(Canvas canvas) {
+ super.dispatchDraw(canvas);
+
+ if (mNavBarScrimHeight > 0) {
+ canvas.drawRect(0, getHeight() - mNavBarScrimHeight, getWidth(), getHeight(),
+ mNavBarScrimPaint);
+ }
+ }
+
+ private void rebindAdapters(boolean showTabs) {
+ rebindAdapters(showTabs, false /* force */);
+ }
+
+ protected void rebindAdapters(boolean showTabs, boolean force) {
+ if (showTabs == mUsingTabs && !force) {
+ return;
+ }
+ replaceRVContainer(showTabs);
+ mUsingTabs = showTabs;
+
+ mAllAppsStore.unregisterIconContainer(mAH[AdapterHolder.MAIN].recyclerView);
+ mAllAppsStore.unregisterIconContainer(mAH[AdapterHolder.WORK].recyclerView);
+
+ if (mUsingTabs) {
+ setupWorkToggle();
+ mAH[AdapterHolder.MAIN].setup(mViewPager.getChildAt(0), mPersonalMatcher);
+ mAH[AdapterHolder.WORK].setup(mViewPager.getChildAt(1), mWorkMatcher);
+ mAH[AdapterHolder.WORK].recyclerView.setId(R.id.apps_list_view_work);
+ mViewPager.getPageIndicator().setActiveMarker(AdapterHolder.MAIN);
+ findViewById(R.id.tab_personal)
+ .setOnClickListener((View view) -> {
+ if (mViewPager.snapToPage(AdapterHolder.MAIN)) {
+ mLauncher.getStatsLogManager().logger()
+ .log(LAUNCHER_ALLAPPS_TAP_ON_PERSONAL_TAB);
+ }
+ });
+ findViewById(R.id.tab_work)
+ .setOnClickListener((View view) -> {
+ if (mViewPager.snapToPage(AdapterHolder.WORK)) {
+ mLauncher.getStatsLogManager().logger()
+ .log(LAUNCHER_ALLAPPS_TAP_ON_WORK_TAB);
+ }
+ });
+ onActivePageChanged(mViewPager.getNextPage());
+ } else {
+ mAH[AdapterHolder.MAIN].setup(findViewById(R.id.apps_list_view), null);
+ mAH[AdapterHolder.WORK].recyclerView = null;
+ }
+ setupHeader();
+
+ mAllAppsStore.registerIconContainer(mAH[AdapterHolder.MAIN].recyclerView);
+ mAllAppsStore.registerIconContainer(mAH[AdapterHolder.WORK].recyclerView);
+ }
+
+ private void setupWorkToggle() {
+ if (Utilities.ATLEAST_P) {
+ mWorkModeSwitch = (WorkModeSwitch) mLauncher.getLayoutInflater().inflate(
+ R.layout.work_mode_fab, this, false);
+ this.addView(mWorkModeSwitch);
+ mWorkModeSwitch.setInsets(mInsets);
+ mWorkModeSwitch.post(() -> {
+ mAH[AdapterHolder.WORK].applyPadding();
+ resetWorkProfile();
+ });
+ }
+ }
+
+ private void replaceRVContainer(boolean showTabs) {
+ for (int i = 0; i < mAH.length; i++) {
+ AllAppsRecyclerView rv = mAH[i].recyclerView;
+ if (rv != null) {
+ rv.setLayoutManager(null);
+ rv.setAdapter(null);
+ }
+ }
+ View oldView = getRecyclerViewContainer();
+ int index = indexOfChild(oldView);
+ removeView(oldView);
+ int layout = showTabs ? R.layout.all_apps_tabs : R.layout.all_apps_rv_layout;
+ View newView = getLayoutInflater().inflate(layout, this, false);
+ addView(newView, index);
+ if (TestProtocol.sDebugTracing) {
+ Log.d(TestProtocol.WORK_PROFILE_REMOVED, "should show tabs:" + showTabs,
+ new Exception());
+ }
+ if (showTabs) {
+ mViewPager = (AllAppsPagedView) newView;
+ mViewPager.initParentViews(this);
+ mViewPager.getPageIndicator().setOnActivePageChangedListener(this);
+ } else {
+ mViewPager = null;
+ }
+ }
+
+ public View getRecyclerViewContainer() {
+ return mViewPager != null ? mViewPager : findViewById(R.id.apps_list_view);
+ }
+
+ @Override
+ public void onActivePageChanged(int currentActivePage) {
+ mHeader.setMainActive(currentActivePage == AdapterHolder.MAIN);
+ if (mAH[currentActivePage].recyclerView != null) {
+ mAH[currentActivePage].recyclerView.bindFastScrollbar();
+ }
+ reset(true /* animate */);
+ if (mWorkModeSwitch != null) {
+ mWorkModeSwitch.setWorkTabVisible(currentActivePage == AdapterHolder.WORK
+ && mAllAppsStore.hasModelFlag(
+ FLAG_HAS_SHORTCUT_PERMISSION | FLAG_QUIET_MODE_CHANGE_PERMISSION));
+
+ if (currentActivePage == AdapterHolder.WORK) {
+ if (mWorkModeSwitch.getParent() == null) {
+ addView(mWorkModeSwitch);
+ }
+ } else {
+ removeView(mWorkModeSwitch);
+ }
+ }
+ }
+
+ // Used by tests only
+ private boolean isDescendantViewVisible(int viewId) {
+ final View view = findViewById(viewId);
+ if (view == null) return false;
+
+ if (!view.isShown()) return false;
+
+ return view.getGlobalVisibleRect(new Rect());
+ }
+
+ @VisibleForTesting
+ public boolean isPersonalTabVisible() {
+ return isDescendantViewVisible(R.id.tab_personal);
+ }
+
+ // Used by tests only
+ public boolean isWorkTabVisible() {
+ return isDescendantViewVisible(R.id.tab_work);
+ }
+
+ public AlphabeticalAppsList getApps() {
+ return mAH[AdapterHolder.MAIN].appsList;
+ }
+
+ public FloatingHeaderView getFloatingHeaderView() {
+ return mHeader;
+ }
+
+ public View getSearchView() {
+ return mSearchContainer;
+ }
+
+ public View getContentView() {
+ return mViewPager == null ? getActiveRecyclerView() : mViewPager;
+ }
+
+ public int getCurrentPage() {
+ return mViewPager != null ? mViewPager.getCurrentPage() : AdapterHolder.MAIN;
+ }
+
+ /**
+ * Handles selection on focused view and returns success
+ */
+ public boolean launchHighlightedItem() {
+ if (mSearchAdapterProvider == null) return false;
+ return mSearchAdapterProvider.launchHighlightedItem();
+ }
+
+ public SearchAdapterProvider getSearchAdapterProvider() {
+ return mSearchAdapterProvider;
+ }
+
+ public RecyclerViewFastScroller getScrollBar() {
+ AllAppsRecyclerView rv = getActiveRecyclerView();
+ return rv == null ? null : rv.getScrollbar();
+ }
+
+ public void setupHeader() {
+ mHeader.setVisibility(View.VISIBLE);
+ mHeader.setup(mAH, mAH[AllAppsContainerView.AdapterHolder.WORK].recyclerView == null);
+
+ int padding = mHeader.getMaxTranslation();
+ for (int i = 0; i < mAH.length; i++) {
+ mAH[i].padding.top = padding;
+ mAH[i].applyPadding();
+ }
+ mHeaderTop = mHeader.getTop();
+ }
+
+ public void setLastSearchQuery(String query) {
+ for (int i = 0; i < mAH.length; i++) {
+ mAH[i].adapter.setLastSearchQuery(query);
+ }
+ if (mUsingTabs) {
+ mSearchModeWhileUsingTabs = true;
+ rebindAdapters(false); // hide tabs
+ }
+ mHeader.setCollapsed(true);
+ }
+
+ public void onClearSearchResult() {
+ if (mSearchModeWhileUsingTabs) {
+ rebindAdapters(true); // show tabs
+ mSearchModeWhileUsingTabs = false;
+ }
+ }
+
+ public void onSearchResultsChanged() {
+ for (int i = 0; i < mAH.length; i++) {
+ if (mAH[i].recyclerView != null) {
+ mAH[i].recyclerView.onSearchResultsChanged();
+ }
+ }
+ }
+
+ public void setRecyclerViewVerticalFadingEdgeEnabled(boolean enabled) {
+ for (int i = 0; i < mAH.length; i++) {
+ mAH[i].applyVerticalFadingEdgeEnabled(enabled);
+ }
+ }
+
+ public void addElevationController(RecyclerView.OnScrollListener scrollListener) {
+ if (!mUsingTabs) {
+ mAH[AdapterHolder.MAIN].recyclerView.addOnScrollListener(scrollListener);
+ }
+ }
+
+ public boolean isHeaderVisible() {
+ return mHeader != null && mHeader.getVisibility() == View.VISIBLE;
+ }
+
+ /**
+ * Adds an update listener to {@param animator} that adds springs to the animation.
+ */
+ public void addSpringFromFlingUpdateListener(ValueAnimator animator,
+ float velocity /* release velocity */,
+ float progress /* portion of the distance to travel*/) {
+ animator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationStart(Animator animator) {
+ float distance = (float) ((1 - progress) * getHeight()); // px
+ float settleVelocity = Math.min(0, distance
+ / (AllAppsTransitionController.INTERP_COEFF * animator.getDuration())
+ + velocity);
+ absorbSwipeUpVelocity(Math.max(1000, Math.abs(
+ Math.round(settleVelocity * FLING_VELOCITY_MULTIPLIER))));
+ }
+ });
+ }
+
+ public void onPull(float deltaDistance, float displacement) {
+ absorbPullDeltaDistance(PULL_MULTIPLIER * deltaDistance, PULL_MULTIPLIER * displacement);
+ // Current motion spec is to actually push and not pull
+ // on this surface. However, until EdgeEffect.onPush (b/190612804) is
+ // implemented at view level, we will simply pull
+ }
+
+ @Override
+ public void getDrawingRect(Rect outRect) {
+ super.getDrawingRect(outRect);
+ outRect.offset(0, (int) getTranslationY());
+ }
+
+ @Override
+ public void setTranslationY(float translationY) {
+ super.setTranslationY(translationY);
+ invalidateHeader();
+ }
+
+ public void setScrimView(ScrimView scrimView) {
+ mScrimView = scrimView;
+ }
+
+ @Override
+ public void drawOnScrim(Canvas canvas) {
+ mHeaderPaint.setColor(mHeaderColor);
+ mHeaderPaint.setAlpha((int) (getAlpha() * Color.alpha(mHeaderColor)));
+ if (mHeaderPaint.getColor() != mScrimColor && mHeaderPaint.getColor() != 0) {
+ int bottom = mUsingTabs && mHeader.mHeaderCollapsed ? mHeader.getVisibleBottomBound()
+ : mSearchContainer.getBottom();
+ canvas.drawRect(0, 0, canvas.getWidth(), bottom + getTranslationY(),
+ mHeaderPaint);
+
+ if (FeatureFlags.ENABLE_DEVICE_SEARCH.get() && getTranslationY() == 0) {
+ mSearchUiManager.getEditText().setBackground(null);
+ }
+ }
+ }
+
+ public class AdapterHolder {
+ public static final int MAIN = 0;
+ public static final int WORK = 1;
+
+ private ItemInfoMatcher mInfoMatcher;
+ private final boolean mIsWork;
+ public final AllAppsGridAdapter adapter;
+ final LinearLayoutManager layoutManager;
+ final AlphabeticalAppsList appsList;
+ final Rect padding = new Rect();
+ AllAppsRecyclerView recyclerView;
+ boolean verticalFadingEdge;
+ private View mOverlay;
+
+ boolean mWorkDisabled;
+
+ AdapterHolder(boolean isWork) {
+ mIsWork = isWork;
+ appsList = new AlphabeticalAppsList(mLauncher, mAllAppsStore,
+ isWork ? mWorkAdapterProvider : null);
+
+ BaseAdapterProvider[] adapterProviders =
+ isWork ? new BaseAdapterProvider[]{mSearchAdapterProvider, mWorkAdapterProvider}
+ : new BaseAdapterProvider[]{mSearchAdapterProvider};
+
+ adapter = new AllAppsGridAdapter(mLauncher, getLayoutInflater(), appsList,
+ adapterProviders);
+ appsList.setAdapter(adapter);
+ layoutManager = adapter.getLayoutManager();
+ }
+
+ void setup(@NonNull View rv, @Nullable ItemInfoMatcher matcher) {
+ mInfoMatcher = matcher;
+ appsList.updateItemFilter(matcher);
+ recyclerView = (AllAppsRecyclerView) rv;
+ recyclerView.setEdgeEffectFactory(createEdgeEffectFactory());
+ recyclerView.setApps(appsList);
+ recyclerView.setLayoutManager(layoutManager);
+ recyclerView.setAdapter(adapter);
+ recyclerView.setHasFixedSize(true);
+ // No animations will occur when changes occur to the items in this RecyclerView.
+ recyclerView.setItemAnimator(null);
+ recyclerView.addOnScrollListener(mScrollListener);
+ FocusedItemDecorator focusedItemDecorator = new FocusedItemDecorator(recyclerView);
+ recyclerView.addItemDecoration(focusedItemDecorator);
+ adapter.setIconFocusListener(focusedItemDecorator.getFocusListener());
+ applyVerticalFadingEdgeEnabled(verticalFadingEdge);
+ applyPadding();
+ if (FeatureFlags.ENABLE_DEVICE_SEARCH.get()) {
+ recyclerView.addItemDecoration(mSearchAdapterProvider.getDecorator());
+ }
+ }
+
+ void applyPadding() {
+ if (recyclerView != null) {
+ Resources res = getResources();
+ int switchH = res.getDimensionPixelSize(R.dimen.work_profile_footer_padding) * 2
+ + mInsets.bottom + Utilities.calculateTextHeight(
+ res.getDimension(R.dimen.work_profile_footer_text_size));
+
+ int bottomOffset = mWorkModeSwitch != null && mIsWork ? switchH : 0;
+ recyclerView.setPadding(padding.left, padding.top, padding.right,
+ padding.bottom + bottomOffset);
+ }
+ }
+
+ public void applyVerticalFadingEdgeEnabled(boolean enabled) {
+ verticalFadingEdge = enabled;
+ mAH[AdapterHolder.MAIN].recyclerView.setVerticalFadingEdgeEnabled(!mUsingTabs
+ && verticalFadingEdge);
+ }
+ }
+
+
+ protected void updateHeaderScroll(int scrolledOffset) {
+ float prog = Math.max(0, Math.min(1, (float) scrolledOffset / mHeaderThreshold));
+ int viewBG = ColorUtils.blendARGB(mScrimColor, mHeaderProtectionColor, prog);
+ int headerColor = ColorUtils.setAlphaComponent(viewBG,
+ (int) (getSearchView().getAlpha() * 255));
+ if (headerColor != mHeaderColor) {
+ mHeaderColor = headerColor;
+ getSearchView().setBackgroundColor(viewBG);
+ getFloatingHeaderView().setHeaderColor(viewBG);
+ invalidateHeader();
+ if (scrolledOffset == 0 && mSearchUiManager.getEditText() != null) {
+ mSearchUiManager.getEditText().show();
+ }
+ }
+ }
+
+ /**
+ * redraws header protection
+ */
+ public void invalidateHeader() {
+ if (mScrimView != null && FeatureFlags.ENABLE_DEVICE_SEARCH.get()) {
+ mScrimView.invalidate();
+ }
+ }
+}
diff --git a/src/com/android/launcher3/allapps/AllAppsFastScrollHelper.java b/src/com/android/launcher3/allapps/AllAppsFastScrollHelper.java
index 7067fa225b..f97eb28dda 100644
--- a/src/com/android/launcher3/allapps/AllAppsFastScrollHelper.java
+++ b/src/com/android/launcher3/allapps/AllAppsFastScrollHelper.java
@@ -37,10 +37,10 @@ public class AllAppsFastScrollHelper {
* Smooth scrolls the recycler view to the given section.
*/
public void smoothScrollToSection(FastScrollSectionInfo info) {
- if (mTargetFastScrollPosition == info.position) {
+ if (mTargetFastScrollPosition == info.fastScrollToItem.position) {
return;
}
- mTargetFastScrollPosition = info.position;
+ mTargetFastScrollPosition = info.fastScrollToItem.position;
mRv.getLayoutManager().startSmoothScroll(new MyScroller(mTargetFastScrollPosition));
}
diff --git a/src/com/android/launcher3/allapps/AllAppsGridAdapter.java b/src/com/android/launcher3/allapps/AllAppsGridAdapter.java
index 33d2f2b1df..874fe80ef0 100644
--- a/src/com/android/launcher3/allapps/AllAppsGridAdapter.java
+++ b/src/com/android/launcher3/allapps/AllAppsGridAdapter.java
@@ -15,48 +15,148 @@
*/
package com.android.launcher3.allapps;
+import static com.android.launcher3.touch.ItemLongClickListener.INSTANCE_ALL_APPS;
+
import android.content.Context;
+import android.content.Intent;
+import android.content.res.Resources;
+import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.View.OnFocusChangeListener;
+import android.view.View.OnLongClickListener;
import android.view.ViewGroup;
import android.view.accessibility.AccessibilityEvent;
+import android.widget.TextView;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
import androidx.core.view.accessibility.AccessibilityEventCompat;
import androidx.core.view.accessibility.AccessibilityNodeInfoCompat;
import androidx.core.view.accessibility.AccessibilityRecordCompat;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
-import com.android.launcher3.views.ActivityContext;
+import com.android.launcher3.BaseDraggingActivity;
+import com.android.launcher3.BubbleTextView;
+import com.android.launcher3.R;
+import com.android.launcher3.model.data.AppInfo;
+import com.android.launcher3.util.PackageManagerHelper;
+import java.util.Arrays;
import java.util.List;
/**
* The grid view adapter of all the apps.
- *
- * @param <T> Type of context inflating all apps.
*/
-public class AllAppsGridAdapter<T extends Context & ActivityContext> extends
- BaseAllAppsAdapter<T> {
+public class AllAppsGridAdapter extends
+ RecyclerView.Adapter<AllAppsGridAdapter.ViewHolder> {
public static final String TAG = "AppsGridAdapter";
- private final GridLayoutManager mGridLayoutMgr;
- private final GridSpanSizer mGridSizer;
- public AllAppsGridAdapter(T activityContext, LayoutInflater inflater,
- AlphabeticalAppsList apps, BaseAdapterProvider[] adapterProviders) {
- super(activityContext, inflater, apps, adapterProviders);
- mGridSizer = new GridSpanSizer();
- mGridLayoutMgr = new AppsGridLayoutManager(mActivityContext);
- mGridLayoutMgr.setSpanSizeLookup(mGridSizer);
- setAppsPerRow(activityContext.getDeviceProfile().numShownAllAppsColumns);
+ // A normal icon
+ public static final int VIEW_TYPE_ICON = 1 << 1;
+ // The message shown when there are no filtered results
+ public static final int VIEW_TYPE_EMPTY_SEARCH = 1 << 2;
+ // The message to continue to a market search when there are no filtered results
+ public static final int VIEW_TYPE_SEARCH_MARKET = 1 << 3;
+
+ // We use various dividers for various purposes. They share enough attributes to reuse layouts,
+ // but differ in enough attributes to require different view types
+
+ // A divider that separates the apps list and the search market button
+ public static final int VIEW_TYPE_ALL_APPS_DIVIDER = 1 << 4;
+
+ // Common view type masks
+ public static final int VIEW_TYPE_MASK_DIVIDER = VIEW_TYPE_ALL_APPS_DIVIDER;
+ public static final int VIEW_TYPE_MASK_ICON = VIEW_TYPE_ICON;
+
+
+ private final BaseAdapterProvider[] mAdapterProviders;
+
+ /**
+ * ViewHolder for each icon.
+ */
+ public static class ViewHolder extends RecyclerView.ViewHolder {
+
+ public ViewHolder(View v) {
+ super(v);
+ }
}
/**
- * Returns the grid layout manager.
+ * Info about a particular adapter item (can be either section or app)
*/
- public RecyclerView.LayoutManager getLayoutManager() {
- return mGridLayoutMgr;
+ public static class AdapterItem {
+ /** Common properties */
+ // The index of this adapter item in the list
+ public int position;
+ // The type of this item
+ public int viewType;
+
+ /** App-only properties */
+ // The section name of this app. Note that there can be multiple items with different
+ // sectionNames in the same section
+ public String sectionName = null;
+ // The row that this item shows up on
+ public int rowIndex;
+ // The index of this app in the row
+ public int rowAppIndex;
+ // The associated AppInfo for the app
+ public AppInfo appInfo = null;
+ // The index of this app not including sections
+ public int appIndex = -1;
+ // Search section associated to result
+ public DecorationInfo decorationInfo = null;
+
+ /**
+ * Factory method for AppIcon AdapterItem
+ */
+ public static AdapterItem asApp(int pos, String sectionName, AppInfo appInfo,
+ int appIndex) {
+ AdapterItem item = new AdapterItem();
+ item.viewType = VIEW_TYPE_ICON;
+ item.position = pos;
+ item.sectionName = sectionName;
+ item.appInfo = appInfo;
+ item.appIndex = appIndex;
+ return item;
+ }
+
+ /**
+ * Factory method for empty search results view
+ */
+ public static AdapterItem asEmptySearch(int pos) {
+ AdapterItem item = new AdapterItem();
+ item.viewType = VIEW_TYPE_EMPTY_SEARCH;
+ item.position = pos;
+ return item;
+ }
+
+ /**
+ * Factory method for a dividerView in AllAppsSearch
+ */
+ public static AdapterItem asAllAppsDivider(int pos) {
+ AdapterItem item = new AdapterItem();
+ item.viewType = VIEW_TYPE_ALL_APPS_DIVIDER;
+ item.position = pos;
+ return item;
+ }
+
+ /**
+ * Factory method for a market search button
+ */
+ public static AdapterItem asMarketSearch(int pos) {
+ AdapterItem item = new AdapterItem();
+ item.viewType = VIEW_TYPE_SEARCH_MARKET;
+ item.position = pos;
+ return item;
+ }
+
+ protected boolean isCountedForAccessibility() {
+ return viewType == VIEW_TYPE_ICON || viewType == VIEW_TYPE_SEARCH_MARKET;
+ }
}
/**
@@ -116,9 +216,9 @@ public class AllAppsGridAdapter<T extends Context & ActivityContext> extends
*/
private int getRowsNotForAccessibility(int adapterPosition) {
List<AdapterItem> items = mApps.getAdapterItems();
- adapterPosition = Math.max(adapterPosition, items.size() - 1);
+ adapterPosition = Math.max(adapterPosition, mApps.getAdapterItems().size() - 1);
int extraRows = 0;
- for (int i = 0; i <= adapterPosition && i < items.size(); i++) {
+ for (int i = 0; i <= adapterPosition; i++) {
if (!isViewType(items.get(i).viewType, VIEW_TYPE_MASK_ICON)) {
extraRows++;
}
@@ -127,20 +227,6 @@ public class AllAppsGridAdapter<T extends Context & ActivityContext> extends
}
}
- @Override
- public void setAppsPerRow(int appsPerRow) {
- mAppsPerRow = appsPerRow;
- int totalSpans = mAppsPerRow;
- for (BaseAdapterProvider adapterProvider : mAdapterProviders) {
- for (int itemPerRow : adapterProvider.getSupportedItemsPerRowArray()) {
- if (totalSpans % itemPerRow != 0) {
- totalSpans *= itemPerRow;
- }
- }
- }
- mGridLayoutMgr.setSpanCount(totalSpans);
- }
-
/**
* Helper class to size the grid items.
*/
@@ -168,4 +254,190 @@ public class AllAppsGridAdapter<T extends Context & ActivityContext> extends
}
}
}
+
+ private final BaseDraggingActivity mLauncher;
+ private final LayoutInflater mLayoutInflater;
+ private final AlphabeticalAppsList mApps;
+ private final GridLayoutManager mGridLayoutMgr;
+ private final GridSpanSizer mGridSizer;
+
+ private final OnClickListener mOnIconClickListener;
+ private OnLongClickListener mOnIconLongClickListener = INSTANCE_ALL_APPS;
+
+ private int mAppsPerRow;
+
+ private OnFocusChangeListener mIconFocusListener;
+
+ // The text to show when there are no search results and no market search handler.
+ protected String mEmptySearchMessage;
+ // The intent to send off to the market app, updated each time the search query changes.
+ private Intent mMarketSearchIntent;
+
+ public AllAppsGridAdapter(BaseDraggingActivity launcher, LayoutInflater inflater,
+ AlphabeticalAppsList apps, BaseAdapterProvider[] adapterProviders) {
+ Resources res = launcher.getResources();
+ mLauncher = launcher;
+ mApps = apps;
+ mEmptySearchMessage = res.getString(R.string.all_apps_loading_message);
+ mGridSizer = new GridSpanSizer();
+ mGridLayoutMgr = new AppsGridLayoutManager(launcher);
+ mGridLayoutMgr.setSpanSizeLookup(mGridSizer);
+ mLayoutInflater = inflater;
+
+ mOnIconClickListener = launcher.getItemOnClickListener();
+
+ mAdapterProviders = adapterProviders;
+ setAppsPerRow(mLauncher.getDeviceProfile().numShownAllAppsColumns);
+ }
+
+ public void setAppsPerRow(int appsPerRow) {
+ mAppsPerRow = appsPerRow;
+ int totalSpans = mAppsPerRow;
+ for (BaseAdapterProvider adapterProvider : mAdapterProviders) {
+ for (int itemPerRow : adapterProvider.getSupportedItemsPerRowArray()) {
+ if (totalSpans % itemPerRow != 0) {
+ totalSpans *= itemPerRow;
+ }
+ }
+ }
+ mGridLayoutMgr.setSpanCount(totalSpans);
+ }
+
+ /**
+ * Sets the long click listener for icons
+ */
+ public void setOnIconLongClickListener(@Nullable OnLongClickListener listener) {
+ mOnIconLongClickListener = listener;
+ }
+
+ public static boolean isDividerViewType(int viewType) {
+ return isViewType(viewType, VIEW_TYPE_MASK_DIVIDER);
+ }
+
+ public static boolean isIconViewType(int viewType) {
+ return isViewType(viewType, VIEW_TYPE_MASK_ICON);
+ }
+
+ public static boolean isViewType(int viewType, int viewTypeMask) {
+ return (viewType & viewTypeMask) != 0;
+ }
+
+ public void setIconFocusListener(OnFocusChangeListener focusListener) {
+ mIconFocusListener = focusListener;
+ }
+
+ /**
+ * Sets the last search query that was made, used to show when there are no results and to also
+ * seed the intent for searching the market.
+ */
+ public void setLastSearchQuery(String query) {
+ Resources res = mLauncher.getResources();
+ mEmptySearchMessage = res.getString(R.string.all_apps_no_search_results, query);
+ mMarketSearchIntent = PackageManagerHelper.getMarketSearchIntent(mLauncher, query);
+ }
+
+ /**
+ * Returns the grid layout manager.
+ */
+ public GridLayoutManager getLayoutManager() {
+ return mGridLayoutMgr;
+ }
+
+ @Override
+ public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+ switch (viewType) {
+ case VIEW_TYPE_ICON:
+ BubbleTextView icon = (BubbleTextView) mLayoutInflater.inflate(
+ R.layout.all_apps_icon, parent, false);
+ icon.setLongPressTimeoutFactor(1f);
+ icon.setOnFocusChangeListener(mIconFocusListener);
+ icon.setOnClickListener(mOnIconClickListener);
+ icon.setOnLongClickListener(mOnIconLongClickListener);
+ // Ensure the all apps icon height matches the workspace icons in portrait mode.
+ icon.getLayoutParams().height = mLauncher.getDeviceProfile().allAppsCellHeightPx;
+ return new ViewHolder(icon);
+ case VIEW_TYPE_EMPTY_SEARCH:
+ return new ViewHolder(mLayoutInflater.inflate(R.layout.all_apps_empty_search,
+ parent, false));
+ case VIEW_TYPE_SEARCH_MARKET:
+ View searchMarketView = mLayoutInflater.inflate(R.layout.all_apps_search_market,
+ parent, false);
+ searchMarketView.setOnClickListener(v -> mLauncher.startActivitySafely(
+ v, mMarketSearchIntent, null));
+ return new ViewHolder(searchMarketView);
+ case VIEW_TYPE_ALL_APPS_DIVIDER:
+ return new ViewHolder(mLayoutInflater.inflate(
+ R.layout.all_apps_divider, parent, false));
+ default:
+ BaseAdapterProvider adapterProvider = getAdapterProvider(viewType);
+ if (adapterProvider != null) {
+ return adapterProvider.onCreateViewHolder(mLayoutInflater, parent, viewType);
+ }
+ throw new RuntimeException("Unexpected view type");
+ }
+ }
+
+ @Override
+ public void onBindViewHolder(ViewHolder holder, int position) {
+ switch (holder.getItemViewType()) {
+ case VIEW_TYPE_ICON:
+ AdapterItem adapterItem = mApps.getAdapterItems().get(position);
+ AppInfo info = adapterItem.appInfo;
+ BubbleTextView icon = (BubbleTextView) holder.itemView;
+ icon.reset();
+ icon.applyFromApplicationInfo(info);
+ break;
+ case VIEW_TYPE_EMPTY_SEARCH:
+ TextView emptyViewText = (TextView) holder.itemView;
+ emptyViewText.setText(mEmptySearchMessage);
+ emptyViewText.setGravity(mApps.hasNoFilteredResults() ? Gravity.CENTER :
+ Gravity.START | Gravity.CENTER_VERTICAL);
+ break;
+ case VIEW_TYPE_SEARCH_MARKET:
+ TextView searchView = (TextView) holder.itemView;
+ if (mMarketSearchIntent != null) {
+ searchView.setVisibility(View.VISIBLE);
+ } else {
+ searchView.setVisibility(View.GONE);
+ }
+ break;
+ case VIEW_TYPE_ALL_APPS_DIVIDER:
+ // nothing to do
+ break;
+ default:
+ BaseAdapterProvider adapterProvider = getAdapterProvider(holder.getItemViewType());
+ if (adapterProvider != null) {
+ adapterProvider.onBindView(holder, position);
+ }
+ }
+ }
+
+ @Override
+ public void onViewRecycled(@NonNull ViewHolder holder) {
+ super.onViewRecycled(holder);
+ }
+
+ @Override
+ public boolean onFailedToRecycleView(ViewHolder holder) {
+ // Always recycle and we will reset the view when it is bound
+ return true;
+ }
+
+ @Override
+ public int getItemCount() {
+ return mApps.getAdapterItems().size();
+ }
+
+ @Override
+ public int getItemViewType(int position) {
+ AdapterItem item = mApps.getAdapterItems().get(position);
+ return item.viewType;
+ }
+
+ @Nullable
+ private BaseAdapterProvider getAdapterProvider(int viewType) {
+ return Arrays.stream(mAdapterProviders).filter(
+ adapterProvider -> adapterProvider.isViewSupported(viewType)).findFirst().orElse(
+ null);
+ }
}
diff --git a/src/com/android/launcher3/allapps/AllAppsPagedView.java b/src/com/android/launcher3/allapps/AllAppsPagedView.java
index 872503ae1c..3cc9ce6806 100644
--- a/src/com/android/launcher3/allapps/AllAppsPagedView.java
+++ b/src/com/android/launcher3/allapps/AllAppsPagedView.java
@@ -21,13 +21,13 @@ import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCH
import android.content.Context;
import android.util.AttributeSet;
+import com.android.launcher3.Launcher;
import com.android.launcher3.PagedView;
-import com.android.launcher3.views.ActivityContext;
import com.android.launcher3.workprofile.PersonalWorkPagedView;
/**
- * A {@link PagedView} for showing different views for the personal and work profile respectively
- * in the {@link BaseAllAppsContainerView}.
+ * A {@link PagedView} for showing different views for the personal and work profile respectively
+ * in the {@link AllAppsContainerView}.
*/
public class AllAppsPagedView extends PersonalWorkPagedView {
@@ -47,7 +47,7 @@ public class AllAppsPagedView extends PersonalWorkPagedView {
protected boolean snapToPageWithVelocity(int whichPage, int velocity) {
boolean resp = super.snapToPageWithVelocity(whichPage, velocity);
if (resp && whichPage != mCurrentPage) {
- ActivityContext.lookupContext(getContext()).getStatsLogManager().logger()
+ Launcher.getLauncher(getContext()).getStatsLogManager().logger()
.log(mCurrentPage < whichPage
? LAUNCHER_ALLAPPS_SWIPE_TO_WORK_TAB
: LAUNCHER_ALLAPPS_SWIPE_TO_PERSONAL_TAB);
diff --git a/src/com/android/launcher3/allapps/AllAppsRecyclerView.java b/src/com/android/launcher3/allapps/AllAppsRecyclerView.java
index af17cf72e9..bddbbd00b2 100644
--- a/src/com/android/launcher3/allapps/AllAppsRecyclerView.java
+++ b/src/com/android/launcher3/allapps/AllAppsRecyclerView.java
@@ -15,12 +15,12 @@
*/
package com.android.launcher3.allapps;
+import static android.view.View.MeasureSpec.EXACTLY;
import static android.view.View.MeasureSpec.UNSPECIFIED;
+import static android.view.View.MeasureSpec.makeMeasureSpec;
-import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ALLAPPS_SCROLLED;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ALLAPPS_VERTICAL_SWIPE_BEGIN;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ALLAPPS_VERTICAL_SWIPE_END;
-import static com.android.launcher3.util.LogConfig.SEARCH_LOGGING;
import static com.android.launcher3.util.UiThreadHelper.hideKeyboardAsync;
import android.content.Context;
@@ -35,28 +35,28 @@ import android.view.View;
import androidx.recyclerview.widget.RecyclerView;
+import com.android.launcher3.BaseDraggingActivity;
+import com.android.launcher3.BaseRecyclerView;
import com.android.launcher3.DeviceProfile;
-import com.android.launcher3.FastScrollRecyclerView;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.R;
-import com.android.launcher3.Utilities;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.logging.StatsLogManager;
import com.android.launcher3.views.ActivityContext;
import com.android.launcher3.views.RecyclerViewFastScroller;
+import java.util.ArrayList;
import java.util.List;
/**
* A RecyclerView with custom fast scroll support for the all apps view.
*/
-public class AllAppsRecyclerView extends FastScrollRecyclerView {
- protected static final String TAG = "AllAppsRecyclerView";
+public class AllAppsRecyclerView extends BaseRecyclerView {
+ private static final String TAG = "AllAppsContainerView";
private static final boolean DEBUG = false;
- private static final boolean DEBUG_LATENCY = Utilities.isPropertyEnabled(SEARCH_LOGGING);
- protected AlphabeticalAppsList<?> mApps;
- protected final int mNumAppsPerRow;
+ private AlphabeticalAppsList mApps;
+ private final int mNumAppsPerRow;
// The specific view heights that we use to calculate scroll
private final SparseIntArray mViewHeights = new SparseIntArray();
@@ -68,31 +68,13 @@ public class AllAppsRecyclerView extends FastScrollRecyclerView {
public void onChanged() {
mCachedScrollPositions.clear();
}
-
- @Override
- public void onItemRangeChanged(int positionStart, int itemCount) {
- onChanged();
- }
-
- @Override
- public void onItemRangeInserted(int positionStart, int itemCount) {
- onChanged();
- }
-
- @Override
- public void onItemRangeRemoved(int positionStart, int itemCount) {
- onChanged();
- }
-
- @Override
- public void onItemRangeMoved(int fromPosition, int toPosition, int itemCount) {
- onChanged();
- }
};
// The empty-search result background
- protected AllAppsBackgroundDrawable mEmptySearchBackground;
- protected int mEmptySearchBackgroundTopOffset;
+ private AllAppsBackgroundDrawable mEmptySearchBackground;
+ private int mEmptySearchBackgroundTopOffset;
+
+ private ArrayList<View> mAutoSizedOverlays = new ArrayList<>();
public AllAppsRecyclerView(Context context) {
this(context, null);
@@ -119,16 +101,16 @@ public class AllAppsRecyclerView extends FastScrollRecyclerView {
/**
* Sets the list of apps in this view, used to determine the fastscroll position.
*/
- public void setApps(AlphabeticalAppsList<?> apps) {
+ public void setApps(AlphabeticalAppsList apps) {
mApps = apps;
}
- public AlphabeticalAppsList<?> getApps() {
+ public AlphabeticalAppsList getApps() {
return mApps;
}
- protected void updatePoolSize() {
- DeviceProfile grid = ActivityContext.lookupContext(getContext()).getDeviceProfile();
+ private void updatePoolSize() {
+ DeviceProfile grid = BaseDraggingActivity.fromContext(getContext()).getDeviceProfile();
RecyclerView.RecycledViewPool pool = getRecycledViewPool();
int approxRows = (int) Math.ceil(grid.availableHeightPx / grid.allAppsIconSizePx);
pool.setMaxRecycledViews(AllAppsGridAdapter.VIEW_TYPE_EMPTY_SEARCH, 1);
@@ -151,10 +133,6 @@ public class AllAppsRecyclerView extends FastScrollRecyclerView {
if (DEBUG) {
Log.d(TAG, "onDraw at = " + System.currentTimeMillis());
}
- if (DEBUG_LATENCY) {
- Log.d(SEARCH_LOGGING, getClass().getSimpleName() + " onDraw; time stamp = "
- + System.currentTimeMillis());
- }
super.onDraw(c);
}
@@ -167,6 +145,30 @@ public class AllAppsRecyclerView extends FastScrollRecyclerView {
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
updateEmptySearchBackgroundBounds();
updatePoolSize();
+ for (int i = 0; i < mAutoSizedOverlays.size(); i++) {
+ View overlay = mAutoSizedOverlays.get(i);
+ overlay.measure(makeMeasureSpec(w, EXACTLY), makeMeasureSpec(w, EXACTLY));
+ overlay.layout(0, 0, w, h);
+ }
+ }
+
+ /**
+ * Adds an overlay that automatically rescales with the recyclerview.
+ */
+ public void addAutoSizedOverlay(View overlay) {
+ mAutoSizedOverlays.add(overlay);
+ getOverlay().add(overlay);
+ onSizeChanged(getWidth(), getHeight(), getWidth(), getHeight());
+ }
+
+ /**
+ * Clears auto scaling overlay views added by #addAutoSizedOverlay
+ */
+ public void clearAutoSizedOverlays() {
+ for (View v : mAutoSizedOverlays) {
+ getOverlay().remove(v);
+ }
+ mAutoSizedOverlays.clear();
}
public void onSearchResultsChanged() {
@@ -192,15 +194,12 @@ public class AllAppsRecyclerView extends FastScrollRecyclerView {
public void onScrollStateChanged(int state) {
super.onScrollStateChanged(state);
- StatsLogManager mgr = ActivityContext.lookupContext(getContext()).getStatsLogManager();
+ StatsLogManager mgr = BaseDraggingActivity.fromContext(getContext()).getStatsLogManager();
switch (state) {
case SCROLL_STATE_DRAGGING:
- mgr.logger().log(LAUNCHER_ALLAPPS_SCROLLED);
requestFocus();
mgr.logger().sendToInteractionJankMonitor(
LAUNCHER_ALLAPPS_VERTICAL_SWIPE_BEGIN, this);
- hideKeyboardAsync(ActivityContext.lookupContext(getContext()),
- getApplicationWindowToken());
break;
case SCROLL_STATE_IDLE:
mgr.logger().sendToInteractionJankMonitor(
@@ -216,6 +215,8 @@ public class AllAppsRecyclerView extends FastScrollRecyclerView {
&& mEmptySearchBackground != null && mEmptySearchBackground.getAlpha() > 0) {
mEmptySearchBackground.setHotspot(e.getX(), e.getY());
}
+ hideKeyboardAsync(ActivityContext.lookupContext(getContext()),
+ getApplicationWindowToken());
return result;
}
@@ -232,14 +233,17 @@ public class AllAppsRecyclerView extends FastScrollRecyclerView {
// Find the fastscroll section that maps to this touch fraction
List<AlphabeticalAppsList.FastScrollSectionInfo> fastScrollSections =
mApps.getFastScrollerSections();
- int count = fastScrollSections.size();
- if (count == 0) {
- return "";
+ AlphabeticalAppsList.FastScrollSectionInfo lastInfo = fastScrollSections.get(0);
+ for (int i = 1; i < fastScrollSections.size(); i++) {
+ AlphabeticalAppsList.FastScrollSectionInfo info = fastScrollSections.get(i);
+ if (info.touchFraction > touchFraction) {
+ break;
+ }
+ lastInfo = info;
}
- int index = Utilities.boundToRange((int) (touchFraction * count), 0, count - 1);
- AlphabeticalAppsList.FastScrollSectionInfo section = fastScrollSections.get(index);
- mFastScrollHelper.smoothScrollToSection(section);
- return section.sectionName;
+
+ mFastScrollHelper.smoothScrollToSection(lastInfo);
+ return lastInfo.sectionName;
}
@Override
@@ -260,6 +264,12 @@ public class AllAppsRecyclerView extends FastScrollRecyclerView {
}
@Override
+ protected float getBottomFadingEdgeStrength() {
+ // No bottom fading edge.
+ return 0;
+ }
+
+ @Override
protected boolean isPaddingOffsetRequired() {
return true;
}
@@ -342,6 +352,13 @@ public class AllAppsRecyclerView extends FastScrollRecyclerView {
}
@Override
+ public boolean supportsFastScrolling() {
+ // Only allow fast scrolling when the user is not searching, since the results are not
+ // grouped in a meaningful order
+ return !mApps.hasFilter();
+ }
+
+ @Override
public int getCurrentScrollY() {
// Return early if there are no items or we haven't been measured
List<AllAppsGridAdapter.AdapterItem> items = mApps.getAdapterItems();
@@ -351,7 +368,7 @@ public class AllAppsRecyclerView extends FastScrollRecyclerView {
// Calculate the y and offset for the item
View child = getChildAt(0);
- int position = getChildAdapterPosition(child);
+ int position = getChildPosition(child);
if (position == NO_POSITION) {
return -1;
}
@@ -441,4 +458,14 @@ public class AllAppsRecyclerView extends FastScrollRecyclerView {
public boolean hasOverlappingRendering() {
return false;
}
+
+ /**
+ * Returns distance between left and right app icons
+ */
+ public int getTabWidth() {
+ DeviceProfile grid = BaseDraggingActivity.fromContext(getContext()).getDeviceProfile();
+ int totalWidth = getMeasuredWidth() - getPaddingLeft() - getPaddingRight();
+ int iconPadding = totalWidth / grid.numShownAllAppsColumns - grid.allAppsIconSizePx;
+ return totalWidth - iconPadding - grid.allAppsIconDrawablePaddingPx;
+ }
}
diff --git a/src/com/android/launcher3/allapps/AllAppsTransitionController.java b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
index a4a208533a..a0551f019a 100644
--- a/src/com/android/launcher3/allapps/AllAppsTransitionController.java
+++ b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
@@ -17,7 +17,6 @@ package com.android.launcher3.allapps;
import static com.android.launcher3.LauncherState.ALL_APPS;
import static com.android.launcher3.LauncherState.ALL_APPS_CONTENT;
-import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.launcher3.anim.Interpolators.DEACCEL_1_7;
import static com.android.launcher3.anim.Interpolators.LINEAR;
import static com.android.launcher3.anim.PropertySetter.NO_ANIM_PROPERTY_SETTER;
@@ -29,7 +28,6 @@ import android.animation.Animator;
import android.animation.Animator.AnimatorListener;
import android.animation.ObjectAnimator;
import android.util.FloatProperty;
-import android.view.HapticFeedbackConstants;
import android.view.View;
import android.view.animation.Interpolator;
@@ -39,14 +37,12 @@ import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherState;
import com.android.launcher3.Utilities;
import com.android.launcher3.anim.AnimatorListeners;
+import com.android.launcher3.anim.Interpolators;
import com.android.launcher3.anim.PendingAnimation;
import com.android.launcher3.anim.PropertySetter;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.statemanager.StateManager.StateHandler;
import com.android.launcher3.states.StateAnimationConfig;
-import com.android.launcher3.util.MultiAdditivePropertyFactory;
-import com.android.launcher3.util.MultiValueAlpha;
-import com.android.launcher3.util.UiThreadHelper;
import com.android.launcher3.views.ScrimView;
/**
@@ -63,6 +59,7 @@ public class AllAppsTransitionController
implements StateHandler<LauncherState>, OnDeviceProfileChangeListener {
// This constant should match the second derivative of the animator interpolator.
public static final float INTERP_COEFF = 1.7f;
+ private static final float CONTENT_VISIBLE_MAX_THRESHOLD = 0.5f;
public static final FloatProperty<AllAppsTransitionController> ALL_APPS_PROGRESS =
new FloatProperty<AllAppsTransitionController>("allAppsProgress") {
@@ -78,57 +75,7 @@ public class AllAppsTransitionController
}
};
- public static final FloatProperty<AllAppsTransitionController> ALL_APPS_PULL_BACK_TRANSLATION =
- new FloatProperty<AllAppsTransitionController>("allAppsPullBackTranslation") {
-
- @Override
- public Float get(AllAppsTransitionController controller) {
- if (controller.mIsTablet) {
- return controller.mAppsView.getActiveRecyclerView().getTranslationY();
- } else {
- return controller.getAppsViewPullbackTranslationY().get(
- controller.mAppsView);
- }
- }
-
- @Override
- public void setValue(AllAppsTransitionController controller, float translation) {
- if (controller.mIsTablet) {
- controller.mAppsView.getActiveRecyclerView().setTranslationY(translation);
- } else {
- controller.getAppsViewPullbackTranslationY().set(controller.mAppsView,
- translation);
- }
- }
- };
-
- public static final FloatProperty<AllAppsTransitionController> ALL_APPS_PULL_BACK_ALPHA =
- new FloatProperty<AllAppsTransitionController>("allAppsPullBackAlpha") {
-
- @Override
- public Float get(AllAppsTransitionController controller) {
- if (controller.mIsTablet) {
- return controller.mAppsView.getActiveRecyclerView().getAlpha();
- } else {
- return controller.getAppsViewPullbackAlpha().getValue();
- }
- }
-
- @Override
- public void setValue(AllAppsTransitionController controller, float alpha) {
- if (controller.mIsTablet) {
- controller.mAppsView.getActiveRecyclerView().setAlpha(alpha);
- } else {
- controller.getAppsViewPullbackAlpha().setValue(alpha);
- }
- }
- };
-
- private static final int INDEX_APPS_VIEW_PROGRESS = 0;
- private static final int INDEX_APPS_VIEW_PULLBACK = 1;
- private static final int APPS_VIEW_INDEX_COUNT = 2;
-
- private ActivityAllAppsContainerView<Launcher> mAppsView;
+ private AllAppsContainerView mAppsView;
private final Launcher mLauncher;
private boolean mIsVerticalLayout;
@@ -142,22 +89,15 @@ public class AllAppsTransitionController
private float mShiftRange; // changes depending on the orientation
private float mProgress; // [0, 1], mShiftRange * mProgress = shiftCurrent
+ private float mScrollRangeDelta = 0;
private ScrimView mScrimView;
- private final MultiAdditivePropertyFactory<View>
- mAppsViewTranslationYPropertyFactory = new MultiAdditivePropertyFactory<>(
- "appsViewTranslationY", View.TRANSLATION_Y);
- private MultiValueAlpha mAppsViewAlpha;
-
- private boolean mIsTablet;
-
public AllAppsTransitionController(Launcher l) {
mLauncher = l;
- DeviceProfile dp = mLauncher.getDeviceProfile();
- setShiftRange(dp.allAppsShiftRange);
+ mShiftRange = mLauncher.getDeviceProfile().heightPx;
mProgress = 1f;
- mIsVerticalLayout = dp.isVerticalBarLayout();
- mIsTablet = dp.isTablet;
+
+ mIsVerticalLayout = mLauncher.getDeviceProfile().isVerticalBarLayout();
mLauncher.addOnDeviceProfileChangeListener(this);
}
@@ -168,14 +108,12 @@ public class AllAppsTransitionController
@Override
public void onDeviceProfileChanged(DeviceProfile dp) {
mIsVerticalLayout = dp.isVerticalBarLayout();
- setShiftRange(dp.allAppsShiftRange);
+ setScrollRangeDelta(mScrollRangeDelta);
if (mIsVerticalLayout) {
mLauncher.getHotseat().setTranslationY(0);
mLauncher.getWorkspace().getPageIndicator().setTranslationY(0);
}
-
- mIsTablet = dp.isTablet;
}
/**
@@ -188,30 +126,13 @@ public class AllAppsTransitionController
*/
public void setProgress(float progress) {
mProgress = progress;
- getAppsViewProgressTranslationY().set(mAppsView, mProgress * mShiftRange);
- mLauncher.onAllAppsTransition(1 - progress);
+ mAppsView.setTranslationY(mProgress * mShiftRange);
}
public float getProgress() {
return mProgress;
}
- private FloatProperty<View> getAppsViewProgressTranslationY() {
- return mAppsViewTranslationYPropertyFactory.get(INDEX_APPS_VIEW_PROGRESS);
- }
-
- private FloatProperty<View> getAppsViewPullbackTranslationY() {
- return mAppsViewTranslationYPropertyFactory.get(INDEX_APPS_VIEW_PULLBACK);
- }
-
- private MultiValueAlpha.AlphaProperty getAppsViewProgressAlpha() {
- return mAppsViewAlpha.getProperty(INDEX_APPS_VIEW_PROGRESS);
- }
-
- private MultiValueAlpha.AlphaProperty getAppsViewPullbackAlpha() {
- return mAppsViewAlpha.getProperty(INDEX_APPS_VIEW_PULLBACK);
- }
-
/**
* Sets the vertical transition progress to {@param state} and updates all the dependent UI
* accordingly.
@@ -230,15 +151,6 @@ public class AllAppsTransitionController
@Override
public void setStateWithAnimation(LauncherState toState,
StateAnimationConfig config, PendingAnimation builder) {
- if (NORMAL.equals(toState) && mLauncher.isInState(ALL_APPS)) {
- UiThreadHelper.hideKeyboardAsync(mLauncher, mLauncher.getAppsView().getWindowToken());
- builder.addEndListener(success -> {
- // Reset pull back progress and alpha after switching states.
- ALL_APPS_PULL_BACK_TRANSLATION.set(this, 0f);
- ALL_APPS_PULL_BACK_ALPHA.set(this, 1f);
- });
- }
-
float targetProgress = toState.getVerticalProgress(mLauncher);
if (Float.compare(mProgress, targetProgress) == 0) {
setAlphas(toState, config, builder);
@@ -248,19 +160,14 @@ public class AllAppsTransitionController
}
// need to decide depending on the release velocity
- Interpolator verticalProgressInterpolator = config.getInterpolator(ANIM_VERTICAL_PROGRESS,
- config.userControlled ? LINEAR : DEACCEL_1_7);
+ Interpolator interpolator = (config.userControlled ? LINEAR : DEACCEL_1_7);
+
Animator anim = createSpringAnimation(mProgress, targetProgress);
- anim.setInterpolator(verticalProgressInterpolator);
+ anim.setInterpolator(config.getInterpolator(ANIM_VERTICAL_PROGRESS, interpolator));
anim.addListener(getProgressAnimatorListener());
builder.add(anim);
setAlphas(toState, config, builder);
-
- if (ALL_APPS.equals(toState) && mLauncher.isInState(NORMAL)) {
- mLauncher.getAppsView().performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY,
- HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);
- }
}
public Animator createSpringAnimation(float... progressValues) {
@@ -274,9 +181,9 @@ public class AllAppsTransitionController
int visibleElements = state.getVisibleElements(mLauncher);
boolean hasAllAppsContent = (visibleElements & ALL_APPS_CONTENT) != 0;
- Interpolator allAppsFade = config.getInterpolator(ANIM_ALL_APPS_FADE, LINEAR);
- setter.setFloat(getAppsViewProgressAlpha(), MultiValueAlpha.VALUE,
- hasAllAppsContent ? 1 : 0, allAppsFade);
+ Interpolator allAppsFade = config.getInterpolator(ANIM_ALL_APPS_FADE,
+ Interpolators.clampToProgress(LINEAR, 0, CONTENT_VISIBLE_MAX_THRESHOLD));
+ setter.setViewAlpha(mAppsView, hasAllAppsContent ? 1 : 0, allAppsFade);
boolean shouldProtectHeader =
ALL_APPS == state || mLauncher.getStateManager().getState() == ALL_APPS;
@@ -290,7 +197,7 @@ public class AllAppsTransitionController
/**
* see Launcher#setupViews
*/
- public void setupViews(ScrimView scrimView, ActivityAllAppsContainerView<Launcher> appsView) {
+ public void setupViews(ScrimView scrimView, AllAppsContainerView appsView) {
mScrimView = scrimView;
mAppsView = appsView;
if (FeatureFlags.ENABLE_DEVICE_SEARCH.get() && Utilities.ATLEAST_R) {
@@ -299,15 +206,14 @@ public class AllAppsTransitionController
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
}
mAppsView.setScrimView(scrimView);
- mAppsViewAlpha = new MultiValueAlpha(mAppsView, APPS_VIEW_INDEX_COUNT);
- mAppsViewAlpha.setUpdateVisibility(true);
}
/**
* Updates the total scroll range but does not update the UI.
*/
- public void setShiftRange(float shiftRange) {
- mShiftRange = shiftRange;
+ public void setScrollRangeDelta(float delta) {
+ mScrollRangeDelta = delta;
+ mShiftRange = mLauncher.getDeviceProfile().heightPx - mScrollRangeDelta;
}
/**
diff --git a/src/com/android/launcher3/allapps/AlphabeticalAppsList.java b/src/com/android/launcher3/allapps/AlphabeticalAppsList.java
index 45a567dd19..ce5c5890ea 100644
--- a/src/com/android/launcher3/allapps/AlphabeticalAppsList.java
+++ b/src/com/android/launcher3/allapps/AlphabeticalAppsList.java
@@ -15,41 +15,35 @@
*/
package com.android.launcher3.allapps;
-import static com.android.launcher3.allapps.BaseAllAppsAdapter.VIEW_TYPE_ALL_APPS_DIVIDER;
-import static com.android.launcher3.allapps.BaseAllAppsAdapter.VIEW_TYPE_EMPTY_SEARCH;
-import static com.android.launcher3.allapps.BaseAllAppsAdapter.VIEW_TYPE_SEARCH_MARKET;
import android.content.Context;
-import androidx.annotation.Nullable;
-import androidx.recyclerview.widget.DiffUtil;
-
-import com.android.launcher3.allapps.BaseAllAppsAdapter.AdapterItem;
+import com.android.launcher3.BaseDraggingActivity;
+import com.android.launcher3.allapps.AllAppsGridAdapter.AdapterItem;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.model.data.AppInfo;
-import com.android.launcher3.model.data.ItemInfo;
+import com.android.launcher3.util.ItemInfoMatcher;
import com.android.launcher3.util.LabelComparator;
-import com.android.launcher3.views.ActivityContext;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
import java.util.Locale;
+import java.util.Map;
import java.util.Objects;
import java.util.TreeMap;
-import java.util.function.Predicate;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
/**
* The alphabetically sorted list of applications.
- *
- * @param <T> Type of context inflating this view.
*/
-public class AlphabeticalAppsList<T extends Context & ActivityContext> implements
- AllAppsStore.OnUpdateListener {
+public class AlphabeticalAppsList implements AllAppsStore.OnUpdateListener {
public static final String TAG = "AlphabeticalAppsList";
+ private static final int FAST_SCROLL_FRACTION_DISTRIBUTE_BY_ROWS_FRACTION = 0;
+ private static final int FAST_SCROLL_FRACTION_DISTRIBUTE_BY_NUM_SECTIONS = 1;
+
+ private final int mFastScrollDistributionMode = FAST_SCROLL_FRACTION_DISTRIBUTE_BY_NUM_SECTIONS;
private final WorkAdapterProvider mWorkAdapterProvider;
/**
@@ -58,22 +52,22 @@ public class AlphabeticalAppsList<T extends Context & ActivityContext> implement
*/
public static class FastScrollSectionInfo {
// The section name
- public final String sectionName;
- // The item position
- public final int position;
+ public String sectionName;
+ // The AdapterItem to scroll to for this section
+ public AdapterItem fastScrollToItem;
+ // The touch fraction that should map to this fast scroll section info
+ public float touchFraction;
- public FastScrollSectionInfo(String sectionName, int position) {
+ public FastScrollSectionInfo(String sectionName) {
this.sectionName = sectionName;
- this.position = position;
}
}
- private final T mActivityContext;
+ private final BaseDraggingActivity mLauncher;
// The set of apps from the system
private final List<AppInfo> mApps = new ArrayList<>();
- @Nullable
private final AllAppsStore mAllAppsStore;
// The number of results in current adapter
@@ -84,26 +78,24 @@ public class AlphabeticalAppsList<T extends Context & ActivityContext> implement
private final List<FastScrollSectionInfo> mFastScrollerSections = new ArrayList<>();
// The of ordered component names as a result of a search query
- private final ArrayList<AdapterItem> mSearchResults = new ArrayList<>();
- private BaseAllAppsAdapter<T> mAdapter;
+ private ArrayList<AdapterItem> mSearchResults;
+ private AllAppsGridAdapter mAdapter;
private AppInfoComparator mAppNameComparator;
- private final int mNumAppsPerRowAllApps;
+ private final int mNumAppsPerRow;
private int mNumAppRowsInAdapter;
- private Predicate<ItemInfo> mItemFilter;
+ private ItemInfoMatcher mItemFilter;
- public AlphabeticalAppsList(Context context, @Nullable AllAppsStore appsStore,
+ public AlphabeticalAppsList(Context context, AllAppsStore appsStore,
WorkAdapterProvider adapterProvider) {
mAllAppsStore = appsStore;
- mActivityContext = ActivityContext.lookupContext(context);
+ mLauncher = BaseDraggingActivity.fromContext(context);
mAppNameComparator = new AppInfoComparator(context);
mWorkAdapterProvider = adapterProvider;
- mNumAppsPerRowAllApps = mActivityContext.getDeviceProfile().inv.numAllAppsColumns;
- if (mAllAppsStore != null) {
- mAllAppsStore.addUpdateListener(this);
- }
+ mNumAppsPerRow = mLauncher.getDeviceProfile().inv.numColumns;
+ mAllAppsStore.addUpdateListener(this);
}
- public void updateItemFilter(Predicate<ItemInfo> itemFilter) {
+ public void updateItemFilter(ItemInfoMatcher itemFilter) {
this.mItemFilter = itemFilter;
onAppsUpdated();
}
@@ -111,11 +103,18 @@ public class AlphabeticalAppsList<T extends Context & ActivityContext> implement
/**
* Sets the adapter to notify when this dataset changes.
*/
- public void setAdapter(BaseAllAppsAdapter<T> adapter) {
+ public void setAdapter(AllAppsGridAdapter adapter) {
mAdapter = adapter;
}
/**
+ * Returns all the apps.
+ */
+ public List<AppInfo> getApps() {
+ return mApps;
+ }
+
+ /**
* Returns fast scroller sections of all the current filtered applications.
*/
public List<FastScrollSectionInfo> getFastScrollerSections() {
@@ -166,32 +165,50 @@ public class AlphabeticalAppsList<T extends Context & ActivityContext> implement
}
/**
- * Returns whether there are search results which will hide the A-Z list.
+ * Returns whether there are is a filter set.
*/
- public boolean hasSearchResults() {
- return !mSearchResults.isEmpty();
+ public boolean hasFilter() {
+ return (mSearchResults != null);
}
/**
* Returns whether there are no filtered results.
*/
public boolean hasNoFilteredResults() {
- return hasSearchResults() && mAccessibilityResultsCount == 0;
+ return (mSearchResults != null) && mAccessibilityResultsCount == 0;
}
/**
* Sets results list for search
*/
public boolean setSearchResults(ArrayList<AdapterItem> results) {
- if (Objects.equals(results, mSearchResults)) {
- return false;
+ if (!Objects.equals(results, mSearchResults)) {
+ mSearchResults = results;
+ updateAdapterItems();
+ return true;
}
- mSearchResults.clear();
- if (results != null) {
- mSearchResults.addAll(results);
+ return false;
+ }
+
+ public boolean appendSearchResults(ArrayList<AdapterItem> results) {
+ if (mSearchResults != null && results != null && results.size() > 0) {
+ updateSearchAdapterItems(results, mSearchResults.size());
+ refreshRecyclerView();
+ return true;
+ }
+ return false;
+ }
+
+ void updateSearchAdapterItems(ArrayList<AdapterItem> list, int offset) {
+ for (int i = 0; i < list.size(); i++) {
+ AdapterItem adapterItem = list.get(i);
+ adapterItem.position = offset + i;
+ mAdapterItems.add(adapterItem);
+
+ if (adapterItem.isCountedForAccessibility()) {
+ mAccessibilityResultsCount++;
+ }
}
- updateAdapterItems();
- return true;
}
/**
@@ -199,37 +216,47 @@ public class AlphabeticalAppsList<T extends Context & ActivityContext> implement
*/
@Override
public void onAppsUpdated() {
- if (mAllAppsStore == null) {
- return;
- }
// Sort the list of apps
mApps.clear();
- Stream<AppInfo> appSteam = Stream.of(mAllAppsStore.getApps());
- if (!hasSearchResults() && mItemFilter != null) {
- appSteam = appSteam.filter(mItemFilter);
+ for (AppInfo app : mAllAppsStore.getApps()) {
+ if (mItemFilter == null || mItemFilter.matches(app, null) || hasFilter()) {
+ mApps.add(app);
+ }
}
- appSteam = appSteam.sorted(mAppNameComparator);
+
+ Collections.sort(mApps, mAppNameComparator);
// As a special case for some languages (currently only Simplified Chinese), we may need to
// coalesce sections
- Locale curLocale = mActivityContext.getResources().getConfiguration().locale;
+ Locale curLocale = mLauncher.getResources().getConfiguration().locale;
boolean localeRequiresSectionSorting = curLocale.equals(Locale.SIMPLIFIED_CHINESE);
if (localeRequiresSectionSorting) {
// Compute the section headers. We use a TreeMap with the section name comparator to
// ensure that the sections are ordered when we iterate over it later
- appSteam = appSteam.collect(Collectors.groupingBy(
- info -> info.sectionName,
- () -> new TreeMap<>(new LabelComparator()),
- Collectors.toCollection(ArrayList::new)))
- .values()
- .stream()
- .flatMap(ArrayList::stream);
+ TreeMap<String, ArrayList<AppInfo>> sectionMap = new TreeMap<>(new LabelComparator());
+ for (AppInfo info : mApps) {
+ // Add the section to the cache
+ String sectionName = info.sectionName;
+
+ // Add it to the mapping
+ ArrayList<AppInfo> sectionApps = sectionMap.get(sectionName);
+ if (sectionApps == null) {
+ sectionApps = new ArrayList<>();
+ sectionMap.put(sectionName, sectionApps);
+ }
+ sectionApps.add(info);
+ }
+
+ // Add each of the section apps to the list in order
+ mApps.clear();
+ for (Map.Entry<String, ArrayList<AppInfo>> entry : sectionMap.entrySet()) {
+ mApps.addAll(entry.getValue());
+ }
}
- appSteam.forEachOrdered(mApps::add);
// Recompose the set of adapter items from the current set of apps
- if (mSearchResults.isEmpty()) {
+ if (mSearchResults == null) {
updateAdapterItems();
}
}
@@ -239,50 +266,71 @@ public class AlphabeticalAppsList<T extends Context & ActivityContext> implement
* mCachedSectionNames to have been calculated for the set of all apps in mApps.
*/
public void updateAdapterItems() {
- List<AdapterItem> oldItems = new ArrayList<>(mAdapterItems);
+ refillAdapterItems();
+ refreshRecyclerView();
+ }
+
+ private void refreshRecyclerView() {
+ if (mAdapter != null) {
+ mAdapter.notifyDataSetChanged();
+ }
+ }
+
+ private void refillAdapterItems() {
+ String lastSectionName = null;
+ FastScrollSectionInfo lastFastScrollerSectionInfo = null;
+ int position = 0;
+ int appIndex = 0;
+
// Prepare to update the list of sections, filtered apps, etc.
+ mAccessibilityResultsCount = 0;
mFastScrollerSections.clear();
mAdapterItems.clear();
- mAccessibilityResultsCount = 0;
// Recreate the filtered and sectioned apps (for convenience for the grid layout) from the
// ordered set of sections
- if (hasSearchResults()) {
- mAdapterItems.addAll(mSearchResults);
- if (!FeatureFlags.ENABLE_DEVICE_SEARCH.get()) {
- // Append the search market item
- if (hasNoFilteredResults()) {
- mAdapterItems.add(new AdapterItem(VIEW_TYPE_EMPTY_SEARCH));
- } else {
- mAdapterItems.add(new AdapterItem(VIEW_TYPE_ALL_APPS_DIVIDER));
- }
- mAdapterItems.add(new AdapterItem(VIEW_TYPE_SEARCH_MARKET));
- }
- } else {
- int position = 0;
+
+ if (!hasFilter()) {
+ mAccessibilityResultsCount = mApps.size();
if (mWorkAdapterProvider != null) {
position += mWorkAdapterProvider.addWorkItems(mAdapterItems);
if (!mWorkAdapterProvider.shouldShowWorkApps()) {
return;
}
}
- String lastSectionName = null;
for (AppInfo info : mApps) {
- mAdapterItems.add(AdapterItem.asApp(info));
-
String sectionName = info.sectionName;
+
// Create a new section if the section names do not match
if (!sectionName.equals(lastSectionName)) {
lastSectionName = sectionName;
- mFastScrollerSections.add(new FastScrollSectionInfo(sectionName, position));
+ lastFastScrollerSectionInfo = new FastScrollSectionInfo(sectionName);
+ mFastScrollerSections.add(lastFastScrollerSectionInfo);
}
- position++;
+
+ // Create an app item
+ AdapterItem appItem = AdapterItem.asApp(position++, sectionName, info,
+ appIndex++);
+ if (lastFastScrollerSectionInfo.fastScrollToItem == null) {
+ lastFastScrollerSectionInfo.fastScrollToItem = appItem;
+ }
+
+ mAdapterItems.add(appItem);
}
- }
- mAccessibilityResultsCount = (int) mAdapterItems.stream()
- .filter(AdapterItem::isCountedForAccessibility).count();
+ } else {
+ updateSearchAdapterItems(mSearchResults, 0);
+ if (!FeatureFlags.ENABLE_DEVICE_SEARCH.get()) {
+ // Append the search market item
+ if (hasNoFilteredResults()) {
+ mAdapterItems.add(AdapterItem.asEmptySearch(position++));
+ } else {
+ mAdapterItems.add(AdapterItem.asAllAppsDivider(position++));
+ }
+ mAdapterItems.add(AdapterItem.asMarketSearch(position++));
- if (mNumAppsPerRowAllApps != 0) {
+ }
+ }
+ if (mNumAppsPerRow != 0) {
// Update the number of rows in the adapter after we do all the merging (otherwise, we
// would have to shift the values again)
int numAppsInSection = 0;
@@ -290,10 +338,10 @@ public class AlphabeticalAppsList<T extends Context & ActivityContext> implement
int rowIndex = -1;
for (AdapterItem item : mAdapterItems) {
item.rowIndex = 0;
- if (BaseAllAppsAdapter.isDividerViewType(item.viewType)) {
+ if (AllAppsGridAdapter.isDividerViewType(item.viewType)) {
numAppsInSection = 0;
- } else if (BaseAllAppsAdapter.isIconViewType(item.viewType)) {
- if (numAppsInSection % mNumAppsPerRowAllApps == 0) {
+ } else if (AllAppsGridAdapter.isIconViewType(item.viewType)) {
+ if (numAppsInSection % mNumAppsPerRow == 0) {
numAppsInRow = 0;
rowIndex++;
}
@@ -304,43 +352,36 @@ public class AlphabeticalAppsList<T extends Context & ActivityContext> implement
}
}
mNumAppRowsInAdapter = rowIndex + 1;
- }
-
- if (mAdapter != null) {
- DiffUtil.calculateDiff(new MyDiffCallback(oldItems, mAdapterItems), false)
- .dispatchUpdatesTo(mAdapter);
- }
- }
- private static class MyDiffCallback extends DiffUtil.Callback {
-
- private final List<AdapterItem> mOldList;
- private final List<AdapterItem> mNewList;
-
- MyDiffCallback(List<AdapterItem> oldList, List<AdapterItem> newList) {
- mOldList = oldList;
- mNewList = newList;
- }
-
- @Override
- public int getOldListSize() {
- return mOldList.size();
- }
-
- @Override
- public int getNewListSize() {
- return mNewList.size();
- }
-
- @Override
- public boolean areItemsTheSame(int oldItemPosition, int newItemPosition) {
- return mOldList.get(oldItemPosition).isSameAs(mNewList.get(newItemPosition));
- }
-
- @Override
- public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) {
- return mOldList.get(oldItemPosition).isContentSame(mNewList.get(newItemPosition));
+ // Pre-calculate all the fast scroller fractions
+ switch (mFastScrollDistributionMode) {
+ case FAST_SCROLL_FRACTION_DISTRIBUTE_BY_ROWS_FRACTION:
+ float rowFraction = 1f / mNumAppRowsInAdapter;
+ for (FastScrollSectionInfo info : mFastScrollerSections) {
+ AdapterItem item = info.fastScrollToItem;
+ if (!AllAppsGridAdapter.isIconViewType(item.viewType)) {
+ info.touchFraction = 0f;
+ continue;
+ }
+
+ float subRowFraction = item.rowAppIndex * (rowFraction / mNumAppsPerRow);
+ info.touchFraction = item.rowIndex * rowFraction + subRowFraction;
+ }
+ break;
+ case FAST_SCROLL_FRACTION_DISTRIBUTE_BY_NUM_SECTIONS:
+ float perSectionTouchFraction = 1f / mFastScrollerSections.size();
+ float cumulativeTouchFraction = 0f;
+ for (FastScrollSectionInfo info : mFastScrollerSections) {
+ AdapterItem item = info.fastScrollToItem;
+ if (!AllAppsGridAdapter.isIconViewType(item.viewType)) {
+ info.touchFraction = 0f;
+ continue;
+ }
+ info.touchFraction = cumulativeTouchFraction;
+ cumulativeTouchFraction += perSectionTouchFraction;
+ }
+ break;
+ }
}
}
-
}
diff --git a/src/com/android/launcher3/allapps/AppInfoComparator.java b/src/com/android/launcher3/allapps/AppInfoComparator.java
index 311a40ef64..823f98efea 100644
--- a/src/com/android/launcher3/allapps/AppInfoComparator.java
+++ b/src/com/android/launcher3/allapps/AppInfoComparator.java
@@ -43,9 +43,7 @@ public class AppInfoComparator implements Comparator<AppInfo> {
@Override
public int compare(AppInfo a, AppInfo b) {
// Order by the title in the current locale
- int result = mLabelComparator.compare(
- a.title == null ? "" : a.title.toString(),
- b.title == null ? "" : b.title.toString());
+ int result = mLabelComparator.compare(a.title.toString(), b.title.toString());
if (result != 0) {
return result;
}
diff --git a/src/com/android/launcher3/allapps/BaseAllAppsAdapter.java b/src/com/android/launcher3/allapps/BaseAllAppsAdapter.java
deleted file mode 100644
index fcba246c95..0000000000
--- a/src/com/android/launcher3/allapps/BaseAllAppsAdapter.java
+++ /dev/null
@@ -1,303 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.launcher3.allapps;
-
-import static com.android.launcher3.touch.ItemLongClickListener.INSTANCE_ALL_APPS;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.view.Gravity;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.view.View.OnFocusChangeListener;
-import android.view.View.OnLongClickListener;
-import android.view.ViewGroup;
-import android.widget.TextView;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.recyclerview.widget.RecyclerView;
-
-import com.android.launcher3.BubbleTextView;
-import com.android.launcher3.R;
-import com.android.launcher3.config.FeatureFlags;
-import com.android.launcher3.model.data.AppInfo;
-import com.android.launcher3.views.ActivityContext;
-
-import java.util.Arrays;
-
-/**
- * Adapter for all the apps.
- *
- * @param <T> Type of context inflating all apps.
- */
-public abstract class BaseAllAppsAdapter<T extends Context & ActivityContext> extends
- RecyclerView.Adapter<BaseAllAppsAdapter.ViewHolder> {
-
- public static final String TAG = "BaseAllAppsAdapter";
-
- // A normal icon
- public static final int VIEW_TYPE_ICON = 1 << 1;
- // The message shown when there are no filtered results
- public static final int VIEW_TYPE_EMPTY_SEARCH = 1 << 2;
- // The message to continue to a market search when there are no filtered results
- public static final int VIEW_TYPE_SEARCH_MARKET = 1 << 3;
-
- // We use various dividers for various purposes. They share enough attributes to reuse layouts,
- // but differ in enough attributes to require different view types
-
- // A divider that separates the apps list and the search market button
- public static final int VIEW_TYPE_ALL_APPS_DIVIDER = 1 << 4;
-
- // Common view type masks
- public static final int VIEW_TYPE_MASK_DIVIDER = VIEW_TYPE_ALL_APPS_DIVIDER;
- public static final int VIEW_TYPE_MASK_ICON = VIEW_TYPE_ICON;
-
-
- protected final BaseAdapterProvider[] mAdapterProviders;
-
- /**
- * ViewHolder for each icon.
- */
- public static class ViewHolder extends RecyclerView.ViewHolder {
-
- public ViewHolder(View v) {
- super(v);
- }
- }
-
- /** Sets the number of apps to be displayed in one row of the all apps screen. */
- public abstract void setAppsPerRow(int appsPerRow);
-
- /**
- * Info about a particular adapter item (can be either section or app)
- */
- public static class AdapterItem {
- /** Common properties */
- // The type of this item
- public final int viewType;
-
- // The row that this item shows up on
- public int rowIndex;
- // The index of this app in the row
- public int rowAppIndex;
- // The associated ItemInfoWithIcon for the item
- public AppInfo itemInfo = null;
-
- public AdapterItem(int viewType) {
- this.viewType = viewType;
- }
-
- /**
- * Factory method for AppIcon AdapterItem
- */
- public static AdapterItem asApp(AppInfo appInfo) {
- AdapterItem item = new AdapterItem(VIEW_TYPE_ICON);
- item.itemInfo = appInfo;
- return item;
- }
-
- protected boolean isCountedForAccessibility() {
- return viewType == VIEW_TYPE_ICON || viewType == VIEW_TYPE_SEARCH_MARKET;
- }
-
- /**
- * Returns true if the items represent the same object
- */
- public boolean isSameAs(AdapterItem other) {
- return (other.viewType == viewType) && (other.getClass() == getClass());
- }
-
- /**
- * This is called only if {@link #isSameAs} returns true to check if the contents are same
- * as well. Returning true will prevent redrawing of thee item.
- */
- public boolean isContentSame(AdapterItem other) {
- return itemInfo == null && other.itemInfo == null;
- }
- }
-
- protected final T mActivityContext;
- protected final AlphabeticalAppsList<T> mApps;
- // The text to show when there are no search results and no market search handler.
- protected String mEmptySearchMessage;
- protected int mAppsPerRow;
-
- protected final LayoutInflater mLayoutInflater;
- protected final OnClickListener mOnIconClickListener;
- protected OnLongClickListener mOnIconLongClickListener = INSTANCE_ALL_APPS;
- protected OnFocusChangeListener mIconFocusListener;
- // The click listener to send off to the market app, updated each time the search query changes.
- private OnClickListener mMarketSearchClickListener;
- private final int mExtraHeight;
-
- public BaseAllAppsAdapter(T activityContext, LayoutInflater inflater,
- AlphabeticalAppsList<T> apps, BaseAdapterProvider[] adapterProviders) {
- Resources res = activityContext.getResources();
- mActivityContext = activityContext;
- mApps = apps;
- mEmptySearchMessage = res.getString(R.string.all_apps_loading_message);
- mLayoutInflater = inflater;
-
- mOnIconClickListener = mActivityContext.getItemOnClickListener();
-
- mAdapterProviders = adapterProviders;
- mExtraHeight = res.getDimensionPixelSize(R.dimen.all_apps_height_extra);
- }
-
- /**
- * Sets the long click listener for icons
- */
- public void setOnIconLongClickListener(@Nullable OnLongClickListener listener) {
- mOnIconLongClickListener = listener;
- }
-
- /** Checks if the passed viewType represents all apps divider. */
- public static boolean isDividerViewType(int viewType) {
- return isViewType(viewType, VIEW_TYPE_MASK_DIVIDER);
- }
-
- /** Checks if the passed viewType represents all apps icon. */
- public static boolean isIconViewType(int viewType) {
- return isViewType(viewType, VIEW_TYPE_MASK_ICON);
- }
-
- public void setIconFocusListener(OnFocusChangeListener focusListener) {
- mIconFocusListener = focusListener;
- }
-
- /**
- * Sets the last search query that was made, used to show when there are no results and to also
- * seed the intent for searching the market.
- */
- public void setLastSearchQuery(String query, OnClickListener marketSearchClickListener) {
- Resources res = mActivityContext.getResources();
- mEmptySearchMessage = res.getString(R.string.all_apps_no_search_results, query);
- mMarketSearchClickListener = marketSearchClickListener;
- }
-
- /**
- * Returns the layout manager.
- */
- public abstract RecyclerView.LayoutManager getLayoutManager();
-
- @Override
- public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
- switch (viewType) {
- case VIEW_TYPE_ICON:
- int layout = !FeatureFlags.ENABLE_TWOLINE_ALLAPPS.get() ? R.layout.all_apps_icon
- : R.layout.all_apps_icon_twoline;
- BubbleTextView icon = (BubbleTextView) mLayoutInflater.inflate(
- layout, parent, false);
- icon.setLongPressTimeoutFactor(1f);
- icon.setOnFocusChangeListener(mIconFocusListener);
- icon.setOnClickListener(mOnIconClickListener);
- icon.setOnLongClickListener(mOnIconLongClickListener);
- // Ensure the all apps icon height matches the workspace icons in portrait mode.
- icon.getLayoutParams().height =
- mActivityContext.getDeviceProfile().allAppsCellHeightPx;
- if (FeatureFlags.ENABLE_TWOLINE_ALLAPPS.get()) {
- icon.getLayoutParams().height += mExtraHeight;
- }
- return new ViewHolder(icon);
- case VIEW_TYPE_EMPTY_SEARCH:
- return new ViewHolder(mLayoutInflater.inflate(R.layout.all_apps_empty_search,
- parent, false));
- case VIEW_TYPE_SEARCH_MARKET:
- View searchMarketView = mLayoutInflater.inflate(R.layout.all_apps_search_market,
- parent, false);
- searchMarketView.setOnClickListener(mMarketSearchClickListener);
- return new ViewHolder(searchMarketView);
- case VIEW_TYPE_ALL_APPS_DIVIDER:
- return new ViewHolder(mLayoutInflater.inflate(
- R.layout.all_apps_divider, parent, false));
- default:
- BaseAdapterProvider adapterProvider = getAdapterProvider(viewType);
- if (adapterProvider != null) {
- return adapterProvider.onCreateViewHolder(mLayoutInflater, parent, viewType);
- }
- throw new RuntimeException("Unexpected view type" + viewType);
- }
- }
-
- @Override
- public void onBindViewHolder(ViewHolder holder, int position) {
- switch (holder.getItemViewType()) {
- case VIEW_TYPE_ICON:
- AdapterItem adapterItem = mApps.getAdapterItems().get(position);
- BubbleTextView icon = (BubbleTextView) holder.itemView;
- icon.reset();
- icon.applyFromApplicationInfo(adapterItem.itemInfo);
- break;
- case VIEW_TYPE_EMPTY_SEARCH:
- TextView emptyViewText = (TextView) holder.itemView;
- emptyViewText.setText(mEmptySearchMessage);
- emptyViewText.setGravity(mApps.hasNoFilteredResults() ? Gravity.CENTER :
- Gravity.START | Gravity.CENTER_VERTICAL);
- break;
- case VIEW_TYPE_SEARCH_MARKET:
- TextView searchView = (TextView) holder.itemView;
- if (mMarketSearchClickListener != null) {
- searchView.setVisibility(View.VISIBLE);
- } else {
- searchView.setVisibility(View.GONE);
- }
- break;
- case VIEW_TYPE_ALL_APPS_DIVIDER:
- // nothing to do
- break;
- default:
- BaseAdapterProvider adapterProvider = getAdapterProvider(holder.getItemViewType());
- if (adapterProvider != null) {
- adapterProvider.onBindView(holder, position);
- }
- }
- }
-
- @Override
- public void onViewRecycled(@NonNull ViewHolder holder) {
- super.onViewRecycled(holder);
- }
-
- @Override
- public boolean onFailedToRecycleView(ViewHolder holder) {
- // Always recycle and we will reset the view when it is bound
- return true;
- }
-
- @Override
- public int getItemCount() {
- return mApps.getAdapterItems().size();
- }
-
- @Override
- public int getItemViewType(int position) {
- AdapterItem item = mApps.getAdapterItems().get(position);
- return item.viewType;
- }
-
- protected static boolean isViewType(int viewType, int viewTypeMask) {
- return (viewType & viewTypeMask) != 0;
- }
-
- @Nullable
- protected BaseAdapterProvider getAdapterProvider(int viewType) {
- return Arrays.stream(mAdapterProviders).filter(
- adapterProvider -> adapterProvider.isViewSupported(viewType)).findFirst().orElse(
- null);
- }
-}
diff --git a/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java b/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java
deleted file mode 100644
index ecadec673a..0000000000
--- a/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java
+++ /dev/null
@@ -1,850 +0,0 @@
-/*
- * Copyright (C) 2015 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.launcher3.allapps;
-
-import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ALLAPPS_TAP_ON_PERSONAL_TAB;
-import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ALLAPPS_TAP_ON_WORK_TAB;
-import static com.android.launcher3.util.UiThreadHelper.hideKeyboardAsync;
-
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.ValueAnimator;
-import android.content.Context;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.Paint;
-import android.graphics.Point;
-import android.graphics.Rect;
-import android.os.Bundle;
-import android.os.Parcelable;
-import android.os.Process;
-import android.os.UserManager;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.util.SparseArray;
-import android.view.LayoutInflater;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.WindowInsets;
-import android.widget.Button;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.annotation.VisibleForTesting;
-import androidx.core.graphics.ColorUtils;
-import androidx.recyclerview.widget.RecyclerView;
-
-import com.android.launcher3.DeviceProfile;
-import com.android.launcher3.DeviceProfile.DeviceProfileListenable;
-import com.android.launcher3.DeviceProfile.OnDeviceProfileChangeListener;
-import com.android.launcher3.DragSource;
-import com.android.launcher3.DropTarget.DragObject;
-import com.android.launcher3.Insettable;
-import com.android.launcher3.InsettableFrameLayout;
-import com.android.launcher3.R;
-import com.android.launcher3.Utilities;
-import com.android.launcher3.allapps.search.SearchAdapterProvider;
-import com.android.launcher3.keyboard.FocusedItemDecorator;
-import com.android.launcher3.model.StringCache;
-import com.android.launcher3.model.data.ItemInfo;
-import com.android.launcher3.util.ItemInfoMatcher;
-import com.android.launcher3.util.Themes;
-import com.android.launcher3.views.ActivityContext;
-import com.android.launcher3.views.BaseDragLayer;
-import com.android.launcher3.views.RecyclerViewFastScroller;
-import com.android.launcher3.views.ScrimView;
-import com.android.launcher3.views.SpringRelativeLayout;
-import com.android.launcher3.workprofile.PersonalWorkSlidingTabStrip.OnActivePageChangedListener;
-
-import java.util.Arrays;
-import java.util.List;
-import java.util.function.Predicate;
-import java.util.stream.Stream;
-
-/**
- * Base all apps view container.
- *
- * @param <T> Type of context inflating all apps.
- */
-public abstract class BaseAllAppsContainerView<T extends Context & ActivityContext
- & DeviceProfileListenable> extends SpringRelativeLayout implements DragSource, Insettable,
- OnDeviceProfileChangeListener, OnActivePageChangedListener,
- ScrimView.ScrimDrawingController {
-
- protected static final String BUNDLE_KEY_CURRENT_PAGE = "launcher.allapps.current_page";
-
- public static final float PULL_MULTIPLIER = .02f;
- public static final float FLING_VELOCITY_MULTIPLIER = 1200f;
-
- private final Paint mHeaderPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
- private final Rect mInsets = new Rect();
-
- /** Context of an activity or window that is inflating this container. */
- protected final T mActivityContext;
- protected final List<AdapterHolder> mAH;
- protected final Predicate<ItemInfo> mPersonalMatcher = ItemInfoMatcher.ofUser(
- Process.myUserHandle());
- private final SearchAdapterProvider<?> mMainAdapterProvider;
- private final AllAppsStore mAllAppsStore = new AllAppsStore();
-
- private final RecyclerView.OnScrollListener mScrollListener =
- new RecyclerView.OnScrollListener() {
- @Override
- public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
- updateHeaderScroll(((AllAppsRecyclerView) recyclerView).getCurrentScrollY());
- }
- };
- private final WorkProfileManager mWorkManager;
-
- private final Paint mNavBarScrimPaint;
- private int mNavBarScrimHeight = 0;
-
- private AllAppsPagedView mViewPager;
- private SearchRecyclerView mSearchRecyclerView;
-
- protected FloatingHeaderView mHeader;
- private View mBottomSheetBackground;
- private View mBottomSheetHandleArea;
-
- protected boolean mUsingTabs;
- private boolean mHasWorkApps;
-
- protected RecyclerViewFastScroller mTouchHandler;
- protected final Point mFastScrollerOffset = new Point();
-
- private final int mScrimColor;
- private final int mHeaderProtectionColor;
- protected final float mHeaderThreshold;
- private int mHeaderBottomAdjustment;
- private ScrimView mScrimView;
- private int mHeaderColor;
- private int mTabsProtectionAlpha;
-
- protected BaseAllAppsContainerView(Context context, AttributeSet attrs, int defStyleAttr) {
- super(context, attrs, defStyleAttr);
- mActivityContext = ActivityContext.lookupContext(context);
- mMainAdapterProvider = createMainAdapterProvider();
-
- mScrimColor = Themes.getAttrColor(context, R.attr.allAppsScrimColor);
- mHeaderThreshold = getResources().getDimensionPixelSize(
- R.dimen.dynamic_grid_cell_border_spacing);
- mHeaderBottomAdjustment = getResources().getDimensionPixelSize(
- R.dimen.all_apps_header_bottom_adjustment);
- mHeaderProtectionColor = Themes.getAttrColor(context, R.attr.allappsHeaderProtectionColor);
-
- mWorkManager = new WorkProfileManager(
- mActivityContext.getSystemService(UserManager.class),
- this,
- Utilities.getPrefs(mActivityContext), mActivityContext.getDeviceProfile());
- mAH = Arrays.asList(null, null, null);
- mAH.set(AdapterHolder.MAIN, new AdapterHolder(AdapterHolder.MAIN));
- mAH.set(AdapterHolder.WORK, new AdapterHolder(AdapterHolder.WORK));
- mAH.set(AdapterHolder.SEARCH, new AdapterHolder(AdapterHolder.SEARCH));
-
- mNavBarScrimPaint = new Paint();
- mNavBarScrimPaint.setColor(Themes.getAttrColor(context, R.attr.allAppsNavBarScrimColor));
-
- mAllAppsStore.addUpdateListener(this::onAppsUpdated);
- mActivityContext.addOnDeviceProfileChangeListener(this);
- }
-
- /** Creates the adapter provider for the main section. */
- protected abstract SearchAdapterProvider<?> createMainAdapterProvider();
-
- /** The adapter provider for the main section. */
- public final SearchAdapterProvider<?> getMainAdapterProvider() {
- return mMainAdapterProvider;
- }
-
- @Override
- protected void dispatchRestoreInstanceState(SparseArray<Parcelable> sparseArray) {
- try {
- // Many slice view id is not properly assigned, and hence throws null
- // pointer exception in the underneath method. Catching the exception
- // simply doesn't restore these slice views. This doesn't have any
- // user visible effect because because we query them again.
- super.dispatchRestoreInstanceState(sparseArray);
- } catch (Exception e) {
- Log.e("AllAppsContainerView", "restoreInstanceState viewId = 0", e);
- }
-
- Bundle state = (Bundle) sparseArray.get(R.id.work_tab_state_id, null);
- if (state != null) {
- int currentPage = state.getInt(BUNDLE_KEY_CURRENT_PAGE, 0);
- if (currentPage == AdapterHolder.WORK && mViewPager != null) {
- mViewPager.setCurrentPage(currentPage);
- rebindAdapters();
- } else {
- reset(true);
- }
- }
-
- }
-
- @Override
- protected void dispatchSaveInstanceState(SparseArray<Parcelable> container) {
- super.dispatchSaveInstanceState(container);
- Bundle state = new Bundle();
- state.putInt(BUNDLE_KEY_CURRENT_PAGE, getCurrentPage());
- container.put(R.id.work_tab_state_id, state);
- }
-
- /**
- * Sets the long click listener for icons
- */
- public void setOnIconLongClickListener(OnLongClickListener listener) {
- for (AdapterHolder holder : mAH) {
- holder.mAdapter.setOnIconLongClickListener(listener);
- }
- }
-
- public AllAppsStore getAppsStore() {
- return mAllAppsStore;
- }
-
- public WorkProfileManager getWorkManager() {
- return mWorkManager;
- }
-
- @Override
- public void onDeviceProfileChanged(DeviceProfile dp) {
- for (AdapterHolder holder : mAH) {
- holder.mAdapter.setAppsPerRow(dp.numShownAllAppsColumns);
- if (holder.mRecyclerView != null) {
- // Remove all views and clear the pool, while keeping the data same. After this
- // call, all the viewHolders will be recreated.
- holder.mRecyclerView.swapAdapter(holder.mRecyclerView.getAdapter(), true);
- holder.mRecyclerView.getRecycledViewPool().clear();
- }
- }
- updateBackground(dp);
- }
-
- protected void updateBackground(DeviceProfile deviceProfile) {
- mBottomSheetBackground.setVisibility(deviceProfile.isTablet ? View.VISIBLE : View.GONE);
- }
-
- private void onAppsUpdated() {
- mHasWorkApps = Stream.of(mAllAppsStore.getApps()).anyMatch(mWorkManager.getMatcher());
- if (!isSearching()) {
- rebindAdapters();
- if (mHasWorkApps) {
- mWorkManager.reset();
- }
- }
- }
-
- /**
- * Returns whether the view itself will handle the touch event or not.
- */
- public boolean shouldContainerScroll(MotionEvent ev) {
- BaseDragLayer dragLayer = mActivityContext.getDragLayer();
- // Scroll if not within the container view (e.g. over large-screen scrim).
- if (!dragLayer.isEventOverView(this, ev)) {
- return true;
- }
- if (dragLayer.isEventOverView(mBottomSheetHandleArea, ev)) {
- return true;
- }
- AllAppsRecyclerView rv = getActiveRecyclerView();
- if (rv == null) {
- return true;
- }
- if (rv.getScrollbar() != null
- && rv.getScrollbar().getThumbOffsetY() >= 0
- && dragLayer.isEventOverView(rv.getScrollbar(), ev)) {
- return false;
- }
- return rv.shouldContainerScroll(ev, dragLayer);
- }
-
- @Override
- public boolean onInterceptTouchEvent(MotionEvent ev) {
- if (ev.getAction() == MotionEvent.ACTION_DOWN) {
- AllAppsRecyclerView rv = getActiveRecyclerView();
- if (rv != null && rv.getScrollbar() != null
- && rv.getScrollbar().isHitInParent(ev.getX(), ev.getY(), mFastScrollerOffset)) {
- mTouchHandler = rv.getScrollbar();
- } else {
- mTouchHandler = null;
- }
- }
- if (mTouchHandler != null) {
- return mTouchHandler.handleTouchEvent(ev, mFastScrollerOffset);
- }
- return false;
- }
-
- @Override
- public boolean onTouchEvent(MotionEvent ev) {
- if (ev.getAction() == MotionEvent.ACTION_DOWN) {
- AllAppsRecyclerView rv = getActiveRecyclerView();
- if (rv != null && rv.getScrollbar() != null
- && rv.getScrollbar().isHitInParent(ev.getX(), ev.getY(), mFastScrollerOffset)) {
- mTouchHandler = rv.getScrollbar();
- } else {
- mTouchHandler = null;
-
- }
- }
- if (mTouchHandler != null) {
- mTouchHandler.handleTouchEvent(ev, mFastScrollerOffset);
- return true;
- }
- if (isSearching()) {
- // if in search state, consume touch event.
- return true;
- }
- return false;
- }
-
- /** Description of the container view based on its current state. */
- public String getDescription() {
- StringCache cache = mActivityContext.getStringCache();
- if (mUsingTabs) {
- if (cache != null) {
- return isPersonalTab()
- ? cache.allAppsPersonalTabAccessibility
- : cache.allAppsWorkTabAccessibility;
- } else {
- return isPersonalTab()
- ? getContext().getString(R.string.all_apps_button_personal_label)
- : getContext().getString(R.string.all_apps_button_work_label);
- }
- }
- return getContext().getString(R.string.all_apps_button_label);
- }
-
- /** The current active recycler view (A-Z list from one of the profiles, or search results). */
- public AllAppsRecyclerView getActiveRecyclerView() {
- if (isSearching()) {
- return getSearchRecyclerView();
- }
- return getActiveAppsRecyclerView();
- }
-
- /** The current apps recycler view in the container. */
- private AllAppsRecyclerView getActiveAppsRecyclerView() {
- if (!mUsingTabs || isPersonalTab()) {
- return mAH.get(AdapterHolder.MAIN).mRecyclerView;
- } else {
- return mAH.get(AdapterHolder.WORK).mRecyclerView;
- }
- }
-
- /**
- * The container for A-Z apps (the ViewPager for main+work tabs, or main RV). This is currently
- * hidden while searching.
- **/
- private View getAppsRecyclerViewContainer() {
- return mViewPager != null ? mViewPager : findViewById(R.id.apps_list_view);
- }
-
- /** The RV for search results, which is hidden while A-Z apps are visible. */
- public SearchRecyclerView getSearchRecyclerView() {
- return mSearchRecyclerView;
- }
-
- protected boolean isPersonalTab() {
- return mViewPager == null || mViewPager.getNextPage() == 0;
- }
-
- /**
- * Switches the current page to the provided {@code tab} if tabs are supported, otherwise does
- * nothing.
- */
- public void switchToTab(int tab) {
- if (mUsingTabs) {
- mViewPager.setCurrentPage(tab);
- }
- }
-
- public LayoutInflater getLayoutInflater() {
- return LayoutInflater.from(getContext());
- }
-
- /**
- * Resets the state of AllApps.
- */
- public void reset(boolean animate) {
- for (int i = 0; i < mAH.size(); i++) {
- if (mAH.get(i).mRecyclerView != null) {
- mAH.get(i).mRecyclerView.scrollToTop();
- }
- }
- if (isHeaderVisible()) {
- mHeader.reset(animate);
- }
- // Reset the base recycler view after transitioning home.
- updateHeaderScroll(0);
- }
-
- @Override
- protected void onFinishInflate() {
- super.onFinishInflate();
-
- // This is a focus listener that proxies focus from a view into the list view. This is to
- // work around the search box from getting first focus and showing the cursor.
- setOnFocusChangeListener((v, hasFocus) -> {
- if (hasFocus && getActiveRecyclerView() != null) {
- getActiveRecyclerView().requestFocus();
- }
- });
-
- mHeader = findViewById(R.id.all_apps_header);
- mSearchRecyclerView = findViewById(R.id.search_results_list_view);
- mAH.get(AdapterHolder.SEARCH).setup(mSearchRecyclerView,
- /* Filter out A-Z apps */ itemInfo -> false);
- rebindAdapters(true /* force */);
-
- mBottomSheetBackground = findViewById(R.id.bottom_sheet_background);
- updateBackground(mActivityContext.getDeviceProfile());
-
- mBottomSheetHandleArea = findViewById(R.id.bottom_sheet_handle_area);
- }
-
- @Override
- public void onDropCompleted(View target, DragObject d, boolean success) {}
-
- @Override
- public void setInsets(Rect insets) {
- mInsets.set(insets);
- DeviceProfile grid = mActivityContext.getDeviceProfile();
-
- applyAdapterSideAndBottomPaddings(grid);
-
- MarginLayoutParams mlp = (MarginLayoutParams) getLayoutParams();
- mlp.leftMargin = insets.left;
- mlp.rightMargin = insets.right;
- setLayoutParams(mlp);
-
- if (grid.isVerticalBarLayout()) {
- setPadding(grid.workspacePadding.left, 0, grid.workspacePadding.right, 0);
- } else {
- setPadding(grid.allAppsLeftRightMargin, grid.allAppsTopPadding,
- grid.allAppsLeftRightMargin, 0);
- }
-
- InsettableFrameLayout.dispatchInsets(this, insets);
- }
-
- /**
- * Returns a padding in case a scrim is shown on the bottom of the view and a padding is needed.
- */
- protected int getNavBarScrimHeight(WindowInsets insets) {
- return 0;
- }
-
- @Override
- public WindowInsets dispatchApplyWindowInsets(WindowInsets insets) {
- mNavBarScrimHeight = getNavBarScrimHeight(insets);
- applyAdapterSideAndBottomPaddings(mActivityContext.getDeviceProfile());
- return super.dispatchApplyWindowInsets(insets);
- }
-
- @Override
- protected void dispatchDraw(Canvas canvas) {
- super.dispatchDraw(canvas);
-
- if (mNavBarScrimHeight > 0) {
- canvas.drawRect(0, getHeight() - mNavBarScrimHeight, getWidth(), getHeight(),
- mNavBarScrimPaint);
- }
- }
-
- protected void rebindAdapters() {
- rebindAdapters(false /* force */);
- }
-
- protected void rebindAdapters(boolean force) {
- updateSearchResultsVisibility();
-
- boolean showTabs = shouldShowTabs();
- if (showTabs == mUsingTabs && !force) {
- return;
- }
-
- if (isSearching()) {
- mUsingTabs = showTabs;
- mWorkManager.detachWorkModeSwitch();
- return;
- }
-
- // replaceAppsRVcontainer() needs to use both mUsingTabs value to remove the old view AND
- // showTabs value to create new view. Hence the mUsingTabs new value assignment MUST happen
- // after this call.
- replaceAppsRVContainer(showTabs);
- mUsingTabs = showTabs;
-
- mAllAppsStore.unregisterIconContainer(mAH.get(AdapterHolder.MAIN).mRecyclerView);
- mAllAppsStore.unregisterIconContainer(mAH.get(AdapterHolder.WORK).mRecyclerView);
-
- if (mUsingTabs) {
- mAH.get(AdapterHolder.MAIN).setup(mViewPager.getChildAt(0), mPersonalMatcher);
- mAH.get(AdapterHolder.WORK).setup(mViewPager.getChildAt(1), mWorkManager.getMatcher());
- mAH.get(AdapterHolder.WORK).mRecyclerView.setId(R.id.apps_list_view_work);
- mViewPager.getPageIndicator().setActiveMarker(AdapterHolder.MAIN);
- findViewById(R.id.tab_personal)
- .setOnClickListener((View view) -> {
- if (mViewPager.snapToPage(AdapterHolder.MAIN)) {
- mActivityContext.getStatsLogManager().logger()
- .log(LAUNCHER_ALLAPPS_TAP_ON_PERSONAL_TAB);
- }
- hideKeyboardAsync(ActivityContext.lookupContext(getContext()),
- getApplicationWindowToken());
- });
- findViewById(R.id.tab_work)
- .setOnClickListener((View view) -> {
- if (mViewPager.snapToPage(AdapterHolder.WORK)) {
- mActivityContext.getStatsLogManager().logger()
- .log(LAUNCHER_ALLAPPS_TAP_ON_WORK_TAB);
- }
- hideKeyboardAsync(ActivityContext.lookupContext(getContext()),
- getApplicationWindowToken());
- });
- setDeviceManagementResources();
- onActivePageChanged(mViewPager.getNextPage());
- } else {
- mAH.get(AdapterHolder.MAIN).setup(findViewById(R.id.apps_list_view), null);
- mAH.get(AdapterHolder.WORK).mRecyclerView = null;
- }
- setupHeader();
-
- mAllAppsStore.registerIconContainer(mAH.get(AdapterHolder.MAIN).mRecyclerView);
- mAllAppsStore.registerIconContainer(mAH.get(AdapterHolder.WORK).mRecyclerView);
- }
-
- private void updateSearchResultsVisibility() {
- if (isSearching()) {
- getSearchRecyclerView().setVisibility(VISIBLE);
- getAppsRecyclerViewContainer().setVisibility(GONE);
- } else {
- getSearchRecyclerView().setVisibility(GONE);
- getAppsRecyclerViewContainer().setVisibility(VISIBLE);
- }
- if (mHeader.isSetUp()) {
- mHeader.setActiveRV(getCurrentPage());
- }
- }
-
- private void applyAdapterSideAndBottomPaddings(DeviceProfile grid) {
- int bottomPadding = Math.max(mInsets.bottom, mNavBarScrimHeight);
- mAH.forEach(adapterHolder -> {
- adapterHolder.mPadding.bottom = bottomPadding;
- adapterHolder.mPadding.left =
- adapterHolder.mPadding.right = grid.allAppsLeftRightPadding;
- adapterHolder.applyPadding();
- });
- }
-
- private void setDeviceManagementResources() {
- if (mActivityContext.getStringCache() != null) {
- Button personalTab = findViewById(R.id.tab_personal);
- personalTab.setText(mActivityContext.getStringCache().allAppsPersonalTab);
-
- Button workTab = findViewById(R.id.tab_work);
- workTab.setText(mActivityContext.getStringCache().allAppsWorkTab);
- }
- }
-
- protected boolean shouldShowTabs() {
- return mHasWorkApps;
- }
-
- protected boolean isSearching() {
- return false;
- }
-
- protected View replaceAppsRVContainer(boolean showTabs) {
- for (int i = AdapterHolder.MAIN; i <= AdapterHolder.WORK; i++) {
- AdapterHolder adapterHolder = mAH.get(i);
- if (adapterHolder.mRecyclerView != null) {
- adapterHolder.mRecyclerView.setLayoutManager(null);
- adapterHolder.mRecyclerView.setAdapter(null);
- }
- }
- View oldView = getAppsRecyclerViewContainer();
- int index = indexOfChild(oldView);
- removeView(oldView);
- int layout = showTabs ? R.layout.all_apps_tabs : R.layout.all_apps_rv_layout;
- View newView = getLayoutInflater().inflate(layout, this, false);
- addView(newView, index);
- if (showTabs) {
- mViewPager = (AllAppsPagedView) newView;
- mViewPager.initParentViews(this);
- mViewPager.getPageIndicator().setOnActivePageChangedListener(this);
- if (mWorkManager.attachWorkModeSwitch()) {
- mWorkManager.getWorkModeSwitch().post(
- () -> mAH.get(AdapterHolder.WORK).applyPadding());
- }
- } else {
- mWorkManager.detachWorkModeSwitch();
- mViewPager = null;
- }
- return newView;
- }
-
- @Override
- public void onActivePageChanged(int currentActivePage) {
- if (mAH.get(currentActivePage).mRecyclerView != null) {
- mAH.get(currentActivePage).mRecyclerView.bindFastScrollbar();
- }
- reset(true /* animate */);
-
- mWorkManager.onActivePageChanged(currentActivePage);
- }
-
- // Used by tests only
- private boolean isDescendantViewVisible(int viewId) {
- final View view = findViewById(viewId);
- if (view == null) return false;
-
- if (!view.isShown()) return false;
-
- return view.getGlobalVisibleRect(new Rect());
- }
-
- @VisibleForTesting
- public boolean isPersonalTabVisible() {
- return isDescendantViewVisible(R.id.tab_personal);
- }
-
- @VisibleForTesting
- public boolean isWorkTabVisible() {
- return isDescendantViewVisible(R.id.tab_work);
- }
-
- public AlphabeticalAppsList<T> getSearchResultList() {
- return mAH.get(AdapterHolder.SEARCH).mAppsList;
- }
-
- public FloatingHeaderView getFloatingHeaderView() {
- return mHeader;
- }
-
- @VisibleForTesting
- public View getContentView() {
- return isSearching() ? getSearchRecyclerView() : getAppsRecyclerViewContainer();
- }
-
- /** The current page visible in all apps. */
- public int getCurrentPage() {
- return isSearching()
- ? AdapterHolder.SEARCH
- : mViewPager == null ? AdapterHolder.MAIN : mViewPager.getNextPage();
- }
-
- /** The scroll bar for the active apps recycler view. */
- public RecyclerViewFastScroller getScrollBar() {
- AllAppsRecyclerView rv = getActiveAppsRecyclerView();
- return rv == null ? null : rv.getScrollbar();
- }
-
- void setupHeader() {
- mHeader.setVisibility(View.VISIBLE);
- boolean tabsHidden = !mUsingTabs;
- mHeader.setup(
- mAH.get(AdapterHolder.MAIN).mRecyclerView,
- mAH.get(AdapterHolder.WORK).mRecyclerView,
- (SearchRecyclerView) mAH.get(AdapterHolder.SEARCH).mRecyclerView,
- getCurrentPage(),
- tabsHidden);
-
- int padding = mHeader.getMaxTranslation();
- mAH.forEach(adapterHolder -> {
- adapterHolder.mPadding.top = padding;
- adapterHolder.applyPadding();
- if (adapterHolder.mRecyclerView != null) {
- adapterHolder.mRecyclerView.scrollToTop();
- }
- });
- }
-
- public boolean isHeaderVisible() {
- return mHeader != null && mHeader.getVisibility() == View.VISIBLE;
- }
-
- /**
- * Adds an update listener to animator that adds springs to the animation.
- */
- public void addSpringFromFlingUpdateListener(ValueAnimator animator,
- float velocity /* release velocity */,
- float progress /* portion of the distance to travel*/) {
- animator.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationStart(Animator animator) {
- float distance = (1 - progress) * getHeight(); // px
- float settleVelocity = Math.min(0, distance
- / (AllAppsTransitionController.INTERP_COEFF * animator.getDuration())
- + velocity);
- absorbSwipeUpVelocity(Math.max(1000, Math.abs(
- Math.round(settleVelocity * FLING_VELOCITY_MULTIPLIER))));
- }
- });
- }
-
- /** Invoked when the container is pulled. */
- public void onPull(float deltaDistance, float displacement) {
- absorbPullDeltaDistance(PULL_MULTIPLIER * deltaDistance, PULL_MULTIPLIER * displacement);
- // Current motion spec is to actually push and not pull
- // on this surface. However, until EdgeEffect.onPush (b/190612804) is
- // implemented at view level, we will simply pull
- }
-
- @Override
- public void getDrawingRect(Rect outRect) {
- super.getDrawingRect(outRect);
- outRect.offset(0, (int) getTranslationY());
- }
-
- @Override
- public void setTranslationY(float translationY) {
- super.setTranslationY(translationY);
- invalidateHeader();
- }
-
- public void setScrimView(ScrimView scrimView) {
- mScrimView = scrimView;
- }
-
- @Override
- public void drawOnScrim(Canvas canvas) {
- if (!mHeader.isHeaderProtectionSupported()) {
- return;
- }
- mHeaderPaint.setColor(mHeaderColor);
- mHeaderPaint.setAlpha((int) (getAlpha() * Color.alpha(mHeaderColor)));
- if (mHeaderPaint.getColor() != mScrimColor && mHeaderPaint.getColor() != 0) {
- int bottom = getHeaderBottom();
- if (!mUsingTabs) {
- bottom += getFloatingHeaderView().getPaddingBottom() - mHeaderBottomAdjustment;
- }
- canvas.drawRect(0, 0, canvas.getWidth(), bottom, mHeaderPaint);
- int tabsHeight = getFloatingHeaderView().getPeripheralProtectionHeight();
- if (mTabsProtectionAlpha > 0 && tabsHeight != 0) {
- mHeaderPaint.setAlpha((int) (getAlpha() * mTabsProtectionAlpha));
- canvas.drawRect(0, bottom, canvas.getWidth(), bottom + tabsHeight, mHeaderPaint);
- }
- }
- }
-
- /**
- * redraws header protection
- */
- public void invalidateHeader() {
- if (mScrimView != null && mHeader.isHeaderProtectionSupported()) {
- mScrimView.invalidate();
- }
- }
-
- protected void updateHeaderScroll(int scrolledOffset) {
- float prog = Utilities.boundToRange((float) scrolledOffset / mHeaderThreshold, 0f, 1f);
- int headerColor = getHeaderColor(prog);
- int tabsAlpha = mHeader.getPeripheralProtectionHeight() == 0 ? 0
- : (int) (Utilities.boundToRange(
- (scrolledOffset + mHeader.mSnappedScrolledY) / mHeaderThreshold, 0f, 1f)
- * 255);
- if (headerColor != mHeaderColor || mTabsProtectionAlpha != tabsAlpha) {
- mHeaderColor = headerColor;
- mTabsProtectionAlpha = tabsAlpha;
- invalidateHeader();
- }
- }
-
- protected int getHeaderColor(float blendRatio) {
- return ColorUtils.blendARGB(mScrimColor, mHeaderProtectionColor, blendRatio);
- }
-
- protected abstract BaseAllAppsAdapter<T> createAdapter(AlphabeticalAppsList<T> mAppsList,
- BaseAdapterProvider[] adapterProviders);
-
- public int getHeaderBottom() {
- return (int) getTranslationY();
- }
-
- /**
- * Returns a view that denotes the visible part of all apps container view.
- */
- public View getVisibleContainerView() {
- return mActivityContext.getDeviceProfile().isTablet ? mBottomSheetBackground : this;
- }
-
- /** Holds a {@link BaseAllAppsAdapter} and related fields. */
- public class AdapterHolder {
- public static final int MAIN = 0;
- public static final int WORK = 1;
- public static final int SEARCH = 2;
-
- private final int mType;
- public final BaseAllAppsAdapter<T> mAdapter;
- final RecyclerView.LayoutManager mLayoutManager;
- final AlphabeticalAppsList<T> mAppsList;
- final Rect mPadding = new Rect();
- AllAppsRecyclerView mRecyclerView;
-
- AdapterHolder(int type) {
- mType = type;
- mAppsList = new AlphabeticalAppsList<>(mActivityContext,
- isSearch() ? null : mAllAppsStore,
- isWork() ? mWorkManager.getAdapterProvider() : null);
-
- BaseAdapterProvider[] adapterProviders =
- isWork() ? new BaseAdapterProvider[]{mMainAdapterProvider,
- mWorkManager.getAdapterProvider()}
- : new BaseAdapterProvider[]{mMainAdapterProvider};
-
- mAdapter = createAdapter(mAppsList, adapterProviders);
- mAppsList.setAdapter(mAdapter);
- mLayoutManager = mAdapter.getLayoutManager();
- }
-
- void setup(@NonNull View rv, @Nullable Predicate<ItemInfo> matcher) {
- mAppsList.updateItemFilter(matcher);
- mRecyclerView = (AllAppsRecyclerView) rv;
- mRecyclerView.setEdgeEffectFactory(createEdgeEffectFactory());
- mRecyclerView.setApps(mAppsList);
- mRecyclerView.setLayoutManager(mLayoutManager);
- mRecyclerView.setAdapter(mAdapter);
- mRecyclerView.setHasFixedSize(true);
- // No animations will occur when changes occur to the items in this RecyclerView.
- mRecyclerView.setItemAnimator(null);
- mRecyclerView.addOnScrollListener(mScrollListener);
- FocusedItemDecorator focusedItemDecorator = new FocusedItemDecorator(mRecyclerView);
- mRecyclerView.addItemDecoration(focusedItemDecorator);
- mAdapter.setIconFocusListener(focusedItemDecorator.getFocusListener());
- applyPadding();
- }
-
- void applyPadding() {
- if (mRecyclerView != null) {
- int bottomOffset = 0;
- if (isWork() && mWorkManager.getWorkModeSwitch() != null) {
- bottomOffset = mInsets.bottom + mWorkManager.getWorkModeSwitch().getHeight();
- }
- mRecyclerView.setPadding(mPadding.left, mPadding.top, mPadding.right,
- mPadding.bottom + bottomOffset);
- }
- }
-
- private boolean isWork() {
- return mType == WORK;
- }
-
- private boolean isSearch() {
- return mType == SEARCH;
- }
- }
-}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarSharedState.java b/src/com/android/launcher3/allapps/DecorationInfo.java
index 87b3789740..50b250cad1 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarSharedState.java
+++ b/src/com/android/launcher3/allapps/DecorationInfo.java
@@ -13,16 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.android.launcher3.taskbar;
+package com.android.launcher3.allapps;
-/**
- * State shared across different taskbar instance
- */
-public class TaskbarSharedState {
-
- public int sysuiStateFlags;
-
- public boolean setupUIVisible = false;
-
- public boolean allAppsVisible = false;
+public class DecorationInfo {
}
diff --git a/src/com/android/launcher3/allapps/FloatingHeaderRow.java b/src/com/android/launcher3/allapps/FloatingHeaderRow.java
index 6ff2132286..9bf60433ff 100644
--- a/src/com/android/launcher3/allapps/FloatingHeaderRow.java
+++ b/src/com/android/launcher3/allapps/FloatingHeaderRow.java
@@ -47,8 +47,6 @@ public interface FloatingHeaderRow {
/**
* Scrolls the content vertically.
- * @param scroll scrolled distance in pixels for active recyclerview.
- * @param isScrolledOut bool to determine if row is scrolled out of view
*/
void setVerticalScroll(int scroll, boolean isScrolledOut);
diff --git a/src/com/android/launcher3/allapps/FloatingHeaderView.java b/src/com/android/launcher3/allapps/FloatingHeaderView.java
index 6ecbad24e8..8ea83d56ac 100644
--- a/src/com/android/launcher3/allapps/FloatingHeaderView.java
+++ b/src/com/android/launcher3/allapps/FloatingHeaderView.java
@@ -17,6 +17,9 @@ package com.android.launcher3.allapps;
import android.animation.ValueAnimator;
import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.Rect;
import android.util.ArrayMap;
@@ -30,13 +33,12 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.RecyclerView;
+import com.android.launcher3.BaseDraggingActivity;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Insettable;
import com.android.launcher3.R;
-import com.android.launcher3.allapps.BaseAllAppsContainerView.AdapterHolder;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.uioverrides.plugins.PluginManagerWrapper;
-import com.android.launcher3.views.ActivityContext;
import com.android.systemui.plugins.AllAppsRow;
import com.android.systemui.plugins.AllAppsRow.OnHeightUpdatedListener;
import com.android.systemui.plugins.PluginListener;
@@ -48,17 +50,19 @@ public class FloatingHeaderView extends LinearLayout implements
ValueAnimator.AnimatorUpdateListener, PluginListener<AllAppsRow>, Insettable,
OnHeightUpdatedListener {
- private final Rect mRVClip = new Rect(0, 0, Integer.MAX_VALUE, Integer.MAX_VALUE);
- private final Rect mHeaderClip = new Rect(0, 0, Integer.MAX_VALUE, Integer.MAX_VALUE);
+ private final Rect mClip = new Rect(0, 0, Integer.MAX_VALUE, Integer.MAX_VALUE);
private final ValueAnimator mAnimator = ValueAnimator.ofInt(0, 0);
+ private final ValueAnimator mHeaderAnimator = ValueAnimator.ofInt(0, 1).setDuration(100);
private final Point mTempOffset = new Point();
+ private final Paint mBGPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private final RecyclerView.OnScrollListener mOnScrollListener =
new RecyclerView.OnScrollListener() {
@Override
- public void onScrollStateChanged(@NonNull RecyclerView rv, int newState) {}
+ public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
+ }
@Override
- public void onScrolled(@NonNull RecyclerView rv, int dx, int dy) {
+ public void onScrolled(RecyclerView rv, int dx, int dy) {
if (rv != mCurrentRV) {
return;
}
@@ -72,33 +76,31 @@ public class FloatingHeaderView extends LinearLayout implements
moved(current);
applyVerticalMove();
if (headerCollapsed != mHeaderCollapsed) {
- BaseAllAppsContainerView<?> parent =
- (BaseAllAppsContainerView<?>) getParent();
+ AllAppsContainerView parent = (AllAppsContainerView) getParent();
parent.invalidateHeader();
}
}
};
- protected final Map<AllAppsRow, PluginHeaderRow> mPluginRows = new ArrayMap<>();
+ private final int mHeaderTopPadding;
- // These two values are necessary to ensure that the header protection is drawn correctly.
- private final int mHeaderTopAdjustment;
- private final int mHeaderBottomAdjustment;
- private final boolean mHeaderProtectionSupported;
+ protected final Map<AllAppsRow, PluginHeaderRow> mPluginRows = new ArrayMap<>();
protected ViewGroup mTabLayout;
private AllAppsRecyclerView mMainRV;
private AllAppsRecyclerView mWorkRV;
- private SearchRecyclerView mSearchRV;
private AllAppsRecyclerView mCurrentRV;
+ private ViewGroup mParent;
public boolean mHeaderCollapsed;
- protected int mSnappedScrolledY;
+ private int mSnappedScrolledY;
private int mTranslationY;
+ private int mHeaderColor;
private boolean mForwardToRecyclerView;
protected boolean mTabsHidden;
protected int mMaxTranslation;
+ private boolean mMainRVActive = true;
private boolean mCollapsed = false;
@@ -110,21 +112,14 @@ public class FloatingHeaderView extends LinearLayout implements
// enabled or disabled, and represent the current set of all rows.
private FloatingHeaderRow[] mAllRows = FloatingHeaderRow.NO_ROWS;
-
public FloatingHeaderView(@NonNull Context context) {
this(context, null);
}
public FloatingHeaderView(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
- mHeaderTopAdjustment = context.getResources()
- .getDimensionPixelSize(R.dimen.all_apps_header_top_adjustment);
- mHeaderBottomAdjustment = context.getResources()
- .getDimensionPixelSize(R.dimen.all_apps_header_bottom_adjustment);
- mHeaderProtectionSupported = context.getResources().getBoolean(
- R.bool.config_header_protection_supported)
- // TODO(b/208599118) Support header protection for bottom sheet.
- && !ActivityContext.lookupContext(context).getDeviceProfile().isTablet;
+ mHeaderTopPadding = context.getResources()
+ .getDimensionPixelSize(R.dimen.all_apps_header_top_padding);
}
@Override
@@ -143,6 +138,7 @@ public class FloatingHeaderView extends LinearLayout implements
}
mFixedRows = rows.toArray(new FloatingHeaderRow[rows.size()]);
mAllRows = mFixedRows;
+ mHeaderAnimator.addUpdateListener(valueAnimator -> invalidate());
}
@Override
@@ -160,20 +156,12 @@ public class FloatingHeaderView extends LinearLayout implements
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- mTabLayout.getLayoutParams().width = getTabWidth();
+ if (mMainRV != null) {
+ mTabLayout.getLayoutParams().width = mMainRV.getTabWidth();
+ }
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
- /**
- * Returns distance between left and right app icons
- */
- public int getTabWidth() {
- DeviceProfile grid = ActivityContext.lookupContext(getContext()).getDeviceProfile();
- int totalWidth = getMeasuredWidth() - getPaddingLeft() - getPaddingRight();
- int iconPadding = totalWidth / grid.numShownAllAppsColumns - grid.allAppsIconSizePx;
- return totalWidth - iconPadding - grid.allAppsIconDrawablePaddingPx;
- }
-
private void recreateAllRowsArray() {
int pluginCount = mPluginRows.size();
if (pluginCount == 0) {
@@ -206,8 +194,8 @@ public class FloatingHeaderView extends LinearLayout implements
int oldMaxHeight = mMaxTranslation;
updateExpectedHeight();
- if (mMaxTranslation != oldMaxHeight || mCollapsed) {
- BaseAllAppsContainerView<?> parent = (BaseAllAppsContainerView<?>) getParent();
+ if (mMaxTranslation != oldMaxHeight) {
+ AllAppsContainerView parent = (AllAppsContainerView) getParent();
if (parent != null) {
parent.setupHeader();
}
@@ -236,8 +224,7 @@ public class FloatingHeaderView extends LinearLayout implements
return super.getFocusedChild();
}
- void setup(AllAppsRecyclerView mainRV, AllAppsRecyclerView workRV, SearchRecyclerView searchRV,
- int activeRV, boolean tabsHidden) {
+ public void setup(AllAppsContainerView.AdapterHolder[] mAH, boolean tabsHidden) {
for (FloatingHeaderRow row : mAllRows) {
row.setup(this, mAllRows, tabsHidden);
}
@@ -245,27 +232,18 @@ public class FloatingHeaderView extends LinearLayout implements
mTabsHidden = tabsHidden;
mTabLayout.setVisibility(tabsHidden ? View.GONE : View.VISIBLE);
- mMainRV = mainRV;
- mWorkRV = workRV;
- mSearchRV = searchRV;
- setActiveRV(activeRV);
+ mMainRV = setupRV(mMainRV, mAH[AllAppsContainerView.AdapterHolder.MAIN].recyclerView);
+ mWorkRV = setupRV(mWorkRV, mAH[AllAppsContainerView.AdapterHolder.WORK].recyclerView);
+ mParent = (ViewGroup) mMainRV.getParent();
+ setMainActive(mMainRVActive || mWorkRV == null);
reset(false);
}
- /** Whether this header has been set up previously. */
- boolean isSetUp() {
- return mMainRV != null;
- }
-
- /** Set the active AllApps RV which will adjust the alpha of the header when scrolled. */
- void setActiveRV(int rvType) {
- if (mCurrentRV != null) {
- mCurrentRV.removeOnScrollListener(mOnScrollListener);
+ private AllAppsRecyclerView setupRV(AllAppsRecyclerView old, AllAppsRecyclerView updated) {
+ if (old != updated && updated != null) {
+ updated.addOnScrollListener(mOnScrollListener);
}
- mCurrentRV =
- rvType == AdapterHolder.MAIN ? mMainRV
- : rvType == AdapterHolder.WORK ? mWorkRV : mSearchRV;
- mCurrentRV.addOnScrollListener(mOnScrollListener);
+ return updated;
}
private void updateExpectedHeight() {
@@ -276,9 +254,11 @@ public class FloatingHeaderView extends LinearLayout implements
for (FloatingHeaderRow row : mAllRows) {
mMaxTranslation += row.getExpectedHeight();
}
- if (!mTabsHidden) {
- mMaxTranslation += mHeaderBottomAdjustment;
- }
+ }
+
+ public void setMainActive(boolean active) {
+ mCurrentRV = active ? mMainRV : mWorkRV;
+ mMainRVActive = active;
}
public int getMaxTranslation() {
@@ -305,7 +285,7 @@ public class FloatingHeaderView extends LinearLayout implements
mHeaderCollapsed = false;
}
mTranslationY = currentScrollY;
- } else {
+ } else if (!mHeaderCollapsed) {
mTranslationY = currentScrollY - mSnappedScrolledY - mMaxTranslation;
// update state vars
@@ -315,15 +295,36 @@ public class FloatingHeaderView extends LinearLayout implements
} else if (mTranslationY <= -mMaxTranslation) { // hide or stay hidden
mHeaderCollapsed = true;
mSnappedScrolledY = -mMaxTranslation;
+ mHeaderAnimator.setCurrentFraction(0);
+ mHeaderAnimator.start();
}
}
}
+ /**
+ * Set current header protection background color
+ */
+ public void setHeaderColor(int color) {
+ mHeaderColor = color;
+ invalidate();
+ }
+
+ @Override
+ protected void dispatchDraw(Canvas canvas) {
+ if (mHeaderCollapsed && !mCollapsed && mTabLayout.getVisibility() == VISIBLE
+ && mHeaderColor != Color.TRANSPARENT && FeatureFlags.ENABLE_DEVICE_SEARCH.get()) {
+ mBGPaint.setColor(mHeaderColor);
+ mBGPaint.setAlpha((int) (255 * mHeaderAnimator.getAnimatedFraction()));
+ canvas.drawRect(0, 0, getWidth(), getHeight() + mTranslationY, mBGPaint);
+ }
+ super.dispatchDraw(canvas);
+ }
+
protected void applyVerticalMove() {
int uncappedTranslationY = mTranslationY;
mTranslationY = Math.max(mTranslationY, -mMaxTranslation);
- if (mCollapsed || uncappedTranslationY < mTranslationY - getPaddingTop()) {
+ if (mCollapsed || uncappedTranslationY < mTranslationY - mHeaderTopPadding) {
// we hide it completely if already capped (for opening search anim)
for (FloatingHeaderRow row : mAllRows) {
row.setVerticalScroll(0, true /* isScrolledOut */);
@@ -335,23 +336,11 @@ public class FloatingHeaderView extends LinearLayout implements
}
mTabLayout.setTranslationY(mTranslationY);
-
- int clipTop = getPaddingTop() - mHeaderTopAdjustment;
- if (mTabsHidden) {
- clipTop += getPaddingBottom() - mHeaderBottomAdjustment;
- }
- mRVClip.top = mTabsHidden ? clipTop : 0;
- mHeaderClip.top = clipTop;
+ mClip.top = mMaxTranslation + mTranslationY;
// clipping on a draw might cause additional redraw
- setClipBounds(mHeaderClip);
- if (mMainRV != null) {
- mMainRV.setClipBounds(mRVClip);
- }
+ mMainRV.setClipBounds(mClip);
if (mWorkRV != null) {
- mWorkRV.setClipBounds(mRVClip);
- }
- if (mSearchRV != null) {
- mSearchRV.setClipBounds(mRVClip);
+ mWorkRV.setClipBounds(mClip);
}
}
@@ -419,8 +408,8 @@ public class FloatingHeaderView extends LinearLayout implements
}
private void calcOffset(Point p) {
- p.x = getLeft() - mCurrentRV.getLeft() - ((ViewGroup) mCurrentRV.getParent()).getLeft();
- p.y = getTop() - mCurrentRV.getTop() - ((ViewGroup) mCurrentRV.getParent()).getTop();
+ p.x = getLeft() - mCurrentRV.getLeft() - mParent.getLeft();
+ p.y = getTop() - mCurrentRV.getTop() - mParent.getTop();
}
public boolean hasVisibleContent() {
@@ -432,10 +421,6 @@ public class FloatingHeaderView extends LinearLayout implements
return false;
}
- public boolean isHeaderProtectionSupported() {
- return mHeaderProtectionSupported;
- }
-
@Override
public boolean hasOverlappingRendering() {
return false;
@@ -443,7 +428,7 @@ public class FloatingHeaderView extends LinearLayout implements
@Override
public void setInsets(Rect insets) {
- DeviceProfile grid = ActivityContext.lookupContext(getContext()).getDeviceProfile();
+ DeviceProfile grid = BaseDraggingActivity.fromContext(getContext()).getDeviceProfile();
for (FloatingHeaderRow row : mAllRows) {
row.setInsets(insets, grid);
}
@@ -459,18 +444,11 @@ public class FloatingHeaderView extends LinearLayout implements
}
/**
- * Returns visible height of FloatingHeaderView contents requiring header protection
+ * Returns visible height of FloatingHeaderView contents
*/
- public int getPeripheralProtectionHeight() {
- if (!mHeaderProtectionSupported) {
- return 0;
- }
-
- // we only want to show protection when work tab is available and header is either
- // collapsed or animating to/from collapsed state
- if (mTabsHidden || !mHeaderCollapsed) {
- return 0;
- }
- return Math.max(getHeight() - getPaddingTop() + mTranslationY, 0);
+ public int getVisibleBottomBound() {
+ return getBottom() + mTranslationY;
}
}
+
+
diff --git a/src/com/android/launcher3/allapps/LauncherAllAppsContainerView.java b/src/com/android/launcher3/allapps/LauncherAllAppsContainerView.java
index 20f5e7440d..f64b7cbd6c 100644
--- a/src/com/android/launcher3/allapps/LauncherAllAppsContainerView.java
+++ b/src/com/android/launcher3/allapps/LauncherAllAppsContainerView.java
@@ -16,18 +16,22 @@
package com.android.launcher3.allapps;
import android.content.Context;
+import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.MotionEvent;
-import android.view.WindowInsets;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherState;
-import com.android.launcher3.Utilities;
+import com.android.launcher3.statemanager.StateManager.StateListener;
/**
* AllAppsContainerView with launcher specific callbacks
*/
-public class LauncherAllAppsContainerView extends ActivityAllAppsContainerView<Launcher> {
+public class LauncherAllAppsContainerView extends AllAppsContainerView {
+
+ private final Launcher mLauncher;
+
+ private StateListener<LauncherState> mWorkTabListener;
public LauncherAllAppsContainerView(Context context) {
this(context, null);
@@ -39,13 +43,14 @@ public class LauncherAllAppsContainerView extends ActivityAllAppsContainerView<L
public LauncherAllAppsContainerView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
+ mLauncher = Launcher.getLauncher(context);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
// The AllAppsContainerView houses the QSB and is hence visible from the Workspace
// Overview states. We shouldn't intercept for the scrubber in these cases.
- if (!mActivityContext.isInState(LauncherState.ALL_APPS)) {
+ if (!mLauncher.isInState(LauncherState.ALL_APPS)) {
mTouchHandler = null;
return false;
}
@@ -55,18 +60,30 @@ public class LauncherAllAppsContainerView extends ActivityAllAppsContainerView<L
@Override
public boolean onTouchEvent(MotionEvent ev) {
- if (!mActivityContext.isInState(LauncherState.ALL_APPS)) {
+ if (!mLauncher.isInState(LauncherState.ALL_APPS)) {
return false;
}
return super.onTouchEvent(ev);
}
@Override
- protected int getNavBarScrimHeight(WindowInsets insets) {
- if (Utilities.ATLEAST_Q) {
- return insets.getTappableElementInsets().bottom;
- } else {
- return insets.getStableInsetBottom();
+ public void setInsets(Rect insets) {
+ super.setInsets(insets);
+ int allAppsStartingPositionY = mLauncher.getDeviceProfile().availableHeightPx
+ - mLauncher.getDeviceProfile().allAppsOpenVerticalTranslate;
+ mLauncher.getAllAppsController().setScrollRangeDelta(allAppsStartingPositionY);
+ }
+
+ @Override
+ public void setupHeader() {
+ super.setupHeader();
+ if (mWorkTabListener != null && !mUsingTabs) {
+ mLauncher.getStateManager().removeStateListener(mWorkTabListener);
}
}
+
+ @Override
+ public void onActivePageChanged(int currentActivePage) {
+ super.onActivePageChanged(currentActivePage);
+ }
}
diff --git a/src/com/android/launcher3/allapps/SearchRecyclerView.java b/src/com/android/launcher3/allapps/SearchRecyclerView.java
deleted file mode 100644
index 482bd296f0..0000000000
--- a/src/com/android/launcher3/allapps/SearchRecyclerView.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.launcher3.allapps;
-
-import android.content.Context;
-import android.util.AttributeSet;
-
-import com.android.launcher3.views.RecyclerViewFastScroller;
-
-/** A RecyclerView for AllApps Search results. */
-public class SearchRecyclerView extends AllAppsRecyclerView {
- private static final String TAG = "SearchRecyclerView";
-
- public SearchRecyclerView(Context context) {
- this(context, null);
- }
-
- public SearchRecyclerView(Context context, AttributeSet attrs) {
- this(context, attrs, 0);
- }
-
- public SearchRecyclerView(Context context, AttributeSet attrs, int defStyleAttr) {
- this(context, attrs, defStyleAttr, 0);
- }
-
- public SearchRecyclerView(Context context, AttributeSet attrs, int defStyleAttr,
- int defStyleRes) {
- super(context, attrs, defStyleAttr, defStyleRes);
- }
-
- @Override
- protected void updatePoolSize() {
- RecycledViewPool pool = getRecycledViewPool();
- pool.setMaxRecycledViews(AllAppsGridAdapter.VIEW_TYPE_ICON, mNumAppsPerRow);
- // TODO(b/206905515): Add maxes for other View types.
- }
-
- @Override
- public boolean supportsFastScrolling() {
- return false;
- }
-
- @Override
- public RecyclerViewFastScroller getScrollbar() {
- return null;
- }
-}
diff --git a/src/com/android/launcher3/allapps/SearchUiManager.java b/src/com/android/launcher3/allapps/SearchUiManager.java
index 6138bc4a9d..924a392389 100644
--- a/src/com/android/launcher3/allapps/SearchUiManager.java
+++ b/src/com/android/launcher3/allapps/SearchUiManager.java
@@ -29,7 +29,7 @@ public interface SearchUiManager {
/**
* Initializes the search manager.
*/
- void initializeSearch(ActivityAllAppsContainerView<?> containerView);
+ void initializeSearch(AllAppsContainerView containerView);
/**
* Notifies the search manager to close any active search session.
@@ -49,28 +49,7 @@ public interface SearchUiManager {
ExtendedEditText getEditText();
/**
- * Sets whether EditText background should be visible
- * @param maxAlpha defines the maximum alpha the background should animates to
- */
- default void setBackgroundVisibility(boolean visible, float maxAlpha) {}
-
- /**
- * Returns whether a visible background is set on EditText
- */
- default boolean getBackgroundVisibility() {
- return false;
- }
-
- /**
* sets highlight result's title
*/
default void setFocusedResultTitle(@Nullable CharSequence title) { }
-
- /** Refresh the currently displayed list of results. */
- default void refreshResults() {}
-
- /** Returns whether search is in zero state. */
- default boolean inZeroState() {
- return false;
- }
}
diff --git a/src/com/android/launcher3/allapps/SecondaryLauncherAllAppsContainerView.java b/src/com/android/launcher3/allapps/SecondaryLauncherAllAppsContainerView.java
deleted file mode 100644
index 0719c4342f..0000000000
--- a/src/com/android/launcher3/allapps/SecondaryLauncherAllAppsContainerView.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.launcher3.allapps;
-
-import android.content.Context;
-import android.util.AttributeSet;
-
-import com.android.launcher3.DeviceProfile;
-import com.android.launcher3.secondarydisplay.SecondaryDisplayLauncher;
-
-/**
- * AllAppsContainerView for secondary launcher
- */
-public class SecondaryLauncherAllAppsContainerView extends
- ActivityAllAppsContainerView<SecondaryDisplayLauncher> {
-
- public SecondaryLauncherAllAppsContainerView(Context context) {
- this(context, null);
- }
-
- public SecondaryLauncherAllAppsContainerView(Context context, AttributeSet attrs) {
- this(context, attrs, 0);
- }
-
- public SecondaryLauncherAllAppsContainerView(Context context, AttributeSet attrs,
- int defStyleAttr) {
- super(context, attrs, defStyleAttr);
- }
-
- @Override
- protected void updateBackground(DeviceProfile deviceProfile) {}
-}
diff --git a/src/com/android/launcher3/allapps/WorkAdapterProvider.java b/src/com/android/launcher3/allapps/WorkAdapterProvider.java
index 76d08c8084..13444dd185 100644
--- a/src/com/android/launcher3/allapps/WorkAdapterProvider.java
+++ b/src/com/android/launcher3/allapps/WorkAdapterProvider.java
@@ -15,16 +15,12 @@
*/
package com.android.launcher3.allapps;
-import android.content.SharedPreferences;
import android.view.LayoutInflater;
-import android.view.View;
import android.view.ViewGroup;
-import android.widget.TextView;
+import com.android.launcher3.BaseDraggingActivity;
import com.android.launcher3.R;
-import com.android.launcher3.allapps.BaseAllAppsAdapter.AdapterItem;
-import com.android.launcher3.model.StringCache;
-import com.android.launcher3.views.ActivityContext;
+import com.android.launcher3.Utilities;
import java.util.ArrayList;
@@ -37,15 +33,13 @@ public class WorkAdapterProvider extends BaseAdapterProvider {
private static final int VIEW_TYPE_WORK_EDU_CARD = 1 << 20;
private static final int VIEW_TYPE_WORK_DISABLED_CARD = 1 << 21;
+ private final Runnable mRefreshCB;
+ private final BaseDraggingActivity mLauncher;
+ private boolean mEnabled;
- @WorkProfileManager.WorkProfileState
- private int mState;
- private ActivityContext mActivityContext;
- private SharedPreferences mPreferences;
-
- WorkAdapterProvider(ActivityContext activityContext, SharedPreferences prefs) {
- mActivityContext = activityContext;
- mPreferences = prefs;
+ WorkAdapterProvider(BaseDraggingActivity launcher, Runnable refreshCallback) {
+ mLauncher = launcher;
+ mRefreshCB = refreshCallback;
}
@Override
@@ -60,56 +54,29 @@ public class WorkAdapterProvider extends BaseAdapterProvider {
ViewGroup parent, int viewType) {
int viewId = viewType == VIEW_TYPE_WORK_DISABLED_CARD ? R.layout.work_apps_paused
: R.layout.work_apps_edu;
- View view = layoutInflater.inflate(viewId, parent, false);
- setDeviceManagementResources(view, viewType);
- return new AllAppsGridAdapter.ViewHolder(view);
- }
-
- private void setDeviceManagementResources(View view, int viewType) {
- StringCache cache = mActivityContext.getStringCache();
- if (cache == null) {
- return;
- }
- if (viewType == VIEW_TYPE_WORK_DISABLED_CARD) {
- setWorkProfilePausedResources(view, cache);
- } else {
- setWorkProfileEduResources(view, cache);
- }
- }
-
- private void setWorkProfilePausedResources(View view, StringCache cache) {
- TextView title = view.findViewById(R.id.work_apps_paused_title);
- title.setText(cache.workProfilePausedTitle);
-
- TextView body = view.findViewById(R.id.work_apps_paused_content);
- body.setText(cache.workProfilePausedDescription);
-
- TextView button = view.findViewById(R.id.enable_work_apps);
- button.setText(cache.workProfileEnableButton);
- }
-
- private void setWorkProfileEduResources(View view, StringCache cache) {
- TextView title = view.findViewById(R.id.work_apps_paused_title);
- title.setText(cache.workProfileEdu);
-
+ return new AllAppsGridAdapter.ViewHolder(layoutInflater.inflate(viewId, parent, false));
}
/**
* returns whether or not work apps should be visible in work tab.
*/
public boolean shouldShowWorkApps() {
- return mState != WorkProfileManager.STATE_DISABLED;
+ return mEnabled;
}
/**
* Adds work profile specific adapter items to adapterItems and returns number of items added
*/
public int addWorkItems(ArrayList<AllAppsGridAdapter.AdapterItem> adapterItems) {
- if (mState == WorkProfileManager.STATE_DISABLED) {
+ if (!mEnabled) {
//add disabled card here.
- adapterItems.add(new AdapterItem(VIEW_TYPE_WORK_DISABLED_CARD));
- } else if (mState == WorkProfileManager.STATE_ENABLED && !isEduSeen()) {
- adapterItems.add(new AdapterItem(VIEW_TYPE_WORK_EDU_CARD));
+ AllAppsGridAdapter.AdapterItem disabledCard = new AllAppsGridAdapter.AdapterItem();
+ disabledCard.viewType = VIEW_TYPE_WORK_DISABLED_CARD;
+ adapterItems.add(disabledCard);
+ } else if (!isEduSeen()) {
+ AllAppsGridAdapter.AdapterItem eduCard = new AllAppsGridAdapter.AdapterItem();
+ eduCard.viewType = VIEW_TYPE_WORK_EDU_CARD;
+ adapterItems.add(eduCard);
}
return adapterItems.size();
@@ -118,8 +85,9 @@ public class WorkAdapterProvider extends BaseAdapterProvider {
/**
* Sets the current state of work profile
*/
- public void updateCurrentState(@WorkProfileManager.WorkProfileState int state) {
- mState = state;
+ public void updateCurrentState(boolean isEnabled) {
+ mEnabled = isEnabled;
+ mRefreshCB.run();
}
@Override
@@ -133,6 +101,6 @@ public class WorkAdapterProvider extends BaseAdapterProvider {
}
private boolean isEduSeen() {
- return mPreferences.getInt(KEY_WORK_EDU_STEP, 0) != 0;
+ return Utilities.getPrefs(mLauncher).getInt(KEY_WORK_EDU_STEP, 0) != 0;
}
}
diff --git a/src/com/android/launcher3/allapps/WorkEduCard.java b/src/com/android/launcher3/allapps/WorkEduCard.java
index 836cd5af93..9db7bf01ac 100644
--- a/src/com/android/launcher3/allapps/WorkEduCard.java
+++ b/src/com/android/launcher3/allapps/WorkEduCard.java
@@ -23,18 +23,16 @@ import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.FrameLayout;
+import com.android.launcher3.Launcher;
import com.android.launcher3.R;
-import com.android.launcher3.Utilities;
-import com.android.launcher3.views.ActivityContext;
/**
* Work profile toggle switch shown at the bottom of AllApps work tab
*/
-public class WorkEduCard extends FrameLayout implements
- View.OnClickListener,
+public class WorkEduCard extends FrameLayout implements View.OnClickListener,
Animation.AnimationListener {
- private final ActivityContext mActivityContext;
+ private final Launcher mLauncher;
Animation mDismissAnim;
private int mPosition = -1;
@@ -48,7 +46,7 @@ public class WorkEduCard extends FrameLayout implements
public WorkEduCard(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
- mActivityContext = ActivityContext.lookupContext(getContext());
+ mLauncher = Launcher.getLauncher(getContext());
mDismissAnim = AnimationUtils.loadAnimation(context, android.R.anim.fade_out);
mDismissAnim.setDuration(500);
mDismissAnim.setAnimationListener(this);
@@ -71,14 +69,13 @@ public class WorkEduCard extends FrameLayout implements
super.onFinishInflate();
findViewById(R.id.action_btn).setOnClickListener(this);
MarginLayoutParams lp = ((MarginLayoutParams) findViewById(R.id.wrapper).getLayoutParams());
- lp.width = mActivityContext.getAppsView().getFloatingHeaderView().getTabWidth();
+ lp.width = mLauncher.getAppsView().getActiveRecyclerView().getTabWidth();
}
@Override
public void onClick(View view) {
startAnimation(mDismissAnim);
- Utilities.getPrefs(getContext()).edit().putInt(WorkAdapterProvider.KEY_WORK_EDU_STEP,
- 1).apply();
+ mLauncher.getSharedPrefs().edit().putInt(WorkAdapterProvider.KEY_WORK_EDU_STEP, 1).apply();
}
@Override
@@ -100,8 +97,8 @@ public class WorkEduCard extends FrameLayout implements
if (mPosition == -1) {
if (getParent() != null) ((ViewGroup) getParent()).removeView(WorkEduCard.this);
} else {
- AllAppsRecyclerView rv = mActivityContext.getAppsView().mAH.get(
- ActivityAllAppsContainerView.AdapterHolder.WORK).mRecyclerView;
+ AllAppsRecyclerView rv = mLauncher.getAppsView()
+ .mAH[AllAppsContainerView.AdapterHolder.WORK].recyclerView;
rv.getApps().getAdapterItems().remove(mPosition);
rv.getAdapter().notifyItemRemoved(mPosition);
}
diff --git a/src/com/android/launcher3/allapps/WorkModeSwitch.java b/src/com/android/launcher3/allapps/WorkModeSwitch.java
index 733577eabf..a800d34758 100644
--- a/src/com/android/launcher3/allapps/WorkModeSwitch.java
+++ b/src/com/android/launcher3/allapps/WorkModeSwitch.java
@@ -16,41 +16,42 @@
package com.android.launcher3.allapps;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TURN_OFF_WORK_APPS_TAP;
+import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
import android.content.Context;
import android.graphics.Insets;
import android.graphics.Rect;
+import android.os.Build;
+import android.os.Process;
+import android.os.UserHandle;
+import android.os.UserManager;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowInsets;
import android.widget.Button;
-import com.android.launcher3.DeviceProfile;
+import androidx.annotation.Nullable;
+import androidx.annotation.RequiresApi;
+
import com.android.launcher3.Insettable;
+import com.android.launcher3.Launcher;
import com.android.launcher3.Utilities;
import com.android.launcher3.anim.KeyboardInsetAnimationCallback;
-import com.android.launcher3.model.StringCache;
-import com.android.launcher3.views.ActivityContext;
-import com.android.launcher3.workprofile.PersonalWorkSlidingTabStrip;
+import com.android.launcher3.pm.UserCache;
/**
* Work profile toggle switch shown at the bottom of AllApps work tab
*/
-public class WorkModeSwitch extends Button implements Insettable, View.OnClickListener,
- KeyboardInsetAnimationCallback.KeyboardInsetListener,
- PersonalWorkSlidingTabStrip.OnActivePageChangedListener {
-
- private static final int FLAG_FADE_ONGOING = 1 << 1;
- private static final int FLAG_TRANSLATION_ONGOING = 1 << 2;
- private static final int FLAG_PROFILE_TOGGLE_ONGOING = 1 << 3;
+public class WorkModeSwitch extends Button implements Insettable, View.OnClickListener {
- private final Rect mInsets = new Rect();
- private int mFlags;
+ private Rect mInsets = new Rect();
private boolean mWorkEnabled;
- private boolean mOnWorkTab;
+ @Nullable
+ private KeyboardInsetAnimationCallback mKeyboardInsetAnimationCallback;
+
public WorkModeSwitch(Context context) {
this(context, null, 0);
}
@@ -69,17 +70,8 @@ public class WorkModeSwitch extends Button implements Insettable, View.OnClickLi
setSelected(true);
setOnClickListener(this);
if (Utilities.ATLEAST_R) {
- KeyboardInsetAnimationCallback keyboardInsetAnimationCallback =
- new KeyboardInsetAnimationCallback(this);
- setWindowInsetsAnimationCallback(keyboardInsetAnimationCallback);
- }
- ActivityContext activityContext = ActivityContext.lookupContext(getContext());
- DeviceProfile grid = activityContext.getDeviceProfile();
- setInsets(grid.getInsets());
-
- StringCache cache = activityContext.getStringCache();
- if (cache != null) {
- setText(cache.workProfilePauseButton);
+ mKeyboardInsetAnimationCallback = new KeyboardInsetAnimationCallback(this);
+ setWindowInsetsAnimationCallback(mKeyboardInsetAnimationCallback);
}
}
@@ -94,57 +86,58 @@ public class WorkModeSwitch extends Button implements Insettable, View.OnClickLi
}
}
-
- @Override
- public void onActivePageChanged(int page) {
- mOnWorkTab = page == ActivityAllAppsContainerView.AdapterHolder.WORK;
- updateVisibility();
+ /**
+ * Animates in/out work profile toggle panel based on the tab user is on
+ */
+ public void setWorkTabVisible(boolean workTabVisible) {
+ clearAnimation();
+ if (workTabVisible) {
+ setEnabled(true);
+ if (mWorkEnabled) {
+ setVisibility(VISIBLE);
+ }
+ setAlpha(0);
+ animate().alpha(1).start();
+ } else {
+ animate().alpha(0).withEndAction(() -> this.setVisibility(GONE)).start();
+ }
}
@Override
public void onClick(View view) {
- if (Utilities.ATLEAST_P && isEnabled()) {
- setFlag(FLAG_PROFILE_TOGGLE_ONGOING);
- ActivityContext activityContext = ActivityContext.lookupContext(getContext());
- activityContext.getStatsLogManager().logger().log(LAUNCHER_TURN_OFF_WORK_APPS_TAP);
- activityContext.getAppsView().getWorkManager().setWorkProfileEnabled(false);
+ if (Utilities.ATLEAST_P) {
+ setEnabled(false);
+ Launcher.fromContext(getContext()).getStatsLogManager().logger().log(
+ LAUNCHER_TURN_OFF_WORK_APPS_TAP);
+ UI_HELPER_EXECUTOR.post(() -> setWorkProfileEnabled(getContext(), false));
}
}
- @Override
- public boolean isEnabled() {
- return super.isEnabled() && getVisibility() == VISIBLE && mFlags == 0;
- }
-
/**
* Sets the enabled or disabled state of the button
*/
- public void updateCurrentState(boolean isEnabled) {
- removeFlag(FLAG_PROFILE_TOGGLE_ONGOING);
- if (mWorkEnabled != isEnabled) {
- mWorkEnabled = isEnabled;
- updateVisibility();
- }
+ public void updateCurrentState(boolean active) {
+ mWorkEnabled = active;
+ setEnabled(true);
+ setVisibility(active ? VISIBLE : GONE);
}
- private void updateVisibility() {
- clearAnimation();
- if (mWorkEnabled && mOnWorkTab) {
- setFlag(FLAG_FADE_ONGOING);
- setVisibility(VISIBLE);
- animate().alpha(1).withEndAction(() -> removeFlag(FLAG_FADE_ONGOING)).start();
- } else if (getVisibility() != GONE) {
- setFlag(FLAG_FADE_ONGOING);
- animate().alpha(0).withEndAction(() -> {
- removeFlag(FLAG_FADE_ONGOING);
- this.setVisibility(GONE);
- }).start();
+ @RequiresApi(Build.VERSION_CODES.P)
+ public static Boolean setWorkProfileEnabled(Context context, boolean enabled) {
+ UserManager userManager = context.getSystemService(UserManager.class);
+ boolean showConfirm = false;
+ for (UserHandle userProfile : UserCache.INSTANCE.get(context).getUserProfiles()) {
+ if (Process.myUserHandle().equals(userProfile)) {
+ continue;
+ }
+ showConfirm |= !userManager.requestQuietModeEnabled(!enabled, userProfile);
}
+ return showConfirm;
}
@Override
public WindowInsets onApplyWindowInsets(WindowInsets insets) {
- if (Utilities.ATLEAST_R && isEnabled()) {
+ if (Utilities.ATLEAST_R) {
setTranslationY(0);
if (insets.isVisible(WindowInsets.Type.ime())) {
Insets keyboardInsets = insets.getInsets(WindowInsets.Type.ime());
@@ -153,22 +146,4 @@ public class WorkModeSwitch extends Button implements Insettable, View.OnClickLi
}
return insets;
}
-
- @Override
- public void onTranslationStart() {
- setFlag(FLAG_TRANSLATION_ONGOING);
- }
-
- @Override
- public void onTranslationEnd() {
- removeFlag(FLAG_TRANSLATION_ONGOING);
- }
-
- private void setFlag(int flag) {
- mFlags |= flag;
- }
-
- private void removeFlag(int flag) {
- mFlags &= ~flag;
- }
}
diff --git a/src/com/android/launcher3/allapps/WorkPausedCard.java b/src/com/android/launcher3/allapps/WorkPausedCard.java
index 729622f519..7908b63ec2 100644
--- a/src/com/android/launcher3/allapps/WorkPausedCard.java
+++ b/src/com/android/launcher3/allapps/WorkPausedCard.java
@@ -16,6 +16,7 @@
package com.android.launcher3.allapps;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TURN_ON_WORK_APPS_TAP;
+import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
import android.content.Context;
import android.content.res.Configuration;
@@ -24,16 +25,16 @@ import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
+import com.android.launcher3.Launcher;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
-import com.android.launcher3.views.ActivityContext;
/**
* Work profile toggle switch shown at the bottom of AllApps work tab
*/
public class WorkPausedCard extends LinearLayout implements View.OnClickListener {
- private final ActivityContext mActivityContext;
+ private final Launcher mLauncher;
private Button mBtn;
public WorkPausedCard(Context context) {
@@ -46,7 +47,7 @@ public class WorkPausedCard extends LinearLayout implements View.OnClickListener
public WorkPausedCard(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
- mActivityContext = ActivityContext.lookupContext(getContext());
+ mLauncher = Launcher.getLauncher(getContext());
}
@@ -61,8 +62,8 @@ public class WorkPausedCard extends LinearLayout implements View.OnClickListener
public void onClick(View view) {
if (Utilities.ATLEAST_P) {
setEnabled(false);
- mActivityContext.getAppsView().getWorkManager().setWorkProfileEnabled(true);
- mActivityContext.getStatsLogManager().logger().log(LAUNCHER_TURN_ON_WORK_APPS_TAP);
+ mLauncher.getStatsLogManager().logger().log(LAUNCHER_TURN_ON_WORK_APPS_TAP);
+ UI_HELPER_EXECUTOR.post(() -> WorkModeSwitch.setWorkProfileEnabled(getContext(), true));
}
}
diff --git a/src/com/android/launcher3/allapps/WorkProfileManager.java b/src/com/android/launcher3/allapps/WorkProfileManager.java
deleted file mode 100644
index b70cb13b07..0000000000
--- a/src/com/android/launcher3/allapps/WorkProfileManager.java
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- * Copyright (C) 2021 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.launcher3.allapps;
-
-import static com.android.launcher3.model.BgDataModel.Callbacks.FLAG_HAS_SHORTCUT_PERMISSION;
-import static com.android.launcher3.model.BgDataModel.Callbacks.FLAG_QUIET_MODE_CHANGE_PERMISSION;
-import static com.android.launcher3.model.BgDataModel.Callbacks.FLAG_QUIET_MODE_ENABLED;
-import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
-
-import android.content.SharedPreferences;
-import android.os.Build;
-import android.os.Process;
-import android.os.UserHandle;
-import android.os.UserManager;
-import android.util.Log;
-import android.view.ViewGroup;
-
-import androidx.annotation.IntDef;
-import androidx.annotation.Nullable;
-import androidx.annotation.RequiresApi;
-
-import com.android.launcher3.DeviceProfile;
-import com.android.launcher3.R;
-import com.android.launcher3.config.FeatureFlags;
-import com.android.launcher3.model.data.ItemInfo;
-import com.android.launcher3.workprofile.PersonalWorkSlidingTabStrip;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.function.Predicate;
-
-/**
- * Companion class for {@link BaseAllAppsContainerView} to manage work tab and personal tab
- * related
- * logic based on {@link WorkProfileState}?
- */
-public class WorkProfileManager implements PersonalWorkSlidingTabStrip.OnActivePageChangedListener {
- private static final String TAG = "WorkProfileManager";
-
-
- public static final int STATE_ENABLED = 1;
- public static final int STATE_DISABLED = 2;
- public static final int STATE_TRANSITION = 3;
-
- private final UserManager mUserManager;
-
- /**
- * Work profile manager states
- */
- @IntDef(value = {
- STATE_ENABLED,
- STATE_DISABLED,
- STATE_TRANSITION
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface WorkProfileState {
- }
-
- private final BaseAllAppsContainerView<?> mAllApps;
- private final WorkAdapterProvider mAdapterProvider;
- private final Predicate<ItemInfo> mMatcher;
-
- private WorkModeSwitch mWorkModeSwitch;
- private final DeviceProfile mDeviceProfile;
-
- @WorkProfileState
- private int mCurrentState;
-
-
- public WorkProfileManager(UserManager userManager, BaseAllAppsContainerView<?> allApps,
- SharedPreferences preferences, DeviceProfile deviceProfile) {
- mUserManager = userManager;
- mAllApps = allApps;
- mDeviceProfile = deviceProfile;
- mAdapterProvider = new WorkAdapterProvider(allApps.mActivityContext, preferences);
- mMatcher = mAllApps.mPersonalMatcher.negate();
- }
-
- /**
- * Posts quite mode enable/disable call for work profile user
- */
- @RequiresApi(Build.VERSION_CODES.P)
- public void setWorkProfileEnabled(boolean enabled) {
- updateCurrentState(STATE_TRANSITION);
- UI_HELPER_EXECUTOR.post(() -> {
- for (UserHandle userProfile : mUserManager.getUserProfiles()) {
- if (Process.myUserHandle().equals(userProfile)) {
- continue;
- }
- mUserManager.requestQuietModeEnabled(!enabled, userProfile);
- }
- });
- }
-
- @Override
- public void onActivePageChanged(int page) {
- if (mWorkModeSwitch != null) {
- mWorkModeSwitch.onActivePageChanged(page);
- }
- }
-
- /**
- * Requests work profile state from {@link AllAppsStore} and updates work profile related views
- */
- public void reset() {
- boolean isEnabled = !mAllApps.getAppsStore().hasModelFlag(FLAG_QUIET_MODE_ENABLED);
- updateCurrentState(isEnabled ? STATE_ENABLED : STATE_DISABLED);
- }
-
- private void updateCurrentState(@WorkProfileState int currentState) {
- mCurrentState = currentState;
- mAdapterProvider.updateCurrentState(currentState);
- if (getAH() != null) {
- getAH().mAppsList.updateAdapterItems();
- }
- if (mWorkModeSwitch != null) {
- mWorkModeSwitch.updateCurrentState(currentState == STATE_ENABLED);
- }
- }
-
- /**
- * Creates and attaches for profile toggle button to {@link BaseAllAppsContainerView}
- */
- public boolean attachWorkModeSwitch() {
- if (!mAllApps.getAppsStore().hasModelFlag(
- FLAG_HAS_SHORTCUT_PERMISSION | FLAG_QUIET_MODE_CHANGE_PERMISSION)) {
- Log.e(TAG, "unable to attach work mode switch; Missing required permissions");
- return false;
- }
- if (mWorkModeSwitch == null) {
- mWorkModeSwitch = (WorkModeSwitch) mAllApps.getLayoutInflater().inflate(
- R.layout.work_mode_fab, mAllApps, false);
- }
- ViewGroup.MarginLayoutParams lp =
- (ViewGroup.MarginLayoutParams) mWorkModeSwitch.getLayoutParams();
- int workFabMarginBottom =
- mWorkModeSwitch.getResources().getDimensionPixelSize(
- R.dimen.work_fab_margin_bottom);
- if (FeatureFlags.ENABLE_FLOATING_SEARCH_BAR.get()) {
- workFabMarginBottom <<= 1; // Double margin to add space above search bar.
- workFabMarginBottom +=
- mWorkModeSwitch.getResources().getDimensionPixelSize(R.dimen.qsb_widget_height);
- }
- if (!mAllApps.mActivityContext.getDeviceProfile().isGestureMode){
- workFabMarginBottom += mAllApps.mActivityContext.getDeviceProfile().getInsets().bottom;
- }
- lp.bottomMargin = workFabMarginBottom;
- int totalScreenWidth = mDeviceProfile.widthPx;
- int personalWorkTabWidth =
- mAllApps.mActivityContext.getAppsView().getFloatingHeaderView().getTabWidth();
- lp.rightMargin = lp.leftMargin = (totalScreenWidth - personalWorkTabWidth) / 2;
- if (mWorkModeSwitch.getParent() != mAllApps) {
- mAllApps.addView(mWorkModeSwitch);
- }
- if (getAH() != null) {
- getAH().applyPadding();
- }
- mWorkModeSwitch.updateCurrentState(mCurrentState == STATE_ENABLED);
- return true;
- }
- /**
- * Removes work profile toggle button from {@link BaseAllAppsContainerView}
- */
- public void detachWorkModeSwitch() {
- if (mWorkModeSwitch != null && mWorkModeSwitch.getParent() == mAllApps) {
- mAllApps.removeView(mWorkModeSwitch);
- }
- mWorkModeSwitch = null;
- }
-
- public WorkAdapterProvider getAdapterProvider() {
- return mAdapterProvider;
- }
-
- public Predicate<ItemInfo> getMatcher() {
- return mMatcher;
- }
-
- @Nullable
- public WorkModeSwitch getWorkModeSwitch() {
- return mWorkModeSwitch;
- }
-
- private BaseAllAppsContainerView<?>.AdapterHolder getAH() {
- return mAllApps.mAH.get(BaseAllAppsContainerView.AdapterHolder.WORK);
- }
-
- public int getCurrentState() {
- return mCurrentState;
- }
-}
diff --git a/src/com/android/launcher3/allapps/search/AllAppsSearchBarController.java b/src/com/android/launcher3/allapps/search/AllAppsSearchBarController.java
index 886460e5c7..79718fb6df 100644
--- a/src/com/android/launcher3/allapps/search/AllAppsSearchBarController.java
+++ b/src/com/android/launcher3/allapps/search/AllAppsSearchBarController.java
@@ -16,13 +16,10 @@
package com.android.launcher3.allapps.search;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ALLAPPS_FOCUSED_ITEM_SELECTED_WITH_IME;
-import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ALLAPPS_QUICK_SEARCH_WITH_IME;
import android.text.Editable;
-import android.text.SpannableStringBuilder;
import android.text.TextUtils;
import android.text.TextWatcher;
-import android.text.style.SuggestionSpan;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnFocusChangeListener;
@@ -30,13 +27,14 @@ import android.view.inputmethod.EditorInfo;
import android.widget.TextView;
import android.widget.TextView.OnEditorActionListener;
+import com.android.launcher3.BaseDraggingActivity;
import com.android.launcher3.ExtendedEditText;
+import com.android.launcher3.Launcher;
import com.android.launcher3.Utilities;
-import com.android.launcher3.allapps.BaseAllAppsAdapter.AdapterItem;
+import com.android.launcher3.allapps.AllAppsGridAdapter.AdapterItem;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.search.SearchAlgorithm;
import com.android.launcher3.search.SearchCallback;
-import com.android.launcher3.views.ActivityContext;
/**
* An interface to a search box that AllApps can command.
@@ -45,11 +43,10 @@ public class AllAppsSearchBarController
implements TextWatcher, OnEditorActionListener, ExtendedEditText.OnBackKeyListener,
OnFocusChangeListener {
- protected ActivityContext mLauncher;
+ protected BaseDraggingActivity mLauncher;
protected SearchCallback<AdapterItem> mCallback;
protected ExtendedEditText mInput;
protected String mQuery;
- private String[] mTextConversions;
protected SearchAlgorithm<AdapterItem> mSearchAlgorithm;
@@ -62,7 +59,7 @@ public class AllAppsSearchBarController
*/
public final void initialize(
SearchAlgorithm<AdapterItem> searchAlgorithm, ExtendedEditText input,
- ActivityContext launcher, SearchCallback<AdapterItem> callback) {
+ BaseDraggingActivity launcher, SearchCallback<AdapterItem> callback) {
mCallback = callback;
mLauncher = launcher;
@@ -81,20 +78,7 @@ public class AllAppsSearchBarController
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
- mTextConversions = extractTextConversions(s);
- }
-
- private static String[] extractTextConversions(CharSequence text) {
- if (text instanceof SpannableStringBuilder) {
- SpannableStringBuilder spanned = (SpannableStringBuilder) text;
- SuggestionSpan[] suggestionSpans =
- spanned.getSpans(0, text.length(), SuggestionSpan.class);
- if (suggestionSpans != null && suggestionSpans.length > 0) {
- spanned.removeSpan(suggestionSpans[0]);
- return suggestionSpans[0].getSuggestions();
- }
- }
- return null;
+ // Do nothing
}
@Override
@@ -105,7 +89,7 @@ public class AllAppsSearchBarController
mCallback.clearSearchResult();
} else {
mSearchAlgorithm.cancel(false);
- mSearchAlgorithm.doSearch(mQuery, mTextConversions, mCallback);
+ mSearchAlgorithm.doSearch(mQuery, mCallback);
}
}
@@ -123,11 +107,9 @@ public class AllAppsSearchBarController
if (actionId == EditorInfo.IME_ACTION_SEARCH || actionId == EditorInfo.IME_ACTION_GO) {
mLauncher.getStatsLogManager().logger()
- .log(actionId == EditorInfo.IME_ACTION_SEARCH
- ? LAUNCHER_ALLAPPS_QUICK_SEARCH_WITH_IME
- : LAUNCHER_ALLAPPS_FOCUSED_ITEM_SELECTED_WITH_IME);
+ .log(LAUNCHER_ALLAPPS_FOCUSED_ITEM_SELECTED_WITH_IME);
// selectFocusedView should return SearchTargetEvent that is passed onto onClick
- return mLauncher.getAppsView().getMainAdapterProvider().launchHighlightedItem();
+ return Launcher.getLauncher(mLauncher).getAppsView().launchHighlightedItem();
}
return false;
}
@@ -172,4 +154,4 @@ public class AllAppsSearchBarController
public boolean isSearchFieldFocused() {
return mInput.isFocused();
}
-}
+} \ No newline at end of file
diff --git a/src/com/android/launcher3/allapps/search/AppsSearchContainerLayout.java b/src/com/android/launcher3/allapps/search/AppsSearchContainerLayout.java
index 6539c05d84..24912173ff 100644
--- a/src/com/android/launcher3/allapps/search/AppsSearchContainerLayout.java
+++ b/src/com/android/launcher3/allapps/search/AppsSearchContainerLayout.java
@@ -32,16 +32,17 @@ import android.view.KeyEvent;
import android.view.View;
import android.view.ViewGroup.MarginLayoutParams;
+import com.android.launcher3.BaseDraggingActivity;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.ExtendedEditText;
import com.android.launcher3.Insettable;
import com.android.launcher3.R;
-import com.android.launcher3.allapps.ActivityAllAppsContainerView;
+import com.android.launcher3.allapps.AllAppsContainerView;
+import com.android.launcher3.allapps.AllAppsGridAdapter.AdapterItem;
import com.android.launcher3.allapps.AllAppsStore;
-import com.android.launcher3.allapps.BaseAllAppsAdapter.AdapterItem;
+import com.android.launcher3.allapps.AlphabeticalAppsList;
import com.android.launcher3.allapps.SearchUiManager;
import com.android.launcher3.search.SearchCallback;
-import com.android.launcher3.views.ActivityContext;
import java.util.ArrayList;
@@ -52,11 +53,12 @@ public class AppsSearchContainerLayout extends ExtendedEditText
implements SearchUiManager, SearchCallback<AdapterItem>,
AllAppsStore.OnUpdateListener, Insettable {
- private final ActivityContext mLauncher;
+ private final BaseDraggingActivity mLauncher;
private final AllAppsSearchBarController mSearchBarController;
private final SpannableStringBuilder mSearchQueryBuilder;
- private ActivityAllAppsContainerView<?> mAppsView;
+ private AlphabeticalAppsList mApps;
+ private AllAppsContainerView mAppsView;
// The amount of pixels to shift down and overlap with the rest of the content.
private final int mContentOverlap;
@@ -72,7 +74,7 @@ public class AppsSearchContainerLayout extends ExtendedEditText
public AppsSearchContainerLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
- mLauncher = ActivityContext.lookupContext(context);
+ mLauncher = BaseDraggingActivity.fromContext(context);
mSearchBarController = new AllAppsSearchBarController();
mSearchQueryBuilder = new SpannableStringBuilder();
@@ -80,7 +82,7 @@ public class AppsSearchContainerLayout extends ExtendedEditText
setHint(prefixTextWithIcon(getContext(), R.drawable.ic_allapps_search, getHint()));
mContentOverlap =
- getResources().getDimensionPixelSize(R.dimen.all_apps_search_bar_content_overlap);
+ getResources().getDimensionPixelSize(R.dimen.all_apps_search_bar_field_height) / 2;
}
@Override
@@ -103,8 +105,8 @@ public class AppsSearchContainerLayout extends ExtendedEditText
int rowWidth = myRequestedWidth - mAppsView.getActiveRecyclerView().getPaddingLeft()
- mAppsView.getActiveRecyclerView().getPaddingRight();
- int cellWidth = DeviceProfile.calculateCellWidth(rowWidth,
- dp.cellLayoutBorderSpacePx.x, dp.numShownHotseatIcons);
+ int cellWidth = DeviceProfile.calculateCellWidth(rowWidth, dp.cellLayoutBorderSpacingPx,
+ dp.numShownHotseatIcons);
int iconVisibleSize = Math.round(ICON_VISIBLE_AREA_FACTOR * dp.iconSizePx);
int iconPadding = cellWidth - iconVisibleSize;
@@ -128,10 +130,11 @@ public class AppsSearchContainerLayout extends ExtendedEditText
}
@Override
- public void initializeSearch(ActivityAllAppsContainerView<?> appsView) {
+ public void initializeSearch(AllAppsContainerView appsView) {
+ mApps = appsView.getApps();
mAppsView = appsView;
mSearchBarController.initialize(
- new DefaultAppSearchAlgorithm(getContext()),
+ new DefaultAppSearchAlgorithm(mLauncher),
this, mLauncher, this);
}
@@ -167,14 +170,25 @@ public class AppsSearchContainerLayout extends ExtendedEditText
@Override
public void onSearchResult(String query, ArrayList<AdapterItem> items) {
if (items != null) {
- mAppsView.setSearchResults(items);
+ mApps.setSearchResults(items);
+ notifyResultChanged();
mAppsView.setLastSearchQuery(query);
}
}
@Override
+ public void onAppendSearchResult(String query, ArrayList<AdapterItem> items) {
+ if (items != null) {
+ mApps.appendSearchResults(items);
+ notifyResultChanged();
+ }
+ }
+
+ @Override
public void clearSearchResult() {
- mAppsView.setSearchResults(null);
+ if (mApps.setSearchResults(null)) {
+ notifyResultChanged();
+ }
// Clear the search query
mSearchQueryBuilder.clear();
@@ -183,6 +197,10 @@ public class AppsSearchContainerLayout extends ExtendedEditText
mAppsView.onClearSearchResult();
}
+ private void notifyResultChanged() {
+ mAppsView.onSearchResultsChanged();
+ }
+
@Override
public void setInsets(Rect insets) {
MarginLayoutParams mlp = (MarginLayoutParams) getLayoutParams();
diff --git a/src/com/android/launcher3/allapps/search/DefaultAppSearchAlgorithm.java b/src/com/android/launcher3/allapps/search/DefaultAppSearchAlgorithm.java
index 4eceb7184e..1f854c6787 100644
--- a/src/com/android/launcher3/allapps/search/DefaultAppSearchAlgorithm.java
+++ b/src/com/android/launcher3/allapps/search/DefaultAppSearchAlgorithm.java
@@ -23,7 +23,7 @@ import android.os.Handler;
import androidx.annotation.AnyThread;
import com.android.launcher3.LauncherAppState;
-import com.android.launcher3.allapps.BaseAllAppsAdapter.AdapterItem;
+import com.android.launcher3.allapps.AllAppsGridAdapter.AdapterItem;
import com.android.launcher3.model.AllAppsList;
import com.android.launcher3.model.BaseModelUpdateTask;
import com.android.launcher3.model.BgDataModel;
@@ -85,7 +85,8 @@ public class DefaultAppSearchAlgorithm implements SearchAlgorithm<AdapterItem> {
for (int i = 0; i < total && resultCount < MAX_RESULTS_COUNT; i++) {
AppInfo info = apps.get(i);
if (StringMatcherUtility.matches(queryTextLower, info.title.toString(), matcher)) {
- result.add(AdapterItem.asApp(info));
+ AdapterItem appItem = AdapterItem.asApp(resultCount, "", info, resultCount);
+ result.add(appItem);
resultCount++;
}
}
diff --git a/src/com/android/launcher3/allapps/search/DefaultSearchAdapterProvider.java b/src/com/android/launcher3/allapps/search/DefaultSearchAdapterProvider.java
index a95bd514da..7abd555b9d 100644
--- a/src/com/android/launcher3/allapps/search/DefaultSearchAdapterProvider.java
+++ b/src/com/android/launcher3/allapps/search/DefaultSearchAdapterProvider.java
@@ -23,21 +23,23 @@ import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
+import com.android.launcher3.BaseDraggingActivity;
import com.android.launcher3.BubbleTextView;
+import com.android.launcher3.allapps.AllAppsContainerView;
import com.android.launcher3.allapps.AllAppsGridAdapter;
import com.android.launcher3.model.data.ItemInfo;
-import com.android.launcher3.views.AppLauncher;
/**
- * Provides views for local search results.
+ * Provides views for local search results
*/
-public class DefaultSearchAdapterProvider extends SearchAdapterProvider<AppLauncher> {
+public class DefaultSearchAdapterProvider extends SearchAdapterProvider {
private final RecyclerView.ItemDecoration mDecoration;
private View mHighlightedView;
- public DefaultSearchAdapterProvider(AppLauncher launcher) {
- super(launcher);
+ public DefaultSearchAdapterProvider(BaseDraggingActivity launcher,
+ AllAppsContainerView appsContainerView) {
+ super(launcher, appsContainerView);
mDecoration = new RecyclerView.ItemDecoration() {
@Override
public void onDraw(@NonNull Canvas c, @NonNull RecyclerView parent,
diff --git a/src/com/android/launcher3/allapps/search/SearchAdapterProvider.java b/src/com/android/launcher3/allapps/search/SearchAdapterProvider.java
index bc52784caf..7af0406e30 100644
--- a/src/com/android/launcher3/allapps/search/SearchAdapterProvider.java
+++ b/src/com/android/launcher3/allapps/search/SearchAdapterProvider.java
@@ -21,19 +21,18 @@ import android.view.View;
import androidx.recyclerview.widget.RecyclerView;
+import com.android.launcher3.BaseDraggingActivity;
+import com.android.launcher3.allapps.AllAppsContainerView;
import com.android.launcher3.allapps.BaseAdapterProvider;
-import com.android.launcher3.views.ActivityContext;
/**
* A UI expansion wrapper providing for search results
- *
- * @param <T> Context for this adapter provider.
*/
-public abstract class SearchAdapterProvider<T extends ActivityContext> extends BaseAdapterProvider {
+public abstract class SearchAdapterProvider extends BaseAdapterProvider {
- protected final T mLauncher;
+ protected final BaseDraggingActivity mLauncher;
- public SearchAdapterProvider(T launcher) {
+ public SearchAdapterProvider(BaseDraggingActivity launcher, AllAppsContainerView appsView) {
mLauncher = launcher;
}
diff --git a/src/com/android/launcher3/anim/AnimatedPropertySetter.java b/src/com/android/launcher3/anim/AnimatedPropertySetter.java
deleted file mode 100644
index e5f5e7c44b..0000000000
--- a/src/com/android/launcher3/anim/AnimatedPropertySetter.java
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.launcher3.anim;
-
-import static com.android.launcher3.LauncherAnimUtils.VIEW_BACKGROUND_COLOR;
-
-import android.animation.Animator;
-import android.animation.Animator.AnimatorListener;
-import android.animation.AnimatorSet;
-import android.animation.ObjectAnimator;
-import android.animation.TimeInterpolator;
-import android.animation.ValueAnimator;
-import android.graphics.drawable.ColorDrawable;
-import android.util.FloatProperty;
-import android.util.IntProperty;
-import android.view.View;
-
-import androidx.annotation.NonNull;
-
-import java.util.function.Consumer;
-
-/**
- * Extension of {@link PropertySetter} which applies the property through an animation
- */
-public class AnimatedPropertySetter extends PropertySetter {
-
- protected final AnimatorSet mAnim = new AnimatorSet();
- protected ValueAnimator mProgressAnimator;
-
- @Override
- public Animator setViewAlpha(View view, float alpha, TimeInterpolator interpolator) {
- if (view == null || view.getAlpha() == alpha) {
- return NO_OP;
- }
- ObjectAnimator anim = ObjectAnimator.ofFloat(view, View.ALPHA, alpha);
- anim.addListener(new AlphaUpdateListener(view));
- anim.setInterpolator(interpolator);
- add(anim);
- return anim;
- }
-
- @Override
- public Animator setViewBackgroundColor(View view, int color, TimeInterpolator interpolator) {
- if (view == null || (view.getBackground() instanceof ColorDrawable
- && ((ColorDrawable) view.getBackground()).getColor() == color)) {
- return NO_OP;
- }
- ObjectAnimator anim = ObjectAnimator.ofArgb(view, VIEW_BACKGROUND_COLOR, color);
- anim.setInterpolator(interpolator);
- add(anim);
- return anim;
- }
-
- @Override
- public <T> Animator setFloat(T target, FloatProperty<T> property, float value,
- TimeInterpolator interpolator) {
- if (property.get(target) == value) {
- return NO_OP;
- }
- Animator anim = ObjectAnimator.ofFloat(target, property, value);
- anim.setInterpolator(interpolator);
- add(anim);
- return anim;
- }
-
- @Override
- public <T> Animator setInt(T target, IntProperty<T> property, int value,
- TimeInterpolator interpolator) {
- if (property.get(target) == value) {
- return NO_OP;
- }
- Animator anim = ObjectAnimator.ofInt(target, property, value);
- anim.setInterpolator(interpolator);
- add(anim);
- return anim;
- }
-
-
- /**
- * Adds a callback to be run on every frame of the animation
- */
- public void addOnFrameCallback(Runnable runnable) {
- addOnFrameListener(anim -> runnable.run());
- }
-
- /**
- * Adds a listener to be run on every frame of the animation
- */
- public void addOnFrameListener(ValueAnimator.AnimatorUpdateListener listener) {
- if (mProgressAnimator == null) {
- mProgressAnimator = ValueAnimator.ofFloat(0, 1);
- }
-
- mProgressAnimator.addUpdateListener(listener);
- }
-
- @Override
- public void addEndListener(Consumer<Boolean> listener) {
- if (mProgressAnimator == null) {
- mProgressAnimator = ValueAnimator.ofFloat(0, 1);
- }
- mProgressAnimator.addListener(AnimatorListeners.forEndCallback(listener));
- }
-
- /**
- * @see AnimatorSet#addListener(AnimatorListener)
- */
- public void addListener(Animator.AnimatorListener listener) {
- mAnim.addListener(listener);
- }
-
- @Override
- public void add(Animator a) {
- mAnim.play(a);
- }
-
- /**
- * Creates and returns the underlying AnimatorSet
- */
- @NonNull
- public AnimatorSet buildAnim() {
- // Add progress animation to the end, so that frame callback is called after all the other
- // animation update.
- if (mProgressAnimator != null) {
- add(mProgressAnimator);
- mProgressAnimator = null;
- }
- return mAnim;
- }
-}
diff --git a/src/com/android/launcher3/anim/AnimatorPlaybackController.java b/src/com/android/launcher3/anim/AnimatorPlaybackController.java
index 1cc0c21745..85ca280ba2 100644
--- a/src/com/android/launcher3/anim/AnimatorPlaybackController.java
+++ b/src/com/android/launcher3/anim/AnimatorPlaybackController.java
@@ -19,7 +19,7 @@ import static com.android.launcher3.Utilities.boundToRange;
import static com.android.launcher3.anim.Interpolators.LINEAR;
import static com.android.launcher3.anim.Interpolators.clampToProgress;
import static com.android.launcher3.anim.Interpolators.scrollInterpolatorForVelocity;
-import static com.android.launcher3.util.window.RefreshRateTracker.getSingleFrameMs;
+import static com.android.launcher3.util.DisplayController.getSingleFrameMs;
import android.animation.Animator;
import android.animation.Animator.AnimatorListener;
diff --git a/src/com/android/launcher3/anim/FlingSpringAnim.java b/src/com/android/launcher3/anim/FlingSpringAnim.java
index 51eab4c386..6ea38ec8ab 100644
--- a/src/com/android/launcher3/anim/FlingSpringAnim.java
+++ b/src/com/android/launcher3/anim/FlingSpringAnim.java
@@ -40,8 +40,8 @@ public class FlingSpringAnim {
private float mTargetPosition;
public <K> FlingSpringAnim(K object, Context context, FloatPropertyCompat<K> property,
- float startPosition, float targetPosition, float startVelocityPxPerS,
- float minVisChange, float minValue, float maxValue,
+ float startPosition, float targetPosition, float startVelocity, float minVisChange,
+ float minValue, float maxValue, float springVelocityFactor,
OnAnimationEndListener onEndListener) {
ResourceProvider rp = DynamicResource.provider(context);
float damping = rp.getFloat(R.dimen.swipe_up_rect_xy_damping_ratio);
@@ -53,19 +53,19 @@ public class FlingSpringAnim {
// Have the spring pull towards the target if we've slowed down too much before
// reaching it.
.setMinimumVisibleChange(minVisChange)
- .setStartVelocity(startVelocityPxPerS)
+ .setStartVelocity(startVelocity)
.setMinValue(minValue)
.setMaxValue(maxValue);
mTargetPosition = targetPosition;
// We are already past the fling target, so skip it to avoid losing a frame of the spring.
- mSkipFlingAnim = startPosition <= minValue && startVelocityPxPerS < 0
- || startPosition >= maxValue && startVelocityPxPerS > 0;
+ mSkipFlingAnim = startPosition <= minValue && startVelocity < 0
+ || startPosition >= maxValue && startVelocity > 0;
mFlingAnim.addEndListener(((animation, canceled, value, velocity) -> {
mSpringAnim = new SpringAnimation(object, property)
.setStartValue(value)
- .setStartVelocity(velocity)
+ .setStartVelocity(velocity * springVelocityFactor)
.setSpring(new SpringForce(mTargetPosition)
.setStiffness(stiffness)
.setDampingRatio(damping));
diff --git a/src/com/android/launcher3/anim/Interpolators.java b/src/com/android/launcher3/anim/Interpolators.java
index 0a77aa7bcf..1e7b2247b8 100644
--- a/src/com/android/launcher3/anim/Interpolators.java
+++ b/src/com/android/launcher3/anim/Interpolators.java
@@ -57,11 +57,6 @@ public class Interpolators {
public static final Interpolator DECELERATED_EASE = new PathInterpolator(0, 0, .2f, 1f);
public static final Interpolator ACCELERATED_EASE = new PathInterpolator(0.4f, 0, 1f, 1f);
- public static final Interpolator EMPHASIZED_ACCELERATE = new PathInterpolator(
- 0.3f, 0f, 0.8f, 0.15f);
- public static final Interpolator EMPHASIZED_DECELERATE = new PathInterpolator(
- 0.05f, 0.7f, 0.1f, 1f);
-
public static final Interpolator EXAGGERATED_EASE;
public static final Interpolator INSTANT = t -> 1;
@@ -150,9 +145,8 @@ public class Interpolators {
}
/**
- * Returns a function that runs the given interpolator such that the entire progress is set
- * between the given bounds. That is, we set the interpolation to 0 until lowerBound and reach
- * 1 by upperBound.
+ * Runs the given interpolator such that the entire progress is set between the given bounds.
+ * That is, we set the interpolation to 0 until lowerBound and reach 1 by upperBound.
*/
public static Interpolator clampToProgress(Interpolator interpolator, float lowerBound,
float upperBound) {
@@ -161,42 +155,18 @@ public class Interpolators {
String.format("upperBound (%f) must be greater than lowerBound (%f)",
upperBound, lowerBound));
}
- return t -> clampToProgress(interpolator, t, lowerBound, upperBound);
- }
-
- /**
- * Returns the progress value's progress between the lower and upper bounds. That is, the
- * progress will be 0f from 0f to lowerBound, and reach 1f by upperBound.
- *
- * Between lowerBound and upperBound, the progress value will be interpolated using the provided
- * interpolator.
- */
- public static float clampToProgress(
- Interpolator interpolator, float progress, float lowerBound, float upperBound) {
- if (upperBound < lowerBound) {
- throw new IllegalArgumentException(
- String.format("upperBound (%f) must be greater than lowerBound (%f)",
- upperBound, lowerBound));
- }
-
- if (progress == lowerBound && progress == upperBound) {
- return progress == 0f ? 0 : 1;
- }
- if (progress < lowerBound) {
- return 0;
- }
- if (progress > upperBound) {
- return 1;
- }
- return interpolator.getInterpolation((progress - lowerBound) / (upperBound - lowerBound));
- }
-
- /**
- * Returns the progress value's progress between the lower and upper bounds. That is, the
- * progress will be 0f from 0f to lowerBound, and reach 1f by upperBound.
- */
- public static float clampToProgress(float progress, float lowerBound, float upperBound) {
- return clampToProgress(Interpolators.LINEAR, progress, lowerBound, upperBound);
+ return t -> {
+ if (t == lowerBound && t == upperBound) {
+ return t == 0f ? 0 : 1;
+ }
+ if (t < lowerBound) {
+ return 0;
+ }
+ if (t > upperBound) {
+ return 1;
+ }
+ return interpolator.getInterpolation((t - lowerBound) / (upperBound - lowerBound));
+ };
}
/**
@@ -208,14 +178,4 @@ public class Interpolators {
float upperBound) {
return t -> Utilities.mapRange(interpolator.getInterpolation(t), lowerBound, upperBound);
}
-
- /**
- * Returns the reverse of the provided interpolator, following the formula: g(x) = 1 - f(1 - x).
- * In practice, this means that if f is an interpolator used to model a value animating between
- * m and n, g is the interpolator to use to obtain the specular behavior when animating from n
- * to m.
- */
- public static Interpolator reverse(Interpolator interpolator) {
- return t -> 1 - interpolator.getInterpolation(1 - t);
- }
}
diff --git a/src/com/android/launcher3/anim/KeyboardInsetAnimationCallback.java b/src/com/android/launcher3/anim/KeyboardInsetAnimationCallback.java
index 9d96365acc..ef4ada3cd9 100644
--- a/src/com/android/launcher3/anim/KeyboardInsetAnimationCallback.java
+++ b/src/com/android/launcher3/anim/KeyboardInsetAnimationCallback.java
@@ -65,32 +65,7 @@ public class KeyboardInsetAnimationCallback extends WindowInsetsAnimation.Callba
public WindowInsetsAnimation.Bounds onStart(WindowInsetsAnimation animation,
WindowInsetsAnimation.Bounds bounds) {
mTerminalTranslation = mView.getTranslationY();
- if (mView instanceof KeyboardInsetListener) {
- ((KeyboardInsetListener) mView).onTranslationStart();
- }
+ mView.setTranslationY(mInitialTranslation);
return super.onStart(animation, bounds);
}
-
- @Override
- public void onEnd(WindowInsetsAnimation animation) {
- if (mView instanceof KeyboardInsetListener) {
- ((KeyboardInsetListener) mView).onTranslationEnd();
- }
- super.onEnd(animation);
- }
-
- /**
- * Interface Allowing views to listen for keyboard translation events
- */
- public interface KeyboardInsetListener {
- /**
- * Called from {@link KeyboardInsetAnimationCallback#onStart}
- */
- void onTranslationStart();
-
- /**
- * Called from {@link KeyboardInsetAnimationCallback#onEnd}
- */
- void onTranslationEnd();
- }
}
diff --git a/src/com/android/launcher3/anim/PendingAnimation.java b/src/com/android/launcher3/anim/PendingAnimation.java
index 7316420b12..01f7de66ce 100644
--- a/src/com/android/launcher3/anim/PendingAnimation.java
+++ b/src/com/android/launcher3/anim/PendingAnimation.java
@@ -15,18 +15,24 @@
*/
package com.android.launcher3.anim;
+import static com.android.launcher3.LauncherAnimUtils.VIEW_BACKGROUND_COLOR;
import static com.android.launcher3.anim.AnimatorPlaybackController.addAnimationHoldersRecur;
import android.animation.Animator;
+import android.animation.Animator.AnimatorListener;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.TimeInterpolator;
import android.animation.ValueAnimator;
+import android.graphics.drawable.ColorDrawable;
import android.util.FloatProperty;
+import android.util.IntProperty;
+import android.view.View;
import com.android.launcher3.anim.AnimatorPlaybackController.Holder;
import java.util.ArrayList;
+import java.util.function.Consumer;
/**
* Utility class to keep track of a running animation.
@@ -37,17 +43,17 @@ import java.util.ArrayList;
*
* TODO: Find a better name
*/
-public class PendingAnimation extends AnimatedPropertySetter {
+public class PendingAnimation implements PropertySetter {
private final ArrayList<Holder> mAnimHolders = new ArrayList<>();
+ private final AnimatorSet mAnim;
private final long mDuration;
+ private ValueAnimator mProgressAnimator;
+
public PendingAnimation(long duration) {
mDuration = duration;
- }
-
- public long getDuration() {
- return mDuration;
+ mAnim = new AnimatorSet();
}
/**
@@ -58,7 +64,6 @@ public class PendingAnimation extends AnimatedPropertySetter {
add(anim, springProperty);
}
- @Override
public void add(Animator anim) {
add(anim, SpringProperty.DEFAULT);
}
@@ -68,11 +73,37 @@ public class PendingAnimation extends AnimatedPropertySetter {
addAnimationHoldersRecur(a, mDuration, springProperty, mAnimHolders);
}
- /**
- * Configures interpolator of the underlying AnimatorSet.
- */
- public void setInterpolator(TimeInterpolator interpolator) {
- mAnim.setInterpolator(interpolator);
+ @Override
+ public void setViewAlpha(View view, float alpha, TimeInterpolator interpolator) {
+ if (view == null || view.getAlpha() == alpha) {
+ return;
+ }
+ ObjectAnimator anim = ObjectAnimator.ofFloat(view, View.ALPHA, alpha);
+ anim.addListener(new AlphaUpdateListener(view));
+ anim.setInterpolator(interpolator);
+ add(anim);
+ }
+
+ @Override
+ public void setViewBackgroundColor(View view, int color, TimeInterpolator interpolator) {
+ if (view == null || (view.getBackground() instanceof ColorDrawable
+ && ((ColorDrawable) view.getBackground()).getColor() == color)) {
+ return;
+ }
+ ObjectAnimator anim = ObjectAnimator.ofArgb(view, VIEW_BACKGROUND_COLOR, color);
+ anim.setInterpolator(interpolator);
+ add(anim);
+ }
+
+ @Override
+ public <T> void setFloat(T target, FloatProperty<T> property, float value,
+ TimeInterpolator interpolator) {
+ if (property.get(target) == value) {
+ return;
+ }
+ Animator anim = ObjectAnimator.ofFloat(target, property, value);
+ anim.setDuration(mDuration).setInterpolator(interpolator);
+ add(anim);
}
public <T> void addFloat(T target, FloatProperty<T> property, float from, float to,
@@ -82,16 +113,57 @@ public class PendingAnimation extends AnimatedPropertySetter {
add(anim);
}
+ @Override
+ public <T> void setInt(T target, IntProperty<T> property, int value,
+ TimeInterpolator interpolator) {
+ if (property.get(target) == value) {
+ return;
+ }
+ Animator anim = ObjectAnimator.ofInt(target, property, value);
+ anim.setInterpolator(interpolator);
+ add(anim);
+ }
+
+ /**
+ * Adds a callback to be run on every frame of the animation
+ */
+ public void addOnFrameCallback(Runnable runnable) {
+ addOnFrameListener(anim -> runnable.run());
+ }
+
+ /**
+ * Adds a listener to be run on every frame of the animation
+ */
+ public void addOnFrameListener(ValueAnimator.AnimatorUpdateListener listener) {
+ if (mProgressAnimator == null) {
+ mProgressAnimator = ValueAnimator.ofFloat(0, 1);
+ }
+
+ mProgressAnimator.addUpdateListener(listener);
+ }
+
+ /**
+ * @see AnimatorSet#addListener(AnimatorListener)
+ */
+ public void addListener(Animator.AnimatorListener listener) {
+ mAnim.addListener(listener);
+ }
+
/**
* Creates and returns the underlying AnimatorSet
*/
- @Override
public AnimatorSet buildAnim() {
+ // Add progress animation to the end, so that frame callback is called after all the other
+ // animation update.
+ if (mProgressAnimator != null) {
+ add(mProgressAnimator);
+ mProgressAnimator = null;
+ }
if (mAnimHolders.isEmpty()) {
// Add a placeholder animation to that the duration is respected
add(ValueAnimator.ofFloat(0, 1).setDuration(mDuration));
}
- return super.buildAnim();
+ return mAnim;
}
/**
@@ -100,4 +172,14 @@ public class PendingAnimation extends AnimatedPropertySetter {
public AnimatorPlaybackController createPlaybackController() {
return new AnimatorPlaybackController(buildAnim(), mDuration, mAnimHolders);
}
+
+ /**
+ * Add a listener of receiving the success/failure callback in the end.
+ */
+ public void addEndListener(Consumer<Boolean> listener) {
+ if (mProgressAnimator == null) {
+ mProgressAnimator = ValueAnimator.ofFloat(0, 1);
+ }
+ mProgressAnimator.addListener(AnimatorListeners.forEndCallback(listener));
+ }
}
diff --git a/src/com/android/launcher3/anim/PropertySetter.java b/src/com/android/launcher3/anim/PropertySetter.java
index d2207f6351..729523feb2 100644
--- a/src/com/android/launcher3/anim/PropertySetter.java
+++ b/src/com/android/launcher3/anim/PropertySetter.java
@@ -16,95 +16,52 @@
package com.android.launcher3.anim;
-import android.animation.Animator;
-import android.animation.AnimatorSet;
import android.animation.TimeInterpolator;
import android.util.FloatProperty;
import android.util.IntProperty;
import android.view.View;
-import androidx.annotation.NonNull;
-
-import java.util.function.Consumer;
-
/**
* Utility class for setting a property with or without animation
*/
-public abstract class PropertySetter {
-
- public static final PropertySetter NO_ANIM_PROPERTY_SETTER = new PropertySetter() {
-
- @Override
- public void add(Animator animatorSet) {
- animatorSet.setDuration(0);
- animatorSet.start();
- }
- };
+public interface PropertySetter {
- protected static final AnimatorSet NO_OP = new AnimatorSet();
+ PropertySetter NO_ANIM_PROPERTY_SETTER = new PropertySetter() { };
/**
* Sets the view alpha using the provided interpolator.
* Unlike {@link #setFloat}, this also updates the visibility of the view as alpha changes
* between zero and non-zero.
*/
- @NonNull
- public Animator setViewAlpha(View view, float alpha, TimeInterpolator interpolator) {
+ default void setViewAlpha(View view, float alpha, TimeInterpolator interpolator) {
if (view != null) {
view.setAlpha(alpha);
AlphaUpdateListener.updateVisibility(view);
}
- return NO_OP;
}
/**
* Sets the background color of the provided view using the provided interpolator.
*/
- @NonNull
- public Animator setViewBackgroundColor(View view, int color, TimeInterpolator interpolator) {
+ default void setViewBackgroundColor(View view, int color, TimeInterpolator interpolator) {
if (view != null) {
view.setBackgroundColor(color);
}
- return NO_OP;
}
/**
* Updates the float property of the target using the provided interpolator
*/
- @NonNull
- public <T> Animator setFloat(T target, FloatProperty<T> property, float value,
+ default <T> void setFloat(T target, FloatProperty<T> property, float value,
TimeInterpolator interpolator) {
property.setValue(target, value);
- return NO_OP;
}
/**
* Updates the int property of the target using the provided interpolator
*/
- @NonNull
- public <T> Animator setInt(T target, IntProperty<T> property, int value,
+ default <T> void setInt(T target, IntProperty<T> property, int value,
TimeInterpolator interpolator) {
property.setValue(target, value);
- return NO_OP;
- }
-
- /**
- * Runs the animation as part of setting the property
- */
- public abstract void add(Animator animatorSet);
-
- /**
- * Add a listener of receiving the success/failure callback in the end.
- */
- public void addEndListener(Consumer<Boolean> listener) {
- listener.accept(true);
- }
-
- /**
- * Creates and returns the AnimatorSet that can be run to apply the properties
- */
- @NonNull
- public AnimatorSet buildAnim() {
- return NO_OP;
}
}
diff --git a/src/com/android/launcher3/anim/RevealOutlineAnimation.java b/src/com/android/launcher3/anim/RevealOutlineAnimation.java
index f5a746f719..f99dabc989 100644
--- a/src/com/android/launcher3/anim/RevealOutlineAnimation.java
+++ b/src/com/android/launcher3/anim/RevealOutlineAnimation.java
@@ -26,27 +26,9 @@ public abstract class RevealOutlineAnimation extends ViewOutlineProvider {
/** Sets the progress, from 0 to 1, of the reveal animation. */
abstract void setProgress(float progress);
- /**
- * @see #createRevealAnimator(View, boolean, float) where startProgress is set to 0.
- */
public ValueAnimator createRevealAnimator(final View revealView, boolean isReversed) {
- return createRevealAnimator(revealView, isReversed, 0f /* startProgress */);
- }
-
- /**
- * Animates the given View's ViewOutline according to {@link #setProgress(float)}.
- * @param revealView The View whose outline we are animating.
- * @param isReversed Whether we are hiding rather than revealing the View.
- * @param startProgress The progress at which to start the newly created animation. Useful if
- * the previous reveal animation was cancelled and we want to create a new animation where it
- * left off. Note that if isReversed=true, we start at 1 - startProgress (and go to 0).
- * @return The Animator, which the caller must start.
- */
- public ValueAnimator createRevealAnimator(final View revealView, boolean isReversed,
- float startProgress) {
- ValueAnimator va = isReversed
- ? ValueAnimator.ofFloat(1f - startProgress, 0f)
- : ValueAnimator.ofFloat(startProgress, 1f);
+ ValueAnimator va =
+ isReversed ? ValueAnimator.ofFloat(1f, 0f) : ValueAnimator.ofFloat(0f, 1f);
final float elevation = revealView.getElevation();
va.addListener(new AnimatorListenerAdapter() {
diff --git a/src/com/android/launcher3/anim/SpringAnimationBuilder.java b/src/com/android/launcher3/anim/SpringAnimationBuilder.java
index 40fa0cfd02..bd52158f0a 100644
--- a/src/com/android/launcher3/anim/SpringAnimationBuilder.java
+++ b/src/com/android/launcher3/anim/SpringAnimationBuilder.java
@@ -25,7 +25,7 @@ import android.util.FloatProperty;
import androidx.annotation.FloatRange;
import androidx.dynamicanimation.animation.SpringForce;
-import com.android.launcher3.util.window.RefreshRateTracker;
+import com.android.launcher3.util.DisplayController;
/**
* Utility class to build an object animator which follows the same path as a spring animation for
@@ -134,7 +134,7 @@ public class SpringAnimationBuilder {
}
public SpringAnimationBuilder computeParams() {
- int singleFrameMs = RefreshRateTracker.getSingleFrameMs(mContext);
+ int singleFrameMs = DisplayController.getSingleFrameMs(mContext);
double naturalFreq = Math.sqrt(mStiffness);
double dampedFreq = naturalFreq * Math.sqrt(1 - mDampingRatio * mDampingRatio);
diff --git a/src/com/android/launcher3/compat/AccessibilityManagerCompat.java b/src/com/android/launcher3/compat/AccessibilityManagerCompat.java
index dd5812302d..30c3417d63 100644
--- a/src/com/android/launcher3/compat/AccessibilityManagerCompat.java
+++ b/src/com/android/launcher3/compat/AccessibilityManagerCompat.java
@@ -41,10 +41,11 @@ public class AccessibilityManagerCompat {
}
/**
+ *
* @param target The view the accessibility event is initialized on.
* If null, this method has no effect.
- * @param type See TYPE_ constants defined in {@link AccessibilityEvent}.
- * @param text Optional text to add to the event, which will be announced to the user.
+ * @param type See TYPE_ constants defined in {@link AccessibilityEvent}.
+ * @param text Optional text to add to the event, which will be announced to the user.
*/
public static void sendCustomAccessibilityEvent(@Nullable View target, int type,
@Nullable String text) {
@@ -88,24 +89,6 @@ public class AccessibilityManagerCompat {
sendEventToTest(accessibilityManager, context, TestProtocol.PAUSE_DETECTED_MESSAGE, null);
}
- public static void sendDismissAnimationEndsEventToTest(Context context) {
- final AccessibilityManager accessibilityManager = getAccessibilityManagerForTest(context);
- if (accessibilityManager == null) return;
-
- sendEventToTest(accessibilityManager, context, TestProtocol.DISMISS_ANIMATION_ENDS_MESSAGE,
- null);
- }
-
- /**
- * Notify running tests of a folder opened.
- */
- public static void sendFolderOpenedEventToTest(Context context) {
- final AccessibilityManager accessibilityManager = getAccessibilityManagerForTest(context);
- if (accessibilityManager == null) return;
-
- sendEventToTest(accessibilityManager, context, TestProtocol.FOLDER_OPENED_MESSAGE, null);
- }
-
private static void sendEventToTest(
AccessibilityManager accessibilityManager,
Context context, String eventTag, Bundle data) {
diff --git a/src/com/android/launcher3/compat/AlphabeticIndexCompat.java b/src/com/android/launcher3/compat/AlphabeticIndexCompat.java
index 4f8d53e11c..46c9006ddf 100644
--- a/src/com/android/launcher3/compat/AlphabeticIndexCompat.java
+++ b/src/com/android/launcher3/compat/AlphabeticIndexCompat.java
@@ -4,12 +4,12 @@ import android.content.Context;
import android.icu.text.AlphabeticIndex;
import android.os.LocaleList;
-import androidx.annotation.NonNull;
-
import com.android.launcher3.Utilities;
import java.util.Locale;
+import androidx.annotation.NonNull;
+
public class AlphabeticIndexCompat {
private static final String MID_DOT = "\u2219";
diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java
index 33beacd4c0..f066dc1e02 100644
--- a/src/com/android/launcher3/config/FeatureFlags.java
+++ b/src/com/android/launcher3/config/FeatureFlags.java
@@ -52,7 +52,7 @@ public final class FeatureFlags {
* Enable moving the QSB on the 0th screen of the workspace. This is not a configuration feature
* and should be modified at a project level.
*/
- public static final boolean QSB_ON_FIRST_SCREEN = BuildConfig.QSB_ON_FIRST_SCREEN;
+ public static final boolean QSB_ON_FIRST_SCREEN = true;
/**
* Feature flag to handle define config changes dynamically instead of killing the process.
@@ -72,13 +72,21 @@ public final class FeatureFlags {
"PROMISE_APPS_NEW_INSTALLS", true,
"Adds a promise icon to the home screen for new install sessions.");
- // TODO: b/206508141: Long pressing on some icons on home screen cause launcher to crash.
+ public static final BooleanFlag QUICKSTEP_SPRINGS = getDebugFlag(
+ "QUICKSTEP_SPRINGS", true, "Enable springs for quickstep animations");
+
+ public static final BooleanFlag UNSTABLE_SPRINGS = getDebugFlag(
+ "UNSTABLE_SPRINGS", false, "Enable unstable springs for quickstep animations");
+
public static final BooleanFlag ENABLE_LOCAL_COLOR_POPUPS = getDebugFlag(
"ENABLE_LOCAL_COLOR_POPUPS", false, "Enable local color extraction for popups.");
public static final BooleanFlag KEYGUARD_ANIMATION = getDebugFlag(
"KEYGUARD_ANIMATION", false, "Enable animation for keyguard going away on wallpaper");
+ public static final BooleanFlag ADAPTIVE_ICON_WINDOW_ANIM = getDebugFlag(
+ "ADAPTIVE_ICON_WINDOW_ANIM", true, "Use adaptive icons for window animations.");
+
public static final BooleanFlag ENABLE_QUICKSTEP_LIVE_TILE = getDebugFlag(
"ENABLE_QUICKSTEP_LIVE_TILE", true, "Enable live tile in Quickstep overview");
@@ -86,24 +94,16 @@ public final class FeatureFlags {
"ENABLE_QUICKSTEP_WIDGET_APP_START", true,
"Enable Quickstep animation when launching activities from an app widget");
- public static final BooleanFlag ENABLE_DEVICE_SEARCH = new DeviceFlag(
- "ENABLE_DEVICE_SEARCH", true, "Allows on device search in all apps");
-
- public static final BooleanFlag ENABLE_FLOATING_SEARCH_BAR =
- getDebugFlag("ENABLE_FLOATING_SEARCH_BAR", false,
- "Keep All Apps search bar at the bottom (but above keyboard if open)");
-
- public static final BooleanFlag ENABLE_QUICK_SEARCH = new DeviceFlag("ENABLE_QUICK_SEARCH",
- true, "Use quick search behavior.");
+ // Keep as DeviceFlag to allow remote disable in emergency.
+ public static final BooleanFlag ENABLE_SUGGESTED_ACTIONS_OVERVIEW = new DeviceFlag(
+ "ENABLE_SUGGESTED_ACTIONS_OVERVIEW", false, "Show chip hints on the overview screen");
- public static final BooleanFlag COLLECT_SEARCH_HISTORY = new DeviceFlag(
- "COLLECT_SEARCH_HISTORY", false, "Allow launcher to collect search history for log");
- public static final BooleanFlag ENABLE_TWOLINE_ALLAPPS = getDebugFlag(
- "ENABLE_TWOLINE_ALLAPPS", false, "Enables two line label inside all apps.");
+ public static final BooleanFlag ENABLE_DEVICE_SEARCH = new DeviceFlag(
+ "ENABLE_DEVICE_SEARCH", true, "Allows on device search in all apps");
public static final BooleanFlag ENABLE_DEVICE_SEARCH_PERFORMANCE_LOGGING = new DeviceFlag(
- "ENABLE_DEVICE_SEARCH_PERFORMANCE_LOGGING", false,
+ "ENABLE_DEVICE_SEARCH_PERFORMANCE_LOGGING", true,
"Allows on device search in all apps logging");
public static final BooleanFlag IME_STICKY_SNACKBAR_EDU = getDebugFlag(
@@ -124,6 +124,16 @@ public final class FeatureFlags {
public static final BooleanFlag ENABLE_PREDICTION_DISMISS = getDebugFlag(
"ENABLE_PREDICTION_DISMISS", true, "Allow option to dimiss apps from predicted list");
+ public static final BooleanFlag ENABLE_QUICK_CAPTURE_GESTURE = getDebugFlag(
+ "ENABLE_QUICK_CAPTURE_GESTURE", true, "Swipe from right to left to quick capture");
+
+ public static final BooleanFlag ENABLE_QUICK_CAPTURE_WINDOW = getDebugFlag(
+ "ENABLE_QUICK_CAPTURE_WINDOW", false, "Use window to host quick capture");
+
+ public static final BooleanFlag FORCE_LOCAL_OVERSCROLL_PLUGIN = getDebugFlag(
+ "FORCE_LOCAL_OVERSCROLL_PLUGIN", false,
+ "Use a launcher-provided OverscrollPlugin if available");
+
public static final BooleanFlag ASSISTANT_GIVES_LAUNCHER_FOCUS = getDebugFlag(
"ASSISTANT_GIVES_LAUNCHER_FOCUS", false,
"Allow Launcher to handle nav bar gestures while Assistant is running over it");
@@ -134,34 +144,46 @@ public final class FeatureFlags {
public static final BooleanFlag ENABLE_DEEP_SHORTCUT_ICON_CACHE = getDebugFlag(
"ENABLE_DEEP_SHORTCUT_ICON_CACHE", true, "R/W deep shortcut in IconCache");
+ public static final BooleanFlag MULTI_DB_GRID_MIRATION_ALGO = getDebugFlag(
+ "MULTI_DB_GRID_MIRATION_ALGO", true, "Use the multi-db grid migration algorithm");
+
public static final BooleanFlag ENABLE_THEMED_ICONS = getDebugFlag(
"ENABLE_THEMED_ICONS", true, "Enable themed icons on workspace");
- public static final BooleanFlag ENABLE_BULK_WORKSPACE_ICON_LOADING = getDebugFlag(
- "ENABLE_BULK_WORKSPACE_ICON_LOADING",
- true,
- "Enable loading workspace icons in bulk.");
-
- public static final BooleanFlag ENABLE_BULK_ALL_APPS_ICON_LOADING = getDebugFlag(
- "ENABLE_BULK_ALL_APPS_ICON_LOADING",
- true,
- "Enable loading all apps icons in bulk.");
-
// Keep as DeviceFlag for remote disable in emergency.
public static final BooleanFlag ENABLE_OVERVIEW_SELECTIONS = new DeviceFlag(
"ENABLE_OVERVIEW_SELECTIONS", true, "Show Select Mode button in Overview Actions");
public static final BooleanFlag ENABLE_WIDGETS_PICKER_AIAI_SEARCH = new DeviceFlag(
- "ENABLE_WIDGETS_PICKER_AIAI_SEARCH", true, "Enable AiAi search in the widgets picker");
+ "ENABLE_WIDGETS_PICKER_AIAI_SEARCH", false, "Enable AiAi search in the widgets picker");
+
+ public static final BooleanFlag ENABLE_OVERVIEW_SHARE = getDebugFlag(
+ "ENABLE_OVERVIEW_SHARE", false, "Show Share button in Overview Actions");
public static final BooleanFlag ENABLE_OVERVIEW_SHARING_TO_PEOPLE = getDebugFlag(
"ENABLE_OVERVIEW_SHARING_TO_PEOPLE", true,
"Show indicators for content on Overview to share with top people. ");
+ public static final BooleanFlag ENABLE_OVERVIEW_CONTENT_PUSH = getDebugFlag(
+ "ENABLE_OVERVIEW_CONTENT_PUSH", false, "Show Content Push button in Overview Actions");
+
public static final BooleanFlag ENABLE_DATABASE_RESTORE = getDebugFlag(
"ENABLE_DATABASE_RESTORE", false,
"Enable database restore when new restore session is created");
+ public static final BooleanFlag ENABLE_SMARTSPACE_UNIVERSAL = getDebugFlag(
+ "ENABLE_SMARTSPACE_UNIVERSAL", false,
+ "Replace Smartspace with a version rendered by System UI.");
+
+ public static final BooleanFlag ENABLE_SMARTSPACE_ENHANCED = getDebugFlag(
+ "ENABLE_SMARTSPACE_ENHANCED", true,
+ "Replace Smartspace with the enhanced version. "
+ + "Ignored if ENABLE_SMARTSPACE_UNIVERSAL is enabled.");
+
+ public static final BooleanFlag ENABLE_SMARTSPACE_FEEDBACK = getDebugFlag(
+ "ENABLE_SMARTSPACE_FEEDBACK", true,
+ "Adds a menu option to send feedback for Enhanced Smartspace.");
+
public static final BooleanFlag ENABLE_SMARTSPACE_DISMISS = getDebugFlag(
"ENABLE_SMARTSPACE_DISMISS", true,
"Adds a menu option to dismiss the current Enhanced Smartspace card.");
@@ -197,12 +219,15 @@ public final class FeatureFlags {
"ENABLE_APP_PREDICTIONS_WHILE_VISIBLE", true, "Allows app "
+ "predictions to be updated while they are visible to the user.");
- public static final BooleanFlag ENABLE_TASKBAR_POPUP_MENU = getDebugFlag(
- "ENABLE_TASKBAR_POPUP_MENU", true, "Enables long pressing taskbar icons to show the"
- + " popup menu.");
+ public static final BooleanFlag ENABLE_TASKBAR = getDebugFlag(
+ "ENABLE_TASKBAR", false, "Allows a system Taskbar to be shown on larger devices.");
+
+ public static final BooleanFlag ENABLE_OVERVIEW_GRID = getDebugFlag(
+ "ENABLE_OVERVIEW_GRID", false, "Uses grid overview layout. "
+ + "Only applicable on large screen devices.");
public static final BooleanFlag ENABLE_TWO_PANEL_HOME = getDebugFlag(
- "ENABLE_TWO_PANEL_HOME", true,
+ "ENABLE_TWO_PANEL_HOME", false,
"Uses two panel on home screen. Only applicable on large screen devices.");
public static final BooleanFlag ENABLE_SCRIM_FOR_APP_LAUNCH = getDebugFlag(
@@ -210,7 +235,7 @@ public final class FeatureFlags {
"Enables scrim during app launch animation.");
public static final BooleanFlag ENABLE_SPLIT_SELECT = getDebugFlag(
- "ENABLE_SPLIT_SELECT", true, "Uses new split screen selection overview UI");
+ "ENABLE_SPLIT_SELECT", false, "Uses new split screen selection overview UI");
public static final BooleanFlag ENABLE_ENFORCED_ROUNDED_CORNERS = new DeviceFlag(
"ENABLE_ENFORCED_ROUNDED_CORNERS", true, "Enforce rounded corners on all App Widgets");
@@ -222,61 +247,13 @@ public final class FeatureFlags {
public static final BooleanFlag NOTIFY_CRASHES = getDebugFlag("NOTIFY_CRASHES", false,
"Sends a notification whenever launcher encounters an uncaught exception.");
+ public static final BooleanFlag PROTOTYPE_APP_CLOSE = getDebugFlag(
+ "PROTOTYPE_APP_CLOSE", false, "Enables new app close");
+
public static final BooleanFlag ENABLE_WALLPAPER_SCRIM = getDebugFlag(
"ENABLE_WALLPAPER_SCRIM", false,
"Enables scrim over wallpaper for text protection.");
- public static final BooleanFlag WIDGETS_IN_LAUNCHER_PREVIEW = getDebugFlag(
- "WIDGETS_IN_LAUNCHER_PREVIEW", true,
- "Enables widgets in Launcher preview for the Wallpaper app.");
-
- public static final BooleanFlag QUICK_WALLPAPER_PICKER = getDebugFlag(
- "QUICK_WALLPAPER_PICKER", true,
- "Shows quick wallpaper picker in long-press menu");
-
- public static final BooleanFlag ENABLE_BACK_SWIPE_HOME_ANIMATION = getDebugFlag(
- "ENABLE_BACK_SWIPE_HOME_ANIMATION", true,
- "Enables home animation to icon when user swipes back.");
-
- public static final BooleanFlag ENABLE_ICON_LABEL_AUTO_SCALING = getDebugFlag(
- "ENABLE_ICON_LABEL_AUTO_SCALING", true,
- "Enables scaling/spacing for icon labels to make more characters visible");
-
- public static final BooleanFlag ENABLE_ALL_APPS_IN_TASKBAR = getDebugFlag(
- "ENABLE_ALL_APPS_IN_TASKBAR", true,
- "Enables accessing All Apps from the system Taskbar.");
-
- public static final BooleanFlag ENABLE_ALL_APPS_BUTTON_IN_HOTSEAT = getDebugFlag(
- "ENABLE_ALL_APPS_BUTTON_IN_HOTSEAT", false,
- "Enables displaying the all apps button in the hotseat.");
-
- public static final BooleanFlag ENABLE_ALL_APPS_ONE_SEARCH_IN_TASKBAR = getDebugFlag(
- "ENABLE_ALL_APPS_ONE_SEARCH_IN_TASKBAR", false,
- "Enables One Search box in Taskbar All Apps.");
-
- public static final BooleanFlag ENABLE_SPLIT_FROM_WORKSPACE = getDebugFlag(
- "ENABLE_SPLIT_FROM_WORKSPACE", true,
- "Enable initiating split screen from workspace.");
-
- public static final BooleanFlag ENABLE_NEW_MIGRATION_LOGIC = getDebugFlag(
- "ENABLE_NEW_MIGRATION_LOGIC", true,
- "Enable the new grid migration logic, keeping pages when src < dest");
-
- public static final BooleanFlag ENABLE_ONE_SEARCH_MOTION = new DeviceFlag(
- "ENABLE_ONE_SEARCH_MOTION", true, "Enables animations in OneSearch.");
-
- public static final BooleanFlag ENABLE_SHOW_KEYBOARD_OPTION_IN_ALL_APPS = new DeviceFlag(
- "ENABLE_SHOW_KEYBOARD_OPTION_IN_ALL_APPS", true,
- "Enable option to show keyboard when going to all-apps");
-
- public static final BooleanFlag USE_LOCAL_ICON_OVERRIDES = getDebugFlag(
- "USE_LOCAL_ICON_OVERRIDES", true,
- "Use inbuilt monochrome icons if app doesn't provide one");
-
- public static final BooleanFlag ENABLE_DISMISS_PREDICTION_UNDO = getDebugFlag(
- "ENABLE_DISMISS_PREDICTION_UNDO", false,
- "Show an 'Undo' snackbar when users dismiss a predicted hotseat item");
-
public static void initialize(Context context) {
synchronized (sDebugFlags) {
for (DebugFlag flag : sDebugFlags) {
@@ -314,7 +291,7 @@ public final class FeatureFlags {
public static class BooleanFlag {
public final String key;
- public final boolean defaultValue;
+ public boolean defaultValue;
public BooleanFlag(String key, boolean defaultValue) {
this.key = key;
@@ -333,12 +310,16 @@ public final class FeatureFlags {
protected StringBuilder appendProps(StringBuilder src) {
return src.append(key).append(", defaultValue=").append(defaultValue);
}
+
+ public void addChangeListener(Context context, Runnable r) { }
+
+ public void removeChangeListener(Runnable r) {}
}
public static class DebugFlag extends BooleanFlag {
public final String description;
- protected boolean mCurrentValue;
+ private boolean mCurrentValue;
public DebugFlag(String key, boolean defaultValue, String description) {
super(key, defaultValue);
diff --git a/src/com/android/launcher3/dragndrop/AddItemActivity.java b/src/com/android/launcher3/dragndrop/AddItemActivity.java
index 466b2689ae..55be4a4604 100644
--- a/src/com/android/launcher3/dragndrop/AddItemActivity.java
+++ b/src/com/android/launcher3/dragndrop/AddItemActivity.java
@@ -189,18 +189,10 @@ public class AddItemActivity extends BaseActivity
if (appWidgetHostView != null) {
bounds = new Rect();
appWidgetHostView.getSourceVisualDragBounds(bounds);
- float appWidgetHostViewScale = mWidgetCell.getAppWidgetHostViewScale();
- int xOffset =
- appWidgetHostView.getLeft() - (int) (mLastTouchPos.x * appWidgetHostViewScale);
- int yOffset =
- appWidgetHostView.getTop() - (int) (mLastTouchPos.y * appWidgetHostViewScale);
- bounds.offset(xOffset, yOffset);
- listener = new PinItemDragListener(
- mRequest,
- bounds,
- appWidgetHostView.getMeasuredWidth(),
- appWidgetHostView.getMeasuredWidth(),
- appWidgetHostViewScale);
+ bounds.offset(appWidgetHostView.getLeft() - (int) mLastTouchPos.x,
+ appWidgetHostView.getTop() - (int) mLastTouchPos.y);
+ listener = new PinItemDragListener(mRequest, bounds,
+ appWidgetHostView.getMeasuredWidth(), appWidgetHostView.getMeasuredWidth());
} else {
bounds = img.getBitmapBounds();
bounds.offset(img.getLeft() - (int) mLastTouchPos.x,
@@ -286,7 +278,9 @@ public class AddItemActivity extends BaseActivity
@Override
protected void onPostExecute(WidgetItem item) {
- mWidgetCell.applyFromCellItem(item);
+ mWidgetCell.setPreviewSize(item);
+ mWidgetCell.applyFromCellItem(item, mApp.getWidgetCache());
+ mWidgetCell.ensurePreview();
}
}.executeOnExecutor(MODEL_EXECUTOR);
// TODO: Create a worker looper executor and reuse that everywhere.
diff --git a/src/com/android/launcher3/dragndrop/DragController.java b/src/com/android/launcher3/dragndrop/DragController.java
index 35cdfef465..5731db4cbb 100644
--- a/src/com/android/launcher3/dragndrop/DragController.java
+++ b/src/com/android/launcher3/dragndrop/DragController.java
@@ -18,10 +18,10 @@ package com.android.launcher3.dragndrop;
import static com.android.launcher3.Utilities.ATLEAST_Q;
+import android.content.ComponentName;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
-import android.util.Log;
import android.view.DragEvent;
import android.view.KeyEvent;
import android.view.MotionEvent;
@@ -34,13 +34,12 @@ import com.android.launcher3.DropTarget;
import com.android.launcher3.logging.InstanceId;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo;
-import com.android.launcher3.testing.TestProtocol;
+import com.android.launcher3.util.ItemInfoMatcher;
import com.android.launcher3.util.TouchController;
import com.android.launcher3.views.ActivityContext;
import java.util.ArrayList;
import java.util.Optional;
-import java.util.function.Predicate;
/**
* Class for initiating a drag within a view or across multiple views.
@@ -75,7 +74,7 @@ public abstract class DragController<T extends ActivityContext>
/** Coordinate for last touch event **/
protected final Point mLastTouch = new Point();
- protected final Point mTmpPoint = new Point();
+ private final Point mTmpPoint = new Point();
protected DropTarget.DragObject mDragObject;
@@ -147,9 +146,6 @@ public abstract class DragController<T extends ActivityContext>
float initialDragViewScale,
float dragViewScaleOnDrop,
DragOptions options) {
- if (TestProtocol.sDebugTracing) {
- Log.d(TestProtocol.NO_DROP_TARGET, "4");
- }
return startDrag(drawable, /* view= */ null, originalView, dragLayerX, dragLayerY,
source, dragInfo, dragOffset, dragRegion, initialDragViewScale, dragViewScaleOnDrop,
options);
@@ -207,9 +203,6 @@ public abstract class DragController<T extends ActivityContext>
DragOptions options);
protected void callOnDragStart() {
- if (TestProtocol.sDebugTracing) {
- Log.d(TestProtocol.NO_DROP_TARGET, "6");
- }
if (mOptions.preDragCondition != null) {
mOptions.preDragCondition.onPreDragEnd(mDragObject, true /* dragStarted*/);
}
@@ -274,12 +267,15 @@ public abstract class DragController<T extends ActivityContext>
protected abstract void exitDrag();
- public void onAppsRemoved(Predicate<ItemInfo> matcher) {
+ public void onAppsRemoved(ItemInfoMatcher matcher) {
// Cancel the current drag if we are removing an app that we are dragging
if (mDragObject != null) {
ItemInfo dragInfo = mDragObject.dragInfo;
- if (dragInfo instanceof WorkspaceItemInfo && matcher.test(dragInfo)) {
- cancelDrag();
+ if (dragInfo instanceof WorkspaceItemInfo) {
+ ComponentName cn = dragInfo.getTargetComponent();
+ if (cn != null && matcher.matches(dragInfo, cn)) {
+ cancelDrag();
+ }
}
}
}
@@ -321,7 +317,7 @@ public abstract class DragController<T extends ActivityContext>
mDragObject.dragView.animateTo(mMotionDown.x, mMotionDown.y, onCompleteRunnable, duration);
}
- protected void callOnDragEnd() {
+ private void callOnDragEnd() {
if (mIsInPreDrag && mOptions.preDragCondition != null) {
mOptions.preDragCondition.onPreDragEnd(mDragObject, false /* dragStarted*/);
}
@@ -347,7 +343,7 @@ public abstract class DragController<T extends ActivityContext>
/**
* Clamps the position to the drag layer bounds.
*/
- protected Point getClampedDragLayerPos(float x, float y) {
+ private Point getClampedDragLayerPos(float x, float y) {
mActivity.getDragLayer().getLocalVisibleRect(mRectTemp);
mTmpPoint.x = (int) Math.max(mRectTemp.left, Math.min(x, mRectTemp.right - 1));
mTmpPoint.y = (int) Math.max(mRectTemp.top, Math.min(y, mRectTemp.bottom - 1));
@@ -394,7 +390,7 @@ public abstract class DragController<T extends ActivityContext>
return false;
}
- Point dragLayerPos = getClampedDragLayerPos(getX(ev), getY(ev));
+ Point dragLayerPos = getClampedDragLayerPos(ev.getX(), ev.getY());
mLastTouch.set(dragLayerPos.x, dragLayerPos.y);
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
// Remember location of down touch
@@ -407,14 +403,6 @@ public abstract class DragController<T extends ActivityContext>
return mDragDriver != null && mDragDriver.onInterceptTouchEvent(ev);
}
- protected float getX(MotionEvent ev) {
- return ev.getX();
- }
-
- protected float getY(MotionEvent ev) {
- return ev.getY();
- }
-
/**
* Call this from a drag source view.
*/
diff --git a/src/com/android/launcher3/dragndrop/DragDriver.java b/src/com/android/launcher3/dragndrop/DragDriver.java
index 72e47e536c..d4ce3080c0 100644
--- a/src/com/android/launcher3/dragndrop/DragDriver.java
+++ b/src/com/android/launcher3/dragndrop/DragDriver.java
@@ -165,11 +165,8 @@ public abstract class DragDriver {
* Class for driving an internal (i.e. not using framework) drag/drop operation.
*/
static class InternalDragDriver extends DragDriver {
- private final DragController mDragController;
-
InternalDragDriver(DragController dragController, Consumer<MotionEvent> sec) {
super(dragController, sec);
- mDragController = dragController;
}
@Override
@@ -179,14 +176,11 @@ public abstract class DragDriver {
switch (action) {
case MotionEvent.ACTION_MOVE:
- mEventListener.onDriverDragMove(mDragController.getX(ev),
- mDragController.getY(ev));
+ mEventListener.onDriverDragMove(ev.getX(), ev.getY());
break;
case MotionEvent.ACTION_UP:
- mEventListener.onDriverDragMove(mDragController.getX(ev),
- mDragController.getY(ev));
- mEventListener.onDriverDragEnd(mDragController.getX(ev),
- mDragController.getY(ev));
+ mEventListener.onDriverDragMove(ev.getX(), ev.getY());
+ mEventListener.onDriverDragEnd(ev.getX(), ev.getY());
break;
case MotionEvent.ACTION_CANCEL:
mEventListener.onDriverDragCancel();
@@ -203,8 +197,7 @@ public abstract class DragDriver {
switch (action) {
case MotionEvent.ACTION_UP:
- mEventListener.onDriverDragEnd(mDragController.getX(ev),
- mDragController.getY(ev));
+ mEventListener.onDriverDragEnd(ev.getX(), ev.getY());
break;
case MotionEvent.ACTION_CANCEL:
mEventListener.onDriverDragCancel();
diff --git a/src/com/android/launcher3/dragndrop/DragLayer.java b/src/com/android/launcher3/dragndrop/DragLayer.java
index 8eeca7d6d8..011325d6cf 100644
--- a/src/com/android/launcher3/dragndrop/DragLayer.java
+++ b/src/com/android/launcher3/dragndrop/DragLayer.java
@@ -17,19 +17,14 @@
package com.android.launcher3.dragndrop;
-import static android.animation.ObjectAnimator.ofFloat;
-
-import static com.android.launcher3.LauncherAnimUtils.VIEW_TRANSLATE_X;
-import static com.android.launcher3.LauncherAnimUtils.VIEW_TRANSLATE_Y;
-import static com.android.launcher3.Utilities.mapRange;
-import static com.android.launcher3.anim.AnimatorListeners.forEndCallback;
import static com.android.launcher3.anim.Interpolators.DEACCEL_1_5;
import static com.android.launcher3.compat.AccessibilityManagerCompat.sendCustomAccessibilityEvent;
import android.animation.Animator;
-import android.animation.ObjectAnimator;
+import android.animation.AnimatorListenerAdapter;
import android.animation.TimeInterpolator;
-import android.animation.TypeEvaluator;
+import android.animation.ValueAnimator;
+import android.animation.ValueAnimator.AnimatorUpdateListener;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Canvas;
@@ -49,11 +44,10 @@ import com.android.launcher3.Launcher;
import com.android.launcher3.R;
import com.android.launcher3.ShortcutAndWidgetContainer;
import com.android.launcher3.Workspace;
-import com.android.launcher3.anim.PendingAnimation;
-import com.android.launcher3.anim.SpringProperty;
import com.android.launcher3.folder.Folder;
import com.android.launcher3.graphics.Scrim;
import com.android.launcher3.keyboard.ViewGroupFocusHelper;
+import com.android.launcher3.util.Thunk;
import com.android.launcher3.util.TouchController;
import com.android.launcher3.views.BaseDragLayer;
@@ -65,7 +59,9 @@ import java.util.ArrayList;
public class DragLayer extends BaseDragLayer<Launcher> {
public static final int ALPHA_INDEX_OVERLAY = 0;
- private static final int ALPHA_CHANNEL_COUNT = 1;
+ public static final int ALPHA_INDEX_LAUNCHER_LOAD = 1;
+ public static final int ALPHA_INDEX_TRANSITIONS = 2;
+ private static final int ALPHA_CHANNEL_COUNT = 3;
public static final int ANIMATION_END_DISAPPEAR = 0;
public static final int ANIMATION_END_REMAIN_VISIBLE = 2;
@@ -73,9 +69,11 @@ public class DragLayer extends BaseDragLayer<Launcher> {
private DragController mDragController;
// Variables relating to animation of views after drop
- private Animator mDropAnim = null;
+ private ValueAnimator mDropAnim = null;
- private DragView mDropView = null;
+ @Thunk DragView mDropView = null;
+ @Thunk int mAnchorViewInitialScrollX = 0;
+ @Thunk View mAnchorView = null;
private boolean mHoverPointClosesFolder = false;
@@ -102,10 +100,7 @@ public class DragLayer extends BaseDragLayer<Launcher> {
mFocusIndicatorHelper = new ViewGroupFocusHelper(this);
}
- /**
- * Set up the drag layer with the parameters.
- */
- public void setup(DragController dragController, Workspace<?> workspace) {
+ public void setup(DragController dragController, Workspace workspace) {
mDragController = dragController;
recreateControllers();
mWorkspaceDragScrim = new Scrim(this);
@@ -225,7 +220,12 @@ public class DragLayer extends BaseDragLayer<Launcher> {
public void animateViewIntoPosition(DragView dragView, final int[] pos, float alpha,
float scaleX, float scaleY, int animationEndStyle, Runnable onFinishRunnable,
int duration) {
- animateViewIntoPosition(dragView, pos[0], pos[1], alpha, scaleX, scaleY,
+ Rect r = new Rect();
+ getViewRectRelativeToSelf(dragView, r);
+ final int fromX = r.left;
+ final int fromY = r.top;
+
+ animateViewIntoPosition(dragView, fromX, fromY, pos[0], pos[1], alpha, 1, 1, scaleX, scaleY,
onFinishRunnable, animationEndStyle, duration, null);
}
@@ -241,6 +241,11 @@ public class DragLayer extends BaseDragLayer<Launcher> {
parentChildren.measureChild(child);
parentChildren.layoutChild(child);
+ Rect dragViewBounds = new Rect();
+ getViewRectRelativeToSelf(dragView, dragViewBounds);
+ final int fromX = dragViewBounds.left;
+ final int fromY = dragViewBounds.top;
+
float coord[] = new float[2];
float childScale = child.getScaleX();
@@ -283,50 +288,51 @@ public class DragLayer extends BaseDragLayer<Launcher> {
child.setVisibility(INVISIBLE);
Runnable onCompleteRunnable = () -> child.setVisibility(VISIBLE);
- animateViewIntoPosition(dragView, toX, toY, 1, toScale, toScale,
+ animateViewIntoPosition(dragView, fromX, fromY, toX, toY, 1, 1, 1, toScale, toScale,
onCompleteRunnable, ANIMATION_END_DISAPPEAR, duration, anchorView);
}
- /**
- * This method animates a view at the end of a drag and drop animation.
- */
- public void animateViewIntoPosition(final DragView view,
- final int toX, final int toY, float finalAlpha,
+ public void animateViewIntoPosition(final DragView view, final int fromX, final int fromY,
+ final int toX, final int toY, float finalAlpha, float initScaleX, float initScaleY,
float finalScaleX, float finalScaleY, Runnable onCompleteRunnable,
int animationEndStyle, int duration, View anchorView) {
+ Rect from = new Rect(fromX, fromY, fromX +
+ view.getMeasuredWidth(), fromY + view.getMeasuredHeight());
Rect to = new Rect(toX, toY, toX + view.getMeasuredWidth(), toY + view.getMeasuredHeight());
- animateView(view, to, finalAlpha, finalScaleX, finalScaleY, duration,
- null, onCompleteRunnable, animationEndStyle, anchorView);
+ animateView(view, from, to, finalAlpha, initScaleX, initScaleY, finalScaleX, finalScaleY, duration,
+ null, null, onCompleteRunnable, animationEndStyle, anchorView);
}
/**
* This method animates a view at the end of a drag and drop animation.
+ *
* @param view The view to be animated. This view is drawn directly into DragLayer, and so
* doesn't need to be a child of DragLayer.
+ * @param from The initial location of the view. Only the left and top parameters are used.
* @param to The final location of the view. Only the left and top parameters are used. This
-* location doesn't account for scaling, and so should be centered about the desired
-* final location (including scaling).
+ * location doesn't account for scaling, and so should be centered about the desired
+ * final location (including scaling).
* @param finalAlpha The final alpha of the view, in case we want it to fade as it animates.
* @param finalScaleX The final scale of the view. The view is scaled about its center.
* @param finalScaleY The final scale of the view. The view is scaled about its center.
* @param duration The duration of the animation.
* @param motionInterpolator The interpolator to use for the location of the view.
+ * @param alphaInterpolator The interpolator to use for the alpha of the view.
* @param onCompleteRunnable Optional runnable to run on animation completion.
* @param animationEndStyle Whether or not to fade out the view once the animation completes.
-* {@link #ANIMATION_END_DISAPPEAR} or {@link #ANIMATION_END_REMAIN_VISIBLE}.
+ * {@link #ANIMATION_END_DISAPPEAR} or {@link #ANIMATION_END_REMAIN_VISIBLE}.
* @param anchorView If not null, this represents the view which the animated view stays
+ * anchored to in case scrolling is currently taking place. Note: currently this is
+ * only used for the X dimension for the case of the workspace.
*/
- public void animateView(final DragView view, final Rect to,
- final float finalAlpha, final float finalScaleX, final float finalScaleY, int duration,
- final Interpolator motionInterpolator, final Runnable onCompleteRunnable,
- final int animationEndStyle, View anchorView) {
- view.cancelAnimation();
- view.requestLayout();
-
- final int[] from = getViewLocationRelativeToSelf(view);
+ public void animateView(final DragView view, final Rect from, final Rect to,
+ final float finalAlpha, final float initScaleX, final float initScaleY,
+ final float finalScaleX, final float finalScaleY, int duration,
+ final Interpolator motionInterpolator, final Interpolator alphaInterpolator,
+ final Runnable onCompleteRunnable, final int animationEndStyle, View anchorView) {
// Calculate the duration of the animation based on the object's distance
- final float dist = (float) Math.hypot(to.left - from[0], to.top - from[1]);
+ final float dist = (float) Math.hypot(to.left - from.left, to.top - from.top);
final Resources res = getResources();
final float maxDist = (float) res.getInteger(R.integer.config_dropAnimMaxDist);
@@ -340,45 +346,93 @@ public class DragLayer extends BaseDragLayer<Launcher> {
}
// Fall back to cubic ease out interpolator for the animation if none is specified
- TimeInterpolator interpolator =
- motionInterpolator == null ? DEACCEL_1_5 : motionInterpolator;
+ TimeInterpolator interpolator = null;
+ if (alphaInterpolator == null || motionInterpolator == null) {
+ interpolator = DEACCEL_1_5;
+ }
// Animate the view
- PendingAnimation anim = new PendingAnimation(duration);
- anim.add(ofFloat(view, View.SCALE_X, finalScaleX), interpolator, SpringProperty.DEFAULT);
- anim.add(ofFloat(view, View.SCALE_Y, finalScaleY), interpolator, SpringProperty.DEFAULT);
- anim.setViewAlpha(view, finalAlpha, interpolator);
- anim.setFloat(view, VIEW_TRANSLATE_Y, to.top, interpolator);
-
- ObjectAnimator xMotion = ofFloat(view, VIEW_TRANSLATE_X, to.left);
- if (anchorView != null) {
- final int startScroll = anchorView.getScrollX();
- TypeEvaluator<Float> evaluator = (f, s, e) -> mapRange(f, s, e)
- + (anchorView.getScaleX() * (startScroll - anchorView.getScrollX()));
- xMotion.setEvaluator(evaluator);
- }
- anim.add(xMotion, interpolator, SpringProperty.DEFAULT);
- if (onCompleteRunnable != null) {
- anim.addListener(forEndCallback(onCompleteRunnable));
- }
- playDropAnimation(view, anim.buildAnim(), animationEndStyle);
+ final float initAlpha = view.getAlpha();
+ final float dropViewScale = view.getScaleX();
+ AnimatorUpdateListener updateCb = new AnimatorUpdateListener() {
+ @Override
+ public void onAnimationUpdate(ValueAnimator animation) {
+ final float percent = (Float) animation.getAnimatedValue();
+ final int width = view.getMeasuredWidth();
+ final int height = view.getMeasuredHeight();
+
+ float alphaPercent = alphaInterpolator == null ? percent :
+ alphaInterpolator.getInterpolation(percent);
+ float motionPercent = motionInterpolator == null ? percent :
+ motionInterpolator.getInterpolation(percent);
+
+ float initialScaleX = initScaleX * dropViewScale;
+ float initialScaleY = initScaleY * dropViewScale;
+ float scaleX = finalScaleX * percent + initialScaleX * (1 - percent);
+ float scaleY = finalScaleY * percent + initialScaleY * (1 - percent);
+ float alpha = finalAlpha * alphaPercent + initAlpha * (1 - alphaPercent);
+
+ float fromLeft = from.left + (initialScaleX - 1f) * width / 2;
+ float fromTop = from.top + (initialScaleY - 1f) * height / 2;
+
+ int x = (int) (fromLeft + Math.round(((to.left - fromLeft) * motionPercent)));
+ int y = (int) (fromTop + Math.round(((to.top - fromTop) * motionPercent)));
+
+ int anchorAdjust = mAnchorView == null ? 0 : (int) (mAnchorView.getScaleX() *
+ (mAnchorViewInitialScrollX - mAnchorView.getScrollX()));
+
+ int xPos = x - mDropView.getScrollX() + anchorAdjust;
+ int yPos = y - mDropView.getScrollY();
+
+ mDropView.setTranslationX(xPos);
+ mDropView.setTranslationY(yPos);
+ mDropView.setScaleX(scaleX);
+ mDropView.setScaleY(scaleY);
+ mDropView.setAlpha(alpha);
+ }
+ };
+ animateView(view, updateCb, duration, interpolator, onCompleteRunnable, animationEndStyle,
+ anchorView);
}
- /**
- * Runs a previously constructed drop animation
- */
- public void playDropAnimation(final DragView view, Animator animator, int animationEndStyle) {
+ public void animateView(final DragView view, AnimatorUpdateListener updateCb, int duration,
+ TimeInterpolator interpolator, final Runnable onCompleteRunnable,
+ final int animationEndStyle, View anchorView) {
// Clean up the previous animations
if (mDropAnim != null) mDropAnim.cancel();
// Show the drop view if it was previously hidden
mDropView = view;
- // Create and start the animation
- mDropAnim = animator;
- mDropAnim.addListener(forEndCallback(() -> mDropAnim = null));
- if (animationEndStyle == ANIMATION_END_DISAPPEAR) {
- mDropAnim.addListener(forEndCallback(this::clearAnimatedView));
+ mDropView.cancelAnimation();
+ mDropView.requestLayout();
+
+ // Set the anchor view if the page is scrolling
+ if (anchorView != null) {
+ mAnchorViewInitialScrollX = anchorView.getScrollX();
}
+ mAnchorView = anchorView;
+
+ // Create and start the animation
+ mDropAnim = new ValueAnimator();
+ mDropAnim.setInterpolator(interpolator);
+ mDropAnim.setDuration(duration);
+ mDropAnim.setFloatValues(0f, 1f);
+ mDropAnim.addUpdateListener(updateCb);
+ mDropAnim.addListener(new AnimatorListenerAdapter() {
+ public void onAnimationEnd(Animator animation) {
+ if (onCompleteRunnable != null) {
+ onCompleteRunnable.run();
+ }
+ switch (animationEndStyle) {
+ case ANIMATION_END_DISAPPEAR:
+ clearAnimatedView();
+ break;
+ case ANIMATION_END_REMAIN_VISIBLE:
+ break;
+ }
+ mDropAnim = null;
+ }
+ });
mDropAnim.start();
}
diff --git a/src/com/android/launcher3/dragndrop/DragView.java b/src/com/android/launcher3/dragndrop/DragView.java
index 0264ae21be..3fdb256d4c 100644
--- a/src/com/android/launcher3/dragndrop/DragView.java
+++ b/src/com/android/launcher3/dragndrop/DragView.java
@@ -21,20 +21,17 @@ import static android.view.View.MeasureSpec.makeMeasureSpec;
import static com.android.launcher3.LauncherAnimUtils.VIEW_ALPHA;
import static com.android.launcher3.Utilities.getBadge;
-import static com.android.launcher3.icons.FastBitmapDrawable.getDisabledColorFilter;
import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.animation.ValueAnimator.AnimatorUpdateListener;
import android.annotation.TargetApi;
import android.content.Context;
+import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
-import android.graphics.ColorFilter;
import android.graphics.Path;
import android.graphics.Picture;
import android.graphics.Point;
@@ -56,19 +53,23 @@ import androidx.dynamicanimation.animation.FloatPropertyCompat;
import androidx.dynamicanimation.animation.SpringAnimation;
import androidx.dynamicanimation.animation.SpringForce;
+import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherSettings;
+import com.android.launcher3.LauncherState;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.anim.Interpolators;
import com.android.launcher3.icons.FastBitmapDrawable;
import com.android.launcher3.icons.LauncherIcons;
import com.android.launcher3.model.data.ItemInfo;
+import com.android.launcher3.statemanager.StateManager.StateListener;
import com.android.launcher3.util.RunnableList;
-import com.android.launcher3.views.ActivityContext;
+import com.android.launcher3.util.Thunk;
import com.android.launcher3.views.BaseDragLayer;
+import com.android.launcher3.widget.LauncherAppWidgetHostView;
/** A custom view for rendering an icon, folder, shortcut or widget during drag-n-drop. */
-public abstract class DragView<T extends Context & ActivityContext> extends FrameLayout {
+public class DragView extends FrameLayout implements StateListener<LauncherState> {
public static final int VIEW_ZOOM_DURATION = 150;
@@ -81,24 +82,22 @@ public abstract class DragView<T extends Context & ActivityContext> extends Fram
private final int mHeight;
private final int mBlurSizeOutline;
- protected final int mRegistrationX;
- protected final int mRegistrationY;
+ private final int mRegistrationX;
+ private final int mRegistrationY;
private final float mInitialScale;
- protected final float mScaleOnDrop;
- protected final int[] mTempLoc = new int[2];
+ private final float mScaleOnDrop;
+ private final int[] mTempLoc = new int[2];
private final RunnableList mOnDragStartCallback = new RunnableList();
private Point mDragVisualizeOffset = null;
private Rect mDragRegion = null;
- protected final T mActivity;
- private final BaseDragLayer<T> mDragLayer;
+ private final Launcher mLauncher;
+ private final DragLayer mDragLayer;
+ @Thunk final DragController mDragController;
private boolean mHasDrawn = false;
final ValueAnimator mAnim;
- // Whether mAnim has started. Unlike mAnim.isStarted(), this is true even after mAnim ends.
- private boolean mAnimStarted;
- private Runnable mOnAnimEndCallback = null;
private int mLastTouchX;
private int mLastTouchY;
@@ -111,7 +110,7 @@ public abstract class DragView<T extends Context & ActivityContext> extends Fram
private Path mScaledMaskPath;
private Drawable mBadge;
- public DragView(T launcher, Drawable drawable, int registrationX,
+ public DragView(Launcher launcher, Drawable drawable, int registrationX,
int registrationY, final float initialScale, final float scaleOnDrop,
final float finalScaleDps) {
this(launcher, getViewFromDrawable(launcher, drawable),
@@ -124,7 +123,7 @@ public abstract class DragView<T extends Context & ActivityContext> extends Fram
* <p>
* The registration point is the point inside our view that the touch events should
* be centered upon.
- * @param activity The Launcher instance/ActivityContext this DragView is in.
+ * @param launcher The Launcher instance
* @param content the view content that is attached to the drag view.
* @param width the width of the dragView
* @param height the height of the dragView
@@ -134,12 +133,13 @@ public abstract class DragView<T extends Context & ActivityContext> extends Fram
* @param scaleOnDrop the scale used in the drop animation.
* @param finalScaleDps the scale used in the zoom out animation when the drag view is shown.
*/
- public DragView(T activity, View content, int width, int height, int registrationX,
+ public DragView(Launcher launcher, View content, int width, int height, int registrationX,
int registrationY, final float initialScale, final float scaleOnDrop,
final float finalScaleDps) {
- super(activity);
- mActivity = activity;
- mDragLayer = activity.getDragLayer();
+ super(launcher);
+ mLauncher = launcher;
+ mDragLayer = launcher.getDragLayer();
+ mDragController = launcher.getDragController();
mContent = content;
mWidth = width;
@@ -153,12 +153,6 @@ public abstract class DragView<T extends Context & ActivityContext> extends Fram
addView(content, new LayoutParams(width, height));
- // If there is already a scale set on the content, we don't want to clip the children.
- if (content.getScaleX() != 1 || content.getScaleY() != 1) {
- setClipChildren(false);
- setClipToPadding(false);
- }
-
final float scale = (width + finalScaleDps) / width;
// Set the initial scale to avoid any jumps
@@ -176,20 +170,6 @@ public abstract class DragView<T extends Context & ActivityContext> extends Fram
animation.cancel();
}
});
- mAnim.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationStart(Animator animation) {
- mAnimStarted = true;
- }
-
- @Override
- public void onAnimationEnd(Animator animation) {
- super.onAnimationEnd(animation);
- if (mOnAnimEndCallback != null) {
- mOnAnimEndCallback.run();
- }
- }
- });
setDragRegion(new Rect(0, 0, width, height));
@@ -208,8 +188,22 @@ public abstract class DragView<T extends Context & ActivityContext> extends Fram
setWillNotDraw(false);
}
- public void setOnAnimationEndCallback(Runnable callback) {
- mOnAnimEndCallback = callback;
+ @Override
+ protected void onAttachedToWindow() {
+ super.onAttachedToWindow();
+ mLauncher.getStateManager().addStateListener(this);
+ }
+
+ @Override
+ protected void onDetachedFromWindow() {
+ super.onDetachedFromWindow();
+ mLauncher.getStateManager().removeStateListener(this);
+ }
+
+ @Override
+ public void onStateTransitionComplete(LauncherState finalState) {
+ setVisibility((finalState == LauncherState.NORMAL
+ || finalState == LauncherState.SPRING_LOADED) ? VISIBLE : INVISIBLE);
}
/**
@@ -219,7 +213,6 @@ public abstract class DragView<T extends Context & ActivityContext> extends Fram
@TargetApi(Build.VERSION_CODES.O)
public void setItemInfo(final ItemInfo info) {
if (info.itemType != LauncherSettings.Favorites.ITEM_TYPE_APPLICATION
- && info.itemType != LauncherSettings.Favorites.ITEM_TYPE_SEARCH_ACTION
&& info.itemType != LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT
&& info.itemType != LauncherSettings.Favorites.ITEM_TYPE_FOLDER) {
return;
@@ -229,24 +222,24 @@ public abstract class DragView<T extends Context & ActivityContext> extends Fram
Object[] outObj = new Object[1];
int w = mWidth;
int h = mHeight;
- Drawable dr = Utilities.getFullDrawable(mActivity, info, w, h,
- true /* shouldThemeIcon */, outObj);
+ Drawable dr = Utilities.getFullDrawable(mLauncher, info, w, h, outObj);
if (dr instanceof AdaptiveIconDrawable) {
- int blurMargin = (int) mActivity.getResources()
+ int blurMargin = (int) mLauncher.getResources()
.getDimension(R.dimen.blur_size_medium_outline) / 2;
Rect bounds = new Rect(0, 0, w, h);
bounds.inset(blurMargin, blurMargin);
// Badge is applied after icon normalization so the bounds for badge should not
// be scaled down due to icon normalization.
- mBadge = getBadge(mActivity, info, outObj[0]);
- FastBitmapDrawable.setBadgeBounds(mBadge, bounds);
+ Rect badgeBounds = new Rect(bounds);
+ mBadge = getBadge(mLauncher, info, outObj[0]);
+ mBadge.setBounds(badgeBounds);
// Do not draw the background in case of folder as its translucent
final boolean shouldDrawBackground = !(dr instanceof FolderAdaptiveIcon);
- try (LauncherIcons li = LauncherIcons.obtain(mActivity)) {
+ try (LauncherIcons li = LauncherIcons.obtain(mLauncher)) {
Drawable nDr; // drawable to be normalized
if (shouldDrawBackground) {
nDr = dr;
@@ -294,10 +287,11 @@ public abstract class DragView<T extends Context & ActivityContext> extends Fram
removeAllViewsInLayout();
if (info.isDisabled()) {
- ColorFilter filter = getDisabledColorFilter();
- mBgSpringDrawable.setColorFilter(filter);
- mFgSpringDrawable.setColorFilter(filter);
- mBadge.setColorFilter(filter);
+ FastBitmapDrawable d = new FastBitmapDrawable((Bitmap) null);
+ d.setIsDisabled(true);
+ mBgSpringDrawable.setColorFilter(d.getColorFilter());
+ mFgSpringDrawable.setColorFilter(d.getColorFilter());
+ mBadge.setColorFilter(d.getColorFilter());
}
invalidate();
}));
@@ -312,6 +306,16 @@ public abstract class DragView<T extends Context & ActivityContext> extends Fram
mOnDragStartCallback.executeAllAndDestroy();
}
+ // TODO(b/183609936): This is only for LauncherAppWidgetHostView that is rendered in a drawable.
+ // Once LauncherAppWidgetHostView is directly rendered in this view, removes this method.
+ @Override
+ public void invalidate() {
+ super.invalidate();
+ if (mContent instanceof ImageView) {
+ mContent.invalidate();
+ }
+ }
+
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(makeMeasureSpec(mWidth, EXACTLY), makeMeasureSpec(mHeight, EXACTLY));
@@ -409,10 +413,6 @@ public abstract class DragView<T extends Context & ActivityContext> extends Fram
}
}
- public boolean isAnimationFinished() {
- return mAnimStarted && !mAnim.isRunning();
- }
-
/**
* Move the window containing this view.
*
@@ -430,11 +430,12 @@ public abstract class DragView<T extends Context & ActivityContext> extends Fram
applyTranslation();
}
- /**
- * Animate this DragView to the given DragLayer coordinates and then remove it.
- */
- public abstract void animateTo(int toTouchX, int toTouchY, Runnable onCompleteRunnable,
- int duration);
+ public void animateTo(int toTouchX, int toTouchY, Runnable onCompleteRunnable, int duration) {
+ mTempLoc[0] = toTouchX - mRegistrationX;
+ mTempLoc[1] = toTouchY - mRegistrationY;
+ mDragLayer.animateViewIntoPosition(this, mTempLoc, 1f, mScaleOnDrop, mScaleOnDrop,
+ DragLayer.ANIMATION_END_DISAPPEAR, onCompleteRunnable, duration);
+ }
public void animateShift(final int shiftX, final int shiftY) {
if (mAnim.isStarted()) {
@@ -470,7 +471,7 @@ public abstract class DragView<T extends Context & ActivityContext> extends Fram
Picture picture = new Picture();
mContent.draw(picture.beginRecording(mWidth, mHeight));
picture.endRecording();
- View view = new View(mActivity);
+ View view = new View(mLauncher);
view.setBackground(new PictureDrawable(picture));
view.measure(makeMeasureSpec(mWidth, EXACTLY), makeMeasureSpec(mHeight, EXACTLY));
view.layout(mContent.getLeft(), mContent.getTop(),
@@ -491,6 +492,24 @@ public abstract class DragView<T extends Context & ActivityContext> extends Fram
}
/**
+ * If the drag view uses color extraction, block it.
+ */
+ public void disableColorExtraction() {
+ if (mContent instanceof LauncherAppWidgetHostView) {
+ ((LauncherAppWidgetHostView) mContent).disableColorExtraction();
+ }
+ }
+
+ /**
+ * If the drag view uses color extraction, restores it.
+ */
+ public void resumeColorExtraction() {
+ if (mContent instanceof LauncherAppWidgetHostView) {
+ ((LauncherAppWidgetHostView) mContent).enableColorExtraction(/* updateColors= */ false);
+ }
+ }
+
+ /**
* Removes this view from the {@link DragLayer}.
*
* <p>If the drag content is a {@link #mContent}, this call doesn't reattach the
@@ -578,19 +597,4 @@ public abstract class DragView<T extends Context & ActivityContext> extends Fram
iv.setImageDrawable(drawable);
return iv;
}
-
- /**
- * Removes any stray DragView from the DragLayer.
- */
- public static void removeAllViews(ActivityContext activity) {
- BaseDragLayer dragLayer = activity.getDragLayer();
- // Iterate in reverse order. DragView is added later to the dragLayer,
- // and will be one of the last views.
- for (int i = dragLayer.getChildCount() - 1; i >= 0; i--) {
- View child = dragLayer.getChildAt(i);
- if (child instanceof DragView) {
- dragLayer.removeView(child);
- }
- }
- }
}
diff --git a/src/com/android/launcher3/dragndrop/FolderAdaptiveIcon.java b/src/com/android/launcher3/dragndrop/FolderAdaptiveIcon.java
index 6f295e6c50..98c0cfc3a6 100644
--- a/src/com/android/launcher3/dragndrop/FolderAdaptiveIcon.java
+++ b/src/com/android/launcher3/dragndrop/FolderAdaptiveIcon.java
@@ -20,13 +20,9 @@ import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import android.annotation.TargetApi;
import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.ColorFilter;
+import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Path;
-import android.graphics.Path.Direction;
-import android.graphics.Picture;
-import android.graphics.PixelFormat;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.drawable.AdaptiveIconDrawable;
@@ -35,14 +31,13 @@ import android.os.Build;
import android.util.Log;
import androidx.annotation.Nullable;
-import androidx.annotation.UiThread;
-import com.android.launcher3.Utilities;
+import com.android.launcher3.Launcher;
import com.android.launcher3.folder.FolderIcon;
import com.android.launcher3.folder.PreviewBackground;
+import com.android.launcher3.graphics.ShiftedBitmapDrawable;
import com.android.launcher3.icons.BitmapRenderer;
import com.android.launcher3.util.Preconditions;
-import com.android.launcher3.views.ActivityContext;
/**
* {@link AdaptiveIconDrawable} representation of a {@link FolderIcon}
@@ -74,104 +69,79 @@ public class FolderAdaptiveIcon extends AdaptiveIconDrawable {
return mBadge;
}
- @TargetApi(Build.VERSION_CODES.P)
public static @Nullable FolderAdaptiveIcon createFolderAdaptiveIcon(
- ActivityContext activity, int folderId, Point size) {
+ Launcher launcher, int folderId, Point dragViewSize) {
Preconditions.assertNonUiThread();
- if (!Utilities.ATLEAST_P) {
- return null;
- }
-
- // assume square
- if (size.x != size.y) {
- return null;
- }
- int requestedSize = size.x;
-
- // Only use the size actually needed for drawing the folder icon
- int drawingSize = activity.getDeviceProfile().folderIconSizePx;
- int foregroundSize = Math.max(requestedSize, drawingSize);
- float shift = foregroundSize - requestedSize;
-
- Picture background = new Picture();
- Picture foreground = new Picture();
- Picture badge = new Picture();
-
- Canvas bgCanvas = background.beginRecording(requestedSize, requestedSize);
- Canvas badgeCanvas = badge.beginRecording(requestedSize, requestedSize);
-
- Canvas fgCanvas = foreground.beginRecording(foregroundSize, foregroundSize);
- fgCanvas.translate(shift, shift);
-
- // Do not clip the folder drawing since the icon previews extend outside the background.
- Path mask = new Path();
- mask.addRect(-shift, -shift, requestedSize + shift, requestedSize + shift,
- Direction.CCW);
- // Initialize the actual draw commands on the UI thread to avoid race conditions with
+ // Create the actual drawable on the UI thread to avoid race conditions with
// FolderIcon draw pass
try {
- MAIN_EXECUTOR.submit(() -> {
- FolderIcon icon = activity.findFolderIcon(folderId);
- if (icon == null) {
- throw new IllegalArgumentException("Folder not found with id: " + folderId);
- }
- initLayersOnUiThread(icon, requestedSize, bgCanvas, fgCanvas, badgeCanvas);
+ return MAIN_EXECUTOR.submit(() -> {
+ FolderIcon icon = launcher.findFolderIcon(folderId);
+ return icon == null ? null : createDrawableOnUiThread(icon, dragViewSize);
+
}).get();
} catch (Exception e) {
Log.e(TAG, "Unable to create folder icon", e);
return null;
- } finally {
- background.endRecording();
- foreground.endRecording();
- badge.endRecording();
}
-
- // Only convert foreground to a bitmap as it can contain multiple draw commands. Other
- // layers either draw a nothing or a single draw call.
- Bitmap fgBitmap = Bitmap.createBitmap(foreground);
- Paint foregroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
-
- // Do not use PictureDrawable as it moves the picture to the canvas bounds, whereas we want
- // to draw it at (0,0)
- return new FolderAdaptiveIcon(
- new BitmapRendererDrawable(c -> c.drawPicture(background)),
- new BitmapRendererDrawable(
- c -> c.drawBitmap(fgBitmap, -shift, -shift, foregroundPaint)),
- new BitmapRendererDrawable(c -> c.drawPicture(badge)),
- mask);
}
- @UiThread
- private static void initLayersOnUiThread(FolderIcon icon, int size,
- Canvas backgroundCanvas, Canvas foregroundCanvas, Canvas badgeCanvas) {
+ private static FolderAdaptiveIcon createDrawableOnUiThread(FolderIcon icon,
+ Point dragViewSize) {
+ Preconditions.assertUIThread();
+
icon.getPreviewBounds(sTmpRect);
- final int previewSize = sTmpRect.width();
PreviewBackground bg = icon.getFolderBackground();
- final int margin = (size - previewSize) / 2;
+
+ // assume square
+ assert (dragViewSize.x == dragViewSize.y);
+ final int previewSize = sTmpRect.width();
+
+ final int margin = (dragViewSize.x - previewSize) / 2;
final float previewShiftX = -sTmpRect.left + margin;
final float previewShiftY = -sTmpRect.top + margin;
// Initialize badge, which consists of the outline stroke, shadow and dot; these
// must be rendered above the foreground
- badgeCanvas.save();
- badgeCanvas.translate(previewShiftX, previewShiftY);
- icon.drawDot(badgeCanvas);
- badgeCanvas.restore();
-
- // Draw foreground
- foregroundCanvas.save();
- foregroundCanvas.translate(previewShiftX, previewShiftY);
- icon.getPreviewItemManager().draw(foregroundCanvas);
- foregroundCanvas.restore();
-
- // Draw background
- Paint backgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
- backgroundPaint.setColor(bg.getBgColor());
- bg.drawShadow(backgroundCanvas);
- backgroundCanvas.drawCircle(size / 2f, size / 2f, bg.getRadius(), backgroundPaint);
- bg.drawBackgroundStroke(backgroundCanvas);
+ Bitmap badgeBmp = BitmapRenderer.createHardwareBitmap(dragViewSize.x, dragViewSize.y,
+ (canvas) -> {
+ canvas.save();
+ canvas.translate(previewShiftX, previewShiftY);
+ bg.drawShadow(canvas);
+ bg.drawBackgroundStroke(canvas);
+ icon.drawDot(canvas);
+ canvas.restore();
+ });
+
+ // Initialize mask
+ Path mask = new Path();
+ Matrix m = new Matrix();
+ m.setTranslate(previewShiftX, previewShiftY);
+ bg.getClipPath().transform(m, mask);
+
+ Bitmap previewBitmap = BitmapRenderer.createHardwareBitmap(dragViewSize.x, dragViewSize.y,
+ (canvas) -> {
+ canvas.save();
+ canvas.translate(previewShiftX, previewShiftY);
+ icon.getPreviewItemManager().draw(canvas);
+ canvas.restore();
+ });
+
+ Bitmap bgBitmap = BitmapRenderer.createHardwareBitmap(dragViewSize.x, dragViewSize.y,
+ (canvas) -> {
+ Paint p = new Paint();
+ p.setColor(bg.getBgColor());
+
+ canvas.drawCircle(dragViewSize.x / 2f, dragViewSize.y / 2f, bg.getRadius(), p);
+ });
+
+ ShiftedBitmapDrawable badge = new ShiftedBitmapDrawable(badgeBmp, 0, 0);
+ ShiftedBitmapDrawable foreground = new ShiftedBitmapDrawable(previewBitmap, 0, 0);
+ ShiftedBitmapDrawable background = new ShiftedBitmapDrawable(bgBitmap, 0, 0);
+
+ return new FolderAdaptiveIcon(background, foreground, badge, mask);
}
@Override
@@ -204,52 +174,4 @@ public class FolderAdaptiveIcon extends AdaptiveIconDrawable {
& mBadge.getChangingConfigurations();
}
}
-
- private static class BitmapRendererDrawable extends Drawable {
-
- private final BitmapRenderer mRenderer;
-
- BitmapRendererDrawable(BitmapRenderer renderer) {
- mRenderer = renderer;
- }
-
- @Override
- public void draw(Canvas canvas) {
- mRenderer.draw(canvas);
- }
-
- @Override
- public void setAlpha(int i) { }
-
- @Override
- public void setColorFilter(ColorFilter colorFilter) { }
-
- @Override
- public int getOpacity() {
- return PixelFormat.TRANSLUCENT;
- }
-
- @Override
- public ConstantState getConstantState() {
- return new MyConstantState(mRenderer);
- }
-
- private static class MyConstantState extends ConstantState {
- private final BitmapRenderer mRenderer;
-
- MyConstantState(BitmapRenderer renderer) {
- mRenderer = renderer;
- }
-
- @Override
- public Drawable newDrawable() {
- return new BitmapRendererDrawable(mRenderer);
- }
-
- @Override
- public int getChangingConfigurations() {
- return 0;
- }
- }
- }
}
diff --git a/src/com/android/launcher3/dragndrop/LauncherDragController.java b/src/com/android/launcher3/dragndrop/LauncherDragController.java
index dcbfa502e6..a98d70ce71 100644
--- a/src/com/android/launcher3/dragndrop/LauncherDragController.java
+++ b/src/com/android/launcher3/dragndrop/LauncherDragController.java
@@ -24,7 +24,6 @@ import android.content.res.Resources;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
-import android.util.Log;
import android.view.HapticFeedbackConstants;
import android.view.View;
@@ -37,7 +36,6 @@ import com.android.launcher3.Launcher;
import com.android.launcher3.R;
import com.android.launcher3.accessibility.DragViewStateAnnouncer;
import com.android.launcher3.model.data.ItemInfo;
-import com.android.launcher3.testing.TestProtocol;
/**
* Drag controller for Launcher activity
@@ -67,9 +65,6 @@ public class LauncherDragController extends DragController<Launcher> {
float initialDragViewScale,
float dragViewScaleOnDrop,
DragOptions options) {
- if (TestProtocol.sDebugTracing) {
- Log.d(TestProtocol.NO_DROP_TARGET, "5");
- }
if (PROFILE_DRAWING_DURING_DRAG) {
android.os.Debug.startMethodTracing("Launcher");
}
@@ -101,7 +96,7 @@ public class LauncherDragController extends DragController<Launcher> {
final float scaleDps = mIsInPreDrag
? res.getDimensionPixelSize(R.dimen.pre_drag_view_scale) : 0f;
final DragView dragView = mDragObject.dragView = drawable != null
- ? new LauncherDragView(
+ ? new DragView(
mActivity,
drawable,
registrationX,
@@ -109,7 +104,7 @@ public class LauncherDragController extends DragController<Launcher> {
initialDragViewScale,
dragViewScaleOnDrop,
scaleDps)
- : new LauncherDragView(
+ : new DragView(
mActivity,
view,
view.getMeasuredWidth(),
diff --git a/src/com/android/launcher3/dragndrop/LauncherDragView.java b/src/com/android/launcher3/dragndrop/LauncherDragView.java
deleted file mode 100644
index cc68e2e3e4..0000000000
--- a/src/com/android/launcher3/dragndrop/LauncherDragView.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2021 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.launcher3.dragndrop;
-
-import android.graphics.drawable.Drawable;
-import android.view.View;
-
-import com.android.launcher3.Launcher;
-import com.android.launcher3.LauncherState;
-import com.android.launcher3.statemanager.StateManager;
-
-/**
- * A DragView drawn/used by the Launcher activity.
- */
-public class LauncherDragView extends DragView<Launcher>
- implements StateManager.StateListener<LauncherState> {
-
-
- public LauncherDragView(Launcher launcher, Drawable drawable, int registrationX,
- int registrationY, float initialScale, float scaleOnDrop, float finalScaleDps) {
- super(launcher, drawable, registrationX, registrationY, initialScale, scaleOnDrop,
- finalScaleDps);
- }
-
- public LauncherDragView(Launcher launcher, View content, int width, int height,
- int registrationX, int registrationY, float initialScale, float scaleOnDrop,
- float finalScaleDps) {
- super(launcher, content, width, height, registrationX, registrationY, initialScale,
- scaleOnDrop, finalScaleDps);
- }
-
- @Override
- protected void onAttachedToWindow() {
- super.onAttachedToWindow();
- mActivity.getStateManager().addStateListener(this);
- }
-
- @Override
- protected void onDetachedFromWindow() {
- super.onDetachedFromWindow();
- mActivity.getStateManager().removeStateListener(this);
- }
-
- @Override
- public void onStateTransitionComplete(LauncherState finalState) {
- setVisibility((finalState == LauncherState.NORMAL
- || finalState == LauncherState.SPRING_LOADED) ? VISIBLE : INVISIBLE);
- }
-
- @Override
- public void animateTo(int toTouchX, int toTouchY, Runnable onCompleteRunnable, int duration) {
- mTempLoc[0] = toTouchX - mRegistrationX;
- mTempLoc[1] = toTouchY - mRegistrationY;
- mActivity.getDragLayer().animateViewIntoPosition(this, mTempLoc, 1f, mScaleOnDrop,
- mScaleOnDrop, DragLayer.ANIMATION_END_DISAPPEAR, onCompleteRunnable, duration);
- }
-}
diff --git a/src/com/android/launcher3/dragndrop/PinItemDragListener.java b/src/com/android/launcher3/dragndrop/PinItemDragListener.java
index af43ae83e2..2bdf8a085b 100644
--- a/src/com/android/launcher3/dragndrop/PinItemDragListener.java
+++ b/src/com/android/launcher3/dragndrop/PinItemDragListener.java
@@ -48,19 +48,12 @@ public class PinItemDragListener extends BaseItemDragListener {
private final PinItemRequest mRequest;
private final CancellationSignal mCancelSignal;
- private final float mPreviewScale;
public PinItemDragListener(PinItemRequest request, Rect previewRect,
int previewBitmapWidth, int previewViewWidth) {
- this(request, previewRect, previewBitmapWidth, previewViewWidth, /* previewScale= */ 1f);
- }
-
- public PinItemDragListener(PinItemRequest request, Rect previewRect,
- int previewBitmapWidth, int previewViewWidth, float previewScale) {
super(previewRect, previewBitmapWidth, previewViewWidth);
mRequest = request;
mCancelSignal = new CancellationSignal();
- mPreviewScale = previewScale;
}
@Override
@@ -105,7 +98,7 @@ public class PinItemDragListener extends BaseItemDragListener {
PendingItemDragHelper dragHelper = new PendingItemDragHelper(view);
if (mRequest.getRequestType() == PinItemRequest.REQUEST_TYPE_APPWIDGET) {
- dragHelper.setRemoteViewsPreview(getPreview(mRequest), mPreviewScale);
+ dragHelper.setRemoteViewsPreview(getPreview(mRequest));
}
return dragHelper;
}
diff --git a/src/com/android/launcher3/dragndrop/PinShortcutRequestActivityInfo.java b/src/com/android/launcher3/dragndrop/PinShortcutRequestActivityInfo.java
index f9916d0b3b..29e7c1854d 100644
--- a/src/com/android/launcher3/dragndrop/PinShortcutRequestActivityInfo.java
+++ b/src/com/android/launcher3/dragndrop/PinShortcutRequestActivityInfo.java
@@ -87,8 +87,7 @@ class PinShortcutRequestActivityInfo extends ShortcutConfigActivityInfo {
// Total duration for the drop animation to complete.
long duration = mContext.getResources().getInteger(R.integer.config_dropAnimMaxDuration) +
LauncherAnimUtils.SPRING_LOADED_EXIT_DELAY +
- LauncherState.SPRING_LOADED.getTransitionDuration(Launcher.getLauncher(mContext),
- true /* isToState */);
+ LauncherState.SPRING_LOADED.getTransitionDuration(Launcher.getLauncher(mContext));
// Delay the actual accept() call until the drop animation is complete.
return PinRequestHelper.createWorkspaceItemFromPinItemRequest(
mContext, mRequest, duration);
diff --git a/src/com/android/launcher3/dragndrop/SpringLoadedDragController.java b/src/com/android/launcher3/dragndrop/SpringLoadedDragController.java
index fb8a1bc99e..6325877936 100644
--- a/src/com/android/launcher3/dragndrop/SpringLoadedDragController.java
+++ b/src/com/android/launcher3/dragndrop/SpringLoadedDragController.java
@@ -55,7 +55,7 @@ public class SpringLoadedDragController implements OnAlarmListener {
public void onAlarm(Alarm alarm) {
if (mScreen != null) {
// Snap to the screen that we are hovering over now
- Workspace<?> w = mLauncher.getWorkspace();
+ Workspace w = mLauncher.getWorkspace();
if (!w.isVisible(mScreen)) {
w.snapToPage(w.indexOfChild(mScreen));
}
diff --git a/src/com/android/launcher3/folder/Folder.java b/src/com/android/launcher3/folder/Folder.java
index e68ebdb6e5..22bb56c472 100644
--- a/src/com/android/launcher3/folder/Folder.java
+++ b/src/com/android/launcher3/folder/Folder.java
@@ -24,7 +24,7 @@ import static com.android.launcher3.compat.AccessibilityManagerCompat.sendCustom
import static com.android.launcher3.config.FeatureFlags.ALWAYS_USE_HARDWARE_OPTIMIZATION_FOR_FOLDER_ANIMATIONS;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_FOLDER_LABEL_UPDATED;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ITEM_DROP_COMPLETED;
-import static com.android.launcher3.util.window.RefreshRateTracker.getSingleFrameMs;
+import static com.android.launcher3.util.DisplayController.getSingleFrameMs;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
@@ -57,7 +57,6 @@ import android.view.animation.AnimationUtils;
import android.view.inputmethod.EditorInfo;
import android.widget.TextView;
-import androidx.annotation.IntDef;
import androidx.annotation.Nullable;
import androidx.core.content.res.ResourcesCompat;
@@ -72,13 +71,14 @@ import com.android.launcher3.ExtendedEditText;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherSettings;
import com.android.launcher3.OnAlarmListener;
+import com.android.launcher3.PagedView;
import com.android.launcher3.R;
import com.android.launcher3.ShortcutAndWidgetContainer;
import com.android.launcher3.Utilities;
+import com.android.launcher3.Workspace.ItemOperator;
import com.android.launcher3.accessibility.AccessibleDragListenerAdapter;
import com.android.launcher3.accessibility.FolderAccessibilityHelper;
import com.android.launcher3.anim.KeyboardInsetAnimationCallback;
-import com.android.launcher3.compat.AccessibilityManagerCompat;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.dragndrop.DragController;
import com.android.launcher3.dragndrop.DragController.DragListener;
@@ -87,22 +87,19 @@ import com.android.launcher3.logger.LauncherAtom.FromState;
import com.android.launcher3.logger.LauncherAtom.ToState;
import com.android.launcher3.logging.StatsLogManager;
import com.android.launcher3.logging.StatsLogManager.StatsLogger;
+import com.android.launcher3.model.data.AppInfo;
import com.android.launcher3.model.data.FolderInfo;
import com.android.launcher3.model.data.FolderInfo.FolderListener;
import com.android.launcher3.model.data.ItemInfo;
-import com.android.launcher3.model.data.WorkspaceItemFactory;
import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.launcher3.pageindicators.PageIndicatorDots;
import com.android.launcher3.util.Executors;
-import com.android.launcher3.util.LauncherBindableItemsContainer.ItemOperator;
import com.android.launcher3.util.Thunk;
import com.android.launcher3.views.ActivityContext;
import com.android.launcher3.views.BaseDragLayer;
import com.android.launcher3.views.ClipPathView;
import com.android.launcher3.widget.PendingAddShortcutInfo;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
@@ -132,19 +129,16 @@ public class Folder extends AbstractFloatingView implements ClipPathView, DragSo
*/
private static final int MIN_CONTENT_DIMEN = 5;
- public static final int STATE_CLOSED = 0;
- public static final int STATE_ANIMATING = 1;
- public static final int STATE_OPEN = 2;
-
- @Retention(RetentionPolicy.SOURCE)
- @IntDef({STATE_CLOSED, STATE_ANIMATING, STATE_OPEN})
- public @interface FolderState {}
+ static final int STATE_NONE = -1;
+ static final int STATE_SMALL = 0;
+ static final int STATE_ANIMATING = 1;
+ static final int STATE_OPEN = 2;
/**
* Time for which the scroll hint is shown before automatically changing page.
*/
public static final int SCROLL_HINT_DURATION = 500;
- private static final int RESCROLL_EXTRA_DELAY = 150;
+ public static final int RESCROLL_DELAY = PagedView.PAGE_SNAP_ANIMATION_DURATION + 150;
public static final int SCROLL_NONE = -1;
public static final int SCROLL_LEFT = 0;
@@ -203,12 +197,13 @@ public class Folder extends AbstractFloatingView implements ClipPathView, DragSo
@ViewDebug.ExportedProperty(category = "launcher",
mapping = {
- @ViewDebug.IntToString(from = STATE_CLOSED, to = "STATE_CLOSED"),
+ @ViewDebug.IntToString(from = STATE_NONE, to = "STATE_NONE"),
+ @ViewDebug.IntToString(from = STATE_SMALL, to = "STATE_SMALL"),
@ViewDebug.IntToString(from = STATE_ANIMATING, to = "STATE_ANIMATING"),
@ViewDebug.IntToString(from = STATE_OPEN, to = "STATE_OPEN"),
})
- private int mState = STATE_CLOSED;
- private OnFolderStateChangedListener mOnFolderStateChangedListener;
+ @Thunk
+ int mState = STATE_NONE;
@ViewDebug.ExportedProperty(category = "launcher")
private boolean mRearrangeOnClose = false;
boolean mItemsInvalidated = false;
@@ -561,7 +556,7 @@ public class Folder extends AbstractFloatingView implements ClipPathView, DragSo
a.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
- setState(STATE_ANIMATING);
+ mState = STATE_ANIMATING;
mCurrentAnimator = a;
}
@@ -686,9 +681,8 @@ public class Folder extends AbstractFloatingView implements ClipPathView, DragSo
@Override
public void onAnimationEnd(Animator animation) {
- setState(STATE_OPEN);
+ mState = STATE_OPEN;
announceAccessibilityChanges();
- AccessibilityManagerCompat.sendFolderOpenedEventToTest(getContext());
mContent.setFocusOnFirstChild();
}
@@ -862,7 +856,7 @@ public class Folder extends AbstractFloatingView implements ClipPathView, DragSo
}
mSuppressFolderDeletion = false;
clearDragInfo();
- setState(STATE_CLOSED);
+ mState = STATE_SMALL;
mContent.setCurrentPage(0);
}
@@ -1202,7 +1196,8 @@ public class Folder extends AbstractFloatingView implements ClipPathView, DragSo
}
void replaceFolderWithFinalItem() {
- mDestroyed = mLauncherDelegate.replaceFolderWithFinalItem(this);
+ mLauncherDelegate.replaceFolderWithFinalItem(this);
+ mDestroyed = true;
}
public boolean isDestroyed() {
@@ -1267,8 +1262,7 @@ public class Folder extends AbstractFloatingView implements ClipPathView, DragSo
PendingAddShortcutInfo pasi = d.dragInfo instanceof PendingAddShortcutInfo
? (PendingAddShortcutInfo) d.dragInfo : null;
- WorkspaceItemInfo pasiSi =
- pasi != null ? pasi.activityInfo.createWorkspaceItemInfo() : null;
+ WorkspaceItemInfo pasiSi = pasi != null ? pasi.activityInfo.createWorkspaceItemInfo() : null;
if (pasi != null && pasiSi == null) {
// There is no WorkspaceItemInfo, so we have to go through a configuration activity.
pasi.container = mInfo.id;
@@ -1282,9 +1276,9 @@ public class Folder extends AbstractFloatingView implements ClipPathView, DragSo
final WorkspaceItemInfo si;
if (pasiSi != null) {
si = pasiSi;
- } else if (d.dragInfo instanceof WorkspaceItemFactory) {
+ } else if (d.dragInfo instanceof AppInfo) {
// Came from all apps -- make a copy.
- si = ((WorkspaceItemFactory) d.dragInfo).makeWorkspaceItem(launcher);
+ si = ((AppInfo) d.dragInfo).makeWorkspaceItem();
} else {
// WorkspaceItemInfo
si = (WorkspaceItemInfo) d.dragInfo;
@@ -1522,9 +1516,7 @@ public class Folder extends AbstractFloatingView implements ClipPathView, DragSo
// Pause drag event until the scrolling is finished
mScrollPauseAlarm.setOnAlarmListener(new OnScrollFinishedListener(mDragObject));
- int rescrollDelay = getResources().getInteger(
- R.integer.config_pageSnapAnimationDuration) + RESCROLL_EXTRA_DELAY;
- mScrollPauseAlarm.setAlarm(rescrollDelay);
+ mScrollPauseAlarm.setAlarm(RESCROLL_DELAY);
}
}
@@ -1657,21 +1649,4 @@ public class Folder extends AbstractFloatingView implements ClipPathView, DragSo
return windowBottomPx - folderBottomPx;
}
-
- private void setState(@FolderState int newState) {
- mState = newState;
- if (mOnFolderStateChangedListener != null) {
- mOnFolderStateChangedListener.onFolderStateChanged(mState);
- }
- }
-
- public void setOnFolderStateChangedListener(@Nullable OnFolderStateChangedListener listener) {
- mOnFolderStateChangedListener = listener;
- }
-
- /** Listener that can be registered via {@link Folder#setOnFolderStateChangedListener} */
- public interface OnFolderStateChangedListener {
- /** See {@link Folder.FolderState} */
- void onFolderStateChanged(@FolderState int newState);
- }
}
diff --git a/src/com/android/launcher3/folder/FolderAnimationManager.java b/src/com/android/launcher3/folder/FolderAnimationManager.java
index 61ffd9d00c..cb3884dc47 100644
--- a/src/com/android/launcher3/folder/FolderAnimationManager.java
+++ b/src/com/android/launcher3/folder/FolderAnimationManager.java
@@ -22,6 +22,7 @@ import static com.android.launcher3.BubbleTextView.TEXT_ALPHA_PROPERTY;
import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY;
import static com.android.launcher3.folder.ClippedFolderIconLayoutRule.MAX_NUM_ITEMS_IN_PREVIEW;
import static com.android.launcher3.graphics.IconShape.getShape;
+import static com.android.launcher3.icons.GraphicsUtils.setColorAlphaBound;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
@@ -174,9 +175,15 @@ public class FolderAnimationManager {
final float yDistance = initialY - lp.y;
// Set up the Folder background.
- final int initialColor = Themes.getAttrColor(mContext, R.attr.folderPreviewColor);
- final int finalColor = Themes.getAttrColor(mContext, R.attr.folderBackgroundColor);
-
+ final int finalColor;
+ int folderFillColor = Themes.getAttrColor(mContext, R.attr.folderFillColor);
+ if (mIsOpening) {
+ finalColor = folderFillColor;
+ } else {
+ finalColor = mFolderBackground.getColor().getDefaultColor();
+ }
+ final int initialColor = setColorAlphaBound(
+ folderFillColor, mPreviewBackground.getBackgroundAlpha());
mFolderBackground.mutate();
mFolderBackground.setColor(mIsOpening ? initialColor : finalColor);
@@ -232,9 +239,9 @@ public class FolderAnimationManager {
mFolder, startRect, endRect, finalRadius, !mIsOpening));
// Create reveal animator for the folder content (capture the top 4 icons 2x2)
- int width = mDeviceProfile.folderCellLayoutBorderSpacePx.x
+ int width = mDeviceProfile.folderCellLayoutBorderSpacingPx
+ mDeviceProfile.folderCellWidthPx * 2;
- int height = mDeviceProfile.folderCellLayoutBorderSpacePx.y
+ int height = mDeviceProfile.folderCellLayoutBorderSpacingPx
+ mDeviceProfile.folderCellHeightPx * 2;
int page = mIsOpening ? mContent.getCurrentPage() : mContent.getDestinationPage();
int left = mContent.getPaddingLeft() + page * lp.width;
diff --git a/src/com/android/launcher3/folder/FolderIcon.java b/src/com/android/launcher3/folder/FolderIcon.java
index b1e27019c3..96030f924e 100644
--- a/src/com/android/launcher3/folder/FolderIcon.java
+++ b/src/com/android/launcher3/folder/FolderIcon.java
@@ -55,7 +55,7 @@ import com.android.launcher3.R;
import com.android.launcher3.Reorderable;
import com.android.launcher3.Utilities;
import com.android.launcher3.Workspace;
-import com.android.launcher3.allapps.ActivityAllAppsContainerView;
+import com.android.launcher3.allapps.AllAppsContainerView;
import com.android.launcher3.anim.Interpolators;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.dot.FolderDotInfo;
@@ -68,11 +68,11 @@ import com.android.launcher3.logger.LauncherAtom.FromState;
import com.android.launcher3.logger.LauncherAtom.ToState;
import com.android.launcher3.logging.InstanceId;
import com.android.launcher3.logging.StatsLogManager;
+import com.android.launcher3.model.data.AppInfo;
import com.android.launcher3.model.data.FolderInfo;
import com.android.launcher3.model.data.FolderInfo.FolderListener;
import com.android.launcher3.model.data.FolderInfo.LabelState;
import com.android.launcher3.model.data.ItemInfo;
-import com.android.launcher3.model.data.WorkspaceItemFactory;
import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.launcher3.touch.ItemClickHandler;
import com.android.launcher3.util.Executors;
@@ -132,9 +132,6 @@ public class FolderIcon extends FrameLayout implements FolderListener, IconLabel
private Rect mTouchArea = new Rect();
- private final PointF mTranslationForMoveFromCenterAnimation = new PointF(0, 0);
- private float mTranslationXForTaskbarAlignmentAnimation = 0f;
-
private final PointF mTranslationForReorderBounce = new PointF(0, 0);
private final PointF mTranslationForReorderPreview = new PointF(0, 0);
private float mScaleForReorderBounce = 1f;
@@ -284,7 +281,7 @@ public class FolderIcon extends FrameLayout implements FolderListener, IconLabel
mBackground.animateToAccept(cl, lp.cellX, lp.cellY);
mOpenAlarm.setOnAlarmListener(mOnOpenListener);
if (SPRING_LOADING_ENABLED &&
- ((dragInfo instanceof WorkspaceItemFactory)
+ ((dragInfo instanceof AppInfo)
|| (dragInfo instanceof WorkspaceItemInfo)
|| (dragInfo instanceof PendingAddShortcutInfo))) {
mOpenAlarm.setAlarm(ON_OPEN_DELAY);
@@ -339,10 +336,12 @@ public class FolderIcon extends FrameLayout implements FolderListener, IconLabel
if (animateView != null && mActivity instanceof Launcher) {
final Launcher launcher = (Launcher) mActivity;
DragLayer dragLayer = launcher.getDragLayer();
+ Rect from = new Rect();
+ dragLayer.getViewRectRelativeToSelf(animateView, from);
Rect to = finalRect;
if (to == null) {
to = new Rect();
- Workspace<?> workspace = launcher.getWorkspace();
+ Workspace workspace = launcher.getWorkspace();
// Set cellLayout and this to it's final state to compute final animation locations
workspace.setFinalTransitionTransform();
float scaleX = getScaleX();
@@ -397,21 +396,20 @@ public class FolderIcon extends FrameLayout implements FolderListener, IconLabel
float finalScale = scale * scaleRelativeToDragLayer;
// Account for potentially different icon sizes with non-default grid settings
- if (d.dragSource instanceof ActivityAllAppsContainerView) {
+ if (d.dragSource instanceof AllAppsContainerView) {
DeviceProfile grid = mActivity.getDeviceProfile();
float containerScale = (1f * grid.iconSizePx / grid.allAppsIconSizePx);
finalScale *= containerScale;
}
final int finalIndex = index;
- dragLayer.animateView(animateView, to, finalAlpha,
- finalScale, finalScale, DROP_IN_ANIMATION_DURATION,
- Interpolators.DEACCEL_2,
+ dragLayer.animateView(animateView, from, to, finalAlpha,
+ 1, 1, finalScale, finalScale, DROP_IN_ANIMATION_DURATION,
+ Interpolators.DEACCEL_2, Interpolators.ACCEL_2,
() -> {
mPreviewItemManager.hidePreviewItem(finalIndex, false);
mFolder.showItem(item);
- },
- DragLayer.ANIMATION_END_DISAPPEAR, null);
+ }, DragLayer.ANIMATION_END_DISAPPEAR, null);
mFolder.hideItem(item);
@@ -486,9 +484,9 @@ public class FolderIcon extends FrameLayout implements FolderListener, IconLabel
public void onDrop(DragObject d, boolean itemReturnedOnFailedDrop) {
WorkspaceItemInfo item;
- if (d.dragInfo instanceof WorkspaceItemFactory) {
+ if (d.dragInfo instanceof AppInfo) {
// Came from all apps -- make a copy
- item = ((WorkspaceItemFactory) d.dragInfo).makeWorkspaceItem(getContext());
+ item = ((AppInfo) d.dragInfo).makeWorkspaceItem();
} else if (d.dragSource instanceof BaseItemDragListener){
// Came from a different window -- make a copy
item = new WorkspaceItemInfo((WorkspaceItemInfo) d.dragInfo);
@@ -628,16 +626,13 @@ public class FolderIcon extends FrameLayout implements FolderListener, IconLabel
public void drawDot(Canvas canvas) {
if (!mForceHideDot && ((mDotInfo != null && mDotInfo.hasDot()) || mDotScale > 0)) {
Rect iconBounds = mDotParams.iconBounds;
-
- Utilities.setRectToViewCenter(this, mActivity.getDeviceProfile().iconSizePx,
- iconBounds);
- iconBounds.offsetTo(iconBounds.left, getPaddingTop());
+ BubbleTextView.getIconBounds(this, iconBounds, mActivity.getDeviceProfile().iconSizePx);
float iconScale = (float) mBackground.previewSize / iconBounds.width();
Utilities.scaleRectAboutCenter(iconBounds, iconScale);
// If we are animating to the accepting state, animate the dot out.
mDotParams.scale = Math.max(0, mDotScale - mBackground.getScaleProgress());
- mDotParams.dotColor = mBackground.getDotColor();
+ mDotParams.color = mBackground.getDotColor();
mDotRenderer.draw(canvas, mDotParams);
}
}
@@ -688,7 +683,6 @@ public class FolderIcon extends FrameLayout implements FolderListener, IconLabel
@Override
public void onAdd(WorkspaceItemInfo item, int rank) {
- updatePreviewItems(false);
boolean wasDotted = mDotInfo.hasDot();
mDotInfo.addDotInfo(mActivity.getDotInfoForItem(item));
boolean isDotted = mDotInfo.hasDot();
@@ -700,7 +694,6 @@ public class FolderIcon extends FrameLayout implements FolderListener, IconLabel
@Override
public void onRemove(List<WorkspaceItemInfo> items) {
- updatePreviewItems(false);
boolean wasDotted = mDotInfo.hasDot();
items.stream().map(mActivity::getDotInfoForItem).forEach(mDotInfo::subtractDotInfo);
boolean isDotted = mDotInfo.hasDot();
@@ -771,11 +764,8 @@ public class FolderIcon extends FrameLayout implements FolderListener, IconLabel
}
private void updateTranslation() {
- super.setTranslationX(mTranslationForReorderBounce.x + mTranslationForReorderPreview.x
- + mTranslationForMoveFromCenterAnimation.x
- + mTranslationXForTaskbarAlignmentAnimation);
- super.setTranslationY(mTranslationForReorderBounce.y + mTranslationForReorderPreview.y
- + mTranslationForMoveFromCenterAnimation.y);
+ super.setTranslationX(mTranslationForReorderBounce.x + mTranslationForReorderPreview.x);
+ super.setTranslationY(mTranslationForReorderBounce.y + mTranslationForReorderPreview.y);
}
public void setReorderBounceOffset(float x, float y) {
@@ -787,29 +777,6 @@ public class FolderIcon extends FrameLayout implements FolderListener, IconLabel
offset.set(mTranslationForReorderBounce);
}
- /**
- * Sets translationX value for taskbar to launcher alignment animation
- */
- public void setTranslationForTaskbarAlignmentAnimation(float translationX) {
- mTranslationXForTaskbarAlignmentAnimation = translationX;
- updateTranslation();
- }
-
- /**
- * Returns translation values for taskbar to launcher alignment animation
- */
- public float getTranslationXForTaskbarAlignmentAnimation() {
- return mTranslationXForTaskbarAlignmentAnimation;
- }
-
- /**
- * Sets translation values for move from center animation
- */
- public void setTranslationForMoveFromCenterAnimation(float x, float y) {
- mTranslationForMoveFromCenterAnimation.set(x, y);
- updateTranslation();
- }
-
@Override
public void setReorderPreviewOffset(float x, float y) {
mTranslationForReorderPreview.set(x, y);
diff --git a/src/com/android/launcher3/folder/FolderNameEditText.java b/src/com/android/launcher3/folder/FolderNameEditText.java
index 7c657f053c..6038a053d6 100644
--- a/src/com/android/launcher3/folder/FolderNameEditText.java
+++ b/src/com/android/launcher3/folder/FolderNameEditText.java
@@ -18,7 +18,6 @@ package com.android.launcher3.folder;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
-import android.view.View;
import android.view.inputmethod.CompletionInfo;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputConnection;
@@ -118,16 +117,4 @@ public class FolderNameEditText extends ExtendedEditText {
return super.setComposingText(cs, newCursorPos);
}
}
-
- @Override
- public void reset() {
- super.reset();
- if (isFocused()) {
- View nextFocus = focusSearch(View.FOCUS_DOWN);
- if (nextFocus != null) {
- nextFocus.requestFocus();
- }
- }
- hideKeyboard();
- }
}
diff --git a/src/com/android/launcher3/folder/FolderNameProvider.java b/src/com/android/launcher3/folder/FolderNameProvider.java
index 502164473f..9c1b24d96c 100644
--- a/src/com/android/launcher3/folder/FolderNameProvider.java
+++ b/src/com/android/launcher3/folder/FolderNameProvider.java
@@ -15,8 +15,6 @@
*/
package com.android.launcher3.folder;
-import android.annotation.SuppressLint;
-import android.app.admin.DevicePolicyManager;
import android.content.ComponentName;
import android.content.Context;
import android.os.Process;
@@ -24,15 +22,11 @@ import android.os.UserHandle;
import android.text.TextUtils;
import android.util.Log;
-import androidx.annotation.WorkerThread;
-
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.R;
-import com.android.launcher3.Utilities;
import com.android.launcher3.model.AllAppsList;
import com.android.launcher3.model.BaseModelUpdateTask;
import com.android.launcher3.model.BgDataModel;
-import com.android.launcher3.model.StringCache;
import com.android.launcher3.model.data.AppInfo;
import com.android.launcher3.model.data.FolderInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo;
@@ -100,7 +94,6 @@ public class FolderNameProvider implements ResourceBasedOverride {
/**
* Generate and rank the suggested Folder names.
*/
- @WorkerThread
public void getSuggestedFolderName(Context context,
ArrayList<WorkspaceItemInfo> workspaceItemInfos,
FolderNameInfos nameInfos) {
@@ -108,13 +101,13 @@ public class FolderNameProvider implements ResourceBasedOverride {
if (DEBUG) {
Log.d(TAG, "getSuggestedFolderName:" + nameInfos.toString());
}
-
// If all the icons are from work profile,
// Then, suggest "Work" as the folder name
Set<UserHandle> users = workspaceItemInfos.stream().map(w -> w.user)
.collect(Collectors.toSet());
if (users.size() == 1 && !users.contains(Process.myUserHandle())) {
- setAsLastSuggestion(nameInfos, getWorkFolderName(context));
+ setAsLastSuggestion(nameInfos,
+ context.getResources().getString(R.string.work_folder_name));
}
// If all the icons are from same package (e.g., main icon, shortcut, shortcut)
@@ -128,25 +121,13 @@ public class FolderNameProvider implements ResourceBasedOverride {
if (packageNames.size() == 1) {
Optional<AppInfo> info = getAppInfoByPackageName(packageNames.iterator().next());
// Place it as first viable suggestion and shift everything else
- info.ifPresent(i -> setAsFirstSuggestion(
- nameInfos, i.title == null ? "" : i.title.toString()));
+ info.ifPresent(i -> setAsFirstSuggestion(nameInfos, i.title.toString()));
}
if (DEBUG) {
Log.d(TAG, "getSuggestedFolderName:" + nameInfos.toString());
}
}
- @WorkerThread
- @SuppressLint("NewApi")
- private String getWorkFolderName(Context context) {
- if (!Utilities.ATLEAST_T) {
- return context.getString(R.string.work_folder_name);
- }
- return context.getSystemService(DevicePolicyManager.class).getResources()
- .getString(StringCache.WORK_FOLDER_NAME, () ->
- context.getString(R.string.work_folder_name));
- }
-
private Optional<AppInfo> getAppInfoByPackageName(String packageName) {
if (mAppInfos == null || mAppInfos.isEmpty()) {
return Optional.empty();
diff --git a/src/com/android/launcher3/folder/FolderPagedView.java b/src/com/android/launcher3/folder/FolderPagedView.java
index 3d5aef5f0b..3d2884a24c 100644
--- a/src/com/android/launcher3/folder/FolderPagedView.java
+++ b/src/com/android/launcher3/folder/FolderPagedView.java
@@ -41,12 +41,12 @@ import com.android.launcher3.PagedView;
import com.android.launcher3.R;
import com.android.launcher3.ShortcutAndWidgetContainer;
import com.android.launcher3.Utilities;
+import com.android.launcher3.Workspace.ItemOperator;
import com.android.launcher3.keyboard.ViewGroupFocusHelper;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.launcher3.pageindicators.PageIndicatorDots;
import com.android.launcher3.touch.ItemClickHandler;
-import com.android.launcher3.util.LauncherBindableItemsContainer.ItemOperator;
import com.android.launcher3.util.Thunk;
import com.android.launcher3.util.ViewCache;
import com.android.launcher3.views.ActivityContext;
@@ -252,7 +252,7 @@ public class FolderPagedView extends PagedView<PageIndicatorDots> implements Cli
}
@Override
- protected int getChildGap(int fromIndex, int toIndex) {
+ protected int getChildGap() {
return getPaddingLeft() + getPaddingRight();
}
diff --git a/src/com/android/launcher3/folder/LauncherDelegate.java b/src/com/android/launcher3/folder/LauncherDelegate.java
index 1f0a011b39..f7d8e8c0d1 100644
--- a/src/com/android/launcher3/folder/LauncherDelegate.java
+++ b/src/com/android/launcher3/folder/LauncherDelegate.java
@@ -18,6 +18,8 @@ package com.android.launcher3.folder;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_FOLDER_CONVERTED_TO_ICON;
import android.content.Context;
+import android.graphics.Rect;
+import android.graphics.RectF;
import android.view.MotionEvent;
import android.view.View;
@@ -36,7 +38,10 @@ import com.android.launcher3.model.data.FolderInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.launcher3.views.ActivityContext;
import com.android.launcher3.views.BaseDragLayer;
+import com.android.launcher3.views.BaseDragLayer.LayoutParams;
+import com.android.launcher3.widget.LocalColorExtractor;
+import java.util.Arrays;
import java.util.Optional;
import java.util.function.Consumer;
@@ -46,6 +51,8 @@ import java.util.function.Consumer;
public class LauncherDelegate {
private final Launcher mLauncher;
+ private final Rect mTempRect = new Rect();
+ private final RectF mTempRectF = new RectF();
private LauncherDelegate(Launcher launcher) {
mLauncher = launcher;
@@ -77,7 +84,16 @@ public class LauncherDelegate {
return mLauncher;
}
- boolean replaceFolderWithFinalItem(Folder folder) {
+ void addRectForColorExtraction(BaseDragLayer.LayoutParams lp, LocalColorExtractor target) {
+ mTempRect.set(lp.x, lp.y, lp.x + lp.width, lp.y + lp.height);
+ target.getExtractedRectForViewRect(mLauncher,
+ mLauncher.getWorkspace().getCurrentPage(), mTempRect, mTempRectF);
+ if (!mTempRectF.isEmpty()) {
+ target.addLocation(Arrays.asList(mTempRectF));
+ }
+ }
+
+ void replaceFolderWithFinalItem(Folder folder) {
// Add the last remaining child to the workspace in place of the folder
Runnable onCompleteRunnable = new Runnable() {
@Override
@@ -100,8 +116,7 @@ public class LauncherDelegate {
}
// Remove the folder
- mLauncher.removeItem(folder.mFolderIcon, info, true /* deleteFromDb */,
- "folder removed because there's only 1 item in it");
+ mLauncher.removeItem(folder.mFolderIcon, info, true /* deleteFromDb */);
if (folder.mFolderIcon instanceof DropTarget) {
folder.mDragController.removeDropTarget((DropTarget) folder.mFolderIcon);
}
@@ -132,7 +147,6 @@ public class LauncherDelegate {
} else {
onCompleteRunnable.run();
}
- return true;
}
@@ -177,7 +191,7 @@ public class LauncherDelegate {
ModelWriter getModelWriter() {
if (mWriter == null) {
mWriter = LauncherAppState.getInstance((Context) mContext).getModel()
- .getWriter(false, false, null);
+ .getWriter(false, false);
}
return mWriter;
}
@@ -191,15 +205,16 @@ public class LauncherDelegate {
}
@Override
- boolean replaceFolderWithFinalItem(Folder folder) {
- return false;
- }
+ void replaceFolderWithFinalItem(Folder folder) { }
@Override
boolean interceptOutsideTouch(MotionEvent ev, BaseDragLayer dl, Folder folder) {
folder.close(true);
return true;
}
+
+ @Override
+ void addRectForColorExtraction(LayoutParams lp, LocalColorExtractor target) { }
}
static LauncherDelegate from(ActivityContext context) {
diff --git a/src/com/android/launcher3/folder/PreviewBackground.java b/src/com/android/launcher3/folder/PreviewBackground.java
index 8f9fa8a575..18d0b10528 100644
--- a/src/com/android/launcher3/folder/PreviewBackground.java
+++ b/src/com/android/launcher3/folder/PreviewBackground.java
@@ -66,6 +66,7 @@ public class PreviewBackground extends CellLayout.DelegatedCellDrawing {
private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
float mScale = 1f;
+ private float mColorMultiplier = 1f;
private int mBgColor;
private int mStrokeColor;
private int mDotColor;
@@ -86,6 +87,7 @@ public class PreviewBackground extends CellLayout.DelegatedCellDrawing {
// Drawing / animation configurations
private static final float ACCEPT_SCALE_FACTOR = 1.20f;
+ private static final float ACCEPT_COLOR_MULTIPLIER = 1.5f;
// Expressed on a scale from 0 to 255.
private static final int BG_OPACITY = 255;
@@ -152,7 +154,7 @@ public class PreviewBackground extends CellLayout.DelegatedCellDrawing {
TypedArray ta = context.getTheme().obtainStyledAttributes(R.styleable.FolderIconPreview);
mDotColor = ta.getColor(R.styleable.FolderIconPreview_folderDotColor, 0);
mStrokeColor = ta.getColor(R.styleable.FolderIconPreview_folderIconBorderColor, 0);
- mBgColor = ta.getColor(R.styleable.FolderIconPreview_folderPreviewColor, 0);
+ mBgColor = ta.getColor(R.styleable.FolderIconPreview_folderFillColor, 0);
ta.recycle();
DeviceProfile grid = activity.getDeviceProfile();
@@ -225,7 +227,8 @@ public class PreviewBackground extends CellLayout.DelegatedCellDrawing {
}
public int getBgColor() {
- return mBgColor;
+ int alpha = (int) Math.min(MAX_BG_OPACITY, BG_OPACITY * mColorMultiplier);
+ return setColorAlphaBound(mBgColor, alpha);
}
public int getDotColor() {
@@ -381,10 +384,14 @@ public class PreviewBackground extends CellLayout.DelegatedCellDrawing {
return mDrawingDelegate != null;
}
- private void animateScale(float finalScale, final Runnable onStart, final Runnable onEnd) {
+ private void animateScale(float finalScale, float finalMultiplier,
+ final Runnable onStart, final Runnable onEnd) {
final float scale0 = mScale;
final float scale1 = finalScale;
+ final float bgMultiplier0 = mColorMultiplier;
+ final float bgMultiplier1 = finalMultiplier;
+
if (mScaleAnimator != null) {
mScaleAnimator.cancel();
}
@@ -396,6 +403,7 @@ public class PreviewBackground extends CellLayout.DelegatedCellDrawing {
public void onAnimationUpdate(ValueAnimator animation) {
float prog = animation.getAnimatedFraction();
mScale = prog * scale1 + (1 - prog) * scale0;
+ mColorMultiplier = prog * bgMultiplier1 + (1 - prog) * bgMultiplier0;
invalidate();
}
});
@@ -421,7 +429,8 @@ public class PreviewBackground extends CellLayout.DelegatedCellDrawing {
}
public void animateToAccept(CellLayout cl, int cellX, int cellY) {
- animateScale(ACCEPT_SCALE_FACTOR, () -> delegateDrawing(cl, cellX, cellY), null);
+ animateScale(ACCEPT_SCALE_FACTOR, ACCEPT_COLOR_MULTIPLIER,
+ () -> delegateDrawing(cl, cellX, cellY), null);
}
public void animateToRest() {
@@ -431,7 +440,11 @@ public class PreviewBackground extends CellLayout.DelegatedCellDrawing {
CellLayout cl = mDrawingDelegate;
int cellX = mDelegateCellX;
int cellY = mDelegateCellY;
- animateScale(1f, () -> delegateDrawing(cl, cellX, cellY), this::clearDrawingDelegate);
+ animateScale(1f, 1f, () -> delegateDrawing(cl, cellX, cellY), this::clearDrawingDelegate);
+ }
+
+ public int getBackgroundAlpha() {
+ return (int) Math.min(MAX_BG_OPACITY, BG_OPACITY * mColorMultiplier);
}
public float getStrokeWidth() {
diff --git a/src/com/android/launcher3/folder/PreviewItemManager.java b/src/com/android/launcher3/folder/PreviewItemManager.java
index 6355b62e27..8bef6ad7ff 100644
--- a/src/com/android/launcher3/folder/PreviewItemManager.java
+++ b/src/com/android/launcher3/folder/PreviewItemManager.java
@@ -21,7 +21,6 @@ import static com.android.launcher3.folder.ClippedFolderIconLayoutRule.EXIT_INDE
import static com.android.launcher3.folder.ClippedFolderIconLayoutRule.MAX_NUM_ITEMS_IN_PREVIEW;
import static com.android.launcher3.folder.FolderIcon.DROP_IN_ANIMATION_DURATION;
import static com.android.launcher3.graphics.PreloadIconDrawable.newPendingIcon;
-import static com.android.launcher3.icons.BitmapInfo.FLAG_THEMED;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
@@ -430,7 +429,7 @@ public class PreviewItemManager {
drawable.setLevel(item.getProgressLevel());
p.drawable = drawable;
} else {
- p.drawable = item.newIcon(mContext, FLAG_THEMED);
+ p.drawable = item.newIcon(mContext, true);
}
p.drawable.setBounds(0, 0, mIconSize, mIconSize);
p.item = item;
diff --git a/src/com/android/launcher3/graphics/DragPreviewProvider.java b/src/com/android/launcher3/graphics/DragPreviewProvider.java
index f027b33f22..a549750dae 100644
--- a/src/com/android/launcher3/graphics/DragPreviewProvider.java
+++ b/src/com/android/launcher3/graphics/DragPreviewProvider.java
@@ -32,13 +32,13 @@ import android.view.View;
import androidx.annotation.Nullable;
import com.android.launcher3.BubbleTextView;
+import com.android.launcher3.Launcher;
import com.android.launcher3.R;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.dragndrop.DraggableView;
import com.android.launcher3.icons.BitmapRenderer;
import com.android.launcher3.icons.FastBitmapDrawable;
import com.android.launcher3.util.SafeCloseable;
-import com.android.launcher3.views.ActivityContext;
import com.android.launcher3.widget.LauncherAppWidgetHostView;
import java.nio.ByteBuffer;
@@ -150,7 +150,7 @@ public class DragPreviewProvider {
}
public float getScaleAndPosition(Drawable preview, int[] outPos) {
- float scale = ActivityContext.lookupContext(mView.getContext())
+ float scale = Launcher.getLauncher(mView.getContext())
.getDragLayer().getLocationInDragLayer(mView, outPos);
if (mView instanceof LauncherAppWidgetHostView) {
// App widgets are technically scaled, but are drawn at their expected size -- so the
@@ -167,7 +167,7 @@ public class DragPreviewProvider {
/** Returns the scale and position of a given view for drag-n-drop. */
public float getScaleAndPosition(View view, int[] outPos) {
- float scale = ActivityContext.lookupContext(mView.getContext())
+ float scale = Launcher.getLauncher(mView.getContext())
.getDragLayer().getLocationInDragLayer(mView, outPos);
if (mView instanceof LauncherAppWidgetHostView) {
// App widgets are technically scaled, but are drawn at their expected size -- so the
@@ -201,7 +201,7 @@ public class DragPreviewProvider {
public void run() {
Bitmap preview = convertPreviewToAlphaBitmap(mPreviewSnapshot);
if (mIsIcon) {
- int size = ActivityContext.lookupContext(mContext).getDeviceProfile().iconSizePx;
+ int size = Launcher.getLauncher(mContext).getDeviceProfile().iconSizePx;
preview = Bitmap.createScaledBitmap(preview, size, size, false);
}
//else case covers AppWidgetHost (doesn't drag/drop across different device profiles)
diff --git a/src/com/android/launcher3/graphics/GridCustomizationsProvider.java b/src/com/android/launcher3/graphics/GridCustomizationsProvider.java
index fc8d855801..e4f5539dbd 100644
--- a/src/com/android/launcher3/graphics/GridCustomizationsProvider.java
+++ b/src/com/android/launcher3/graphics/GridCustomizationsProvider.java
@@ -9,6 +9,7 @@ import android.annotation.TargetApi;
import android.content.ContentProvider;
import android.content.ContentValues;
import android.content.pm.PackageManager;
+import android.content.res.XmlResourceParser;
import android.database.Cursor;
import android.database.MatrixCursor;
import android.net.Uri;
@@ -22,13 +23,23 @@ import android.os.Message;
import android.os.Messenger;
import android.util.ArrayMap;
import android.util.Log;
+import android.util.Xml;
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.InvariantDeviceProfile.GridOption;
+import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.util.Executors;
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
/**
* Exposes various launcher grid options and allows the caller to change them.
* APIs:
@@ -83,7 +94,7 @@ public class GridCustomizationsProvider extends ContentProvider {
MatrixCursor cursor = new MatrixCursor(new String[] {
KEY_NAME, KEY_ROWS, KEY_COLS, KEY_PREVIEW_COUNT, KEY_IS_DEFAULT});
InvariantDeviceProfile idp = InvariantDeviceProfile.INSTANCE.get(getContext());
- for (GridOption gridOption : idp.parseAllGridOptions(getContext())) {
+ for (GridOption gridOption : parseAllGridOptions()) {
cursor.newRow()
.add(KEY_NAME, gridOption.name)
.add(KEY_ROWS, gridOption.numRows)
@@ -105,6 +116,25 @@ public class GridCustomizationsProvider extends ContentProvider {
}
}
+ private List<GridOption> parseAllGridOptions() {
+ List<GridOption> result = new ArrayList<>();
+ try (XmlResourceParser parser = getContext().getResources().getXml(R.xml.device_profiles)) {
+ final int depth = parser.getDepth();
+ int type;
+ while (((type = parser.next()) != XmlPullParser.END_TAG ||
+ parser.getDepth() > depth) && type != XmlPullParser.END_DOCUMENT) {
+ if ((type == XmlPullParser.START_TAG)
+ && GridOption.TAG_NAME.equals(parser.getName())) {
+ result.add(new GridOption(getContext(), Xml.asAttributeSet(parser)));
+ }
+ }
+ } catch (IOException | XmlPullParserException e) {
+ Log.e(TAG, "Error parsing device profile", e);
+ return Collections.emptyList();
+ }
+ return result;
+ }
+
@Override
public String getType(Uri uri) {
return "vnd.android.cursor.dir/launcher_grid";
@@ -125,10 +155,9 @@ public class GridCustomizationsProvider extends ContentProvider {
switch (uri.getPath()) {
case KEY_DEFAULT_GRID: {
String gridName = values.getAsString(KEY_NAME);
- InvariantDeviceProfile idp = InvariantDeviceProfile.INSTANCE.get(getContext());
// Verify that this is a valid grid option
GridOption match = null;
- for (GridOption option : idp.parseAllGridOptions(getContext())) {
+ for (GridOption option : parseAllGridOptions()) {
if (option.name.equals(gridName)) {
match = option;
break;
@@ -138,7 +167,8 @@ public class GridCustomizationsProvider extends ContentProvider {
return 0;
}
- idp.setCurrentGrid(getContext(), gridName);
+ InvariantDeviceProfile.INSTANCE.get(getContext())
+ .setCurrentGrid(getContext(), gridName);
return 1;
}
case ICON_THEMED:
diff --git a/src/com/android/launcher3/graphics/IconPalette.java b/src/com/android/launcher3/graphics/IconPalette.java
index 778b32a863..3d4a1001a2 100644
--- a/src/com/android/launcher3/graphics/IconPalette.java
+++ b/src/com/android/launcher3/graphics/IconPalette.java
@@ -16,16 +16,18 @@
package com.android.launcher3.graphics;
+import static com.android.launcher3.icons.GraphicsUtils.setColorAlphaBound;
+
import android.app.Notification;
import android.content.Context;
import android.graphics.Color;
import android.util.Log;
-import androidx.core.graphics.ColorUtils;
-
import com.android.launcher3.R;
import com.android.launcher3.util.Themes;
+import androidx.core.graphics.ColorUtils;
+
/**
* Contains colors based on the dominant color of an icon.
*/
@@ -145,4 +147,9 @@ public class IconPalette {
}
return ColorUtils.LABToColor(low, a, b);
}
+
+ public static int getMutedColor(int color, float whiteScrimAlpha) {
+ int whiteScrim = setColorAlphaBound(Color.WHITE, (int) (255 * whiteScrimAlpha));
+ return ColorUtils.compositeColors(whiteScrim, color);
+ }
}
diff --git a/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java b/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java
index d5bcb0cbcb..7a31ea01b5 100644
--- a/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java
+++ b/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java
@@ -23,12 +23,12 @@ import static android.view.View.VISIBLE;
import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_HOTSEAT_PREDICTION;
import static com.android.launcher3.model.ModelUtils.filterCurrentWorkspaceItems;
import static com.android.launcher3.model.ModelUtils.getMissingHotseatRanks;
+import static com.android.launcher3.model.ModelUtils.sortWorkspaceItemsSpatially;
import android.annotation.TargetApi;
import android.app.Fragment;
import android.app.WallpaperColors;
import android.app.WallpaperManager;
-import android.appwidget.AppWidgetHost;
import android.appwidget.AppWidgetHostView;
import android.appwidget.AppWidgetProviderInfo;
import android.content.Context;
@@ -42,6 +42,7 @@ import android.graphics.drawable.ColorDrawable;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
+import android.os.Process;
import android.util.AttributeSet;
import android.util.SparseIntArray;
import android.view.ContextThemeWrapper;
@@ -63,7 +64,6 @@ import com.android.launcher3.LauncherAppState;
import com.android.launcher3.LauncherSettings.Favorites;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
-import com.android.launcher3.Workspace;
import com.android.launcher3.WorkspaceLayoutManager;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.folder.FolderIcon;
@@ -83,25 +83,22 @@ import com.android.launcher3.pm.UserCache;
import com.android.launcher3.uioverrides.PredictedAppIconInflater;
import com.android.launcher3.uioverrides.plugins.PluginManagerWrapper;
import com.android.launcher3.util.ComponentKey;
-import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.IntArray;
-import com.android.launcher3.util.IntSet;
-import com.android.launcher3.util.MainThreadInitializedObject.SandboxContext;
-import com.android.launcher3.util.window.WindowManagerProxy;
+import com.android.launcher3.util.MainThreadInitializedObject;
import com.android.launcher3.views.ActivityContext;
import com.android.launcher3.views.BaseDragLayer;
-import com.android.launcher3.widget.BaseLauncherAppWidgetHostView;
-import com.android.launcher3.widget.LauncherAppWidgetHost;
import com.android.launcher3.widget.LauncherAppWidgetProviderInfo;
import com.android.launcher3.widget.LocalColorExtractor;
-import com.android.launcher3.widget.NavigableAppWidgetHostView;
import com.android.launcher3.widget.custom.CustomWidgetManager;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import java.util.concurrent.ConcurrentLinkedQueue;
/**
@@ -112,7 +109,7 @@ import java.util.concurrent.ConcurrentLinkedQueue;
* 3) Place appropriate elements like icons and first-page qsb
* 4) Measure and draw the view on a canvas
*/
-@TargetApi(Build.VERSION_CODES.R)
+@TargetApi(Build.VERSION_CODES.O)
public class LauncherPreviewRenderer extends ContextWrapper
implements ActivityContext, WorkspaceLayoutManager, LayoutInflater.Factory2 {
@@ -120,40 +117,74 @@ public class LauncherPreviewRenderer extends ContextWrapper
* Context used just for preview. It also provides a few objects (e.g. UserCache) just for
* preview purposes.
*/
- public static class PreviewContext extends SandboxContext {
+ public static class PreviewContext extends ContextWrapper {
+
+ private final Set<MainThreadInitializedObject> mAllowedObjects = new HashSet<>(
+ Arrays.asList(UserCache.INSTANCE, InstallSessionHelper.INSTANCE,
+ LauncherAppState.INSTANCE, InvariantDeviceProfile.INSTANCE,
+ CustomWidgetManager.INSTANCE, PluginManagerWrapper.INSTANCE));
private final InvariantDeviceProfile mIdp;
+ private final Map<MainThreadInitializedObject, Object> mObjectMap = new HashMap<>();
private final ConcurrentLinkedQueue<LauncherIconsForPreview> mIconPool =
new ConcurrentLinkedQueue<>();
+ private boolean mDestroyed = false;
+
public PreviewContext(Context base, InvariantDeviceProfile idp) {
- super(base, UserCache.INSTANCE, InstallSessionHelper.INSTANCE,
- LauncherAppState.INSTANCE, InvariantDeviceProfile.INSTANCE,
- CustomWidgetManager.INSTANCE, PluginManagerWrapper.INSTANCE,
- WindowManagerProxy.INSTANCE, DisplayController.INSTANCE);
+ super(base);
mIdp = idp;
mObjectMap.put(InvariantDeviceProfile.INSTANCE, idp);
mObjectMap.put(LauncherAppState.INSTANCE,
new LauncherAppState(this, null /* iconCacheFileName */));
+
+ }
+
+ @Override
+ public Context getApplicationContext() {
+ return this;
+ }
+
+ public void onDestroy() {
+ CustomWidgetManager.INSTANCE.get(this).onDestroy();
+ LauncherAppState.INSTANCE.get(this).onTerminate();
+ mDestroyed = true;
}
/**
- * Creates a new LauncherIcons for the preview, skipping the global pool
+ * Find a cached object from mObjectMap if we have already created one. If not, generate
+ * an object using the provider.
*/
- public LauncherIcons newLauncherIcons(Context context) {
+ public <T> T getObject(MainThreadInitializedObject<T> mainThreadInitializedObject,
+ MainThreadInitializedObject.ObjectProvider<T> provider) {
+ if (FeatureFlags.IS_STUDIO_BUILD && mDestroyed) {
+ throw new RuntimeException("Context already destroyed");
+ }
+ if (!mAllowedObjects.contains(mainThreadInitializedObject)) {
+ throw new IllegalStateException("Leaking unknown objects");
+ }
+ if (mObjectMap.containsKey(mainThreadInitializedObject)) {
+ return (T) mObjectMap.get(mainThreadInitializedObject);
+ }
+ T t = provider.get(this);
+ mObjectMap.put(mainThreadInitializedObject, t);
+ return t;
+ }
+
+ public LauncherIcons newLauncherIcons(Context context, boolean shapeDetection) {
LauncherIconsForPreview launcherIconsForPreview = mIconPool.poll();
if (launcherIconsForPreview != null) {
return launcherIconsForPreview;
}
return new LauncherIconsForPreview(context, mIdp.fillResIconDpi, mIdp.iconBitmapSize,
- -1 /* poolId */);
+ -1 /* poolId */, shapeDetection);
}
private final class LauncherIconsForPreview extends LauncherIcons {
private LauncherIconsForPreview(Context context, int fillResIconDpi, int iconBitmapSize,
- int poolId) {
- super(context, fillResIconDpi, iconBitmapSize, poolId);
+ int poolId, boolean shapeDetection) {
+ super(context, fillResIconDpi, iconBitmapSize, poolId, shapeDetection);
}
@Override
@@ -174,8 +205,7 @@ public class LauncherPreviewRenderer extends ContextWrapper
private final LayoutInflater mHomeElementInflater;
private final InsettableFrameLayout mRootView;
private final Hotseat mHotseat;
- private final Map<Integer, CellLayout> mWorkspaceScreens = new HashMap<>();
- private final AppWidgetHost mAppWidgetHost;
+ private final CellLayout mWorkspace;
private final SparseIntArray mWallpaperColorResources;
public LauncherPreviewRenderer(Context context,
@@ -188,21 +218,27 @@ public class LauncherPreviewRenderer extends ContextWrapper
mIdp = idp;
mDp = idp.getDeviceProfile(context).copy(context);
- WindowInsets currentWindowInsets = context.getSystemService(WindowManager.class)
- .getCurrentWindowMetrics().getWindowInsets();
- mInsets = new Rect(
- currentWindowInsets.getSystemWindowInsetLeft(),
- currentWindowInsets.getSystemWindowInsetTop(),
- currentWindowInsets.getSystemWindowInsetRight(),
- mDp.isTaskbarPresent ? 0 : currentWindowInsets.getSystemWindowInsetBottom());
+ if (Utilities.ATLEAST_R) {
+ WindowInsets currentWindowInsets = context.getSystemService(WindowManager.class)
+ .getCurrentWindowMetrics().getWindowInsets();
+ mInsets = new Rect(
+ currentWindowInsets.getSystemWindowInsetLeft(),
+ currentWindowInsets.getSystemWindowInsetTop(),
+ currentWindowInsets.getSystemWindowInsetRight(),
+ currentWindowInsets.getSystemWindowInsetBottom());
+ } else {
+ mInsets = new Rect();
+ mInsets.left = mInsets.right = (mDp.widthPx - mDp.availableWidthPx) / 2;
+ mInsets.top = mInsets.bottom = (mDp.heightPx - mDp.availableHeightPx) / 2;
+ }
mDp.updateInsets(mInsets);
BaseIconFactory iconFactory =
new BaseIconFactory(context, mIdp.fillResIconDpi, mIdp.iconBitmapSize) { };
- BitmapInfo iconInfo = iconFactory.createBadgedIconBitmap(
- new AdaptiveIconDrawable(
- new ColorDrawable(Color.WHITE),
- new ColorDrawable(Color.WHITE)));
+ BitmapInfo iconInfo = iconFactory.createBadgedIconBitmap(new AdaptiveIconDrawable(
+ new ColorDrawable(Color.WHITE), new ColorDrawable(Color.WHITE)),
+ Process.myUserHandle(),
+ Build.VERSION.SDK_INT);
mWorkspaceItemInfo = new WorkspaceItemInfo();
mWorkspaceItemInfo.bitmap = iconInfo;
@@ -214,35 +250,19 @@ public class LauncherPreviewRenderer extends ContextWrapper
new ContextThemeWrapper(this, R.style.HomeScreenElementTheme));
mHomeElementInflater.setFactory2(this);
- int layoutRes = mDp.isTwoPanels ? R.layout.launcher_preview_two_panel_layout
- : R.layout.launcher_preview_layout;
mRootView = (InsettableFrameLayout) mHomeElementInflater.inflate(
- layoutRes, null, false);
+ R.layout.launcher_preview_layout, null, false);
mRootView.setInsets(mInsets);
measureView(mRootView, mDp.widthPx, mDp.heightPx);
mHotseat = mRootView.findViewById(R.id.hotseat);
mHotseat.resetLayout(false);
- CellLayout firstScreen = mRootView.findViewById(R.id.workspace);
- firstScreen.setPadding(mDp.workspacePadding.left + mDp.cellLayoutPaddingPx.left,
- mDp.workspacePadding.top + mDp.cellLayoutPaddingPx.top,
- (mDp.isTwoPanels ? mDp.cellLayoutBorderSpacePx.x / 2
- : mDp.workspacePadding.right) + mDp.cellLayoutPaddingPx.right,
- mDp.workspacePadding.bottom + mDp.cellLayoutPaddingPx.bottom
- );
- mWorkspaceScreens.put(FIRST_SCREEN_ID, firstScreen);
-
- if (mDp.isTwoPanels) {
- CellLayout rightPanel = mRootView.findViewById(R.id.workspace_right);
- rightPanel.setPadding(
- mDp.cellLayoutBorderSpacePx.x / 2 + mDp.cellLayoutPaddingPx.left,
- mDp.workspacePadding.top + mDp.cellLayoutPaddingPx.top,
- mDp.workspacePadding.right + mDp.cellLayoutPaddingPx.right,
- mDp.workspacePadding.bottom + mDp.cellLayoutPaddingPx.bottom
- );
- mWorkspaceScreens.put(Workspace.SECOND_SCREEN_ID, rightPanel);
- }
+ mWorkspace = mRootView.findViewById(R.id.workspace);
+ mWorkspace.setPadding(mDp.workspacePadding.left + mDp.cellLayoutPaddingLeftRightPx,
+ mDp.workspacePadding.top,
+ mDp.workspacePadding.right + mDp.cellLayoutPaddingLeftRightPx,
+ mDp.workspacePadding.bottom);
if (Utilities.ATLEAST_S) {
WallpaperColors wallpaperColors = wallpaperColorsOverride != null
@@ -253,9 +273,6 @@ public class LauncherPreviewRenderer extends ContextWrapper
} else {
mWallpaperColorResources = null;
}
- mAppWidgetHost = FeatureFlags.WIDGETS_IN_LAUNCHER_PREVIEW.get()
- ? new LauncherPreviewAppWidgetHost(context)
- : null;
}
/** Populate preview and render it. */
@@ -313,22 +330,18 @@ public class LauncherPreviewRenderer extends ContextWrapper
@Override
public CellLayout getScreenWithId(int screenId) {
- return mWorkspaceScreens.get(screenId);
+ return mWorkspace;
}
private void inflateAndAddIcon(WorkspaceItemInfo info) {
- CellLayout screen = mWorkspaceScreens.get(info.screenId);
BubbleTextView icon = (BubbleTextView) mHomeElementInflater.inflate(
- R.layout.app_icon, screen, false);
+ R.layout.app_icon, mWorkspace, false);
icon.applyFromWorkspaceItem(info);
addInScreenFromBind(icon, info);
}
private void inflateAndAddFolder(FolderInfo info) {
- CellLayout screen = info.container == Favorites.CONTAINER_DESKTOP
- ? mWorkspaceScreens.get(info.screenId)
- : mHotseat;
- FolderIcon folderIcon = FolderIcon.inflateIcon(R.layout.folder_icon, this, screen,
+ FolderIcon folderIcon = FolderIcon.inflateIcon(R.layout.folder_icon, this, mWorkspace,
info);
addInScreenFromBind(folderIcon, info);
}
@@ -350,7 +363,7 @@ public class LauncherPreviewRenderer extends ContextWrapper
private void inflateAndAddWidgets(LauncherAppWidgetInfo info, WidgetsModel widgetsModel) {
WidgetItem widgetItem = widgetsModel.getWidgetProviderInfoByProviderName(
- info.providerName, info.user);
+ info.providerName);
if (widgetItem == null) {
return;
}
@@ -359,31 +372,20 @@ public class LauncherPreviewRenderer extends ContextWrapper
private void inflateAndAddWidgets(
LauncherAppWidgetInfo info, LauncherAppWidgetProviderInfo providerInfo) {
- AppWidgetHostView view;
- if (FeatureFlags.WIDGETS_IN_LAUNCHER_PREVIEW.get()) {
- view = mAppWidgetHost.createView(mContext, info.appWidgetId, providerInfo);
- } else {
- view = new NavigableAppWidgetHostView(this) {
- @Override
- protected boolean shouldAllowDirectClick() {
- return false;
- }
- };
- view.setAppWidget(-1, providerInfo);
- view.updateAppWidget(null);
- }
+ AppWidgetHostView view = new AppWidgetHostView(mContext);
+ view.setAppWidget(-1, providerInfo);
+ view.updateAppWidget(null);
+ view.setTag(info);
if (mWallpaperColorResources != null) {
view.setColorResources(mWallpaperColorResources);
}
- view.setTag(info);
addInScreenFromBind(view, info);
}
private void inflateAndAddPredictedIcon(WorkspaceItemInfo info) {
- CellLayout screen = mWorkspaceScreens.get(info.screenId);
- View view = PredictedAppIconInflater.inflate(mHomeElementInflater, screen, info);
+ View view = PredictedAppIconInflater.inflate(mHomeElementInflater, mWorkspace, info);
if (view != null) {
addInScreenFromBind(view, info);
}
@@ -414,12 +416,12 @@ public class LauncherPreviewRenderer extends ContextWrapper
ArrayList<ItemInfo> otherWorkspaceItems = new ArrayList<>();
ArrayList<LauncherAppWidgetInfo> currentAppWidgets = new ArrayList<>();
ArrayList<LauncherAppWidgetInfo> otherAppWidgets = new ArrayList<>();
-
- IntSet currentScreenIds = IntSet.wrap(mWorkspaceScreens.keySet());
- filterCurrentWorkspaceItems(currentScreenIds, dataModel.workspaceItems,
- currentWorkspaceItems, otherWorkspaceItems);
- filterCurrentWorkspaceItems(currentScreenIds, dataModel.appWidgets, currentAppWidgets,
- otherAppWidgets);
+ filterCurrentWorkspaceItems(0 /* currentScreenId */,
+ dataModel.workspaceItems, currentWorkspaceItems,
+ otherWorkspaceItems);
+ filterCurrentWorkspaceItems(0 /* currentScreenId */, dataModel.appWidgets,
+ currentAppWidgets, otherAppWidgets);
+ sortWorkspaceItemsSpatially(mIdp, currentWorkspaceItems);
for (ItemInfo itemInfo : currentWorkspaceItems) {
switch (itemInfo.itemType) {
case Favorites.ITEM_TYPE_APPLICATION:
@@ -452,10 +454,10 @@ public class LauncherPreviewRenderer extends ContextWrapper
}
IntArray ranks = getMissingHotseatRanks(currentWorkspaceItems,
mDp.numShownHotseatIcons);
- FixedContainerItems hotseatPredictions =
+ FixedContainerItems hotseatpredictions =
dataModel.extraItems.get(CONTAINER_HOTSEAT_PREDICTION);
- List<ItemInfo> predictions = hotseatPredictions == null
- ? Collections.emptyList() : hotseatPredictions.items;
+ List<ItemInfo> predictions = hotseatpredictions == null
+ ? Collections.emptyList() : hotseatpredictions.items;
int count = Math.min(ranks.size(), predictions.size());
for (int i = 0; i < count; i++) {
int rank = ranks.get(i);
@@ -471,13 +473,12 @@ public class LauncherPreviewRenderer extends ContextWrapper
// Add first page QSB
if (FeatureFlags.QSB_ON_FIRST_SCREEN) {
- CellLayout firstScreen = mWorkspaceScreens.get(FIRST_SCREEN_ID);
- View qsb = mHomeElementInflater.inflate(R.layout.qsb_preview, firstScreen,
- false);
+ View qsb = mHomeElementInflater.inflate(
+ R.layout.search_container_workspace, mWorkspace, false);
CellLayout.LayoutParams lp =
- new CellLayout.LayoutParams(0, 0, firstScreen.getCountX(), 1);
+ new CellLayout.LayoutParams(0, 0, mWorkspace.getCountX(), 1);
lp.canReorder = false;
- firstScreen.addViewToCellLayout(qsb, 0, R.id.search_container_workspace, lp, true);
+ mWorkspace.addViewToCellLayout(qsb, 0, R.id.search_container_workspace, lp, true);
}
measureView(mRootView, mDp.widthPx, mDp.heightPx);
@@ -492,32 +493,6 @@ public class LauncherPreviewRenderer extends ContextWrapper
view.layout(0, 0, width, height);
}
- private class LauncherPreviewAppWidgetHost extends AppWidgetHost {
-
- private LauncherPreviewAppWidgetHost(Context context) {
- super(context, LauncherAppWidgetHost.APPWIDGET_HOST_ID);
- }
-
- @Override
- protected AppWidgetHostView onCreateView(
- Context context,
- int appWidgetId,
- AppWidgetProviderInfo appWidget) {
- return new LauncherPreviewAppWidgetHostView(LauncherPreviewRenderer.this);
- }
- }
-
- private static class LauncherPreviewAppWidgetHostView extends BaseLauncherAppWidgetHostView {
- private LauncherPreviewAppWidgetHostView(Context context) {
- super(context);
- }
-
- @Override
- protected boolean shouldAllowDirectClick() {
- return false;
- }
- }
-
/** Root layout for launcher preview that intercepts all touch events. */
public static class LauncherPreviewLayout extends InsettableFrameLayout {
public LauncherPreviewLayout(Context context, AttributeSet attrs) {
diff --git a/src/com/android/launcher3/graphics/PreloadIconDrawable.java b/src/com/android/launcher3/graphics/PreloadIconDrawable.java
index d2e4c511f9..e45b8f7918 100644
--- a/src/com/android/launcher3/graphics/PreloadIconDrawable.java
+++ b/src/com/android/launcher3/graphics/PreloadIconDrawable.java
@@ -142,7 +142,7 @@ public class PreloadIconDrawable extends FastBitmapDrawable {
mSystemBackgroundColor = preloadColors[PRELOAD_BACKGROUND_COLOR_INDEX];
mIsDarkMode = isDarkMode;
- setLevel(info.getProgressLevel());
+ setInternalProgress(info.getProgressLevel());
setIsStartable(info.isAppStartable());
}
@@ -345,10 +345,11 @@ public class PreloadIconDrawable extends FastBitmapDrawable {
}
@Override
- public FastBitmapConstantState newConstantState() {
+ public ConstantState getConstantState() {
return new PreloadIconConstantState(
mBitmap,
mIconColor,
+ !mItem.isAppStartable(),
mItem,
mIndicatorColor,
new int[] {mSystemAccentColor, mSystemBackgroundColor},
@@ -366,11 +367,12 @@ public class PreloadIconDrawable extends FastBitmapDrawable {
public PreloadIconConstantState(
Bitmap bitmap,
int iconColor,
+ boolean isDisabled,
ItemInfoWithIcon info,
int indicatorColor,
int[] preloadColors,
boolean isDarkMode) {
- super(bitmap, iconColor);
+ super(bitmap, iconColor, isDisabled);
mInfo = info;
mIndicatorColor = indicatorColor;
mPreloadColors = preloadColors;
@@ -379,12 +381,17 @@ public class PreloadIconDrawable extends FastBitmapDrawable {
}
@Override
- public PreloadIconDrawable createDrawable() {
+ public PreloadIconDrawable newDrawable() {
return new PreloadIconDrawable(
mInfo,
mIndicatorColor,
mPreloadColors,
mIsDarkMode);
}
+
+ @Override
+ public int getChangingConfigurations() {
+ return 0;
+ }
}
}
diff --git a/src/com/android/launcher3/graphics/PreviewSurfaceRenderer.java b/src/com/android/launcher3/graphics/PreviewSurfaceRenderer.java
index fd11b37795..3b140a06bd 100644
--- a/src/com/android/launcher3/graphics/PreviewSurfaceRenderer.java
+++ b/src/com/android/launcher3/graphics/PreviewSurfaceRenderer.java
@@ -16,6 +16,7 @@
package com.android.launcher3.graphics;
+import static com.android.launcher3.config.FeatureFlags.MULTI_DB_GRID_MIRATION_ALGO;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
@@ -37,16 +38,17 @@ import android.view.animation.AccelerateDecelerateInterpolator;
import androidx.annotation.UiThread;
import androidx.annotation.WorkerThread;
-import com.android.launcher3.DeviceProfile;
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.LauncherSettings;
+import com.android.launcher3.R;
import com.android.launcher3.Utilities;
-import com.android.launcher3.Workspace;
import com.android.launcher3.graphics.LauncherPreviewRenderer.PreviewContext;
import com.android.launcher3.model.BgDataModel;
+import com.android.launcher3.model.GridSizeMigrationTask;
import com.android.launcher3.model.GridSizeMigrationTaskV2;
import com.android.launcher3.model.LoaderTask;
+import com.android.launcher3.model.ModelDelegate;
import com.android.launcher3.util.ComponentKey;
import com.android.launcher3.util.RunnableList;
import com.android.launcher3.util.Themes;
@@ -147,33 +149,23 @@ public class PreviewSurfaceRenderer {
inflationContext = new ContextThemeWrapper(context,
Themes.getActivityThemeRes(context, mWallpaperColors.getColorHints()));
} else {
- inflationContext = new ContextThemeWrapper(mContext,
- Themes.getActivityThemeRes(mContext));
+ inflationContext = new ContextThemeWrapper(mContext, R.style.AppTheme);
}
if (migrated) {
PreviewContext previewContext = new PreviewContext(inflationContext, mIdp);
new LoaderTask(
LauncherAppState.getInstance(previewContext),
- /* bgAllAppsList= */ null,
+ null,
new BgDataModel(),
- LauncherAppState.getInstance(previewContext).getModel().getModelDelegate(),
- /* results= */ null) {
+ new ModelDelegate(), null) {
@Override
public void run() {
- DeviceProfile deviceProfile = mIdp.getDeviceProfile(previewContext);
- String query =
- LauncherSettings.Favorites.SCREEN + " = " + Workspace.FIRST_SCREEN_ID
- + " or " + LauncherSettings.Favorites.CONTAINER + " = "
- + LauncherSettings.Favorites.CONTAINER_HOTSEAT;
- if (deviceProfile.isTwoPanels) {
- query += " or " + LauncherSettings.Favorites.SCREEN + " = "
- + Workspace.SECOND_SCREEN_ID;
- }
loadWorkspace(new ArrayList<>(), LauncherSettings.Favorites.PREVIEW_CONTENT_URI,
- query);
-
+ LauncherSettings.Favorites.SCREEN + " = 0 or "
+ + LauncherSettings.Favorites.CONTAINER + " = "
+ + LauncherSettings.Favorites.CONTAINER_HOTSEAT);
MAIN_EXECUTOR.execute(() -> {
renderView(previewContext, mBgDataModel, mWidgetProvidersMap);
mOnDestroyCallbacks.add(previewContext::onDestroy);
@@ -193,10 +185,16 @@ public class PreviewSurfaceRenderer {
@WorkerThread
private boolean doGridMigrationIfNecessary() {
- if (!GridSizeMigrationTaskV2.needsToMigrate(mContext, mIdp)) {
+ boolean needsToMigrate =
+ MULTI_DB_GRID_MIRATION_ALGO.get()
+ ? GridSizeMigrationTaskV2.needsToMigrate(mContext, mIdp)
+ : GridSizeMigrationTask.needsToMigrate(mContext, mIdp);
+ if (!needsToMigrate) {
return false;
}
- return GridSizeMigrationTaskV2.migrateGridIfNeeded(mContext, mIdp);
+ return MULTI_DB_GRID_MIRATION_ALGO.get()
+ ? GridSizeMigrationTaskV2.migrateGridIfNeeded(mContext, mIdp)
+ : GridSizeMigrationTask.migrateGridIfNeeded(mContext, mIdp);
}
@UiThread
diff --git a/src/com/android/launcher3/graphics/ShiftedBitmapDrawable.java b/src/com/android/launcher3/graphics/ShiftedBitmapDrawable.java
new file mode 100644
index 0000000000..f8583b89e0
--- /dev/null
+++ b/src/com/android/launcher3/graphics/ShiftedBitmapDrawable.java
@@ -0,0 +1,105 @@
+/*
+ * 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.
+ */
+package com.android.launcher3.graphics;
+
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.ColorFilter;
+import android.graphics.Paint;
+import android.graphics.PixelFormat;
+import android.graphics.drawable.Drawable;
+
+/**
+ * A simple drawable which draws a bitmap at a fixed position irrespective of the bounds
+ */
+public class ShiftedBitmapDrawable extends Drawable {
+
+ private final Paint mPaint = new Paint(Paint.FILTER_BITMAP_FLAG);
+ private final Bitmap mBitmap;
+ private float mShiftX;
+ private float mShiftY;
+
+ private final ConstantState mConstantState;
+
+ public ShiftedBitmapDrawable(Bitmap bitmap, float shiftX, float shiftY) {
+ mBitmap = bitmap;
+ mShiftX = shiftX;
+ mShiftY = shiftY;
+
+ mConstantState = new MyConstantState(mBitmap, mShiftX, mShiftY);
+ }
+
+ public float getShiftX() {
+ return mShiftX;
+ }
+
+ public float getShiftY() {
+ return mShiftY;
+ }
+
+ public void setShiftX(float shiftX) {
+ mShiftX = shiftX;
+ }
+
+ public void setShiftY(float shiftY) {
+ mShiftY = shiftY;
+ }
+
+ @Override
+ public void draw(Canvas canvas) {
+ canvas.drawBitmap(mBitmap, mShiftX, mShiftY, mPaint);
+ }
+
+ @Override
+ public void setAlpha(int i) { }
+
+ @Override
+ public void setColorFilter(ColorFilter colorFilter) {
+ mPaint.setColorFilter(colorFilter);
+ }
+
+ @Override
+ public int getOpacity() {
+ return PixelFormat.TRANSLUCENT;
+ }
+
+ @Override
+ public ConstantState getConstantState() {
+ return mConstantState;
+ }
+
+ private static class MyConstantState extends ConstantState {
+ private final Bitmap mBitmap;
+ private float mShiftX;
+ private float mShiftY;
+
+ MyConstantState(Bitmap bitmap, float shiftX, float shiftY) {
+ mBitmap = bitmap;
+ mShiftX = shiftX;
+ mShiftY = shiftY;
+ }
+
+ @Override
+ public Drawable newDrawable() {
+ return new ShiftedBitmapDrawable(mBitmap, mShiftX, mShiftY);
+ }
+
+ @Override
+ public int getChangingConfigurations() {
+ return 0;
+ }
+ }
+} \ No newline at end of file
diff --git a/src/com/android/launcher3/icons/ComponentWithLabelAndIcon.java b/src/com/android/launcher3/icons/ComponentWithLabelAndIcon.java
index c8606b1002..248a57d2fd 100644
--- a/src/com/android/launcher3/icons/ComponentWithLabelAndIcon.java
+++ b/src/com/android/launcher3/icons/ComponentWithLabelAndIcon.java
@@ -21,7 +21,6 @@ import android.graphics.drawable.Drawable;
import androidx.annotation.NonNull;
import com.android.launcher3.LauncherAppState;
-import com.android.launcher3.icons.BaseIconFactory.IconOptions;
/**
* Extension of ComponentWithLabel to also support loading icons
@@ -48,7 +47,7 @@ public interface ComponentWithLabelAndIcon extends ComponentWithLabel {
return super.loadIcon(context, object);
}
try (LauncherIcons li = LauncherIcons.obtain(context)) {
- return li.createBadgedIconBitmap(d, new IconOptions().setUser(object.getUser()));
+ return li.createBadgedIconBitmap(d, object.getUser(), 0);
}
}
}
diff --git a/src/com/android/launcher3/icons/IconCache.java b/src/com/android/launcher3/icons/IconCache.java
index fe9b633b66..cd13cd0ec5 100644
--- a/src/com/android/launcher3/icons/IconCache.java
+++ b/src/com/android/launcher3/icons/IconCache.java
@@ -16,12 +16,8 @@
package com.android.launcher3.icons;
-import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
-import static com.android.launcher3.widget.WidgetSections.NO_CATEGORY;
-
-import static java.util.stream.Collectors.groupingBy;
import android.content.ComponentName;
import android.content.Context;
@@ -34,22 +30,16 @@ import android.content.pm.PackageInstaller;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ShortcutInfo;
-import android.database.Cursor;
-import android.database.sqlite.SQLiteException;
import android.graphics.drawable.Drawable;
import android.os.Process;
-import android.os.Trace;
import android.os.UserHandle;
-import android.text.TextUtils;
import android.util.Log;
-import android.util.SparseArray;
import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.core.util.Pair;
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.LauncherFiles;
+import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.icons.ComponentWithLabel.ComponentCachingLogic;
@@ -57,7 +47,6 @@ import com.android.launcher3.icons.cache.BaseIconCache;
import com.android.launcher3.icons.cache.CachingLogic;
import com.android.launcher3.icons.cache.HandlerRunnable;
import com.android.launcher3.model.data.AppInfo;
-import com.android.launcher3.model.data.IconRequestInfo;
import com.android.launcher3.model.data.ItemInfoWithIcon;
import com.android.launcher3.model.data.PackageItemInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo;
@@ -66,16 +55,9 @@ import com.android.launcher3.shortcuts.ShortcutKey;
import com.android.launcher3.util.InstantAppResolver;
import com.android.launcher3.util.PackageUserKey;
import com.android.launcher3.util.Preconditions;
-import com.android.launcher3.widget.WidgetSections;
-import com.android.launcher3.widget.WidgetSections.WidgetSection;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
import java.util.function.Predicate;
import java.util.function.Supplier;
-import java.util.stream.Stream;
/**
* Cache of application icons. Icons can be made from any thread.
@@ -96,8 +78,6 @@ public class IconCache extends BaseIconCache {
private final InstantAppResolver mInstantAppResolver;
private final IconProvider mIconProvider;
- private final SparseArray<BitmapInfo> mWidgetCategoryBitmapInfos;
-
private int mPendingIconRequestCount = 0;
public IconCache(Context context, InvariantDeviceProfile idp) {
@@ -115,7 +95,6 @@ public class IconCache extends BaseIconCache {
mUserManager = UserCache.INSTANCE.get(mContext);
mInstantAppResolver = InstantAppResolver.newInstance(mContext);
mIconProvider = iconProvider;
- mWidgetCategoryBitmapInfos = new SparseArray<>();
}
@Override
@@ -155,9 +134,6 @@ public class IconCache extends BaseIconCache {
* Closes the cache DB. This will clear any in-memory cache.
*/
public void close() {
- // This will clear all pending updates
- getUpdateHandler();
-
mIconDb.close();
}
@@ -222,7 +198,14 @@ public class IconCache extends BaseIconCache {
* Fill in {@param info} with the icon for {@param si}
*/
public void getShortcutIcon(ItemInfoWithIcon info, ShortcutInfo si) {
- getShortcutIcon(info, si, mIsUsingFallbackOrNonDefaultIconCheck);
+ getShortcutIcon(info, si, true, mIsUsingFallbackOrNonDefaultIconCheck);
+ }
+
+ /**
+ * Fill in {@param info} with an unbadged icon for {@param si}
+ */
+ public void getUnbadgedShortcutIcon(ItemInfoWithIcon info, ShortcutInfo si) {
+ getShortcutIcon(info, si, false, mIsUsingFallbackOrNonDefaultIconCheck);
}
/**
@@ -231,6 +214,11 @@ public class IconCache extends BaseIconCache {
*/
public <T extends ItemInfoWithIcon> void getShortcutIcon(T info, ShortcutInfo si,
@NonNull Predicate<T> fallbackIconCheck) {
+ getShortcutIcon(info, si, true /* use badged */, fallbackIconCheck);
+ }
+
+ private synchronized <T extends ItemInfoWithIcon> void getShortcutIcon(T info, ShortcutInfo si,
+ boolean useBadged, @NonNull Predicate<T> fallbackIconCheck) {
BitmapInfo bitmapInfo;
if (FeatureFlags.ENABLE_DEEP_SHORTCUT_ICON_CACHE.get()) {
bitmapInfo = cacheLocked(ShortcutKey.fromInfo(si).componentName, si.getUserHandle(),
@@ -246,7 +234,13 @@ public class IconCache extends BaseIconCache {
if (isDefaultIcon(bitmapInfo, si.getUserHandle()) && fallbackIconCheck.test(info)) {
return;
}
- info.bitmap = bitmapInfo.withBadgeInfo(getShortcutInfoBadge(si));
+ info.bitmap = bitmapInfo;
+ if (useBadged) {
+ BitmapInfo badgeInfo = getShortcutInfoBadge(si);
+ try (LauncherIcons li = LauncherIcons.obtain(mContext)) {
+ info.bitmap = li.badgeBitmap(info.bitmap.icon, badgeInfo);
+ }
+ }
}
/**
@@ -265,8 +259,7 @@ public class IconCache extends BaseIconCache {
getTitleAndIcon(appInfo, false);
return appInfo.bitmap;
} else {
- PackageItemInfo pkgInfo = new PackageItemInfo(shortcutInfo.getPackage(),
- shortcutInfo.getUserHandle());
+ PackageItemInfo pkgInfo = new PackageItemInfo(shortcutInfo.getPackage());
getTitleAndIconForApp(pkgInfo, false);
return pkgInfo.bitmap;
}
@@ -310,169 +303,6 @@ public class IconCache extends BaseIconCache {
applyCacheEntry(entry, infoInOut);
}
- /**
- * Creates an sql cursor for a query of a set of ItemInfoWithIcon icons and titles.
- *
- * @param iconRequestInfos List of IconRequestInfos representing titles and icons to query.
- * @param user UserHandle all the given iconRequestInfos share
- * @param useLowResIcons whether we should exclude the icon column from the sql results.
- */
- private <T extends ItemInfoWithIcon> Cursor createBulkQueryCursor(
- List<IconRequestInfo<T>> iconRequestInfos, UserHandle user, boolean useLowResIcons)
- throws SQLiteException {
- String[] queryParams = Stream.concat(
- iconRequestInfos.stream()
- .map(r -> r.itemInfo.getTargetComponent())
- .filter(Objects::nonNull)
- .distinct()
- .map(ComponentName::flattenToString),
- Stream.of(Long.toString(getSerialNumberForUser(user)))).toArray(String[]::new);
- String componentNameQuery = TextUtils.join(
- ",", Collections.nCopies(queryParams.length - 1, "?"));
-
- return mIconDb.query(
- useLowResIcons ? IconDB.COLUMNS_LOW_RES : IconDB.COLUMNS_HIGH_RES,
- IconDB.COLUMN_COMPONENT
- + " IN ( " + componentNameQuery + " )"
- + " AND " + IconDB.COLUMN_USER + " = ?",
- queryParams);
- }
-
- /**
- * Load and fill icons requested in iconRequestInfos using a single bulk sql query.
- */
- public synchronized <T extends ItemInfoWithIcon> void getTitlesAndIconsInBulk(
- List<IconRequestInfo<T>> iconRequestInfos) {
- Map<Pair<UserHandle, Boolean>, List<IconRequestInfo<T>>> iconLoadSubsectionsMap =
- iconRequestInfos.stream()
- .filter(iconRequest -> {
- if (iconRequest.itemInfo.getTargetComponent() == null) {
- Log.i(TAG,
- "Skipping Item info with null component name: "
- + iconRequest.itemInfo);
- iconRequest.itemInfo.bitmap = getDefaultIcon(
- iconRequest.itemInfo.user);
- return false;
- }
- return true;
- })
- .collect(groupingBy(iconRequest ->
- Pair.create(iconRequest.itemInfo.user, iconRequest.useLowResIcon)));
-
- Trace.beginSection("loadIconsInBulk");
- iconLoadSubsectionsMap.forEach((sectionKey, filteredList) -> {
- Map<ComponentName, List<IconRequestInfo<T>>> duplicateIconRequestsMap =
- filteredList.stream()
- .filter(iconRequest -> {
- // Filter out icons that should not share the same bitmap and title
- if (iconRequest.itemInfo.itemType == ITEM_TYPE_DEEP_SHORTCUT) {
- Log.e(TAG,
- "Skipping Item info for deep shortcut: "
- + iconRequest.itemInfo,
- new IllegalStateException());
- return false;
- }
- return true;
- })
- .collect(groupingBy(iconRequest ->
- iconRequest.itemInfo.getTargetComponent()));
-
- Trace.beginSection("loadIconSubsectionInBulk");
- loadIconSubsection(sectionKey, filteredList, duplicateIconRequestsMap);
- Trace.endSection();
- });
- Trace.endSection();
- }
-
- private <T extends ItemInfoWithIcon> void loadIconSubsection(
- Pair<UserHandle, Boolean> sectionKey,
- List<IconRequestInfo<T>> filteredList,
- Map<ComponentName, List<IconRequestInfo<T>>> duplicateIconRequestsMap) {
- Trace.beginSection("loadIconSubsectionWithDatabase");
- try (Cursor c = createBulkQueryCursor(
- filteredList,
- /* user = */ sectionKey.first,
- /* useLowResIcons = */ sectionKey.second)) {
- // Database title and icon loading
- int componentNameColumnIndex = c.getColumnIndexOrThrow(IconDB.COLUMN_COMPONENT);
- while (c.moveToNext()) {
- ComponentName cn = ComponentName.unflattenFromString(
- c.getString(componentNameColumnIndex));
- List<IconRequestInfo<T>> duplicateIconRequests =
- duplicateIconRequestsMap.get(cn);
-
- if (cn != null) {
- CacheEntry entry = cacheLocked(
- cn,
- /* user = */ sectionKey.first,
- () -> duplicateIconRequests.get(0).launcherActivityInfo,
- mLauncherActivityInfoCachingLogic,
- c,
- /* usePackageIcon= */ false,
- /* useLowResIcons = */ sectionKey.second);
-
- for (IconRequestInfo<T> iconRequest : duplicateIconRequests) {
- applyCacheEntry(entry, iconRequest.itemInfo);
- }
- }
- }
- } catch (SQLiteException e) {
- Log.d(TAG, "Error reading icon cache", e);
- } finally {
- Trace.endSection();
- }
-
- Trace.beginSection("loadIconSubsectionWithFallback");
- // Fallback title and icon loading
- for (ComponentName cn : duplicateIconRequestsMap.keySet()) {
- IconRequestInfo<T> iconRequestInfo = duplicateIconRequestsMap.get(cn).get(0);
- ItemInfoWithIcon itemInfo = iconRequestInfo.itemInfo;
- BitmapInfo icon = itemInfo.bitmap;
- boolean loadFallbackTitle = TextUtils.isEmpty(itemInfo.title);
- boolean loadFallbackIcon = icon == null
- || isDefaultIcon(icon, itemInfo.user)
- || icon == BitmapInfo.LOW_RES_INFO;
-
- if (loadFallbackTitle || loadFallbackIcon) {
- Log.i(TAG,
- "Database bulk icon loading failed, using fallback bulk icon loading "
- + "for: " + cn);
- CacheEntry entry = new CacheEntry();
- LauncherActivityInfo lai = iconRequestInfo.launcherActivityInfo;
-
- // Fill fields that are not updated below so they are not subsequently
- // deleted.
- entry.title = itemInfo.title;
- if (icon != null) {
- entry.bitmap = icon;
- }
- entry.contentDescription = itemInfo.contentDescription;
-
- if (loadFallbackIcon) {
- loadFallbackIcon(
- lai,
- entry,
- mLauncherActivityInfoCachingLogic,
- /* usePackageIcon= */ false,
- /* usePackageTitle= */ loadFallbackTitle,
- cn,
- sectionKey.first);
- }
- if (loadFallbackTitle && TextUtils.isEmpty(entry.title) && lai != null) {
- loadFallbackTitle(
- lai,
- entry,
- mLauncherActivityInfoCachingLogic,
- sectionKey.first);
- }
-
- for (IconRequestInfo<T> iconRequest : duplicateIconRequestsMap.get(cn)) {
- applyCacheEntry(entry, iconRequest.itemInfo);
- }
- }
- }
- Trace.endSection();
- }
/**
* Fill in {@param infoInOut} with the corresponding icon and label.
@@ -482,39 +312,11 @@ public class IconCache extends BaseIconCache {
CacheEntry entry = getEntryForPackageLocked(
infoInOut.packageName, infoInOut.user, useLowResIcon);
applyCacheEntry(entry, infoInOut);
- if (infoInOut.widgetCategory == NO_CATEGORY) {
- return;
- }
-
- WidgetSection widgetSection = WidgetSections.getWidgetSections(mContext)
- .get(infoInOut.widgetCategory);
- infoInOut.title = mContext.getString(widgetSection.mSectionTitle);
- infoInOut.contentDescription = mPackageManager.getUserBadgedLabel(
- infoInOut.title, infoInOut.user);
- final BitmapInfo cachedBitmap = mWidgetCategoryBitmapInfos.get(infoInOut.widgetCategory);
- if (cachedBitmap != null) {
- infoInOut.bitmap = getBadgedIcon(cachedBitmap, infoInOut.user);
- return;
- }
-
- try (LauncherIcons li = LauncherIcons.obtain(mContext)) {
- final BitmapInfo tempBitmap = li.createBadgedIconBitmap(
- mContext.getDrawable(widgetSection.mSectionDrawable),
- new BaseIconFactory.IconOptions().setShrinkNonAdaptiveIcons(false));
- mWidgetCategoryBitmapInfos.put(infoInOut.widgetCategory, tempBitmap);
- infoInOut.bitmap = getBadgedIcon(tempBitmap, infoInOut.user);
- } catch (Exception e) {
- Log.e(TAG, "Error initializing bitmap for icons with widget category", e);
- }
-
- }
-
- private synchronized BitmapInfo getBadgedIcon(@Nullable final BitmapInfo bitmap,
- @NonNull final UserHandle user) {
- if (bitmap == null) {
- return getDefaultIcon(user);
+ if (infoInOut.category == PackageItemInfo.CONVERSATIONS) {
+ infoInOut.title = mContext.getString(R.string.widget_category_conversations);
+ infoInOut.contentDescription = mPackageManager.getUserBadgedLabel(
+ infoInOut.title, infoInOut.user);
}
- return bitmap.withFlags(getUserFlagOpLocked(user));
}
protected void applyCacheEntry(CacheEntry entry, ItemInfoWithIcon info) {
diff --git a/src/com/android/launcher3/icons/LauncherActivityCachingLogic.java b/src/com/android/launcher3/icons/LauncherActivityCachingLogic.java
index 4b8c1ad590..e820ac474a 100644
--- a/src/com/android/launcher3/icons/LauncherActivityCachingLogic.java
+++ b/src/com/android/launcher3/icons/LauncherActivityCachingLogic.java
@@ -22,7 +22,6 @@ import android.os.UserHandle;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.R;
-import com.android.launcher3.icons.BaseIconFactory.IconOptions;
import com.android.launcher3.icons.cache.CachingLogic;
import com.android.launcher3.util.ResourceBasedOverride;
@@ -60,7 +59,7 @@ public class LauncherActivityCachingLogic
try (LauncherIcons li = LauncherIcons.obtain(context)) {
return li.createBadgedIconBitmap(LauncherAppState.getInstance(context)
.getIconProvider().getIcon(object, li.mFillResIconDpi),
- new IconOptions().setUser(object.getUser()));
+ object.getUser(), object.getApplicationInfo().targetSdkVersion);
}
}
}
diff --git a/src/com/android/launcher3/icons/LauncherIconProvider.java b/src/com/android/launcher3/icons/LauncherIconProvider.java
deleted file mode 100644
index c4d5f2b5b5..0000000000
--- a/src/com/android/launcher3/icons/LauncherIconProvider.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.launcher3.icons;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.content.res.XmlResourceParser;
-import android.text.TextUtils;
-import android.util.ArrayMap;
-import android.util.Log;
-
-import com.android.launcher3.R;
-import com.android.launcher3.config.FeatureFlags;
-import com.android.launcher3.util.Themes;
-
-import org.xmlpull.v1.XmlPullParser;
-
-import java.util.Collections;
-import java.util.Map;
-
-/**
- * Extension of {@link IconProvider} with support for overriding theme icons
- */
-public class LauncherIconProvider extends IconProvider {
-
- private static final String TAG_ICON = "icon";
- private static final String ATTR_PACKAGE = "package";
- private static final String ATTR_DRAWABLE = "drawable";
-
- private static final String TAG = "LIconProvider";
- private static final Map<String, ThemeData> DISABLED_MAP = Collections.emptyMap();
-
- private Map<String, ThemeData> mThemedIconMap;
- private boolean mSupportsIconTheme;
-
- public LauncherIconProvider(Context context) {
- super(context);
- setIconThemeSupported(Themes.isThemedIconEnabled(context));
- }
-
- /**
- * Enables or disables icon theme support
- */
- public void setIconThemeSupported(boolean isSupported) {
- mSupportsIconTheme = isSupported;
- mThemedIconMap = isSupported && FeatureFlags.USE_LOCAL_ICON_OVERRIDES.get()
- ? null : DISABLED_MAP;
- }
-
- @Override
- protected ThemeData getThemeDataForPackage(String packageName) {
- return getThemedIconMap().get(packageName);
- }
-
- @Override
- public String getSystemIconState() {
- return super.getSystemIconState() + (mSupportsIconTheme ? ",with-theme" : ",no-theme");
- }
-
- private Map<String, ThemeData> getThemedIconMap() {
- if (mThemedIconMap != null) {
- return mThemedIconMap;
- }
- ArrayMap<String, ThemeData> map = new ArrayMap<>();
- Resources res = mContext.getResources();
- try (XmlResourceParser parser = res.getXml(R.xml.grayscale_icon_map)) {
- final int depth = parser.getDepth();
- int type;
- while ((type = parser.next()) != XmlPullParser.START_TAG
- && type != XmlPullParser.END_DOCUMENT);
-
- while (((type = parser.next()) != XmlPullParser.END_TAG
- || parser.getDepth() > depth) && type != XmlPullParser.END_DOCUMENT) {
- if (type != XmlPullParser.START_TAG) {
- continue;
- }
- if (TAG_ICON.equals(parser.getName())) {
- String pkg = parser.getAttributeValue(null, ATTR_PACKAGE);
- int iconId = parser.getAttributeResourceValue(null, ATTR_DRAWABLE, 0);
- if (iconId != 0 && !TextUtils.isEmpty(pkg)) {
- map.put(pkg, new ThemeData(res, iconId));
- }
- }
- }
- } catch (Exception e) {
- Log.e(TAG, "Unable to parse icon map", e);
- }
- mThemedIconMap = map;
- return mThemedIconMap;
- }
-}
diff --git a/src/com/android/launcher3/icons/LauncherIcons.java b/src/com/android/launcher3/icons/LauncherIcons.java
index 5508c49410..bf7897e8cc 100644
--- a/src/com/android/launcher3/icons/LauncherIcons.java
+++ b/src/com/android/launcher3/icons/LauncherIcons.java
@@ -21,7 +21,6 @@ import android.content.Context;
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.graphics.IconShape;
import com.android.launcher3.graphics.LauncherPreviewRenderer;
-import com.android.launcher3.util.Themes;
/**
* Wrapper class to provide access to {@link BaseIconFactory} and also to provide pool of this class
@@ -33,13 +32,18 @@ public class LauncherIcons extends BaseIconFactory implements AutoCloseable {
private static LauncherIcons sPool;
private static int sPoolId = 0;
+ public static LauncherIcons obtain(Context context) {
+ return obtain(context, IconShape.getShape().enableShapeDetection());
+ }
+
/**
* Return a new Message instance from the global pool. Allows us to
* avoid allocating new objects in many cases.
*/
- public static LauncherIcons obtain(Context context) {
+ public static LauncherIcons obtain(Context context, boolean shapeDetection) {
if (context instanceof LauncherPreviewRenderer.PreviewContext) {
- return ((LauncherPreviewRenderer.PreviewContext) context).newLauncherIcons(context);
+ return ((LauncherPreviewRenderer.PreviewContext) context).newLauncherIcons(context,
+ shapeDetection);
}
int poolId;
@@ -54,7 +58,8 @@ public class LauncherIcons extends BaseIconFactory implements AutoCloseable {
}
InvariantDeviceProfile idp = InvariantDeviceProfile.INSTANCE.get(context);
- return new LauncherIcons(context, idp.fillResIconDpi, idp.iconBitmapSize, poolId);
+ return new LauncherIcons(context, idp.fillResIconDpi, idp.iconBitmapSize, poolId,
+ shapeDetection);
}
public static void clearPool() {
@@ -68,9 +73,9 @@ public class LauncherIcons extends BaseIconFactory implements AutoCloseable {
private LauncherIcons next;
- protected LauncherIcons(Context context, int fillResIconDpi, int iconBitmapSize, int poolId) {
- super(context, fillResIconDpi, iconBitmapSize, IconShape.getShape().enableShapeDetection());
- mMonoIconEnabled = Themes.isThemedIconEnabled(context);
+ protected LauncherIcons(Context context, int fillResIconDpi, int iconBitmapSize, int poolId,
+ boolean shapeDetection) {
+ super(context, fillResIconDpi, iconBitmapSize, shapeDetection);
mPoolId = poolId;
}
diff --git a/src/com/android/launcher3/icons/ShortcutCachingLogic.java b/src/com/android/launcher3/icons/ShortcutCachingLogic.java
index 6a8f34a93d..d7eed06901 100644
--- a/src/com/android/launcher3/icons/ShortcutCachingLogic.java
+++ b/src/com/android/launcher3/icons/ShortcutCachingLogic.java
@@ -71,8 +71,8 @@ public class ShortcutCachingLogic implements CachingLogic<ShortcutInfo> {
Drawable unbadgedDrawable = ShortcutCachingLogic.getIcon(
context, info, LauncherAppState.getIDP(context).fillResIconDpi);
if (unbadgedDrawable == null) return BitmapInfo.LOW_RES_INFO;
- return new BitmapInfo(li.createScaledBitmapWithoutShadow(unbadgedDrawable),
- Themes.getColorAccent(context));
+ return new BitmapInfo(li.createScaledBitmapWithoutShadow(
+ unbadgedDrawable, 0), Themes.getColorAccent(context));
}
}
diff --git a/src/com/android/launcher3/logging/InstanceId.java b/src/com/android/launcher3/logging/InstanceId.java
index 3c4a644053..e720d758b4 100644
--- a/src/com/android/launcher3/logging/InstanceId.java
+++ b/src/com/android/launcher3/logging/InstanceId.java
@@ -36,10 +36,10 @@ import androidx.annotation.VisibleForTesting;
*/
public final class InstanceId implements Parcelable {
// At most 20 bits: ~1m possibilities, ~0.5% probability of collision in 100 values
- public static final int INSTANCE_ID_MAX = 1 << 20;
+ static final int INSTANCE_ID_MAX = 1 << 20;
private final int mId;
- public InstanceId(int id) {
+ InstanceId(int id) {
mId = min(max(0, id), INSTANCE_ID_MAX);
}
diff --git a/src/com/android/launcher3/logging/StatsLogManager.java b/src/com/android/launcher3/logging/StatsLogManager.java
index c4ec4e36fd..79e5b5d04c 100644
--- a/src/com/android/launcher3/logging/StatsLogManager.java
+++ b/src/com/android/launcher3/logging/StatsLogManager.java
@@ -33,7 +33,6 @@ import com.android.launcher3.logger.LauncherAtom.FromState;
import com.android.launcher3.logger.LauncherAtom.ToState;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.util.ResourceBasedOverride;
-import com.android.launcher3.views.ActivityContext;
/**
* Handles the user event logging in R+.
@@ -54,9 +53,6 @@ public class StatsLogManager implements ResourceBasedOverride {
public static final int LAUNCHER_STATE_UNCHANGED = 5;
private InstanceId mInstanceId;
-
- protected @Nullable ActivityContext mActivityContext = null;
-
/**
* Returns event enum based on the two state transition information when swipe
* gesture happens(to be removed during UserEventDispatcher cleanup).
@@ -80,22 +76,6 @@ public class StatsLogManager implements ResourceBasedOverride {
}
public interface EventEnum {
-
- /**
- * Tag used to request new UI Event IDs via presubmit analysis.
- *
- * <p>Use RESERVE_NEW_UI_EVENT_ID as the constructor parameter for a new {@link EventEnum}
- * to signal the presubmit analyzer to reserve a new ID for the event. The new ID will be
- * returned as a Gerrit presubmit finding. Do not submit {@code RESERVE_NEW_UI_EVENT_ID} as
- * the constructor parameter for any event.
- *
- * <pre>
- * &#064;UiEvent(doc = "Briefly describe the interaction when this event will be logged")
- * UNIQUE_EVENT_NAME(RESERVE_NEW_UI_EVENT_ID);
- * </pre>
- */
- int RESERVE_NEW_UI_EVENT_ID = Integer.MIN_VALUE; // Negative IDs are ignored by the logger.
-
int getId();
}
@@ -258,9 +238,6 @@ public class StatsLogManager implements ResourceBasedOverride {
@UiEvent(doc = "User swipes or fling in DOWN direction to close apps drawer.")
LAUNCHER_ALLAPPS_CLOSE_DOWN(569),
- @UiEvent(doc = "User tap outside apps drawer sheet to close apps drawer.")
- LAUNCHER_ALLAPPS_CLOSE_TAP_OUTSIDE(941),
-
@UiEvent(doc = "User swipes or fling in UP direction and hold from the bottom bazel area")
LAUNCHER_OVERVIEW_GESTURE(570),
@@ -288,9 +265,6 @@ public class StatsLogManager implements ResourceBasedOverride {
@UiEvent(doc = "User tapped on the share button on overview")
LAUNCHER_OVERVIEW_ACTIONS_SHARE(582),
- @UiEvent(doc = "User tapped on the split screen button on overview")
- LAUNCHER_OVERVIEW_ACTIONS_SPLIT(895),
-
@UiEvent(doc = "User tapped on the close button in select mode")
LAUNCHER_SELECT_MODE_CLOSE(583),
@@ -375,9 +349,6 @@ public class StatsLogManager implements ResourceBasedOverride {
@UiEvent(doc = "Notification dismissed by swiping right.")
LAUNCHER_NOTIFICATION_DISMISSED(652),
- @UiEvent(doc = "Current grid size is changed to 6.")
- LAUNCHER_GRID_SIZE_6(930),
-
@UiEvent(doc = "Current grid size is changed to 5.")
LAUNCHER_GRID_SIZE_5(662),
@@ -515,83 +486,7 @@ public class StatsLogManager implements ResourceBasedOverride {
LAUNCHER_TURN_ON_WORK_APPS_TAP(838),
@UiEvent(doc = "User tapped on 'Turn off work apps' button in all apps window.")
- LAUNCHER_TURN_OFF_WORK_APPS_TAP(839),
-
- @UiEvent(doc = "Launcher item drop failed since there was not enough room on the screen.")
- LAUNCHER_ITEM_DROP_FAILED_INSUFFICIENT_SPACE(872),
-
- @UiEvent(doc = "User long pressed on the taskbar background to hide the taskbar")
- LAUNCHER_TASKBAR_LONGPRESS_HIDE(896),
-
- @UiEvent(doc = "User long pressed on the taskbar gesture handle to show the taskbar")
- LAUNCHER_TASKBAR_LONGPRESS_SHOW(897),
-
- @UiEvent(doc = "User clicks on the search icon on header to launch search in app.")
- LAUNCHER_ALLAPPS_SEARCHINAPP_LAUNCH(913),
-
- @UiEvent(doc = "User is shown the back gesture navigation tutorial step.")
- LAUNCHER_GESTURE_TUTORIAL_BACK_STEP_SHOWN(959),
-
- @UiEvent(doc = "User is shown the home gesture navigation tutorial step.")
- LAUNCHER_GESTURE_TUTORIAL_HOME_STEP_SHOWN(960),
-
- @UiEvent(doc = "User is shown the overview gesture navigation tutorial step.")
- LAUNCHER_GESTURE_TUTORIAL_OVERVIEW_STEP_SHOWN(961),
-
- @UiEvent(doc = "User completed the back gesture navigation tutorial step.")
- LAUNCHER_GESTURE_TUTORIAL_BACK_STEP_COMPLETED(962),
-
- @UiEvent(doc = "User completed the home gesture navigation tutorial step.")
- LAUNCHER_GESTURE_TUTORIAL_HOME_STEP_COMPLETED(963),
-
- @UiEvent(doc = "User completed the overview gesture navigation tutorial step.")
- LAUNCHER_GESTURE_TUTORIAL_OVERVIEW_STEP_COMPLETED(964),
-
- @UiEvent(doc = "User skips the gesture navigation tutorial.")
- LAUNCHER_GESTURE_TUTORIAL_SKIPPED(965),
-
- @UiEvent(doc = "User scrolled on one of the all apps surfaces such as A-Z list, search "
- + "result page etc.")
- LAUNCHER_ALLAPPS_SCROLLED(985),
-
- @UiEvent(doc = "User tapped taskbar home button")
- LAUNCHER_TASKBAR_HOME_BUTTON_TAP(1003),
-
- @UiEvent(doc = "User tapped taskbar back button")
- LAUNCHER_TASKBAR_BACK_BUTTON_TAP(1004),
-
- @UiEvent(doc = "User tapped taskbar overview/recents button")
- LAUNCHER_TASKBAR_OVERVIEW_BUTTON_TAP(1005),
-
- @UiEvent(doc = "User tapped taskbar IME switcher button")
- LAUNCHER_TASKBAR_IME_SWITCHER_BUTTON_TAP(1006),
-
- @UiEvent(doc = "User tapped taskbar a11y button")
- LAUNCHER_TASKBAR_A11Y_BUTTON_TAP(1007),
-
- @UiEvent(doc = "User tapped taskbar home button")
- LAUNCHER_TASKBAR_HOME_BUTTON_LONGPRESS(1008),
-
- @UiEvent(doc = "User tapped taskbar back button")
- LAUNCHER_TASKBAR_BACK_BUTTON_LONGPRESS(1009),
-
- @UiEvent(doc = "User tapped taskbar overview/recents button")
- LAUNCHER_TASKBAR_OVERVIEW_BUTTON_LONGPRESS(1010),
-
- @UiEvent(doc = "User tapped taskbar a11y button")
- LAUNCHER_TASKBAR_A11Y_BUTTON_LONGPRESS(1011),
-
- @UiEvent(doc = "Show an 'Undo' snackbar when users dismiss a predicted hotseat item")
- LAUNCHER_DISMISS_PREDICTION_UNDO(1035),
-
- @UiEvent(doc = "User clicked on IME quicksearch button.")
- LAUNCHER_ALLAPPS_QUICK_SEARCH_WITH_IME(1047),
-
- @UiEvent(doc = "User tapped taskbar All Apps button.")
- LAUNCHER_TASKBAR_ALLAPPS_BUTTON_TAP(1057),
-
- @UiEvent(doc = "User tapped on Share app system shortcut.")
- LAUNCHER_SYSTEM_SHORTCUT_APP_SHARE_TAP(1075),
+ LAUNCHER_TURN_OFF_WORK_APPS_TAP(839)
;
// ADD MORE
@@ -627,7 +522,7 @@ public class StatsLogManager implements ResourceBasedOverride {
}
/**
- * Helps to construct and log launcher event.
+ * Helps to construct and write the log message.
*/
public interface StatsLogger {
@@ -727,91 +622,12 @@ public class StatsLogManager implements ResourceBasedOverride {
}
/**
- * Helps to construct and log latency event.
- */
- public interface StatsLatencyLogger {
-
- enum LatencyType {
- UNKNOWN(0),
- COLD(1),
- HOT(2),
- TIMEOUT(3),
- FAIL(4),
- COLD_USERWAITING(5);
-
- private final int mId;
-
- LatencyType(int id) {
- this.mId = id;
- }
-
- public int getId() {
- return mId;
- }
-
- }
-
- /**
- * Sets {@link InstanceId} of log message.
- */
- default StatsLatencyLogger withInstanceId(InstanceId instanceId) {
- return this;
- }
-
-
- /**
- * Sets latency of the event.
- */
- default StatsLatencyLogger withLatency(long latencyInMillis) {
- return this;
- }
-
- /**
- * Sets {@link LatencyType} of log message.
- */
- default StatsLatencyLogger withType(LatencyType type) {
- return this;
- }
-
- /**
- * Sets query length of the event.
- */
- default StatsLatencyLogger withQueryLength(int queryLength) {
- return this;
- }
-
- /**
- * Sets packageId of log message.
- */
- default StatsLatencyLogger withPackageId(int packageId) {
- return this;
- }
-
- /**
- * Builds the final message and logs it as {@link EventEnum}.
- */
- default void log(EventEnum event) {
- }
- }
-
- /**
* Returns new logger object.
*/
public StatsLogger logger() {
StatsLogger logger = createLogger();
if (mInstanceId != null) {
- logger.withInstanceId(mInstanceId);
- }
- return logger;
- }
-
- /**
- * Returns new latency logger object.
- */
- public StatsLatencyLogger latencyLogger() {
- StatsLatencyLogger logger = createLatencyLogger();
- if (mInstanceId != null) {
- logger.withInstanceId(mInstanceId);
+ return logger.withInstanceId(mInstanceId);
}
return logger;
}
@@ -821,11 +637,6 @@ public class StatsLogManager implements ResourceBasedOverride {
};
}
- protected StatsLatencyLogger createLatencyLogger() {
- return new StatsLatencyLogger() {
- };
- }
-
/**
* Sets InstanceId to every new {@link StatsLogger} object returned by {@link #logger()} when
* not-null.
@@ -839,9 +650,7 @@ public class StatsLogManager implements ResourceBasedOverride {
* Creates a new instance of {@link StatsLogManager} based on provided context.
*/
public static StatsLogManager newInstance(Context context) {
- StatsLogManager manager = Overrides.getObject(StatsLogManager.class,
+ return Overrides.getObject(StatsLogManager.class,
context.getApplicationContext(), R.string.stats_log_manager_class);
- manager.mActivityContext = ActivityContext.lookupContextNoThrow(context);
- return manager;
}
}
diff --git a/src/com/android/launcher3/model/AddWorkspaceItemsTask.java b/src/com/android/launcher3/model/AddWorkspaceItemsTask.java
index 31ef2e5ea6..01b3e6e3ba 100644
--- a/src/com/android/launcher3/model/AddWorkspaceItemsTask.java
+++ b/src/com/android/launcher3/model/AddWorkspaceItemsTask.java
@@ -20,9 +20,10 @@ import android.content.pm.LauncherActivityInfo;
import android.content.pm.LauncherApps;
import android.content.pm.PackageInstaller.SessionInfo;
import android.os.UserHandle;
-import android.util.Log;
+import android.util.LongSparseArray;
import android.util.Pair;
+import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.LauncherModel.CallbackTask;
import com.android.launcher3.LauncherSettings;
@@ -32,11 +33,10 @@ import com.android.launcher3.model.data.AppInfo;
import com.android.launcher3.model.data.FolderInfo;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.LauncherAppWidgetInfo;
-import com.android.launcher3.model.data.WorkspaceItemFactory;
import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.launcher3.pm.InstallSessionHelper;
import com.android.launcher3.pm.PackageInstallInfo;
-import com.android.launcher3.testing.TestProtocol;
+import com.android.launcher3.util.GridOccupancy;
import com.android.launcher3.util.IntArray;
import com.android.launcher3.util.PackageManagerHelper;
@@ -52,23 +52,11 @@ public class AddWorkspaceItemsTask extends BaseModelUpdateTask {
private final List<Pair<ItemInfo, Object>> mItemList;
- private final WorkspaceItemSpaceFinder mItemSpaceFinder;
-
/**
* @param itemList items to add on the workspace
*/
public AddWorkspaceItemsTask(List<Pair<ItemInfo, Object>> itemList) {
- this(itemList, new WorkspaceItemSpaceFinder());
- }
-
- /**
- * @param itemList items to add on the workspace
- * @param itemSpaceFinder inject WorkspaceItemSpaceFinder dependency for testing
- */
- public AddWorkspaceItemsTask(List<Pair<ItemInfo, Object>> itemList,
- WorkspaceItemSpaceFinder itemSpaceFinder) {
mItemList = itemList;
- mItemSpaceFinder = itemSpaceFinder;
}
@Override
@@ -80,7 +68,7 @@ public class AddWorkspaceItemsTask extends BaseModelUpdateTask {
final ArrayList<ItemInfo> addedItemsFinal = new ArrayList<>();
final IntArray addedWorkspaceScreensFinal = new IntArray();
- synchronized (dataModel) {
+ synchronized(dataModel) {
IntArray workspaceScreens = dataModel.collectWorkspaceScreens();
List<ItemInfo> filteredItems = new ArrayList<>();
@@ -90,26 +78,18 @@ public class AddWorkspaceItemsTask extends BaseModelUpdateTask {
item.itemType == LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT) {
// Short-circuit this logic if the icon exists somewhere on the workspace
if (shortcutExists(dataModel, item.getIntent(), item.user)) {
- if (TestProtocol.sDebugTracing) {
- Log.d(TestProtocol.MISSING_PROMISE_ICON,
- LOG + " Item already on workspace.");
- }
continue;
}
// b/139663018 Short-circuit this logic if the icon is a system app
if (PackageManagerHelper.isSystemApp(app.getContext(), item.getIntent())) {
- if (TestProtocol.sDebugTracing) {
- Log.d(TestProtocol.MISSING_PROMISE_ICON,
- LOG + " Item is a system app.");
- }
continue;
}
}
if (item.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION) {
- if (item instanceof WorkspaceItemFactory) {
- item = ((WorkspaceItemFactory) item).makeWorkspaceItem(app.getContext());
+ if (item instanceof AppInfo) {
+ item = ((AppInfo) item).makeWorkspaceItem();
}
}
if (item != null) {
@@ -123,7 +103,7 @@ public class AddWorkspaceItemsTask extends BaseModelUpdateTask {
for (ItemInfo item : filteredItems) {
// Find appropriate space for the item.
- int[] coords = mItemSpaceFinder.findSpaceForItem(app, dataModel, workspaceScreens,
+ int[] coords = findSpaceForItem(app, dataModel, workspaceScreens,
addedWorkspaceScreensFinal, item.spanX, item.spanY);
int screenId = coords[0];
@@ -131,8 +111,8 @@ public class AddWorkspaceItemsTask extends BaseModelUpdateTask {
if (item instanceof WorkspaceItemInfo || item instanceof FolderInfo ||
item instanceof LauncherAppWidgetInfo) {
itemInfo = item;
- } else if (item instanceof WorkspaceItemFactory) {
- itemInfo = ((WorkspaceItemFactory) item).makeWorkspaceItem(app.getContext());
+ } else if (item instanceof AppInfo) {
+ itemInfo = ((AppInfo) item).makeWorkspaceItem();
} else {
throw new RuntimeException("Unexpected info type");
}
@@ -142,9 +122,6 @@ public class AddWorkspaceItemsTask extends BaseModelUpdateTask {
String packageName = item.getTargetComponent() != null
? item.getTargetComponent().getPackageName() : null;
if (packageName == null) {
- if (TestProtocol.sDebugTracing) {
- Log.d(TestProtocol.MISSING_PROMISE_ICON, LOG + " Null packageName.");
- }
continue;
}
SessionInfo sessionInfo = packageInstaller.getActiveSessionInfo(item.user,
@@ -153,9 +130,6 @@ public class AddWorkspaceItemsTask extends BaseModelUpdateTask {
if (!packageInstaller.verifySessionInfo(sessionInfo)) {
FileLog.d(LOG, "Item info failed session info verification. "
+ "Skipping : " + workspaceInfo);
- if (TestProtocol.sDebugTracing) {
- Log.d(TestProtocol.MISSING_PROMISE_ICON, LOG + "Failed verification.");
- }
continue;
}
@@ -166,9 +140,6 @@ public class AddWorkspaceItemsTask extends BaseModelUpdateTask {
if (sessionInfo == null) {
if (!hasActivity) {
// Session was cancelled, do not add.
- if (TestProtocol.sDebugTracing) {
- Log.d(TestProtocol.MISSING_PROMISE_ICON, LOG + "Session cancelled");
- }
continue;
}
} else {
@@ -181,16 +152,13 @@ public class AddWorkspaceItemsTask extends BaseModelUpdateTask {
// App was installed while launcher was in the background,
// or app was already installed for another user.
itemInfo = new AppInfo(app.getContext(), activities.get(0), item.user)
- .makeWorkspaceItem(app.getContext());
+ .makeWorkspaceItem();
if (shortcutExists(dataModel, itemInfo.getIntent(), itemInfo.user)) {
// We need this additional check here since we treat all auto added
// workspace items as promise icons. At this point we now have the
// correct intent to compare against existing workspace icons.
// Icon already exists on the workspace and should not be auto-added.
- if (TestProtocol.sDebugTracing) {
- Log.d(TestProtocol.MISSING_PROMISE_ICON, LOG + "shortcutExists");
- }
continue;
}
@@ -294,4 +262,87 @@ public class AddWorkspaceItemsTask extends BaseModelUpdateTask {
}
return false;
}
+
+ /**
+ * Find a position on the screen for the given size or adds a new screen.
+ * @return screenId and the coordinates for the item in an int array of size 3.
+ */
+ protected int[] findSpaceForItem( LauncherAppState app, BgDataModel dataModel,
+ IntArray workspaceScreens, IntArray addedWorkspaceScreensFinal, int spanX, int spanY) {
+ LongSparseArray<ArrayList<ItemInfo>> screenItems = new LongSparseArray<>();
+
+ // Use sBgItemsIdMap as all the items are already loaded.
+ synchronized (dataModel) {
+ for (ItemInfo info : dataModel.itemsIdMap) {
+ if (info.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {
+ ArrayList<ItemInfo> items = screenItems.get(info.screenId);
+ if (items == null) {
+ items = new ArrayList<>();
+ screenItems.put(info.screenId, items);
+ }
+ items.add(info);
+ }
+ }
+ }
+
+ // Find appropriate space for the item.
+ int screenId = 0;
+ int[] cordinates = new int[2];
+ boolean found = false;
+
+ int screenCount = workspaceScreens.size();
+ // First check the preferred screen.
+ int preferredScreenIndex = workspaceScreens.isEmpty() ? 0 : 1;
+ if (preferredScreenIndex < screenCount) {
+ screenId = workspaceScreens.get(preferredScreenIndex);
+ found = findNextAvailableIconSpaceInScreen(
+ app, screenItems.get(screenId), cordinates, spanX, spanY);
+ }
+
+ if (!found) {
+ // Search on any of the screens starting from the first screen.
+ for (int screen = 1; screen < screenCount; screen++) {
+ screenId = workspaceScreens.get(screen);
+ if (findNextAvailableIconSpaceInScreen(
+ app, screenItems.get(screenId), cordinates, spanX, spanY)) {
+ // We found a space for it
+ found = true;
+ break;
+ }
+ }
+ }
+
+ if (!found) {
+ // Still no position found. Add a new screen to the end.
+ screenId = LauncherSettings.Settings.call(app.getContext().getContentResolver(),
+ LauncherSettings.Settings.METHOD_NEW_SCREEN_ID)
+ .getInt(LauncherSettings.Settings.EXTRA_VALUE);
+
+ // Save the screen id for binding in the workspace
+ workspaceScreens.add(screenId);
+ addedWorkspaceScreensFinal.add(screenId);
+
+ // If we still can't find an empty space, then God help us all!!!
+ if (!findNextAvailableIconSpaceInScreen(
+ app, screenItems.get(screenId), cordinates, spanX, spanY)) {
+ throw new RuntimeException("Can't find space to add the item");
+ }
+ }
+ return new int[] {screenId, cordinates[0], cordinates[1]};
+ }
+
+ private boolean findNextAvailableIconSpaceInScreen(
+ LauncherAppState app, ArrayList<ItemInfo> occupiedPos,
+ int[] xy, int spanX, int spanY) {
+ InvariantDeviceProfile profile = app.getInvariantDeviceProfile();
+
+ GridOccupancy occupied = new GridOccupancy(profile.numColumns, profile.numRows);
+ if (occupiedPos != null) {
+ for (ItemInfo r : occupiedPos) {
+ occupied.markCells(r, true);
+ }
+ }
+ return occupied.findVacantCell(xy, spanX, spanY);
+ }
+
}
diff --git a/src/com/android/launcher3/model/AllAppsList.java b/src/com/android/launcher3/model/AllAppsList.java
index 4875d83942..92b5885e9e 100644
--- a/src/com/android/launcher3/model/AllAppsList.java
+++ b/src/com/android/launcher3/model/AllAppsList.java
@@ -36,9 +36,9 @@ import com.android.launcher3.compat.AlphabeticIndexCompat;
import com.android.launcher3.icons.IconCache;
import com.android.launcher3.model.BgDataModel.Callbacks;
import com.android.launcher3.model.data.AppInfo;
-import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.pm.PackageInstallInfo;
import com.android.launcher3.util.FlagOp;
+import com.android.launcher3.util.ItemInfoMatcher;
import com.android.launcher3.util.PackageManagerHelper;
import com.android.launcher3.util.SafeCloseable;
@@ -47,7 +47,6 @@ import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.function.Consumer;
-import java.util.function.Predicate;
/**
@@ -131,58 +130,30 @@ public class AllAppsList {
* If the app is already in the list, doesn't add it.
*/
public void add(AppInfo info, LauncherActivityInfo activityInfo) {
- add(info, activityInfo, true);
- }
-
- public void add(AppInfo info, LauncherActivityInfo activityInfo, boolean loadIcon) {
if (!mAppFilter.shouldShowApp(info.componentName)) {
return;
}
if (findAppInfo(info.componentName, info.user) != null) {
return;
}
- if (loadIcon) {
- mIconCache.getTitleAndIcon(info, activityInfo, false /* useLowResIcon */);
- info.sectionName = mIndex.computeSectionName(info.title);
- } else {
- info.title = "";
- }
+ mIconCache.getTitleAndIcon(info, activityInfo, false /* useLowResIcon */);
+ info.sectionName = mIndex.computeSectionName(info.title);
data.add(info);
mDataChanged = true;
}
- @Nullable
- public AppInfo addPromiseApp(Context context, PackageInstallInfo installInfo) {
- return addPromiseApp(context, installInfo, true);
- }
-
- @Nullable
- public AppInfo addPromiseApp(
- Context context, PackageInstallInfo installInfo, boolean loadIcon) {
+ public void addPromiseApp(Context context, PackageInstallInfo installInfo) {
// only if not yet installed
- if (new PackageManagerHelper(context)
+ if (!new PackageManagerHelper(context)
.isAppInstalled(installInfo.packageName, installInfo.user)) {
- return null;
- }
- AppInfo promiseAppInfo = new AppInfo(installInfo);
+ AppInfo info = new AppInfo(installInfo);
+ mIconCache.getTitleAndIcon(info, info.usingLowResIcon());
+ info.sectionName = mIndex.computeSectionName(info.title);
- if (loadIcon) {
- mIconCache.getTitleAndIcon(promiseAppInfo, promiseAppInfo.usingLowResIcon());
- promiseAppInfo.sectionName = mIndex.computeSectionName(promiseAppInfo.title);
- } else {
- promiseAppInfo.title = "";
+ data.add(info);
+ mDataChanged = true;
}
-
- data.add(promiseAppInfo);
- mDataChanged = true;
-
- return promiseAppInfo;
- }
-
- public void updateSectionName(AppInfo appInfo) {
- appInfo.sectionName = mIndex.computeSectionName(appInfo.title);
-
}
/** Updates the given PackageInstallInfo's associated AppInfo's installation info. */
@@ -258,11 +229,11 @@ public class AllAppsList {
/**
* Updates the disabled flags of apps matching {@param matcher} based on {@param op}.
*/
- public void updateDisabledFlags(Predicate<ItemInfo> matcher, FlagOp op) {
+ public void updateDisabledFlags(ItemInfoMatcher matcher, FlagOp op) {
final List<AppInfo> data = this.data;
for (int i = data.size() - 1; i >= 0; i--) {
AppInfo info = data.get(i);
- if (matcher.test(info)) {
+ if (matcher.matches(info, info.componentName)) {
info.runtimeStatusFlags = op.apply(info.runtimeStatusFlags);
mDataChanged = true;
}
diff --git a/src/com/android/launcher3/model/BaseLoaderResults.java b/src/com/android/launcher3/model/BaseLoaderResults.java
index b50ab587f4..5c85babb76 100644
--- a/src/com/android/launcher3/model/BaseLoaderResults.java
+++ b/src/com/android/launcher3/model/BaseLoaderResults.java
@@ -16,34 +16,28 @@
package com.android.launcher3.model;
-import static com.android.launcher3.model.ItemInstallQueue.FLAG_LOADER_RUNNING;
import static com.android.launcher3.model.ModelUtils.filterCurrentWorkspaceItems;
-import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
+import static com.android.launcher3.model.ModelUtils.sortWorkspaceItemsSpatially;
-import android.os.Process;
import android.util.Log;
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.LauncherModel.CallbackTask;
-import com.android.launcher3.LauncherSettings;
-import com.android.launcher3.config.FeatureFlags;
+import com.android.launcher3.PagedView;
import com.android.launcher3.model.BgDataModel.Callbacks;
import com.android.launcher3.model.BgDataModel.FixedContainerItems;
import com.android.launcher3.model.data.AppInfo;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.LauncherAppWidgetInfo;
-import com.android.launcher3.testing.TestProtocol;
import com.android.launcher3.util.IntArray;
-import com.android.launcher3.util.IntSet;
import com.android.launcher3.util.LooperExecutor;
import com.android.launcher3.util.LooperIdleLock;
-import com.android.launcher3.util.RunnableList;
+import com.android.launcher3.util.ViewOnDrawExecutor;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
-import java.util.Objects;
import java.util.concurrent.Executor;
/**
@@ -77,7 +71,7 @@ public abstract class BaseLoaderResults {
/**
* Binds all loaded data to actual views on the main thread.
*/
- public void bindWorkspace(boolean incrementBindId) {
+ public void bindWorkspace() {
// Save a copy of all the bg-thread collections
ArrayList<ItemInfo> workspaceItems = new ArrayList<>();
ArrayList<LauncherAppWidgetInfo> appWidgets = new ArrayList<>();
@@ -89,9 +83,7 @@ public abstract class BaseLoaderResults {
appWidgets.addAll(mBgDataModel.appWidgets);
orderedScreenIds.addAll(mBgDataModel.collectWorkspaceScreens());
mBgDataModel.extraItems.forEach(extraItems::add);
- if (incrementBindId) {
- mBgDataModel.lastBindId++;
- }
+ mBgDataModel.lastBindId++;
mMyBindingId = mBgDataModel.lastBindId;
}
@@ -112,42 +104,6 @@ public abstract class BaseLoaderResults {
public abstract void bindWidgets();
- /**
- * Sorts the set of items by hotseat, workspace (spatially from top to bottom, left to right)
- */
- protected void sortWorkspaceItemsSpatially(InvariantDeviceProfile profile,
- ArrayList<ItemInfo> workspaceItems) {
- final int screenCols = profile.numColumns;
- final int screenCellCount = profile.numColumns * profile.numRows;
- Collections.sort(workspaceItems, (lhs, rhs) -> {
- if (lhs.container == rhs.container) {
- // Within containers, order by their spatial position in that container
- switch (lhs.container) {
- case LauncherSettings.Favorites.CONTAINER_DESKTOP: {
- int lr = (lhs.screenId * screenCellCount + lhs.cellY * screenCols
- + lhs.cellX);
- int rr = (rhs.screenId * screenCellCount + +rhs.cellY * screenCols
- + rhs.cellX);
- return Integer.compare(lr, rr);
- }
- case LauncherSettings.Favorites.CONTAINER_HOTSEAT: {
- // We currently use the screen id as the rank
- return Integer.compare(lhs.screenId, rhs.screenId);
- }
- default:
- if (FeatureFlags.IS_STUDIO_BUILD) {
- throw new RuntimeException(
- "Unexpected container type when sorting workspace items.");
- }
- return 0;
- }
- } else {
- // Between containers, order by hotseat, desktop
- return Integer.compare(lhs.container, rhs.container);
- }
- });
- }
-
protected void executeCallbacksTask(CallbackTask task, Executor executor) {
executor.execute(() -> {
if (mMyBindingId != mBgDataModel.lastBindId) {
@@ -169,7 +125,7 @@ public abstract class BaseLoaderResults {
return idleLock;
}
- private class WorkspaceBinder {
+ private static class WorkspaceBinder {
private final Executor mUiExecutor;
private final Callbacks mCallbacks;
@@ -204,9 +160,20 @@ public abstract class BaseLoaderResults {
}
private void bind() {
- final IntSet currentScreenIds =
- mCallbacks.getPagesToBindSynchronously(mOrderedScreenIds);
- Objects.requireNonNull(currentScreenIds, "Null screen ids provided by " + mCallbacks);
+ final int currentScreen;
+ {
+ // Create an anonymous scope to calculate currentScreen as it has to be a
+ // final variable.
+ int currScreen = mCallbacks.getPageToBindSynchronously();
+ if (currScreen >= mOrderedScreenIds.size()) {
+ // There may be no workspace screens (just hotseat items and an empty page).
+ currScreen = PagedView.INVALID_PAGE;
+ }
+ currentScreen = currScreen;
+ }
+ final boolean validFirstPage = currentScreen >= 0;
+ final int currentScreenId =
+ validFirstPage ? mOrderedScreenIds.get(currentScreen) : INVALID_SCREEN_ID;
// Separate the items that are on the current screen, and all the other remaining items
ArrayList<ItemInfo> currentWorkspaceItems = new ArrayList<>();
@@ -214,21 +181,9 @@ public abstract class BaseLoaderResults {
ArrayList<LauncherAppWidgetInfo> currentAppWidgets = new ArrayList<>();
ArrayList<LauncherAppWidgetInfo> otherAppWidgets = new ArrayList<>();
- if (TestProtocol.sDebugTracing) {
- Log.d(TestProtocol.NULL_INT_SET, "bind (1) currentScreenIds: "
- + currentScreenIds
- + ", pointer: "
- + mCallbacks
- + ", name: "
- + mCallbacks.getClass().getName());
- }
- filterCurrentWorkspaceItems(currentScreenIds, mWorkspaceItems, currentWorkspaceItems,
+ filterCurrentWorkspaceItems(currentScreenId, mWorkspaceItems, currentWorkspaceItems,
otherWorkspaceItems);
- if (TestProtocol.sDebugTracing) {
- Log.d(TestProtocol.NULL_INT_SET, "bind (2) currentScreenIds: "
- + currentScreenIds);
- }
- filterCurrentWorkspaceItems(currentScreenIds, mAppWidgets, currentAppWidgets,
+ filterCurrentWorkspaceItems(currentScreenId, mAppWidgets, currentAppWidgets,
otherAppWidgets);
final InvariantDeviceProfile idp = mApp.getInvariantDeviceProfile();
sortWorkspaceItemsSpatially(idp, currentWorkspaceItems);
@@ -243,31 +198,40 @@ public abstract class BaseLoaderResults {
// Bind workspace screens
executeCallbacksTask(c -> c.bindScreens(mOrderedScreenIds), mUiExecutor);
+ Executor mainExecutor = mUiExecutor;
// Load items on the current page.
- bindWorkspaceItems(currentWorkspaceItems, mUiExecutor);
- bindAppWidgets(currentAppWidgets, mUiExecutor);
+ bindWorkspaceItems(currentWorkspaceItems, mainExecutor);
+ bindAppWidgets(currentAppWidgets, mainExecutor);
mExtraItems.forEach(item ->
- executeCallbacksTask(c -> c.bindExtraContainerItems(item), mUiExecutor));
-
- RunnableList pendingTasks = new RunnableList();
- Executor pendingExecutor = pendingTasks::add;
- bindWorkspaceItems(otherWorkspaceItems, pendingExecutor);
- bindAppWidgets(otherAppWidgets, pendingExecutor);
- executeCallbacksTask(c -> c.finishBindingItems(currentScreenIds), pendingExecutor);
- pendingExecutor.execute(
- () -> {
- MODEL_EXECUTOR.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
- ItemInstallQueue.INSTANCE.get(mApp.getContext())
- .resumeModelPush(FLAG_LOADER_RUNNING);
- });
-
- executeCallbacksTask(
- c -> {
- MODEL_EXECUTOR.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
- c.onInitialBindComplete(currentScreenIds, pendingTasks);
- }, mUiExecutor);
-
- mCallbacks.bindStringCache(mBgDataModel.stringCache.clone());
+ executeCallbacksTask(c -> c.bindExtraContainerItems(item), mainExecutor));
+
+ // In case of validFirstPage, only bind the first screen, and defer binding the
+ // remaining screens after first onDraw (and an optional the fade animation whichever
+ // happens later).
+ // This ensures that the first screen is immediately visible (eg. during rotation)
+ // In case of !validFirstPage, bind all pages one after other.
+
+ final Executor deferredExecutor =
+ validFirstPage ? new ViewOnDrawExecutor() : mainExecutor;
+
+ executeCallbacksTask(c -> c.finishFirstPageBind(
+ validFirstPage ? (ViewOnDrawExecutor) deferredExecutor : null), mainExecutor);
+
+ bindWorkspaceItems(otherWorkspaceItems, deferredExecutor);
+ bindAppWidgets(otherAppWidgets, deferredExecutor);
+ // Tell the workspace that we're done binding items
+ executeCallbacksTask(c -> c.finishBindingItems(currentScreen), deferredExecutor);
+
+ if (validFirstPage) {
+ executeCallbacksTask(c -> {
+ // We are loading synchronously, which means, some of the pages will be
+ // bound after first draw. Inform the mCallbacks that page binding is
+ // not complete, and schedule the remaining pages.
+ c.onPageBoundSynchronously(currentScreen);
+ c.executeOnNextDraw((ViewOnDrawExecutor) deferredExecutor);
+
+ }, mUiExecutor);
+ }
}
private void bindWorkspaceItems(
diff --git a/src/com/android/launcher3/model/BaseModelUpdateTask.java b/src/com/android/launcher3/model/BaseModelUpdateTask.java
index 2a6a6919e0..ad553d5e46 100644
--- a/src/com/android/launcher3/model/BaseModelUpdateTask.java
+++ b/src/com/android/launcher3/model/BaseModelUpdateTask.java
@@ -17,8 +17,6 @@ package com.android.launcher3.model;
import android.util.Log;
-import androidx.annotation.Nullable;
-
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.LauncherModel;
import com.android.launcher3.LauncherModel.CallbackTask;
@@ -29,6 +27,7 @@ import com.android.launcher3.model.data.AppInfo;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.launcher3.util.ComponentKey;
+import com.android.launcher3.util.ItemInfoMatcher;
import com.android.launcher3.widget.model.WidgetsListBaseEntry;
import java.util.ArrayList;
@@ -36,7 +35,6 @@ import java.util.HashMap;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.Executor;
-import java.util.function.Predicate;
import java.util.stream.Collectors;
/**
@@ -92,7 +90,7 @@ public abstract class BaseModelUpdateTask implements ModelUpdateTask {
public ModelWriter getModelWriter() {
// Updates from model task, do not deal with icon position in hotseat. Also no need to
// verify changes as the ModelTasks always push the changes to callbacks
- return mModel.getWriter(false /* hasVerticalHotseat */, false /* verifyChanges */, null);
+ return mModel.getWriter(false /* hasVerticalHotseat */, false /* verifyChanges */);
}
public void bindUpdatedWorkspaceItems(List<WorkspaceItemInfo> allUpdates) {
@@ -130,9 +128,8 @@ public abstract class BaseModelUpdateTask implements ModelUpdateTask {
scheduleCallbackTask(c -> c.bindAllWidgets(widgets));
}
- public void deleteAndBindComponentsRemoved(final Predicate<ItemInfo> matcher,
- @Nullable final String reason) {
- getModelWriter().deleteItemsFromDatabase(matcher, reason);
+ public void deleteAndBindComponentsRemoved(final ItemInfoMatcher matcher) {
+ getModelWriter().deleteItemsFromDatabase(matcher);
// Call the components-removed callback
scheduleCallbackTask(c -> c.bindWorkspaceComponentsRemoved(matcher));
diff --git a/src/com/android/launcher3/model/BgDataModel.java b/src/com/android/launcher3/model/BgDataModel.java
index de23c4b31f..1d7d1a2ba7 100644
--- a/src/com/android/launcher3/model/BgDataModel.java
+++ b/src/com/android/launcher3/model/BgDataModel.java
@@ -31,9 +31,6 @@ import android.text.TextUtils;
import android.util.ArraySet;
import android.util.Log;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
import com.android.launcher3.LauncherSettings;
import com.android.launcher3.LauncherSettings.Favorites;
import com.android.launcher3.Workspace;
@@ -51,7 +48,8 @@ import com.android.launcher3.util.ComponentKey;
import com.android.launcher3.util.IntArray;
import com.android.launcher3.util.IntSet;
import com.android.launcher3.util.IntSparseArrayMap;
-import com.android.launcher3.util.RunnableList;
+import com.android.launcher3.util.ItemInfoMatcher;
+import com.android.launcher3.util.ViewOnDrawExecutor;
import com.android.launcher3.widget.model.WidgetsListBaseEntry;
import java.io.FileDescriptor;
@@ -66,7 +64,6 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Consumer;
-import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -115,11 +112,6 @@ public class BgDataModel {
public final WidgetsModel widgetsModel = new WidgetsModel();
/**
- * Cache for strings used in launcher
- */
- public final StringCache stringCache = new StringCache();
-
- /**
* Id when the model was last bound
*/
public int lastBindId = 0;
@@ -223,18 +215,6 @@ public class BgDataModel {
}
public synchronized void addItem(Context context, ItemInfo item, boolean newItem) {
- addItem(context, item, newItem, null);
- }
-
- public synchronized void addItem(
- Context context, ItemInfo item, boolean newItem, @Nullable LoaderMemoryLogger logger) {
- if (logger != null) {
- logger.addLog(
- Log.DEBUG,
- TAG,
- String.format("Adding item to ID map: %s", item.toString()),
- /* stackTrace= */ null);
- }
itemsIdMap.put(item.id, item);
switch (item.itemType) {
case LauncherSettings.Favorites.ITEM_TYPE_FOLDER:
@@ -466,56 +446,37 @@ public class BgDataModel {
int FLAG_QUIET_MODE_CHANGE_PERMISSION = 1 << 2;
/**
- * Returns an IntSet of page ids to bind first, synchronously if possible
- * or an empty IntSet
- * @param orderedScreenIds All the page ids to be bound
- */
- @NonNull
- default IntSet getPagesToBindSynchronously(IntArray orderedScreenIds) {
- return new IntSet();
- }
-
- default void clearPendingBinds() { }
- default void startBinding() { }
-
- default void bindItems(List<ItemInfo> shortcuts, boolean forceAnimateIcons) { }
- default void bindScreens(IntArray orderedScreenIds) { }
- default void finishBindingItems(IntSet pagesBoundFirst) { }
- default void preAddApps() { }
- default void bindAppsAdded(IntArray newScreens,
- ArrayList<ItemInfo> addNotAnimated, ArrayList<ItemInfo> addAnimated) { }
-
- /**
- * Called when some persistent property of an item is modified
+ * Returns the page number to bind first, synchronously if possible or -1
*/
- default void bindItemsModified(List<ItemInfo> items) { }
+ int getPageToBindSynchronously();
+ void clearPendingBinds();
+ void startBinding();
+ void bindItems(List<ItemInfo> shortcuts, boolean forceAnimateIcons);
+ void bindScreens(IntArray orderedScreenIds);
+ void finishFirstPageBind(ViewOnDrawExecutor executor);
+ void finishBindingItems(int pageBoundFirst);
+ void preAddApps();
+ void bindAppsAdded(IntArray newScreens,
+ ArrayList<ItemInfo> addNotAnimated, ArrayList<ItemInfo> addAnimated);
/**
* Binds updated incremental download progress
*/
- default void bindIncrementalDownloadProgressUpdated(AppInfo app) { }
- default void bindWorkspaceItemsChanged(List<WorkspaceItemInfo> updated) { }
- default void bindWidgetsRestored(ArrayList<LauncherAppWidgetInfo> widgets) { }
- default void bindRestoreItemsChange(HashSet<ItemInfo> updates) { }
- default void bindWorkspaceComponentsRemoved(Predicate<ItemInfo> matcher) { }
- default void bindAllWidgets(List<WidgetsListBaseEntry> widgets) { }
-
- default void onInitialBindComplete(IntSet boundPages, RunnableList pendingTasks) {
- pendingTasks.executeAllAndDestroy();
- }
-
- default void bindDeepShortcutMap(HashMap<ComponentKey, Integer> deepShortcutMap) { }
+ void bindIncrementalDownloadProgressUpdated(AppInfo app);
+ void bindWorkspaceItemsChanged(List<WorkspaceItemInfo> updated);
+ void bindWidgetsRestored(ArrayList<LauncherAppWidgetInfo> widgets);
+ void bindRestoreItemsChange(HashSet<ItemInfo> updates);
+ void bindWorkspaceComponentsRemoved(ItemInfoMatcher matcher);
+ void bindAllWidgets(List<WidgetsListBaseEntry> widgets);
+ void onPageBoundSynchronously(int page);
+ void executeOnNextDraw(ViewOnDrawExecutor executor);
+ void bindDeepShortcutMap(HashMap<ComponentKey, Integer> deepShortcutMap);
/**
* Binds extra item provided any external source
*/
default void bindExtraContainerItems(FixedContainerItems item) { }
- default void bindAllApplications(AppInfo[] apps, int flags) { }
-
- /**
- * Binds the cache of string resources
- */
- default void bindStringCache(StringCache cache) { }
+ void bindAllApplications(AppInfo[] apps, int flags);
}
}
diff --git a/src/com/android/launcher3/model/DeviceGridState.java b/src/com/android/launcher3/model/DeviceGridState.java
deleted file mode 100644
index 35fcb789e7..0000000000
--- a/src/com/android/launcher3/model/DeviceGridState.java
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * Copyright (C) 2021 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.launcher3.model;
-
-import static com.android.launcher3.InvariantDeviceProfile.DeviceType;
-import static com.android.launcher3.InvariantDeviceProfile.TYPE_PHONE;
-import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_GRID_SIZE_2;
-import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_GRID_SIZE_3;
-import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_GRID_SIZE_4;
-import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_GRID_SIZE_5;
-import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_GRID_SIZE_6;
-
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.text.TextUtils;
-
-import com.android.launcher3.InvariantDeviceProfile;
-import com.android.launcher3.Utilities;
-import com.android.launcher3.logging.StatsLogManager.LauncherEvent;
-
-import java.util.Locale;
-import java.util.Objects;
-
-/**
- * Utility class representing persisted grid properties.
- */
-public class DeviceGridState implements Comparable<DeviceGridState> {
-
- public static final String KEY_WORKSPACE_SIZE = "migration_src_workspace_size";
- public static final String KEY_HOTSEAT_COUNT = "migration_src_hotseat_count";
- public static final String KEY_DEVICE_TYPE = "migration_src_device_type";
- public static final String KEY_DB_FILE = "migration_src_db_file";
-
- private final String mGridSizeString;
- private final int mNumHotseat;
- private final @DeviceType int mDeviceType;
- private final String mDbFile;
-
- public DeviceGridState(InvariantDeviceProfile idp) {
- mGridSizeString = String.format(Locale.ENGLISH, "%d,%d", idp.numColumns, idp.numRows);
- mNumHotseat = idp.numDatabaseHotseatIcons;
- mDeviceType = idp.deviceType;
- mDbFile = idp.dbFile;
- }
-
- public DeviceGridState(Context context) {
- SharedPreferences prefs = Utilities.getPrefs(context);
- mGridSizeString = prefs.getString(KEY_WORKSPACE_SIZE, "");
- mNumHotseat = prefs.getInt(KEY_HOTSEAT_COUNT, -1);
- mDeviceType = prefs.getInt(KEY_DEVICE_TYPE, TYPE_PHONE);
- mDbFile = prefs.getString(KEY_DB_FILE, "");
- }
-
- /**
- * Returns the device type for the grid
- */
- public @DeviceType int getDeviceType() {
- return mDeviceType;
- }
-
- /**
- * Returns the databaseFile for the grid.
- */
- public String getDbFile() {
- return mDbFile;
- }
-
- /**
- * Returns the number of hotseat icons.
- */
- public int getNumHotseat() {
- return mNumHotseat;
- }
-
- /**
- * Stores the device state to shared preferences
- */
- public void writeToPrefs(Context context) {
- Utilities.getPrefs(context).edit()
- .putString(KEY_WORKSPACE_SIZE, mGridSizeString)
- .putInt(KEY_HOTSEAT_COUNT, mNumHotseat)
- .putInt(KEY_DEVICE_TYPE, mDeviceType)
- .putString(KEY_DB_FILE, mDbFile)
- .apply();
- }
-
- /**
- * Returns the logging event corresponding to the grid state
- */
- public LauncherEvent getWorkspaceSizeEvent() {
- if (!TextUtils.isEmpty(mGridSizeString)) {
- switch (getColumns()) {
- case 6:
- return LAUNCHER_GRID_SIZE_6;
- case 5:
- return LAUNCHER_GRID_SIZE_5;
- case 4:
- return LAUNCHER_GRID_SIZE_4;
- case 3:
- return LAUNCHER_GRID_SIZE_3;
- case 2:
- return LAUNCHER_GRID_SIZE_2;
- }
- }
- return null;
- }
-
- @Override
- public String toString() {
- return "DeviceGridState{"
- + "mGridSizeString='" + mGridSizeString + '\''
- + ", mNumHotseat=" + mNumHotseat
- + ", mDeviceType=" + mDeviceType
- + ", mDbFile=" + mDbFile
- + '}';
- }
-
- /**
- * Returns true if the database from another DeviceGridState can be loaded into the current
- * DeviceGridState without migration, or false otherwise.
- */
- public boolean isCompatible(DeviceGridState other) {
- if (this == other) return true;
- if (other == null) return false;
- return mNumHotseat == other.mNumHotseat
- && Objects.equals(mGridSizeString, other.mGridSizeString);
- }
-
- public Integer getColumns() {
- return Integer.parseInt(String.valueOf(mGridSizeString.charAt(0)));
- }
-
- public Integer getRows() {
- return Integer.parseInt(String.valueOf(mGridSizeString.charAt(2)));
- }
-
- @Override
- public int compareTo(DeviceGridState other) {
- Integer size = getColumns() * getRows();
- Integer otherSize = other.getColumns() * other.getRows();
-
- return size.compareTo(otherSize);
- }
-
-}
diff --git a/src/com/android/launcher3/model/FirstScreenBroadcast.java b/src/com/android/launcher3/model/FirstScreenBroadcast.java
index 9e91b9d6e8..e391d37938 100644
--- a/src/com/android/launcher3/model/FirstScreenBroadcast.java
+++ b/src/com/android/launcher3/model/FirstScreenBroadcast.java
@@ -20,7 +20,6 @@ import static android.app.PendingIntent.FLAG_ONE_SHOT;
import static android.os.Process.myUserHandle;
import static com.android.launcher3.pm.InstallSessionHelper.getUserHandle;
-import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import static java.util.stream.Collectors.groupingBy;
import static java.util.stream.Collectors.mapping;
@@ -32,18 +31,13 @@ import android.content.pm.PackageInstaller.SessionInfo;
import android.os.UserHandle;
import android.util.Log;
-import androidx.annotation.AnyThread;
-import androidx.annotation.WorkerThread;
-
import com.android.launcher3.LauncherSettings;
import com.android.launcher3.model.data.FolderInfo;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.LauncherAppWidgetInfo;
-import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.launcher3.util.PackageUserKey;
import java.util.ArrayList;
-import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@@ -84,7 +78,6 @@ public class FirstScreenBroadcast {
* Sends a broadcast to all package installers that have items with active sessions on the users
* first screen.
*/
- @WorkerThread
public void sendBroadcasts(Context context, List<ItemInfo> firstScreenItems) {
UserHandle myUser = myUserHandle();
mSessionInfoForPackage
@@ -102,7 +95,6 @@ public class FirstScreenBroadcast {
* @param packages List of packages with active sessions for this package installer.
* @param firstScreenItems List of items on the first screen.
*/
- @WorkerThread
private void sendBroadcastToInstaller(Context context, String installerPackageName,
Set<String> packages, List<ItemInfo> firstScreenItems) {
Set<String> folderItems = new HashSet<>();
@@ -114,7 +106,7 @@ public class FirstScreenBroadcast {
if (info instanceof FolderInfo) {
FolderInfo folderInfo = (FolderInfo) info;
String folderItemInfoPackage;
- for (ItemInfo folderItemInfo : cloneOnMainThread(folderInfo.contents)) {
+ for (ItemInfo folderItemInfo : folderInfo.contents) {
folderItemInfoPackage = getPackageName(folderItemInfo);
if (folderItemInfoPackage != null
&& packages.contains(folderItemInfoPackage)) {
@@ -143,13 +135,6 @@ public class FirstScreenBroadcast {
printList(installerPackageName, "Widget item", widgetItems);
}
- if (folderItems.isEmpty()
- && workspaceItems.isEmpty()
- && hotseatItems.isEmpty()
- && widgetItems.isEmpty()) {
- // Avoid sending broadcast if there is nothing to send.
- return;
- }
context.sendBroadcast(new Intent(ACTION_FIRST_SCREEN_ACTIVE_INSTALLS)
.setPackage(installerPackageName)
.putStringArrayListExtra(FOLDER_ITEM_EXTRA, new ArrayList<>(folderItems))
@@ -178,17 +163,4 @@ public class FirstScreenBroadcast {
Log.d(TAG, packageInstaller + ":" + label + ":" + pkg);
}
}
-
- /**
- * Clone the provided list on UI thread. This is used for {@link FolderInfo#contents} which
- * is always modified on UI thread.
- */
- @AnyThread
- private static List<WorkspaceItemInfo> cloneOnMainThread(ArrayList<WorkspaceItemInfo> list) {
- try {
- return MAIN_EXECUTOR.submit(() -> new ArrayList(list)).get();
- } catch (Exception e) {
- return Collections.emptyList();
- }
- }
}
diff --git a/src/com/android/launcher3/model/GridBackupTable.java b/src/com/android/launcher3/model/GridBackupTable.java
index 51cbf4b770..acfc339268 100644
--- a/src/com/android/launcher3/model/GridBackupTable.java
+++ b/src/com/android/launcher3/model/GridBackupTable.java
@@ -23,12 +23,14 @@ import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
+import android.graphics.Point;
import android.os.Process;
import android.util.Log;
import androidx.annotation.IntDef;
import com.android.launcher3.LauncherSettings.Favorites;
+import com.android.launcher3.LauncherSettings.Settings;
import com.android.launcher3.pm.UserCache;
/**
@@ -83,6 +85,49 @@ public class GridBackupTable {
}
/**
+ * Create a backup from current workspace layout if one isn't created already (Note backup
+ * created this way is always sanitized). Otherwise restore from the backup instead.
+ */
+ public boolean backupOrRestoreAsNeeded() {
+ // Check if backup table exists
+ if (!tableExists(mDb, BACKUP_TABLE_NAME)) {
+ if (Settings.call(mContext.getContentResolver(), Settings.METHOD_WAS_EMPTY_DB_CREATED)
+ .getBoolean(Settings.EXTRA_VALUE, false)) {
+ // No need to copy if empty DB was created.
+ return false;
+ }
+ doBackup(UserCache.INSTANCE.get(mContext).getSerialNumberForUser(
+ Process.myUserHandle()), 0);
+ return false;
+ }
+ return restoreIfBackupExists(Favorites.TABLE_NAME);
+ }
+
+ public boolean restoreToPreviewIfBackupExists() {
+ if (!tableExists(mDb, BACKUP_TABLE_NAME)) {
+ return false;
+ }
+
+ return restoreIfBackupExists(Favorites.PREVIEW_TABLE_NAME);
+ }
+
+ private boolean restoreIfBackupExists(String toTableName) {
+ if (loadDBProperties() != STATE_SANITIZED) {
+ return false;
+ }
+ long userSerial = UserCache.INSTANCE.get(mContext).getSerialNumberForUser(
+ Process.myUserHandle());
+ copyTable(mDb, BACKUP_TABLE_NAME, toTableName, userSerial);
+ Log.d(TAG, "Backup table found");
+ return true;
+ }
+
+ public int getRestoreHotseatAndGridSize(Point outGridSize) {
+ outGridSize.set(mRestoredGridX, mRestoredGridY);
+ return mRestoredHotseatSize;
+ }
+
+ /**
* Creates a new table and populates with copy of Favorites.TABLE_NAME
*/
public void createCustomBackupTable(String tableName) {
diff --git a/src/com/android/launcher3/model/GridSizeMigrationTask.java b/src/com/android/launcher3/model/GridSizeMigrationTask.java
new file mode 100644
index 0000000000..7b3e509d52
--- /dev/null
+++ b/src/com/android/launcher3/model/GridSizeMigrationTask.java
@@ -0,0 +1,1098 @@
+package com.android.launcher3.model;
+
+import static com.android.launcher3.InvariantDeviceProfile.KEY_MIGRATION_SRC_HOTSEAT_COUNT;
+import static com.android.launcher3.InvariantDeviceProfile.KEY_MIGRATION_SRC_WORKSPACE_SIZE;
+import static com.android.launcher3.LauncherSettings.Settings.EXTRA_VALUE;
+import static com.android.launcher3.Utilities.getPointString;
+import static com.android.launcher3.Utilities.parsePoint;
+import static com.android.launcher3.provider.LauncherDbUtils.copyTable;
+
+import android.content.ComponentName;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.graphics.Point;
+import android.os.SystemClock;
+import android.util.Log;
+import android.util.SparseArray;
+
+import androidx.annotation.VisibleForTesting;
+
+import com.android.launcher3.InvariantDeviceProfile;
+import com.android.launcher3.LauncherAppState;
+import com.android.launcher3.LauncherSettings;
+import com.android.launcher3.LauncherSettings.Favorites;
+import com.android.launcher3.LauncherSettings.Settings;
+import com.android.launcher3.Utilities;
+import com.android.launcher3.Workspace;
+import com.android.launcher3.config.FeatureFlags;
+import com.android.launcher3.graphics.LauncherPreviewRenderer;
+import com.android.launcher3.model.data.ItemInfo;
+import com.android.launcher3.pm.InstallSessionHelper;
+import com.android.launcher3.provider.LauncherDbUtils;
+import com.android.launcher3.provider.LauncherDbUtils.SQLiteTransaction;
+import com.android.launcher3.util.GridOccupancy;
+import com.android.launcher3.util.IntArray;
+import com.android.launcher3.util.IntSparseArrayMap;
+import com.android.launcher3.widget.LauncherAppWidgetProviderInfo;
+import com.android.launcher3.widget.WidgetManagerHelper;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+
+/**
+ * This class takes care of shrinking the workspace (by maximum of one row and one column), as a
+ * result of restoring from a larger device or device density change.
+ */
+public class GridSizeMigrationTask {
+
+ private static final String TAG = "GridSizeMigrationTask";
+ private static final boolean DEBUG = false;
+
+ // These are carefully selected weights for various item types (Math.random?), to allow for
+ // the least absurd migration experience.
+ private static final float WT_SHORTCUT = 1;
+ private static final float WT_APPLICATION = 0.8f;
+ private static final float WT_WIDGET_MIN = 2;
+ private static final float WT_WIDGET_FACTOR = 0.6f;
+ private static final float WT_FOLDER_FACTOR = 0.5f;
+
+ protected final SQLiteDatabase mDb;
+ protected final Context mContext;
+
+ protected final IntArray mEntryToRemove = new IntArray();
+ protected final ArrayList<DbEntry> mCarryOver = new ArrayList<>();
+
+ private final SparseArray<ContentValues> mUpdateOperations = new SparseArray<>();
+ private final HashSet<String> mValidPackages;
+ private final String mTableName;
+
+ private final int mSrcX, mSrcY;
+ private final int mTrgX, mTrgY;
+ private final boolean mShouldRemoveX, mShouldRemoveY;
+
+ private final int mSrcHotseatSize;
+ private final int mDestHotseatSize;
+
+ protected GridSizeMigrationTask(Context context, SQLiteDatabase db,
+ HashSet<String> validPackages, boolean usePreviewTable, Point sourceSize,
+ Point targetSize) {
+ mContext = context;
+ mDb = db;
+ mValidPackages = validPackages;
+ mTableName = usePreviewTable ? Favorites.PREVIEW_TABLE_NAME : Favorites.TABLE_NAME;
+
+ mSrcX = sourceSize.x;
+ mSrcY = sourceSize.y;
+
+ mTrgX = targetSize.x;
+ mTrgY = targetSize.y;
+
+ mShouldRemoveX = mTrgX < mSrcX;
+ mShouldRemoveY = mTrgY < mSrcY;
+
+ // Non-used variables
+ mSrcHotseatSize = mDestHotseatSize = -1;
+ }
+
+ protected GridSizeMigrationTask(Context context, SQLiteDatabase db,
+ HashSet<String> validPackages, boolean usePreviewTable, int srcHotseatSize,
+ int destHotseatSize) {
+ mContext = context;
+ mDb = db;
+ mValidPackages = validPackages;
+ mTableName = usePreviewTable ? Favorites.PREVIEW_TABLE_NAME : Favorites.TABLE_NAME;
+
+ mSrcHotseatSize = srcHotseatSize;
+
+ mDestHotseatSize = destHotseatSize;
+
+ // Non-used variables
+ mSrcX = mSrcY = mTrgX = mTrgY = -1;
+ mShouldRemoveX = mShouldRemoveY = false;
+ }
+
+ /**
+ * Applied all the pending DB operations
+ *
+ * @return true if any DB operation was commited.
+ */
+ private boolean applyOperations() throws Exception {
+ // Update items
+ int updateCount = mUpdateOperations.size();
+ for (int i = 0; i < updateCount; i++) {
+ mDb.update(mTableName, mUpdateOperations.valueAt(i),
+ "_id=" + mUpdateOperations.keyAt(i), null);
+ }
+
+ if (!mEntryToRemove.isEmpty()) {
+ if (DEBUG) {
+ Log.d(TAG, "Removing items: " + mEntryToRemove.toConcatString());
+ }
+ mDb.delete(mTableName, Utilities.createDbSelectionQuery(Favorites._ID, mEntryToRemove),
+ null);
+ }
+
+ return updateCount > 0 || !mEntryToRemove.isEmpty();
+ }
+
+ /**
+ * To migrate hotseat, we load all the entries in order (LTR or RTL) and arrange them
+ * in the order in the new hotseat while keeping an empty space for all-apps. If the number of
+ * entries is more than what can fit in the new hotseat, we drop the entries with least weight.
+ * For weight calculation {@see #WT_SHORTCUT}, {@see #WT_APPLICATION}
+ * & {@see #WT_FOLDER_FACTOR}.
+ *
+ * @return true if any DB change was made
+ */
+ protected boolean migrateHotseat() throws Exception {
+ ArrayList<DbEntry> items = loadHotseatEntries();
+ while (items.size() > mDestHotseatSize) {
+ // Pick the center item by default.
+ DbEntry toRemove = items.get(items.size() / 2);
+
+ // Find the item with least weight.
+ for (DbEntry entry : items) {
+ if (entry.weight < toRemove.weight) {
+ toRemove = entry;
+ }
+ }
+
+ mEntryToRemove.add(toRemove.id);
+ items.remove(toRemove);
+ }
+
+ // Update screen IDS
+ int newScreenId = 0;
+ for (DbEntry entry : items) {
+ if (entry.screenId != newScreenId) {
+ entry.screenId = newScreenId;
+
+ // These values does not affect the item position, but we should set them
+ // to something other than -1.
+ entry.cellX = newScreenId;
+ entry.cellY = 0;
+
+ update(entry);
+ }
+
+ newScreenId++;
+ }
+
+ return applyOperations();
+ }
+
+ @VisibleForTesting
+ static IntArray getWorkspaceScreenIds(SQLiteDatabase db, String tableName) {
+ return LauncherDbUtils.queryIntArray(db, tableName, Favorites.SCREEN,
+ Favorites.CONTAINER + " = " + Favorites.CONTAINER_DESKTOP,
+ Favorites.SCREEN, Favorites.SCREEN);
+ }
+
+ /**
+ * @return true if any DB change was made
+ */
+ protected boolean migrateWorkspace() throws Exception {
+ IntArray allScreens = getWorkspaceScreenIds(mDb, mTableName);
+ if (allScreens.isEmpty()) {
+ throw new Exception("Unable to get workspace screens");
+ }
+
+ for (int i = 0; i < allScreens.size(); i++) {
+ int screenId = allScreens.get(i);
+ if (DEBUG) {
+ Log.d(TAG, "Migrating " + screenId);
+ }
+ migrateScreen(screenId);
+ }
+
+ if (!mCarryOver.isEmpty()) {
+ IntSparseArrayMap<DbEntry> itemMap = new IntSparseArrayMap<>();
+ for (DbEntry e : mCarryOver) {
+ itemMap.put(e.id, e);
+ }
+
+ do {
+ // Some items are still remaining. Try adding a few new screens.
+
+ // At every iteration, make sure that at least one item is removed from
+ // {@link #mCarryOver}, to prevent an infinite loop. If no item could be removed,
+ // break the loop and abort migration by throwing an exception.
+ OptimalPlacementSolution placement = new OptimalPlacementSolution(
+ new GridOccupancy(mTrgX, mTrgY), deepCopy(mCarryOver), 0, true);
+ placement.find();
+ if (placement.finalPlacedItems.size() > 0) {
+ int newScreenId = LauncherSettings.Settings.call(
+ mContext.getContentResolver(),
+ LauncherSettings.Settings.METHOD_NEW_SCREEN_ID)
+ .getInt(EXTRA_VALUE);
+ for (DbEntry item : placement.finalPlacedItems) {
+ if (!mCarryOver.remove(itemMap.get(item.id))) {
+ throw new Exception("Unable to find matching items");
+ }
+ item.screenId = newScreenId;
+ update(item);
+ }
+ } else {
+ throw new Exception("None of the items can be placed on an empty screen");
+ }
+
+ } while (!mCarryOver.isEmpty());
+ }
+ return applyOperations();
+ }
+
+ /**
+ * Migrate a particular screen id.
+ * Strategy:
+ * 1) For all possible combinations of row and column, pick the one which causes the least
+ * data loss: {@link #tryRemove(int, int, int, ArrayList, float[])}
+ * 2) Maintain a list of all lost items before this screen, and add any new item lost from
+ * this screen to that list as well.
+ * 3) If all those items from the above list can be placed on this screen, place them
+ * (otherwise they are placed on a new screen).
+ */
+ protected void migrateScreen(int screenId) {
+ // If we are migrating the first screen, do not touch the first row.
+ int startY = (FeatureFlags.QSB_ON_FIRST_SCREEN && screenId == Workspace.FIRST_SCREEN_ID)
+ ? 1 : 0;
+
+ ArrayList<DbEntry> items = loadWorkspaceEntries(screenId);
+
+ int removedCol = Integer.MAX_VALUE;
+ int removedRow = Integer.MAX_VALUE;
+
+ // removeWt represents the cost function for loss of items during migration, and moveWt
+ // represents the cost function for repositioning the items. moveWt is only considered if
+ // removeWt is same for two different configurations.
+ // Start with Float.MAX_VALUE (assuming full data) and pick the configuration with least
+ // cost.
+ float removeWt = Float.MAX_VALUE;
+ float moveWt = Float.MAX_VALUE;
+ float[] outLoss = new float[2];
+ ArrayList<DbEntry> finalItems = null;
+
+ // Try removing all possible combinations
+ for (int x = 0; x < mSrcX; x++) {
+ // Try removing the rows first from bottom. This keeps the workspace
+ // nicely aligned with hotseat.
+ for (int y = mSrcY - 1; y >= startY; y--) {
+ // Use a deep copy when trying out a particular combination as it can change
+ // the underlying object.
+ ArrayList<DbEntry> itemsOnScreen = tryRemove(x, y, startY, deepCopy(items),
+ outLoss);
+
+ if ((outLoss[0] < removeWt) || ((outLoss[0] == removeWt) && (outLoss[1]
+ < moveWt))) {
+ removeWt = outLoss[0];
+ moveWt = outLoss[1];
+ removedCol = mShouldRemoveX ? x : removedCol;
+ removedRow = mShouldRemoveY ? y : removedRow;
+ finalItems = itemsOnScreen;
+ }
+
+ // No need to loop over all rows, if a row removal is not needed.
+ if (!mShouldRemoveY) {
+ break;
+ }
+ }
+
+ if (!mShouldRemoveX) {
+ break;
+ }
+ }
+
+ if (DEBUG) {
+ Log.d(TAG, String.format("Removing row %d, column %d on screen %d",
+ removedRow, removedCol, screenId));
+ }
+
+ IntSparseArrayMap<DbEntry> itemMap = new IntSparseArrayMap<>();
+ for (DbEntry e : deepCopy(items)) {
+ itemMap.put(e.id, e);
+ }
+
+ for (DbEntry item : finalItems) {
+ DbEntry org = itemMap.get(item.id);
+ itemMap.remove(item.id);
+
+ // Check if update is required
+ if (!item.columnsSame(org)) {
+ update(item);
+ }
+ }
+
+ // The remaining items in {@link #itemMap} are those which didn't get placed.
+ for (DbEntry item : itemMap) {
+ mCarryOver.add(item);
+ }
+
+ if (!mCarryOver.isEmpty() && removeWt == 0) {
+ // No new items were removed in this step. Try placing all the items on this screen.
+ GridOccupancy occupied = new GridOccupancy(mTrgX, mTrgY);
+ occupied.markCells(0, 0, mTrgX, startY, true);
+ for (DbEntry item : finalItems) {
+ occupied.markCells(item, true);
+ }
+
+ OptimalPlacementSolution placement = new OptimalPlacementSolution(occupied,
+ deepCopy(mCarryOver), startY, true);
+ placement.find();
+ if (placement.lowestWeightLoss == 0) {
+ // All items got placed
+
+ for (DbEntry item : placement.finalPlacedItems) {
+ item.screenId = screenId;
+ update(item);
+ }
+
+ mCarryOver.clear();
+ }
+ }
+ }
+
+ /**
+ * Updates an item in the DB.
+ */
+ protected void update(DbEntry item) {
+ ContentValues values = new ContentValues();
+ item.addToContentValues(values);
+ mUpdateOperations.put(item.id, values);
+ }
+
+ /**
+ * Tries the remove the provided row and column.
+ *
+ * @param items all the items on the screen under operation
+ * @param outLoss array of size 2. The first entry is filled with weight loss, and the second
+ * with the overall item movement.
+ */
+ private ArrayList<DbEntry> tryRemove(int col, int row, int startY,
+ ArrayList<DbEntry> items, float[] outLoss) {
+ GridOccupancy occupied = new GridOccupancy(mTrgX, mTrgY);
+ occupied.markCells(0, 0, mTrgX, startY, true);
+
+ col = mShouldRemoveX ? col : Integer.MAX_VALUE;
+ row = mShouldRemoveY ? row : Integer.MAX_VALUE;
+
+ ArrayList<DbEntry> finalItems = new ArrayList<>();
+ ArrayList<DbEntry> removedItems = new ArrayList<>();
+
+ for (DbEntry item : items) {
+ if ((item.cellX <= col && (item.spanX + item.cellX) > col)
+ || (item.cellY <= row && (item.spanY + item.cellY) > row)) {
+ removedItems.add(item);
+ if (item.cellX >= col) item.cellX--;
+ if (item.cellY >= row) item.cellY--;
+ } else {
+ if (item.cellX > col) item.cellX--;
+ if (item.cellY > row) item.cellY--;
+ finalItems.add(item);
+ occupied.markCells(item, true);
+ }
+ }
+
+ OptimalPlacementSolution placement =
+ new OptimalPlacementSolution(occupied, removedItems, startY);
+ placement.find();
+ finalItems.addAll(placement.finalPlacedItems);
+ outLoss[0] = placement.lowestWeightLoss;
+ outLoss[1] = placement.lowestMoveCost;
+ return finalItems;
+ }
+
+ private class OptimalPlacementSolution {
+ private final ArrayList<DbEntry> itemsToPlace;
+ private final GridOccupancy occupied;
+
+ // If set to true, item movement are not considered in move cost, leading to a more
+ // linear placement.
+ private final boolean ignoreMove;
+
+ // The first row in the grid from where the placement should start.
+ private final int startY;
+
+ float lowestWeightLoss = Float.MAX_VALUE;
+ float lowestMoveCost = Float.MAX_VALUE;
+ ArrayList<DbEntry> finalPlacedItems;
+
+ public OptimalPlacementSolution(
+ GridOccupancy occupied, ArrayList<DbEntry> itemsToPlace, int startY) {
+ this(occupied, itemsToPlace, startY, false);
+ }
+
+ public OptimalPlacementSolution(GridOccupancy occupied, ArrayList<DbEntry> itemsToPlace,
+ int startY, boolean ignoreMove) {
+ this.occupied = occupied;
+ this.itemsToPlace = itemsToPlace;
+ this.ignoreMove = ignoreMove;
+ this.startY = startY;
+
+ // Sort the items such that larger widgets appear first followed by 1x1 items
+ Collections.sort(this.itemsToPlace);
+ }
+
+ public void find() {
+ find(0, 0, 0, new ArrayList<DbEntry>());
+ }
+
+ /**
+ * Recursively finds a placement for the provided items.
+ *
+ * @param index the position in {@link #itemsToPlace} to start looking at.
+ * @param weightLoss total weight loss upto this point
+ * @param moveCost total move cost upto this point
+ * @param itemsPlaced all the items already placed upto this point
+ */
+ public void find(int index, float weightLoss, float moveCost,
+ ArrayList<DbEntry> itemsPlaced) {
+ if ((weightLoss >= lowestWeightLoss) ||
+ ((weightLoss == lowestWeightLoss) && (moveCost >= lowestMoveCost))) {
+ // Abort, as we already have a better solution.
+ return;
+
+ } else if (index >= itemsToPlace.size()) {
+ // End loop.
+ lowestWeightLoss = weightLoss;
+ lowestMoveCost = moveCost;
+
+ // Keep a deep copy of current configuration as it can change during recursion.
+ finalPlacedItems = deepCopy(itemsPlaced);
+ return;
+ }
+
+ DbEntry me = itemsToPlace.get(index);
+ int myX = me.cellX;
+ int myY = me.cellY;
+
+ // List of items to pass over if this item was placed.
+ ArrayList<DbEntry> itemsIncludingMe = new ArrayList<>(itemsPlaced.size() + 1);
+ itemsIncludingMe.addAll(itemsPlaced);
+ itemsIncludingMe.add(me);
+
+ if (me.spanX > 1 || me.spanY > 1) {
+ // If the current item is a widget (and it greater than 1x1), try to place it at
+ // all possible positions. This is because a widget placed at one position can
+ // affect the placement of a different widget.
+ int myW = me.spanX;
+ int myH = me.spanY;
+
+ for (int y = startY; y < mTrgY; y++) {
+ for (int x = 0; x < mTrgX; x++) {
+ float newMoveCost = moveCost;
+ if (x != myX) {
+ me.cellX = x;
+ newMoveCost++;
+ }
+ if (y != myY) {
+ me.cellY = y;
+ newMoveCost++;
+ }
+ if (ignoreMove) {
+ newMoveCost = moveCost;
+ }
+
+ if (occupied.isRegionVacant(x, y, myW, myH)) {
+ // place at this position and continue search.
+ occupied.markCells(me, true);
+ find(index + 1, weightLoss, newMoveCost, itemsIncludingMe);
+ occupied.markCells(me, false);
+ }
+
+ // Try resizing horizontally
+ if (myW > me.minSpanX && occupied.isRegionVacant(x, y, myW - 1, myH)) {
+ me.spanX--;
+ occupied.markCells(me, true);
+ // 1 extra move cost
+ find(index + 1, weightLoss, newMoveCost + 1, itemsIncludingMe);
+ occupied.markCells(me, false);
+ me.spanX++;
+ }
+
+ // Try resizing vertically
+ if (myH > me.minSpanY && occupied.isRegionVacant(x, y, myW, myH - 1)) {
+ me.spanY--;
+ occupied.markCells(me, true);
+ // 1 extra move cost
+ find(index + 1, weightLoss, newMoveCost + 1, itemsIncludingMe);
+ occupied.markCells(me, false);
+ me.spanY++;
+ }
+
+ // Try resizing horizontally & vertically
+ if (myH > me.minSpanY && myW > me.minSpanX &&
+ occupied.isRegionVacant(x, y, myW - 1, myH - 1)) {
+ me.spanX--;
+ me.spanY--;
+ occupied.markCells(me, true);
+ // 2 extra move cost
+ find(index + 1, weightLoss, newMoveCost + 2, itemsIncludingMe);
+ occupied.markCells(me, false);
+ me.spanX++;
+ me.spanY++;
+ }
+ me.cellX = myX;
+ me.cellY = myY;
+ }
+ }
+
+ // Finally also try a solution when this item is not included. Trying it in the end
+ // causes it to get skipped in most cases due to higher weight loss, and prevents
+ // unnecessary deep copies of various configurations.
+ find(index + 1, weightLoss + me.weight, moveCost, itemsPlaced);
+ } else {
+ // Since this is a 1x1 item and all the following items are also 1x1, just place
+ // it at 'the most appropriate position' and hope for the best.
+ // The most appropriate position: one with lease straight line distance
+ int newDistance = Integer.MAX_VALUE;
+ int newX = Integer.MAX_VALUE, newY = Integer.MAX_VALUE;
+
+ for (int y = startY; y < mTrgY; y++) {
+ for (int x = 0; x < mTrgX; x++) {
+ if (!occupied.cells[x][y]) {
+ int dist = ignoreMove ? 0 :
+ ((me.cellX - x) * (me.cellX - x) + (me.cellY - y) * (me.cellY
+ - y));
+ if (dist < newDistance) {
+ newX = x;
+ newY = y;
+ newDistance = dist;
+ }
+ }
+ }
+ }
+
+ if (newX < mTrgX && newY < mTrgY) {
+ float newMoveCost = moveCost;
+ if (newX != myX) {
+ me.cellX = newX;
+ newMoveCost++;
+ }
+ if (newY != myY) {
+ me.cellY = newY;
+ newMoveCost++;
+ }
+ if (ignoreMove) {
+ newMoveCost = moveCost;
+ }
+ occupied.markCells(me, true);
+ find(index + 1, weightLoss, newMoveCost, itemsIncludingMe);
+ occupied.markCells(me, false);
+ me.cellX = myX;
+ me.cellY = myY;
+
+ // Try to find a solution without this item, only if
+ // 1) there was at least one space, i.e., we were able to place this item
+ // 2) if the next item has the same weight (all items are already sorted), as
+ // if it has lower weight, that solution will automatically get discarded.
+ // 3) ignoreMove false otherwise, move cost is ignored and the weight will
+ // anyway be same.
+ if (index + 1 < itemsToPlace.size()
+ && itemsToPlace.get(index + 1).weight >= me.weight && !ignoreMove) {
+ find(index + 1, weightLoss + me.weight, moveCost, itemsPlaced);
+ }
+ } else {
+ // No more space. Jump to the end.
+ for (int i = index + 1; i < itemsToPlace.size(); i++) {
+ weightLoss += itemsToPlace.get(i).weight;
+ }
+ find(itemsToPlace.size(), weightLoss + me.weight, moveCost, itemsPlaced);
+ }
+ }
+ }
+ }
+
+ private ArrayList<DbEntry> loadHotseatEntries() {
+ Cursor c = queryWorkspace(
+ new String[]{
+ Favorites._ID, // 0
+ Favorites.ITEM_TYPE, // 1
+ Favorites.INTENT, // 2
+ Favorites.SCREEN}, // 3
+ Favorites.CONTAINER + " = " + Favorites.CONTAINER_HOTSEAT);
+
+ final int indexId = c.getColumnIndexOrThrow(Favorites._ID);
+ final int indexItemType = c.getColumnIndexOrThrow(Favorites.ITEM_TYPE);
+ final int indexIntent = c.getColumnIndexOrThrow(Favorites.INTENT);
+ final int indexScreen = c.getColumnIndexOrThrow(Favorites.SCREEN);
+
+ ArrayList<DbEntry> entries = new ArrayList<>();
+ while (c.moveToNext()) {
+ DbEntry entry = new DbEntry();
+ entry.id = c.getInt(indexId);
+ entry.itemType = c.getInt(indexItemType);
+ entry.screenId = c.getInt(indexScreen);
+
+ if (entry.screenId >= mSrcHotseatSize) {
+ mEntryToRemove.add(entry.id);
+ continue;
+ }
+
+ try {
+ // calculate weight
+ switch (entry.itemType) {
+ case Favorites.ITEM_TYPE_SHORTCUT:
+ case Favorites.ITEM_TYPE_DEEP_SHORTCUT:
+ case Favorites.ITEM_TYPE_APPLICATION: {
+ verifyIntent(c.getString(indexIntent));
+ entry.weight = entry.itemType == Favorites.ITEM_TYPE_APPLICATION ?
+ WT_APPLICATION : WT_SHORTCUT;
+ break;
+ }
+ case Favorites.ITEM_TYPE_FOLDER: {
+ int total = getFolderItemsCount(entry.id);
+ if (total == 0) {
+ throw new Exception("Folder is empty");
+ }
+ entry.weight = WT_FOLDER_FACTOR * total;
+ break;
+ }
+ default:
+ throw new Exception("Invalid item type");
+ }
+ } catch (Exception e) {
+ if (DEBUG) {
+ Log.d(TAG, "Removing item " + entry.id, e);
+ }
+ mEntryToRemove.add(entry.id);
+ continue;
+ }
+ entries.add(entry);
+ }
+ c.close();
+ return entries;
+ }
+
+
+ /**
+ * Loads entries for a particular screen id.
+ */
+ protected ArrayList<DbEntry> loadWorkspaceEntries(int screen) {
+ Cursor c = queryWorkspace(
+ new String[]{
+ Favorites._ID, // 0
+ Favorites.ITEM_TYPE, // 1
+ Favorites.CELLX, // 2
+ Favorites.CELLY, // 3
+ Favorites.SPANX, // 4
+ Favorites.SPANY, // 5
+ Favorites.INTENT, // 6
+ Favorites.APPWIDGET_PROVIDER, // 7
+ Favorites.APPWIDGET_ID}, // 8
+ Favorites.CONTAINER + " = " + Favorites.CONTAINER_DESKTOP
+ + " AND " + Favorites.SCREEN + " = " + screen);
+
+ final int indexId = c.getColumnIndexOrThrow(Favorites._ID);
+ final int indexItemType = c.getColumnIndexOrThrow(Favorites.ITEM_TYPE);
+ final int indexCellX = c.getColumnIndexOrThrow(Favorites.CELLX);
+ final int indexCellY = c.getColumnIndexOrThrow(Favorites.CELLY);
+ final int indexSpanX = c.getColumnIndexOrThrow(Favorites.SPANX);
+ final int indexSpanY = c.getColumnIndexOrThrow(Favorites.SPANY);
+ final int indexIntent = c.getColumnIndexOrThrow(Favorites.INTENT);
+ final int indexAppWidgetProvider = c.getColumnIndexOrThrow(Favorites.APPWIDGET_PROVIDER);
+ final int indexAppWidgetId = c.getColumnIndexOrThrow(Favorites.APPWIDGET_ID);
+
+ ArrayList<DbEntry> entries = new ArrayList<>();
+ WidgetManagerHelper widgetManagerHelper = new WidgetManagerHelper(mContext);
+ while (c.moveToNext()) {
+ DbEntry entry = new DbEntry();
+ entry.id = c.getInt(indexId);
+ entry.itemType = c.getInt(indexItemType);
+ entry.cellX = c.getInt(indexCellX);
+ entry.cellY = c.getInt(indexCellY);
+ entry.spanX = c.getInt(indexSpanX);
+ entry.spanY = c.getInt(indexSpanY);
+ entry.screenId = screen;
+
+ try {
+ // calculate weight
+ switch (entry.itemType) {
+ case Favorites.ITEM_TYPE_SHORTCUT:
+ case Favorites.ITEM_TYPE_DEEP_SHORTCUT:
+ case Favorites.ITEM_TYPE_APPLICATION: {
+ verifyIntent(c.getString(indexIntent));
+ entry.weight = entry.itemType == Favorites.ITEM_TYPE_APPLICATION ?
+ WT_APPLICATION : WT_SHORTCUT;
+ break;
+ }
+ case Favorites.ITEM_TYPE_APPWIDGET: {
+ String provider = c.getString(indexAppWidgetProvider);
+ ComponentName cn = ComponentName.unflattenFromString(provider);
+ verifyPackage(cn.getPackageName());
+ entry.weight = Math.max(WT_WIDGET_MIN, WT_WIDGET_FACTOR
+ * entry.spanX * entry.spanY);
+
+ int widgetId = c.getInt(indexAppWidgetId);
+ LauncherAppWidgetProviderInfo pInfo =
+ widgetManagerHelper.getLauncherAppWidgetInfo(widgetId);
+ Point spans = null;
+ if (pInfo != null) {
+ spans = pInfo.getMinSpans();
+ }
+ if (spans != null) {
+ entry.minSpanX = spans.x > 0 ? spans.x : entry.spanX;
+ entry.minSpanY = spans.y > 0 ? spans.y : entry.spanY;
+ } else {
+ // Assume that the widget be resized down to 2x2
+ entry.minSpanX = entry.minSpanY = 2;
+ }
+
+ if (entry.minSpanX > mTrgX || entry.minSpanY > mTrgY) {
+ throw new Exception("Widget can't be resized down to fit the grid");
+ }
+ break;
+ }
+ case Favorites.ITEM_TYPE_FOLDER: {
+ int total = getFolderItemsCount(entry.id);
+ if (total == 0) {
+ throw new Exception("Folder is empty");
+ }
+ entry.weight = WT_FOLDER_FACTOR * total;
+ break;
+ }
+ default:
+ throw new Exception("Invalid item type");
+ }
+ } catch (Exception e) {
+ if (DEBUG) {
+ Log.d(TAG, "Removing item " + entry.id, e);
+ }
+ mEntryToRemove.add(entry.id);
+ continue;
+ }
+ entries.add(entry);
+ }
+ c.close();
+ return entries;
+ }
+
+ /**
+ * @return the number of valid items in the folder.
+ */
+ private int getFolderItemsCount(int folderId) {
+ Cursor c = queryWorkspace(
+ new String[]{Favorites._ID, Favorites.INTENT},
+ Favorites.CONTAINER + " = " + folderId);
+
+ int total = 0;
+ while (c.moveToNext()) {
+ try {
+ verifyIntent(c.getString(1));
+ total++;
+ } catch (Exception e) {
+ mEntryToRemove.add(c.getInt(0));
+ }
+ }
+ c.close();
+ return total;
+ }
+
+ protected Cursor queryWorkspace(String[] columns, String where) {
+ return mDb.query(mTableName, columns, where, null, null, null, null);
+ }
+
+ /**
+ * Verifies if the intent should be restored.
+ */
+ private void verifyIntent(String intentStr) throws Exception {
+ Intent intent = Intent.parseUri(intentStr, 0);
+ if (intent.getComponent() != null) {
+ verifyPackage(intent.getComponent().getPackageName());
+ } else if (intent.getPackage() != null) {
+ // Only verify package if the component was null.
+ verifyPackage(intent.getPackage());
+ }
+ }
+
+ /**
+ * Verifies if the package should be restored
+ */
+ private void verifyPackage(String packageName) throws Exception {
+ if (!mValidPackages.contains(packageName)) {
+ throw new Exception("Package not available");
+ }
+ }
+
+ protected static class DbEntry extends ItemInfo implements Comparable<DbEntry> {
+
+ public float weight;
+
+ public DbEntry() {
+ }
+
+ public DbEntry copy() {
+ DbEntry entry = new DbEntry();
+ entry.copyFrom(this);
+ entry.weight = weight;
+ entry.minSpanX = minSpanX;
+ entry.minSpanY = minSpanY;
+ return entry;
+ }
+
+ /**
+ * Comparator such that larger widgets come first, followed by all 1x1 items
+ * based on their weights.
+ */
+ @Override
+ public int compareTo(DbEntry another) {
+ if (itemType == Favorites.ITEM_TYPE_APPWIDGET) {
+ if (another.itemType == Favorites.ITEM_TYPE_APPWIDGET) {
+ return another.spanY * another.spanX - spanX * spanY;
+ } else {
+ return -1;
+ }
+ } else if (another.itemType == Favorites.ITEM_TYPE_APPWIDGET) {
+ return 1;
+ } else {
+ // Place higher weight before lower weight.
+ return Float.compare(another.weight, weight);
+ }
+ }
+
+ public boolean columnsSame(DbEntry org) {
+ return org.cellX == cellX && org.cellY == cellY && org.spanX == spanX &&
+ org.spanY == spanY && org.screenId == screenId;
+ }
+
+ public void addToContentValues(ContentValues values) {
+ values.put(Favorites.SCREEN, screenId);
+ values.put(Favorites.CELLX, cellX);
+ values.put(Favorites.CELLY, cellY);
+ values.put(Favorites.SPANX, spanX);
+ values.put(Favorites.SPANY, spanY);
+ }
+ }
+
+ private static ArrayList<DbEntry> deepCopy(ArrayList<DbEntry> src) {
+ ArrayList<DbEntry> dup = new ArrayList<>(src.size());
+ for (DbEntry e : src) {
+ dup.add(e.copy());
+ }
+ return dup;
+ }
+
+ public static void markForMigration(
+ Context context, int gridX, int gridY, int hotseatSize) {
+ Utilities.getPrefs(context).edit()
+ .putString(KEY_MIGRATION_SRC_WORKSPACE_SIZE, getPointString(gridX, gridY))
+ .putInt(KEY_MIGRATION_SRC_HOTSEAT_COUNT, hotseatSize)
+ .apply();
+ }
+
+ /**
+ * Check given a new IDP, if migration is necessary.
+ */
+ public static boolean needsToMigrate(Context context, InvariantDeviceProfile idp) {
+ SharedPreferences prefs = Utilities.getPrefs(context);
+ String gridSizeString = getPointString(idp.numColumns, idp.numRows);
+
+ return !gridSizeString.equals(prefs.getString(KEY_MIGRATION_SRC_WORKSPACE_SIZE, ""))
+ || idp.numDatabaseHotseatIcons != prefs.getInt(KEY_MIGRATION_SRC_HOTSEAT_COUNT, -1);
+ }
+
+ /** See {@link #migrateGridIfNeeded(Context, InvariantDeviceProfile)} */
+ public static boolean migrateGridIfNeeded(Context context) {
+ if (context instanceof LauncherPreviewRenderer.PreviewContext) {
+ return true;
+ }
+ return migrateGridIfNeeded(context, null);
+ }
+
+ /**
+ * Run the migration algorithm if needed. For preview, we provide the intended idp because it
+ * has not been changed. If idp is null, we read it from the context, for actual grid migration.
+ *
+ * @return false if the migration failed.
+ */
+ public static boolean migrateGridIfNeeded(Context context, InvariantDeviceProfile idp) {
+ boolean migrateForPreview = idp != null;
+ if (!migrateForPreview) {
+ idp = LauncherAppState.getIDP(context);
+ }
+
+ if (!needsToMigrate(context, idp)) {
+ return true;
+ }
+
+ SharedPreferences prefs = Utilities.getPrefs(context);
+ String gridSizeString = getPointString(idp.numColumns, idp.numRows);
+ long migrationStartTime = SystemClock.elapsedRealtime();
+ try (SQLiteTransaction transaction = (SQLiteTransaction) Settings.call(
+ context.getContentResolver(), Settings.METHOD_NEW_TRANSACTION)
+ .getBinder(Settings.EXTRA_VALUE)) {
+
+ int srcHotseatCount = prefs.getInt(KEY_MIGRATION_SRC_HOTSEAT_COUNT,
+ idp.numDatabaseHotseatIcons);
+ Point sourceSize = parsePoint(prefs.getString(
+ KEY_MIGRATION_SRC_WORKSPACE_SIZE, gridSizeString));
+
+ boolean dbChanged = false;
+ if (migrateForPreview) {
+ copyTable(transaction.getDb(), Favorites.TABLE_NAME, transaction.getDb(),
+ Favorites.PREVIEW_TABLE_NAME, context);
+ }
+
+ GridBackupTable backupTable = new GridBackupTable(context, transaction.getDb(),
+ srcHotseatCount, sourceSize.x, sourceSize.y);
+ if (migrateForPreview ? backupTable.restoreToPreviewIfBackupExists()
+ : backupTable.backupOrRestoreAsNeeded()) {
+ dbChanged = true;
+ srcHotseatCount = backupTable.getRestoreHotseatAndGridSize(sourceSize);
+ }
+
+ HashSet<String> validPackages = getValidPackages(context);
+ // Hotseat.
+ if (srcHotseatCount != idp.numDatabaseHotseatIcons
+ && new GridSizeMigrationTask(context, transaction.getDb(), validPackages,
+ migrateForPreview, srcHotseatCount,
+ idp.numDatabaseHotseatIcons).migrateHotseat()) {
+ dbChanged = true;
+ }
+
+ // Grid size
+ Point targetSize = new Point(idp.numColumns, idp.numRows);
+ if (new MultiStepMigrationTask(validPackages, context, transaction.getDb(),
+ migrateForPreview).migrate(sourceSize, targetSize)) {
+ dbChanged = true;
+ }
+
+ if (dbChanged) {
+ // Make sure we haven't removed everything.
+ final Cursor c = context.getContentResolver().query(
+ migrateForPreview ? Favorites.PREVIEW_CONTENT_URI : Favorites.CONTENT_URI,
+ null, null, null, null);
+ boolean hasData = c.moveToNext();
+ c.close();
+ if (!hasData) {
+ throw new Exception("Removed every thing during grid resize");
+ }
+ }
+
+ transaction.commit();
+ if (!migrateForPreview) {
+ Settings.call(context.getContentResolver(), Settings.METHOD_REFRESH_BACKUP_TABLE);
+ }
+ return true;
+ } catch (Exception e) {
+ Log.e(TAG, "Error during preview grid migration", e);
+
+ return false;
+ } finally {
+ Log.v(TAG, "Preview workspace migration completed in "
+ + (SystemClock.elapsedRealtime() - migrationStartTime));
+
+ if (!migrateForPreview) {
+ // Save current configuration, so that the migration does not run again.
+ prefs.edit()
+ .putString(KEY_MIGRATION_SRC_WORKSPACE_SIZE, gridSizeString)
+ .putInt(KEY_MIGRATION_SRC_HOTSEAT_COUNT, idp.numDatabaseHotseatIcons)
+ .apply();
+ }
+ }
+ }
+
+ protected static HashSet<String> getValidPackages(Context context) {
+ // Initialize list of valid packages. This contain all the packages which are already on
+ // the device and packages which are being installed. Any item which doesn't belong to
+ // this set is removed.
+ // Since the loader removes such items anyway, removing these items here doesn't cause
+ // any extra data loss and gives us more free space on the grid for better migration.
+ HashSet<String> validPackages = new HashSet<>();
+ for (PackageInfo info : context.getPackageManager()
+ .getInstalledPackages(PackageManager.GET_UNINSTALLED_PACKAGES)) {
+ validPackages.add(info.packageName);
+ }
+ InstallSessionHelper.INSTANCE.get(context)
+ .getActiveSessions().keySet()
+ .forEach(packageUserKey -> validPackages.add(packageUserKey.mPackageName));
+ return validPackages;
+ }
+
+ /**
+ * Removes any broken item from the hotseat.
+ *
+ * @return a map with occupied hotseat position set to non-null value.
+ */
+ public static IntSparseArrayMap<Object> removeBrokenHotseatItems(Context context)
+ throws Exception {
+ try (SQLiteTransaction transaction = (SQLiteTransaction) Settings.call(
+ context.getContentResolver(), Settings.METHOD_NEW_TRANSACTION)
+ .getBinder(Settings.EXTRA_VALUE)) {
+ GridSizeMigrationTask task = new GridSizeMigrationTask(
+ context, transaction.getDb(), getValidPackages(context),
+ false /* usePreviewTable */, Integer.MAX_VALUE, Integer.MAX_VALUE);
+
+ // Load all the valid entries
+ ArrayList<DbEntry> items = task.loadHotseatEntries();
+ // Delete any entry marked for deletion by above load.
+ task.applyOperations();
+ IntSparseArrayMap<Object> positions = new IntSparseArrayMap<>();
+ for (DbEntry item : items) {
+ positions.put(item.screenId, item);
+ }
+ transaction.commit();
+ return positions;
+ }
+ }
+
+ /**
+ * Task to run grid migration in multiple steps when the size difference is more than 1.
+ */
+ protected static class MultiStepMigrationTask {
+ private final HashSet<String> mValidPackages;
+ private final Context mContext;
+ private final SQLiteDatabase mDb;
+ private final boolean mUsePreviewTable;
+
+ public MultiStepMigrationTask(HashSet<String> validPackages, Context context,
+ SQLiteDatabase db, boolean usePreviewTable) {
+ mValidPackages = validPackages;
+ mContext = context;
+ mDb = db;
+ mUsePreviewTable = usePreviewTable;
+ }
+
+ public boolean migrate(Point sourceSize, Point targetSize) throws Exception {
+ boolean dbChanged = false;
+ if (!targetSize.equals(sourceSize)) {
+ if (sourceSize.x < targetSize.x) {
+ // Source is smaller that target, just expand the grid without actual migration.
+ sourceSize.x = targetSize.x;
+ }
+ if (sourceSize.y < targetSize.y) {
+ // Source is smaller that target, just expand the grid without actual migration.
+ sourceSize.y = targetSize.y;
+ }
+
+ // Migrate the workspace grid, such that the points differ by max 1 in x and y
+ // each on every step.
+ while (!targetSize.equals(sourceSize)) {
+ // Get the next size, such that the points differ by max 1 in x and y each
+ Point nextSize = new Point(sourceSize);
+ if (targetSize.x < nextSize.x) {
+ nextSize.x--;
+ }
+ if (targetSize.y < nextSize.y) {
+ nextSize.y--;
+ }
+ if (runStepTask(sourceSize, nextSize)) {
+ dbChanged = true;
+ }
+ sourceSize.set(nextSize.x, nextSize.y);
+ }
+ }
+ return dbChanged;
+ }
+
+ protected boolean runStepTask(Point sourceSize, Point nextSize) throws Exception {
+ return new GridSizeMigrationTask(mContext, mDb, mValidPackages, mUsePreviewTable,
+ sourceSize, nextSize).migrateWorkspace();
+ }
+ }
+}
diff --git a/src/com/android/launcher3/model/GridSizeMigrationTaskV2.java b/src/com/android/launcher3/model/GridSizeMigrationTaskV2.java
index ef9250c900..8a1d73ed72 100644
--- a/src/com/android/launcher3/model/GridSizeMigrationTaskV2.java
+++ b/src/com/android/launcher3/model/GridSizeMigrationTaskV2.java
@@ -16,12 +16,16 @@
package com.android.launcher3.model;
+import static com.android.launcher3.InvariantDeviceProfile.KEY_MIGRATION_SRC_HOTSEAT_COUNT;
+import static com.android.launcher3.InvariantDeviceProfile.KEY_MIGRATION_SRC_WORKSPACE_SIZE;
+import static com.android.launcher3.Utilities.getPointString;
import static com.android.launcher3.provider.LauncherDbUtils.dropTable;
import android.content.ComponentName;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
+import android.content.SharedPreferences;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.database.Cursor;
@@ -37,7 +41,6 @@ import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.LauncherSettings;
import com.android.launcher3.Utilities;
-import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.graphics.LauncherPreviewRenderer;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.pm.InstallSessionHelper;
@@ -103,18 +106,11 @@ public class GridSizeMigrationTaskV2 {
* Check given a new IDP, if migration is necessary.
*/
public static boolean needsToMigrate(Context context, InvariantDeviceProfile idp) {
- return needsToMigrate(new DeviceGridState(context), new DeviceGridState(idp));
- }
+ SharedPreferences prefs = Utilities.getPrefs(context);
+ String gridSizeString = getPointString(idp.numColumns, idp.numRows);
- private static boolean needsToMigrate(
- DeviceGridState srcDeviceState, DeviceGridState destDeviceState) {
- boolean needsToMigrate = !destDeviceState.isCompatible(srcDeviceState);
- // TODO(b/198965093): Revert this change after bug is fixed
- if (needsToMigrate) {
- Log.d("b/198965093", "Migration is needed. destDeviceState: " + destDeviceState
- + ", srcDeviceState: " + srcDeviceState);
- }
- return needsToMigrate;
+ return !gridSizeString.equals(prefs.getString(KEY_MIGRATION_SRC_WORKSPACE_SIZE, ""))
+ || idp.numDatabaseHotseatIcons != prefs.getInt(KEY_MIGRATION_SRC_HOTSEAT_COUNT, -1);
}
/** See {@link #migrateGridIfNeeded(Context, InvariantDeviceProfile)} */
@@ -127,15 +123,15 @@ public class GridSizeMigrationTaskV2 {
/**
* When migrating the grid for preview, we copy the table
- * {@link LauncherSettings.Favorites#TABLE_NAME} into
- * {@link LauncherSettings.Favorites#PREVIEW_TABLE_NAME}, run grid size migration from the
+ * {@link LauncherSettings.Favorites.TABLE_NAME} into
+ * {@link LauncherSettings.Favorites.PREVIEW_TABLE_NAME}, run grid size migration from the
* former to the later, then use the later table for preview.
*
* Similarly when doing the actual grid migration, the former grid option's table
- * {@link LauncherSettings.Favorites#TABLE_NAME} is copied into the new grid option's
- * {@link LauncherSettings.Favorites#TMP_TABLE}, we then run the grid size migration algorithm
+ * {@link LauncherSettings.Favorites.TABLE_NAME} is copied into the new grid option's
+ * {@link LauncherSettings.Favorites.TMP_TABLE}, we then run the grid size migration algorithm
* to migrate the later to the former, and load the workspace from the default
- * {@link LauncherSettings.Favorites#TABLE_NAME}.
+ * {@link LauncherSettings.Favorites.TABLE_NAME}.
*
* @return false if the migration failed.
*/
@@ -145,26 +141,26 @@ public class GridSizeMigrationTaskV2 {
idp = LauncherAppState.getIDP(context);
}
- DeviceGridState srcDeviceState = new DeviceGridState(context);
- DeviceGridState destDeviceState = new DeviceGridState(idp);
- if (!needsToMigrate(srcDeviceState, destDeviceState)) {
+ if (!needsToMigrate(context, idp)) {
return true;
}
+ SharedPreferences prefs = Utilities.getPrefs(context);
+ String gridSizeString = getPointString(idp.numColumns, idp.numRows);
HashSet<String> validPackages = getValidPackages(context);
+ int srcHotseatCount = prefs.getInt(KEY_MIGRATION_SRC_HOTSEAT_COUNT,
+ idp.numDatabaseHotseatIcons);
if (migrateForPreview) {
if (!LauncherSettings.Settings.call(
context.getContentResolver(),
- LauncherSettings.Settings.METHOD_PREP_FOR_PREVIEW,
- destDeviceState.getDbFile()).getBoolean(
+ LauncherSettings.Settings.METHOD_PREP_FOR_PREVIEW, idp.dbFile).getBoolean(
LauncherSettings.Settings.EXTRA_VALUE)) {
return false;
}
} else if (!LauncherSettings.Settings.call(
context.getContentResolver(),
- LauncherSettings.Settings.METHOD_UPDATE_CURRENT_OPEN_HELPER,
- destDeviceState.getDbFile()).getBoolean(
+ LauncherSettings.Settings.METHOD_UPDATE_CURRENT_OPEN_HELPER).getBoolean(
LauncherSettings.Settings.EXTRA_VALUE)) {
return false;
}
@@ -178,16 +174,16 @@ public class GridSizeMigrationTaskV2 {
DbReader srcReader = new DbReader(t.getDb(),
migrateForPreview ? LauncherSettings.Favorites.TABLE_NAME
: LauncherSettings.Favorites.TMP_TABLE,
- context, validPackages);
+ context, validPackages, srcHotseatCount);
DbReader destReader = new DbReader(t.getDb(),
migrateForPreview ? LauncherSettings.Favorites.PREVIEW_TABLE_NAME
: LauncherSettings.Favorites.TABLE_NAME,
- context, validPackages);
+ context, validPackages, idp.numDatabaseHotseatIcons);
- Point targetSize = new Point(destDeviceState.getColumns(), destDeviceState.getRows());
+ Point targetSize = new Point(idp.numColumns, idp.numRows);
GridSizeMigrationTaskV2 task = new GridSizeMigrationTaskV2(context, t.getDb(),
- srcReader, destReader, destDeviceState.getNumHotseat(), targetSize);
- task.migrate(srcDeviceState, destDeviceState);
+ srcReader, destReader, idp.numDatabaseHotseatIcons, targetSize);
+ task.migrate();
if (!migrateForPreview) {
dropTable(t.getDb(), LauncherSettings.Favorites.TMP_TABLE);
@@ -205,63 +201,48 @@ public class GridSizeMigrationTaskV2 {
if (!migrateForPreview) {
// Save current configuration, so that the migration does not run again.
- destDeviceState.writeToPrefs(context);
+ prefs.edit()
+ .putString(KEY_MIGRATION_SRC_WORKSPACE_SIZE, gridSizeString)
+ .putInt(KEY_MIGRATION_SRC_HOTSEAT_COUNT, idp.numDatabaseHotseatIcons)
+ .apply();
}
}
}
@VisibleForTesting
- protected boolean migrate(DeviceGridState srcDeviceState, DeviceGridState destDeviceState) {
+ protected boolean migrate() {
if (mHotseatDiff.isEmpty() && mWorkspaceDiff.isEmpty()) {
return false;
}
- // Sort the items by the reading order.
- Collections.sort(mHotseatDiff);
- Collections.sort(mWorkspaceDiff);
-
// Migrate hotseat
HotseatPlacementSolution hotseatSolution = new HotseatPlacementSolution(mDb, mSrcReader,
mDestReader, mContext, mDestHotseatSize, mHotseatItems, mHotseatDiff);
hotseatSolution.find();
+ // Sort the items by the reading order.
+ Collections.sort(mWorkspaceDiff);
+
// Migrate workspace.
- // First we create a collection of the screens
- List<Integer> screens = new ArrayList<>();
for (int screenId = 0; screenId <= mDestReader.mLastScreenId; screenId++) {
- screens.add(screenId);
- }
-
- boolean preservePages = false;
- if (screens.isEmpty() && FeatureFlags.ENABLE_NEW_MIGRATION_LOGIC.get()) {
- preservePages = destDeviceState.compareTo(srcDeviceState) >= 0
- && destDeviceState.getColumns() - srcDeviceState.getColumns() <= 2;
- }
-
- // Then we place the items on the screens
- for (int screenId : screens) {
if (DEBUG) {
Log.d(TAG, "Migrating " + screenId);
}
GridPlacementSolution workspaceSolution = new GridPlacementSolution(mDb, mSrcReader,
- mDestReader, mContext, screenId, mTrgX, mTrgY, mWorkspaceDiff, false);
+ mDestReader, mContext, screenId, mTrgX, mTrgY, mWorkspaceDiff);
workspaceSolution.find();
if (mWorkspaceDiff.isEmpty()) {
break;
}
}
- // In case the new grid is smaller, there might be some leftover items that don't fit on
- // any of the screens, in this case we add them to new screens until all of them are placed.
int screenId = mDestReader.mLastScreenId + 1;
while (!mWorkspaceDiff.isEmpty()) {
GridPlacementSolution workspaceSolution = new GridPlacementSolution(mDb, mSrcReader,
- mDestReader, mContext, screenId, mTrgX, mTrgY, mWorkspaceDiff,
- preservePages);
+ mDestReader, mContext, screenId, mTrgX, mTrgY, mWorkspaceDiff);
workspaceSolution.find();
screenId++;
}
-
return true;
}
@@ -378,15 +359,13 @@ public class GridSizeMigrationTaskV2 {
private final int mScreenId;
private final int mTrgX;
private final int mTrgY;
- private final List<DbEntry> mSortedItemsToPlace;
- private final boolean mMatchingScreenIdOnly;
+ private final List<DbEntry> mItemsToPlace;
private int mNextStartX;
private int mNextStartY;
GridPlacementSolution(SQLiteDatabase db, DbReader srcReader, DbReader destReader,
- Context context, int screenId, int trgX, int trgY, List<DbEntry> sortedItemsToPlace,
- boolean matchingScreenIdOnly) {
+ Context context, int screenId, int trgX, int trgY, List<DbEntry> itemsToPlace) {
mDb = db;
mSrcReader = srcReader;
mDestReader = destReader;
@@ -396,24 +375,20 @@ public class GridSizeMigrationTaskV2 {
mTrgX = trgX;
mTrgY = trgY;
mNextStartX = 0;
- mNextStartY = mScreenId == 0 && FeatureFlags.QSB_ON_FIRST_SCREEN
- ? 1 /* smartspace */ : 0;
+ mNextStartY = mTrgY - 1;
List<DbEntry> existedEntries = mDestReader.mWorkspaceEntriesByScreenId.get(screenId);
if (existedEntries != null) {
for (DbEntry entry : existedEntries) {
mOccupied.markCells(entry, true);
}
}
- mSortedItemsToPlace = sortedItemsToPlace;
- mMatchingScreenIdOnly = matchingScreenIdOnly;
+ mItemsToPlace = itemsToPlace;
}
public void find() {
- Iterator<DbEntry> iterator = mSortedItemsToPlace.iterator();
+ Iterator<DbEntry> iterator = mItemsToPlace.iterator();
while (iterator.hasNext()) {
final DbEntry entry = iterator.next();
- if (mMatchingScreenIdOnly && entry.screenId < mScreenId) continue;
- if (mMatchingScreenIdOnly && entry.screenId > mScreenId) break;
if (entry.minSpanX > mTrgX || entry.minSpanY > mTrgY) {
iterator.remove();
continue;
@@ -432,7 +407,7 @@ public class GridSizeMigrationTaskV2 {
* to speed up the search.
*/
private boolean findPlacement(DbEntry entry) {
- for (int y = mNextStartY; y < mTrgY; y++) {
+ for (int y = mNextStartY; y >= (mScreenId == 0 ? 1 /* smartspace */ : 0); y--) {
for (int x = mNextStartX; x < mTrgX; x++) {
boolean fits = mOccupied.isRegionVacant(x, y, entry.spanX, entry.spanY);
boolean minFits = mOccupied.isRegionVacant(x, y, entry.minSpanX,
@@ -515,7 +490,8 @@ public class GridSizeMigrationTaskV2 {
private final SQLiteDatabase mDb;
private final String mTableName;
private final Context mContext;
- private final Set<String> mValidPackages;
+ private final HashSet<String> mValidPackages;
+ private final int mHotseatSize;
private int mLastScreenId = -1;
private final ArrayList<DbEntry> mHotseatEntries = new ArrayList<>();
@@ -524,11 +500,12 @@ public class GridSizeMigrationTaskV2 {
new ArrayMap<>();
DbReader(SQLiteDatabase db, String tableName, Context context,
- Set<String> validPackages) {
+ HashSet<String> validPackages, int hotseatSize) {
mDb = db;
mTableName = tableName;
mContext = context;
mValidPackages = validPackages;
+ mHotseatSize = hotseatSize;
}
protected ArrayList<DbEntry> loadHotseatEntries() {
@@ -553,6 +530,11 @@ public class GridSizeMigrationTaskV2 {
entry.itemType = c.getInt(indexItemType);
entry.screenId = c.getInt(indexScreen);
+ if (entry.screenId >= mHotseatSize) {
+ entriesToRemove.add(entry.id);
+ continue;
+ }
+
try {
// calculate weight
switch (entry.itemType) {
@@ -755,7 +737,7 @@ public class GridSizeMigrationTaskV2 {
return Integer.compare(screenId, another.screenId);
}
if (cellY != another.cellY) {
- return Integer.compare(cellY, another.cellY);
+ return -Integer.compare(cellY, another.cellY);
}
return Integer.compare(cellX, another.cellX);
}
diff --git a/src/com/android/launcher3/model/ItemInstallQueue.java b/src/com/android/launcher3/model/ItemInstallQueue.java
index 5a220f74c7..217f523e14 100644
--- a/src/com/android/launcher3/model/ItemInstallQueue.java
+++ b/src/com/android/launcher3/model/ItemInstallQueue.java
@@ -49,7 +49,6 @@ import com.android.launcher3.model.data.LauncherAppWidgetInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.launcher3.shortcuts.ShortcutKey;
import com.android.launcher3.shortcuts.ShortcutRequest;
-import com.android.launcher3.testing.TestProtocol;
import com.android.launcher3.util.MainThreadInitializedObject;
import com.android.launcher3.util.PersistedItemArray;
import com.android.launcher3.util.Preconditions;
@@ -119,18 +118,10 @@ public class ItemInstallQueue {
Launcher launcher = Launcher.ACTIVITY_TRACKER.getCreatedActivity();
if (launcher == null) {
// Launcher not loaded
- if (TestProtocol.sDebugTracing) {
- Log.d(TestProtocol.MISSING_PROMISE_ICON,
- LOG + " flushQueueInBackground launcher not loaded");
- }
return;
}
ensureQueueLoaded();
if (mItems.isEmpty()) {
- if (TestProtocol.sDebugTracing) {
- Log.d(TestProtocol.MISSING_PROMISE_ICON,
- LOG + " flushQueueInBackground no items to load");
- }
return;
}
@@ -140,10 +131,6 @@ public class ItemInstallQueue {
// Add the items and clear queue
if (!installQueue.isEmpty()) {
- if (TestProtocol.sDebugTracing) {
- Log.d(TestProtocol.MISSING_PROMISE_ICON,
- LOG + " flushQueueInBackground launcher addAndBindAddedWorkspaceItems");
- }
// add log
launcher.getModel().addAndBindAddedWorkspaceItems(installQueue);
}
@@ -204,10 +191,6 @@ public class ItemInstallQueue {
// Queue the item up for adding if launcher has not loaded properly yet
MODEL_EXECUTOR.post(() -> {
Pair<ItemInfo, Object> itemInfo = info.getItemInfo(mContext);
- if (TestProtocol.sDebugTracing) {
- Log.d(TestProtocol.MISSING_PROMISE_ICON, LOG + " queuePendingShortcutInfo"
- + ", itemInfo=" + itemInfo);
- }
if (itemInfo == null) {
FileLog.d(LOG,
"Adding PendingInstallShortcutInfo with no attached info to queue.",
diff --git a/src/com/android/launcher3/model/LoaderCursor.java b/src/com/android/launcher3/model/LoaderCursor.java
index ae5b66ad88..7e3bceee1d 100644
--- a/src/com/android/launcher3/model/LoaderCursor.java
+++ b/src/com/android/launcher3/model/LoaderCursor.java
@@ -16,10 +16,13 @@
package com.android.launcher3.model;
+import static android.graphics.BitmapFactory.decodeByteArray;
+
import android.content.ComponentName;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
+import android.content.Intent.ShortcutIconResource;
import android.content.pm.LauncherActivityInfo;
import android.content.pm.LauncherApps;
import android.content.pm.PackageManager;
@@ -42,10 +45,11 @@ import com.android.launcher3.LauncherSettings.Favorites;
import com.android.launcher3.Utilities;
import com.android.launcher3.Workspace;
import com.android.launcher3.config.FeatureFlags;
+import com.android.launcher3.icons.BitmapInfo;
import com.android.launcher3.icons.IconCache;
+import com.android.launcher3.icons.LauncherIcons;
import com.android.launcher3.logging.FileLog;
import com.android.launcher3.model.data.AppInfo;
-import com.android.launcher3.model.data.IconRequestInfo;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.launcher3.shortcuts.ShortcutKey;
@@ -180,29 +184,40 @@ public class LoaderCursor extends CursorWrapper {
* Loads the icon from the cursor and updates the {@param info} if the icon is an app resource.
*/
protected boolean loadIcon(WorkspaceItemInfo info) {
- return createIconRequestInfo(info, false).loadWorkspaceIcon(mContext);
- }
+ try (LauncherIcons li = LauncherIcons.obtain(mContext)) {
+ if (itemType == LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT) {
+ String packageName = getString(iconPackageIndex);
+ String resourceName = getString(iconResourceIndex);
+ if (!TextUtils.isEmpty(packageName) || !TextUtils.isEmpty(resourceName)) {
+ info.iconResource = new ShortcutIconResource();
+ info.iconResource.packageName = packageName;
+ info.iconResource.resourceName = resourceName;
+ BitmapInfo iconInfo = li.createIconBitmap(info.iconResource);
+ if (iconInfo != null) {
+ info.bitmap = iconInfo;
+ return true;
+ }
+ }
+ }
- public IconRequestInfo<WorkspaceItemInfo> createIconRequestInfo(
- WorkspaceItemInfo wai, boolean useLowResIcon) {
- String packageName = itemType == LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT
- ? getString(iconPackageIndex) : null;
- String resourceName = itemType == LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT
- ? getString(iconResourceIndex) : null;
- byte[] iconBlob = itemType == LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT
- || itemType == Favorites.ITEM_TYPE_DEEP_SHORTCUT
- || restoreFlag != 0
- ? getBlob(iconIndex) : null;
-
- return new IconRequestInfo<>(
- wai, mActivityInfo, packageName, resourceName, iconBlob, useLowResIcon);
+ // Failed to load from resource, try loading from DB.
+ byte[] data = getBlob(iconIndex);
+ try {
+ info.bitmap = li.createIconBitmap(decodeByteArray(data, 0, data.length));
+ return true;
+ } catch (Exception e) {
+ Log.e(TAG, "Failed to decode byte array for info " + info, e);
+ return false;
+ }
+ }
}
/**
* Returns the title or empty string
*/
private String getTitle() {
- return Utilities.trim(getString(titleIndex));
+ String title = getString(titleIndex);
+ return TextUtils.isEmpty(title) ? "" : Utilities.trim(title);
}
/**
@@ -247,11 +262,6 @@ public class LoaderCursor extends CursorWrapper {
*/
public WorkspaceItemInfo getAppShortcutInfo(
Intent intent, boolean allowMissingTarget, boolean useLowResIcon) {
- return getAppShortcutInfo(intent, allowMissingTarget, useLowResIcon, true);
- }
-
- public WorkspaceItemInfo getAppShortcutInfo(
- Intent intent, boolean allowMissingTarget, boolean useLowResIcon, boolean loadIcon) {
if (user == null) {
Log.d(TAG, "Null user found in getShortcutInfo");
return null;
@@ -278,11 +288,9 @@ public class LoaderCursor extends CursorWrapper {
info.user = user;
info.intent = newIntent;
- if (loadIcon) {
- mIconCache.getTitleAndIcon(info, mActivityInfo, useLowResIcon);
- if (mIconCache.isDefaultIcon(info.bitmap, user)) {
- loadIcon(info);
- }
+ mIconCache.getTitleAndIcon(info, mActivityInfo, useLowResIcon);
+ if (mIconCache.isDefaultIcon(info.bitmap, user)) {
+ loadIcon(info);
}
if (mActivityInfo != null) {
@@ -382,23 +390,18 @@ public class LoaderCursor extends CursorWrapper {
info.cellY = getInt(cellYIndex);
}
- public void checkAndAddItem(ItemInfo info, BgDataModel dataModel) {
- checkAndAddItem(info, dataModel, null);
- }
-
/**
* Adds the {@param info} to {@param dataModel} if it does not overlap with any other item,
* otherwise marks it for deletion.
*/
- public void checkAndAddItem(
- ItemInfo info, BgDataModel dataModel, LoaderMemoryLogger logger) {
+ public void checkAndAddItem(ItemInfo info, BgDataModel dataModel) {
if (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT) {
// Ensure that it is a valid intent. An exception here will
// cause the item loading to get skipped
ShortcutKey.fromItemInfo(info);
}
if (checkItemPlacement(info)) {
- dataModel.addItem(mContext, info, false, logger);
+ dataModel.addItem(mContext, info, false);
} else {
markDeleted("Item position overlap");
}
@@ -456,13 +459,11 @@ public class LoaderCursor extends CursorWrapper {
if (!occupied.containsKey(item.screenId)) {
GridOccupancy screen = new GridOccupancy(countX + 1, countY + 1);
- if (item.screenId == Workspace.FIRST_SCREEN_ID && FeatureFlags.QSB_ON_FIRST_SCREEN) {
- // Mark the first X columns (X is width of the search container) in the first row as
- // occupied (if the feature is enabled) in order to account for the search
- // container.
- int spanX = mIDP.numSearchContainerColumns;
+ if (item.screenId == Workspace.FIRST_SCREEN_ID) {
+ // Mark the first row as occupied (if the feature is enabled)
+ // in order to account for the QSB.
int spanY = FeatureFlags.EXPANDED_SMARTSPACE.get() ? 2 : 1;
- screen.markCells(0, 0, spanX, spanY, true);
+ screen.markCells(0, 0, countX + 1, spanY, FeatureFlags.QSB_ON_FIRST_SCREEN);
}
occupied.put(item.screenId, screen);
}
diff --git a/src/com/android/launcher3/model/LoaderMemoryLogger.java b/src/com/android/launcher3/model/LoaderMemoryLogger.java
deleted file mode 100644
index f48efcb4a0..0000000000
--- a/src/com/android/launcher3/model/LoaderMemoryLogger.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright (C) 2021 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.launcher3.model;
-
-import android.util.Log;
-
-import androidx.annotation.Nullable;
-
-import java.util.ArrayList;
-
-/**
- * Helper logger that collects logs while {@code LoaderTask#run} executes and prints them all iff
- * an exception is caught in {@code LoaderTask#run}.
- */
-public class LoaderMemoryLogger {
-
- private static final String TAG = "LoaderMemoryLogger";
-
- private final ArrayList<LogEntry> mLogEntries = new ArrayList<>();
-
- protected LoaderMemoryLogger() {}
-
- protected void addLog(int logLevel, String tag, String log) {
- addLog(logLevel, tag, log, null);
- }
-
- protected void addLog(
- int logLevel, String tag, String log, Exception stackTrace) {
- switch (logLevel) {
- case Log.ASSERT:
- case Log.ERROR:
- case Log.DEBUG:
- case Log.INFO:
- case Log.VERBOSE:
- case Log.WARN:
- mLogEntries.add(new LogEntry(logLevel, tag, log, stackTrace));
- break;
- default:
- throw new IllegalArgumentException("Invalid log level provided: " + logLevel);
-
- }
- }
-
- protected void clearLogs() {
- mLogEntries.clear();
- }
-
- protected void printLogs() {
- for (LogEntry logEntry : mLogEntries) {
- String tag = String.format("%s: %s", TAG, logEntry.mLogTag);
- String logString = logEntry.mStackStrace == null
- ? logEntry.mLogString
- : String.format(
- "%s\n%s",
- logEntry.mLogString,
- Log.getStackTraceString(logEntry.mStackStrace));
-
- Log.println(logEntry.mLogLevel, tag, logString);
- }
- clearLogs();
- }
-
- private static class LogEntry {
-
- protected final int mLogLevel;
- protected final String mLogTag;
- protected final String mLogString;
- @Nullable protected final Exception mStackStrace;
-
- protected LogEntry(
- int logLevel, String logTag, String logString, @Nullable Exception stackStrace) {
- mLogLevel = logLevel;
- mLogTag = logTag;
- mLogString = logString;
- mStackStrace = stackStrace;
- }
- }
-}
diff --git a/src/com/android/launcher3/model/LoaderTask.java b/src/com/android/launcher3/model/LoaderTask.java
index f1c5d59fc8..f6b0b4d3c8 100644
--- a/src/com/android/launcher3/model/LoaderTask.java
+++ b/src/com/android/launcher3/model/LoaderTask.java
@@ -16,6 +16,7 @@
package com.android.launcher3.model;
+import static com.android.launcher3.config.FeatureFlags.MULTI_DB_GRID_MIRATION_ALGO;
import static com.android.launcher3.model.BgDataModel.Callbacks.FLAG_HAS_SHORTCUT_PERMISSION;
import static com.android.launcher3.model.BgDataModel.Callbacks.FLAG_QUIET_MODE_CHANGE_PERMISSION;
import static com.android.launcher3.model.BgDataModel.Callbacks.FLAG_QUIET_MODE_ENABLED;
@@ -43,7 +44,6 @@ import android.content.pm.ShortcutInfo;
import android.graphics.Point;
import android.net.Uri;
import android.os.Bundle;
-import android.os.Trace;
import android.os.UserHandle;
import android.os.UserManager;
import android.text.TextUtils;
@@ -52,8 +52,6 @@ import android.util.Log;
import android.util.LongSparseArray;
import android.util.TimingLogger;
-import androidx.annotation.Nullable;
-
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.LauncherAppState;
@@ -74,7 +72,6 @@ import com.android.launcher3.icons.cache.IconCacheUpdateHandler;
import com.android.launcher3.logging.FileLog;
import com.android.launcher3.model.data.AppInfo;
import com.android.launcher3.model.data.FolderInfo;
-import com.android.launcher3.model.data.IconRequestInfo;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.ItemInfoWithIcon;
import com.android.launcher3.model.data.LauncherAppWidgetInfo;
@@ -82,14 +79,13 @@ import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.launcher3.pm.InstallSessionHelper;
import com.android.launcher3.pm.PackageInstallInfo;
import com.android.launcher3.pm.UserCache;
+import com.android.launcher3.provider.ImportDataTask;
import com.android.launcher3.qsb.QsbContainerView;
import com.android.launcher3.shortcuts.ShortcutKey;
import com.android.launcher3.shortcuts.ShortcutRequest;
import com.android.launcher3.shortcuts.ShortcutRequest.QueryResult;
import com.android.launcher3.util.ComponentKey;
import com.android.launcher3.util.IOUtils;
-import com.android.launcher3.util.IntArray;
-import com.android.launcher3.util.IntSet;
import com.android.launcher3.util.LooperIdleLock;
import com.android.launcher3.util.PackageManagerHelper;
import com.android.launcher3.util.PackageUserKey;
@@ -178,13 +174,10 @@ public class LoaderTask implements Runnable {
private void sendFirstScreenActiveInstallsBroadcast() {
ArrayList<ItemInfo> firstScreenItems = new ArrayList<>();
ArrayList<ItemInfo> allItems = mBgDataModel.getAllWorkspaceItems();
-
// Screen set is never empty
- IntArray allScreens = mBgDataModel.collectWorkspaceScreens();
- final int firstScreen = allScreens.get(0);
- IntSet firstScreens = IntSet.wrap(firstScreen);
+ final int firstScreen = mBgDataModel.collectWorkspaceScreens().get(0);
- filterCurrentWorkspaceItems(firstScreens, allItems, firstScreenItems,
+ filterCurrentWorkspaceItems(firstScreen, allItems, firstScreenItems,
new ArrayList<>() /* otherScreenItems are ignored */);
mFirstScreenBroadcast.sendBroadcasts(mApp.getContext(), firstScreenItems);
}
@@ -199,15 +192,9 @@ public class LoaderTask implements Runnable {
Object traceToken = TraceHelper.INSTANCE.beginSection(TAG);
TimingLogger logger = new TimingLogger(TAG, "run");
- LoaderMemoryLogger memoryLogger = new LoaderMemoryLogger();
try (LauncherModel.LoaderTransaction transaction = mApp.getModel().beginLoader(this)) {
List<ShortcutInfo> allShortcuts = new ArrayList<>();
- Trace.beginSection("LoadWorkspace");
- try {
- loadWorkspace(allShortcuts, memoryLogger);
- } finally {
- Trace.endSection();
- }
+ loadWorkspace(allShortcuts);
logASplit(logger, "loadWorkspace");
// Sanitize data re-syncs widgets/shortcuts based on the workspace loaded from db.
@@ -221,7 +208,7 @@ public class LoaderTask implements Runnable {
}
verifyNotStopped();
- mResults.bindWorkspace(true /* incrementBindId */);
+ mResults.bindWorkspace();
logASplit(logger, "bindWorkspace");
mModelDelegate.workspaceLoadComplete();
@@ -235,13 +222,7 @@ public class LoaderTask implements Runnable {
verifyNotStopped();
// second step
- Trace.beginSection("LoadAllApps");
- List<LauncherActivityInfo> allActivityList;
- try {
- allActivityList = loadAllApps();
- } finally {
- Trace.endSection();
- }
+ List<LauncherActivityInfo> allActivityList = loadAllApps();
logASplit(logger, "loadAllApps");
verifyNotStopped();
@@ -314,13 +295,9 @@ public class LoaderTask implements Runnable {
mModelDelegate.modelLoadComplete();
transaction.commit();
- memoryLogger.clearLogs();
} catch (CancellationException e) {
// Loader stopped, ignore
logASplit(logger, "Cancelled");
- } catch (Exception e) {
- memoryLogger.printLogs();
- throw e;
} finally {
logger.dumpToLog();
}
@@ -332,21 +309,13 @@ public class LoaderTask implements Runnable {
this.notify();
}
- private void loadWorkspace(List<ShortcutInfo> allDeepShortcuts, LoaderMemoryLogger logger) {
+ private void loadWorkspace(List<ShortcutInfo> allDeepShortcuts) {
loadWorkspace(allDeepShortcuts, LauncherSettings.Favorites.CONTENT_URI,
- null /* selection */, logger);
+ null /* selection */);
}
- protected void loadWorkspace(
- List<ShortcutInfo> allDeepShortcuts, Uri contentUri, String selection) {
- loadWorkspace(allDeepShortcuts, contentUri, selection, null);
- }
-
- protected void loadWorkspace(
- List<ShortcutInfo> allDeepShortcuts,
- Uri contentUri,
- String selection,
- @Nullable LoaderMemoryLogger logger) {
+ protected void loadWorkspace(List<ShortcutInfo> allDeepShortcuts, Uri contentUri,
+ String selection) {
final Context context = mApp.getContext();
final ContentResolver contentResolver = context.getContentResolver();
final PackageManagerHelper pmHelper = new PackageManagerHelper(context);
@@ -355,7 +324,16 @@ public class LoaderTask implements Runnable {
final WidgetManagerHelper widgetHelper = new WidgetManagerHelper(context);
boolean clearDb = false;
- if (!GridSizeMigrationTaskV2.migrateGridIfNeeded(context)) {
+ try {
+ ImportDataTask.performImportIfPossible(context);
+ } catch (Exception e) {
+ // Migration failed. Clear workspace.
+ clearDb = true;
+ }
+
+ if (!clearDb && (MULTI_DB_GRID_MIRATION_ALGO.get()
+ ? !GridSizeMigrationTaskV2.migrateGridIfNeeded(context)
+ : !GridSizeMigrationTask.migrateGridIfNeeded(context))) {
// Migration failed. Clear workspace.
clearDb = true;
}
@@ -436,7 +414,6 @@ public class LoaderTask implements Runnable {
LauncherAppWidgetProviderInfo widgetProviderInfo;
Intent intent;
String targetPkg;
- List<IconRequestInfo<WorkspaceItemInfo>> iconRequestInfos = new ArrayList<>();
while (!mStopped && c.moveToNext()) {
try {
@@ -559,10 +536,7 @@ public class LoaderTask implements Runnable {
} else if (c.itemType ==
LauncherSettings.Favorites.ITEM_TYPE_APPLICATION) {
info = c.getAppShortcutInfo(
- intent,
- allowMissingTarget,
- useLowResIcon,
- !FeatureFlags.ENABLE_BULK_WORKSPACE_ICON_LOADING.get());
+ intent, allowMissingTarget, useLowResIcon);
} else if (c.itemType ==
LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT) {
@@ -599,7 +573,6 @@ public class LoaderTask implements Runnable {
&& pmHelper.isAppSuspended(targetPkg, c.user)) {
disabledState |= FLAG_DISABLED_SUSPENDED;
}
- info.options = c.getInt(optionsIndex);
// App shortcuts that used to be automatically added to Launcher
// didn't always have the correct intent flags set, so do that
@@ -615,14 +588,6 @@ public class LoaderTask implements Runnable {
}
if (info != null) {
- if (info.itemType
- != LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT) {
- // Skip deep shortcuts; their title and icons have already been
- // loaded above.
- iconRequestInfos.add(
- c.createIconRequestInfo(info, useLowResIcon));
- }
-
c.applyCommonProperties(info);
info.intent = intent;
@@ -656,7 +621,7 @@ public class LoaderTask implements Runnable {
}
}
- c.checkAndAddItem(info, mBgDataModel, logger);
+ c.checkAndAddItem(info, mBgDataModel);
} else {
throw new RuntimeException("Unexpected null WorkspaceItemInfo");
}
@@ -675,7 +640,7 @@ public class LoaderTask implements Runnable {
// no special handling required for restored folders
c.markRestored();
- c.checkAndAddItem(folderInfo, mBgDataModel, logger);
+ c.checkAndAddItem(folderInfo, mBgDataModel);
break;
case LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET:
@@ -826,9 +791,8 @@ public class LoaderTask implements Runnable {
if (appWidgetInfo.restoreStatus !=
LauncherAppWidgetInfo.RESTORE_COMPLETED) {
appWidgetInfo.pendingItemInfo = WidgetsModel.newPendingItemInfo(
- mApp.getContext(),
- appWidgetInfo.providerName,
- appWidgetInfo.user);
+ appWidgetInfo.providerName);
+ appWidgetInfo.pendingItemInfo.user = appWidgetInfo.user;
mIconCache.getTitleAndIconForApp(
appWidgetInfo.pendingItemInfo, false);
}
@@ -841,21 +805,6 @@ public class LoaderTask implements Runnable {
Log.e(TAG, "Desktop items loading interrupted", e);
}
}
- if (FeatureFlags.ENABLE_BULK_WORKSPACE_ICON_LOADING.get()) {
- Trace.beginSection("LoadWorkspaceIconsInBulk");
- try {
- mIconCache.getTitlesAndIconsInBulk(iconRequestInfos);
- for (IconRequestInfo<WorkspaceItemInfo> iconRequestInfo :
- iconRequestInfos) {
- WorkspaceItemInfo wai = iconRequestInfo.itemInfo;
- if (mIconCache.isDefaultIcon(wai.bitmap, wai.user)) {
- iconRequestInfo.loadWorkspaceIcon(mApp.getContext());
- }
- }
- } finally {
- Trace.endSection();
- }
- }
} finally {
IOUtils.closeSilently(c);
}
@@ -863,9 +812,6 @@ public class LoaderTask implements Runnable {
// Load delegate items
mModelDelegate.loadItems(mUserManagerState, shortcutKeyToPinnedShortcuts);
- // Load string cache
- mModelDelegate.loadStringCache(mBgDataModel.stringCache);
-
// Break early if we've stopped loading
if (mStopped) {
mBgDataModel.clear();
@@ -962,8 +908,6 @@ public class LoaderTask implements Runnable {
List<LauncherActivityInfo> allActivityList = new ArrayList<>();
// Clear the list of apps
mBgAllAppsList.clear();
-
- List<IconRequestInfo<AppInfo>> iconRequestInfos = new ArrayList<>();
for (UserHandle user : profiles) {
// Query for the set of apps
final List<LauncherActivityInfo> apps = mLauncherApps.getActivityList(null, user);
@@ -976,43 +920,18 @@ public class LoaderTask implements Runnable {
// Create the ApplicationInfos
for (int i = 0; i < apps.size(); i++) {
LauncherActivityInfo app = apps.get(i);
- AppInfo appInfo = new AppInfo(app, user, quietMode);
-
- iconRequestInfos.add(new IconRequestInfo<>(
- appInfo, app, /* useLowResIcon= */ false));
- mBgAllAppsList.add(
- appInfo, app, !FeatureFlags.ENABLE_BULK_ALL_APPS_ICON_LOADING.get());
+ // This builds the icon bitmaps.
+ mBgAllAppsList.add(new AppInfo(app, user, quietMode), app);
}
allActivityList.addAll(apps);
}
-
if (FeatureFlags.PROMISE_APPS_IN_ALL_APPS.get()) {
// get all active sessions and add them to the all apps list
for (PackageInstaller.SessionInfo info :
mSessionHelper.getAllVerifiedSessions()) {
- AppInfo promiseAppInfo = mBgAllAppsList.addPromiseApp(
- mApp.getContext(),
- PackageInstallInfo.fromInstallingState(info),
- !FeatureFlags.ENABLE_BULK_ALL_APPS_ICON_LOADING.get());
-
- if (promiseAppInfo != null) {
- iconRequestInfos.add(new IconRequestInfo<>(
- promiseAppInfo,
- /* launcherActivityInfo= */ null,
- promiseAppInfo.usingLowResIcon()));
- }
- }
- }
-
- if (FeatureFlags.ENABLE_BULK_ALL_APPS_ICON_LOADING.get()) {
- Trace.beginSection("LoadAllAppsIconsInBulk");
- try {
- mIconCache.getTitlesAndIconsInBulk(iconRequestInfos);
- iconRequestInfos.forEach(iconRequestInfo ->
- mBgAllAppsList.updateSectionName(iconRequestInfo.itemInfo));
- } finally {
- Trace.endSection();
+ mBgAllAppsList.addPromiseApp(mApp.getContext(),
+ PackageInstallInfo.fromInstallingState(info));
}
}
@@ -1075,10 +994,7 @@ public class LoaderTask implements Runnable {
deviceProfile.getCellSize(cellSize);
FileLog.d(TAG, "DeviceProfile available width: " + deviceProfile.availableWidthPx
+ ", available height: " + deviceProfile.availableHeightPx
- + ", cellLayoutBorderSpacePx Horizontal: "
- + deviceProfile.cellLayoutBorderSpacePx.x
- + ", cellLayoutBorderSpacePx Vertical: "
- + deviceProfile.cellLayoutBorderSpacePx.y
+ + ", cellLayoutBorderSpacingPx: " + deviceProfile.cellLayoutBorderSpacingPx
+ ", cellSize: " + cellSize);
}
diff --git a/src/com/android/launcher3/model/ModelDelegate.java b/src/com/android/launcher3/model/ModelDelegate.java
index 3bd9470566..13ec1ecefb 100644
--- a/src/com/android/launcher3/model/ModelDelegate.java
+++ b/src/com/android/launcher3/model/ModelDelegate.java
@@ -40,35 +40,23 @@ public class ModelDelegate implements ResourceBasedOverride {
* Creates and initializes a new instance of the delegate
*/
public static ModelDelegate newInstance(
- Context context, LauncherAppState app, AllAppsList appsList, BgDataModel dataModel,
- boolean isPrimaryInstance) {
+ Context context, LauncherAppState app, AllAppsList appsList, BgDataModel dataModel) {
ModelDelegate delegate = Overrides.getObject(
ModelDelegate.class, context, R.string.model_delegate_class);
- delegate.init(context, app, appsList, dataModel, isPrimaryInstance);
+
+ delegate.mApp = app;
+ delegate.mAppsList = appsList;
+ delegate.mDataModel = dataModel;
return delegate;
}
- protected Context mContext;
protected LauncherAppState mApp;
protected AllAppsList mAppsList;
protected BgDataModel mDataModel;
- protected boolean mIsPrimaryInstance;
public ModelDelegate() { }
/**
- * Initializes the object with the given params.
- */
- private void init(Context context, LauncherAppState app, AllAppsList appsList,
- BgDataModel dataModel, boolean isPrimaryInstance) {
- this.mApp = app;
- this.mAppsList = appsList;
- this.mDataModel = dataModel;
- this.mIsPrimaryInstance = isPrimaryInstance;
- this.mContext = context;
- }
-
- /**
* Called periodically to validate and update any data
*/
@WorkerThread
@@ -86,14 +74,6 @@ public class ModelDelegate implements ResourceBasedOverride {
public void loadItems(UserManagerState ums, Map<ShortcutKey, ShortcutInfo> pinnedShortcuts) { }
/**
- * Load String cache
- */
- @WorkerThread
- public void loadStringCache(StringCache cache) {
- cache.loadStrings(mContext);
- }
-
- /**
* Called during loader after workspace loading is complete
*/
@WorkerThread
diff --git a/src/com/android/launcher3/model/ModelUtils.java b/src/com/android/launcher3/model/ModelUtils.java
index 422af43e19..9b5fac8734 100644
--- a/src/com/android/launcher3/model/ModelUtils.java
+++ b/src/com/android/launcher3/model/ModelUtils.java
@@ -23,13 +23,14 @@ import android.graphics.Bitmap;
import android.os.Process;
import android.util.Log;
+import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.LauncherSettings;
import com.android.launcher3.Utilities;
+import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.icons.BitmapInfo;
import com.android.launcher3.icons.LauncherIcons;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo;
-import com.android.launcher3.testing.TestProtocol;
import com.android.launcher3.util.IntArray;
import com.android.launcher3.util.IntSet;
@@ -50,8 +51,7 @@ public class ModelUtils {
* Filters the set of items who are directly or indirectly (via another container) on the
* specified screen.
*/
- public static <T extends ItemInfo> void filterCurrentWorkspaceItems(
- final IntSet currentScreenIds,
+ public static <T extends ItemInfo> void filterCurrentWorkspaceItems(int currentScreenId,
ArrayList<T> allWorkspaceItems,
ArrayList<T> currentScreenItems,
ArrayList<T> otherScreenItems) {
@@ -65,11 +65,7 @@ public class ModelUtils {
(lhs, rhs) -> Integer.compare(lhs.container, rhs.container));
for (T info : allWorkspaceItems) {
if (info.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {
- if (TestProtocol.sDebugTracing) {
- Log.d(TestProtocol.NULL_INT_SET, "filterCurrentWorkspaceItems: "
- + currentScreenIds);
- }
- if (currentScreenIds.contains(info.screenId)) {
+ if (info.screenId == currentScreenId) {
currentScreenItems.add(info);
itemsOnScreen.add(info.id);
} else {
@@ -90,6 +86,42 @@ public class ModelUtils {
}
/**
+ * Sorts the set of items by hotseat, workspace (spatially from top to bottom, left to right)
+ */
+ public static void sortWorkspaceItemsSpatially(InvariantDeviceProfile profile,
+ ArrayList<ItemInfo> workspaceItems) {
+ final int screenCols = profile.numColumns;
+ final int screenCellCount = profile.numColumns * profile.numRows;
+ Collections.sort(workspaceItems, (lhs, rhs) -> {
+ if (lhs.container == rhs.container) {
+ // Within containers, order by their spatial position in that container
+ switch (lhs.container) {
+ case LauncherSettings.Favorites.CONTAINER_DESKTOP: {
+ int lr = (lhs.screenId * screenCellCount + lhs.cellY * screenCols
+ + lhs.cellX);
+ int rr = (rhs.screenId * screenCellCount + +rhs.cellY * screenCols
+ + rhs.cellX);
+ return Integer.compare(lr, rr);
+ }
+ case LauncherSettings.Favorites.CONTAINER_HOTSEAT: {
+ // We currently use the screen id as the rank
+ return Integer.compare(lhs.screenId, rhs.screenId);
+ }
+ default:
+ if (FeatureFlags.IS_STUDIO_BUILD) {
+ throw new RuntimeException(
+ "Unexpected container type when sorting workspace items.");
+ }
+ return 0;
+ }
+ } else {
+ // Between containers, order by hotseat, desktop
+ return Integer.compare(lhs.container, rhs.container);
+ }
+ });
+ }
+
+ /**
* Iterates though current workspace items and returns available hotseat ranks for prediction.
*/
public static IntArray getMissingHotseatRanks(List<ItemInfo> items, int len) {
diff --git a/src/com/android/launcher3/model/ModelWriter.java b/src/com/android/launcher3/model/ModelWriter.java
index 0a68d4aa34..080ce20f31 100644
--- a/src/com/android/launcher3/model/ModelWriter.java
+++ b/src/com/android/launcher3/model/ModelWriter.java
@@ -23,15 +23,12 @@ import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.net.Uri;
-import android.text.TextUtils;
+import android.os.Handler;
+import android.os.Looper;
import android.util.Log;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.LauncherModel;
-import com.android.launcher3.LauncherModel.CallbackTask;
import com.android.launcher3.LauncherProvider;
import com.android.launcher3.LauncherSettings;
import com.android.launcher3.LauncherSettings.Favorites;
@@ -39,23 +36,19 @@ import com.android.launcher3.LauncherSettings.Settings;
import com.android.launcher3.Utilities;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.logging.FileLog;
-import com.android.launcher3.model.BgDataModel.Callbacks;
import com.android.launcher3.model.data.FolderInfo;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.LauncherAppWidgetInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.launcher3.util.ContentWriter;
-import com.android.launcher3.util.Executors;
import com.android.launcher3.util.ItemInfoMatcher;
-import com.android.launcher3.util.LooperExecutor;
import com.android.launcher3.widget.LauncherAppWidgetHost;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
-import java.util.Collections;
import java.util.List;
-import java.util.function.Predicate;
+import java.util.concurrent.Executor;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;
@@ -70,10 +63,7 @@ public class ModelWriter {
private final Context mContext;
private final LauncherModel mModel;
private final BgDataModel mBgDataModel;
- private final LooperExecutor mUiExecutor;
-
- @Nullable
- private final Callbacks mOwner;
+ private final Handler mUiHandler;
private final boolean mHasVerticalHotseat;
private final boolean mVerifyChanges;
@@ -83,15 +73,13 @@ public class ModelWriter {
private boolean mPreparingToUndo;
public ModelWriter(Context context, LauncherModel model, BgDataModel dataModel,
- boolean hasVerticalHotseat, boolean verifyChanges,
- @Nullable Callbacks owner) {
+ boolean hasVerticalHotseat, boolean verifyChanges) {
mContext = context;
mModel = model;
mBgDataModel = dataModel;
mHasVerticalHotseat = hasVerticalHotseat;
mVerifyChanges = verifyChanges;
- mOwner = owner;
- mUiExecutor = Executors.MAIN_EXECUTOR;
+ mUiHandler = new Handler(Looper.getMainLooper());
}
private void updateItemInfoProps(
@@ -167,8 +155,6 @@ public class ModelWriter {
public void moveItemInDatabase(final ItemInfo item,
int container, int screenId, int cellX, int cellY) {
updateItemInfoProps(item, container, screenId, cellX, cellY);
- notifyItemModified(item);
-
enqueueDeleteRunnable(new UpdateItemRunnable(item, () ->
new ContentWriter(mContext)
.put(Favorites.CONTAINER, item.container)
@@ -185,7 +171,6 @@ public class ModelWriter {
public void moveItemsInDatabase(final ArrayList<ItemInfo> items, int container, int screen) {
ArrayList<ContentValues> contentValues = new ArrayList<>();
int count = items.size();
- notifyOtherCallbacks(c -> c.bindItemsModified(items));
for (int i = 0; i < count; i++) {
ItemInfo item = items.get(i);
@@ -211,9 +196,8 @@ public class ModelWriter {
updateItemInfoProps(item, container, screenId, cellX, cellY);
item.spanX = spanX;
item.spanY = spanY;
- notifyItemModified(item);
- MODEL_EXECUTOR.execute(new UpdateItemRunnable(item, () ->
+ ((Executor) MODEL_EXECUTOR).execute(new UpdateItemRunnable(item, () ->
new ContentWriter(mContext)
.put(Favorites.CONTAINER, item.container)
.put(Favorites.CELLX, item.cellX)
@@ -228,18 +212,13 @@ public class ModelWriter {
* Update an item to the database in a specified container.
*/
public void updateItemInDatabase(ItemInfo item) {
- notifyItemModified(item);
- MODEL_EXECUTOR.execute(new UpdateItemRunnable(item, () -> {
+ ((Executor) MODEL_EXECUTOR).execute(new UpdateItemRunnable(item, () -> {
ContentWriter writer = new ContentWriter(mContext);
item.onAddToDatabase(writer);
return writer;
}));
}
- private void notifyItemModified(ItemInfo item) {
- notifyOtherCallbacks(c -> c.bindItemsModified(Collections.singletonList(item)));
- }
-
/**
* Add an item to the database in a specified container. Sets the container, screen, cellX and
* cellY fields of the item. Also assigns an ID to the item.
@@ -250,11 +229,10 @@ public class ModelWriter {
final ContentResolver cr = mContext.getContentResolver();
item.id = Settings.call(cr, Settings.METHOD_NEW_ITEM_ID).getInt(Settings.EXTRA_VALUE);
- notifyOtherCallbacks(c -> c.bindItems(Collections.singletonList(item), false));
ModelVerifier verifier = new ModelVerifier();
final StackTraceElement[] stackTrace = new Throwable().getStackTrace();
- MODEL_EXECUTOR.execute(() -> {
+ ((Executor) MODEL_EXECUTOR).execute(() -> {
// Write the item on background thread, as some properties might have been updated in
// the background.
final ContentWriter writer = new ContentWriter(mContext);
@@ -274,31 +252,28 @@ public class ModelWriter {
/**
* Removes the specified item from the database
*/
- public void deleteItemFromDatabase(ItemInfo item, @Nullable final String reason) {
- deleteItemsFromDatabase(Arrays.asList(item), reason);
+ public void deleteItemFromDatabase(ItemInfo item) {
+ deleteItemsFromDatabase(Arrays.asList(item));
}
/**
* Removes all the items from the database matching {@param matcher}.
*/
- public void deleteItemsFromDatabase(@NonNull final Predicate<ItemInfo> matcher,
- @Nullable final String reason) {
+ public void deleteItemsFromDatabase(ItemInfoMatcher matcher) {
deleteItemsFromDatabase(StreamSupport.stream(mBgDataModel.itemsIdMap.spliterator(), false)
- .filter(matcher).collect(Collectors.toList()), reason);
+ .filter(matcher::matchesInfo)
+ .collect(Collectors.toList()));
}
/**
* Removes the specified items from the database
*/
- public void deleteItemsFromDatabase(final Collection<? extends ItemInfo> items,
- @Nullable final String reason) {
+ public void deleteItemsFromDatabase(final Collection<? extends ItemInfo> items) {
ModelVerifier verifier = new ModelVerifier();
FileLog.d(TAG, "removing items from db " + items.stream().map(
(item) -> item.getTargetComponent() == null ? ""
: item.getTargetComponent().getPackageName()).collect(
- Collectors.joining(","))
- + ". Reason: [" + (TextUtils.isEmpty(reason) ? "unknown" : reason) + "]");
- notifyDelete(items);
+ Collectors.joining(",")), new Exception());
enqueueDeleteRunnable(() -> {
for (ItemInfo item : items) {
final Uri uri = Favorites.getContentUri(item.id);
@@ -315,7 +290,6 @@ public class ModelWriter {
*/
public void deleteFolderAndContentsFromDatabase(final FolderInfo info) {
ModelVerifier verifier = new ModelVerifier();
- notifyDelete(Collections.singleton(info));
enqueueDeleteRunnable(() -> {
ContentResolver cr = mContext.getContentResolver();
@@ -333,19 +307,13 @@ public class ModelWriter {
/**
* Deletes the widget info and the widget id.
*/
- public void deleteWidgetInfo(final LauncherAppWidgetInfo info, LauncherAppWidgetHost host,
- @Nullable final String reason) {
- notifyDelete(Collections.singleton(info));
+ public void deleteWidgetInfo(final LauncherAppWidgetInfo info, LauncherAppWidgetHost host) {
if (host != null && !info.isCustomWidget() && info.isWidgetIdAllocated()) {
// Deleting an app widget ID is a void call but writes to disk before returning
// to the caller...
enqueueDeleteRunnable(() -> host.deleteAppWidgetId(info.appWidgetId));
}
- deleteItemFromDatabase(info, reason);
- }
-
- private void notifyDelete(Collection<? extends ItemInfo> items) {
- notifyOtherCallbacks(c -> c.bindWorkspaceComponentsRemoved(ItemInfoMatcher.ofItems(items)));
+ deleteItemFromDatabase(info);
}
/**
@@ -373,14 +341,14 @@ public class ModelWriter {
if (mPreparingToUndo) {
mDeleteRunnables.add(r);
} else {
- MODEL_EXECUTOR.execute(r);
+ ((Executor) MODEL_EXECUTOR).execute(r);
}
}
public void commitDelete() {
mPreparingToUndo = false;
for (Runnable runnable : mDeleteRunnables) {
- MODEL_EXECUTOR.execute(runnable);
+ ((Executor) MODEL_EXECUTOR).execute(runnable);
}
mDeleteRunnables.clear();
}
@@ -396,20 +364,6 @@ public class ModelWriter {
mModel.forceReload();
}
- private void notifyOtherCallbacks(CallbackTask task) {
- if (mOwner == null) {
- // If the call is happening from a model, it will take care of updating the callbacks
- return;
- }
- mUiExecutor.execute(() -> {
- for (Callbacks c : mModel.getCallbacks()) {
- if (c != mOwner) {
- task.execute(c);
- }
- }
- });
- }
-
private class UpdateItemRunnable extends UpdateItemBaseRunnable {
private final ItemInfo mItem;
private final Supplier<ContentWriter> mWriter;
@@ -530,7 +484,7 @@ public class ModelWriter {
int executeId = mBgDataModel.lastBindId;
- mUiExecutor.post(() -> {
+ mUiHandler.post(() -> {
int currentId = mBgDataModel.lastBindId;
if (currentId > executeId) {
// Model was already bound after job was executed.
diff --git a/src/com/android/launcher3/model/PackageInstallStateChangedTask.java b/src/com/android/launcher3/model/PackageInstallStateChangedTask.java
index b74d0fc482..9889a8065d 100644
--- a/src/com/android/launcher3/model/PackageInstallStateChangedTask.java
+++ b/src/com/android/launcher3/model/PackageInstallStateChangedTask.java
@@ -21,6 +21,7 @@ import android.content.pm.PackageManager;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.model.data.AppInfo;
import com.android.launcher3.model.data.ItemInfo;
+import com.android.launcher3.model.data.ItemInfoWithIcon;
import com.android.launcher3.model.data.LauncherAppWidgetInfo;
import com.android.launcher3.pm.PackageInstallInfo;
import com.android.launcher3.util.InstantAppResolver;
@@ -72,7 +73,13 @@ public class PackageInstallStateChangedTask extends BaseModelUpdateTask {
dataModel.forAllWorkspaceItemInfos(mInstallInfo.user, si -> {
if (si.hasPromiseIconUi()
&& mInstallInfo.packageName.equals(si.getTargetPackage())) {
- si.setProgressLevel(mInstallInfo);
+ int installProgress = mInstallInfo.progress;
+
+ si.setProgressLevel(installProgress, PackageInstallInfo.STATUS_INSTALLING);
+ if (mInstallInfo.state == PackageInstallInfo.STATUS_FAILED) {
+ // Mark this info as broken.
+ si.runtimeStatusFlags &= ~ItemInfoWithIcon.FLAG_INSTALL_SESSION_ACTIVE;
+ }
updates.add(si);
}
});
diff --git a/src/com/android/launcher3/model/PackageUpdatedTask.java b/src/com/android/launcher3/model/PackageUpdatedTask.java
index 489bc38376..82b0f7c7d5 100644
--- a/src/com/android/launcher3/model/PackageUpdatedTask.java
+++ b/src/com/android/launcher3/model/PackageUpdatedTask.java
@@ -57,7 +57,6 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
-import java.util.function.Predicate;
/**
* Handles updates due to changes in package manager (app installed/updated/removed)
@@ -96,7 +95,7 @@ public class PackageUpdatedTask extends BaseModelUpdateTask {
final int N = packages.length;
final FlagOp flagOp;
final HashSet<String> packageSet = new HashSet<>(Arrays.asList(packages));
- final Predicate<ItemInfo> matcher = mOp == OP_USER_AVAILABILITY_CHANGE
+ final ItemInfoMatcher matcher = mOp == OP_USER_AVAILABILITY_CHANGE
? ItemInfoMatcher.ofUser(mUser) // We want to update all packages for this user
: ItemInfoMatcher.ofPackages(packageSet, mUser);
final HashSet<ComponentName> removedComponents = new HashSet<>();
@@ -113,7 +112,7 @@ public class PackageUpdatedTask extends BaseModelUpdateTask {
activitiesLists.put(
packages[i], appsList.addPackage(context, packages[i], mUser));
}
- flagOp = FlagOp.NO_OP.removeFlag(WorkspaceItemInfo.FLAG_DISABLED_NOT_AVAILABLE);
+ flagOp = FlagOp.removeFlag(WorkspaceItemInfo.FLAG_DISABLED_NOT_AVAILABLE);
break;
}
case OP_UPDATE:
@@ -124,6 +123,7 @@ public class PackageUpdatedTask extends BaseModelUpdateTask {
iconCache.updateIconsForPkg(packages[i], mUser);
activitiesLists.put(
packages[i], appsList.updatePackage(context, packages[i], mUser));
+ app.getWidgetCache().removePackage(packages[i], mUser);
// The update may have changed which shortcuts/widgets are available.
// Refresh the widgets for the package if we have an activity running.
@@ -135,7 +135,7 @@ public class PackageUpdatedTask extends BaseModelUpdateTask {
}
}
// Since package was just updated, the target must be available now.
- flagOp = FlagOp.NO_OP.removeFlag(WorkspaceItemInfo.FLAG_DISABLED_NOT_AVAILABLE);
+ flagOp = FlagOp.removeFlag(WorkspaceItemInfo.FLAG_DISABLED_NOT_AVAILABLE);
break;
case OP_REMOVE: {
for (int i = 0; i < N; i++) {
@@ -148,13 +148,15 @@ public class PackageUpdatedTask extends BaseModelUpdateTask {
for (int i = 0; i < N; i++) {
if (DEBUG) Log.d(TAG, "mAllAppsList.removePackage " + packages[i]);
appsList.removePackage(packages[i], mUser);
+ app.getWidgetCache().removePackage(packages[i], mUser);
}
- flagOp = FlagOp.NO_OP.addFlag(WorkspaceItemInfo.FLAG_DISABLED_NOT_AVAILABLE);
+ flagOp = FlagOp.addFlag(WorkspaceItemInfo.FLAG_DISABLED_NOT_AVAILABLE);
break;
case OP_SUSPEND:
case OP_UNSUSPEND:
- flagOp = FlagOp.NO_OP.setFlag(
- WorkspaceItemInfo.FLAG_DISABLED_SUSPENDED, mOp == OP_SUSPEND);
+ flagOp = mOp == OP_SUSPEND ?
+ FlagOp.addFlag(WorkspaceItemInfo.FLAG_DISABLED_SUSPENDED) :
+ FlagOp.removeFlag(WorkspaceItemInfo.FLAG_DISABLED_SUSPENDED);
if (DEBUG) Log.d(TAG, "mAllAppsList.(un)suspend " + N);
appsList.updateDisabledFlags(matcher, flagOp);
break;
@@ -162,8 +164,9 @@ public class PackageUpdatedTask extends BaseModelUpdateTask {
UserManagerState ums = new UserManagerState();
ums.init(UserCache.INSTANCE.get(context),
context.getSystemService(UserManager.class));
- flagOp = FlagOp.NO_OP.setFlag(
- WorkspaceItemInfo.FLAG_DISABLED_QUIET_USER, ums.isUserQuiet(mUser));
+ flagOp = ums.isUserQuiet(mUser)
+ ? FlagOp.addFlag(WorkspaceItemInfo.FLAG_DISABLED_QUIET_USER)
+ : FlagOp.removeFlag(WorkspaceItemInfo.FLAG_DISABLED_QUIET_USER);
appsList.updateDisabledFlags(matcher, flagOp);
// We are not synchronizing here, as int operations are atomic
@@ -207,7 +210,7 @@ public class PackageUpdatedTask extends BaseModelUpdateTask {
}
ComponentName cn = si.getTargetComponent();
- if (cn != null && matcher.test(si)) {
+ if (cn != null && matcher.matches(si, cn)) {
String packageName = cn.getPackageName();
if (si.hasStatusFlag(WorkspaceItemInfo.FLAG_SUPPORTS_WEB_UI)) {
@@ -311,9 +314,7 @@ public class PackageUpdatedTask extends BaseModelUpdateTask {
bindUpdatedWorkspaceItems(updatedWorkspaceItems);
if (!removedShortcuts.isEmpty()) {
- deleteAndBindComponentsRemoved(
- ItemInfoMatcher.ofItemIds(removedShortcuts),
- "removed because the target component is invalid");
+ deleteAndBindComponentsRemoved(ItemInfoMatcher.ofItemIds(removedShortcuts));
}
if (!widgets.isEmpty()) {
@@ -339,11 +340,10 @@ public class PackageUpdatedTask extends BaseModelUpdateTask {
}
if (!removedPackages.isEmpty() || !removedComponents.isEmpty()) {
- Predicate<ItemInfo> removeMatch = ItemInfoMatcher.ofPackages(removedPackages, mUser)
+ ItemInfoMatcher removeMatch = ItemInfoMatcher.ofPackages(removedPackages, mUser)
.or(ItemInfoMatcher.ofComponents(removedComponents, mUser))
.and(ItemInfoMatcher.ofItemIds(forceKeepShortcuts).negate());
- deleteAndBindComponentsRemoved(removeMatch,
- "removed because the corresponding package or component is removed");
+ deleteAndBindComponentsRemoved(removeMatch);
// Remove any queued items from the install queue
ItemInstallQueue.INSTANCE.get(context)
diff --git a/src/com/android/launcher3/model/ReloadStringCacheTask.java b/src/com/android/launcher3/model/ReloadStringCacheTask.java
deleted file mode 100644
index f4d42988bf..0000000000
--- a/src/com/android/launcher3/model/ReloadStringCacheTask.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2016 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.launcher3.model;
-
-import com.android.launcher3.LauncherAppState;
-
-/**
- * Handles updates due to changes in Device Policy Management resources triggered by
- * {@link android.app.admin.DevicePolicyManager#ACTION_DEVICE_POLICY_RESOURCE_UPDATED}.
- */
-public class ReloadStringCacheTask extends BaseModelUpdateTask {
- private ModelDelegate mModelDelegate;
-
- public ReloadStringCacheTask(ModelDelegate modelDelegate) {
- mModelDelegate = modelDelegate;
- }
-
- @Override
- public void execute(LauncherAppState app, BgDataModel dataModel, AllAppsList appsList) {
- synchronized (dataModel) {
- mModelDelegate.loadStringCache(dataModel.stringCache);
- StringCache cloneSC = dataModel.stringCache.clone();
- scheduleCallbackTask(c -> c.bindStringCache(cloneSC));
- }
- }
-}
diff --git a/src/com/android/launcher3/model/ShortcutsChangedTask.java b/src/com/android/launcher3/model/ShortcutsChangedTask.java
index 1026e0bd5b..4296d32f24 100644
--- a/src/com/android/launcher3/model/ShortcutsChangedTask.java
+++ b/src/com/android/launcher3/model/ShortcutsChangedTask.java
@@ -108,8 +108,7 @@ public class ShortcutsChangedTask extends BaseModelUpdateTask {
deleteAndBindComponentsRemoved(ItemInfoMatcher.ofShortcutKeys(
nonPinnedIds.stream()
.map(id -> new ShortcutKey(mPackageName, mUser, id))
- .collect(Collectors.toSet())),
- "removed because the shortcut is no longer available in shortcut service");
+ .collect(Collectors.toSet())));
}
}
diff --git a/src/com/android/launcher3/model/StringCache.java b/src/com/android/launcher3/model/StringCache.java
deleted file mode 100644
index 9859ddca28..0000000000
--- a/src/com/android/launcher3/model/StringCache.java
+++ /dev/null
@@ -1,254 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.launcher3.model;
-
-import android.annotation.SuppressLint;
-import android.app.admin.DevicePolicyManager;
-import android.content.Context;
-import android.os.Build;
-
-import androidx.annotation.RequiresApi;
-
-import com.android.launcher3.R;
-import com.android.launcher3.Utilities;
-
-/**
- *
- * Cache for the device policy strings used in Launcher.
- */
-public class StringCache {
-
- private static final String PREFIX = "Launcher.";
-
- /**
- * Work folder name.
- */
- public static final String WORK_FOLDER_NAME = PREFIX + "WORK_FOLDER_NAME";
-
- /**
- * User on-boarding title for work profile apps.
- */
- private static final String WORK_PROFILE_EDU = PREFIX + "WORK_PROFILE_EDU";
-
- /**
- * Action label to finish work profile edu.
- */
- private static final String WORK_PROFILE_EDU_ACCEPT = PREFIX + "WORK_PROFILE_EDU_ACCEPT";
-
- /**
- * Title shown when user opens work apps tab while work profile is paused.
- */
- private static final String WORK_PROFILE_PAUSED_TITLE =
- PREFIX + "WORK_PROFILE_PAUSED_TITLE";
-
- /**
- * Description shown when user opens work apps tab while work profile is paused.
- */
- private static final String WORK_PROFILE_PAUSED_DESCRIPTION =
- PREFIX + "WORK_PROFILE_PAUSED_DESCRIPTION";
-
- /**
- * Shown on the button to pause work profile.
- */
- private static final String WORK_PROFILE_PAUSE_BUTTON =
- PREFIX + "WORK_PROFILE_PAUSE_BUTTON";
-
- /**
- * Shown on the button to enable work profile.
- */
- private static final String WORK_PROFILE_ENABLE_BUTTON =
- PREFIX + "WORK_PROFILE_ENABLE_BUTTON";
-
- /**
- * Label on launcher tab to indicate work apps.
- */
- private static final String ALL_APPS_WORK_TAB = PREFIX + "ALL_APPS_WORK_TAB";
-
- /**
- * Label on launcher tab to indicate personal apps.
- */
- private static final String ALL_APPS_PERSONAL_TAB = PREFIX + "ALL_APPS_PERSONAL_TAB";
-
- /**
- * Accessibility description for launcher tab to indicate work apps.
- */
- private static final String ALL_APPS_WORK_TAB_ACCESSIBILITY =
- PREFIX + "ALL_APPS_WORK_TAB_ACCESSIBILITY";
-
- /**
- * Accessibility description for launcher tab to indicate personal apps.
- */
- private static final String ALL_APPS_PERSONAL_TAB_ACCESSIBILITY =
- PREFIX + "ALL_APPS_PERSONAL_TAB_ACCESSIBILITY";
-
- /**
- * Label on widget tab to indicate work app widgets.
- */
- private static final String WIDGETS_WORK_TAB = PREFIX + "WIDGETS_WORK_TAB";
-
- /**
- * Label on widget tab to indicate personal app widgets.
- */
- private static final String WIDGETS_PERSONAL_TAB = PREFIX + "WIDGETS_PERSONAL_TAB";
-
- /**
- * Message shown when a feature is disabled by the admin (e.g. changing wallpaper).
- */
- private static final String DISABLED_BY_ADMIN_MESSAGE =
- PREFIX + "DISABLED_BY_ADMIN_MESSAGE";
-
- /**
- * User on-boarding title for work profile apps.
- */
- public String workProfileEdu;
-
- /**
- * Action label to finish work profile edu.
- */
- public String workProfileEduAccept;
-
- /**
- * Title shown when user opens work apps tab while work profile is paused.
- */
- public String workProfilePausedTitle;
-
- /**
- * Description shown when user opens work apps tab while work profile is paused.
- */
- public String workProfilePausedDescription;
-
- /**
- * Shown on the button to pause work profile.
- */
- public String workProfilePauseButton;
-
- /**
- * Shown on the button to enable work profile.
- */
- public String workProfileEnableButton;
-
- /**
- * Label on launcher tab to indicate work apps.
- */
- public String allAppsWorkTab;
-
- /**
- * Label on launcher tab to indicate personal apps.
- */
- public String allAppsPersonalTab;
-
- /**
- * Accessibility description for launcher tab to indicate work apps.
- */
- public String allAppsWorkTabAccessibility;
-
- /**
- * Accessibility description for launcher tab to indicate personal apps.
- */
- public String allAppsPersonalTabAccessibility;
-
- /**
- * Work folder name.
- */
- public String workFolderName;
-
- /**
- * Label on widget tab to indicate work app widgets.
- */
- public String widgetsWorkTab;
-
- /**
- * Label on widget tab to indicate personal app widgets.
- */
- public String widgetsPersonalTab;
-
- /**
- * Message shown when a feature is disabled by the admin (e.g. changing wallpaper).
- */
- public String disabledByAdminMessage;
-
- /**
- * Sets the default values for the strings.
- */
- public void loadStrings(Context context) {
- workProfileEdu = getEnterpriseString(
- context, WORK_PROFILE_EDU, R.string.work_profile_edu_work_apps);
- workProfileEduAccept = getEnterpriseString(
- context, WORK_PROFILE_EDU_ACCEPT, R.string.work_profile_edu_accept);
- workProfilePausedTitle = getEnterpriseString(
- context, WORK_PROFILE_PAUSED_TITLE, R.string.work_apps_paused_title);
- workProfilePausedDescription = getEnterpriseString(
- context, WORK_PROFILE_PAUSED_DESCRIPTION, R.string.work_apps_paused_body);
- workProfilePauseButton = getEnterpriseString(
- context, WORK_PROFILE_PAUSE_BUTTON, R.string.work_apps_pause_btn_text);
- workProfileEnableButton = getEnterpriseString(
- context, WORK_PROFILE_ENABLE_BUTTON, R.string.work_apps_enable_btn_text);
- allAppsWorkTab = getEnterpriseString(
- context, ALL_APPS_WORK_TAB, R.string.all_apps_work_tab);
- allAppsPersonalTab = getEnterpriseString(
- context, ALL_APPS_PERSONAL_TAB, R.string.all_apps_personal_tab);
- allAppsWorkTabAccessibility = getEnterpriseString(
- context, ALL_APPS_WORK_TAB_ACCESSIBILITY, R.string.all_apps_button_work_label);
- allAppsPersonalTabAccessibility = getEnterpriseString(
- context, ALL_APPS_PERSONAL_TAB_ACCESSIBILITY,
- R.string.all_apps_button_personal_label);
- workFolderName = getEnterpriseString(
- context, WORK_FOLDER_NAME, R.string.work_folder_name);
- widgetsWorkTab = getEnterpriseString(
- context, WIDGETS_WORK_TAB, R.string.widgets_full_sheet_work_tab);
- widgetsPersonalTab = getEnterpriseString(
- context, WIDGETS_PERSONAL_TAB, R.string.widgets_full_sheet_personal_tab);
- disabledByAdminMessage = getEnterpriseString(
- context, DISABLED_BY_ADMIN_MESSAGE, R.string.msg_disabled_by_admin);
- }
-
- @SuppressLint("NewApi")
- private String getEnterpriseString(
- Context context, String updatableStringId, int defaultStringId) {
- return Utilities.ATLEAST_T
- ? getUpdatableEnterpriseSting(context, updatableStringId, defaultStringId)
- : context.getString(defaultStringId);
- }
-
- @RequiresApi(Build.VERSION_CODES.TIRAMISU)
- private String getUpdatableEnterpriseSting(
- Context context, String updatableStringId, int defaultStringId) {
- DevicePolicyManager dpm = context.getSystemService(DevicePolicyManager.class);
- return dpm.getResources().getString(
- updatableStringId, () -> context.getString(defaultStringId));
- }
-
- @Override
- public StringCache clone() {
- StringCache clone = new StringCache();
- clone.workProfileEdu = this.workProfileEdu;
- clone.workProfileEduAccept = this.workProfileEduAccept;
- clone.workProfilePausedTitle = this.workProfilePausedTitle;
- clone.workProfilePausedDescription = this.workProfilePausedDescription;
- clone.workProfilePauseButton = this.workProfilePauseButton;
- clone.workProfileEnableButton = this.workProfileEnableButton;
- clone.allAppsWorkTab = this.allAppsWorkTab;
- clone.allAppsPersonalTab = this.allAppsPersonalTab;
- clone.allAppsWorkTabAccessibility = this.allAppsWorkTabAccessibility;
- clone.allAppsPersonalTabAccessibility = this.allAppsPersonalTabAccessibility;
- clone.workFolderName = this.workFolderName;
- clone.widgetsWorkTab = this.widgetsWorkTab;
- clone.widgetsPersonalTab = this.widgetsPersonalTab;
- clone.disabledByAdminMessage = this.disabledByAdminMessage;
- return clone;
- }
-}
diff --git a/src/com/android/launcher3/model/UserLockStateChangedTask.java b/src/com/android/launcher3/model/UserLockStateChangedTask.java
index 1565b19f4c..5048e13e3e 100644
--- a/src/com/android/launcher3/model/UserLockStateChangedTask.java
+++ b/src/com/android/launcher3/model/UserLockStateChangedTask.java
@@ -96,9 +96,7 @@ public class UserLockStateChangedTask extends BaseModelUpdateTask {
}
bindUpdatedWorkspaceItems(updatedWorkspaceItemInfos);
if (!removedKeys.isEmpty()) {
- deleteAndBindComponentsRemoved(ItemInfoMatcher.ofShortcutKeys(removedKeys),
- "removed during unlock because it's no longer available"
- + " (possibly due to clear data)");
+ deleteAndBindComponentsRemoved(ItemInfoMatcher.ofShortcutKeys(removedKeys));
}
// Remove shortcut id map for that user
diff --git a/src/com/android/launcher3/model/UserManagerState.java b/src/com/android/launcher3/model/UserManagerState.java
index 97a5905f0a..3a4206c144 100644
--- a/src/com/android/launcher3/model/UserManagerState.java
+++ b/src/com/android/launcher3/model/UserManagerState.java
@@ -36,7 +36,7 @@ public class UserManagerState {
* Initialises the state values for all users
*/
public void init(UserCache userCache, UserManager userManager) {
- for (UserHandle user : userManager.getUserProfiles()) {
+ for (UserHandle user : userCache.getUserProfiles()) {
long serialNo = userCache.getSerialNumberForUser(user);
boolean isUserQuiet = userManager.isQuietModeEnabled(user);
allUsers.put(serialNo, user);
diff --git a/src/com/android/launcher3/model/WorkspaceItemSpaceFinder.java b/src/com/android/launcher3/model/WorkspaceItemSpaceFinder.java
deleted file mode 100644
index 93fc6a539f..0000000000
--- a/src/com/android/launcher3/model/WorkspaceItemSpaceFinder.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.launcher3.model;
-
-import static com.android.launcher3.WorkspaceLayoutManager.FIRST_SCREEN_ID;
-
-import android.util.LongSparseArray;
-
-import com.android.launcher3.InvariantDeviceProfile;
-import com.android.launcher3.LauncherAppState;
-import com.android.launcher3.LauncherSettings;
-import com.android.launcher3.config.FeatureFlags;
-import com.android.launcher3.model.data.ItemInfo;
-import com.android.launcher3.util.GridOccupancy;
-import com.android.launcher3.util.IntArray;
-import com.android.launcher3.util.IntSet;
-
-import java.util.ArrayList;
-
-/**
- * Utility class to help find space for new workspace items
- */
-public class WorkspaceItemSpaceFinder {
-
- /**
- * Find a position on the screen for the given size or adds a new screen.
- *
- * @return screenId and the coordinates for the item in an int array of size 3.
- */
- public int[] findSpaceForItem(LauncherAppState app, BgDataModel dataModel,
- IntArray workspaceScreens, IntArray addedWorkspaceScreensFinal, int spanX, int spanY) {
- LongSparseArray<ArrayList<ItemInfo>> screenItems = new LongSparseArray<>();
-
- // Use sBgItemsIdMap as all the items are already loaded.
- synchronized (dataModel) {
- for (ItemInfo info : dataModel.itemsIdMap) {
- if (info.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {
- ArrayList<ItemInfo> items = screenItems.get(info.screenId);
- if (items == null) {
- items = new ArrayList<>();
- screenItems.put(info.screenId, items);
- }
- items.add(info);
- }
- }
- }
-
- // Find appropriate space for the item.
- int screenId = 0;
- int[] coordinates = new int[2];
- boolean found = false;
-
- int screenCount = workspaceScreens.size();
- // First check the preferred screen.
- IntSet screensToExclude = new IntSet();
- if (FeatureFlags.QSB_ON_FIRST_SCREEN) {
- screensToExclude.add(FIRST_SCREEN_ID);
- }
-
- for (int screen = 0; screen < screenCount; screen++) {
- screenId = workspaceScreens.get(screen);
- if (!screensToExclude.contains(screenId) && findNextAvailableIconSpaceInScreen(
- app, screenItems.get(screenId), coordinates, spanX, spanY)) {
- // We found a space for it
- found = true;
- break;
- }
- }
-
- if (!found) {
- // Still no position found. Add a new screen to the end.
- screenId = LauncherSettings.Settings.call(app.getContext().getContentResolver(),
- LauncherSettings.Settings.METHOD_NEW_SCREEN_ID)
- .getInt(LauncherSettings.Settings.EXTRA_VALUE);
-
- // Save the screen id for binding in the workspace
- workspaceScreens.add(screenId);
- addedWorkspaceScreensFinal.add(screenId);
-
- // If we still can't find an empty space, then God help us all!!!
- if (!findNextAvailableIconSpaceInScreen(
- app, screenItems.get(screenId), coordinates, spanX, spanY)) {
- throw new RuntimeException("Can't find space to add the item");
- }
- }
- return new int[]{screenId, coordinates[0], coordinates[1]};
- }
-
- private boolean findNextAvailableIconSpaceInScreen(
- LauncherAppState app, ArrayList<ItemInfo> occupiedPos,
- int[] xy, int spanX, int spanY) {
- InvariantDeviceProfile profile = app.getInvariantDeviceProfile();
-
- GridOccupancy occupied = new GridOccupancy(profile.numColumns, profile.numRows);
- if (occupiedPos != null) {
- for (ItemInfo r : occupiedPos) {
- occupied.markCells(r, true);
- }
- }
- return occupied.findVacantCell(xy, spanX, spanY);
- }
-}
diff --git a/src/com/android/launcher3/model/data/AppInfo.java b/src/com/android/launcher3/model/data/AppInfo.java
index 5b2bcf5819..7f70bade3c 100644
--- a/src/com/android/launcher3/model/data/AppInfo.java
+++ b/src/com/android/launcher3/model/data/AppInfo.java
@@ -35,6 +35,7 @@ import androidx.annotation.VisibleForTesting;
import com.android.launcher3.LauncherSettings;
import com.android.launcher3.Utilities;
import com.android.launcher3.pm.PackageInstallInfo;
+import com.android.launcher3.util.ComponentKey;
import com.android.launcher3.util.PackageManagerHelper;
import java.util.Comparator;
@@ -42,7 +43,7 @@ import java.util.Comparator;
/**
* Represents an app in AllAppsView.
*/
-public class AppInfo extends ItemInfoWithIcon implements WorkspaceItemFactory {
+public class AppInfo extends ItemInfoWithIcon {
public static final AppInfo[] EMPTY_ARRAY = new AppInfo[0];
public static final Comparator<AppInfo> COMPONENT_KEY_COMPARATOR = (a, b) -> {
@@ -120,8 +121,7 @@ public class AppInfo extends ItemInfoWithIcon implements WorkspaceItemFactory {
return super.dumpProperties() + " componentName=" + componentName;
}
- @Override
- public WorkspaceItemInfo makeWorkspaceItem(Context context) {
+ public WorkspaceItemInfo makeWorkspaceItem() {
WorkspaceItemInfo workspaceItemInfo = new WorkspaceItemInfo(this);
if ((runtimeStatusFlags & FLAG_INSTALL_SESSION_ACTIVE) != 0) {
@@ -139,6 +139,10 @@ public class AppInfo extends ItemInfoWithIcon implements WorkspaceItemFactory {
return workspaceItemInfo;
}
+ public ComponentKey toComponentKey() {
+ return new ComponentKey(componentName, user);
+ }
+
public static Intent makeLaunchIntent(LauncherActivityInfo info) {
return makeLaunchIntent(info.getComponentName());
}
diff --git a/src/com/android/launcher3/model/data/FolderInfo.java b/src/com/android/launcher3/model/data/FolderInfo.java
index efebce342f..cd2ef35a66 100644
--- a/src/com/android/launcher3/model/data/FolderInfo.java
+++ b/src/com/android/launcher3/model/data/FolderInfo.java
@@ -217,7 +217,7 @@ public class FolderInfo extends ItemInfo {
return getDefaultItemInfoBuilder()
.setFolderIcon(folderIcon)
.setRank(rank)
- .addItemAttributes(getLabelState().mLogAttribute)
+ .setAttribute(getLabelState().mLogAttribute)
.setContainerInfo(getContainerInfo())
.build();
}
diff --git a/src/com/android/launcher3/model/data/IconRequestInfo.java b/src/com/android/launcher3/model/data/IconRequestInfo.java
deleted file mode 100644
index fbf01e514e..0000000000
--- a/src/com/android/launcher3/model/data/IconRequestInfo.java
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Copyright (C) 2021 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.launcher3.model.data;
-
-import static android.graphics.BitmapFactory.decodeByteArray;
-
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.LauncherActivityInfo;
-import android.text.TextUtils;
-import android.util.Log;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
-import com.android.launcher3.LauncherSettings;
-import com.android.launcher3.icons.BitmapInfo;
-import com.android.launcher3.icons.LauncherIcons;
-
-/**
- * Class representing one request for an icon to be queried in a sql database.
- *
- * @param <T> ItemInfoWithIcon subclass whose title and icon can be loaded and filled by an sql
- * query.
- */
-public class IconRequestInfo<T extends ItemInfoWithIcon> {
-
- private static final String TAG = "IconRequestInfo";
-
- @NonNull public final T itemInfo;
- @Nullable public final LauncherActivityInfo launcherActivityInfo;
- @Nullable public final String packageName;
- @Nullable public final String resourceName;
- @Nullable public final byte[] iconBlob;
- public final boolean useLowResIcon;
-
- public IconRequestInfo(
- @NonNull T itemInfo,
- @Nullable LauncherActivityInfo launcherActivityInfo,
- boolean useLowResIcon) {
- this(
- itemInfo,
- launcherActivityInfo,
- /* packageName= */ null,
- /* resourceName= */ null,
- /* iconBlob= */ null,
- useLowResIcon);
- }
-
- public IconRequestInfo(
- @NonNull T itemInfo,
- @Nullable LauncherActivityInfo launcherActivityInfo,
- @Nullable String packageName,
- @Nullable String resourceName,
- @Nullable byte[] iconBlob,
- boolean useLowResIcon) {
- this.itemInfo = itemInfo;
- this.launcherActivityInfo = launcherActivityInfo;
- this.packageName = packageName;
- this.resourceName = resourceName;
- this.iconBlob = iconBlob;
- this.useLowResIcon = useLowResIcon;
- }
-
- /**
- * Loads this request's item info's title. This method should only be used on IconRequestInfos
- * for WorkspaceItemInfos.
- */
- public boolean loadWorkspaceIcon(Context context) {
- if (!(itemInfo instanceof WorkspaceItemInfo)) {
- throw new IllegalStateException(
- "loadWorkspaceIcon should only be use for a WorkspaceItemInfos: " + itemInfo);
- }
-
- try (LauncherIcons li = LauncherIcons.obtain(context)) {
- WorkspaceItemInfo info = (WorkspaceItemInfo) itemInfo;
- if (itemInfo.itemType == LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT) {
- if (!TextUtils.isEmpty(packageName) || !TextUtils.isEmpty(resourceName)) {
- info.iconResource = new Intent.ShortcutIconResource();
- info.iconResource.packageName = packageName;
- info.iconResource.resourceName = resourceName;
- BitmapInfo iconInfo = li.createIconBitmap(info.iconResource);
- if (iconInfo != null) {
- info.bitmap = iconInfo;
- return true;
- }
- }
- }
-
- // Failed to load from resource, try loading from DB.
- try {
- if (iconBlob == null) {
- return false;
- }
- info.bitmap = li.createIconBitmap(decodeByteArray(
- iconBlob, 0, iconBlob.length));
- return true;
- } catch (Exception e) {
- Log.e(TAG, "Failed to decode byte array for info " + info, e);
- return false;
- }
- }
- }
-}
diff --git a/src/com/android/launcher3/model/data/ItemInfo.java b/src/com/android/launcher3/model/data/ItemInfo.java
index 1e8e3cad83..7091d2b143 100644
--- a/src/com/android/launcher3/model/data/ItemInfo.java
+++ b/src/com/android/launcher3/model/data/ItemInfo.java
@@ -25,7 +25,6 @@ import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_SEARCH_
import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_SETTINGS;
import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_SHORTCUTS;
import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_TASKSWITCHER;
-import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_WALLPAPERS;
import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_WIDGETS_TRAY;
import static com.android.launcher3.LauncherSettings.Favorites.EXTENDED_CONTAINERS;
import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_APPLICATION;
@@ -56,7 +55,6 @@ import com.android.launcher3.logger.LauncherAtom.SettingsContainer;
import com.android.launcher3.logger.LauncherAtom.Shortcut;
import com.android.launcher3.logger.LauncherAtom.ShortcutsContainer;
import com.android.launcher3.logger.LauncherAtom.TaskSwitcherContainer;
-import com.android.launcher3.logger.LauncherAtom.WallpapersContainer;
import com.android.launcher3.logger.LauncherAtomExtensions.ExtendedContainers;
import com.android.launcher3.model.ModelWriter;
import com.android.launcher3.util.ContentWriter;
@@ -166,7 +164,6 @@ public class ItemInfo {
public void copyFrom(ItemInfo info) {
id = info.id;
- title = info.title;
cellX = info.cellX;
cellY = info.cellY;
spanX = info.spanX;
@@ -235,9 +232,9 @@ public class ItemInfo {
* Write the fields of this item to the DB
*/
public void onAddToDatabase(ContentWriter writer) {
- if (Workspace.EXTRA_EMPTY_SCREEN_IDS.contains(screenId)) {
+ if (screenId == Workspace.EXTRA_EMPTY_SCREEN_ID) {
// We should never persist an item on the extra empty screen.
- throw new RuntimeException("Screen id should not be extra empty screen: " + screenId);
+ throw new RuntimeException("Screen id should not be EXTRA_EMPTY_SCREEN_ID");
}
writeToValues(writer);
@@ -375,8 +372,7 @@ public class ItemInfo {
protected LauncherAtom.ItemInfo.Builder getDefaultItemInfoBuilder() {
LauncherAtom.ItemInfo.Builder itemBuilder = LauncherAtom.ItemInfo.newBuilder();
- itemBuilder.setIsWork(!Process.myUserHandle().equals(user));
- itemBuilder.setRank(rank);
+ itemBuilder.setIsWork(user != Process.myUserHandle());
return itemBuilder;
}
@@ -431,10 +427,6 @@ public class ItemInfo {
return ContainerInfo.newBuilder()
.setTaskSwitcherContainer(TaskSwitcherContainer.getDefaultInstance())
.build();
- case CONTAINER_WALLPAPERS:
- return ContainerInfo.newBuilder()
- .setWallpapersContainer(WallpapersContainer.getDefaultInstance())
- .build();
case EXTENDED_CONTAINERS:
return ContainerInfo.newBuilder()
.setExtendedContainers(getExtendedContainer())
diff --git a/src/com/android/launcher3/model/data/ItemInfoWithIcon.java b/src/com/android/launcher3/model/data/ItemInfoWithIcon.java
index 76a0c4d64c..6813b972ab 100644
--- a/src/com/android/launcher3/model/data/ItemInfoWithIcon.java
+++ b/src/com/android/launcher3/model/data/ItemInfoWithIcon.java
@@ -23,9 +23,7 @@ import android.content.Intent;
import androidx.annotation.Nullable;
import com.android.launcher3.icons.BitmapInfo;
-import com.android.launcher3.icons.BitmapInfo.DrawableCreationFlags;
import com.android.launcher3.icons.FastBitmapDrawable;
-import com.android.launcher3.logging.FileLog;
import com.android.launcher3.pm.PackageInstallInfo;
import com.android.launcher3.util.PackageManagerHelper;
@@ -71,6 +69,10 @@ public abstract class ItemInfoWithIcon extends ItemInfo {
*/
public static final int FLAG_DISABLED_LOCKED_USER = 1 << 5;
+ public static final int FLAG_DISABLED_MASK = FLAG_DISABLED_SAFEMODE
+ | FLAG_DISABLED_NOT_AVAILABLE | FLAG_DISABLED_SUSPENDED
+ | FLAG_DISABLED_QUIET_USER | FLAG_DISABLED_BY_PUBLISHER | FLAG_DISABLED_LOCKED_USER;
+
/**
* The item points to a system app.
*/
@@ -110,16 +112,6 @@ public abstract class ItemInfoWithIcon extends ItemInfo {
| FLAG_INCREMENTAL_DOWNLOAD_ACTIVE;
/**
- * Indicates that the icon is a disabled shortcut and application updates are required.
- */
- public static final int FLAG_DISABLED_VERSION_LOWER = 1 << 12;
-
- public static final int FLAG_DISABLED_MASK = FLAG_DISABLED_SAFEMODE
- | FLAG_DISABLED_NOT_AVAILABLE | FLAG_DISABLED_SUSPENDED
- | FLAG_DISABLED_QUIET_USER | FLAG_DISABLED_BY_PUBLISHER | FLAG_DISABLED_LOCKED_USER
- | FLAG_DISABLED_VERSION_LOWER;
-
- /**
* Status associated with the system state of the underlying item. This is calculated every
* time a new info is created and not persisted on the disk.
*/
@@ -187,12 +179,6 @@ public abstract class ItemInfoWithIcon extends ItemInfo {
*/
public void setProgressLevel(PackageInstallInfo installInfo) {
setProgressLevel(installInfo.progress, installInfo.state);
-
- if (installInfo.state == PackageInstallInfo.STATUS_FAILED) {
- FileLog.d(TAG,
- "Icon info: " + this + " marked broken with install info: " + installInfo,
- new Exception());
- }
}
/**
@@ -237,14 +223,15 @@ public abstract class ItemInfoWithIcon extends ItemInfo {
* Returns a FastBitmapDrawable with the icon.
*/
public FastBitmapDrawable newIcon(Context context) {
- return newIcon(context, 0);
+ return newIcon(context, false);
}
/**
* Returns a FastBitmapDrawable with the icon and context theme applied
*/
- public FastBitmapDrawable newIcon(Context context, @DrawableCreationFlags int creationFlags) {
- FastBitmapDrawable drawable = bitmap.newIcon(context, creationFlags);
+ public FastBitmapDrawable newIcon(Context context, boolean applyTheme) {
+ FastBitmapDrawable drawable = applyTheme
+ ? bitmap.newThemedIcon(context) : bitmap.newIcon(context);
drawable.setIsDisabled(isDisabled());
return drawable;
}
diff --git a/src/com/android/launcher3/model/data/LauncherAppWidgetInfo.java b/src/com/android/launcher3/model/data/LauncherAppWidgetInfo.java
index e57a895ddd..0283d5f398 100644
--- a/src/com/android/launcher3/model/data/LauncherAppWidgetInfo.java
+++ b/src/com/android/launcher3/model/data/LauncherAppWidgetInfo.java
@@ -288,7 +288,7 @@ public class LauncherAppWidgetInfo extends ItemInfo {
LauncherAtom.ItemInfo info = super.buildProto(folderInfo);
return info.toBuilder()
.setWidget(info.getWidget().toBuilder().setWidgetFeatures(widgetFeatures))
- .addItemAttributes(getAttribute(sourceContainer))
+ .setAttribute(getAttribute(sourceContainer))
.build();
}
}
diff --git a/src/com/android/launcher3/model/data/PackageItemInfo.java b/src/com/android/launcher3/model/data/PackageItemInfo.java
index 0055763cef..a81fe6a9d1 100644
--- a/src/com/android/launcher3/model/data/PackageItemInfo.java
+++ b/src/com/android/launcher3/model/data/PackageItemInfo.java
@@ -16,41 +16,47 @@
package com.android.launcher3.model.data;
-import static com.android.launcher3.widget.WidgetSections.NO_CATEGORY;
-
-import android.os.UserHandle;
+import androidx.annotation.IntDef;
import com.android.launcher3.LauncherSettings;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.util.Objects;
/**
* Represents a {@link Package} in the widget tray section.
*/
public class PackageItemInfo extends ItemInfoWithIcon {
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef({NO_CATEGORY, CONVERSATIONS})
+ public @interface Category{}
+ /** The package is not categorized in the widget tray. */
+ public static final int NO_CATEGORY = 0;
+ /** The package is categorized to conversations widget in the widget tray. */
+ public static final int CONVERSATIONS = 1;
+
/**
* Package name of the {@link PackageItemInfo}.
*/
public final String packageName;
/** Represents a widget category shown in the widget tray section. */
- public final int widgetCategory;
+ @Category public final int category;
- public PackageItemInfo(String packageName, UserHandle user) {
- this(packageName, NO_CATEGORY, user);
+ public PackageItemInfo(String packageName) {
+ this(packageName, NO_CATEGORY);
}
- public PackageItemInfo(String packageName, int widgetCategory, UserHandle user) {
+ public PackageItemInfo(String packageName, @Category int category) {
this.packageName = packageName;
- this.widgetCategory = widgetCategory;
- this.user = user;
+ this.category = category;
this.itemType = LauncherSettings.Favorites.ITEM_TYPE_NON_ACTIONABLE;
}
public PackageItemInfo(PackageItemInfo copy) {
this.packageName = copy.packageName;
- this.widgetCategory = copy.widgetCategory;
- this.user = copy.user;
+ this.category = copy.category;
this.itemType = LauncherSettings.Favorites.ITEM_TYPE_NON_ACTIONABLE;
}
@@ -69,13 +75,11 @@ public class PackageItemInfo extends ItemInfoWithIcon {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
PackageItemInfo that = (PackageItemInfo) o;
- return Objects.equals(packageName, that.packageName)
- && Objects.equals(user, that.user)
- && widgetCategory == that.widgetCategory;
+ return Objects.equals(packageName, that.packageName);
}
@Override
public int hashCode() {
- return Objects.hash(packageName, user, widgetCategory);
+ return Objects.hash(packageName, user);
}
}
diff --git a/src/com/android/launcher3/model/data/SearchActionItemInfo.java b/src/com/android/launcher3/model/data/SearchActionItemInfo.java
index e879313f5e..b3057d5bd2 100644
--- a/src/com/android/launcher3/model/data/SearchActionItemInfo.java
+++ b/src/com/android/launcher3/model/data/SearchActionItemInfo.java
@@ -18,7 +18,6 @@ package com.android.launcher3.model.data;
import static com.android.launcher3.LauncherSettings.Favorites.EXTENDED_CONTAINERS;
import android.app.PendingIntent;
-import android.content.Context;
import android.content.Intent;
import android.graphics.drawable.Icon;
import android.os.Process;
@@ -26,30 +25,26 @@ import android.os.UserHandle;
import androidx.annotation.Nullable;
-import com.android.launcher3.LauncherAppState;
-import com.android.launcher3.LauncherSettings;
import com.android.launcher3.logger.LauncherAtom.ItemInfo;
import com.android.launcher3.logger.LauncherAtom.SearchActionItem;
/**
* Represents a SearchAction with in launcher
*/
-public class SearchActionItemInfo extends ItemInfoWithIcon implements WorkspaceItemFactory {
+public class SearchActionItemInfo extends ItemInfoWithIcon {
public static final int FLAG_SHOULD_START = 1 << 1;
public static final int FLAG_SHOULD_START_FOR_RESULT = FLAG_SHOULD_START | 1 << 2;
public static final int FLAG_BADGE_WITH_PACKAGE = 1 << 3;
public static final int FLAG_PRIMARY_ICON_FROM_TITLE = 1 << 4;
public static final int FLAG_BADGE_WITH_COMPONENT_NAME = 1 << 5;
- public static final int FLAG_ALLOW_PINNING = 1 << 6;
- public static final int FLAG_SEARCH_IN_APP = 1 << 7;
- private String mFallbackPackageName;
+ private final String mFallbackPackageName;
private int mFlags = 0;
- private Icon mIcon;
+ private final Icon mIcon;
// If true title does not contain any personal info and eligible for logging.
- private boolean mIsPersonalTitle;
+ private final boolean mIsPersonalTitle;
private Intent mIntent;
private PendingIntent mPendingIntent;
@@ -57,7 +52,6 @@ public class SearchActionItemInfo extends ItemInfoWithIcon implements WorkspaceI
public SearchActionItemInfo(Icon icon, String packageName, UserHandle user,
CharSequence title, boolean isPersonalTitle) {
mIsPersonalTitle = isPersonalTitle;
- this.itemType = LauncherSettings.Favorites.ITEM_TYPE_SEARCH_ACTION;
this.user = user == null ? Process.myUserHandle() : user;
this.title = title;
this.container = EXTENDED_CONTAINERS;
@@ -65,18 +59,14 @@ public class SearchActionItemInfo extends ItemInfoWithIcon implements WorkspaceI
mIcon = icon;
}
- private SearchActionItemInfo(SearchActionItemInfo info) {
+ public SearchActionItemInfo(SearchActionItemInfo info) {
super(info);
- }
-
- @Override
- public void copyFrom(com.android.launcher3.model.data.ItemInfo info) {
- super.copyFrom(info);
- SearchActionItemInfo itemInfo = (SearchActionItemInfo) info;
- this.mFallbackPackageName = itemInfo.mFallbackPackageName;
- this.mIcon = itemInfo.mIcon;
- this.mFlags = itemInfo.mFlags;
- this.mIsPersonalTitle = itemInfo.mIsPersonalTitle;
+ mIcon = info.mIcon;
+ mFallbackPackageName = info.mFallbackPackageName;
+ mFlags = info.mFlags;
+ title = info.title;
+ this.container = EXTENDED_CONTAINERS;
+ this.mIsPersonalTitle = info.mIsPersonalTitle;
}
/**
@@ -87,7 +77,7 @@ public class SearchActionItemInfo extends ItemInfoWithIcon implements WorkspaceI
}
public void setFlags(int flags) {
- mFlags |= flags;
+ mFlags |= flags ;
}
@Override
@@ -144,43 +134,4 @@ public class SearchActionItemInfo extends ItemInfoWithIcon implements WorkspaceI
.setContainerInfo(getContainerInfo())
.build();
}
-
- /**
- * Returns true if result supports drag/drop to home screen
- */
- public boolean supportsPinning() {
- return hasFlags(FLAG_ALLOW_PINNING) && getIntentPackageName() != null;
- }
-
- /**
- * Creates a {@link WorkspaceItemInfo} coorsponding to search action to be stored in launcher db
- */
- @Override
- public WorkspaceItemInfo makeWorkspaceItem(Context context) {
- WorkspaceItemInfo info = new WorkspaceItemInfo();
- info.title = title;
- info.bitmap = bitmap;
- info.intent = mIntent;
-
- if (hasFlags(FLAG_SHOULD_START_FOR_RESULT)) {
- info.options |= WorkspaceItemInfo.FLAG_START_FOR_RESULT;
- }
- LauncherAppState app = LauncherAppState.getInstance(context);
- app.getModel().updateAndBindWorkspaceItem(() -> {
- PackageItemInfo pkgInfo = new PackageItemInfo(getIntentPackageName(), user);
- app.getIconCache().getTitleAndIconForApp(pkgInfo, false);
- info.bitmap = info.bitmap.withBadgeInfo(pkgInfo.bitmap);
- return info;
- });
- return info;
- }
-
- @Nullable
- private String getIntentPackageName() {
- if (mIntent != null) {
- if (mIntent.getPackage() != null) return mIntent.getPackage();
- return mFallbackPackageName;
- }
- return null;
- }
}
diff --git a/src/com/android/launcher3/model/data/WorkspaceItemFactory.java b/src/com/android/launcher3/model/data/WorkspaceItemFactory.java
deleted file mode 100644
index 47b9c6e443..0000000000
--- a/src/com/android/launcher3/model/data/WorkspaceItemFactory.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.launcher3.model.data;
-
-import android.content.Context;
-
-/**
- * Interface to objects capable of generating workspace item
- */
-public interface WorkspaceItemFactory {
-
- /**
- * Called to create a pinnable item info
- */
- WorkspaceItemInfo makeWorkspaceItem(Context context);
-}
diff --git a/src/com/android/launcher3/model/data/WorkspaceItemInfo.java b/src/com/android/launcher3/model/data/WorkspaceItemInfo.java
index 2b3da335c3..690e904a02 100644
--- a/src/com/android/launcher3/model/data/WorkspaceItemInfo.java
+++ b/src/com/android/launcher3/model/data/WorkspaceItemInfo.java
@@ -68,11 +68,6 @@ public class WorkspaceItemInfo extends ItemInfoWithIcon {
public static final int FLAG_SUPPORTS_WEB_UI = 1 << 3;
/**
- *
- */
- public static final int FLAG_START_FOR_RESULT = 1 << 4;
-
- /**
* The intent used to start the application.
*/
public Intent intent;
@@ -97,8 +92,6 @@ public class WorkspaceItemInfo extends ItemInfoWithIcon {
*/
@NonNull private String[] personKeys = Utilities.EMPTY_STRING_ARRAY;
- public int options;
-
public WorkspaceItemInfo() {
itemType = LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT;
@@ -134,7 +127,6 @@ public class WorkspaceItemInfo extends ItemInfoWithIcon {
super.onAddToDatabase(writer);
writer.put(Favorites.TITLE, title)
.put(Favorites.INTENT, getIntent())
- .put(Favorites.OPTIONS, options)
.put(Favorites.RESTORED, status);
if (!usingLowResIcon()) {
@@ -180,25 +172,12 @@ public class WorkspaceItemInfo extends ItemInfoWithIcon {
runtimeStatusFlags |= FLAG_DISABLED_BY_PUBLISHER;
}
disabledMessage = shortcutInfo.getDisabledMessage();
- if (Utilities.ATLEAST_P
- && shortcutInfo.getDisabledReason() == ShortcutInfo.DISABLED_REASON_VERSION_LOWER) {
- runtimeStatusFlags |= FLAG_DISABLED_VERSION_LOWER;
- } else {
- runtimeStatusFlags &= ~FLAG_DISABLED_VERSION_LOWER;
- }
Person[] persons = ApiWrapper.getPersons(shortcutInfo);
personKeys = persons.length == 0 ? Utilities.EMPTY_STRING_ARRAY
: Arrays.stream(persons).map(Person::getKey).sorted().toArray(String[]::new);
}
- /**
- * {@code true} if the shortcut is disabled due to its app being a lower version.
- */
- public boolean isDisabledVersionLower() {
- return (runtimeStatusFlags & FLAG_DISABLED_VERSION_LOWER) != 0;
- }
-
/** Returns the WorkspaceItemInfo id associated with the deep shortcut. */
public String getDeepShortcutId() {
return itemType == Favorites.ITEM_TYPE_DEEP_SHORTCUT
@@ -225,7 +204,7 @@ public class WorkspaceItemInfo extends ItemInfoWithIcon {
}
@Override
- public WorkspaceItemInfo clone() {
+ public ItemInfoWithIcon clone() {
return new WorkspaceItemInfo(this);
}
}
diff --git a/src/com/android/launcher3/notification/NotificationContainer.java b/src/com/android/launcher3/notification/NotificationContainer.java
deleted file mode 100644
index 9eb05cd40f..0000000000
--- a/src/com/android/launcher3/notification/NotificationContainer.java
+++ /dev/null
@@ -1,283 +0,0 @@
-/*
- * Copyright (C) 2021 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.launcher3.notification;
-
-import static com.android.launcher3.anim.Interpolators.scrollInterpolatorForVelocity;
-import static com.android.launcher3.touch.SingleAxisSwipeDetector.HORIZONTAL;
-
-import android.animation.Animator;
-import android.animation.AnimatorSet;
-import android.animation.ObjectAnimator;
-import android.content.Context;
-import android.graphics.Rect;
-import android.util.AttributeSet;
-import android.util.FloatProperty;
-import android.view.MotionEvent;
-import android.view.View;
-import android.widget.FrameLayout;
-
-import com.android.launcher3.R;
-import com.android.launcher3.anim.AnimationSuccessListener;
-import com.android.launcher3.popup.PopupContainerWithArrow;
-import com.android.launcher3.touch.BaseSwipeDetector;
-import com.android.launcher3.touch.OverScroll;
-import com.android.launcher3.touch.SingleAxisSwipeDetector;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-/**
- * Class to manage the notification UI in a {@link PopupContainerWithArrow}.
- *
- * - Has two {@link NotificationMainView} that represent the top two notifications
- * - Handles dismissing a notification
- */
-public class NotificationContainer extends FrameLayout implements SingleAxisSwipeDetector.Listener {
-
- private static final FloatProperty<NotificationContainer> DRAG_TRANSLATION_X =
- new FloatProperty<NotificationContainer>("notificationProgress") {
- @Override
- public void setValue(NotificationContainer view, float transX) {
- view.setDragTranslationX(transX);
- }
-
- @Override
- public Float get(NotificationContainer view) {
- return view.mDragTranslationX;
- }
- };
-
- private static final Rect sTempRect = new Rect();
-
- private final SingleAxisSwipeDetector mSwipeDetector;
- private final List<NotificationInfo> mNotificationInfos = new ArrayList<>();
- private boolean mIgnoreTouch = false;
-
- private final ObjectAnimator mContentTranslateAnimator;
- private float mDragTranslationX = 0;
-
- private final NotificationMainView mPrimaryView;
- private final NotificationMainView mSecondaryView;
- private PopupContainerWithArrow mPopupContainer;
-
- public NotificationContainer(Context context) {
- this(context, null, 0);
- }
-
- public NotificationContainer(Context context, AttributeSet attrs) {
- this(context, attrs, 0);
- }
-
- public NotificationContainer(Context context, AttributeSet attrs, int defStyleAttr) {
- super(context, attrs, defStyleAttr);
- mSwipeDetector = new SingleAxisSwipeDetector(getContext(), this, HORIZONTAL);
- mSwipeDetector.setDetectableScrollConditions(SingleAxisSwipeDetector.DIRECTION_BOTH, false);
- mContentTranslateAnimator = ObjectAnimator.ofFloat(this, DRAG_TRANSLATION_X, 0);
-
- mPrimaryView = (NotificationMainView) View.inflate(getContext(),
- R.layout.notification_content, null);
- mSecondaryView = (NotificationMainView) View.inflate(getContext(),
- R.layout.notification_content, null);
- mSecondaryView.setAlpha(0);
-
- addView(mSecondaryView);
- addView(mPrimaryView);
-
- }
-
- public void setPopupView(PopupContainerWithArrow popupView) {
- mPopupContainer = popupView;
- }
-
- /**
- * Returns true if we should intercept the swipe.
- */
- public boolean onInterceptSwipeEvent(MotionEvent ev) {
- if (ev.getAction() == MotionEvent.ACTION_DOWN) {
- sTempRect.set(getLeft(), getTop(), getRight(), getBottom());
- mIgnoreTouch = !sTempRect.contains((int) ev.getX(), (int) ev.getY());
- if (!mIgnoreTouch) {
- mPopupContainer.getParent().requestDisallowInterceptTouchEvent(true);
- }
- }
- if (mIgnoreTouch) {
- return false;
- }
- if (mPrimaryView.getNotificationInfo() == null) {
- // The notification hasn't been populated yet.
- return false;
- }
-
- mSwipeDetector.onTouchEvent(ev);
- return mSwipeDetector.isDraggingOrSettling();
- }
-
- /**
- * Returns true when we should handle the swipe.
- */
- public boolean onSwipeEvent(MotionEvent ev) {
- if (mIgnoreTouch) {
- return false;
- }
- if (mPrimaryView.getNotificationInfo() == null) {
- // The notification hasn't been populated yet.
- return false;
- }
- return mSwipeDetector.onTouchEvent(ev);
- }
-
- /**
- * Applies the list of @param notificationInfos to this container.
- */
- public void applyNotificationInfos(final List<NotificationInfo> notificationInfos) {
- mNotificationInfos.clear();
- if (notificationInfos.isEmpty()) {
- mPrimaryView.applyNotificationInfo(null);
- mSecondaryView.applyNotificationInfo(null);
- return;
- }
- mNotificationInfos.addAll(notificationInfos);
-
- NotificationInfo mainNotification = notificationInfos.get(0);
- mPrimaryView.applyNotificationInfo(mainNotification);
- mSecondaryView.applyNotificationInfo(notificationInfos.size() > 1
- ? notificationInfos.get(1)
- : null);
- }
-
- /**
- * Trims the notifications.
- * @param notificationKeys List of all valid notification keys.
- */
- public void trimNotifications(final List<String> notificationKeys) {
- Iterator<NotificationInfo> iterator = mNotificationInfos.iterator();
- while (iterator.hasNext()) {
- if (!notificationKeys.contains(iterator.next().notificationKey)) {
- iterator.remove();
- }
- }
-
- NotificationInfo primaryInfo = mNotificationInfos.size() > 0
- ? mNotificationInfos.get(0)
- : null;
- NotificationInfo secondaryInfo = mNotificationInfos.size() > 1
- ? mNotificationInfos.get(1)
- : null;
-
- mPrimaryView.applyNotificationInfo(primaryInfo);
- mSecondaryView.applyNotificationInfo(secondaryInfo);
-
- mPrimaryView.onPrimaryDrag(0);
- mSecondaryView.onSecondaryDrag(0);
- }
-
- private void setDragTranslationX(float translationX) {
- mDragTranslationX = translationX;
-
- float progress = translationX / getWidth();
- mPrimaryView.onPrimaryDrag(progress);
- if (mSecondaryView.getNotificationInfo() == null) {
- mSecondaryView.setAlpha(0f);
- } else {
- mSecondaryView.onSecondaryDrag(progress);
- }
- }
-
- // SingleAxisSwipeDetector.Listener's
- @Override
- public void onDragStart(boolean start, float startDisplacement) {
- mPopupContainer.showArrow(false);
- }
-
- @Override
- public boolean onDrag(float displacement) {
- if (!mPrimaryView.canChildBeDismissed()) {
- displacement = OverScroll.dampedScroll(displacement, getWidth());
- }
-
- float progress = displacement / getWidth();
- mPrimaryView.onPrimaryDrag(progress);
- if (mSecondaryView.getNotificationInfo() == null) {
- mSecondaryView.setAlpha(0f);
- } else {
- mSecondaryView.onSecondaryDrag(progress);
- }
- mContentTranslateAnimator.cancel();
- return true;
- }
-
- @Override
- public void onDragEnd(float velocity) {
- final boolean willExit;
- final float endTranslation;
- final float startTranslation = mPrimaryView.getTranslationX();
- final float width = getWidth();
-
- if (!mPrimaryView.canChildBeDismissed()) {
- willExit = false;
- endTranslation = 0;
- } else if (mSwipeDetector.isFling(velocity)) {
- willExit = true;
- endTranslation = velocity < 0 ? -width : width;
- } else if (Math.abs(startTranslation) > width / 2f) {
- willExit = true;
- endTranslation = (startTranslation < 0 ? -width : width);
- } else {
- willExit = false;
- endTranslation = 0;
- }
-
- long duration = BaseSwipeDetector.calculateDuration(velocity,
- (endTranslation - startTranslation) / width);
-
- mContentTranslateAnimator.removeAllListeners();
- mContentTranslateAnimator.setDuration(duration)
- .setInterpolator(scrollInterpolatorForVelocity(velocity));
- mContentTranslateAnimator.setFloatValues(startTranslation, endTranslation);
-
- NotificationMainView current = mPrimaryView;
- mContentTranslateAnimator.addListener(new AnimationSuccessListener() {
- @Override
- public void onAnimationSuccess(Animator animator) {
- mSwipeDetector.finishedScrolling();
- if (willExit) {
- current.onChildDismissed();
- }
- mPopupContainer.showArrow(true);
- }
- });
- mContentTranslateAnimator.start();
- }
-
- /**
- * Animates the background color to a new color.
- * @param color The color to change to.
- * @param animatorSetOut The AnimatorSet where we add the color animator to.
- */
- public void updateBackgroundColor(int color, AnimatorSet animatorSetOut) {
- mPrimaryView.updateBackgroundColor(color, animatorSetOut);
- mSecondaryView.updateBackgroundColor(color, animatorSetOut);
- }
-
- /**
- * Updates the header with a new @param notificationCount.
- */
- public void updateHeader(int notificationCount) {
- mPrimaryView.updateHeader(notificationCount);
- mSecondaryView.updateHeader(notificationCount - 1);
- }
-}
diff --git a/src/com/android/launcher3/notification/NotificationInfo.java b/src/com/android/launcher3/notification/NotificationInfo.java
index bb2c37f131..d27d8c7778 100644
--- a/src/com/android/launcher3/notification/NotificationInfo.java
+++ b/src/com/android/launcher3/notification/NotificationInfo.java
@@ -16,8 +16,6 @@
package com.android.launcher3.notification;
-import static com.android.launcher3.AbstractFloatingView.TYPE_ACTION_POPUP;
-import static com.android.launcher3.AbstractFloatingView.TYPE_TASKBAR_ALL_APPS;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_NOTIFICATION_LAUNCH_TAP;
import android.app.ActivityOptions;
@@ -31,13 +29,12 @@ import android.service.notification.StatusBarNotification;
import android.view.View;
import com.android.launcher3.AbstractFloatingView;
+import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.dot.DotInfo;
import com.android.launcher3.graphics.IconPalette;
import com.android.launcher3.model.data.ItemInfo;
-import com.android.launcher3.popup.PopupDataProvider;
import com.android.launcher3.util.PackageUserKey;
-import com.android.launcher3.views.ActivityContext;
/**
* An object that contains relevant information from a {@link StatusBarNotification}. This should
@@ -102,24 +99,21 @@ public class NotificationInfo implements View.OnClickListener {
if (intent == null) {
return;
}
- final ActivityContext context = ActivityContext.lookupContext(view.getContext());
+ final Launcher launcher = Launcher.getLauncher(view.getContext());
Bundle activityOptions = ActivityOptions.makeClipRevealAnimation(
view, 0, 0, view.getWidth(), view.getHeight()).toBundle();
try {
intent.send(null, 0, null, null, null, null, activityOptions);
- context.getStatsLogManager().logger().withItemInfo(mItemInfo)
+ launcher.getStatsLogManager().logger().withItemInfo(mItemInfo)
.log(LAUNCHER_NOTIFICATION_LAUNCH_TAP);
} catch (PendingIntent.CanceledException e) {
e.printStackTrace();
}
if (autoCancel) {
- PopupDataProvider popupDataProvider = context.getPopupDataProvider();
- if (popupDataProvider != null) {
- popupDataProvider.cancelNotification(notificationKey);
- }
+ launcher.getPopupDataProvider().cancelNotification(notificationKey);
}
- AbstractFloatingView.closeOpenViews(
- context, true, TYPE_ACTION_POPUP | TYPE_TASKBAR_ALL_APPS);
+ AbstractFloatingView.closeOpenContainer(launcher, AbstractFloatingView
+ .TYPE_ACTION_POPUP);
}
public Drawable getIconForBackground(Context context, int background) {
diff --git a/src/com/android/launcher3/notification/NotificationItemView.java b/src/com/android/launcher3/notification/NotificationItemView.java
new file mode 100644
index 0000000000..af943a6933
--- /dev/null
+++ b/src/com/android/launcher3/notification/NotificationItemView.java
@@ -0,0 +1,179 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.launcher3.notification;
+
+import android.animation.AnimatorSet;
+import android.content.Context;
+import android.graphics.Outline;
+import android.graphics.Rect;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ViewGroup.MarginLayoutParams;
+import android.view.ViewOutlineProvider;
+import android.widget.TextView;
+
+import com.android.launcher3.R;
+import com.android.launcher3.popup.PopupContainerWithArrow;
+import com.android.launcher3.util.Themes;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Utility class to manage notification UI
+ */
+public class NotificationItemView {
+
+ private static final Rect sTempRect = new Rect();
+
+ private final Context mContext;
+ private final PopupContainerWithArrow mPopupContainer;
+ private final ViewGroup mRootView;
+
+ private final TextView mHeaderCount;
+ private final NotificationMainView mMainView;
+
+ private final View mHeader;
+
+ private View mGutter;
+
+ private boolean mIgnoreTouch = false;
+ private List<NotificationInfo> mNotificationInfos = new ArrayList<>();
+
+ public NotificationItemView(PopupContainerWithArrow container, ViewGroup rootView) {
+ mPopupContainer = container;
+ mRootView = rootView;
+ mContext = container.getContext();
+
+ mHeaderCount = container.findViewById(R.id.notification_count);
+ mMainView = container.findViewById(R.id.main_view);
+
+ mHeader = container.findViewById(R.id.header);
+
+ float radius = Themes.getDialogCornerRadius(mContext);
+ rootView.setClipToOutline(true);
+ rootView.setOutlineProvider(new ViewOutlineProvider() {
+ @Override
+ public void getOutline(View view, Outline outline) {
+ outline.setRoundRect(0, 0, view.getWidth(), view.getHeight(), radius);
+ }
+ });
+ }
+
+ /**
+ * Animates the background color to a new color.
+ * @param color The color to change to.
+ * @param animatorSetOut The AnimatorSet where we add the color animator to.
+ */
+ public void updateBackgroundColor(int color, AnimatorSet animatorSetOut) {
+ mMainView.updateBackgroundColor(color, animatorSetOut);
+ }
+
+ public void addGutter() {
+ if (mGutter == null) {
+ mGutter = mPopupContainer.inflateAndAdd(R.layout.notification_gutter, mRootView);
+ }
+ }
+
+ public void inverseGutterMargin() {
+ MarginLayoutParams lp = (MarginLayoutParams) mGutter.getLayoutParams();
+ int top = lp.topMargin;
+ lp.topMargin = lp.bottomMargin;
+ lp.bottomMargin = top;
+ }
+
+ public void removeAllViews() {
+ mRootView.removeView(mMainView);
+ mRootView.removeView(mHeader);
+ if (mGutter != null) {
+ mRootView.removeView(mGutter);
+ }
+ }
+
+ /**
+ * Updates the header text.
+ * @param notificationCount The number of notifications.
+ */
+ public void updateHeader(int notificationCount) {
+ final String text;
+ final int visibility;
+ if (notificationCount <= 1) {
+ text = "";
+ visibility = View.INVISIBLE;
+ } else {
+ text = String.valueOf(notificationCount);
+ visibility = View.VISIBLE;
+
+ }
+ mHeaderCount.setText(text);
+ mHeaderCount.setVisibility(visibility);
+ }
+
+ public boolean onInterceptTouchEvent(MotionEvent ev) {
+ if (ev.getAction() == MotionEvent.ACTION_DOWN) {
+ sTempRect.set(mRootView.getLeft(), mRootView.getTop(),
+ mRootView.getRight(), mRootView.getBottom());
+ mIgnoreTouch = !sTempRect.contains((int) ev.getX(), (int) ev.getY());
+ if (!mIgnoreTouch) {
+ mPopupContainer.getParent().requestDisallowInterceptTouchEvent(true);
+ }
+ }
+ if (mIgnoreTouch) {
+ return false;
+ }
+ if (mMainView.getNotificationInfo() == null) {
+ // The notification hasn't been populated yet.
+ return false;
+ }
+
+ return false;
+ }
+
+ public void applyNotificationInfos(final List<NotificationInfo> notificationInfos) {
+ mNotificationInfos.clear();
+ if (notificationInfos.isEmpty()) {
+ return;
+ }
+ mNotificationInfos.addAll(notificationInfos);
+
+ NotificationInfo mainNotification = notificationInfos.get(0);
+ mMainView.applyNotificationInfo(mainNotification, false);
+ }
+
+ public void trimNotifications(final List<String> notificationKeys) {
+ NotificationInfo currentMainNotificationInfo = mMainView.getNotificationInfo();
+ boolean shouldUpdateMainNotification = !notificationKeys.contains(
+ currentMainNotificationInfo.notificationKey);
+
+ if (shouldUpdateMainNotification) {
+ int size = notificationKeys.size();
+ NotificationInfo nextNotification = null;
+ // We get the latest notification by finding the notification after the one that was
+ // just dismissed.
+ for (int i = 0; i < size; ++i) {
+ if (currentMainNotificationInfo == mNotificationInfos.get(i) && i + 1 < size) {
+ nextNotification = mNotificationInfos.get(i + 1);
+ break;
+ }
+ }
+ if (nextNotification != null) {
+ mMainView.applyNotificationInfo(nextNotification, true);
+ }
+ }
+ }
+}
diff --git a/src/com/android/launcher3/notification/NotificationListener.java b/src/com/android/launcher3/notification/NotificationListener.java
index 04eb38a3c5..e58f5fa2d5 100644
--- a/src/com/android/launcher3/notification/NotificationListener.java
+++ b/src/com/android/launcher3/notification/NotificationListener.java
@@ -30,12 +30,10 @@ import android.os.Message;
import android.service.notification.NotificationListenerService;
import android.service.notification.StatusBarNotification;
import android.text.TextUtils;
-import android.util.ArraySet;
import android.util.Log;
import android.util.Pair;
import androidx.annotation.AnyThread;
-import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.WorkerThread;
@@ -68,8 +66,7 @@ public class NotificationListener extends NotificationListenerService {
private static final int MSG_RANKING_UPDATE = 5;
private static NotificationListener sNotificationListenerInstance = null;
- private static final ArraySet<NotificationsChangedListener> sNotificationsChangedListeners =
- new ArraySet<>();
+ private static NotificationsChangedListener sNotificationsChangedListener;
private static boolean sIsConnected;
private final Handler mWorkerHandler;
@@ -97,11 +94,8 @@ public class NotificationListener extends NotificationListenerService {
return sIsConnected ? sNotificationListenerInstance : null;
}
- public static void addNotificationsChangedListener(NotificationsChangedListener listener) {
- if (listener == null) {
- return;
- }
- sNotificationsChangedListeners.add(listener);
+ public static void setNotificationsChangedListener(NotificationsChangedListener listener) {
+ sNotificationsChangedListener = listener;
NotificationListener notificationListener = getInstanceIfConnected();
if (notificationListener != null) {
@@ -114,10 +108,8 @@ public class NotificationListener extends NotificationListenerService {
}
}
- public static void removeNotificationsChangedListener(NotificationsChangedListener listener) {
- if (listener != null) {
- sNotificationsChangedListeners.remove(listener);
- }
+ public static void removeNotificationsChangedListener() {
+ sNotificationsChangedListener = null;
}
private boolean handleWorkerMessage(Message message) {
@@ -155,9 +147,14 @@ public class NotificationListener extends NotificationListenerService {
case MSG_NOTIFICATION_FULL_REFRESH:
List<StatusBarNotification> activeNotifications = null;
if (sIsConnected) {
- activeNotifications = Arrays.stream(getActiveNotificationsSafely(null))
- .filter(this::notificationIsValidForUI)
- .collect(Collectors.toList());
+ try {
+ activeNotifications = Arrays.stream(getActiveNotifications())
+ .filter(this::notificationIsValidForUI)
+ .collect(Collectors.toList());
+ } catch (SecurityException ex) {
+ Log.e(TAG, "SecurityException: failed to fetch notifications");
+ activeNotifications = new ArrayList<>();
+ }
} else {
activeNotifications = new ArrayList<>();
}
@@ -171,7 +168,7 @@ public class NotificationListener extends NotificationListenerService {
}
case MSG_RANKING_UPDATE: {
String[] keys = ((RankingMap) message.obj).getOrderedKeys();
- for (StatusBarNotification sbn : getActiveNotificationsSafely(keys)) {
+ for (StatusBarNotification sbn : getActiveNotifications(keys)) {
updateGroupKeyIfNecessary(sbn);
}
return true;
@@ -183,43 +180,29 @@ public class NotificationListener extends NotificationListenerService {
private boolean handleUiMessage(Message message) {
switch (message.what) {
case MSG_NOTIFICATION_POSTED:
- if (sNotificationsChangedListeners.size() > 0) {
+ if (sNotificationsChangedListener != null) {
Pair<PackageUserKey, NotificationKeyData> msg = (Pair) message.obj;
- for (NotificationsChangedListener listener : sNotificationsChangedListeners) {
- listener.onNotificationPosted(msg.first, msg.second);
- }
+ sNotificationsChangedListener.onNotificationPosted(
+ msg.first, msg.second);
}
break;
case MSG_NOTIFICATION_REMOVED:
- if (sNotificationsChangedListeners.size() > 0) {
+ if (sNotificationsChangedListener != null) {
Pair<PackageUserKey, NotificationKeyData> msg = (Pair) message.obj;
- for (NotificationsChangedListener listener : sNotificationsChangedListeners) {
- listener.onNotificationRemoved(msg.first, msg.second);
- }
+ sNotificationsChangedListener.onNotificationRemoved(
+ msg.first, msg.second);
}
break;
case MSG_NOTIFICATION_FULL_REFRESH:
- if (sNotificationsChangedListeners.size() > 0) {
- for (NotificationsChangedListener listener : sNotificationsChangedListeners) {
- listener.onNotificationFullRefresh(
- (List<StatusBarNotification>) message.obj);
- }
+ if (sNotificationsChangedListener != null) {
+ sNotificationsChangedListener.onNotificationFullRefresh(
+ (List<StatusBarNotification>) message.obj);
}
break;
}
return true;
}
- private @NonNull StatusBarNotification[] getActiveNotificationsSafely(@Nullable String[] keys) {
- StatusBarNotification[] result = null;
- try {
- result = getActiveNotifications(keys);
- } catch (SecurityException e) {
- Log.e(TAG, "SecurityException: failed to fetch notifications");
- }
- return result == null ? new StatusBarNotification[0] : result;
- }
-
@Override
public void onListenerConnected() {
super.onListenerConnected();
@@ -319,8 +302,9 @@ public class NotificationListener extends NotificationListenerService {
*/
@WorkerThread
public List<StatusBarNotification> getNotificationsForKeys(List<NotificationKeyData> keys) {
- return Arrays.asList(getActiveNotificationsSafely(
- keys.stream().map(n -> n.notificationKey).toArray(String[]::new)));
+ StatusBarNotification[] notifications = getActiveNotifications(
+ keys.stream().map(n -> n.notificationKey).toArray(String[]::new));
+ return notifications == null ? Collections.emptyList() : Arrays.asList(notifications);
}
/**
diff --git a/src/com/android/launcher3/notification/NotificationMainView.java b/src/com/android/launcher3/notification/NotificationMainView.java
index 16a40576b8..b8aa8246fb 100644
--- a/src/com/android/launcher3/notification/NotificationMainView.java
+++ b/src/com/android/launcher3/notification/NotificationMainView.java
@@ -16,71 +16,62 @@
package com.android.launcher3.notification;
-import static com.android.launcher3.Utilities.mapToRange;
-import static com.android.launcher3.anim.Interpolators.LINEAR;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_NOTIFICATION_DISMISSED;
import android.animation.AnimatorSet;
+import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.annotation.TargetApi;
import android.content.Context;
-import android.graphics.Outline;
-import android.graphics.Rect;
-import android.graphics.drawable.GradientDrawable;
+import android.graphics.Color;
+import android.graphics.drawable.ColorDrawable;
import android.os.Build;
import android.text.TextUtils;
import android.util.AttributeSet;
+import android.util.FloatProperty;
import android.view.View;
import android.view.ViewGroup;
-import android.view.ViewOutlineProvider;
-import android.widget.LinearLayout;
+import android.widget.FrameLayout;
import android.widget.TextView;
-import androidx.annotation.Nullable;
-
+import com.android.launcher3.Launcher;
import com.android.launcher3.R;
-import com.android.launcher3.Utilities;
import com.android.launcher3.model.data.ItemInfo;
-import com.android.launcher3.popup.PopupDataProvider;
-import com.android.launcher3.util.Themes;
-import com.android.launcher3.views.ActivityContext;
+import com.android.launcher3.touch.SingleAxisSwipeDetector;
/**
* A {@link android.widget.FrameLayout} that contains a single notification,
* e.g. icon + title + text.
*/
@TargetApi(Build.VERSION_CODES.N)
-public class NotificationMainView extends LinearLayout {
+public class NotificationMainView extends FrameLayout {
+
+ private static final FloatProperty<NotificationMainView> CONTENT_TRANSLATION =
+ new FloatProperty<NotificationMainView>("contentTranslation") {
+ @Override
+ public void setValue(NotificationMainView view, float v) {
+ view.setContentTranslation(v);
+ }
+
+ @Override
+ public Float get(NotificationMainView view) {
+ return view.mTextAndBackground.getTranslationX();
+ }
+ };
// This is used only to track the notification view, so that it can be properly logged.
public static final ItemInfo NOTIFICATION_ITEM_INFO = new ItemInfo();
- // Value when the primary notification main view will be gone (zero alpha).
- private static final float PRIMARY_GONE_PROGRESS = 0.7f;
- private static final float PRIMARY_MIN_PROGRESS = 0.40f;
- private static final float PRIMARY_MAX_PROGRESS = 0.60f;
- private static final float SECONDARY_MIN_PROGRESS = 0.30f;
- private static final float SECONDARY_MAX_PROGRESS = 0.50f;
- private static final float SECONDARY_CONTENT_MAX_PROGRESS = 0.6f;
-
private NotificationInfo mNotificationInfo;
+ private ViewGroup mTextAndBackground;
private int mBackgroundColor;
private TextView mTitleView;
private TextView mTextView;
private View mIconView;
- private View mHeader;
- private View mMainView;
-
- private TextView mHeaderCount;
- private final Rect mOutline = new Rect();
+ private SingleAxisSwipeDetector mSwipeDetector;
- // Space between notifications during swipe
- private final int mNotificationSpace;
- private final int mMaxTransX;
- private final int mMaxElevation;
-
- private final GradientDrawable mBackground;
+ private final ColorDrawable mColorDrawable;
public NotificationMainView(Context context) {
this(context, null, 0);
@@ -91,77 +82,28 @@ public class NotificationMainView extends LinearLayout {
}
public NotificationMainView(Context context, AttributeSet attrs, int defStyle) {
- this(context, attrs, defStyle, 0);
- }
-
- public NotificationMainView(Context context, AttributeSet attrs, int defStyle, int defStylRes) {
- super(context, attrs, defStyle, defStylRes);
-
- float outlineRadius = Themes.getDialogCornerRadius(context);
-
- mBackground = new GradientDrawable();
- mBackground.setColor(Themes.getAttrColor(context, R.attr.popupColorPrimary));
- mBackground.setCornerRadius(outlineRadius);
- setBackground(mBackground);
-
- mMaxElevation = getResources().getDimensionPixelSize(R.dimen.deep_shortcuts_elevation);
- setElevation(mMaxElevation);
-
- mMaxTransX = getResources().getDimensionPixelSize(R.dimen.notification_max_trans);
- mNotificationSpace = getResources().getDimensionPixelSize(R.dimen.notification_space);
+ super(context, attrs, defStyle);
- setClipToOutline(true);
- setOutlineProvider(new ViewOutlineProvider() {
- @Override
- public void getOutline(View view, Outline outline) {
- outline.setRoundRect(mOutline, outlineRadius);
- }
- });
- }
-
- /**
- * Updates the header text.
- * @param notificationCount The number of notifications.
- */
- public void updateHeader(int notificationCount) {
- final String text;
- final int visibility;
- if (notificationCount <= 1) {
- text = "";
- visibility = View.INVISIBLE;
- } else {
- text = String.valueOf(notificationCount);
- visibility = View.VISIBLE;
-
- }
- mHeaderCount.setText(text);
- mHeaderCount.setVisibility(visibility);
+ mColorDrawable = new ColorDrawable(Color.TRANSPARENT);
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
- ViewGroup textAndBackground = findViewById(R.id.text_and_background);
- mTitleView = textAndBackground.findViewById(R.id.title);
- mTextView = textAndBackground.findViewById(R.id.text);
+ mTextAndBackground = findViewById(R.id.text_and_background);
+ mTitleView = mTextAndBackground.findViewById(R.id.title);
+ mTextView = mTextAndBackground.findViewById(R.id.text);
mIconView = findViewById(R.id.popup_item_icon);
- mHeaderCount = findViewById(R.id.notification_count);
-
- mHeader = findViewById(R.id.header);
- mMainView = findViewById(R.id.main_view);
- }
- @Override
- protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- super.onMeasure(widthMeasureSpec, heightMeasureSpec);
- mOutline.set(0, 0, getWidth(), getHeight());
- invalidateOutline();
+ ColorDrawable colorBackground = (ColorDrawable) mTextAndBackground.getBackground();
+ updateBackgroundColor(colorBackground.getColor());
}
private void updateBackgroundColor(int color) {
mBackgroundColor = color;
- mBackground.setColor(color);
+ mColorDrawable.setColor(color);
+ mTextAndBackground.setBackground(mColorDrawable);
if (mNotificationInfo != null) {
mIconView.setBackground(mNotificationInfo.getIconForBackground(getContext(),
mBackgroundColor));
@@ -186,11 +128,8 @@ public class NotificationMainView extends LinearLayout {
/**
* Sets the content of this view, animating it after a new icon shifts up if necessary.
*/
- public void applyNotificationInfo(NotificationInfo notificationInfo) {
- mNotificationInfo = notificationInfo;
- if (notificationInfo == null) {
- return;
- }
+ public void applyNotificationInfo(NotificationInfo mainNotification, boolean animate) {
+ mNotificationInfo = mainNotification;
NotificationListener listener = NotificationListener.getInstanceIfConnected();
if (listener != null) {
listener.setNotificationsShown(new String[] {mNotificationInfo.notificationKey});
@@ -210,123 +149,33 @@ public class NotificationMainView extends LinearLayout {
if (mNotificationInfo.intent != null) {
setOnClickListener(mNotificationInfo);
}
-
+ setContentTranslation(0);
// Add a stub ItemInfo so that logging populates the correct container and item types
// instead of DEFAULT_CONTAINERTYPE and DEFAULT_ITEMTYPE, respectively.
setTag(NOTIFICATION_ITEM_INFO);
- }
-
- /**
- * Sets the alpha of only the child views.
- */
- public void setContentAlpha(float alpha) {
- mHeader.setAlpha(alpha);
- mMainView.setAlpha(alpha);
- }
-
- /**
- * Sets the translation of only the child views.
- */
- public void setContentTranslationX(float transX) {
- mHeader.setTranslationX(transX);
- mMainView.setTranslationX(transX);
- }
-
- /**
- * Updates the alpha, content alpha, and elevation of this view.
- *
- * @param progress Range from [0, 1] or [-1, 0]
- * When 0: Full alpha
- * When 1/-1: zero alpha
- */
- public void onPrimaryDrag(float progress) {
- float absProgress = Math.abs(progress);
- final int width = getWidth();
-
- float min = PRIMARY_MIN_PROGRESS;
- float max = PRIMARY_MAX_PROGRESS;
-
- if (absProgress < min) {
- setAlpha(1f);
- setContentAlpha(1);
- setElevation(mMaxElevation);
- } else if (absProgress < max) {
- setAlpha(1f);
- setContentAlpha(mapToRange(absProgress, min, max, 1f, 0f, LINEAR));
- setElevation(Utilities.mapToRange(absProgress, min, max, mMaxElevation, 0, LINEAR));
- } else {
- setAlpha(mapToRange(absProgress, max, PRIMARY_GONE_PROGRESS, 1f, 0f, LINEAR));
- setContentAlpha(0f);
- setElevation(0f);
+ if (animate) {
+ ObjectAnimator.ofFloat(mTextAndBackground, ALPHA, 0, 1).setDuration(150).start();
}
-
- setTranslationX(width * progress);
}
- /**
- * Updates the alpha, content alpha, elevation, and clipping of this view.
- * @param progress Range from [0, 1] or [-1, 0]
- * When 0: Smallest clipping, zero alpha
- * When 1/-1: Full clip, full alpha
- */
- public void onSecondaryDrag(float progress) {
- final float absProgress = Math.abs(progress);
-
- float min = SECONDARY_MIN_PROGRESS;
- float max = SECONDARY_MAX_PROGRESS;
- float contentMax = SECONDARY_CONTENT_MAX_PROGRESS;
-
- if (absProgress < min) {
- setAlpha(0f);
- setContentAlpha(0);
- setElevation(0f);
- } else if (absProgress < max) {
- setAlpha(mapToRange(absProgress, min, max, 0, 1f, LINEAR));
- setContentAlpha(0f);
- setElevation(0f);
- } else {
- setAlpha(1f);
- setContentAlpha(absProgress > contentMax
- ? 1f
- : mapToRange(absProgress, max, contentMax, 0, 1f, LINEAR));
- setElevation(Utilities.mapToRange(absProgress, max, 1, 0, mMaxElevation, LINEAR));
- }
-
- final int width = getWidth();
- int crop = (int) (width * absProgress);
- int space = (int) (absProgress > PRIMARY_GONE_PROGRESS
- ? mapToRange(absProgress, PRIMARY_GONE_PROGRESS, 1f, mNotificationSpace, 0, LINEAR)
- : mNotificationSpace);
- if (progress < 0) {
- mOutline.left = Math.max(0, getWidth() - crop + space);
- mOutline.right = getWidth();
- } else {
- mOutline.right = Math.min(getWidth(), crop - space);
- mOutline.left = 0;
- }
-
- float contentTransX = mMaxTransX * (1f - absProgress);
- setContentTranslationX(progress < 0
- ? contentTransX
- : -contentTransX);
- invalidateOutline();
+ public void setContentTranslation(float translation) {
+ mTextAndBackground.setTranslationX(translation);
+ mIconView.setTranslationX(translation);
}
- public @Nullable NotificationInfo getNotificationInfo() {
+ public NotificationInfo getNotificationInfo() {
return mNotificationInfo;
}
+
public boolean canChildBeDismissed() {
return mNotificationInfo != null && mNotificationInfo.dismissable;
}
public void onChildDismissed() {
- ActivityContext activityContext = ActivityContext.lookupContext(getContext());
- PopupDataProvider popupDataProvider = activityContext.getPopupDataProvider();
- if (popupDataProvider == null) {
- return;
- }
- popupDataProvider.cancelNotification(mNotificationInfo.notificationKey);
- activityContext.getStatsLogManager().logger().log(LAUNCHER_NOTIFICATION_DISMISSED);
+ Launcher launcher = Launcher.getLauncher(getContext());
+ launcher.getPopupDataProvider().cancelNotification(
+ mNotificationInfo.notificationKey);
+ launcher.getStatsLogManager().logger().log(LAUNCHER_NOTIFICATION_DISMISSED);
}
}
diff --git a/src/com/android/launcher3/pageindicators/PageIndicator.java b/src/com/android/launcher3/pageindicators/PageIndicator.java
index ec691931a1..8fafb6fdde 100644
--- a/src/com/android/launcher3/pageindicators/PageIndicator.java
+++ b/src/com/android/launcher3/pageindicators/PageIndicator.java
@@ -25,25 +25,4 @@ public interface PageIndicator {
void setActiveMarker(int activePage);
void setMarkersCount(int numMarkers);
-
- /**
- * Sets the flag if the Page Indicator should autohide.
- */
- default void setShouldAutoHide(boolean shouldAutoHide) {
- // No-op by default
- }
-
- /**
- * Pauses all currently running animations.
- */
- default void pauseAnimations() {
- // No-op by default
- }
-
- /**
- * Force-ends all currently running or paused animations.
- */
- default void skipAnimationsToEnd() {
- // No-op by default
- }
}
diff --git a/src/com/android/launcher3/pageindicators/PageIndicatorDots.java b/src/com/android/launcher3/pageindicators/PageIndicatorDots.java
index 29eefe2a03..f7c730a6c5 100644
--- a/src/com/android/launcher3/pageindicators/PageIndicatorDots.java
+++ b/src/com/android/launcher3/pageindicators/PageIndicatorDots.java
@@ -53,9 +53,6 @@ public class PageIndicatorDots extends View implements PageIndicator {
private static final int ENTER_ANIMATION_STAGGERED_DELAY = 150;
private static final int ENTER_ANIMATION_DURATION = 400;
- private static final int DOT_ACTIVE_ALPHA = 255;
- private static final int DOT_INACTIVE_ALPHA = 128;
-
// This value approximately overshoots to 1.5 times the original size.
private static final float ENTER_ANIMATION_OVERSHOOT_TENSION = 4.9f;
@@ -78,6 +75,8 @@ public class PageIndicatorDots extends View implements PageIndicator {
private final Paint mCirclePaint;
private final float mDotRadius;
+ private final int mActiveColor;
+ private final int mInActiveColor;
private final boolean mIsRtl;
private int mNumPages;
@@ -111,10 +110,12 @@ public class PageIndicatorDots extends View implements PageIndicator {
mCirclePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mCirclePaint.setStyle(Style.FILL);
- mCirclePaint.setColor(Themes.getAttrColor(context, R.attr.folderPaginationColor));
mDotRadius = getResources().getDimension(R.dimen.page_indicator_dot_size) / 2;
setOutlineProvider(new MyOutlineProver());
+ mActiveColor = Themes.getColorAccent(context);
+ mInActiveColor = Themes.getAttrColor(context, android.R.attr.colorControlHighlight);
+
mIsRtl = Utilities.isRtl(getResources());
}
@@ -252,18 +253,18 @@ public class PageIndicatorDots extends View implements PageIndicator {
circleGap = -circleGap;
}
for (int i = 0; i < mEntryAnimationRadiusFactors.length; i++) {
- mCirclePaint.setAlpha(i == mActivePage ? DOT_ACTIVE_ALPHA : DOT_INACTIVE_ALPHA);
+ mCirclePaint.setColor(i == mActivePage ? mActiveColor : mInActiveColor);
canvas.drawCircle(x, y, mDotRadius * mEntryAnimationRadiusFactors[i], mCirclePaint);
x += circleGap;
}
} else {
- mCirclePaint.setAlpha(DOT_INACTIVE_ALPHA);
+ mCirclePaint.setColor(mInActiveColor);
for (int i = 0; i < mNumPages; i++) {
canvas.drawCircle(x, y, mDotRadius, mCirclePaint);
x += circleGap;
}
- mCirclePaint.setAlpha(DOT_ACTIVE_ALPHA);
+ mCirclePaint.setColor(mActiveColor);
canvas.drawRoundRect(getActiveRect(), mDotRadius, mDotRadius, mCirclePaint);
}
}
diff --git a/src/com/android/launcher3/pageindicators/WorkspacePageIndicator.java b/src/com/android/launcher3/pageindicators/WorkspacePageIndicator.java
index 1681ea5758..f73d782685 100644
--- a/src/com/android/launcher3/pageindicators/WorkspacePageIndicator.java
+++ b/src/com/android/launcher3/pageindicators/WorkspacePageIndicator.java
@@ -187,7 +187,6 @@ public class WorkspacePageIndicator extends View implements Insettable, PageIndi
}
}
- @Override
public void setShouldAutoHide(boolean shouldAutoHide) {
mShouldAutoHide = shouldAutoHide;
if (shouldAutoHide && mLinePaint.getAlpha() > 0) {
@@ -237,7 +236,6 @@ public class WorkspacePageIndicator extends View implements Insettable, PageIndi
/**
* Pauses all currently running animations.
*/
- @Override
public void pauseAnimations() {
for (int i = 0; i < ANIMATOR_COUNT; i++) {
if (mAnimators[i] != null) {
@@ -249,7 +247,6 @@ public class WorkspacePageIndicator extends View implements Insettable, PageIndi
/**
* Force-ends all currently running or paused animations.
*/
- @Override
public void skipAnimationsToEnd() {
for (int i = 0; i < ANIMATOR_COUNT; i++) {
if (mAnimators[i] != null) {
@@ -271,7 +268,9 @@ public class WorkspacePageIndicator extends View implements Insettable, PageIndi
} else {
lp.leftMargin = lp.rightMargin = 0;
lp.gravity = Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
- lp.bottomMargin = grid.hotseatBarSizePx + insets.bottom;
+ lp.bottomMargin = grid.isTaskbarPresent
+ ? grid.workspacePadding.bottom + grid.taskbarSize
+ : grid.hotseatBarSizePx + insets.bottom;
}
setLayoutParams(lp);
}
diff --git a/src/com/android/launcher3/pm/InstallSessionHelper.java b/src/com/android/launcher3/pm/InstallSessionHelper.java
index 618f926bc3..ab35bd6175 100644
--- a/src/com/android/launcher3/pm/InstallSessionHelper.java
+++ b/src/com/android/launcher3/pm/InstallSessionHelper.java
@@ -17,6 +17,7 @@
package com.android.launcher3.pm;
import static com.android.launcher3.Utilities.getPrefs;
+import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
import android.content.Context;
import android.content.pm.ApplicationInfo;
@@ -24,10 +25,10 @@ import android.content.pm.LauncherApps;
import android.content.pm.PackageInstaller;
import android.content.pm.PackageInstaller.SessionInfo;
import android.content.pm.PackageManager;
+import android.os.Build;
import android.os.Process;
import android.os.UserHandle;
import android.text.TextUtils;
-import android.util.Log;
import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
@@ -39,7 +40,6 @@ import com.android.launcher3.Utilities;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.logging.FileLog;
import com.android.launcher3.model.ItemInstallQueue;
-import com.android.launcher3.testing.TestProtocol;
import com.android.launcher3.util.IntArray;
import com.android.launcher3.util.IntSet;
import com.android.launcher3.util.MainThreadInitializedObject;
@@ -144,16 +144,6 @@ public class InstallSessionHelper {
if (sessionInfo == null
|| sessionInfo.getInstallerPackageName() == null
|| TextUtils.isEmpty(sessionInfo.getAppPackageName())) {
- if (TestProtocol.sDebugTracing) {
- Log.d(TestProtocol.MISSING_PROMISE_ICON, LOG + " verify"
- + ", info=" + (sessionInfo == null)
- + ", info install name" + (sessionInfo == null
- ? null
- : sessionInfo.getInstallerPackageName())
- + ", empty pkg name" + TextUtils.isEmpty((sessionInfo == null
- ? null
- : sessionInfo.getAppPackageName())));
- }
return null;
}
String pkg = sessionInfo.getInstallerPackageName();
@@ -223,14 +213,6 @@ public class InstallSessionHelper {
*/
@WorkerThread
void tryQueuePromiseAppIcon(PackageInstaller.SessionInfo sessionInfo) {
- if (TestProtocol.sDebugTracing) {
- Log.d(TestProtocol.MISSING_PROMISE_ICON, LOG + " tryQueuePromiseAppIcon"
- + ", FeatureFlags=" + FeatureFlags.PROMISE_APPS_NEW_INSTALLS.get()
- + ", SessionCommitReceiveEnabled" + SessionCommitReceiver.isEnabled(mAppContext)
- + ", verifySessionInfo(sessionInfo)=" + verifySessionInfo(sessionInfo)
- + ", !promiseIconAdded=" + (sessionInfo != null
- && !promiseIconAddedForId(sessionInfo.getSessionId())));
- }
if (FeatureFlags.PROMISE_APPS_NEW_INSTALLS.get()
&& SessionCommitReceiver.isEnabled(mAppContext)
&& verifySessionInfo(sessionInfo)
@@ -247,20 +229,6 @@ public class InstallSessionHelper {
}
public boolean verifySessionInfo(PackageInstaller.SessionInfo sessionInfo) {
- if (TestProtocol.sDebugTracing) {
- boolean appNotInstalled = sessionInfo == null
- || !new PackageManagerHelper(mAppContext)
- .isAppInstalled(sessionInfo.getAppPackageName(), getUserHandle(sessionInfo));
- boolean labelNotEmpty = sessionInfo != null
- && !TextUtils.isEmpty(sessionInfo.getAppLabel());
- Log.d(TestProtocol.MISSING_PROMISE_ICON, LOG + " verifySessionInfo"
- + ", verify(sessionInfo)=" + verify(sessionInfo)
- + ", reason=" + (sessionInfo == null ? null : sessionInfo.getInstallReason())
- + ", PackageManager.INSTALL_REASON_USER=" + PackageManager.INSTALL_REASON_USER
- + ", hasIcon=" + (sessionInfo != null && sessionInfo.getAppIcon() != null)
- + ", label is ! empty=" + labelNotEmpty
- + " +, app not installed=" + appNotInstalled);
- }
return verify(sessionInfo) != null
&& sessionInfo.getInstallReason() == PackageManager.INSTALL_REASON_USER
&& sessionInfo.getAppIcon() != null
@@ -270,12 +238,24 @@ public class InstallSessionHelper {
}
public InstallSessionTracker registerInstallTracker(InstallSessionTracker.Callback callback) {
- InstallSessionTracker tracker = new InstallSessionTracker(
- this, callback, mInstaller, mLauncherApps);
- tracker.register();
+ InstallSessionTracker tracker = new InstallSessionTracker(this, callback);
+
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
+ mInstaller.registerSessionCallback(tracker, MODEL_EXECUTOR.getHandler());
+ } else {
+ mLauncherApps.registerPackageInstallerSessionCallback(MODEL_EXECUTOR, tracker);
+ }
return tracker;
}
+ void unregister(InstallSessionTracker tracker) {
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
+ mInstaller.unregisterSessionCallback(tracker);
+ } else {
+ mLauncherApps.unregisterPackageInstallerSessionCallback(tracker);
+ }
+ }
+
public static UserHandle getUserHandle(SessionInfo info) {
return Utilities.ATLEAST_Q ? info.getUser() : Process.myUserHandle();
}
diff --git a/src/com/android/launcher3/pm/InstallSessionTracker.java b/src/com/android/launcher3/pm/InstallSessionTracker.java
index 75cf7a845b..b0b907ab19 100644
--- a/src/com/android/launcher3/pm/InstallSessionTracker.java
+++ b/src/com/android/launcher3/pm/InstallSessionTracker.java
@@ -18,77 +18,45 @@ package com.android.launcher3.pm;
import static com.android.launcher3.pm.InstallSessionHelper.getUserHandle;
import static com.android.launcher3.pm.PackageInstallInfo.STATUS_FAILED;
import static com.android.launcher3.pm.PackageInstallInfo.STATUS_INSTALLED;
-import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
-import android.content.pm.LauncherApps;
import android.content.pm.PackageInstaller;
import android.content.pm.PackageInstaller.SessionInfo;
-import android.os.Build;
import android.os.UserHandle;
-import android.util.Log;
import android.util.SparseArray;
import androidx.annotation.WorkerThread;
-import com.android.launcher3.testing.TestProtocol;
import com.android.launcher3.util.PackageUserKey;
-import java.lang.ref.WeakReference;
-
@WorkerThread
public class InstallSessionTracker extends PackageInstaller.SessionCallback {
// Lazily initialized
private SparseArray<PackageUserKey> mActiveSessions = null;
- private final WeakReference<InstallSessionHelper> mWeakHelper;
- private final WeakReference<Callback> mWeakCallback;
- private final PackageInstaller mInstaller;
- private final LauncherApps mLauncherApps;
-
+ private final InstallSessionHelper mInstallerCompat;
+ private final Callback mCallback;
- InstallSessionTracker(InstallSessionHelper installerCompat, Callback callback,
- PackageInstaller installer, LauncherApps launcherApps) {
- mWeakHelper = new WeakReference<>(installerCompat);
- mWeakCallback = new WeakReference<>(callback);
- mInstaller = installer;
- mLauncherApps = launcherApps;
+ InstallSessionTracker(InstallSessionHelper installerCompat, Callback callback) {
+ mInstallerCompat = installerCompat;
+ mCallback = callback;
}
@Override
public void onCreated(int sessionId) {
- InstallSessionHelper helper = mWeakHelper.get();
- Callback callback = mWeakCallback.get();
- if (TestProtocol.sDebugTracing) {
- Log.d(TestProtocol.MISSING_PROMISE_ICON, "Session created sessionId=" + sessionId
- + ", callback=" + callback
- + ", helper=" + helper);
- }
- if (callback == null || helper == null) {
- return;
- }
- SessionInfo sessionInfo = pushSessionDisplayToLauncher(sessionId, helper, callback);
- if (TestProtocol.sDebugTracing) {
- Log.d(TestProtocol.MISSING_PROMISE_ICON, "Session created sessionId=" + sessionId
- + ", sessionInfo=" + sessionInfo);
- }
+ SessionInfo sessionInfo = pushSessionDisplayToLauncher(sessionId);
if (sessionInfo != null) {
- callback.onInstallSessionCreated(PackageInstallInfo.fromInstallingState(sessionInfo));
+ mCallback.onInstallSessionCreated(PackageInstallInfo.fromInstallingState(sessionInfo));
}
- helper.tryQueuePromiseAppIcon(sessionInfo);
+ mInstallerCompat.tryQueuePromiseAppIcon(sessionInfo);
}
@Override
public void onFinished(int sessionId, boolean success) {
- InstallSessionHelper helper = mWeakHelper.get();
- Callback callback = mWeakCallback.get();
- if (callback == null || helper == null) {
- return;
- }
// For a finished session, we can't get the session info. So use the
// packageName from our local cache.
- SparseArray<PackageUserKey> activeSessions = getActiveSessionMap(helper);
+ SparseArray<PackageUserKey> activeSessions = getActiveSessionMap();
PackageUserKey key = activeSessions.get(sessionId);
activeSessions.remove(sessionId);
@@ -97,26 +65,21 @@ public class InstallSessionTracker extends PackageInstaller.SessionCallback {
PackageInstallInfo info = PackageInstallInfo.fromState(
success ? STATUS_INSTALLED : STATUS_FAILED,
packageName, key.mUser);
- callback.onPackageStateChanged(info);
+ mCallback.onPackageStateChanged(info);
- if (!success && helper.promiseIconAddedForId(sessionId)) {
- callback.onSessionFailure(packageName, key.mUser);
+ if (!success && mInstallerCompat.promiseIconAddedForId(sessionId)) {
+ mCallback.onSessionFailure(packageName, key.mUser);
// If it is successful, the id is removed in the the package added flow.
- helper.removePromiseIconId(sessionId);
+ mInstallerCompat.removePromiseIconId(sessionId);
}
}
}
@Override
public void onProgressChanged(int sessionId, float progress) {
- InstallSessionHelper helper = mWeakHelper.get();
- Callback callback = mWeakCallback.get();
- if (callback == null || helper == null) {
- return;
- }
- SessionInfo session = helper.getVerifiedSessionInfo(sessionId);
+ SessionInfo session = mInstallerCompat.getVerifiedSessionInfo(sessionId);
if (session != null && session.getAppPackageName() != null) {
- callback.onPackageStateChanged(PackageInstallInfo.fromInstallingState(session));
+ mCallback.onPackageStateChanged(PackageInstallInfo.fromInstallingState(session));
}
}
@@ -125,53 +88,35 @@ public class InstallSessionTracker extends PackageInstaller.SessionCallback {
@Override
public void onBadgingChanged(int sessionId) {
- InstallSessionHelper helper = mWeakHelper.get();
- Callback callback = mWeakCallback.get();
- if (callback == null || helper == null) {
- return;
- }
- SessionInfo sessionInfo = pushSessionDisplayToLauncher(sessionId, helper, callback);
+ SessionInfo sessionInfo = pushSessionDisplayToLauncher(sessionId);
if (sessionInfo != null) {
- helper.tryQueuePromiseAppIcon(sessionInfo);
+ mInstallerCompat.tryQueuePromiseAppIcon(sessionInfo);
}
}
- private SessionInfo pushSessionDisplayToLauncher(
- int sessionId, InstallSessionHelper helper, Callback callback) {
- SessionInfo session = helper.getVerifiedSessionInfo(sessionId);
+ private SessionInfo pushSessionDisplayToLauncher(int sessionId) {
+ SessionInfo session = mInstallerCompat.getVerifiedSessionInfo(sessionId);
if (session != null && session.getAppPackageName() != null) {
PackageUserKey key =
new PackageUserKey(session.getAppPackageName(), getUserHandle(session));
- getActiveSessionMap(helper).put(session.getSessionId(), key);
- callback.onUpdateSessionDisplay(key, session);
+ getActiveSessionMap().put(session.getSessionId(), key);
+ mCallback.onUpdateSessionDisplay(key, session);
return session;
}
return null;
}
- private SparseArray<PackageUserKey> getActiveSessionMap(InstallSessionHelper helper) {
+ private SparseArray<PackageUserKey> getActiveSessionMap() {
if (mActiveSessions == null) {
mActiveSessions = new SparseArray<>();
- helper.getActiveSessions().forEach(
+ mInstallerCompat.getActiveSessions().forEach(
(key, si) -> mActiveSessions.put(si.getSessionId(), key));
}
return mActiveSessions;
}
- void register() {
- if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
- mInstaller.registerSessionCallback(this, MODEL_EXECUTOR.getHandler());
- } else {
- mLauncherApps.registerPackageInstallerSessionCallback(MODEL_EXECUTOR, this);
- }
- }
-
public void unregister() {
- if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
- mInstaller.unregisterSessionCallback(this);
- } else {
- mLauncherApps.unregisterPackageInstallerSessionCallback(this);
- }
+ mInstallerCompat.unregister(this);
}
public interface Callback {
diff --git a/src/com/android/launcher3/pm/PackageInstallInfo.java b/src/com/android/launcher3/pm/PackageInstallInfo.java
index 1797c1fc81..fad904f968 100644
--- a/src/com/android/launcher3/pm/PackageInstallInfo.java
+++ b/src/com/android/launcher3/pm/PackageInstallInfo.java
@@ -57,28 +57,4 @@ public final class PackageInstallInfo {
public static PackageInstallInfo fromState(int state, String packageName, UserHandle user) {
return new PackageInstallInfo(packageName, state, 0 /* progress */, user);
}
-
-
- @Override
- public String toString() {
- return getClass().getSimpleName() + "(" + dumpProperties() + ")";
- }
-
- private String dumpProperties() {
- return "componentName=" + componentName
- + "packageName=" + packageName
- + " state=" + stateToString()
- + " progress=" + progress
- + " user=" + user;
- }
-
- private String stateToString() {
- switch (state) {
- case STATUS_INSTALLED : return "STATUS_INSTALLED";
- case STATUS_INSTALLING : return "STATUS_INSTALLING";
- case STATUS_INSTALLED_DOWNLOADING : return "STATUS_INSTALLED_DOWNLOADING";
- case STATUS_FAILED : return "STATUS_FAILED";
- default : return "INVALID STATE";
- }
- }
}
diff --git a/src/com/android/launcher3/pm/UserCache.java b/src/com/android/launcher3/pm/UserCache.java
index 5aab41a8a2..5ade22be5e 100644
--- a/src/com/android/launcher3/pm/UserCache.java
+++ b/src/com/android/launcher3/pm/UserCache.java
@@ -21,8 +21,10 @@ import android.content.Intent;
import android.os.UserHandle;
import android.os.UserManager;
import android.util.ArrayMap;
+import android.util.Log;
import android.util.LongSparseArray;
+import com.android.launcher3.testing.TestProtocol;
import com.android.launcher3.util.MainThreadInitializedObject;
import com.android.launcher3.util.SafeCloseable;
import com.android.launcher3.util.SimpleBroadcastReceiver;
@@ -58,6 +60,9 @@ public class UserCache {
private void onUsersChanged(Intent intent) {
enableAndResetCache();
mUserChangeListeners.forEach(Runnable::run);
+ if (TestProtocol.sDebugTracing) {
+ Log.d(TestProtocol.WORK_PROFILE_REMOVED, "profile changed", new Exception());
+ }
}
/**
diff --git a/src/com/android/launcher3/popup/ArrowPopup.java b/src/com/android/launcher3/popup/ArrowPopup.java
index 196cc56be7..a534ee3eb4 100644
--- a/src/com/android/launcher3/popup/ArrowPopup.java
+++ b/src/com/android/launcher3/popup/ArrowPopup.java
@@ -33,6 +33,7 @@ import android.content.Context;
import android.content.res.Resources;
import android.graphics.Color;
import android.graphics.Rect;
+import android.graphics.RectF;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.GradientDrawable;
@@ -48,24 +49,27 @@ import android.view.ViewTreeObserver;
import android.view.animation.Interpolator;
import android.widget.FrameLayout;
+import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.android.launcher3.AbstractFloatingView;
+import com.android.launcher3.BaseDraggingActivity;
import com.android.launcher3.InsettableFrameLayout;
import com.android.launcher3.Launcher;
+import com.android.launcher3.LauncherState;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.Workspace;
import com.android.launcher3.dragndrop.DragLayer;
import com.android.launcher3.shortcuts.DeepShortcutView;
+import com.android.launcher3.statemanager.StatefulActivity;
import com.android.launcher3.util.Themes;
-import com.android.launcher3.views.ActivityContext;
import com.android.launcher3.views.BaseDragLayer;
import com.android.launcher3.widget.LocalColorExtractor;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Collections;
+import java.util.HashMap;
import java.util.List;
/**
@@ -73,71 +77,73 @@ import java.util.List;
*
* @param <T> The activity on with the popup shows
*/
-public abstract class ArrowPopup<T extends Context & ActivityContext>
+public abstract class ArrowPopup<T extends StatefulActivity<LauncherState>>
extends AbstractFloatingView {
// Duration values (ms) for popup open and close animations.
- protected int OPEN_DURATION = 276;
- protected int OPEN_FADE_START_DELAY = 0;
- protected int OPEN_FADE_DURATION = 38;
- protected int OPEN_CHILD_FADE_START_DELAY = 38;
- protected int OPEN_CHILD_FADE_DURATION = 76;
-
- protected int CLOSE_DURATION = 200;
- protected int CLOSE_FADE_START_DELAY = 140;
- protected int CLOSE_FADE_DURATION = 50;
- protected int CLOSE_CHILD_FADE_START_DELAY = 0;
- protected int CLOSE_CHILD_FADE_DURATION = 140;
+ private static final int OPEN_DURATION = 276;
+ private static final int OPEN_FADE_START_DELAY = 0;
+ private static final int OPEN_FADE_DURATION = 38;
+ private static final int OPEN_CHILD_FADE_START_DELAY = 38;
+ private static final int OPEN_CHILD_FADE_DURATION = 76;
+
+ private static final int CLOSE_DURATION = 200;
+ private static final int CLOSE_FADE_START_DELAY = 140;
+ private static final int CLOSE_FADE_DURATION = 50;
+ private static final int CLOSE_CHILD_FADE_START_DELAY = 0;
+ private static final int CLOSE_CHILD_FADE_DURATION = 140;
// Index used to get background color when using local wallpaper color extraction,
private static final int DARK_COLOR_EXTRACTION_INDEX = android.R.color.system_neutral2_800;
private static final int LIGHT_COLOR_EXTRACTION_INDEX = android.R.color.system_accent2_50;
- protected final Rect mTempRect = new Rect();
+ private final Rect mTempRect = new Rect();
protected final LayoutInflater mInflater;
- protected final float mOutlineRadius;
- protected final T mActivityContext;
+ private final float mOutlineRadius;
+ protected final T mLauncher;
protected final boolean mIsRtl;
- protected final int mArrowOffsetVertical;
- protected final int mArrowOffsetHorizontal;
- protected final int mArrowWidth;
- protected final int mArrowHeight;
- protected final int mArrowPointRadius;
- protected final View mArrow;
+ private final int mArrowOffsetVertical;
+ private final int mArrowOffsetHorizontal;
+ private final int mArrowWidth;
+ private final int mArrowHeight;
+ private final int mArrowPointRadius;
+ private final View mArrow;
private final int mMargin;
protected boolean mIsLeftAligned;
protected boolean mIsAboveIcon;
- protected int mGravity;
+ private int mGravity;
protected AnimatorSet mOpenCloseAnimator;
protected boolean mDeferContainerRemoval;
- protected boolean shouldScaleArrow = false;
private final GradientDrawable mRoundedTop;
private final GradientDrawable mRoundedBottom;
- @Nullable private Runnable mOnCloseCallback = null;
+ private Runnable mOnCloseCallback = () -> { };
// The rect string of the view that the arrow is attached to, in screen reference frame.
- protected int mArrowColor;
- protected final List<LocalColorExtractor> mColorExtractors;
+ protected String mArrowColorRectString;
+ private int mArrowColor;
+ protected final HashMap<String, View> mViewForRect = new HashMap<>();
- protected final float mElevation;
+ @Nullable protected LocalColorExtractor mColorExtractor;
+
+ private final float mElevation;
private final int mBackgroundColor;
private final String mIterateChildrenTag;
- private final int[] mColorIds;
+ private final int[] mColors;
public ArrowPopup(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mInflater = LayoutInflater.from(context);
mOutlineRadius = Themes.getDialogCornerRadius(context);
- mActivityContext = ActivityContext.lookupContext(context);
+ mLauncher = BaseDraggingActivity.fromContext(context);
mIsRtl = Utilities.isRtl(getResources());
mBackgroundColor = Themes.getAttrColor(context, R.attr.popupColorPrimary);
@@ -169,18 +175,20 @@ public abstract class ArrowPopup<T extends Context & ActivityContext>
mIterateChildrenTag = getContext().getString(R.string.popup_container_iterate_children);
- boolean shouldUseColorExtraction = mActivityContext.shouldUseColorExtractionForPopup();
- if (shouldUseColorExtraction && Utilities.ATLEAST_S && ENABLE_LOCAL_COLOR_POPUPS.get()) {
- mColorExtractors = new ArrayList<>();
- } else {
- mColorExtractors = null;
+ boolean isAboveAnotherSurface = getTopOpenViewWithType(mLauncher, TYPE_FOLDER) != null
+ || mLauncher.getStateManager().getState() == LauncherState.ALL_APPS;
+ if (!isAboveAnotherSurface && Utilities.ATLEAST_S && ENABLE_LOCAL_COLOR_POPUPS.get()) {
+ setupColorExtraction();
}
- if (shouldUseColorExtraction) {
- mColorIds = new int[]{R.color.popup_shade_first, R.color.popup_shade_second,
- R.color.popup_shade_third};
+ if (isAboveAnotherSurface) {
+ mColors = new int[] {
+ getColorStateList(context, R.color.popup_shade_first).getDefaultColor()};
} else {
- mColorIds = new int[]{R.color.popup_shade_first};
+ mColors = new int[] {
+ getColorStateList(context, R.color.popup_shade_first).getDefaultColor(),
+ getColorStateList(context, R.color.popup_shade_second).getDefaultColor(),
+ getColorStateList(context, R.color.popup_shade_third).getDefaultColor()};
}
}
@@ -232,22 +240,17 @@ public abstract class ArrowPopup<T extends Context & ActivityContext>
}
/**
- * @param backgroundColor When Color.TRANSPARENT, we get color from {@link #mColorIds}.
+ * @param backgroundColor When Color.TRANSPARENT, we get color from {@link #mColors}.
* Otherwise, we will use this color for all child views.
*/
- protected void assignMarginsAndBackgrounds(ViewGroup viewGroup, int backgroundColor) {
- int[] colors = null;
- if (backgroundColor == Color.TRANSPARENT) {
- // Lazily get the colors so they match the current wallpaper colors.
- colors = Arrays.stream(mColorIds).map(
- r -> getColorStateList(getContext(), r).getDefaultColor()).toArray();
- }
+ private void assignMarginsAndBackgrounds(ViewGroup viewGroup, int backgroundColor) {
+ final boolean getColorFromColorArray = backgroundColor == Color.TRANSPARENT;
int count = viewGroup.getChildCount();
int totalVisibleShortcuts = 0;
for (int i = 0; i < count; i++) {
View view = viewGroup.getChildAt(i);
- if (view.getVisibility() == VISIBLE && isShortcutOrWrapper(view)) {
+ if (view.getVisibility() == VISIBLE && view instanceof DeepShortcutView) {
totalVisibleShortcuts++;
}
}
@@ -267,17 +270,9 @@ public abstract class ArrowPopup<T extends Context & ActivityContext>
MarginLayoutParams mlp = (MarginLayoutParams) lastView.getLayoutParams();
mlp.bottomMargin = 0;
- if (colors != null) {
- backgroundColor = colors[numVisibleChild % colors.length];
- }
- if (!ENABLE_LOCAL_COLOR_POPUPS.get()) {
- // Arrow color matches the first child or the last child.
- if (!mIsAboveIcon && numVisibleChild == 0 && viewGroup == this) {
- mArrowColor = backgroundColor;
- } else if (mIsAboveIcon) {
- mArrowColor = backgroundColor;
- }
+ if (getColorFromColorArray) {
+ backgroundColor = mColors[numVisibleChild % mColors.length];
}
if (view instanceof ViewGroup && mIterateChildrenTag.equals(view.getTag())) {
@@ -286,7 +281,7 @@ public abstract class ArrowPopup<T extends Context & ActivityContext>
continue;
}
- if (isShortcutOrWrapper(view)) {
+ if (view instanceof DeepShortcutView) {
if (totalVisibleShortcuts == 1) {
view.setBackgroundResource(R.drawable.single_item_primary);
} else if (totalVisibleShortcuts > 1) {
@@ -303,6 +298,12 @@ public abstract class ArrowPopup<T extends Context & ActivityContext>
if (!ENABLE_LOCAL_COLOR_POPUPS.get()) {
setChildColor(view, backgroundColor, colorAnimator);
+ // Arrow color matches the first child or the last child.
+ if (!mIsAboveIcon && numVisibleChild == 0) {
+ mArrowColor = backgroundColor;
+ } else if (mIsAboveIcon) {
+ mArrowColor = backgroundColor;
+ }
}
numVisibleChild++;
@@ -313,12 +314,6 @@ public abstract class ArrowPopup<T extends Context & ActivityContext>
measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
}
- /**
- * Returns {@code true} if the child is a shortcut or wraps a shortcut.
- */
- protected boolean isShortcutOrWrapper(View view) {
- return view instanceof DeepShortcutView;
- }
@TargetApi(Build.VERSION_CODES.S)
private int getExtractedColor(SparseIntArray colors) {
@@ -328,6 +323,37 @@ public abstract class ArrowPopup<T extends Context & ActivityContext>
return colors.get(index, mBackgroundColor);
}
+ @TargetApi(Build.VERSION_CODES.S)
+ private void setupColorExtraction() {
+ Workspace workspace = mLauncher.findViewById(R.id.workspace);
+ if (workspace == null) {
+ return;
+ }
+
+ mColorExtractor = LocalColorExtractor.newInstance(mLauncher);
+ mColorExtractor.setListener((rect, extractedColors) -> {
+ String rectString = rect.toShortString();
+ View v = mViewForRect.get(rectString);
+ AnimatorSet colors = new AnimatorSet();
+ if (v != null) {
+ int newColor = getExtractedColor(extractedColors);
+ setChildColor(v, newColor, colors);
+ int numChildren = v instanceof ViewGroup ? ((ViewGroup) v).getChildCount() : 0;
+ for (int i = 0; i < numChildren; ++i) {
+ View childView = ((ViewGroup) v).getChildAt(i);
+ setChildColor(childView, newColor, colors);
+
+ }
+ if (rectString.equals(mArrowColorRectString)) {
+ mArrowColor = newColor;
+ updateArrowColor();
+ }
+ }
+ colors.setDuration(150);
+ v.post(colors::start);
+ });
+ }
+
protected void addPreDrawForColorExtraction(Launcher launcher) {
getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
@Override
@@ -348,55 +374,40 @@ public abstract class ArrowPopup<T extends Context & ActivityContext>
}
private void initColorExtractionLocations(Launcher launcher) {
- if (mColorExtractors == null) {
- return;
- }
- Workspace<?> workspace = launcher.getWorkspace();
- if (workspace == null) {
+ if (mColorExtractor == null) {
return;
}
+ ArrayList<RectF> locations = new ArrayList<>();
boolean firstVisibleChild = true;
- int screenId = workspace.getScreenIdForPageIndex(workspace.getCurrentPage());
- DragLayer dragLayer = launcher.getDragLayer();
-
- final View[] viewAlignedWithArrow = new View[1];
-
// Order matters here, since we need the arrow to match the color of its adjacent view.
- for (final View view : getChildrenForColorExtraction()) {
+ for (View view : getChildrenForColorExtraction()) {
if (view != null && view.getVisibility() == VISIBLE) {
- Rect pos = new Rect();
- dragLayer.getDescendantRectRelativeToSelf(view, pos);
- if (!pos.isEmpty()) {
- LocalColorExtractor extractor = LocalColorExtractor.newInstance(launcher);
- extractor.setWorkspaceLocation(pos, dragLayer, screenId);
- extractor.setListener(extractedColors -> {
- AnimatorSet colors = new AnimatorSet();
- int newColor = getExtractedColor(extractedColors);
- setChildColor(view, newColor, colors);
- int numChildren = view instanceof ViewGroup
- ? ((ViewGroup) view).getChildCount() : 0;
- for (int i = 0; i < numChildren; ++i) {
- View childView = ((ViewGroup) view).getChildAt(i);
- setChildColor(childView, newColor, colors);
- }
- if (viewAlignedWithArrow[0] == view) {
- mArrowColor = newColor;
- updateArrowColor();
+ RectF rf = new RectF();
+ mColorExtractor.getExtractedRectForView(launcher,
+ launcher.getWorkspace().getCurrentPage(), view, rf);
+ if (!rf.isEmpty()) {
+ locations.add(rf);
+ String rectString = rf.toShortString();
+ mViewForRect.put(rectString, view);
+ if (mIsAboveIcon) {
+ mArrowColorRectString = rectString;
+ } else {
+ if (firstVisibleChild) {
+ mArrowColorRectString = rectString;
}
- colors.setDuration(150);
- view.post(colors::start);
- });
- mColorExtractors.add(extractor);
+ }
- if (mIsAboveIcon || firstVisibleChild) {
- viewAlignedWithArrow[0] = view;
+ if (firstVisibleChild) {
+ firstVisibleChild = false;
}
- firstVisibleChild = false;
+
}
}
}
-
+ if (!locations.isEmpty()) {
+ mColorExtractor.addLocation(locations);
+ }
}
/**
@@ -436,7 +447,7 @@ public abstract class ArrowPopup<T extends Context & ActivityContext>
/**
* Shows the popup at the desired location.
*/
- public void show() {
+ protected void show() {
setupForDisplay();
onInflationComplete(false);
assignMarginsAndBackgrounds(this);
@@ -446,7 +457,7 @@ public abstract class ArrowPopup<T extends Context & ActivityContext>
animateOpen();
}
- protected void setupForDisplay() {
+ private void setupForDisplay() {
setVisibility(View.INVISIBLE);
mIsOpen = true;
getPopupContainer().addView(this);
@@ -476,14 +487,7 @@ public abstract class ArrowPopup<T extends Context & ActivityContext>
return getMeasuredWidth() - mArrowOffsetHorizontal - mArrowWidth;
}
- /**
- * @param show If true, shows arrow (when applicable), otherwise hides arrow.
- */
- public void showArrow(boolean show) {
- mArrow.setVisibility(show && shouldAddArrow() ? VISIBLE : INVISIBLE);
- }
-
- protected void addArrow() {
+ private void addArrow() {
getPopupContainer().addView(mArrow);
mArrow.setX(getX() + getArrowLeft());
@@ -499,7 +503,7 @@ public abstract class ArrowPopup<T extends Context & ActivityContext>
mArrow.setPivotY(mIsAboveIcon ? mArrowHeight : 0);
}
- protected void updateArrowColor() {
+ private void updateArrowColor() {
if (!Gravity.isVertical(mGravity)) {
mArrow.setBackground(new RoundedArrowDrawable(
mArrowWidth, mArrowHeight, mArrowPointRadius,
@@ -602,7 +606,6 @@ public abstract class ArrowPopup<T extends Context & ActivityContext>
mIsAboveIcon = y > dragLayer.getTop() + insets.top;
if (!mIsAboveIcon) {
y = mTempRect.top + iconHeight + extraVerticalSpace;
- height -= extraVerticalSpace;
}
// Insets are added later, so subtract them now.
@@ -610,7 +613,7 @@ public abstract class ArrowPopup<T extends Context & ActivityContext>
y -= insets.top;
mGravity = 0;
- if ((insets.top + y + height) > (dragLayer.getBottom() - insets.bottom)) {
+ if (y + height > dragLayer.getBottom() - insets.bottom) {
// The container is opening off the screen, so just center it in the drag layer instead.
mGravity = Gravity.CENTER_VERTICAL;
// Put the container next to the icon, preferring the right side in ltr (left in rtl).
@@ -688,13 +691,12 @@ public abstract class ArrowPopup<T extends Context & ActivityContext>
return getChildCount() > 0 ? getChildAt(0) : this;
}
- protected void animateOpen() {
+ private void animateOpen() {
setVisibility(View.VISIBLE);
mOpenCloseAnimator = getOpenCloseAnimator(true, OPEN_DURATION, OPEN_FADE_START_DELAY,
OPEN_FADE_DURATION, OPEN_CHILD_FADE_START_DELAY, OPEN_CHILD_FADE_DURATION,
DECELERATED_EASE);
- onCreateOpenAnimation(mOpenCloseAnimator);
mOpenCloseAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
@@ -731,14 +733,6 @@ public abstract class ArrowPopup<T extends Context & ActivityContext>
scale.setInterpolator(interpolator);
animatorSet.play(scale);
- if (shouldScaleArrow) {
- Animator arrowScaleAnimator = ObjectAnimator.ofFloat(mArrow, View.SCALE_Y,
- scaleValues);
- arrowScaleAnimator.setDuration(totalDuration);
- arrowScaleAnimator.setInterpolator(interpolator);
- animatorSet.play(arrowScaleAnimator);
- }
-
fadeInChildViews(this, alphaValues, childFadeStartDelay, childFadeDuration, animatorSet);
return animatorSet;
@@ -767,6 +761,7 @@ public abstract class ArrowPopup<T extends Context & ActivityContext>
}
}
+
protected void animateClose() {
if (!mIsOpen) {
return;
@@ -795,11 +790,6 @@ public abstract class ArrowPopup<T extends Context & ActivityContext>
}
/**
- * Called when creating the open transition allowing subclass can add additional animations.
- */
- protected void onCreateOpenAnimation(AnimatorSet anim) { }
-
- /**
* Called when creating the close transition allowing subclass can add additional animations.
*/
protected void onCreateCloseAnimation(AnimatorSet anim) { }
@@ -816,22 +806,23 @@ public abstract class ArrowPopup<T extends Context & ActivityContext>
mDeferContainerRemoval = false;
getPopupContainer().removeView(this);
getPopupContainer().removeView(mArrow);
- if (mOnCloseCallback != null) {
- mOnCloseCallback.run();
- }
- if (mColorExtractors != null) {
- mColorExtractors.forEach(e -> e.setListener(null));
+ mOnCloseCallback.run();
+ mArrowColorRectString = null;
+ mViewForRect.clear();
+ if (mColorExtractor != null) {
+ mColorExtractor.removeLocations();
+ mColorExtractor.setListener(null);
}
}
/**
* Callback to be called when the popup is closed
*/
- public void setOnCloseCallback(@Nullable Runnable callback) {
+ public void setOnCloseCallback(@NonNull Runnable callback) {
mOnCloseCallback = callback;
}
protected BaseDragLayer getPopupContainer() {
- return mActivityContext.getDragLayer();
+ return mLauncher.getDragLayer();
}
}
diff --git a/src/com/android/launcher3/popup/LauncherPopupLiveUpdateHandler.java b/src/com/android/launcher3/popup/LauncherPopupLiveUpdateHandler.java
deleted file mode 100644
index c0a04b1302..0000000000
--- a/src/com/android/launcher3/popup/LauncherPopupLiveUpdateHandler.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (C) 2021 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.launcher3.popup;
-
-import android.view.View;
-import android.view.ViewGroup;
-
-import com.android.launcher3.BubbleTextView;
-import com.android.launcher3.Launcher;
-import com.android.launcher3.R;
-import com.android.launcher3.model.data.ItemInfo;
-
-/**
- * Utility class to handle updates while the popup is visible on the Launcher
- */
-public class LauncherPopupLiveUpdateHandler extends PopupLiveUpdateHandler<Launcher> {
-
- public LauncherPopupLiveUpdateHandler(
- Launcher launcher, PopupContainerWithArrow<Launcher> popupContainerWithArrow) {
- super(launcher, popupContainerWithArrow);
- }
-
- private View getWidgetsView(ViewGroup container) {
- for (int i = container.getChildCount() - 1; i >= 0; --i) {
- View systemShortcutView = container.getChildAt(i);
- if (systemShortcutView.getTag() instanceof SystemShortcut.Widgets) {
- return systemShortcutView;
- }
- }
- return null;
- }
-
- @Override
- public void onWidgetsBound() {
- BubbleTextView originalIcon = mPopupContainerWithArrow.getOriginalIcon();
- SystemShortcut widgetInfo = SystemShortcut.WIDGETS.getShortcut(mContext,
- (ItemInfo) originalIcon.getTag(), originalIcon);
- View widgetsView = getWidgetsView(mPopupContainerWithArrow);
- if (widgetsView == null && mPopupContainerWithArrow.getWidgetContainer() != null) {
- widgetsView = getWidgetsView(mPopupContainerWithArrow.getWidgetContainer());
- }
-
- if (widgetInfo != null && widgetsView == null) {
- // We didn't have any widgets cached but now there are some, so enable the shortcut.
- if (mPopupContainerWithArrow.getSystemShortcutContainer()
- != mPopupContainerWithArrow) {
- if (mPopupContainerWithArrow.getWidgetContainer() == null) {
- mPopupContainerWithArrow.setWidgetContainer(
- mPopupContainerWithArrow.inflateAndAdd(
- R.layout.widget_shortcut_container,
- mPopupContainerWithArrow));
- }
- mPopupContainerWithArrow.initializeWidgetShortcut(
- mPopupContainerWithArrow.getWidgetContainer(),
- widgetInfo);
- } else {
- // If using the expanded system shortcut (as opposed to just the icon), we need
- // to reopen the container to ensure measurements etc. all work out. While this
- // could be quite janky, in practice the user would typically see a small
- // flicker as the animation restarts partway through, and this is a very rare
- // edge case anyway.
- mPopupContainerWithArrow.close(false);
- PopupContainerWithArrow.showForIcon(mPopupContainerWithArrow.getOriginalIcon());
- }
- } else if (widgetInfo == null && widgetsView != null) {
- // No widgets exist, but we previously added the shortcut so remove it.
- if (mPopupContainerWithArrow.getSystemShortcutContainer()
- != mPopupContainerWithArrow
- && mPopupContainerWithArrow.getWidgetContainer() != null) {
- mPopupContainerWithArrow.getWidgetContainer().removeView(widgetsView);
- } else {
- mPopupContainerWithArrow.close(false);
- PopupContainerWithArrow.showForIcon(mPopupContainerWithArrow.getOriginalIcon());
- }
- }
- }
-
- @Override
- protected void showPopupContainerForIcon(BubbleTextView originalIcon) {
- PopupContainerWithArrow.showForIcon(originalIcon);
- }
-}
diff --git a/src/com/android/launcher3/popup/PopupContainerWithArrow.java b/src/com/android/launcher3/popup/PopupContainerWithArrow.java
index 49d97d21c1..18f263a8ec 100644
--- a/src/com/android/launcher3/popup/PopupContainerWithArrow.java
+++ b/src/com/android/launcher3/popup/PopupContainerWithArrow.java
@@ -46,6 +46,7 @@ import com.android.launcher3.DragSource;
import com.android.launcher3.DropTarget;
import com.android.launcher3.DropTarget.DragObject;
import com.android.launcher3.Launcher;
+import com.android.launcher3.LauncherState;
import com.android.launcher3.R;
import com.android.launcher3.accessibility.LauncherAccessibilityDelegate;
import com.android.launcher3.accessibility.ShortcutMenuAccessibilityDelegate;
@@ -57,21 +58,24 @@ import com.android.launcher3.dragndrop.DraggableView;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.ItemInfoWithIcon;
import com.android.launcher3.model.data.WorkspaceItemInfo;
-import com.android.launcher3.notification.NotificationContainer;
import com.android.launcher3.notification.NotificationInfo;
+import com.android.launcher3.notification.NotificationItemView;
import com.android.launcher3.notification.NotificationKeyData;
+import com.android.launcher3.popup.PopupDataProvider.PopupDataChangeListener;
import com.android.launcher3.shortcuts.DeepShortcutView;
import com.android.launcher3.shortcuts.ShortcutDragPreviewProvider;
+import com.android.launcher3.statemanager.StatefulActivity;
import com.android.launcher3.touch.ItemLongClickListener;
import com.android.launcher3.util.PackageUserKey;
import com.android.launcher3.util.ShortcutUtil;
-import com.android.launcher3.views.ActivityContext;
import com.android.launcher3.views.BaseDragLayer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
+import java.util.Map;
import java.util.Objects;
+import java.util.function.Predicate;
import java.util.stream.Collectors;
/**
@@ -79,7 +83,7 @@ import java.util.stream.Collectors;
*
* @param <T> The activity on with the popup shows
*/
-public class PopupContainerWithArrow<T extends Context & ActivityContext>
+public class PopupContainerWithArrow<T extends StatefulActivity<LauncherState>>
extends ArrowPopup<T> implements DragSource, DragController.DragListener {
private final List<DeepShortcutView> mShortcuts = new ArrayList<>();
@@ -88,9 +92,9 @@ public class PopupContainerWithArrow<T extends Context & ActivityContext>
private final int mStartDragThreshold;
private BubbleTextView mOriginalIcon;
+ private NotificationItemView mNotificationItemView;
private int mNumNotifications;
- private NotificationContainer mNotificationContainer;
- private int mContainerWidth;
+ private ViewGroup mNotificationContainer;
private ViewGroup mWidgetContainer;
@@ -105,7 +109,6 @@ public class PopupContainerWithArrow<T extends Context & ActivityContext>
super(context, attrs, defStyleAttr);
mStartDragThreshold = getResources().getDimensionPixelSize(
R.dimen.deep_shortcuts_start_drag_threshold);
- mContainerWidth = getResources().getDimensionPixelSize(R.dimen.bg_popup_item_width);
}
public PopupContainerWithArrow(Context context, AttributeSet attrs) {
@@ -125,8 +128,8 @@ public class PopupContainerWithArrow<T extends Context & ActivityContext>
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
mInterceptTouchDown.set(ev.getX(), ev.getY());
}
- if (mNotificationContainer != null
- && mNotificationContainer.onInterceptSwipeEvent(ev)) {
+ if (mNotificationItemView != null
+ && mNotificationItemView.onInterceptTouchEvent(ev)) {
return true;
}
// Stop sending touch events to deep shortcut views if user moved beyond touch slop.
@@ -135,28 +138,17 @@ public class PopupContainerWithArrow<T extends Context & ActivityContext>
}
@Override
- public boolean onTouchEvent(MotionEvent ev) {
- if (mNotificationContainer != null) {
- return mNotificationContainer.onSwipeEvent(ev) || super.onTouchEvent(ev);
- }
- return super.onTouchEvent(ev);
- }
-
- @Override
protected boolean isOfType(int type) {
return (type & TYPE_ACTION_POPUP) != 0;
}
public OnClickListener getItemClickListener() {
return (view) -> {
- mActivityContext.getItemOnClickListener().onClick(view);
+ mLauncher.getItemOnClickListener().onClick(view);
+ close(true);
};
}
- public void setPopupItemDragHandler(PopupItemDragHandler popupItemDragHandler) {
- mPopupItemDragHandler = popupItemDragHandler;
- }
-
public PopupItemDragHandler getItemDragHandler() {
return mPopupItemDragHandler;
}
@@ -180,26 +172,23 @@ public class PopupContainerWithArrow<T extends Context & ActivityContext>
@Override
protected void setChildColor(View view, int color, AnimatorSet animatorSetOut) {
super.setChildColor(view, color, animatorSetOut);
- if (view.getId() == R.id.notification_container && mNotificationContainer != null) {
- mNotificationContainer.updateBackgroundColor(color, animatorSetOut);
+ if (view.getId() == R.id.notification_container && mNotificationItemView != null) {
+ mNotificationItemView.updateBackgroundColor(color, animatorSetOut);
}
}
/**
* Returns true if we can show the container.
- *
- * @deprecated Left here since some dependent projects are using this method
*/
- @Deprecated
public static boolean canShow(View icon, ItemInfo item) {
return icon instanceof BubbleTextView && ShortcutUtil.supportsShortcuts(item);
}
/**
- * Shows the notifications and deep shortcuts associated with a Launcher {@param icon}.
+ * Shows the notifications and deep shortcuts associated with {@param icon}.
* @return the container if shown or null.
*/
- public static PopupContainerWithArrow<Launcher> showForIcon(BubbleTextView icon) {
+ public static PopupContainerWithArrow showForIcon(BubbleTextView icon) {
Launcher launcher = Launcher.getLauncher(icon.getContext());
if (getOpen(launcher) != null) {
// There is already an items container open, so don't open this one.
@@ -207,11 +196,11 @@ public class PopupContainerWithArrow<T extends Context & ActivityContext>
return null;
}
ItemInfo item = (ItemInfo) icon.getTag();
- if (!ShortcutUtil.supportsShortcuts(item)) {
+ if (!canShow(icon, item)) {
return null;
}
- final PopupContainerWithArrow<Launcher> container =
+ final PopupContainerWithArrow container =
(PopupContainerWithArrow) launcher.getLayoutInflater().inflate(
R.layout.popup_container, launcher.getDragLayer(), false);
container.configureForLauncher(launcher);
@@ -221,7 +210,7 @@ public class PopupContainerWithArrow<T extends Context & ActivityContext>
popupDataProvider.getShortcutCountForItem(item),
popupDataProvider.getNotificationKeysForItem(item),
launcher.getSupportedShortcuts()
- .map(s -> s.getShortcut(launcher, item, icon))
+ .map(s -> s.getShortcut(launcher, item))
.filter(Objects::nonNull)
.collect(Collectors.toList()));
launcher.refreshAndBindWidgetsForPackageUser(PackageUserKey.fromItemInfo(item));
@@ -230,8 +219,7 @@ public class PopupContainerWithArrow<T extends Context & ActivityContext>
}
private void configureForLauncher(Launcher launcher) {
- addOnAttachStateChangeListener(new LauncherPopupLiveUpdateHandler(
- launcher, (PopupContainerWithArrow<Launcher>) this));
+ addOnAttachStateChangeListener(new LiveUpdateHandler(launcher));
mPopupItemDragHandler = new LauncherPopupItemDragHandler(launcher, this);
mAccessibilityDelegate = new ShortcutMenuAccessibilityDelegate(launcher);
launcher.getDragController().addDragListener(this);
@@ -244,6 +232,13 @@ public class PopupContainerWithArrow<T extends Context & ActivityContext>
mNotificationContainer);
}
+ @Override
+ protected void onInflationComplete(boolean isReversed) {
+ if (isReversed && mNotificationItemView != null) {
+ mNotificationItemView.inverseGutterMargin();
+ }
+ }
+
@TargetApi(Build.VERSION_CODES.P)
public void populateAndShow(final BubbleTextView originalIcon, int shortcutCount,
final List<NotificationKeyData> notificationKeys, List<SystemShortcut> systemShortcuts) {
@@ -251,15 +246,14 @@ public class PopupContainerWithArrow<T extends Context & ActivityContext>
mOriginalIcon = originalIcon;
boolean hasDeepShortcuts = shortcutCount > 0;
- mContainerWidth = getResources().getDimensionPixelSize(R.dimen.bg_popup_item_width);
+ int containerWidth = (int) getResources().getDimension(R.dimen.bg_popup_item_width);
// if there are deep shortcuts, we might want to increase the width of shortcuts to fit
// horizontally laid out system shortcuts.
if (hasDeepShortcuts) {
- mContainerWidth = Math.max(mContainerWidth,
- systemShortcuts.size() * getResources()
- .getDimensionPixelSize(R.dimen.system_shortcut_header_icon_touch_size)
- );
+ containerWidth = (int) Math.max(containerWidth,
+ systemShortcuts.size() * getResources().getDimension(
+ R.dimen.system_shortcut_header_icon_touch_size));
}
// Add views
if (mNumNotifications > 0) {
@@ -267,10 +261,9 @@ public class PopupContainerWithArrow<T extends Context & ActivityContext>
if (mNotificationContainer == null) {
mNotificationContainer = findViewById(R.id.notification_container);
mNotificationContainer.setVisibility(VISIBLE);
- mNotificationContainer.setPopupView(this);
- } else {
- mNotificationContainer.setVisibility(GONE);
}
+ View.inflate(getContext(), R.layout.notification_content, mNotificationContainer);
+ mNotificationItemView = new NotificationItemView(this, mNotificationContainer);
updateNotificationHeader();
}
int viewsToFlip = getChildCount();
@@ -281,9 +274,13 @@ public class PopupContainerWithArrow<T extends Context & ActivityContext>
if (hasDeepShortcuts) {
mDeepShortcutContainer.setVisibility(View.VISIBLE);
+ if (mNotificationItemView != null) {
+ mNotificationItemView.addGutter();
+ }
+
for (int i = shortcutCount; i > 0; i--) {
DeepShortcutView v = inflateAndAdd(R.layout.deep_shortcut, mDeepShortcutContainer);
- v.getLayoutParams().width = mContainerWidth;
+ v.getLayoutParams().width = containerWidth;
mShortcuts.add(v);
}
updateHiddenShortcuts();
@@ -295,7 +292,8 @@ public class PopupContainerWithArrow<T extends Context & ActivityContext>
mWidgetContainer = inflateAndAdd(R.layout.widget_shortcut_container,
this);
}
- initializeWidgetShortcut(mWidgetContainer, shortcut);
+ initializeSystemShortcut(R.layout.system_shortcut, mWidgetContainer,
+ shortcut);
}
}
mSystemShortcutContainer = inflateAndAdd(R.layout.system_shortcut_icons, this);
@@ -311,6 +309,10 @@ public class PopupContainerWithArrow<T extends Context & ActivityContext>
} else {
mDeepShortcutContainer.setVisibility(View.GONE);
if (!systemShortcuts.isEmpty()) {
+ if (mNotificationItemView != null) {
+ mNotificationItemView.addGutter();
+ }
+
for (SystemShortcut shortcut : systemShortcuts) {
initializeSystemShortcut(R.layout.system_shortcut, this, shortcut);
}
@@ -331,30 +333,10 @@ public class PopupContainerWithArrow<T extends Context & ActivityContext>
// Load the shortcuts on a background thread and update the container as it animates.
MODEL_EXECUTOR.getHandler().postAtFrontOfQueue(PopupPopulator.createUpdateRunnable(
- mActivityContext, originalItemInfo, new Handler(Looper.getMainLooper()),
+ mLauncher, originalItemInfo, new Handler(Looper.getMainLooper()),
this, mShortcuts, notificationKeys));
}
- protected NotificationContainer getNotificationContainer() {
- return mNotificationContainer;
- }
-
- protected BubbleTextView getOriginalIcon() {
- return mOriginalIcon;
- }
-
- protected ViewGroup getSystemShortcutContainer() {
- return mSystemShortcutContainer;
- }
-
- protected ViewGroup getWidgetContainer() {
- return mWidgetContainer;
- }
-
- protected void setWidgetContainer(ViewGroup widgetContainer) {
- mWidgetContainer = widgetContainer;
- }
-
private String getTitleForAccessibility() {
return getContext().getString(mNumNotifications == 0 ?
R.string.action_deep_shortcut :
@@ -373,13 +355,13 @@ public class PopupContainerWithArrow<T extends Context & ActivityContext>
}
public void applyNotificationInfos(List<NotificationInfo> notificationInfos) {
- if (mNotificationContainer != null) {
- mNotificationContainer.applyNotificationInfos(notificationInfos);
+ if (mNotificationItemView != null) {
+ mNotificationItemView.applyNotificationInfos(notificationInfos);
}
}
- protected void updateHiddenShortcuts() {
- int allowedCount = mNotificationContainer != null
+ private void updateHiddenShortcuts() {
+ int allowedCount = mNotificationItemView != null
? MAX_SHORTCUTS_IF_NOTIFICATIONS : MAX_SHORTCUTS;
int total = mShortcuts.size();
@@ -389,12 +371,7 @@ public class PopupContainerWithArrow<T extends Context & ActivityContext>
}
}
- protected void initializeWidgetShortcut(ViewGroup container, SystemShortcut info) {
- View view = initializeSystemShortcut(R.layout.system_shortcut, container, info);
- view.getLayoutParams().width = mContainerWidth;
- }
-
- protected View initializeSystemShortcut(int resId, ViewGroup container, SystemShortcut info) {
+ private void initializeSystemShortcut(int resId, ViewGroup container, SystemShortcut info) {
View view = inflateAndAdd(
resId, container, getInsertIndexForSystemShortcut(container, info));
if (view instanceof DeepShortcutView) {
@@ -408,7 +385,6 @@ public class PopupContainerWithArrow<T extends Context & ActivityContext>
}
view.setTag(info);
view.setOnClickListener(info);
- return view;
}
/**
@@ -428,7 +404,7 @@ public class PopupContainerWithArrow<T extends Context & ActivityContext>
* Current behavior:
* - Start the drag if the touch passes a certain distance from the original touch down.
*/
- public DragOptions.PreDragCondition createPreDragCondition(boolean updateIconUi) {
+ public DragOptions.PreDragCondition createPreDragCondition() {
return new DragOptions.PreDragCondition() {
@Override
@@ -438,9 +414,6 @@ public class PopupContainerWithArrow<T extends Context & ActivityContext>
@Override
public void onPreDragStart(DropTarget.DragObject dragObject) {
- if (!updateIconUi) {
- return;
- }
if (mIsAboveIcon) {
// Hide only the icon, keep the text visible.
mOriginalIcon.setIconVisible(false);
@@ -453,9 +426,6 @@ public class PopupContainerWithArrow<T extends Context & ActivityContext>
@Override
public void onPreDragEnd(DropTarget.DragObject dragObject, boolean dragStarted) {
- if (!updateIconUi) {
- return;
- }
mOriginalIcon.setIconVisible(true);
if (dragStarted) {
// Make sure we keep the original icon hidden while it is being dragged.
@@ -474,11 +444,11 @@ public class PopupContainerWithArrow<T extends Context & ActivityContext>
};
}
- protected void updateNotificationHeader() {
+ private void updateNotificationHeader() {
ItemInfoWithIcon itemInfo = (ItemInfoWithIcon) mOriginalIcon.getTag();
- DotInfo dotInfo = mActivityContext.getDotInfoForItem(itemInfo);
- if (mNotificationContainer != null && dotInfo != null) {
- mNotificationContainer.updateHeader(dotInfo.getNotificationCount());
+ DotInfo dotInfo = mLauncher.getDotInfoForItem(itemInfo);
+ if (mNotificationItemView != null && dotInfo != null) {
+ mNotificationItemView.updateHeader(dotInfo.getNotificationCount());
}
}
@@ -517,22 +487,126 @@ public class PopupContainerWithArrow<T extends Context & ActivityContext>
@Override
protected void closeComplete() {
- super.closeComplete();
- if (mActivityContext.getDragController() != null) {
- mActivityContext.getDragController().removeDragListener(this);
- }
- PopupContainerWithArrow openPopup = getOpen(mActivityContext);
+ PopupContainerWithArrow openPopup = getOpen(mLauncher);
if (openPopup == null || openPopup.mOriginalIcon != mOriginalIcon) {
mOriginalIcon.setTextVisibility(mOriginalIcon.shouldTextBeVisible());
mOriginalIcon.setForceHideDot(false);
}
+ super.closeComplete();
}
/**
* Returns a PopupContainerWithArrow which is already open or null
*/
- public static <T extends Context & ActivityContext> PopupContainerWithArrow getOpen(T context) {
- return getOpenView(context, TYPE_ACTION_POPUP);
+ public static PopupContainerWithArrow getOpen(BaseDraggingActivity launcher) {
+ return getOpenView(launcher, TYPE_ACTION_POPUP);
+ }
+
+ /**
+ * Utility class to handle updates while the popup is visible (like widgets and
+ * notification changes)
+ */
+ private class LiveUpdateHandler implements
+ PopupDataChangeListener, View.OnAttachStateChangeListener {
+
+ private final Launcher mLauncher;
+
+ LiveUpdateHandler(Launcher launcher) {
+ mLauncher = launcher;
+ }
+
+ @Override
+ public void onViewAttachedToWindow(View view) {
+ mLauncher.getPopupDataProvider().setChangeListener(this);
+ }
+
+ @Override
+ public void onViewDetachedFromWindow(View view) {
+ mLauncher.getPopupDataProvider().setChangeListener(null);
+ }
+
+ private View getWidgetsView(ViewGroup container) {
+ for (int i = container.getChildCount() - 1; i >= 0; --i) {
+ View systemShortcutView = container.getChildAt(i);
+ if (systemShortcutView.getTag() instanceof SystemShortcut.Widgets) {
+ return systemShortcutView;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public void onWidgetsBound() {
+ ItemInfo itemInfo = (ItemInfo) mOriginalIcon.getTag();
+ SystemShortcut widgetInfo = SystemShortcut.WIDGETS.getShortcut(mLauncher, itemInfo);
+ View widgetsView = getWidgetsView(PopupContainerWithArrow.this);
+ if (widgetsView == null && mWidgetContainer != null) {
+ widgetsView = getWidgetsView(mWidgetContainer);
+ }
+
+ if (widgetInfo != null && widgetsView == null) {
+ // We didn't have any widgets cached but now there are some, so enable the shortcut.
+ if (mSystemShortcutContainer != PopupContainerWithArrow.this) {
+ if (mWidgetContainer == null) {
+ mWidgetContainer = inflateAndAdd(R.layout.widget_shortcut_container,
+ PopupContainerWithArrow.this);
+ }
+ initializeSystemShortcut(R.layout.system_shortcut, mWidgetContainer,
+ widgetInfo);
+ } else {
+ // If using the expanded system shortcut (as opposed to just the icon), we need
+ // to reopen the container to ensure measurements etc. all work out. While this
+ // could be quite janky, in practice the user would typically see a small
+ // flicker as the animation restarts partway through, and this is a very rare
+ // edge case anyway.
+ close(false);
+ PopupContainerWithArrow.showForIcon(mOriginalIcon);
+ }
+ } else if (widgetInfo == null && widgetsView != null) {
+ // No widgets exist, but we previously added the shortcut so remove it.
+ if (mSystemShortcutContainer
+ != PopupContainerWithArrow.this
+ && mWidgetContainer != null) {
+ mWidgetContainer.removeView(widgetsView);
+ } else {
+ close(false);
+ PopupContainerWithArrow.showForIcon(mOriginalIcon);
+ }
+ }
+ }
+
+ /**
+ * Updates the notification header if the original icon's dot updated.
+ */
+ @Override
+ public void onNotificationDotsUpdated(Predicate<PackageUserKey> updatedDots) {
+ ItemInfo itemInfo = (ItemInfo) mOriginalIcon.getTag();
+ PackageUserKey packageUser = PackageUserKey.fromItemInfo(itemInfo);
+ if (updatedDots.test(packageUser)) {
+ updateNotificationHeader();
+ }
+ }
+
+
+ @Override
+ public void trimNotifications(Map<PackageUserKey, DotInfo> updatedDots) {
+ if (mNotificationItemView == null) {
+ return;
+ }
+ ItemInfo originalInfo = (ItemInfo) mOriginalIcon.getTag();
+ DotInfo dotInfo = updatedDots.get(PackageUserKey.fromItemInfo(originalInfo));
+ if (dotInfo == null || dotInfo.getNotificationKeys().size() == 0) {
+ // No more notifications, remove the notification views and expand all shortcuts.
+ mNotificationItemView.removeAllViews();
+ mNotificationItemView = null;
+ mNotificationContainer.setVisibility(GONE);
+ updateHiddenShortcuts();
+ assignMarginsAndBackgrounds(PopupContainerWithArrow.this);
+ } else {
+ mNotificationItemView.trimNotifications(
+ NotificationKeyData.extractKeysOnly(dotInfo.getNotificationKeys()));
+ }
+ }
}
/**
@@ -541,7 +615,7 @@ public class PopupContainerWithArrow<T extends Context & ActivityContext>
public static void dismissInvalidPopup(BaseDraggingActivity activity) {
PopupContainerWithArrow popup = getOpen(activity);
if (popup != null && (!popup.mOriginalIcon.isAttachedToWindow()
- || !ShortcutUtil.supportsShortcuts((ItemInfo) popup.mOriginalIcon.getTag()))) {
+ || !canShow(popup.mOriginalIcon, (ItemInfo) popup.mOriginalIcon.getTag()))) {
popup.animateClose();
}
}
diff --git a/src/com/android/launcher3/popup/PopupDataProvider.java b/src/com/android/launcher3/popup/PopupDataProvider.java
index 80ffecca2e..6f9f0d7867 100644
--- a/src/com/android/launcher3/popup/PopupDataProvider.java
+++ b/src/com/android/launcher3/popup/PopupDataProvider.java
@@ -264,13 +264,6 @@ public class PopupDataProvider implements NotificationListener.NotificationsChan
writer.println(prefix + "\tmPackageUserToDotInfos:" + mPackageUserToDotInfos);
}
- /**
- * Tells the listener that the system shortcuts have been updated, causing them to be redrawn.
- */
- public void redrawSystemShortcuts() {
- mChangeListener.onSystemShortcutsUpdated();
- }
-
public interface PopupDataChangeListener {
PopupDataChangeListener INSTANCE = new PopupDataChangeListener() { };
@@ -283,8 +276,5 @@ public class PopupDataProvider implements NotificationListener.NotificationsChan
/** A callback to get notified when recommended widgets are bound. */
default void onRecommendedWidgetsBound() { }
-
- /** A callback to get notified when system shortcuts have been updated. */
- default void onSystemShortcutsUpdated() { }
}
}
diff --git a/src/com/android/launcher3/popup/PopupLiveUpdateHandler.java b/src/com/android/launcher3/popup/PopupLiveUpdateHandler.java
deleted file mode 100644
index c5d545225c..0000000000
--- a/src/com/android/launcher3/popup/PopupLiveUpdateHandler.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright (C) 2021 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.launcher3.popup;
-
-import static android.view.View.GONE;
-
-import android.content.Context;
-import android.view.View;
-
-import com.android.launcher3.BubbleTextView;
-import com.android.launcher3.dot.DotInfo;
-import com.android.launcher3.model.data.ItemInfo;
-import com.android.launcher3.notification.NotificationContainer;
-import com.android.launcher3.notification.NotificationKeyData;
-import com.android.launcher3.util.PackageUserKey;
-import com.android.launcher3.views.ActivityContext;
-
-import java.util.Map;
-import java.util.function.Predicate;
-
-/**
- * Utility class to handle updates while the popup is visible (like widgets and
- * notification changes)
- *
- * @param <T> The activity on which the popup shows
- */
-public abstract class PopupLiveUpdateHandler<T extends Context & ActivityContext> implements
- PopupDataProvider.PopupDataChangeListener, View.OnAttachStateChangeListener {
-
- protected final T mContext;
- protected final PopupContainerWithArrow<T> mPopupContainerWithArrow;
-
- public PopupLiveUpdateHandler(
- T context, PopupContainerWithArrow<T> popupContainerWithArrow) {
- mContext = context;
- mPopupContainerWithArrow = popupContainerWithArrow;
- }
-
- @Override
- public void onViewAttachedToWindow(View view) {
- PopupDataProvider popupDataProvider = mContext.getPopupDataProvider();
-
- if (popupDataProvider != null) {
- popupDataProvider.setChangeListener(this);
- }
- }
-
- @Override
- public void onViewDetachedFromWindow(View view) {
- PopupDataProvider popupDataProvider = mContext.getPopupDataProvider();
-
- if (popupDataProvider != null) {
- popupDataProvider.setChangeListener(null);
- }
- }
-
- /**
- * Updates the notification header if the original icon's dot updated.
- */
- @Override
- public void onNotificationDotsUpdated(Predicate<PackageUserKey> updatedDots) {
- ItemInfo itemInfo = (ItemInfo) mPopupContainerWithArrow.getOriginalIcon().getTag();
- PackageUserKey packageUser = PackageUserKey.fromItemInfo(itemInfo);
- if (updatedDots.test(packageUser)) {
- mPopupContainerWithArrow.updateNotificationHeader();
- }
- }
-
-
- @Override
- public void trimNotifications(Map<PackageUserKey, DotInfo> updatedDots) {
- NotificationContainer notificationContainer =
- mPopupContainerWithArrow.getNotificationContainer();
- if (notificationContainer == null) {
- return;
- }
- ItemInfo originalInfo = (ItemInfo) mPopupContainerWithArrow.getOriginalIcon().getTag();
- DotInfo dotInfo = updatedDots.get(PackageUserKey.fromItemInfo(originalInfo));
- if (dotInfo == null || dotInfo.getNotificationKeys().size() == 0) {
- // No more notifications, remove the notification views and expand all shortcuts.
- notificationContainer.setVisibility(GONE);
- mPopupContainerWithArrow.updateHiddenShortcuts();
- mPopupContainerWithArrow.assignMarginsAndBackgrounds(mPopupContainerWithArrow);
- mPopupContainerWithArrow.updateArrowColor();
- } else {
- notificationContainer.trimNotifications(
- NotificationKeyData.extractKeysOnly(dotInfo.getNotificationKeys()));
- }
- }
-
- @Override
- public void onSystemShortcutsUpdated() {
- mPopupContainerWithArrow.close(true);
- showPopupContainerForIcon(mPopupContainerWithArrow.getOriginalIcon());
- }
-
- protected abstract void showPopupContainerForIcon(BubbleTextView originalIcon);
-}
diff --git a/src/com/android/launcher3/popup/PopupPopulator.java b/src/com/android/launcher3/popup/PopupPopulator.java
index 8be4e6c8d9..5ed6f2e37e 100644
--- a/src/com/android/launcher3/popup/PopupPopulator.java
+++ b/src/com/android/launcher3/popup/PopupPopulator.java
@@ -19,7 +19,6 @@ package com.android.launcher3.popup;
import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_SHORTCUTS;
import android.content.ComponentName;
-import android.content.Context;
import android.content.pm.ShortcutInfo;
import android.os.Handler;
import android.os.UserHandle;
@@ -27,6 +26,7 @@ import android.os.UserHandle;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
+import com.android.launcher3.BaseDraggingActivity;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.icons.IconCache;
import com.android.launcher3.model.data.ItemInfo;
@@ -36,7 +36,6 @@ import com.android.launcher3.notification.NotificationKeyData;
import com.android.launcher3.notification.NotificationListener;
import com.android.launcher3.shortcuts.DeepShortcutView;
import com.android.launcher3.shortcuts.ShortcutRequest;
-import com.android.launcher3.views.ActivityContext;
import java.util.ArrayList;
import java.util.Collections;
@@ -129,8 +128,7 @@ public class PopupPopulator {
/**
* Returns a runnable to update the provided shortcuts and notifications
*/
- public static <T extends Context & ActivityContext> Runnable createUpdateRunnable(
- final T context,
+ public static Runnable createUpdateRunnable(final BaseDraggingActivity launcher,
final ItemInfo originalInfo,
final Handler uiHandler, final PopupContainerWithArrow container,
final List<DeepShortcutView> shortcutViews,
@@ -146,23 +144,23 @@ public class PopupPopulator {
infos = Collections.emptyList();
} else {
infos = notificationListener.getNotificationsForKeys(notificationKeys).stream()
- .map(sbn -> new NotificationInfo(context, sbn, originalInfo))
+ .map(sbn -> new NotificationInfo(launcher, sbn, originalInfo))
.collect(Collectors.toList());
}
uiHandler.post(() -> container.applyNotificationInfos(infos));
}
- List<ShortcutInfo> shortcuts = new ShortcutRequest(context, user)
+ List<ShortcutInfo> shortcuts = new ShortcutRequest(launcher, user)
.withContainer(activity)
.query(ShortcutRequest.PUBLISHED);
String shortcutIdToDeDupe = notificationKeys.isEmpty() ? null
: notificationKeys.get(0).shortcutId;
shortcuts = PopupPopulator.sortAndFilterShortcuts(shortcuts, shortcutIdToDeDupe);
- IconCache cache = LauncherAppState.getInstance(context).getIconCache();
+ IconCache cache = LauncherAppState.getInstance(launcher).getIconCache();
for (int i = 0; i < shortcuts.size() && i < shortcutViews.size(); i++) {
final ShortcutInfo shortcut = shortcuts.get(i);
- final WorkspaceItemInfo si = new WorkspaceItemInfo(shortcut, context);
- cache.getShortcutIcon(si, shortcut);
+ final WorkspaceItemInfo si = new WorkspaceItemInfo(shortcut, launcher);
+ cache.getUnbadgedShortcutIcon(si, shortcut);
si.rank = i;
si.container = CONTAINER_SHORTCUTS;
diff --git a/src/com/android/launcher3/popup/RemoteActionShortcut.java b/src/com/android/launcher3/popup/RemoteActionShortcut.java
index e5e2c350b4..7c393ad1e2 100644
--- a/src/com/android/launcher3/popup/RemoteActionShortcut.java
+++ b/src/com/android/launcher3/popup/RemoteActionShortcut.java
@@ -46,8 +46,8 @@ public class RemoteActionShortcut extends SystemShortcut<BaseDraggingActivity> {
private final RemoteAction mAction;
public RemoteActionShortcut(RemoteAction action,
- BaseDraggingActivity activity, ItemInfo itemInfo, View originalView) {
- super(0, R.id.action_remote_action_shortcut, activity, itemInfo, originalView);
+ BaseDraggingActivity activity, ItemInfo itemInfo) {
+ super(0, R.id.action_remote_action_shortcut, activity, itemInfo);
mAction = action;
}
diff --git a/src/com/android/launcher3/popup/RoundedArrowDrawable.java b/src/com/android/launcher3/popup/RoundedArrowDrawable.java
index 436aa51de9..e662d5c039 100644
--- a/src/com/android/launcher3/popup/RoundedArrowDrawable.java
+++ b/src/com/android/launcher3/popup/RoundedArrowDrawable.java
@@ -78,32 +78,6 @@ public class RoundedArrowDrawable extends Drawable {
mPath.transform(pathTransform);
}
- /**
- * Constructor for an arrow that points to the left or right.
- *
- * @param width of the arrow.
- * @param height of the arrow.
- * @param radius of the tip of the arrow.
- * @param isPointingLeft or not.
- * @param color to draw the triangle.
- */
- public RoundedArrowDrawable(float width, float height, float radius, boolean isPointingLeft,
- int color) {
- mPath = new Path();
- mPaint = new Paint();
- mPaint.setColor(color);
- mPaint.setStyle(Paint.Style.FILL);
- mPaint.setAntiAlias(true);
-
- // Make the drawable with the triangle pointing down...
- addDownPointingRoundedTriangleToPath(width, height, radius, mPath);
-
- // ... then rotate it to the side it needs to point.
- Matrix pathTransform = new Matrix();
- pathTransform.setRotate(isPointingLeft ? 90 : -90, width * 0.5f, height * 0.5f);
- mPath.transform(pathTransform);
- }
-
@Override
public void draw(Canvas canvas) {
canvas.drawPath(mPath, mPaint);
diff --git a/src/com/android/launcher3/popup/SystemShortcut.java b/src/com/android/launcher3/popup/SystemShortcut.java
index 0e25984c1b..d3f4909296 100644
--- a/src/com/android/launcher3/popup/SystemShortcut.java
+++ b/src/com/android/launcher3/popup/SystemShortcut.java
@@ -18,14 +18,12 @@ import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.BaseDraggingActivity;
import com.android.launcher3.Launcher;
import com.android.launcher3.R;
-import com.android.launcher3.Utilities;
import com.android.launcher3.model.WidgetItem;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.launcher3.util.InstantAppResolver;
import com.android.launcher3.util.PackageManagerHelper;
import com.android.launcher3.util.PackageUserKey;
-import com.android.launcher3.views.ActivityContext;
import com.android.launcher3.widget.WidgetsBottomSheet;
import java.util.List;
@@ -37,30 +35,29 @@ import java.util.List;
* Example system shortcuts, defined as inner classes, include Widgets and AppInfo.
* @param <T>
*/
-public abstract class SystemShortcut<T extends Context & ActivityContext> extends ItemInfo
+public abstract class SystemShortcut<T extends BaseDraggingActivity> extends ItemInfo
implements View.OnClickListener {
private final int mIconResId;
- protected final int mLabelResId;
- protected int mAccessibilityActionId;
+ private final int mLabelResId;
+ private final int mAccessibilityActionId;
protected final T mTarget;
protected final ItemInfo mItemInfo;
- protected final View mOriginalView;
/**
* Indicates if it's invokable or not through some disabled UI
*/
private boolean isEnabled = true;
- public SystemShortcut(int iconResId, int labelResId, T target, ItemInfo itemInfo,
- View originalView) {
+ private boolean mHasFinishRecentsInAction = false;
+
+ public SystemShortcut(int iconResId, int labelResId, T target, ItemInfo itemInfo) {
mIconResId = iconResId;
mLabelResId = labelResId;
mAccessibilityActionId = labelResId;
mTarget = target;
mItemInfo = itemInfo;
- mOriginalView = originalView;
}
public SystemShortcut(SystemShortcut<T> other) {
@@ -69,7 +66,6 @@ public abstract class SystemShortcut<T extends Context & ActivityContext> extend
mAccessibilityActionId = other.mAccessibilityActionId;
mTarget = other.mTarget;
mItemInfo = other.mItemInfo;
- mOriginalView = other.mOriginalView;
}
/**
@@ -81,15 +77,12 @@ public abstract class SystemShortcut<T extends Context & ActivityContext> extend
public void setIconAndLabelFor(View iconView, TextView labelView) {
iconView.setBackgroundResource(mIconResId);
- iconView.setEnabled(isEnabled);
labelView.setText(mLabelResId);
- labelView.setEnabled(isEnabled);
}
public void setIconAndContentDescriptionFor(ImageView view) {
view.setImageResource(mIconResId);
view.setContentDescription(view.getContext().getText(mLabelResId));
- view.setEnabled(isEnabled);
}
public AccessibilityNodeInfo.AccessibilityAction createAccessibilityAction(Context context) {
@@ -109,12 +102,20 @@ public abstract class SystemShortcut<T extends Context & ActivityContext> extend
return mAccessibilityActionId == action;
}
- public interface Factory<T extends Context & ActivityContext> {
+ public void setHasFinishRecentsInAction(boolean hasFinishRecentsInAction) {
+ mHasFinishRecentsInAction = hasFinishRecentsInAction;
+ }
+
+ public boolean hasFinishRecentsInAction() {
+ return mHasFinishRecentsInAction;
+ }
+
+ public interface Factory<T extends BaseDraggingActivity> {
- @Nullable SystemShortcut<T> getShortcut(T activity, ItemInfo itemInfo, View originalView);
+ @Nullable SystemShortcut<T> getShortcut(T activity, ItemInfo itemInfo);
}
- public static final Factory<Launcher> WIDGETS = (launcher, itemInfo, originalView) -> {
+ public static final Factory<Launcher> WIDGETS = (launcher, itemInfo) -> {
if (itemInfo.getTargetComponent() == null) return null;
final List<WidgetItem> widgets =
launcher.getPopupDataProvider().getWidgetsForPackageUser(new PackageUserKey(
@@ -122,13 +123,12 @@ public abstract class SystemShortcut<T extends Context & ActivityContext> extend
if (widgets.isEmpty()) {
return null;
}
- return new Widgets(launcher, itemInfo, originalView);
+ return new Widgets(launcher, itemInfo);
};
public static class Widgets extends SystemShortcut<Launcher> {
- public Widgets(Launcher target, ItemInfo itemInfo, View originalView) {
- super(R.drawable.ic_widget, R.string.widget_button_text, target, itemInfo,
- originalView);
+ public Widgets(Launcher target, ItemInfo itemInfo) {
+ super(R.drawable.ic_widget, R.string.widget_button_text, target, itemInfo);
}
@Override
@@ -145,93 +145,46 @@ public abstract class SystemShortcut<T extends Context & ActivityContext> extend
public static final Factory<BaseDraggingActivity> APP_INFO = AppInfo::new;
- public static class AppInfo<T extends Context & ActivityContext> extends SystemShortcut<T> {
-
- @Nullable
- private SplitAccessibilityInfo mSplitA11yInfo;
+ public static class AppInfo extends SystemShortcut {
- public AppInfo(T target, ItemInfo itemInfo, View originalView) {
+ public AppInfo(BaseDraggingActivity target, ItemInfo itemInfo) {
super(R.drawable.ic_info_no_shadow, R.string.app_info_drop_target_label, target,
- itemInfo, originalView);
- }
-
- /**
- * Constructor used by overview for staged split to provide custom A11y information.
- *
- * Future improvements considerations:
- * Have the logic in {@link #createAccessibilityAction(Context)} be moved to super
- * call in {@link SystemShortcut#createAccessibilityAction(Context)} by having
- * SystemShortcut be aware of TaskContainers and staged split.
- * That way it could directly create the correct node info for any shortcut that supports
- * split, but then we'll need custom resIDs for each pair of shortcuts.
- */
- public AppInfo(T target, ItemInfo itemInfo, View originalView,
- SplitAccessibilityInfo accessibilityInfo) {
- this(target, itemInfo, originalView);
- mSplitA11yInfo = accessibilityInfo;
- mAccessibilityActionId = accessibilityInfo.nodeId;
- }
-
- @Override
- public AccessibilityNodeInfo.AccessibilityAction createAccessibilityAction(
- Context context) {
- if (mSplitA11yInfo != null && mSplitA11yInfo.containsMultipleTasks) {
- String accessibilityLabel = context.getString(R.string.split_app_info_accessibility,
- mSplitA11yInfo.taskTitle);
- return new AccessibilityNodeInfo.AccessibilityAction(mAccessibilityActionId,
- accessibilityLabel);
- } else {
- return super.createAccessibilityAction(context);
- }
+ itemInfo);
}
@Override
public void onClick(View view) {
dismissTaskMenuView(mTarget);
- Rect sourceBounds = Utilities.getViewBounds(view);
+ Rect sourceBounds = mTarget.getViewBounds(view);
new PackageManagerHelper(mTarget).startDetailsActivityForInfo(
mItemInfo, sourceBounds, ActivityOptions.makeBasic().toBundle());
mTarget.getStatsLogManager().logger().withItemInfo(mItemInfo)
.log(LAUNCHER_SYSTEM_SHORTCUT_APP_INFO_TAP);
}
-
- public static class SplitAccessibilityInfo {
- public final boolean containsMultipleTasks;
- public final CharSequence taskTitle;
- public final int nodeId;
-
- public SplitAccessibilityInfo(boolean containsMultipleTasks,
- CharSequence taskTitle, int nodeId) {
- this.containsMultipleTasks = containsMultipleTasks;
- this.taskTitle = taskTitle;
- this.nodeId = nodeId;
- }
- }
}
- public static final Factory<BaseDraggingActivity> INSTALL =
- (activity, itemInfo, originalView) -> {
- boolean supportsWebUI = (itemInfo instanceof WorkspaceItemInfo)
- && ((WorkspaceItemInfo) itemInfo).hasStatusFlag(
+ public static final Factory<BaseDraggingActivity> INSTALL = (activity, itemInfo) -> {
+ boolean supportsWebUI = (itemInfo instanceof WorkspaceItemInfo)
+ && ((WorkspaceItemInfo) itemInfo).hasStatusFlag(
WorkspaceItemInfo.FLAG_SUPPORTS_WEB_UI);
- boolean isInstantApp = false;
- if (itemInfo instanceof com.android.launcher3.model.data.AppInfo) {
- com.android.launcher3.model.data.AppInfo
- appInfo = (com.android.launcher3.model.data.AppInfo) itemInfo;
- isInstantApp = InstantAppResolver.newInstance(activity).isInstantApp(appInfo);
- }
- boolean enabled = supportsWebUI || isInstantApp;
- if (!enabled) {
- return null;
- }
- return new Install(activity, itemInfo, originalView);
+ boolean isInstantApp = false;
+ if (itemInfo instanceof com.android.launcher3.model.data.AppInfo) {
+ com.android.launcher3.model.data.AppInfo
+ appInfo = (com.android.launcher3.model.data.AppInfo) itemInfo;
+ isInstantApp = InstantAppResolver.newInstance(activity).isInstantApp(appInfo);
+ }
+ boolean enabled = supportsWebUI || isInstantApp;
+ if (!enabled) {
+ return null;
+ }
+ return new Install(activity, itemInfo);
};
- public static class Install extends SystemShortcut<BaseDraggingActivity> {
+ public static class Install extends SystemShortcut {
- public Install(BaseDraggingActivity target, ItemInfo itemInfo, View originalView) {
+ public Install(BaseDraggingActivity target, ItemInfo itemInfo) {
super(R.drawable.ic_install_no_shadow, R.string.install_drop_target_label,
- target, itemInfo, originalView);
+ target, itemInfo);
}
@Override
@@ -243,7 +196,7 @@ public abstract class SystemShortcut<T extends Context & ActivityContext> extend
}
}
- public static <T extends Context & ActivityContext> void dismissTaskMenuView(T activity) {
+ public static void dismissTaskMenuView(BaseDraggingActivity activity) {
AbstractFloatingView.closeOpenViews(activity, true,
AbstractFloatingView.TYPE_ALL & ~AbstractFloatingView.TYPE_REBIND_SAFE);
}
diff --git a/src/com/android/launcher3/provider/ImportDataTask.java b/src/com/android/launcher3/provider/ImportDataTask.java
new file mode 100644
index 0000000000..c9af2fe6fc
--- /dev/null
+++ b/src/com/android/launcher3/provider/ImportDataTask.java
@@ -0,0 +1,438 @@
+/*
+ * Copyright (C) 2016 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.launcher3.provider;
+
+import static com.android.launcher3.Utilities.getDevicePrefs;
+
+import android.content.ContentProviderOperation;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ProviderInfo;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.net.Uri;
+import android.os.Process;
+import android.text.TextUtils;
+import android.util.ArrayMap;
+import android.util.SparseBooleanArray;
+
+import com.android.launcher3.AutoInstallsLayout.LayoutParserCallback;
+import com.android.launcher3.DefaultLayoutParser;
+import com.android.launcher3.LauncherAppState;
+import com.android.launcher3.LauncherProvider;
+import com.android.launcher3.LauncherSettings;
+import com.android.launcher3.LauncherSettings.Favorites;
+import com.android.launcher3.LauncherSettings.Settings;
+import com.android.launcher3.Workspace;
+import com.android.launcher3.config.FeatureFlags;
+import com.android.launcher3.logging.FileLog;
+import com.android.launcher3.model.GridSizeMigrationTask;
+import com.android.launcher3.model.data.LauncherAppWidgetInfo;
+import com.android.launcher3.pm.UserCache;
+import com.android.launcher3.util.IntArray;
+import com.android.launcher3.util.IntSparseArrayMap;
+import com.android.launcher3.util.PackageManagerHelper;
+
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.HashSet;
+
+/**
+ * Utility class to import data from another Launcher which is based on Launcher3 schema.
+ */
+public class ImportDataTask {
+
+ public static final String KEY_DATA_IMPORT_SRC_PKG = "data_import_src_pkg";
+ public static final String KEY_DATA_IMPORT_SRC_AUTHORITY = "data_import_src_authority";
+
+ private static final String TAG = "ImportDataTask";
+ private static final int MIN_ITEM_COUNT_FOR_SUCCESSFUL_MIGRATION = 6;
+ // Insert items progressively to avoid OOM exception when loading icons.
+ private static final int BATCH_INSERT_SIZE = 15;
+
+ private final Context mContext;
+
+ private final Uri mOtherFavoritesUri;
+
+ private int mHotseatSize;
+ private int mMaxGridSizeX;
+ private int mMaxGridSizeY;
+
+ private ImportDataTask(Context context, String sourceAuthority) {
+ mContext = context;
+ mOtherFavoritesUri = Uri.parse("content://" + sourceAuthority + "/" + Favorites.TABLE_NAME);
+ }
+
+ public boolean importWorkspace() throws Exception {
+ FileLog.d(TAG, "Importing DB from " + mOtherFavoritesUri);
+
+ mHotseatSize = mMaxGridSizeX = mMaxGridSizeY = 0;
+ importWorkspaceItems();
+ GridSizeMigrationTask.markForMigration(mContext, mMaxGridSizeX, mMaxGridSizeY, mHotseatSize);
+
+ // Create empty DB flag.
+ LauncherSettings.Settings.call(mContext.getContentResolver(),
+ LauncherSettings.Settings.METHOD_CLEAR_EMPTY_DB_FLAG);
+ return true;
+ }
+
+ /**
+ * 1) Imports all the workspace entries from the source provider.
+ * 2) For home screen entries, maps the screen id based on {@param screenIdMap}
+ * 3) In the end fills any holes in hotseat with items from default hotseat layout.
+ */
+ private void importWorkspaceItems() throws Exception {
+ String profileId = Long.toString(UserCache.INSTANCE.get(mContext)
+ .getSerialNumberForUser(Process.myUserHandle()));
+
+ boolean createEmptyRowOnFirstScreen;
+ if (FeatureFlags.QSB_ON_FIRST_SCREEN) {
+ try (Cursor c = mContext.getContentResolver().query(mOtherFavoritesUri, null,
+ // get items on the first row of the first screen (min screen id)
+ "profileId = ? AND container = -100 AND cellY = 0 AND screen = " +
+ "(SELECT MIN(screen) FROM favorites WHERE container = -100)",
+ new String[]{profileId},
+ null)) {
+ // First row of first screen is not empty
+ createEmptyRowOnFirstScreen = c.moveToNext();
+ }
+ } else {
+ createEmptyRowOnFirstScreen = false;
+ }
+
+ ArrayList<ContentProviderOperation> insertOperations = new ArrayList<>(BATCH_INSERT_SIZE);
+
+ // Set of package names present in hotseat
+ final HashSet<String> hotseatTargetApps = new HashSet<>();
+ int maxId = 0;
+
+ // Number of imported items on workspace and hotseat
+ int totalItemsOnWorkspace = 0;
+
+ try (Cursor c = mContext.getContentResolver()
+ .query(mOtherFavoritesUri, null,
+ // Only migrate the primary user
+ Favorites.PROFILE_ID + " = ?", new String[]{profileId},
+ // Get the items sorted by container, so that the folders are loaded
+ // before the corresponding items.
+ Favorites.CONTAINER + " , " + Favorites.SCREEN)) {
+
+ // various columns we expect to exist.
+ final int idIndex = c.getColumnIndexOrThrow(Favorites._ID);
+ final int intentIndex = c.getColumnIndexOrThrow(Favorites.INTENT);
+ final int titleIndex = c.getColumnIndexOrThrow(Favorites.TITLE);
+ final int containerIndex = c.getColumnIndexOrThrow(Favorites.CONTAINER);
+ final int itemTypeIndex = c.getColumnIndexOrThrow(Favorites.ITEM_TYPE);
+ final int widgetProviderIndex = c.getColumnIndexOrThrow(Favorites.APPWIDGET_PROVIDER);
+ final int screenIndex = c.getColumnIndexOrThrow(Favorites.SCREEN);
+ final int cellXIndex = c.getColumnIndexOrThrow(Favorites.CELLX);
+ final int cellYIndex = c.getColumnIndexOrThrow(Favorites.CELLY);
+ final int spanXIndex = c.getColumnIndexOrThrow(Favorites.SPANX);
+ final int spanYIndex = c.getColumnIndexOrThrow(Favorites.SPANY);
+ final int rankIndex = c.getColumnIndexOrThrow(Favorites.RANK);
+ final int iconIndex = c.getColumnIndexOrThrow(Favorites.ICON);
+ final int iconPackageIndex = c.getColumnIndexOrThrow(Favorites.ICON_PACKAGE);
+ final int iconResourceIndex = c.getColumnIndexOrThrow(Favorites.ICON_RESOURCE);
+
+ SparseBooleanArray mValidFolders = new SparseBooleanArray();
+ ContentValues values = new ContentValues();
+
+ Integer firstScreenId = null;
+ while (c.moveToNext()) {
+ values.clear();
+ int id = c.getInt(idIndex);
+ maxId = Math.max(maxId, id);
+ int type = c.getInt(itemTypeIndex);
+ int container = c.getInt(containerIndex);
+
+ int screen = c.getInt(screenIndex);
+
+ int cellX = c.getInt(cellXIndex);
+ int cellY = c.getInt(cellYIndex);
+ int spanX = c.getInt(spanXIndex);
+ int spanY = c.getInt(spanYIndex);
+
+ switch (container) {
+ case Favorites.CONTAINER_DESKTOP: {
+ if (screen < Workspace.FIRST_SCREEN_ID) {
+ FileLog.d(TAG, String.format(
+ "Skipping item %d, type %d not on a valid screen %d",
+ id, type, screen));
+ continue;
+ }
+ if (firstScreenId == null) {
+ firstScreenId = screen;
+ }
+ // Reset the screen to 0-index value
+ if (createEmptyRowOnFirstScreen && firstScreenId.equals(screen)) {
+ // Shift items by 1.
+ cellY++;
+ // Change the screen id to first screen
+ screen = Workspace.FIRST_SCREEN_ID;
+ }
+
+ mMaxGridSizeX = Math.max(mMaxGridSizeX, cellX + spanX);
+ mMaxGridSizeY = Math.max(mMaxGridSizeY, cellY + spanY);
+ break;
+ }
+ case Favorites.CONTAINER_HOTSEAT: {
+ mHotseatSize = Math.max(mHotseatSize, screen + 1);
+ break;
+ }
+ default:
+ if (!mValidFolders.get(container)) {
+ FileLog.d(TAG, String.format("Skipping item %d, type %d not in a valid folder %d", id, type, container));
+ continue;
+ }
+ }
+
+ Intent intent = null;
+ switch (type) {
+ case Favorites.ITEM_TYPE_FOLDER: {
+ mValidFolders.put(id, true);
+ // Use a empty intent to indicate a folder.
+ intent = new Intent();
+ break;
+ }
+ case Favorites.ITEM_TYPE_APPWIDGET: {
+ values.put(Favorites.RESTORED,
+ LauncherAppWidgetInfo.FLAG_ID_NOT_VALID |
+ LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY |
+ LauncherAppWidgetInfo.FLAG_UI_NOT_READY);
+ values.put(Favorites.APPWIDGET_PROVIDER, c.getString(widgetProviderIndex));
+ break;
+ }
+ case Favorites.ITEM_TYPE_SHORTCUT:
+ case Favorites.ITEM_TYPE_APPLICATION: {
+ intent = Intent.parseUri(c.getString(intentIndex), 0);
+ if (PackageManagerHelper.isLauncherAppTarget(intent)) {
+ type = Favorites.ITEM_TYPE_APPLICATION;
+ } else {
+ values.put(Favorites.ICON_PACKAGE, c.getString(iconPackageIndex));
+ values.put(Favorites.ICON_RESOURCE, c.getString(iconResourceIndex));
+ }
+ values.put(Favorites.ICON, c.getBlob(iconIndex));
+ values.put(Favorites.INTENT, intent.toUri(0));
+ values.put(Favorites.RANK, c.getInt(rankIndex));
+
+ values.put(Favorites.RESTORED, 1);
+ break;
+ }
+ default:
+ FileLog.d(TAG, String.format("Skipping item %d, not a valid type %d", id, type));
+ continue;
+ }
+
+ if (container == Favorites.CONTAINER_HOTSEAT) {
+ if (intent == null) {
+ FileLog.d(TAG, String.format("Skipping item %d, null intent on hotseat", id));
+ continue;
+ }
+ if (intent.getComponent() != null) {
+ intent.setPackage(intent.getComponent().getPackageName());
+ }
+ hotseatTargetApps.add(getPackage(intent));
+ }
+
+ values.put(Favorites._ID, id);
+ values.put(Favorites.ITEM_TYPE, type);
+ values.put(Favorites.CONTAINER, container);
+ values.put(Favorites.SCREEN, screen);
+ values.put(Favorites.CELLX, cellX);
+ values.put(Favorites.CELLY, cellY);
+ values.put(Favorites.SPANX, spanX);
+ values.put(Favorites.SPANY, spanY);
+ values.put(Favorites.TITLE, c.getString(titleIndex));
+ insertOperations.add(ContentProviderOperation
+ .newInsert(Favorites.CONTENT_URI).withValues(values).build());
+ if (container < 0) {
+ totalItemsOnWorkspace++;
+ }
+
+ if (insertOperations.size() >= BATCH_INSERT_SIZE) {
+ mContext.getContentResolver().applyBatch(LauncherProvider.AUTHORITY,
+ insertOperations);
+ insertOperations.clear();
+ }
+ }
+ }
+ FileLog.d(TAG, totalItemsOnWorkspace + " items imported from external source");
+ if (totalItemsOnWorkspace < MIN_ITEM_COUNT_FOR_SUCCESSFUL_MIGRATION) {
+ throw new Exception("Insufficient data");
+ }
+ if (!insertOperations.isEmpty()) {
+ mContext.getContentResolver().applyBatch(LauncherProvider.AUTHORITY,
+ insertOperations);
+ insertOperations.clear();
+ }
+
+ IntSparseArrayMap<Object> hotseatItems = GridSizeMigrationTask
+ .removeBrokenHotseatItems(mContext);
+ int myHotseatCount = LauncherAppState.getIDP(mContext).numDatabaseHotseatIcons;
+ if (hotseatItems.size() < myHotseatCount) {
+ // Insufficient hotseat items. Add a few more.
+ HotseatParserCallback parserCallback = new HotseatParserCallback(
+ hotseatTargetApps, hotseatItems, insertOperations, maxId + 1, myHotseatCount);
+ new HotseatLayoutParser(mContext,
+ parserCallback).loadLayout(null, new IntArray());
+ mHotseatSize = hotseatItems.keyAt(hotseatItems.size() - 1) + 1;
+
+ if (!insertOperations.isEmpty()) {
+ mContext.getContentResolver().applyBatch(LauncherProvider.AUTHORITY,
+ insertOperations);
+ }
+ }
+ }
+
+ private static String getPackage(Intent intent) {
+ return intent.getComponent() != null ? intent.getComponent().getPackageName()
+ : intent.getPackage();
+ }
+
+ /**
+ * Performs data import if possible.
+ * @return true on successful data import, false if it was not available
+ * @throws Exception if the import failed
+ */
+ public static boolean performImportIfPossible(Context context) throws Exception {
+ SharedPreferences devicePrefs = getDevicePrefs(context);
+ String sourcePackage = devicePrefs.getString(KEY_DATA_IMPORT_SRC_PKG, "");
+ String sourceAuthority = devicePrefs.getString(KEY_DATA_IMPORT_SRC_AUTHORITY, "");
+
+ if (TextUtils.isEmpty(sourcePackage) || TextUtils.isEmpty(sourceAuthority)) {
+ return false;
+ }
+
+ // Synchronously clear the migration flags. This ensures that we do not try migration
+ // again and thus prevents potential crash loops due to migration failure.
+ devicePrefs.edit().remove(KEY_DATA_IMPORT_SRC_PKG).remove(KEY_DATA_IMPORT_SRC_AUTHORITY).commit();
+
+ if (!Settings.call(context.getContentResolver(), Settings.METHOD_WAS_EMPTY_DB_CREATED)
+ .getBoolean(Settings.EXTRA_VALUE, false)) {
+ // Only migration if a new DB was created.
+ return false;
+ }
+
+ for (ProviderInfo info : context.getPackageManager().queryContentProviders(
+ null, context.getApplicationInfo().uid, 0)) {
+
+ if (sourcePackage.equals(info.packageName)) {
+ if ((info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
+ // Only migrate if the source launcher is also on system image.
+ return false;
+ }
+
+ // Wait until we found a provider with matching authority.
+ if (sourceAuthority.equals(info.authority)) {
+ if (TextUtils.isEmpty(info.readPermission) ||
+ context.checkPermission(info.readPermission, Process.myPid(),
+ Process.myUid()) == PackageManager.PERMISSION_GRANTED) {
+ // All checks passed, run the import task.
+ return new ImportDataTask(context, sourceAuthority).importWorkspace();
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Extension of {@link DefaultLayoutParser} which only allows icons and shortcuts.
+ */
+ private static class HotseatLayoutParser extends DefaultLayoutParser {
+ public HotseatLayoutParser(Context context, LayoutParserCallback callback) {
+ super(context, null, callback, context.getResources(),
+ LauncherAppState.getIDP(context).defaultLayoutId);
+ }
+
+ @Override
+ protected ArrayMap<String, TagParser> getLayoutElementsMap() {
+ // Only allow shortcut parsers
+ ArrayMap<String, TagParser> parsers = new ArrayMap<>();
+ parsers.put(TAG_FAVORITE, new AppShortcutWithUriParser());
+ parsers.put(TAG_SHORTCUT, new UriShortcutParser(mSourceRes));
+ parsers.put(TAG_RESOLVE, new ResolveParser());
+ return parsers;
+ }
+ }
+
+ /**
+ * {@link LayoutParserCallback} which adds items in empty hotseat spots.
+ */
+ private static class HotseatParserCallback implements LayoutParserCallback {
+ private final HashSet<String> mExistingApps;
+ private final IntSparseArrayMap<Object> mExistingItems;
+ private final ArrayList<ContentProviderOperation> mOutOps;
+ private final int mRequiredSize;
+ private int mStartItemId;
+
+ HotseatParserCallback(
+ HashSet<String> existingApps, IntSparseArrayMap<Object> existingItems,
+ ArrayList<ContentProviderOperation> outOps, int startItemId, int requiredSize) {
+ mExistingApps = existingApps;
+ mExistingItems = existingItems;
+ mOutOps = outOps;
+ mRequiredSize = requiredSize;
+ mStartItemId = startItemId;
+ }
+
+ @Override
+ public int generateNewItemId() {
+ return mStartItemId++;
+ }
+
+ @Override
+ public int insertAndCheck(SQLiteDatabase db, ContentValues values) {
+ if (mExistingItems.size() >= mRequiredSize) {
+ // No need to add more items.
+ return 0;
+ }
+ if (!Integer.valueOf(Favorites.CONTAINER_HOTSEAT)
+ .equals(values.getAsInteger(Favorites.CONTAINER))) {
+ // Ignore items which are not for hotseat.
+ return 0;
+ }
+
+ Intent intent;
+ try {
+ intent = Intent.parseUri(values.getAsString(Favorites.INTENT), 0);
+ } catch (URISyntaxException e) {
+ return 0;
+ }
+ String pkg = getPackage(intent);
+ if (pkg == null || mExistingApps.contains(pkg)) {
+ // The item does not target an app or is already in hotseat.
+ return 0;
+ }
+ mExistingApps.add(pkg);
+
+ // find next vacant spot.
+ int screen = 0;
+ while (mExistingItems.get(screen) != null) {
+ screen++;
+ }
+ mExistingItems.put(screen, intent);
+ values.put(Favorites.SCREEN, screen);
+ mOutOps.add(ContentProviderOperation.newInsert(Favorites.CONTENT_URI).withValues(values).build());
+ return 0;
+ }
+ }
+}
diff --git a/src/com/android/launcher3/provider/LauncherDbUtils.java b/src/com/android/launcher3/provider/LauncherDbUtils.java
index b5103787d4..7e05a5a78d 100644
--- a/src/com/android/launcher3/provider/LauncherDbUtils.java
+++ b/src/com/android/launcher3/provider/LauncherDbUtils.java
@@ -16,26 +16,89 @@
package com.android.launcher3.provider;
+import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
+import android.database.DatabaseUtils;
import android.database.sqlite.SQLiteDatabase;
import android.os.Binder;
import android.os.Process;
+import android.util.Log;
+import com.android.launcher3.LauncherAppState;
import com.android.launcher3.LauncherSettings.Favorites;
import com.android.launcher3.pm.UserCache;
import com.android.launcher3.util.IntArray;
+import java.util.Locale;
+
/**
* A set of utility methods for Launcher DB used for DB updates and migration.
*/
public class LauncherDbUtils {
- public static IntArray queryIntArray(boolean distinct, SQLiteDatabase db, String tableName,
- String columnName, String selection, String groupBy, String orderBy) {
+ private static final String TAG = "LauncherDbUtils";
+
+ /**
+ * Makes the first screen as screen 0 (if screen 0 already exists,
+ * renames it to some other number).
+ * If the first row of screen 0 is non empty, runs a 'lossy' GridMigrationTask to clear
+ * the first row. The items in the first screen are moved and resized but the carry-forward
+ * items are simply deleted.
+ */
+ public static boolean prepareScreenZeroToHostQsb(Context context, SQLiteDatabase db) {
+ try (SQLiteTransaction t = new SQLiteTransaction(db)) {
+ // Get the first screen
+ final int firstScreenId;
+ try (Cursor c = db.rawQuery(String.format(Locale.ENGLISH,
+ "SELECT MIN(%1$s) from %2$s where %3$s = %4$d",
+ Favorites.SCREEN, Favorites.TABLE_NAME, Favorites.CONTAINER,
+ Favorites.CONTAINER_DESKTOP), null)) {
+
+ if (!c.moveToNext()) {
+ // No update needed
+ t.commit();
+ return true;
+ }
+
+ firstScreenId = c.getInt(0);
+ }
+
+ if (firstScreenId != 0) {
+ // Rename the first screen to 0.
+ renameScreen(db, firstScreenId, 0);
+ }
+
+ // Check if the first row is empty
+ if (DatabaseUtils.queryNumEntries(db, Favorites.TABLE_NAME,
+ "container = -100 and screen = 0 and cellY = 0") == 0) {
+ // First row is empty, no need to migrate.
+ t.commit();
+ return true;
+ }
+
+ new LossyScreenMigrationTask(context, LauncherAppState.getIDP(context), db)
+ .migrateScreen0();
+ t.commit();
+ return true;
+ } catch (Exception e) {
+ Log.e(TAG, "Failed to update workspace size", e);
+ return false;
+ }
+ }
+
+ private static void renameScreen(SQLiteDatabase db, int oldScreen, int newScreen) {
+ String[] whereParams = new String[] { Integer.toString(oldScreen) };
+ ContentValues values = new ContentValues();
+ values.put(Favorites.SCREEN, newScreen);
+ db.update(Favorites.TABLE_NAME, values, "container = -100 and screen = ?", whereParams);
+ }
+
+ public static IntArray queryIntArray(SQLiteDatabase db, String tableName, String columnName,
+ String selection, String groupBy, String orderBy) {
IntArray out = new IntArray();
- try (Cursor c = db.query(distinct, tableName, new String[] { columnName }, selection, null,
- groupBy, null, orderBy, null)) {
+ try (Cursor c = db.query(tableName, new String[] { columnName }, selection, null,
+ groupBy, null, orderBy)) {
while (c.moveToNext()) {
out.add(c.getInt(0));
}
diff --git a/src/com/android/launcher3/provider/LossyScreenMigrationTask.java b/src/com/android/launcher3/provider/LossyScreenMigrationTask.java
new file mode 100644
index 0000000000..c0111b9388
--- /dev/null
+++ b/src/com/android/launcher3/provider/LossyScreenMigrationTask.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2016 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.launcher3.provider;
+
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.sqlite.SQLiteDatabase;
+import android.graphics.Point;
+
+import com.android.launcher3.InvariantDeviceProfile;
+import com.android.launcher3.LauncherSettings.Favorites;
+import com.android.launcher3.Utilities;
+import com.android.launcher3.Workspace;
+import com.android.launcher3.model.GridSizeMigrationTask;
+import com.android.launcher3.util.IntSparseArrayMap;
+
+import java.util.ArrayList;
+
+/**
+ * An extension of {@link GridSizeMigrationTask} which migrates only one screen and
+ * deletes all carry-forward items.
+ */
+public class LossyScreenMigrationTask extends GridSizeMigrationTask {
+
+ private final IntSparseArrayMap<DbEntry> mOriginalItems;
+ private final IntSparseArrayMap<DbEntry> mUpdates;
+
+ protected LossyScreenMigrationTask(
+ Context context, InvariantDeviceProfile idp, SQLiteDatabase db) {
+ // Decrease the rows count by 1
+ super(context, db, getValidPackages(context), false /* usePreviewTable */,
+ new Point(idp.numColumns, idp.numRows + 1),
+ new Point(idp.numColumns, idp.numRows));
+
+ mOriginalItems = new IntSparseArrayMap<>();
+ mUpdates = new IntSparseArrayMap<>();
+ }
+
+ @Override
+ protected void update(DbEntry item) {
+ mUpdates.put(item.id, item.copy());
+ }
+
+ @Override
+ protected ArrayList<DbEntry> loadWorkspaceEntries(int screen) {
+ ArrayList<DbEntry> result = super.loadWorkspaceEntries(screen);
+ for (DbEntry entry : result) {
+ mOriginalItems.put(entry.id, entry.copy());
+
+ // Shift all items by 1 in y direction and mark them for update.
+ entry.cellY++;
+ mUpdates.put(entry.id, entry.copy());
+ }
+
+ return result;
+ }
+
+ public void migrateScreen0() {
+ migrateScreen(Workspace.FIRST_SCREEN_ID);
+
+ ContentValues tempValues = new ContentValues();
+ for (DbEntry update : mUpdates) {
+ DbEntry org = mOriginalItems.get(update.id);
+
+ if (org.cellX != update.cellX || org.cellY != update.cellY
+ || org.spanX != update.spanX || org.spanY != update.spanY) {
+ tempValues.clear();
+ update.addToContentValues(tempValues);
+ mDb.update(Favorites.TABLE_NAME, tempValues, "_id = ?",
+ new String[] {Integer.toString(update.id)});
+ }
+ }
+
+ // Delete any carry over items as we are only migration a single screen.
+ for (DbEntry entry : mCarryOver) {
+ mEntryToRemove.add(entry.id);
+ }
+
+ if (!mEntryToRemove.isEmpty()) {
+ mDb.delete(Favorites.TABLE_NAME,
+ Utilities.createDbSelectionQuery(Favorites._ID, mEntryToRemove), null);
+ }
+ }
+}
diff --git a/src/com/android/launcher3/provider/RestoreDbTask.java b/src/com/android/launcher3/provider/RestoreDbTask.java
index 48b3acfbf1..223f4f1937 100644
--- a/src/com/android/launcher3/provider/RestoreDbTask.java
+++ b/src/com/android/launcher3/provider/RestoreDbTask.java
@@ -16,8 +16,6 @@
package com.android.launcher3.provider;
-import static com.android.launcher3.InvariantDeviceProfile.TYPE_MULTI_DISPLAY;
-import static com.android.launcher3.InvariantDeviceProfile.TYPE_PHONE;
import static com.android.launcher3.provider.LauncherDbUtils.dropTable;
import android.app.backup.BackupManager;
@@ -40,7 +38,6 @@ import com.android.launcher3.LauncherProvider.DatabaseHelper;
import com.android.launcher3.LauncherSettings.Favorites;
import com.android.launcher3.Utilities;
import com.android.launcher3.logging.FileLog;
-import com.android.launcher3.model.DeviceGridState;
import com.android.launcher3.model.GridBackupTable;
import com.android.launcher3.model.data.LauncherAppWidgetInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo;
@@ -60,7 +57,7 @@ import java.util.Arrays;
public class RestoreDbTask {
private static final String TAG = "RestoreDbTask";
- private static final String RESTORED_DEVICE_TYPE = "restored_task_pending";
+ private static final String RESTORE_TASK_PENDING = "restore_task_pending";
private static final String INFO_COLUMN_NAME = "name";
private static final String INFO_COLUMN_DEFAULT_VALUE = "dflt_value";
@@ -68,34 +65,13 @@ public class RestoreDbTask {
private static final String APPWIDGET_OLD_IDS = "appwidget_old_ids";
private static final String APPWIDGET_IDS = "appwidget_ids";
- /**
- * Tries to restore the backup DB if needed
- */
- public static void restoreIfNeeded(Context context, DatabaseHelper helper) {
- if (!isPending(context)) {
- return;
- }
- if (!performRestore(context, helper)) {
- helper.createEmptyDB(helper.getWritableDatabase());
- }
-
- // Obtain InvariantDeviceProfile first before setting pending to false, so
- // InvariantDeviceProfile won't switch to new grid when initializing.
- InvariantDeviceProfile idp = InvariantDeviceProfile.INSTANCE.get(context);
-
- // Set is pending to false irrespective of the result, so that it doesn't get
- // executed again.
- Utilities.getPrefs(context).edit().remove(RESTORED_DEVICE_TYPE).commit();
-
- idp.reinitializeAfterRestore(context);
- }
-
- private static boolean performRestore(Context context, DatabaseHelper helper) {
+ public static boolean performRestore(Context context, DatabaseHelper helper,
+ BackupManager backupManager) {
SQLiteDatabase db = helper.getWritableDatabase();
try (SQLiteTransaction t = new SQLiteTransaction(db)) {
RestoreDbTask task = new RestoreDbTask();
task.backupWorkspace(context, db);
- task.sanitizeDB(context, helper, db, new BackupManager(context));
+ task.sanitizeDB(helper, db, backupManager);
task.restoreAppWidgetIdsIfExists(context);
t.commit();
return true;
@@ -138,7 +114,7 @@ public class RestoreDbTask {
GridBackupTable backupTable = new GridBackupTable(context, db, idp.numDatabaseHotseatIcons,
idp.numColumns, idp.numRows);
if (backupTable.restoreFromRawBackupIfAvailable(getDefaultProfileId(db))) {
- int itemsDeleted = sanitizeDB(context, helper, db, backupManager);
+ int itemsDeleted = sanitizeDB(helper, db, backupManager);
LauncherAppState.getInstance(context).getModel().forceReload();
restoreAppWidgetIdsIfExists(context);
if (itemsDeleted == 0) {
@@ -155,12 +131,11 @@ public class RestoreDbTask {
* the restored apps get installed.
* 3. If the user serial for any restored profile is different than that of the previous
* device, update the entries to the new profile id.
- * 4. If restored from a single display backup, remove gaps between screenIds
*
* @return number of items deleted.
*/
- private int sanitizeDB(Context context, DatabaseHelper helper, SQLiteDatabase db,
- BackupManager backupManager) throws Exception {
+ private int sanitizeDB(DatabaseHelper helper, SQLiteDatabase db, BackupManager backupManager)
+ throws Exception {
// Primary user ids
long myProfileId = helper.getDefaultUserSerial();
long oldProfileId = getDefaultProfileId(db);
@@ -236,43 +211,10 @@ public class RestoreDbTask {
if (myProfileId != oldProfileId) {
changeDefaultColumn(db, myProfileId);
}
-
- // If restored from a single display backup, remove gaps between screenIds
- if (Utilities.getPrefs(context).getInt(RESTORED_DEVICE_TYPE, TYPE_PHONE)
- != TYPE_MULTI_DISPLAY) {
- removeScreenIdGaps(db);
- }
-
return itemsDeleted;
}
/**
- * Remove gaps between screenIds to make sure no empty pages are left in between.
- *
- * e.g. [0, 3, 4, 6, 7] -> [0, 1, 2, 3, 4]
- */
- protected void removeScreenIdGaps(SQLiteDatabase db) {
- FileLog.d(TAG, "Removing gaps between screenIds");
- IntArray distinctScreens = LauncherDbUtils.queryIntArray(true, db, Favorites.TABLE_NAME,
- Favorites.SCREEN, Favorites.CONTAINER + " = " + Favorites.CONTAINER_DESKTOP, null,
- Favorites.SCREEN);
- if (distinctScreens.isEmpty()) {
- return;
- }
-
- StringBuilder sql = new StringBuilder("UPDATE ").append(Favorites.TABLE_NAME)
- .append(" SET ").append(Favorites.SCREEN).append(" =\nCASE\n");
- int screenId = distinctScreens.contains(0) ? 0 : 1;
- for (int i = 0; i < distinctScreens.size(); i++) {
- sql.append("WHEN ").append(Favorites.SCREEN).append(" == ")
- .append(distinctScreens.get(i)).append(" THEN ").append(screenId++).append("\n");
- }
- sql.append("ELSE screen\nEND WHERE ").append(Favorites.CONTAINER).append(" = ")
- .append(Favorites.CONTAINER_DESKTOP).append(";");
- db.execSQL(sql.toString());
- }
-
- /**
* Updates profile id of all entries from {@param oldProfileId} to {@param newProfileId}.
*/
protected void migrateProfileId(SQLiteDatabase db, long oldProfileId, long newProfileId) {
@@ -337,17 +279,12 @@ public class RestoreDbTask {
}
public static boolean isPending(Context context) {
- return Utilities.getPrefs(context).contains(RESTORED_DEVICE_TYPE);
+ return Utilities.getPrefs(context).getBoolean(RESTORE_TASK_PENDING, false);
}
- /**
- * Marks the DB state as pending restoration
- */
- public static void setPending(Context context) {
- FileLog.d(TAG, "Restore data received through full backup ");
- Utilities.getPrefs(context).edit()
- .putInt(RESTORED_DEVICE_TYPE, new DeviceGridState(context).getDeviceType())
- .commit();
+ public static void setPending(Context context, boolean isPending) {
+ FileLog.d(TAG, "Restore data received through full backup " + isPending);
+ Utilities.getPrefs(context).edit().putBoolean(RESTORE_TASK_PENDING, isPending).commit();
}
private void restoreAppWidgetIdsIfExists(Context context) {
diff --git a/src/com/android/launcher3/recyclerview/ViewHolderBinder.java b/src/com/android/launcher3/recyclerview/ViewHolderBinder.java
index 31436c4d6c..5b8d5bcafe 100644
--- a/src/com/android/launcher3/recyclerview/ViewHolderBinder.java
+++ b/src/com/android/launcher3/recyclerview/ViewHolderBinder.java
@@ -17,13 +17,8 @@ package com.android.launcher3.recyclerview;
import android.view.ViewGroup;
-import androidx.annotation.IntDef;
import androidx.recyclerview.widget.RecyclerView.ViewHolder;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.List;
-
/**
* Creates and populates views with data
*
@@ -31,15 +26,6 @@ import java.util.List;
* @param <V> A subclass of {@link ViewHolder} which holds references to views.
*/
public interface ViewHolderBinder<T, V extends ViewHolder> {
-
- int POSITION_DEFAULT = 0;
- int POSITION_FIRST = 1 << 0;
- int POSITION_LAST = 1 << 1;
-
- @Retention(RetentionPolicy.SOURCE)
- @IntDef(value = {POSITION_DEFAULT, POSITION_FIRST, POSITION_LAST}, flag = true)
- @interface ListPosition {}
-
/**
* Creates a new view, and attach it to the parent {@link ViewGroup}. Then, populates UI
* references in a {@link ViewHolder}.
@@ -47,7 +33,7 @@ public interface ViewHolderBinder<T, V extends ViewHolder> {
V newViewHolder(ViewGroup parent);
/** Populate UI references in {@link ViewHolder} with data. */
- void bindViewHolder(V viewHolder, T data, @ListPosition int position, List<Object> payloads);
+ void bindViewHolder(V viewHolder, T data, int position);
/**
* Called when the view is recycled. Views are recycled in batches once they are sufficiently
diff --git a/src/com/android/launcher3/search/SearchAlgorithm.java b/src/com/android/launcher3/search/SearchAlgorithm.java
index 96a15f4912..a1720c733b 100644
--- a/src/com/android/launcher3/search/SearchAlgorithm.java
+++ b/src/com/android/launcher3/search/SearchAlgorithm.java
@@ -28,13 +28,6 @@ public interface SearchAlgorithm<T> {
void doSearch(String query, SearchCallback<T> callback);
/**
- * Performs search with {@code query} and the {@code suggestedQueries}/
- */
- default void doSearch(String query, String[] suggestedQueries, SearchCallback<T> callback) {
- doSearch(query, callback);
- }
-
- /**
* Cancels any active request.
*/
void cancel(boolean interruptActiveRequests);
diff --git a/src/com/android/launcher3/search/SearchCallback.java b/src/com/android/launcher3/search/SearchCallback.java
index 495a303a7e..5796116963 100644
--- a/src/com/android/launcher3/search/SearchCallback.java
+++ b/src/com/android/launcher3/search/SearchCallback.java
@@ -32,6 +32,13 @@ public interface SearchCallback<T> {
void onSearchResult(String query, ArrayList<T> items);
/**
+ * Called when the search from secondary source is complete.
+ *
+ * @param items list of search results
+ */
+ void onAppendSearchResult(String query, ArrayList<T> items);
+
+ /**
* Called when the search results should be cleared.
*/
void clearSearchResult();
diff --git a/src/com/android/launcher3/secondarydisplay/PinnedAppsAdapter.java b/src/com/android/launcher3/secondarydisplay/PinnedAppsAdapter.java
index a0ed77e38f..e9058c343d 100644
--- a/src/com/android/launcher3/secondarydisplay/PinnedAppsAdapter.java
+++ b/src/com/android/launcher3/secondarydisplay/PinnedAppsAdapter.java
@@ -205,8 +205,8 @@ public class PinnedAppsAdapter extends BaseAdapter implements OnSharedPreference
/**
* Returns a system shortcut to pin/unpin a shortcut
*/
- public SystemShortcut getSystemShortcut(ItemInfo info, View originalView) {
- return new PinUnPinShortcut(mLauncher, info, originalView,
+ public SystemShortcut getSystemShortcut(ItemInfo info) {
+ return new PinUnPinShortcut(mLauncher, info,
mPinnedApps.contains(new ComponentKey(info.getTargetComponent(), info.user)));
}
@@ -214,11 +214,10 @@ public class PinnedAppsAdapter extends BaseAdapter implements OnSharedPreference
private final boolean mIsPinned;
- PinUnPinShortcut(SecondaryDisplayLauncher target, ItemInfo info, View originalView,
- boolean isPinned) {
+ PinUnPinShortcut(SecondaryDisplayLauncher target, ItemInfo info, boolean isPinned) {
super(isPinned ? R.drawable.ic_remove_no_shadow : R.drawable.ic_pin,
isPinned ? R.string.remove_drop_target_label : R.string.action_add_to_workspace,
- target, info, originalView);
+ target, info);
mIsPinned = isPinned;
}
diff --git a/src/com/android/launcher3/secondarydisplay/SecondaryDisplayLauncher.java b/src/com/android/launcher3/secondarydisplay/SecondaryDisplayLauncher.java
index a2ab7f9d53..5999091786 100644
--- a/src/com/android/launcher3/secondarydisplay/SecondaryDisplayLauncher.java
+++ b/src/com/android/launcher3/secondarydisplay/SecondaryDisplayLauncher.java
@@ -30,19 +30,27 @@ import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.LauncherModel;
import com.android.launcher3.R;
-import com.android.launcher3.allapps.ActivityAllAppsContainerView;
+import com.android.launcher3.allapps.AllAppsContainerView;
import com.android.launcher3.model.BgDataModel;
-import com.android.launcher3.model.StringCache;
import com.android.launcher3.model.data.AppInfo;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.ItemInfoWithIcon;
+import com.android.launcher3.model.data.LauncherAppWidgetInfo;
+import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.launcher3.popup.PopupContainerWithArrow;
import com.android.launcher3.popup.PopupDataProvider;
import com.android.launcher3.util.ComponentKey;
+import com.android.launcher3.util.IntArray;
+import com.android.launcher3.util.ItemInfoMatcher;
import com.android.launcher3.util.Themes;
+import com.android.launcher3.util.ViewOnDrawExecutor;
import com.android.launcher3.views.BaseDragLayer;
+import com.android.launcher3.widget.model.WidgetsListBaseEntry;
+import java.util.ArrayList;
import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
/**
* Launcher activity for secondary displays
@@ -53,15 +61,13 @@ public class SecondaryDisplayLauncher extends BaseDraggingActivity
private LauncherModel mModel;
private BaseDragLayer mDragLayer;
- private ActivityAllAppsContainerView<SecondaryDisplayLauncher> mAppsView;
+ private AllAppsContainerView mAppsView;
private View mAppsButton;
private PopupDataProvider mPopupDataProvider;
private boolean mAppDrawerShown = false;
- private StringCache mStringCache;
-
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -146,8 +152,7 @@ public class SecondaryDisplayLauncher extends BaseDraggingActivity
return mAppDrawerShown;
}
- @Override
- public ActivityAllAppsContainerView<SecondaryDisplayLauncher> getAppsView() {
+ public AllAppsContainerView getAppsView() {
return mAppsView;
}
@@ -170,10 +175,67 @@ public class SecondaryDisplayLauncher extends BaseDraggingActivity
}
@Override
+ public int getPageToBindSynchronously() {
+ return 0;
+ }
+
+ @Override
+ public void clearPendingBinds() { }
+
+ @Override
+ public void startBinding() { }
+
+ @Override
+ public void bindItems(List<ItemInfo> shortcuts, boolean forceAnimateIcons) { }
+
+ @Override
+ public void bindScreens(IntArray orderedScreenIds) { }
+
+ @Override
+ public void finishFirstPageBind(ViewOnDrawExecutor executor) {
+ if (executor != null) {
+ executor.onLoadAnimationCompleted();
+ }
+ }
+
+ @Override
+ public void finishBindingItems(int pageBoundFirst) { }
+
+ @Override
+ public void preAddApps() { }
+
+ @Override
+ public void bindAppsAdded(IntArray newScreens, ArrayList<ItemInfo> addNotAnimated,
+ ArrayList<ItemInfo> addAnimated) { }
+
+ @Override
public void bindIncrementalDownloadProgressUpdated(AppInfo app) {
mAppsView.getAppsStore().updateProgressBar(app);
}
+ @Override
+ public void bindWorkspaceItemsChanged(List<WorkspaceItemInfo> updated) { }
+
+ @Override
+ public void bindWidgetsRestored(ArrayList<LauncherAppWidgetInfo> widgets) { }
+
+ @Override
+ public void bindRestoreItemsChange(HashSet<ItemInfo> updates) { }
+
+ @Override
+ public void bindWorkspaceComponentsRemoved(ItemInfoMatcher matcher) { }
+
+ @Override
+ public void bindAllWidgets(List<WidgetsListBaseEntry> widgets) { }
+
+ @Override
+ public void onPageBoundSynchronously(int page) { }
+
+ @Override
+ public void executeOnNextDraw(ViewOnDrawExecutor executor) {
+ executor.attachTo(getDragLayer(), false, null);
+ }
+
/**
* Called when apps-button is clicked
*/
@@ -229,16 +291,6 @@ public class SecondaryDisplayLauncher extends BaseDraggingActivity
PopupContainerWithArrow.dismissInvalidPopup(this);
}
- @Override
- public StringCache getStringCache() {
- return mStringCache;
- }
-
- @Override
- public void bindStringCache(StringCache cache) {
- mStringCache = cache;
- }
-
public PopupDataProvider getPopupDataProvider() {
return mPopupDataProvider;
}
diff --git a/src/com/android/launcher3/secondarydisplay/SecondaryDragLayer.java b/src/com/android/launcher3/secondarydisplay/SecondaryDragLayer.java
index c79d70dacc..f78f6dd40c 100644
--- a/src/com/android/launcher3/secondarydisplay/SecondaryDragLayer.java
+++ b/src/com/android/launcher3/secondarydisplay/SecondaryDragLayer.java
@@ -30,10 +30,9 @@ import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.BubbleTextView;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.R;
-import com.android.launcher3.allapps.ActivityAllAppsContainerView;
+import com.android.launcher3.allapps.AllAppsContainerView;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.popup.PopupContainerWithArrow;
-import com.android.launcher3.popup.PopupDataProvider;
import com.android.launcher3.util.ShortcutUtil;
import com.android.launcher3.util.TouchController;
import com.android.launcher3.views.BaseDragLayer;
@@ -47,7 +46,7 @@ import java.util.Collections;
public class SecondaryDragLayer extends BaseDragLayer<SecondaryDisplayLauncher> {
private View mAllAppsButton;
- private ActivityAllAppsContainerView<SecondaryDisplayLauncher> mAppsView;
+ private AllAppsContainerView mAppsView;
private GridView mWorkspace;
private PinnedAppsAdapter mPinnedAppsAdapter;
@@ -113,27 +112,26 @@ public class SecondaryDragLayer extends BaseDragLayer<SecondaryDisplayLauncher>
for (int i = 0; i < count; i++) {
final View child = getChildAt(i);
if (child == mAppsView) {
- int horizontalPadding = (2 * grid.desiredWorkspaceHorizontalMarginPx)
- + grid.cellLayoutPaddingPx.left + grid.cellLayoutPaddingPx.right;
- int verticalPadding =
- grid.cellLayoutPaddingPx.top + grid.cellLayoutPaddingPx.bottom;
+ int padding = 2 * (grid.desiredWorkspaceLeftRightMarginPx
+ + grid.cellLayoutPaddingLeftRightPx);
- int maxWidth =
- grid.allAppsCellWidthPx * grid.numShownAllAppsColumns + horizontalPadding;
- int appsWidth = Math.min(width - getPaddingLeft() - getPaddingRight(), maxWidth);
+ int maxWidth = grid.allAppsCellWidthPx * grid.numShownAllAppsColumns + padding;
+ int appsWidth = Math.min(width, maxWidth);
- int maxHeight =
- grid.allAppsCellHeightPx * grid.numShownAllAppsColumns + verticalPadding;
- int appsHeight = Math.min(height - getPaddingTop() - getPaddingBottom(), maxHeight);
+ int maxHeight = grid.allAppsCellHeightPx * grid.numShownAllAppsColumns + padding;
+ int appsHeight = Math.min(height, maxHeight);
mAppsView.measure(
makeMeasureSpec(appsWidth, EXACTLY), makeMeasureSpec(appsHeight, EXACTLY));
+
} else if (child == mAllAppsButton) {
int appsButtonSpec = makeMeasureSpec(grid.iconSizePx, EXACTLY);
mAllAppsButton.measure(appsButtonSpec, appsButtonSpec);
+
} else if (child == mWorkspace) {
measureChildWithMargins(mWorkspace, widthMeasureSpec, 0, heightMeasureSpec,
grid.iconSizePx + grid.edgeMarginPx);
+
} else {
measureChildWithMargins(child, widthMeasureSpec, 0, heightMeasureSpec, 0);
}
@@ -179,19 +177,15 @@ public class SecondaryDragLayer extends BaseDragLayer<SecondaryDisplayLauncher>
if (!ShortcutUtil.supportsShortcuts(item)) {
return false;
}
- PopupDataProvider popupDataProvider = mActivity.getPopupDataProvider();
- if (popupDataProvider == null) {
- return false;
- }
final PopupContainerWithArrow container =
(PopupContainerWithArrow) mActivity.getLayoutInflater().inflate(
R.layout.popup_container, mActivity.getDragLayer(), false);
container.populateAndShow((BubbleTextView) v,
- popupDataProvider.getShortcutCountForItem(item),
+ mActivity.getPopupDataProvider().getShortcutCountForItem(item),
Collections.emptyList(),
- Arrays.asList(mPinnedAppsAdapter.getSystemShortcut(item, v),
- APP_INFO.getShortcut(mActivity, item, v)));
+ Arrays.asList(mPinnedAppsAdapter.getSystemShortcut(item),
+ APP_INFO.getShortcut(mActivity, item)));
v.getParent().requestDisallowInterceptTouchEvent(true);
return true;
}
diff --git a/src/com/android/launcher3/settings/DeveloperOptionsFragment.java b/src/com/android/launcher3/settings/DeveloperOptionsFragment.java
index b06b8a10bf..4d63218785 100644
--- a/src/com/android/launcher3/settings/DeveloperOptionsFragment.java
+++ b/src/com/android/launcher3/settings/DeveloperOptionsFragment.java
@@ -20,7 +20,6 @@ import static android.content.pm.PackageManager.MATCH_DISABLED_COMPONENTS;
import static android.view.View.GONE;
import static android.view.View.VISIBLE;
-import static com.android.launcher3.settings.SettingsActivity.EXTRA_FRAGMENT_ARG_KEY;
import static com.android.launcher3.uioverrides.plugins.PluginManagerWrapper.PLUGIN_CHANGED;
import static com.android.launcher3.uioverrides.plugins.PluginManagerWrapper.pluginEnabledKey;
@@ -30,7 +29,6 @@ import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
-import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.net.Uri;
@@ -46,7 +44,6 @@ import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.EditText;
-import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@@ -60,15 +57,12 @@ import androidx.preference.PreferenceViewHolder;
import androidx.preference.SwitchPreference;
import com.android.launcher3.R;
-import com.android.launcher3.Utilities;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.config.FlagTogglerPrefUi;
import com.android.launcher3.uioverrides.plugins.PluginManagerWrapper;
-import com.android.launcher3.util.OnboardingPrefs;
import java.util.ArrayList;
import java.util.List;
-import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
@@ -110,7 +104,6 @@ public class DeveloperOptionsFragment extends PreferenceFragmentCompat {
initFlags();
loadPluginPrefs();
maybeAddSandboxCategory();
- addOnboardingPrefsCatergory();
if (getActivity() != null) {
getActivity().setTitle("Developer Options");
@@ -160,15 +153,6 @@ public class DeveloperOptionsFragment extends PreferenceFragmentCompat {
}
});
- if (getArguments() != null) {
- String filter = getArguments().getString(EXTRA_FRAGMENT_ARG_KEY);
- // Normally EXTRA_FRAGMENT_ARG_KEY is used to highlight the preference with the given
- // key. This is a slight variation where we instead filter by the human-readable titles.
- if (filter != null) {
- filterBox.setText(filter);
- }
- }
-
View listView = getListView();
final int bottomPadding = listView.getPaddingBottom();
listView.setOnApplyWindowInsetsListener((v, insets) -> {
@@ -371,28 +355,6 @@ public class DeveloperOptionsFragment extends PreferenceFragmentCompat {
sandboxCategory.addPreference(launchSandboxModeTutorialPreference);
}
- private void addOnboardingPrefsCatergory() {
- PreferenceCategory onboardingCategory = newCategory("Onboarding Flows");
- onboardingCategory.setSummary("Reset these if you want to see the education again.");
- for (Map.Entry<String, String[]> titleAndKeys : OnboardingPrefs.ALL_PREF_KEYS.entrySet()) {
- String title = titleAndKeys.getKey();
- String[] keys = titleAndKeys.getValue();
- Preference onboardingPref = new Preference(getContext());
- onboardingPref.setTitle(title);
- onboardingPref.setSummary("Tap to reset");
- onboardingPref.setOnPreferenceClickListener(preference -> {
- SharedPreferences.Editor sharedPrefsEdit = Utilities.getPrefs(getContext()).edit();
- for (String key : keys) {
- sharedPrefsEdit.remove(key);
- }
- sharedPrefsEdit.apply();
- Toast.makeText(getContext(), "Reset " + title, Toast.LENGTH_SHORT).show();
- return true;
- });
- onboardingCategory.addPreference(onboardingPref);
- }
- }
-
private String toName(String action) {
String str = action.replace("com.android.systemui.action.PLUGIN_", "")
.replace("com.android.launcher3.action.PLUGIN_", "");
diff --git a/src/com/android/launcher3/settings/NotificationDotsPreference.java b/src/com/android/launcher3/settings/NotificationDotsPreference.java
index 1816e7be38..0ee27443ef 100644
--- a/src/com/android/launcher3/settings/NotificationDotsPreference.java
+++ b/src/com/android/launcher3/settings/NotificationDotsPreference.java
@@ -89,7 +89,6 @@ public class NotificationDotsPreference extends Preference
// Update intent
Bundle extras = new Bundle();
extras.putString(EXTRA_FRAGMENT_ARG_KEY, "notification_badging");
-
setIntent(new Intent("android.settings.NOTIFICATION_SETTINGS")
.putExtra(EXTRA_SHOW_FRAGMENT_ARGS, extras));
}
diff --git a/src/com/android/launcher3/settings/SettingsActivity.java b/src/com/android/launcher3/settings/SettingsActivity.java
index 49d27b7ed4..915e140aaf 100644
--- a/src/com/android/launcher3/settings/SettingsActivity.java
+++ b/src/com/android/launcher3/settings/SettingsActivity.java
@@ -49,7 +49,6 @@ import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.model.WidgetsModel;
-import com.android.launcher3.states.RotationHelper;
import com.android.launcher3.uioverrides.plugins.PluginManagerWrapper;
import java.util.Collections;
@@ -63,9 +62,8 @@ public class SettingsActivity extends FragmentActivity
SharedPreferences.OnSharedPreferenceChangeListener{
/** List of fragments that can be hosted by this activity. */
- private static final List<String> VALID_PREFERENCE_FRAGMENTS =
- !Utilities.IS_DEBUG_DEVICE ? Collections.emptyList()
- : Collections.singletonList(DeveloperOptionsFragment.class.getName());
+ private static final List<String> VALID_PREFERENCE_FRAGMENTS = Collections.singletonList(
+ DeveloperOptionsFragment.class.getName());
private static final String DEVELOPER_OPTIONS_KEY = "pref_developer_options";
private static final String FLAGS_PREFERENCE_KEY = "flag_toggler";
@@ -213,14 +211,6 @@ public class SettingsActivity extends FragmentActivity
}
if (getActivity() != null && !TextUtils.isEmpty(getPreferenceScreen().getTitle())) {
- if (getPreferenceScreen().getTitle().equals(
- getResources().getString(R.string.search_pref_screen_title))){
- DeviceProfile mDeviceProfile = InvariantDeviceProfile.INSTANCE.get(
- getContext()).getDeviceProfile(getContext());
- getPreferenceScreen().setTitle(mDeviceProfile.isTablet ?
- R.string.search_pref_screen_title_tablet
- : R.string.search_pref_screen_title);
- }
getActivity().setTitle(getPreferenceScreen().getTitle());
}
}
@@ -262,13 +252,12 @@ public class SettingsActivity extends FragmentActivity
case ALLOW_ROTATION_PREFERENCE_KEY:
DeviceProfile deviceProfile = InvariantDeviceProfile.INSTANCE.get(
getContext()).getDeviceProfile(getContext());
- if (deviceProfile.isTablet) {
+ if (deviceProfile.allowRotation) {
// Launcher supports rotation by default. No need to show this setting.
return false;
}
// Initialize the UI once
- preference.setDefaultValue(
- RotationHelper.getAllowRotationDefaultValue(deviceProfile));
+ preference.setDefaultValue(false);
return true;
case FLAGS_PREFERENCE_KEY:
diff --git a/src/com/android/launcher3/shortcuts/DeepShortcutView.java b/src/com/android/launcher3/shortcuts/DeepShortcutView.java
index 2f17ce0260..71d288c0ab 100644
--- a/src/com/android/launcher3/shortcuts/DeepShortcutView.java
+++ b/src/com/android/launcher3/shortcuts/DeepShortcutView.java
@@ -72,7 +72,6 @@ public class DeepShortcutView extends FrameLayout implements BubbleTextHolder {
protected void onFinishInflate() {
super.onFinishInflate();
mBubbleText = findViewById(R.id.bubble_text);
- mBubbleText.setHideBadge(true);
mIconView = findViewById(R.id.icon);
tryUpdateTextBackground();
}
diff --git a/src/com/android/launcher3/shortcuts/ShortcutDragPreviewProvider.java b/src/com/android/launcher3/shortcuts/ShortcutDragPreviewProvider.java
index c166bfc83a..cecbb0db13 100644
--- a/src/com/android/launcher3/shortcuts/ShortcutDragPreviewProvider.java
+++ b/src/com/android/launcher3/shortcuts/ShortcutDragPreviewProvider.java
@@ -23,12 +23,12 @@ import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.view.View;
+import com.android.launcher3.Launcher;
import com.android.launcher3.Utilities;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.graphics.DragPreviewProvider;
import com.android.launcher3.icons.BitmapRenderer;
import com.android.launcher3.icons.FastBitmapDrawable;
-import com.android.launcher3.views.ActivityContext;
/**
* Extension of {@link DragPreviewProvider} which generates bitmaps scaled to the default icon size.
@@ -45,8 +45,7 @@ public class ShortcutDragPreviewProvider extends DragPreviewProvider {
@Override
public Drawable createDrawable() {
if (FeatureFlags.ENABLE_DEEP_SHORTCUT_ICON_CACHE.get()) {
- int size = ActivityContext.lookupContext(mView.getContext())
- .getDeviceProfile().iconSizePx;
+ int size = Launcher.getLauncher(mView.getContext()).getDeviceProfile().iconSizePx;
return new FastBitmapDrawable(
BitmapRenderer.createHardwareBitmap(
size + blurSizeOutline,
@@ -60,7 +59,7 @@ public class ShortcutDragPreviewProvider extends DragPreviewProvider {
private Bitmap createDragBitmapLegacy() {
Drawable d = mView.getBackground();
Rect bounds = getDrawableBounds(d);
- int size = ActivityContext.lookupContext(mView.getContext()).getDeviceProfile().iconSizePx;
+ int size = Launcher.getLauncher(mView.getContext()).getDeviceProfile().iconSizePx;
final Bitmap b = Bitmap.createBitmap(
size + blurSizeOutline,
size + blurSizeOutline,
@@ -85,9 +84,9 @@ public class ShortcutDragPreviewProvider extends DragPreviewProvider {
@Override
public float getScaleAndPosition(Drawable preview, int[] outPos) {
- ActivityContext context = ActivityContext.lookupContext(mView.getContext());
+ Launcher launcher = Launcher.getLauncher(mView.getContext());
int iconSize = getDrawableBounds(mView.getBackground()).width();
- float scale = context.getDragLayer().getLocationInDragLayer(mView, outPos);
+ float scale = launcher.getDragLayer().getLocationInDragLayer(mView, outPos);
int iconLeft = mView.getPaddingStart();
if (Utilities.isRtl(mView.getResources())) {
@@ -99,7 +98,7 @@ public class ShortcutDragPreviewProvider extends DragPreviewProvider {
+ mPositionShift.x);
outPos[1] += Math.round((scale * mView.getHeight() - preview.getIntrinsicHeight()) / 2
+ mPositionShift.y);
- float size = context.getDeviceProfile().iconSizePx;
+ float size = launcher.getDeviceProfile().iconSizePx;
return scale * iconSize / size;
}
}
diff --git a/src/com/android/launcher3/shortcuts/ShortcutKey.java b/src/com/android/launcher3/shortcuts/ShortcutKey.java
index 9af68c0388..0c6d675afd 100644
--- a/src/com/android/launcher3/shortcuts/ShortcutKey.java
+++ b/src/com/android/launcher3/shortcuts/ShortcutKey.java
@@ -57,17 +57,11 @@ public class ShortcutKey extends ComponentKey {
}
public static Intent makeIntent(ShortcutInfo si) {
- return makeIntent(si.getId(), si.getPackage()).setComponent(si.getActivity());
- }
-
- /**
- * Creates an intent for shortcut id and package name.
- */
- public static Intent makeIntent(String shortcutId, String packageName) {
return new Intent(Intent.ACTION_MAIN)
.addCategory(INTENT_CATEGORY)
- .setPackage(packageName)
+ .setComponent(si.getActivity())
+ .setPackage(si.getPackage())
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED)
- .putExtra(EXTRA_SHORTCUT_ID, shortcutId);
+ .putExtra(EXTRA_SHORTCUT_ID, si.getId());
}
}
diff --git a/src/com/android/launcher3/statemanager/BaseState.java b/src/com/android/launcher3/statemanager/BaseState.java
index f9a36ad17c..122573cfa1 100644
--- a/src/com/android/launcher3/statemanager/BaseState.java
+++ b/src/com/android/launcher3/statemanager/BaseState.java
@@ -18,7 +18,6 @@ package com.android.launcher3.statemanager;
import android.content.Context;
import com.android.launcher3.DeviceProfile;
-import com.android.launcher3.DeviceProfile.DeviceProfileListenable;
/**
* Interface representing a state of a StatefulActivity
@@ -37,8 +36,7 @@ public interface BaseState<T extends BaseState> {
/**
* @return How long the animation to this state should take (or from this state to NORMAL).
*/
- <DEVICE_PROFILE_CONTEXT extends Context & DeviceProfileListenable>
- int getTransitionDuration(DEVICE_PROFILE_CONTEXT context, boolean isToState);
+ int getTransitionDuration(Context context);
/**
* Returns the state to go back to from this state
diff --git a/src/com/android/launcher3/statemanager/StateManager.java b/src/com/android/launcher3/statemanager/StateManager.java
index 2aa9ddeb50..b34af975bd 100644
--- a/src/com/android/launcher3/statemanager/StateManager.java
+++ b/src/com/android/launcher3/statemanager/StateManager.java
@@ -84,7 +84,7 @@ public class StateManager<STATE_TYPE extends BaseState<STATE_TYPE>> {
+ ", mCurrentStableState:" + mCurrentStableState
+ ", mState:" + mState
+ ", mRestState:" + mRestState
- + ", isInTransition:" + isInTransition() + ")";
+ + ", isInTransition:" + (mConfig.currentAnimation != null) + ")";
}
public void dump(String prefix, PrintWriter writer) {
@@ -93,7 +93,7 @@ public class StateManager<STATE_TYPE extends BaseState<STATE_TYPE>> {
writer.println(prefix + "\tmCurrentStableState:" + mCurrentStableState);
writer.println(prefix + "\tmState:" + mState);
writer.println(prefix + "\tmRestState:" + mRestState);
- writer.println(prefix + "\tisInTransition:" + isInTransition());
+ writer.println(prefix + "\tisInTransition:" + (mConfig.currentAnimation != null));
}
public StateHandler[] getStateHandlers() {
@@ -130,13 +130,6 @@ public class StateManager<STATE_TYPE extends BaseState<STATE_TYPE>> {
}
/**
- * @return {@code true} If there is an active transition.
- */
- public boolean isInTransition() {
- return mConfig.currentAnimation != null;
- }
-
- /**
* @see #goToState(STATE_TYPE, boolean, AnimatorListener)
*/
public void goToState(STATE_TYPE state) {
@@ -253,8 +246,8 @@ public class StateManager<STATE_TYPE extends BaseState<STATE_TYPE>> {
// Since state mBaseState can be reached from multiple states, just assume that the
// transition plays in reverse and use the same duration as previous state.
mConfig.duration = state == mBaseState
- ? fromState.getTransitionDuration(mActivity, false /* isToState */)
- : state.getTransitionDuration(mActivity, true /* isToState */);
+ ? fromState.getTransitionDuration(mActivity)
+ : state.getTransitionDuration(mActivity);
prepareForAtomicAnimation(fromState, state, mConfig);
AnimatorSet animation = createAnimationToNewWorkspaceInternal(state).buildAnim();
if (listener != null) {
diff --git a/src/com/android/launcher3/statemanager/StatefulActivity.java b/src/com/android/launcher3/statemanager/StatefulActivity.java
index c554d069f3..8a35cb33c0 100644
--- a/src/com/android/launcher3/statemanager/StatefulActivity.java
+++ b/src/com/android/launcher3/statemanager/StatefulActivity.java
@@ -148,7 +148,7 @@ public abstract class StatefulActivity<STATE_TYPE extends BaseState<STATE_TYPE>>
/**
* Called if the Activity UI changed while the activity was not visible
*/
- public void onUiChangedWhileSleeping() { }
+ protected void onUiChangedWhileSleeping() { }
private void handleDeferredResume() {
if (hasBeenResumed() && !getStateManager().getState().hasFlag(FLAG_NON_INTERACTIVE)) {
@@ -173,11 +173,4 @@ public abstract class StatefulActivity<STATE_TYPE extends BaseState<STATE_TYPE>>
mHandler.removeCallbacks(mHandleDeferredResume);
Utilities.postAsyncCallback(mHandler, mHandleDeferredResume);
}
-
- /**
- * Runs the given {@param r} runnable when this activity binds to the touch interaction service.
- */
- public void runOnBindToTouchInteractionService(Runnable r) {
- r.run();
- }
}
diff --git a/src/com/android/launcher3/states/HintState.java b/src/com/android/launcher3/states/HintState.java
index 4cfced8561..8b520165ce 100644
--- a/src/com/android/launcher3/states/HintState.java
+++ b/src/com/android/launcher3/states/HintState.java
@@ -43,7 +43,7 @@ public class HintState extends LauncherState {
}
@Override
- public int getTransitionDuration(Context context, boolean isToState) {
+ public int getTransitionDuration(Context context) {
return 80;
}
diff --git a/src/com/android/launcher3/states/RotationHelper.java b/src/com/android/launcher3/states/RotationHelper.java
index 38b62d466e..87871b11db 100644
--- a/src/com/android/launcher3/states/RotationHelper.java
+++ b/src/com/android/launcher3/states/RotationHelper.java
@@ -18,10 +18,6 @@ package com.android.launcher3.states;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LOCKED;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_NOSENSOR;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
-import static android.util.DisplayMetrics.DENSITY_DEVICE_STABLE;
-
-import static com.android.launcher3.Utilities.dpiFromPx;
-import static com.android.launcher3.util.window.WindowManagerProxy.MIN_TABLET_WIDTH;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
@@ -29,6 +25,7 @@ import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import com.android.launcher3.BaseActivity;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Utilities;
+import com.android.launcher3.util.ActivityTracker;
import com.android.launcher3.util.UiThreadHelper;
/**
@@ -41,17 +38,6 @@ public class RotationHelper implements OnSharedPreferenceChangeListener,
public static final String ALLOW_ROTATION_PREFERENCE_KEY = "pref_allowRotation";
- /**
- * Returns the default value of {@link #ALLOW_ROTATION_PREFERENCE_KEY} preference.
- */
- public static boolean getAllowRotationDefaultValue(DeviceProfile deviceProfile) {
- // If the device's pixel density was scaled (usually via settings for A11y), use the
- // original dimensions to determine if rotation is allowed of not.
- float originalSmallestWidth = dpiFromPx(
- Math.min(deviceProfile.widthPx, deviceProfile.heightPx), DENSITY_DEVICE_STABLE);
- return originalSmallestWidth >= MIN_TABLET_WIDTH;
- }
-
public static final int REQUEST_NONE = 0;
public static final int REQUEST_ROTATE = 1;
public static final int REQUEST_LOCK = 2;
@@ -65,7 +51,7 @@ public class RotationHelper implements OnSharedPreferenceChangeListener,
/**
* Rotation request made by
- * {@link com.android.launcher3.util.ActivityTracker.SchedulerCallback}.
+ * {@link ActivityTracker.SchedulerCallback}.
* This supersedes any other request.
*/
private int mStateHandlerRequest = REQUEST_NONE;
@@ -98,7 +84,7 @@ public class RotationHelper implements OnSharedPreferenceChangeListener,
mSharedPrefs.registerOnSharedPreferenceChangeListener(this);
}
mHomeRotationEnabled = mSharedPrefs.getBoolean(ALLOW_ROTATION_PREFERENCE_KEY,
- getAllowRotationDefaultValue(mActivity.getDeviceProfile()));
+ mActivity.getDeviceProfile().allowRotation);
} else {
if (mSharedPrefs != null) {
mSharedPrefs.unregisterOnSharedPreferenceChangeListener(this);
@@ -109,10 +95,10 @@ public class RotationHelper implements OnSharedPreferenceChangeListener,
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String s) {
- if (mDestroyed || mIgnoreAutoRotateSettings) return;
+ if (mDestroyed) return;
boolean wasRotationEnabled = mHomeRotationEnabled;
mHomeRotationEnabled = mSharedPrefs.getBoolean(ALLOW_ROTATION_PREFERENCE_KEY,
- getAllowRotationDefaultValue(mActivity.getDeviceProfile()));
+ mActivity.getDeviceProfile().allowRotation);
if (mHomeRotationEnabled != wasRotationEnabled) {
notifyChange();
}
@@ -120,7 +106,7 @@ public class RotationHelper implements OnSharedPreferenceChangeListener,
@Override
public void onDeviceProfileChanged(DeviceProfile dp) {
- boolean ignoreAutoRotateSettings = dp.isTablet;
+ boolean ignoreAutoRotateSettings = dp.allowRotation;
if (mIgnoreAutoRotateSettings != ignoreAutoRotateSettings) {
setIgnoreAutoRotateSettings(ignoreAutoRotateSettings);
notifyChange();
@@ -157,7 +143,7 @@ public class RotationHelper implements OnSharedPreferenceChangeListener,
public void initialize() {
if (!mInitialized) {
mInitialized = true;
- setIgnoreAutoRotateSettings(mActivity.getDeviceProfile().isTablet);
+ setIgnoreAutoRotateSettings(mActivity.getDeviceProfile().allowRotation);
mActivity.addOnDeviceProfileChangeListener(this);
notifyChange();
}
diff --git a/src/com/android/launcher3/states/SpringLoadedState.java b/src/com/android/launcher3/states/SpringLoadedState.java
index a205ab55ca..8db1dbe69d 100644
--- a/src/com/android/launcher3/states/SpringLoadedState.java
+++ b/src/com/android/launcher3/states/SpringLoadedState.java
@@ -18,6 +18,7 @@ package com.android.launcher3.states;
import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_HOME;
import android.content.Context;
+import android.graphics.Rect;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Launcher;
@@ -39,26 +40,41 @@ public class SpringLoadedState extends LauncherState {
}
@Override
- public int getTransitionDuration(Context context, boolean isToState) {
+ public int getTransitionDuration(Context context) {
return 150;
}
@Override
public ScaleAndTranslation getWorkspaceScaleAndTranslation(Launcher launcher) {
DeviceProfile grid = launcher.getDeviceProfile();
- Workspace<?> ws = launcher.getWorkspace();
+ Workspace ws = launcher.getWorkspace();
if (ws.getChildCount() == 0) {
return super.getWorkspaceScaleAndTranslation(launcher);
}
- float shrunkTop = grid.getCellLayoutSpringLoadShrunkTop();
- float scale = grid.getWorkspaceSpringLoadScale();
+ if (grid.isVerticalBarLayout()) {
+ float scale = grid.workspaceSpringLoadShrinkFactor;
+ return new ScaleAndTranslation(scale, 0, 0);
+ }
+
+ float scale = grid.workspaceSpringLoadShrinkFactor;
+ Rect insets = launcher.getDragLayer().getInsets();
+ int insetsBottom = grid.isTaskbarPresent ? grid.taskbarSize : insets.bottom;
+
+ float scaledHeight = scale * ws.getNormalChildHeight();
+ float shrunkTop = insets.top + grid.dropTargetBarSizePx;
+ float shrunkBottom = ws.getMeasuredHeight() - insetsBottom
+ - grid.workspacePadding.bottom
+ - grid.workspaceSpringLoadedBottomSpace;
+ float totalShrunkSpace = shrunkBottom - shrunkTop;
+
+ float desiredCellTop = shrunkTop + (totalShrunkSpace - scaledHeight) / 2;
float halfHeight = ws.getHeight() / 2;
float myCenter = ws.getTop() + halfHeight;
float cellTopFromCenter = halfHeight - ws.getChildAt(0).getTop();
float actualCellTop = myCenter - cellTopFromCenter * scale;
- return new ScaleAndTranslation(scale, 0, (shrunkTop - actualCellTop) / scale);
+ return new ScaleAndTranslation(scale, 0, (desiredCellTop - actualCellTop) / scale);
}
@Override
@@ -75,4 +91,9 @@ public class SpringLoadedState extends LauncherState {
public float getWorkspaceBackgroundAlpha(Launcher launcher) {
return 0.2f;
}
+
+ @Override
+ public int getVisibleElements(Launcher launcher) {
+ return (super.getVisibleElements(launcher) | HOTSEAT_ICONS) & ~TASKBAR;
+ }
}
diff --git a/src/com/android/launcher3/states/StateAnimationConfig.java b/src/com/android/launcher3/states/StateAnimationConfig.java
index f99519d6e9..bd6f7d3a74 100644
--- a/src/com/android/launcher3/states/StateAnimationConfig.java
+++ b/src/com/android/launcher3/states/StateAnimationConfig.java
@@ -53,7 +53,6 @@ public class StateAnimationConfig {
ANIM_WORKSPACE_FADE,
ANIM_HOTSEAT_SCALE,
ANIM_HOTSEAT_TRANSLATE,
- ANIM_HOTSEAT_FADE,
ANIM_OVERVIEW_SCALE,
ANIM_OVERVIEW_TRANSLATE_X,
ANIM_OVERVIEW_TRANSLATE_Y,
@@ -63,7 +62,6 @@ public class StateAnimationConfig {
ANIM_OVERVIEW_MODAL,
ANIM_DEPTH,
ANIM_OVERVIEW_ACTIONS_FADE,
- ANIM_WORKSPACE_PAGE_TRANSLATE_X,
})
@Retention(RetentionPolicy.SOURCE)
public @interface AnimType {}
@@ -73,7 +71,6 @@ public class StateAnimationConfig {
public static final int ANIM_WORKSPACE_FADE = 3;
public static final int ANIM_HOTSEAT_SCALE = 4;
public static final int ANIM_HOTSEAT_TRANSLATE = 5;
- public static final int ANIM_HOTSEAT_FADE = 16;
public static final int ANIM_OVERVIEW_SCALE = 6;
public static final int ANIM_OVERVIEW_TRANSLATE_X = 7;
public static final int ANIM_OVERVIEW_TRANSLATE_Y = 8;
@@ -83,9 +80,8 @@ public class StateAnimationConfig {
public static final int ANIM_OVERVIEW_MODAL = 12;
public static final int ANIM_DEPTH = 13;
public static final int ANIM_OVERVIEW_ACTIONS_FADE = 14;
- public static final int ANIM_WORKSPACE_PAGE_TRANSLATE_X = 15;
- private static final int ANIM_TYPES_COUNT = 17;
+ private static final int ANIM_TYPES_COUNT = 15;
protected final Interpolator[] mInterpolators = new Interpolator[ANIM_TYPES_COUNT];
diff --git a/src/com/android/launcher3/testing/TestInformationHandler.java b/src/com/android/launcher3/testing/TestInformationHandler.java
index 242d2d423c..4261d080d9 100644
--- a/src/com/android/launcher3/testing/TestInformationHandler.java
+++ b/src/com/android/launcher3/testing/TestInformationHandler.java
@@ -21,25 +21,17 @@ import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Context;
-import android.content.res.Resources;
import android.graphics.Insets;
-import android.graphics.Point;
-import android.graphics.Rect;
import android.os.Build;
import android.os.Bundle;
import android.view.WindowInsets;
-import androidx.annotation.Nullable;
-
-import com.android.launcher3.CellLayout;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.LauncherState;
import com.android.launcher3.R;
-import com.android.launcher3.Workspace;
-import com.android.launcher3.dragndrop.DragLayer;
import com.android.launcher3.util.ResourceBasedOverride;
import com.android.launcher3.widget.picker.WidgetsFullSheet;
@@ -69,18 +61,8 @@ public class TestInformationHandler implements ResourceBasedOverride {
mLauncherAppState = LauncherAppState.getInstanceNoCreate();
}
- /**
- * handle a request and return result Bundle.
- *
- * @param method request name.
- * @param arg optional single string argument.
- * @param extra extra request payload.
- */
- public Bundle call(String method, String arg, @Nullable Bundle extra) {
+ public Bundle call(String method) {
final Bundle response = new Bundle();
- if (extra != null && extra.getClassLoader() == null) {
- extra.setClassLoader(getClass().getClassLoader());
- }
switch (method) {
case TestProtocol.REQUEST_HOME_TO_ALL_APPS_SWIPE_HEIGHT: {
return getLauncherUIProperty(Bundle::putInt, l -> {
@@ -116,21 +98,12 @@ public class TestInformationHandler implements ResourceBasedOverride {
l -> WidgetsFullSheet.getWidgetsView(l).getCurrentScrollY());
}
- case TestProtocol.REQUEST_TARGET_INSETS: {
- return getUIProperty(Bundle::putParcelable, activity -> {
- WindowInsets insets = activity.getWindow()
- .getDecorView().getRootWindowInsets();
- return Insets.max(
- insets.getSystemGestureInsets(),
- insets.getSystemWindowInsets());
- }, this::getCurrentActivity);
- }
-
case TestProtocol.REQUEST_WINDOW_INSETS: {
- return getUIProperty(Bundle::putParcelable, activity -> {
- WindowInsets insets = activity.getWindow()
+ return getUIProperty(Bundle::putParcelable, a -> {
+ WindowInsets insets = a.getWindow()
.getDecorView().getRootWindowInsets();
- return insets.getSystemWindowInsets();
+ return Insets.max(
+ insets.getSystemGestureInsets(), insets.getSystemWindowInsets());
}, this::getCurrentActivity);
}
@@ -144,86 +117,11 @@ public class TestInformationHandler implements ResourceBasedOverride {
TestProtocol.sDisableSensorRotation = true;
return response;
- case TestProtocol.REQUEST_IS_TABLET:
- response.putBoolean(TestProtocol.TEST_INFO_RESPONSE_FIELD, mDeviceProfile.isTablet);
- return response;
-
- case TestProtocol.REQUEST_IS_TWO_PANELS:
- response.putBoolean(TestProtocol.TEST_INFO_RESPONSE_FIELD,
- mDeviceProfile.isTwoPanels);
- return response;
-
- case TestProtocol.REQUEST_SET_FORCE_PAUSE_TIMEOUT:
- TestProtocol.sForcePauseTimeout = Long.parseLong(arg);
- return response;
-
- case TestProtocol.REQUEST_GET_HAD_NONTEST_EVENTS:
- response.putBoolean(
- TestProtocol.TEST_INFO_RESPONSE_FIELD, TestLogging.sHadEventsNotFromTest);
- return response;
-
- case TestProtocol.REQUEST_START_DRAG_THRESHOLD: {
- final Resources resources = mContext.getResources();
- response.putInt(TestProtocol.TEST_INFO_RESPONSE_FIELD,
- resources.getDimensionPixelSize(R.dimen.deep_shortcuts_start_drag_threshold)
- + resources.getDimensionPixelSize(R.dimen.pre_drag_view_scale));
- return response;
- }
-
- case TestProtocol.REQUEST_ENABLE_ROTATION:
- MAIN_EXECUTOR.submit(() ->
- Launcher.ACTIVITY_TRACKER.getCreatedActivity().getRotationHelper()
- .forceAllowRotationForTesting(Boolean.parseBoolean(arg)));
- return null;
-
- case TestProtocol.REQUEST_WORKSPACE_CELL_LAYOUT_SIZE:
- return getLauncherUIProperty(Bundle::putIntArray, launcher -> {
- final Workspace<?> workspace = launcher.getWorkspace();
- final int screenId = workspace.getScreenIdForPageIndex(
- workspace.getCurrentPage());
- final CellLayout cellLayout = workspace.getScreenWithId(screenId);
- return new int[]{cellLayout.getCountX(), cellLayout.getCountY()};
- });
-
- case TestProtocol.REQUEST_WORKSPACE_CELL_CENTER:
- final WorkspaceCellCenterRequest request = extra.getParcelable(
- TestProtocol.TEST_INFO_REQUEST_FIELD);
- return getLauncherUIProperty(Bundle::putParcelable, launcher -> {
- final Workspace<?> workspace = launcher.getWorkspace();
- // TODO(b/216387249): allow caller selecting different pages.
- CellLayout cellLayout = (CellLayout) workspace.getPageAt(
- workspace.getCurrentPage());
- final Rect cellRect = getDescendantRectRelativeToDragLayerForCell(launcher,
- cellLayout, request.cellX, request.cellY, request.spanX, request.spanY);
- return new Point(cellRect.centerX(), cellRect.centerY());
- });
-
- case TestProtocol.REQUEST_HAS_TIS: {
- response.putBoolean(
- TestProtocol.REQUEST_HAS_TIS, false);
- return response;
- }
-
default:
return null;
}
}
- private static Rect getDescendantRectRelativeToDragLayerForCell(Launcher launcher,
- CellLayout cellLayout, int cellX, int cellY, int spanX, int spanY) {
- final DragLayer dragLayer = launcher.getDragLayer();
- final Rect target = new Rect();
-
- cellLayout.cellToRect(cellX, cellY, spanX, spanY, target);
- int[] leftTop = {target.left, target.top};
- int[] rightBottom = {target.right, target.bottom};
- dragLayer.getDescendantCoordRelativeToSelf(cellLayout, leftTop);
- dragLayer.getDescendantCoordRelativeToSelf(cellLayout, rightBottom);
-
- target.set(leftTop[0], leftTop[1], rightBottom[0], rightBottom[1]);
- return target;
- }
-
protected boolean isLauncherInitialized() {
return Launcher.ACTIVITY_TRACKER.getCreatedActivity() == null
|| LauncherAppState.getInstance(mContext).getModel().isModelLoaded();
@@ -264,7 +162,6 @@ public class TestInformationHandler implements ResourceBasedOverride {
/**
* Generic interface for setting a fiend in bundle
- *
* @param <T> the type of value being set
*/
public interface BundleSetter<T> {
diff --git a/src/com/android/launcher3/testing/TestInformationProvider.java b/src/com/android/launcher3/testing/TestInformationProvider.java
index bcc7c2de4e..bd177c0031 100644
--- a/src/com/android/launcher3/testing/TestInformationProvider.java
+++ b/src/com/android/launcher3/testing/TestInformationProvider.java
@@ -60,7 +60,7 @@ public class TestInformationProvider extends ContentProvider {
if (Utilities.IS_RUNNING_IN_TEST_HARNESS) {
TestInformationHandler handler = TestInformationHandler.newInstance(getContext());
handler.init(getContext());
- return handler.call(method, arg, extras);
+ return handler.call(method);
}
return null;
}
diff --git a/src/com/android/launcher3/testing/TestInformationRequest.java b/src/com/android/launcher3/testing/TestInformationRequest.java
deleted file mode 100644
index 272ae56a30..0000000000
--- a/src/com/android/launcher3/testing/TestInformationRequest.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2021 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.launcher3.testing;
-
-import android.os.Parcelable;
-
-/**
- * A Request sent to TestInformationHandler can implement this interface to carry more information.
- */
-public interface TestInformationRequest extends Parcelable {
- /**
- * The name for handler to dispatch request.
- */
- String getRequestName();
-}
diff --git a/src/com/android/launcher3/testing/TestLogging.java b/src/com/android/launcher3/testing/TestLogging.java
index 103b565140..51e081972f 100644
--- a/src/com/android/launcher3/testing/TestLogging.java
+++ b/src/com/android/launcher3/testing/TestLogging.java
@@ -17,8 +17,6 @@
package com.android.launcher3.testing;
import android.util.Log;
-import android.view.InputEvent;
-import android.view.KeyEvent;
import android.view.MotionEvent;
import com.android.launcher3.Utilities;
@@ -27,7 +25,6 @@ import java.util.function.BiConsumer;
public final class TestLogging {
private static BiConsumer<String, String> sEventConsumer;
- public static boolean sHadEventsNotFromTest;
private static void recordEventSlow(String sequence, String event) {
Log.d(TestProtocol.TAPL_EVENTS_TAG, sequence + " / " + event);
@@ -49,24 +46,9 @@ public final class TestLogging {
}
}
- private static void registerEventNotFromTest(InputEvent event) {
- if (!sHadEventsNotFromTest && event.getDeviceId() != -1) {
- sHadEventsNotFromTest = true;
- Log.d(TestProtocol.PERMANENT_DIAG_TAG, "First event not from test: " + event);
- }
- }
-
- public static void recordKeyEvent(String sequence, String message, KeyEvent event) {
- if (Utilities.IS_RUNNING_IN_TEST_HARNESS) {
- recordEventSlow(sequence, message + ": " + event);
- registerEventNotFromTest(event);
- }
- }
-
public static void recordMotionEvent(String sequence, String message, MotionEvent event) {
if (Utilities.IS_RUNNING_IN_TEST_HARNESS && event.getAction() != MotionEvent.ACTION_MOVE) {
recordEventSlow(sequence, message + ": " + event);
- registerEventNotFromTest(event);
}
}
diff --git a/src/com/android/launcher3/testing/TestProtocol.java b/src/com/android/launcher3/testing/TestProtocol.java
index 3a030a8b87..b6da7fcd37 100644
--- a/src/com/android/launcher3/testing/TestProtocol.java
+++ b/src/com/android/launcher3/testing/TestProtocol.java
@@ -24,8 +24,6 @@ public final class TestProtocol {
public static final String SWITCHED_TO_STATE_MESSAGE = "TAPL_SWITCHED_TO_STATE";
public static final String SCROLL_FINISHED_MESSAGE = "TAPL_SCROLL_FINISHED";
public static final String PAUSE_DETECTED_MESSAGE = "TAPL_PAUSE_DETECTED";
- public static final String DISMISS_ANIMATION_ENDS_MESSAGE = "TAPL_DISMISS_ANIMATION_ENDS";
- public static final String FOLDER_OPENED_MESSAGE = "TAPL_FOLDER_OPENED";
public static final int NORMAL_STATE_ORDINAL = 0;
public static final int SPRING_LOADED_STATE_ORDINAL = 1;
public static final int OVERVIEW_STATE_ORDINAL = 2;
@@ -68,28 +66,25 @@ public final class TestProtocol {
}
}
- public static final String TEST_INFO_REQUEST_FIELD = "request";
public static final String TEST_INFO_RESPONSE_FIELD = "response";
public static final String REQUEST_HOME_TO_OVERVIEW_SWIPE_HEIGHT =
"home-to-overview-swipe-height";
public static final String REQUEST_BACKGROUND_TO_OVERVIEW_SWIPE_HEIGHT =
"background-to-overview-swipe-height";
+ public static final String REQUEST_ALL_APPS_TO_OVERVIEW_SWIPE_HEIGHT =
+ "all-apps-to-overview-swipe-height";
public static final String REQUEST_HOME_TO_ALL_APPS_SWIPE_HEIGHT =
"home-to-all-apps-swipe-height";
public static final String REQUEST_ICON_HEIGHT =
"icon-height";
+ public static final String REQUEST_HOTSEAT_TOP = "hotseat-top";
public static final String REQUEST_IS_LAUNCHER_INITIALIZED = "is-launcher-initialized";
public static final String REQUEST_FREEZE_APP_LIST = "freeze-app-list";
public static final String REQUEST_UNFREEZE_APP_LIST = "unfreeze-app-list";
- public static final String REQUEST_ENABLE_MANUAL_TASKBAR_STASHING = "enable-taskbar-stashing";
- public static final String REQUEST_DISABLE_MANUAL_TASKBAR_STASHING = "disable-taskbar-stashing";
- public static final String REQUEST_UNSTASH_TASKBAR_IF_STASHED = "unstash-taskbar-if-stashed";
- public static final String REQUEST_STASHED_TASKBAR_HEIGHT = "stashed-taskbar-height";
public static final String REQUEST_APP_LIST_FREEZE_FLAGS = "app-list-freeze-flags";
public static final String REQUEST_APPS_LIST_SCROLL_Y = "apps-list-scroll-y";
public static final String REQUEST_WIDGETS_SCROLL_Y = "widgets-scroll-y";
- public static final String REQUEST_TARGET_INSETS = "target-insets";
public static final String REQUEST_WINDOW_INSETS = "window-insets";
public static final String REQUEST_PID = "pid";
public static final String REQUEST_FORCE_GC = "gc";
@@ -97,46 +92,21 @@ public final class TestProtocol {
public static final String REQUEST_RECENT_TASKS_LIST = "recent-tasks-list";
public static final String REQUEST_START_EVENT_LOGGING = "start-event-logging";
public static final String REQUEST_GET_TEST_EVENTS = "get-test-events";
- public static final String REQUEST_GET_HAD_NONTEST_EVENTS = "get-had-nontest-events";
public static final String REQUEST_STOP_EVENT_LOGGING = "stop-event-logging";
public static final String REQUEST_CLEAR_DATA = "clear-data";
- public static final String REQUEST_USE_TEST_WORKSPACE_LAYOUT = "use-test-workspace-layout";
- public static final String REQUEST_USE_DEFAULT_WORKSPACE_LAYOUT =
- "use-default-workspace-layout";
- public static final String REQUEST_HOTSEAT_ICON_NAMES = "get-hotseat-icon-names";
- public static final String REQUEST_IS_TABLET = "is-tablet";
- public static final String REQUEST_IS_TWO_PANELS = "is-two-panel";
- public static final String REQUEST_START_DRAG_THRESHOLD = "start-drag-threshold";
- public static final String REQUEST_GET_ACTIVITIES_CREATED_COUNT =
- "get-activities-created-count";
- public static final String REQUEST_GET_ACTIVITIES = "get-activities";
- public static final String REQUEST_HAS_TIS = "has-touch-interaction-service";
-
- public static final String REQUEST_WORKSPACE_CELL_LAYOUT_SIZE = "workspace-cell-layout-size";
- public static final String REQUEST_WORKSPACE_CELL_CENTER = "workspace-cell-center";
-
- public static final String REQUEST_GET_FOCUSED_TASK_HEIGHT_FOR_TABLET =
- "get-focused-task-height-for-tablet";
- public static final String REQUEST_GET_GRID_TASK_SIZE_RECT_FOR_TABLET =
- "get-grid-task-size-rect-for-tablet";
- public static final String REQUEST_GET_OVERVIEW_PAGE_SPACING = "get-overview-page-spacing";
- public static final String REQUEST_ENABLE_ROTATION = "enable_rotation";
-
- public static Long sForcePauseTimeout;
- public static final String REQUEST_SET_FORCE_PAUSE_TIMEOUT = "set-force-pause-timeout";
public static boolean sDebugTracing = false;
public static final String REQUEST_ENABLE_DEBUG_TRACING = "enable-debug-tracing";
public static final String REQUEST_DISABLE_DEBUG_TRACING = "disable-debug-tracing";
+ public static final String REQUEST_OVERVIEW_SHARE_ENABLED = "overview-share-enabled";
+ public static final String REQUEST_OVERVIEW_CONTENT_PUSH_ENABLED =
+ "overview-content-push-enabled";
public static boolean sDisableSensorRotation;
public static final String REQUEST_MOCK_SENSOR_ROTATION = "mock-sensor-rotation";
public static final String PERMANENT_DIAG_TAG = "TaplTarget";
- public static final String NO_DROP_TARGET = "b/195031154";
- public static final String NULL_INT_SET = "b/200572078";
- public static final String MISSING_PROMISE_ICON = "b/202985412";
- public static final String BAD_STATE = "b/223498680";
- public static final String TASKBAR_IN_APP_STATE = "b/227657604";
+ public static final String WORK_PROFILE_REMOVED = "b/159671700";
+ public static final String FALLBACK_ACTIVITY_NO_SET = "b/181019015";
}
diff --git a/src/com/android/launcher3/testing/WorkspaceCellCenterRequest.java b/src/com/android/launcher3/testing/WorkspaceCellCenterRequest.java
deleted file mode 100644
index 71ab09f3f2..0000000000
--- a/src/com/android/launcher3/testing/WorkspaceCellCenterRequest.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.launcher3.testing;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * Request object for querying a workspace cell region in Rect.
- */
-public class WorkspaceCellCenterRequest implements TestInformationRequest {
- public final int cellX;
- public final int cellY;
- public final int spanX;
- public final int spanY;
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeInt(cellX);
- dest.writeInt(cellY);
- dest.writeInt(spanX);
- dest.writeInt(spanY);
- }
-
- public static final Parcelable.Creator<WorkspaceCellCenterRequest> CREATOR =
- new Parcelable.Creator<WorkspaceCellCenterRequest>() {
-
- @Override
- public WorkspaceCellCenterRequest createFromParcel(Parcel source) {
- return new WorkspaceCellCenterRequest(source);
- }
-
- @Override
- public WorkspaceCellCenterRequest[] newArray(int size) {
- return new WorkspaceCellCenterRequest[size];
- }
- };
-
- private WorkspaceCellCenterRequest(int cellX, int cellY, int spanX, int spanY) {
- this.cellX = cellX;
- this.cellY = cellY;
- this.spanX = spanX;
- this.spanY = spanY;
- }
-
- private WorkspaceCellCenterRequest(Parcel in) {
- this(in.readInt(), in.readInt(), in.readInt(), in.readInt());
- }
-
- /**
- * Create a builder for WorkspaceCellRectRequest.
- *
- * @return WorkspaceCellRectRequest builder.
- */
- public static WorkspaceCellCenterRequest.Builder builder() {
- return new WorkspaceCellCenterRequest.Builder();
- }
-
- @Override
- public String getRequestName() {
- return TestProtocol.REQUEST_WORKSPACE_CELL_CENTER;
- }
-
- /**
- * WorkspaceCellRectRequest Builder.
- */
- public static final class Builder {
- private int mCellX;
- private int mCellY;
- private int mSpanX;
- private int mSpanY;
-
- private Builder() {
- this.mCellX = 0;
- this.mCellY = 0;
- this.mSpanX = 1;
- this.mSpanY = 1;
- }
-
- /**
- * Set X coordinate of upper left corner expressed as a cell position
- */
- public WorkspaceCellCenterRequest.Builder setCellX(int x) {
- this.mCellX = x;
- return this;
- }
-
- /**
- * Set Y coordinate of upper left corner expressed as a cell position
- */
- public WorkspaceCellCenterRequest.Builder setCellY(int y) {
- this.mCellY = y;
- return this;
- }
-
- /**
- * Set span Width in cells
- */
- public WorkspaceCellCenterRequest.Builder setSpanX(int x) {
- this.mSpanX = x;
- return this;
- }
-
- /**
- * Set span Height in cells
- */
- public WorkspaceCellCenterRequest.Builder setSpanY(int y) {
- this.mCellY = y;
- return this;
- }
-
- /**
- * build the WorkspaceCellRectRequest.
- */
- public WorkspaceCellCenterRequest build() {
- return new WorkspaceCellCenterRequest(mCellX, mCellY, mSpanX, mSpanY);
- }
- }
-}
diff --git a/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java b/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java
index 09b8228182..5f8a4d4f3c 100644
--- a/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java
+++ b/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java
@@ -16,19 +16,18 @@
package com.android.launcher3.touch;
import static com.android.launcher3.LauncherAnimUtils.SUCCESS_TRANSITION_PROGRESS;
-import static com.android.launcher3.LauncherAnimUtils.TABLET_BOTTOM_SHEET_SUCCESS_TRANSITION_PROGRESS;
import static com.android.launcher3.LauncherAnimUtils.newCancelListener;
import static com.android.launcher3.LauncherState.ALL_APPS;
import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.launcher3.LauncherState.OVERVIEW;
-import static com.android.launcher3.anim.AnimatorListeners.forEndCallback;
import static com.android.launcher3.anim.Interpolators.scrollInterpolatorForVelocity;
+import static com.android.launcher3.config.FeatureFlags.UNSTABLE_SPRINGS;
import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_ALLAPPS;
import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_HOME;
import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_OVERVIEW;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_UNKNOWN_SWIPEDOWN;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_UNKNOWN_SWIPEUP;
-import static com.android.launcher3.util.window.RefreshRateTracker.getSingleFrameMs;
+import static com.android.launcher3.util.DisplayController.getSingleFrameMs;
import android.animation.Animator.AnimatorListener;
import android.animation.ValueAnimator;
@@ -218,7 +217,7 @@ public abstract class AbstractStateChangeTouchController
mFlingBlockCheck.blockFling();
}
}
- if (mToState == LauncherState.ALL_APPS) {
+ if (mToState == LauncherState.ALL_APPS && !UNSTABLE_SPRINGS.get()) {
mAllAppsOvershootStarted = true;
// 1f, value when all apps container hit the top
mLauncher.getAppsView().onPull(progress - 1f, progress - 1f);
@@ -287,13 +286,8 @@ public abstract class AbstractStateChangeTouchController
? mToState : mFromState;
// snap to top or bottom using the release velocity
} else {
- float successTransitionProgress =
- mLauncher.getDeviceProfile().isTablet
- && (mToState == ALL_APPS || mFromState == ALL_APPS)
- ? TABLET_BOTTOM_SHEET_SUCCESS_TRANSITION_PROGRESS
- : SUCCESS_TRANSITION_PROGRESS;
targetState =
- (interpolatedProgress > successTransitionProgress) ? mToState : mFromState;
+ (interpolatedProgress > SUCCESS_TRANSITION_PROGRESS) ? mToState : mFromState;
}
final float endProgress;
@@ -331,12 +325,15 @@ public abstract class AbstractStateChangeTouchController
Math.min(progress, 1) - endProgress) * durationMultiplier;
}
}
+ if (targetState != mStartState) {
+ logReachedState(targetState);
+ }
mCurrentAnimation.setEndAction(() -> onSwipeInteractionCompleted(targetState));
ValueAnimator anim = mCurrentAnimation.getAnimationPlayer();
anim.setFloatValues(startProgress, endProgress);
updateSwipeCompleteAnimation(anim, duration, targetState, velocity, fling);
mCurrentAnimation.dispatchOnStart();
- if (targetState == LauncherState.ALL_APPS) {
+ if (targetState == LauncherState.ALL_APPS && !UNSTABLE_SPRINGS.get()) {
if (mAllAppsOvershootStarted) {
mLauncher.getAppsView().onRelease();
mAllAppsOvershootStarted = false;
@@ -359,8 +356,6 @@ public abstract class AbstractStateChangeTouchController
boolean shouldGoToTargetState = mGoingBetweenStates || (mToState != targetState);
if (shouldGoToTargetState) {
goToTargetState(targetState);
- } else {
- logReachedState(mToState);
}
}
@@ -368,19 +363,13 @@ public abstract class AbstractStateChangeTouchController
if (!mLauncher.isInState(targetState)) {
// If we're already in the target state, don't jump to it at the end of the animation in
// case the user started interacting with it before the animation finished.
- mLauncher.getStateManager().goToState(targetState, false /* animated */,
- forEndCallback(() -> logReachedState(targetState)));
- } else {
- logReachedState(targetState);
+ mLauncher.getStateManager().goToState(targetState, false /* animated */);
}
mLauncher.getRootView().getSysUiScrim().createSysuiMultiplierAnim(
1f).setDuration(0).start();
}
private void logReachedState(LauncherState targetState) {
- if (mStartState == targetState) {
- return;
- }
// Transition complete. log the action
mLauncher.getStatsLogManager().logger()
.withSrcState(mStartState.statsLogOrdinal)
diff --git a/src/com/android/launcher3/touch/AllAppsSwipeController.java b/src/com/android/launcher3/touch/AllAppsSwipeController.java
index db43baa4d8..ab2652ab5e 100644
--- a/src/com/android/launcher3/touch/AllAppsSwipeController.java
+++ b/src/com/android/launcher3/touch/AllAppsSwipeController.java
@@ -1,5 +1,5 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
+/**
+ * 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.
@@ -17,79 +17,18 @@ package com.android.launcher3.touch;
import static com.android.launcher3.LauncherState.ALL_APPS;
import static com.android.launcher3.LauncherState.NORMAL;
-import static com.android.launcher3.anim.Interpolators.DECELERATED_EASE;
-import static com.android.launcher3.anim.Interpolators.EMPHASIZED_ACCELERATE;
-import static com.android.launcher3.anim.Interpolators.EMPHASIZED_DECELERATE;
-import static com.android.launcher3.anim.Interpolators.FINAL_FRAME;
-import static com.android.launcher3.anim.Interpolators.INSTANT;
-import static com.android.launcher3.anim.Interpolators.LINEAR;
-import static com.android.launcher3.states.StateAnimationConfig.ANIM_ALL_APPS_FADE;
-import static com.android.launcher3.states.StateAnimationConfig.ANIM_DEPTH;
-import static com.android.launcher3.states.StateAnimationConfig.ANIM_HOTSEAT_FADE;
-import static com.android.launcher3.states.StateAnimationConfig.ANIM_HOTSEAT_SCALE;
-import static com.android.launcher3.states.StateAnimationConfig.ANIM_HOTSEAT_TRANSLATE;
-import static com.android.launcher3.states.StateAnimationConfig.ANIM_SCRIM_FADE;
-import static com.android.launcher3.states.StateAnimationConfig.ANIM_VERTICAL_PROGRESS;
-import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_FADE;
-import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_SCALE;
import android.view.MotionEvent;
-import android.view.animation.Interpolator;
import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherState;
-import com.android.launcher3.anim.Interpolators;
-import com.android.launcher3.states.StateAnimationConfig;
/**
* TouchController to switch between NORMAL and ALL_APPS state.
*/
public class AllAppsSwipeController extends AbstractStateChangeTouchController {
- private static final float ALLAPPS_STAGGERED_FADE_THRESHOLD = 0.5f;
-
- // Custom timing for NORMAL -> ALL_APPS on phones only.
- private static final float WORKSPACE_MOTION_START = 0.1667f;
- private static final float ALL_APPS_STATE_TRANSITION = 0.305f;
- private static final float ALL_APPS_FADE_END = 0.4717f;
- private static final float ALL_APPS_FULL_DEPTH_PROGRESS = 0.5f;
-
- public static final Interpolator ALLAPPS_STAGGERED_FADE_EARLY_RESPONDER =
- Interpolators.clampToProgress(LINEAR, 0, ALLAPPS_STAGGERED_FADE_THRESHOLD);
- public static final Interpolator ALLAPPS_STAGGERED_FADE_LATE_RESPONDER =
- Interpolators.clampToProgress(LINEAR, ALLAPPS_STAGGERED_FADE_THRESHOLD, 1f);
-
- // Custom interpolators for NORMAL -> ALL_APPS on phones only.
- // The blur to All Apps is set to be complete when the interpolator is at 0.5.
- public static final Interpolator BLUR =
- Interpolators.clampToProgress(
- Interpolators.mapToProgress(
- LINEAR, 0f, ALL_APPS_FULL_DEPTH_PROGRESS),
- WORKSPACE_MOTION_START, ALL_APPS_STATE_TRANSITION);
- public static final Interpolator WORKSPACE_FADE =
- Interpolators.clampToProgress(FINAL_FRAME, 0f, ALL_APPS_STATE_TRANSITION);
- public static final Interpolator WORKSPACE_SCALE =
- Interpolators.clampToProgress(
- EMPHASIZED_ACCELERATE, WORKSPACE_MOTION_START, ALL_APPS_STATE_TRANSITION);
- public static final Interpolator HOTSEAT_FADE = WORKSPACE_FADE;
- public static final Interpolator HOTSEAT_SCALE = HOTSEAT_FADE;
- public static final Interpolator HOTSEAT_TRANSLATE =
- Interpolators.clampToProgress(
- EMPHASIZED_ACCELERATE, WORKSPACE_MOTION_START, ALL_APPS_STATE_TRANSITION);
- public static final Interpolator SCRIM_FADE =
- Interpolators.clampToProgress(
- Interpolators.mapToProgress(LINEAR, 0f, 0.8f),
- WORKSPACE_MOTION_START, ALL_APPS_STATE_TRANSITION);
- public static final Interpolator ALL_APPS_FADE =
- Interpolators.clampToProgress(
- Interpolators.mapToProgress(DECELERATED_EASE, 0.2f, 1.0f),
- ALL_APPS_STATE_TRANSITION, ALL_APPS_FADE_END);
- public static final Interpolator ALL_APPS_VERTICAL_PROGRESS =
- Interpolators.clampToProgress(
- Interpolators.mapToProgress(EMPHASIZED_DECELERATE, 0.4f, 1.0f),
- ALL_APPS_STATE_TRANSITION, 1.0f);
-
public AllAppsSwipeController(Launcher l) {
super(l, SingleAxisSwipeDetector.VERTICAL);
}
@@ -126,60 +65,12 @@ public class AllAppsSwipeController extends AbstractStateChangeTouchController {
@Override
protected float initCurrentAnimation() {
float range = getShiftRange();
- StateAnimationConfig config = getConfigForStates(mFromState, mToState);
- config.duration = (long) (2 * range);
-
+ long maxAccuracy = (long) (2 * range);
mCurrentAnimation = mLauncher.getStateManager()
- .createAnimationToNewWorkspace(mToState, config);
+ .createAnimationToNewWorkspace(mToState, maxAccuracy);
float startVerticalShift = mFromState.getVerticalProgress(mLauncher) * range;
float endVerticalShift = mToState.getVerticalProgress(mLauncher) * range;
float totalShift = endVerticalShift - startVerticalShift;
return 1 / totalShift;
}
-
- @Override
- protected StateAnimationConfig getConfigForStates(LauncherState fromState,
- LauncherState toState) {
- StateAnimationConfig config = super.getConfigForStates(fromState, toState);
- if (fromState == NORMAL && toState == ALL_APPS) {
- applyNormalToAllAppsAnimConfig(mLauncher, config);
- } else if (fromState == ALL_APPS && toState == NORMAL) {
- applyAllAppsToNormalConfig(mLauncher, config);
- }
- return config;
- }
-
- /**
- * Applies Animation config values for transition from all apps to home
- */
- public static void applyAllAppsToNormalConfig(Launcher launcher, StateAnimationConfig config) {
- boolean isTablet = launcher.getDeviceProfile().isTablet;
- config.setInterpolator(ANIM_SCRIM_FADE, ALLAPPS_STAGGERED_FADE_LATE_RESPONDER);
- config.setInterpolator(ANIM_ALL_APPS_FADE, isTablet
- ? FINAL_FRAME : ALLAPPS_STAGGERED_FADE_EARLY_RESPONDER);
- if (!isTablet) {
- config.setInterpolator(ANIM_WORKSPACE_FADE, INSTANT);
- }
- }
-
- /**
- * Applies Animation config values for transition from home to all apps
- */
- public static void applyNormalToAllAppsAnimConfig(Launcher launcher,
- StateAnimationConfig config) {
- if (launcher.getDeviceProfile().isTablet) {
- config.setInterpolator(ANIM_SCRIM_FADE, ALLAPPS_STAGGERED_FADE_EARLY_RESPONDER);
- config.setInterpolator(ANIM_ALL_APPS_FADE, INSTANT);
- } else {
- config.setInterpolator(ANIM_DEPTH, BLUR);
- config.setInterpolator(ANIM_WORKSPACE_FADE, WORKSPACE_FADE);
- config.setInterpolator(ANIM_WORKSPACE_SCALE, WORKSPACE_SCALE);
- config.setInterpolator(ANIM_HOTSEAT_FADE, HOTSEAT_FADE);
- config.setInterpolator(ANIM_HOTSEAT_SCALE, HOTSEAT_SCALE);
- config.setInterpolator(ANIM_HOTSEAT_TRANSLATE, HOTSEAT_TRANSLATE);
- config.setInterpolator(ANIM_SCRIM_FADE, SCRIM_FADE);
- config.setInterpolator(ANIM_ALL_APPS_FADE, ALL_APPS_FADE);
- config.setInterpolator(ANIM_VERTICAL_PROGRESS, ALL_APPS_VERTICAL_PROGRESS);
- }
- }
}
diff --git a/src/com/android/launcher3/touch/BaseSwipeDetector.java b/src/com/android/launcher3/touch/BaseSwipeDetector.java
index 52c358143a..1276ece7e2 100644
--- a/src/com/android/launcher3/touch/BaseSwipeDetector.java
+++ b/src/com/android/launcher3/touch/BaseSwipeDetector.java
@@ -17,7 +17,6 @@ package com.android.launcher3.touch;
import static android.view.MotionEvent.INVALID_POINTER_ID;
-import android.content.Context;
import android.graphics.PointF;
import android.util.Log;
import android.view.MotionEvent;
@@ -27,8 +26,6 @@ import android.view.ViewConfiguration;
import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting;
-import com.android.launcher3.R;
-
import java.util.LinkedList;
import java.util.Queue;
@@ -47,9 +44,10 @@ public abstract class BaseSwipeDetector {
private static final boolean DBG = false;
private static final String TAG = "BaseSwipeDetector";
private static final float ANIMATION_DURATION = 1200;
+ /** The minimum release velocity in pixels per millisecond that triggers fling.*/
+ private static final float RELEASE_VELOCITY_PX_MS = 1.0f;
private static final PointF sTempPoint = new PointF();
- private final float mReleaseVelocity;
private final PointF mDownPos = new PointF();
private final PointF mLastPos = new PointF();
protected final boolean mIsRtl;
@@ -66,7 +64,6 @@ public abstract class BaseSwipeDetector {
private boolean mIsSettingState;
protected boolean mIgnoreSlopWhenSettling;
- protected Context mContext;
private enum ScrollState {
IDLE,
@@ -74,14 +71,10 @@ public abstract class BaseSwipeDetector {
SETTLING // onDragEnd
}
- protected BaseSwipeDetector(@NonNull Context context, @NonNull ViewConfiguration config,
- boolean isRtl) {
+ protected BaseSwipeDetector(@NonNull ViewConfiguration config, boolean isRtl) {
mTouchSlop = config.getScaledTouchSlop();
mMaxVelocity = config.getScaledMaximumFlingVelocity();
mIsRtl = isRtl;
- mContext = context;
- mReleaseVelocity = mContext.getResources()
- .getDimensionPixelSize(R.dimen.base_swift_detector_fling_release_velocity);
}
public static long calculateDuration(float velocity, float progressNeeded) {
@@ -127,7 +120,7 @@ public abstract class BaseSwipeDetector {
}
public boolean isFling(float velocity) {
- return Math.abs(velocity) > mReleaseVelocity;
+ return Math.abs(velocity) > RELEASE_VELOCITY_PX_MS;
}
public boolean onTouchEvent(MotionEvent ev) {
@@ -243,7 +236,7 @@ public abstract class BaseSwipeDetector {
} else {
mSubtractDisplacement.x = mDisplacement.x > 0 ? mTouchSlop : -mTouchSlop;
mSubtractDisplacement.y = mDisplacement.y > 0 ? mTouchSlop : -mTouchSlop;
- }
+ }
}
protected abstract boolean shouldScrollStart(PointF displacement);
diff --git a/src/com/android/launcher3/touch/BothAxesSwipeDetector.java b/src/com/android/launcher3/touch/BothAxesSwipeDetector.java
index 6e2f0d86c4..944391e9b4 100644
--- a/src/com/android/launcher3/touch/BothAxesSwipeDetector.java
+++ b/src/com/android/launcher3/touch/BothAxesSwipeDetector.java
@@ -21,6 +21,7 @@ import android.view.MotionEvent;
import android.view.ViewConfiguration;
import androidx.annotation.NonNull;
+import androidx.annotation.VisibleForTesting;
import com.android.launcher3.Utilities;
@@ -42,7 +43,13 @@ public class BothAxesSwipeDetector extends BaseSwipeDetector {
private int mScrollDirections;
public BothAxesSwipeDetector(@NonNull Context context, @NonNull Listener l) {
- super(context, ViewConfiguration.get(context), Utilities.isRtl(context.getResources()));
+ this(ViewConfiguration.get(context), l, Utilities.isRtl(context.getResources()));
+ }
+
+ @VisibleForTesting
+ protected BothAxesSwipeDetector(@NonNull ViewConfiguration config, @NonNull Listener l,
+ boolean isRtl) {
+ super(config, isRtl);
mListener = l;
}
diff --git a/src/com/android/launcher3/touch/ItemClickHandler.java b/src/com/android/launcher3/touch/ItemClickHandler.java
index e95a787cfd..b53f96eea3 100644
--- a/src/com/android/launcher3/touch/ItemClickHandler.java
+++ b/src/com/android/launcher3/touch/ItemClickHandler.java
@@ -17,7 +17,6 @@ package com.android.launcher3.touch;
import static com.android.launcher3.Launcher.REQUEST_BIND_PENDING_APPWIDGET;
import static com.android.launcher3.Launcher.REQUEST_RECONFIGURE_APPWIDGET;
-import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ALLAPPS_SEARCHINAPP_LAUNCH;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_APP_LAUNCH_TAP;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_FOLDER_OPEN;
import static com.android.launcher3.model.data.ItemInfoWithIcon.FLAG_DISABLED_BY_PUBLISHER;
@@ -43,13 +42,10 @@ import android.widget.Toast;
import com.android.launcher3.BubbleTextView;
import com.android.launcher3.Launcher;
-import com.android.launcher3.LauncherSettings;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.folder.Folder;
import com.android.launcher3.folder.FolderIcon;
-import com.android.launcher3.logging.InstanceId;
-import com.android.launcher3.logging.InstanceIdSequence;
import com.android.launcher3.logging.StatsLogManager;
import com.android.launcher3.model.data.AppInfo;
import com.android.launcher3.model.data.FolderInfo;
@@ -59,10 +55,8 @@ import com.android.launcher3.model.data.LauncherAppWidgetInfo;
import com.android.launcher3.model.data.SearchActionItemInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.launcher3.pm.InstallSessionHelper;
-import com.android.launcher3.shortcuts.ShortcutKey;
import com.android.launcher3.testing.TestLogging;
import com.android.launcher3.testing.TestProtocol;
-import com.android.launcher3.util.ItemInfoMatcher;
import com.android.launcher3.util.PackageManagerHelper;
import com.android.launcher3.views.FloatingIconView;
import com.android.launcher3.widget.LauncherAppWidgetProviderInfo;
@@ -70,8 +64,6 @@ import com.android.launcher3.widget.PendingAppWidgetHostView;
import com.android.launcher3.widget.WidgetAddFlowHandler;
import com.android.launcher3.widget.WidgetManagerHelper;
-import java.util.Collections;
-
/**
* Class for handling clicks on workspace and all-apps items
*/
@@ -100,7 +92,8 @@ public class ItemClickHandler {
onClickFolderIcon(v);
}
} else if (tag instanceof AppInfo) {
- startAppShortcutOrInfoActivity(v, (AppInfo) tag, launcher);
+ startAppShortcutOrInfoActivity(v, (AppInfo) tag, launcher
+ );
} else if (tag instanceof LauncherAppWidgetInfo) {
if (v instanceof PendingAppWidgetHostView) {
onClickPendingWidget((PendingAppWidgetHostView) v, launcher);
@@ -175,9 +168,7 @@ public class ItemClickHandler {
(d, i) -> startMarketIntentForPackage(v, launcher, packageName))
.setNeutralButton(R.string.abandoned_clean_this,
(d, i) -> launcher.getWorkspace()
- .persistRemoveItemsByMatcher(ItemInfoMatcher.ofPackages(
- Collections.singleton(packageName), user),
- "user explicitly removes the promise app icon"))
+ .removeAbandonedPromise(packageName, user))
.create().show();
}
@@ -211,12 +202,6 @@ public class ItemClickHandler {
public static boolean handleDisabledItemClicked(WorkspaceItemInfo shortcut, Context context) {
final int disabledFlags = shortcut.runtimeStatusFlags
& WorkspaceItemInfo.FLAG_DISABLED_MASK;
- // Handle the case where the disabled reason is DISABLED_REASON_VERSION_LOWER.
- // Show an AlertDialog for the user to choose either updating the app or cancel the launch.
- if (maybeCreateAlertDialogForShortcut(shortcut, context)) {
- return true;
- }
-
if ((disabledFlags
& ~FLAG_DISABLED_SUSPENDED
& ~FLAG_DISABLED_QUIET_USER) == 0) {
@@ -242,38 +227,6 @@ public class ItemClickHandler {
}
}
- private static boolean maybeCreateAlertDialogForShortcut(final WorkspaceItemInfo shortcut,
- Context context) {
- try {
- final Launcher launcher = Launcher.getLauncher(context);
- if (shortcut.itemType == LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT
- && shortcut.isDisabledVersionLower()) {
-
- new AlertDialog.Builder(context)
- .setTitle(R.string.dialog_update_title)
- .setMessage(R.string.dialog_update_message)
- .setPositiveButton(R.string.dialog_update, (d, i) -> {
- // Direct the user to the play store to update the app
- context.startActivity(shortcut.getMarketIntent(context));
- })
- .setNeutralButton(R.string.dialog_remove, (d, i) -> {
- // Remove the icon if launcher is successfully initialized
- launcher.getWorkspace().persistRemoveItemsByMatcher(ItemInfoMatcher
- .ofShortcutKeys(Collections.singleton(ShortcutKey
- .fromItemInfo(shortcut))),
- "user explicitly removes disabled shortcut");
- })
- .create()
- .show();
- return true;
- }
- } catch (Exception e) {
- Log.e(TAG, "Error creating alert dialog", e);
- }
-
- return false;
- }
-
/**
* Event handler for an app shortcut click.
*
@@ -331,13 +284,7 @@ public class ItemClickHandler {
Toast.LENGTH_SHORT).show();
}
}
- if (itemInfo.hasFlags(SearchActionItemInfo.FLAG_SEARCH_IN_APP)) {
- launcher.getStatsLogManager().logger().withItemInfo(itemInfo).log(
- LAUNCHER_ALLAPPS_SEARCHINAPP_LAUNCH);
- } else {
- launcher.getStatsLogManager().logger().withItemInfo(itemInfo).log(
- LAUNCHER_APP_LAUNCH_TAP);
- }
+ launcher.getStatsLogManager().logger().withItemInfo(itemInfo).log(LAUNCHER_APP_LAUNCH_TAP);
}
private static void startAppShortcutOrInfoActivity(View v, ItemInfo item, Launcher launcher) {
@@ -367,12 +314,6 @@ public class ItemClickHandler {
intent = new Intent(intent);
intent.setPackage(null);
}
- if ((si.options & WorkspaceItemInfo.FLAG_START_FOR_RESULT) != 0) {
- launcher.startActivityForResult(item.getIntent(), 0);
- InstanceId instanceId = new InstanceIdSequence().newInstanceId();
- launcher.logAppLaunch(launcher.getStatsLogManager(), item, instanceId);
- return;
- }
}
if (v != null && launcher.supportsAdaptiveIconAnimation(v)) {
// Preload the icon to reduce latency b/w swapping the floating view with the original.
diff --git a/src/com/android/launcher3/touch/ItemLongClickListener.java b/src/com/android/launcher3/touch/ItemLongClickListener.java
index 6bae745ef8..f876dd9230 100644
--- a/src/com/android/launcher3/touch/ItemLongClickListener.java
+++ b/src/com/android/launcher3/touch/ItemLongClickListener.java
@@ -37,7 +37,6 @@ import com.android.launcher3.logging.StatsLogManager.StatsLogger;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.testing.TestLogging;
import com.android.launcher3.testing.TestProtocol;
-import com.android.launcher3.views.BubbleTextHolder;
/**
* Class to handle long-clicks on workspace items and start drag as a result.
@@ -80,12 +79,9 @@ public class ItemLongClickListener {
launcher.getWorkspace().startDrag(longClickCellInfo, dragOptions);
}
- private static boolean onAllAppsItemLongClick(View view) {
+ private static boolean onAllAppsItemLongClick(View v) {
TestLogging.recordEvent(TestProtocol.SEQUENCE_MAIN, "onAllAppsItemLongClick");
- view.cancelLongPress();
- View v = (view instanceof BubbleTextHolder)
- ? ((BubbleTextHolder) view).getBubbleText()
- : view;
+ v.cancelLongPress();
Launcher launcher = Launcher.getLauncher(v.getContext());
if (!canStartDrag(launcher)) return false;
// When we have exited all apps or are in transition, disregard long clicks
diff --git a/src/com/android/launcher3/touch/LandscapePagedViewHandler.java b/src/com/android/launcher3/touch/LandscapePagedViewHandler.java
index b477905dff..d047eca29e 100644
--- a/src/com/android/launcher3/touch/LandscapePagedViewHandler.java
+++ b/src/com/android/launcher3/touch/LandscapePagedViewHandler.java
@@ -16,13 +16,7 @@
package com.android.launcher3.touch;
-import static android.view.Gravity.BOTTOM;
-import static android.view.Gravity.CENTER_VERTICAL;
-import static android.view.Gravity.END;
-import static android.view.Gravity.START;
-import static android.view.Gravity.TOP;
-import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
-import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
+import static android.widget.ListPopupWindow.WRAP_CONTENT;
import static com.android.launcher3.LauncherAnimUtils.VIEW_TRANSLATE_X;
import static com.android.launcher3.LauncherAnimUtils.VIEW_TRANSLATE_Y;
@@ -37,22 +31,17 @@ import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.ShapeDrawable;
import android.util.FloatProperty;
-import android.util.Pair;
import android.view.MotionEvent;
import android.view.Surface;
import android.view.VelocityTracker;
import android.view.View;
import android.view.accessibility.AccessibilityEvent;
-import android.widget.FrameLayout;
import android.widget.LinearLayout;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
-import com.android.launcher3.util.SplitConfigurationOptions;
import com.android.launcher3.util.SplitConfigurationOptions.SplitPositionOption;
-import com.android.launcher3.util.SplitConfigurationOptions.StagePosition;
-import com.android.launcher3.util.SplitConfigurationOptions.StagedSplitBounds;
import com.android.launcher3.views.BaseDragLayer;
import java.util.Collections;
@@ -103,23 +92,12 @@ public class LandscapePagedViewHandler implements PagedOrientationHandler {
}
@Override
- public void fixBoundsForHomeAnimStartRect(RectF outStartRect, DeviceProfile deviceProfile) {
- // We don't need to check the "top" value here because the startRect is in the orientation
- // of the app, not of the fixed portrait launcher.
- if (outStartRect.left > deviceProfile.heightPx) {
- outStartRect.offsetTo(0, outStartRect.top);
- } else if (outStartRect.left < -deviceProfile.heightPx) {
- outStartRect.offsetTo(0, outStartRect.top);
- }
- }
-
- @Override
- public <T> void setPrimary(T target, Int2DAction<T> action, int param) {
+ public <T> void set(T target, Int2DAction<T> action, int param) {
action.call(target, 0, param);
}
@Override
- public <T> void setPrimary(T target, Float2DAction<T> action, float param) {
+ public <T> void set(T target, Float2DAction<T> action, float param) {
action.call(target, 0, param);
}
@@ -129,12 +107,6 @@ public class LandscapePagedViewHandler implements PagedOrientationHandler {
}
@Override
- public <T> void set(T target, Int2DAction<T> action, int primaryParam,
- int secondaryParam) {
- action.call(target, secondaryParam, primaryParam);
- }
-
- @Override
public float getPrimaryDirection(MotionEvent event, int pointerIndex) {
return event.getY(pointerIndex);
}
@@ -190,6 +162,19 @@ public class LandscapePagedViewHandler implements PagedOrientationHandler {
}
@Override
+ public int getSplitTaskViewDismissDirection(SplitPositionOption splitPosition,
+ DeviceProfile dp) {
+ // Don't use device profile here because we know we're in fake landscape, only split option
+ // available is top/left
+ if (splitPosition.mStagePosition == STAGE_POSITION_TOP_OR_LEFT) {
+ // Top (visually left) side
+ return SPLIT_TRANSLATE_PRIMARY_NEGATIVE;
+ }
+ throw new IllegalStateException("Invalid split stage position: " +
+ splitPosition.mStagePosition);
+ }
+
+ @Override
public int getPrimaryScroll(View view) {
return view.getScrollY();
}
@@ -220,18 +205,13 @@ public class LandscapePagedViewHandler implements PagedOrientationHandler {
}
@Override
- public void setPrimaryScale(View view, float scale) {
- view.setScaleY(scale);
+ public int getChildStart(View view) {
+ return view.getTop();
}
@Override
- public void setSecondaryScale(View view, float scale) {
- view.setScaleX(scale);
- }
-
- @Override
- public int getChildStart(View view) {
- return view.getTop();
+ public float getChildStartWithTranslation(View view) {
+ return view.getTop() + view.getTranslationY();
}
@Override
@@ -250,12 +230,17 @@ public class LandscapePagedViewHandler implements PagedOrientationHandler {
return view.getHeight() - view.getPaddingBottom() - insets.bottom;
}
+ @Override
+ public int getPrimaryTranslationDirectionFactor() {
+ return -1;
+ }
+
public int getSecondaryTranslationDirectionFactor() {
return 1;
}
@Override
- public int getSplitTranslationDirectionFactor(int stagePosition, DeviceProfile deviceProfile) {
+ public int getSplitTranslationDirectionFactor(int stagePosition) {
if (stagePosition == STAGE_POSITION_BOTTOM_OR_RIGHT) {
return -1;
} else {
@@ -264,28 +249,31 @@ public class LandscapePagedViewHandler implements PagedOrientationHandler {
}
@Override
- public float getTaskMenuX(float x, View thumbnailView, int overScroll,
- DeviceProfile deviceProfile) {
+ public int getSplitAnimationTranslation(int translationOffset, DeviceProfile dp) {
+ return translationOffset;
+ }
+
+ @Override
+ public float getTaskMenuX(float x, View thumbnailView, int overScroll) {
return thumbnailView.getMeasuredWidth() + x;
}
@Override
public float getTaskMenuY(float y, View thumbnailView, int overScroll) {
- return y + overScroll +
- (thumbnailView.getMeasuredHeight() - thumbnailView.getMeasuredWidth()) / 2f;
+ return y + overScroll;
}
@Override
- public int getTaskMenuWidth(View view, DeviceProfile deviceProfile) {
- return view.getMeasuredWidth();
+ public int getTaskMenuWidth(View view) {
+ return view.getMeasuredHeight();
}
@Override
public void setTaskOptionsMenuLayoutOrientation(DeviceProfile deviceProfile,
LinearLayout taskMenuLayout, int dividerSpacing,
ShapeDrawable dividerDrawable) {
- taskMenuLayout.setOrientation(LinearLayout.VERTICAL);
- dividerDrawable.setIntrinsicHeight(dividerSpacing);
+ taskMenuLayout.setOrientation(LinearLayout.HORIZONTAL);
+ dividerDrawable.setIntrinsicWidth(dividerSpacing);
taskMenuLayout.setDividerDrawable(dividerDrawable);
}
@@ -293,9 +281,12 @@ public class LandscapePagedViewHandler implements PagedOrientationHandler {
public void setLayoutParamsForTaskMenuOptionItem(LinearLayout.LayoutParams lp,
LinearLayout viewGroup, DeviceProfile deviceProfile) {
// Phone fake landscape
- viewGroup.setOrientation(LinearLayout.HORIZONTAL);
- lp.width = MATCH_PARENT;
+ viewGroup.setOrientation(LinearLayout.VERTICAL);
+ lp.width = 0;
lp.height = WRAP_CONTENT;
+ lp.weight = 1;
+ Utilities.setStartMarginForView(viewGroup.findViewById(R.id.text), 0);
+ Utilities.setStartMarginForView(viewGroup.findViewById(R.id.icon), 0);
}
@Override
@@ -309,49 +300,6 @@ public class LandscapePagedViewHandler implements PagedOrientationHandler {
return new PointF(margin, 0);
}
- @Override
- public Pair<Float, Float> getDwbLayoutTranslations(int taskViewWidth,
- int taskViewHeight, StagedSplitBounds splitBounds, DeviceProfile deviceProfile,
- View[] thumbnailViews, int desiredTaskId, View banner) {
- boolean isRtl = banner.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL;
- float translationX = 0;
- float translationY = 0;
- FrameLayout.LayoutParams bannerParams = (FrameLayout.LayoutParams) banner.getLayoutParams();
- banner.setPivotX(0);
- banner.setPivotY(0);
- banner.setRotation(getDegreesRotated());
- translationX = banner.getHeight();
- FrameLayout.LayoutParams snapshotParams =
- (FrameLayout.LayoutParams) thumbnailViews[0]
- .getLayoutParams();
- bannerParams.gravity = TOP | (isRtl ? END : START);
- if (splitBounds == null) {
- // Single, fullscreen case
- bannerParams.width = taskViewHeight - snapshotParams.topMargin;
- return new Pair<>(translationX, Integer.valueOf(snapshotParams.topMargin).floatValue());
- }
-
- // Set correct width
- if (desiredTaskId == splitBounds.leftTopTaskId) {
- bannerParams.width = thumbnailViews[0].getMeasuredHeight();
- } else {
- bannerParams.width = thumbnailViews[1].getMeasuredHeight();
- }
-
- // Set translations
- if (desiredTaskId == splitBounds.rightBottomTaskId) {
- float topLeftTaskPlusDividerPercent = splitBounds.appsStackedVertically
- ? (splitBounds.topTaskPercent + splitBounds.dividerHeightPercent)
- : (splitBounds.leftTaskPercent + splitBounds.dividerWidthPercent);
- translationY = snapshotParams.topMargin
- + ((taskViewHeight - snapshotParams.topMargin) * topLeftTaskPlusDividerPercent);
- }
- if (desiredTaskId == splitBounds.leftTopTaskId) {
- translationY = snapshotParams.topMargin;
- }
- return new Pair<>(translationX, translationY);
- }
-
/* ---------- The following are only used by TaskViewTouchHandler. ---------- */
@Override
@@ -400,160 +348,13 @@ public class LandscapePagedViewHandler implements PagedOrientationHandler {
public List<SplitPositionOption> getSplitPositionOptions(DeviceProfile dp) {
// Add "left" side of phone which is actually the top
return Collections.singletonList(new SplitPositionOption(
- R.drawable.ic_split_left, R.string.split_screen_position_left,
+ R.drawable.ic_split_screen, R.string.split_screen_position_left,
STAGE_POSITION_TOP_OR_LEFT, STAGE_TYPE_MAIN));
}
@Override
- public void getInitialSplitPlaceholderBounds(int placeholderHeight, int placeholderInset,
- DeviceProfile dp, @StagePosition int stagePosition, Rect out) {
- // In fake land/seascape, the placeholder always needs to go to the "top" of the device,
- // which is the same bounds as 0 rotation.
- int width = dp.widthPx;
- int insetThickness = dp.getInsets().top;
- out.set(0, 0, width, placeholderHeight + insetThickness);
- out.inset(placeholderInset, 0);
-
- // Adjust the top to account for content off screen. This will help to animate the view in
- // with rounded corners.
- int screenWidth = dp.widthPx;
- int screenHeight = dp.heightPx;
- int totalHeight = (int) (1.0f * screenHeight / 2 * (screenWidth - 2 * placeholderInset)
- / screenWidth);
- out.top -= (totalHeight - placeholderHeight);
- }
-
- @Override
- public void updateStagedSplitIconParams(View out, float onScreenRectCenterX,
- float onScreenRectCenterY, float fullscreenScaleX, float fullscreenScaleY,
- int drawableWidth, int drawableHeight, DeviceProfile dp,
- @StagePosition int stagePosition) {
- float inset = dp.getInsets().top;
- out.setX(Math.round(onScreenRectCenterX / fullscreenScaleX
- - 1.0f * drawableWidth / 2));
- out.setY(Math.round((onScreenRectCenterY + (inset / 2f)) / fullscreenScaleY
- - 1.0f * drawableHeight / 2));
- }
-
- @Override
- public void getFinalSplitPlaceholderBounds(int splitDividerSize, DeviceProfile dp,
- @StagePosition int stagePosition, Rect out1, Rect out2) {
- // In fake land/seascape, the window bounds are always top and bottom half
- int screenHeight = dp.heightPx;
- int screenWidth = dp.widthPx;
- out1.set(0, 0, screenWidth, screenHeight / 2 - splitDividerSize);
- out2.set(0, screenHeight / 2 + splitDividerSize, screenWidth, screenHeight);
- }
-
- @Override
- public void setSplitTaskSwipeRect(DeviceProfile dp, Rect outRect,
- StagedSplitBounds splitInfo, int desiredStagePosition) {
- float topLeftTaskPercent = splitInfo.appsStackedVertically
- ? splitInfo.topTaskPercent
- : splitInfo.leftTaskPercent;
- float dividerBarPercent = splitInfo.appsStackedVertically
- ? splitInfo.dividerHeightPercent
- : splitInfo.dividerWidthPercent;
-
- if (desiredStagePosition == SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT) {
- outRect.bottom = outRect.top + (int) (outRect.height() * topLeftTaskPercent);
- } else {
- outRect.top += (int) (outRect.height() * (topLeftTaskPercent + dividerBarPercent));
- }
- }
-
- @Override
- public void measureGroupedTaskViewThumbnailBounds(View primarySnapshot, View secondarySnapshot,
- int parentWidth, int parentHeight, StagedSplitBounds splitBoundsConfig,
- DeviceProfile dp, boolean isRtl) {
- int spaceAboveSnapshot = dp.overviewTaskThumbnailTopMarginPx;
- int totalThumbnailHeight = parentHeight - spaceAboveSnapshot;
- int dividerBar = splitBoundsConfig.appsStackedVertically
- ? splitBoundsConfig.visualDividerBounds.height()
- : splitBoundsConfig.visualDividerBounds.width();
- int primarySnapshotHeight;
- int primarySnapshotWidth;
- int secondarySnapshotHeight;
- int secondarySnapshotWidth;
-
- float taskPercent = splitBoundsConfig.appsStackedVertically ?
- splitBoundsConfig.topTaskPercent : splitBoundsConfig.leftTaskPercent;
- primarySnapshotWidth = parentWidth;
- primarySnapshotHeight = (int) (totalThumbnailHeight * taskPercent);
-
- secondarySnapshotWidth = parentWidth;
- secondarySnapshotHeight = totalThumbnailHeight - primarySnapshotHeight - dividerBar;
- secondarySnapshot.setTranslationY(primarySnapshotHeight + spaceAboveSnapshot + dividerBar);
- primarySnapshot.measure(
- View.MeasureSpec.makeMeasureSpec(primarySnapshotWidth, View.MeasureSpec.EXACTLY),
- View.MeasureSpec.makeMeasureSpec(primarySnapshotHeight, View.MeasureSpec.EXACTLY));
- secondarySnapshot.measure(
- View.MeasureSpec.makeMeasureSpec(secondarySnapshotWidth, View.MeasureSpec.EXACTLY),
- View.MeasureSpec.makeMeasureSpec(secondarySnapshotHeight,
- View.MeasureSpec.EXACTLY));
- }
-
- @Override
- public void setTaskIconParams(FrameLayout.LayoutParams iconParams, int taskIconMargin,
- int taskIconHeight, int thumbnailTopMargin, boolean isRtl) {
- iconParams.gravity = (isRtl ? START : END) | CENTER_VERTICAL;
- iconParams.rightMargin = -taskIconHeight - taskIconMargin / 2;
- iconParams.leftMargin = 0;
- iconParams.topMargin = thumbnailTopMargin / 2;
- }
-
- @Override
- public void setSplitIconParams(View primaryIconView, View secondaryIconView,
- int taskIconHeight, int primarySnapshotWidth, int primarySnapshotHeight,
- int groupedTaskViewHeight, int groupedTaskViewWidth, boolean isRtl,
- DeviceProfile deviceProfile, StagedSplitBounds splitConfig) {
- FrameLayout.LayoutParams primaryIconParams =
- (FrameLayout.LayoutParams) primaryIconView.getLayoutParams();
- FrameLayout.LayoutParams secondaryIconParams =
- new FrameLayout.LayoutParams(primaryIconParams);
-
- // We calculate the "midpoint" of the thumbnail area, and place the icons there.
- // This is the place where the thumbnail area splits by default, in a near-50/50 split.
- // It is usually not exactly 50/50, due to insets/screen cutouts.
- int fullscreenInsetThickness = deviceProfile.getInsets().top;
- int fullscreenMidpointFromBottom = ((deviceProfile.heightPx - fullscreenInsetThickness)
- / 2);
- float midpointFromBottomPct = (float) fullscreenMidpointFromBottom / deviceProfile.heightPx;
- float insetPct = (float) fullscreenInsetThickness / deviceProfile.heightPx;
- int spaceAboveSnapshots = deviceProfile.overviewTaskThumbnailTopMarginPx;
- int overviewThumbnailAreaThickness = groupedTaskViewHeight - spaceAboveSnapshots;
- int bottomToMidpointOffset = (int) (overviewThumbnailAreaThickness * midpointFromBottomPct);
- int insetOffset = (int) (overviewThumbnailAreaThickness * insetPct);
-
- primaryIconParams.gravity = BOTTOM | (isRtl ? START : END);
- secondaryIconParams.gravity = BOTTOM | (isRtl ? START : END);
- primaryIconView.setTranslationX(0);
- secondaryIconView.setTranslationX(0);
- if (splitConfig.initiatedFromSeascape) {
- // if the split was initiated from seascape,
- // the task on the right (secondary) is slightly larger
- primaryIconView.setTranslationY(-bottomToMidpointOffset - insetOffset);
- secondaryIconView.setTranslationY(-bottomToMidpointOffset - insetOffset
- + taskIconHeight);
- } else {
- // if not,
- // the task on the left (primary) is slightly larger
- primaryIconView.setTranslationY(-bottomToMidpointOffset);
- secondaryIconView.setTranslationY(-bottomToMidpointOffset + taskIconHeight);
- }
-
- primaryIconView.setLayoutParams(primaryIconParams);
- secondaryIconView.setLayoutParams(secondaryIconParams);
- }
-
- @Override
- public int getDefaultSplitPosition(DeviceProfile deviceProfile) {
- throw new IllegalStateException("Default position not available in fake landscape");
- }
-
- @Override
- public Pair<FloatProperty, FloatProperty> getSplitSelectTaskOffset(FloatProperty primary,
- FloatProperty secondary, DeviceProfile deviceProfile) {
- return new Pair<>(primary, secondary);
+ public FloatProperty getSplitSelectTaskOffset(FloatProperty primary, FloatProperty secondary,
+ DeviceProfile deviceProfile) {
+ return primary;
}
}
diff --git a/src/com/android/launcher3/touch/PagedOrientationHandler.java b/src/com/android/launcher3/touch/PagedOrientationHandler.java
index ca46aa8a84..266e05fee1 100644
--- a/src/com/android/launcher3/touch/PagedOrientationHandler.java
+++ b/src/com/android/launcher3/touch/PagedOrientationHandler.java
@@ -24,19 +24,15 @@ import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.ShapeDrawable;
import android.util.FloatProperty;
-import android.util.Pair;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.accessibility.AccessibilityEvent;
-import android.widget.FrameLayout;
import android.widget.LinearLayout;
import com.android.launcher3.DeviceProfile;
-import com.android.launcher3.util.SplitConfigurationOptions;
import com.android.launcher3.util.SplitConfigurationOptions.SplitPositionOption;
import com.android.launcher3.util.SplitConfigurationOptions.StagePosition;
-import com.android.launcher3.util.SplitConfigurationOptions.StagedSplitBounds;
import java.util.List;
@@ -47,6 +43,10 @@ import java.util.List;
*/
public interface PagedOrientationHandler {
+ int SPLIT_TRANSLATE_PRIMARY_POSITIVE = 0;
+ int SPLIT_TRANSLATE_PRIMARY_NEGATIVE = 1;
+ int SPLIT_TRANSLATE_SECONDARY_NEGATIVE = 2;
+
PagedOrientationHandler PORTRAIT = new PortraitPagedViewHandler();
PagedOrientationHandler LANDSCAPE = new LandscapePagedViewHandler();
PagedOrientationHandler SEASCAPE = new SeascapePagedViewHandler();
@@ -62,10 +62,9 @@ public interface PagedOrientationHandler {
Float2DAction<Canvas> CANVAS_TRANSLATE = Canvas::translate;
Float2DAction<Matrix> MATRIX_POST_TRANSLATE = Matrix::postTranslate;
- <T> void setPrimary(T target, Int2DAction<T> action, int param);
- <T> void setPrimary(T target, Float2DAction<T> action, float param);
+ <T> void set(T target, Int2DAction<T> action, int param);
+ <T> void set(T target, Float2DAction<T> action, float param);
<T> void setSecondary(T target, Float2DAction<T> action, float param);
- <T> void set(T target, Int2DAction<T> action, int primaryParam, int secondaryParam);
float getPrimaryDirection(MotionEvent event, int pointerIndex);
float getPrimaryVelocity(VelocityTracker velocityTracker, int pointerId);
int getMeasuredSize(View view);
@@ -78,22 +77,28 @@ public interface PagedOrientationHandler {
FloatProperty<View> getPrimaryViewTranslate();
FloatProperty<View> getSecondaryViewTranslate();
+ /**
+ * @param splitPosition The position where the view to be split will go
+ * @return {@link #SPLIT_TRANSLATE_*} constants to indicate which direction the
+ * dismissal should happen
+ */
+ int getSplitTaskViewDismissDirection(SplitPositionOption splitPosition, DeviceProfile dp);
int getPrimaryScroll(View view);
float getPrimaryScale(View view);
int getChildStart(View view);
+ float getChildStartWithTranslation(View view);
int getCenterForPage(View view, Rect insets);
int getScrollOffsetStart(View view, Rect insets);
int getScrollOffsetEnd(View view, Rect insets);
+ int getPrimaryTranslationDirectionFactor();
int getSecondaryTranslationDirectionFactor();
- int getSplitTranslationDirectionFactor(@StagePosition int stagePosition,
- DeviceProfile deviceProfile);
+ int getSplitTranslationDirectionFactor(@StagePosition int stagePosition);
+ int getSplitAnimationTranslation(int translationOffset, DeviceProfile dp);
ChildBounds getChildBounds(View child, int childStart, int pageCenter, boolean layoutChild);
void setMaxScroll(AccessibilityEvent event, int maxScroll);
boolean getRecentsRtlSetting(Resources resources);
float getDegreesRotated();
int getRotation();
- void setPrimaryScale(View view, float scale);
- void setSecondaryScale(View view, float scale);
<T> T getPrimaryValue(T x, T y);
<T> T getSecondaryValue(T x, T y);
@@ -105,78 +110,15 @@ public interface PagedOrientationHandler {
float getSecondaryValue(float x, float y);
boolean isLayoutNaturalToLauncher();
- Pair<FloatProperty, FloatProperty> getSplitSelectTaskOffset(FloatProperty primary,
- FloatProperty secondary, DeviceProfile deviceProfile);
+ FloatProperty getSplitSelectTaskOffset(FloatProperty primary, FloatProperty secondary,
+ DeviceProfile deviceProfile);
int getDistanceToBottomOfRect(DeviceProfile dp, Rect rect);
List<SplitPositionOption> getSplitPositionOptions(DeviceProfile dp);
- /**
- * @param placeholderHeight height of placeholder view in portrait, width in landscape
- */
- void getInitialSplitPlaceholderBounds(int placeholderHeight, int placeholderInset,
- DeviceProfile dp, @StagePosition int stagePosition, Rect out);
-
- /**
- * Centers an icon in the split staging area, accounting for insets.
- * @param out The icon that needs to be centered.
- * @param onScreenRectCenterX The x-center of the on-screen staging area (most of the Rect is
- * offscreen).
- * @param onScreenRectCenterY The y-center of the on-screen staging area (most of the Rect is
- * offscreen).
- * @param fullscreenScaleX A x-scaling factor used to convert coordinates back into pixels.
- * @param fullscreenScaleY A y-scaling factor used to convert coordinates back into pixels.
- * @param drawableWidth The icon's drawable (final) width.
- * @param drawableHeight The icon's drawable (final) height.
- * @param dp The device profile, used to report rotation and hardware insets.
- * @param stagePosition 0 if the staging area is pinned to top/left, 1 for bottom/right.
- */
- void updateStagedSplitIconParams(View out, float onScreenRectCenterX,
- float onScreenRectCenterY, float fullscreenScaleX, float fullscreenScaleY,
- int drawableWidth, int drawableHeight, DeviceProfile dp,
- @StagePosition int stagePosition);
-
- /**
- * @param splitDividerSize height of split screen drag handle in portrait, width in landscape
- * @param stagePosition the split position option (top/left, bottom/right) of the first
- * task selected for entering split
- * @param out1 the bounds for where the first selected app will be
- * @param out2 the bounds for where the second selected app will be, complimentary to
- * {@param out1} based on {@param initialSplitOption}
- */
- void getFinalSplitPlaceholderBounds(int splitDividerSize, DeviceProfile dp,
- @StagePosition int stagePosition, Rect out1, Rect out2);
-
- int getDefaultSplitPosition(DeviceProfile deviceProfile);
-
- /**
- * @param outRect This is expected to be the rect that has the dimensions for a non-split,
- * fullscreen task in overview. This will directly be modified.
- * @param desiredStagePosition Which stage position (topLeft/rightBottom) we want to resize
- * outRect for
- */
- void setSplitTaskSwipeRect(DeviceProfile dp, Rect outRect, StagedSplitBounds splitInfo,
- @SplitConfigurationOptions.StagePosition int desiredStagePosition);
-
- void measureGroupedTaskViewThumbnailBounds(View primarySnapshot, View secondarySnapshot,
- int parentWidth, int parentHeight,
- StagedSplitBounds splitBoundsConfig, DeviceProfile dp, boolean isRtl);
// Overview TaskMenuView methods
- void setTaskIconParams(FrameLayout.LayoutParams iconParams,
- int taskIconMargin, int taskIconHeight, int thumbnailTopMargin, boolean isRtl);
- void setSplitIconParams(View primaryIconView, View secondaryIconView,
- int taskIconHeight, int primarySnapshotWidth, int primarySnapshotHeight,
- int groupedTaskViewHeight, int groupedTaskViewWidth, boolean isRtl,
- DeviceProfile deviceProfile, StagedSplitBounds splitConfig);
-
- /*
- * The following two methods try to center the TaskMenuView in landscape by finding the center
- * of the thumbnail view and then subtracting half of the taskMenu width. In this case, the
- * taskMenu width is the same size as the thumbnail width (what got set below in
- * getTaskMenuWidth()), so we directly use that in the calculations.
- */
- float getTaskMenuX(float x, View thumbnailView, int overScroll, DeviceProfile deviceProfile);
+ float getTaskMenuX(float x, View thumbnailView, int overScroll);
float getTaskMenuY(float y, View thumbnailView, int overScroll);
- int getTaskMenuWidth(View view, DeviceProfile deviceProfile);
+ int getTaskMenuWidth(View view);
/**
* Sets linear layout orientation for {@link com.android.launcher3.popup.SystemShortcut} items
* inside task menu view.
@@ -201,15 +143,6 @@ public interface PagedOrientationHandler {
*/
PointF getAdditionalInsetForTaskMenu(float margin);
- /**
- * Calculates the position where a Digital Wellbeing Banner should be placed on its parent
- * TaskView.
- * @return A Pair of Floats representing the proper x and y translations.
- */
- Pair<Float, Float> getDwbLayoutTranslations(int taskViewWidth,
- int taskViewHeight, StagedSplitBounds splitBounds, DeviceProfile deviceProfile,
- View[] thumbnailViews, int desiredTaskId, View banner);
-
// The following are only used by TaskViewTouchHandler.
/** @return Either VERTICAL or HORIZONTAL. */
SingleAxisSwipeDetector.Direction getUpDownSwipeDirection();
@@ -226,12 +159,6 @@ public interface PagedOrientationHandler {
*/
void adjustFloatingIconStartVelocity(PointF velocity);
- /**
- * Ensures that outStartRect left bound is within the DeviceProfile's visual boundaries
- * @param outStartRect The start rect that will directly be modified
- */
- void fixBoundsForHomeAnimStartRect(RectF outStartRect, DeviceProfile deviceProfile);
-
class ChildBounds {
public final int primaryDimension;
diff --git a/src/com/android/launcher3/touch/PortraitPagedViewHandler.java b/src/com/android/launcher3/touch/PortraitPagedViewHandler.java
index 508823c4d0..dd97af5d76 100644
--- a/src/com/android/launcher3/touch/PortraitPagedViewHandler.java
+++ b/src/com/android/launcher3/touch/PortraitPagedViewHandler.java
@@ -16,51 +16,37 @@
package com.android.launcher3.touch;
-import static android.view.Gravity.BOTTOM;
-import static android.view.Gravity.CENTER_HORIZONTAL;
-import static android.view.Gravity.END;
-import static android.view.Gravity.START;
-import static android.view.Gravity.TOP;
-import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
-import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
-
import static com.android.launcher3.LauncherAnimUtils.VIEW_TRANSLATE_X;
import static com.android.launcher3.LauncherAnimUtils.VIEW_TRANSLATE_Y;
import static com.android.launcher3.touch.SingleAxisSwipeDetector.VERTICAL;
import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_BOTTOM_OR_RIGHT;
import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT;
+import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_TYPE_MAIN;
import android.content.res.Resources;
-import android.graphics.Matrix;
import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.ShapeDrawable;
import android.util.FloatProperty;
-import android.util.Pair;
import android.view.MotionEvent;
import android.view.Surface;
import android.view.VelocityTracker;
import android.view.View;
import android.view.accessibility.AccessibilityEvent;
-import android.widget.FrameLayout;
import android.widget.LinearLayout;
import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.R;
import com.android.launcher3.Utilities;
-import com.android.launcher3.util.SplitConfigurationOptions;
import com.android.launcher3.util.SplitConfigurationOptions.SplitPositionOption;
-import com.android.launcher3.util.SplitConfigurationOptions.StagePosition;
-import com.android.launcher3.util.SplitConfigurationOptions.StagedSplitBounds;
import com.android.launcher3.views.BaseDragLayer;
+import java.util.ArrayList;
import java.util.List;
public class PortraitPagedViewHandler implements PagedOrientationHandler {
- private final Matrix mTmpMatrix = new Matrix();
- private final RectF mTmpRectF = new RectF();
-
@Override
public <T> T getPrimaryValue(T x, T y) {
return x;
@@ -102,21 +88,12 @@ public class PortraitPagedViewHandler implements PagedOrientationHandler {
}
@Override
- public void fixBoundsForHomeAnimStartRect(RectF outStartRect, DeviceProfile deviceProfile) {
- if (outStartRect.left > deviceProfile.widthPx) {
- outStartRect.offsetTo(0, outStartRect.top);
- } else if (outStartRect.left < -deviceProfile.widthPx) {
- outStartRect.offsetTo(0, outStartRect.top);
- }
- }
-
- @Override
- public <T> void setPrimary(T target, Int2DAction<T> action, int param) {
+ public <T> void set(T target, Int2DAction<T> action, int param) {
action.call(target, param, 0);
}
@Override
- public <T> void setPrimary(T target, Float2DAction<T> action, float param) {
+ public <T> void set(T target, Float2DAction<T> action, float param) {
action.call(target, param, 0);
}
@@ -126,12 +103,6 @@ public class PortraitPagedViewHandler implements PagedOrientationHandler {
}
@Override
- public <T> void set(T target, Int2DAction<T> action, int primaryParam,
- int secondaryParam) {
- action.call(target, primaryParam, secondaryParam);
- }
-
- @Override
public float getPrimaryDirection(MotionEvent event, int pointerIndex) {
return event.getX(pointerIndex);
}
@@ -187,6 +158,25 @@ public class PortraitPagedViewHandler implements PagedOrientationHandler {
}
@Override
+ public int getSplitTaskViewDismissDirection(SplitPositionOption splitPosition,
+ DeviceProfile dp) {
+ if (splitPosition.mStagePosition == STAGE_POSITION_TOP_OR_LEFT) {
+ if (dp.isLandscape) {
+ // Left side
+ return SPLIT_TRANSLATE_PRIMARY_NEGATIVE;
+ } else {
+ // Top side
+ return SPLIT_TRANSLATE_SECONDARY_NEGATIVE;
+ }
+ } else if (splitPosition.mStagePosition == STAGE_POSITION_BOTTOM_OR_RIGHT) {
+ // We don't have a bottom option, so should be right
+ return SPLIT_TRANSLATE_PRIMARY_POSITIVE;
+ }
+ throw new IllegalStateException("Invalid split stage position: " +
+ splitPosition.mStagePosition);
+ }
+
+ @Override
public int getPrimaryScroll(View view) {
return view.getScrollX();
}
@@ -217,18 +207,13 @@ public class PortraitPagedViewHandler implements PagedOrientationHandler {
}
@Override
- public void setPrimaryScale(View view, float scale) {
- view.setScaleX(scale);
- }
-
- @Override
- public void setSecondaryScale(View view, float scale) {
- view.setScaleY(scale);
+ public int getChildStart(View view) {
+ return view.getLeft();
}
@Override
- public int getChildStart(View view) {
- return view.getLeft();
+ public float getChildStartWithTranslation(View view) {
+ return view.getLeft() + view.getTranslationX();
}
@Override
@@ -247,13 +232,18 @@ public class PortraitPagedViewHandler implements PagedOrientationHandler {
return view.getWidth() - view.getPaddingRight() - insets.right;
}
+ @Override
+ public int getPrimaryTranslationDirectionFactor() {
+ return 1;
+ }
+
public int getSecondaryTranslationDirectionFactor() {
return -1;
}
@Override
- public int getSplitTranslationDirectionFactor(int stagePosition, DeviceProfile deviceProfile) {
- if (deviceProfile.isLandscape && stagePosition == STAGE_POSITION_BOTTOM_OR_RIGHT) {
+ public int getSplitTranslationDirectionFactor(int stagePosition) {
+ if (stagePosition == STAGE_POSITION_BOTTOM_OR_RIGHT) {
return -1;
} else {
return 1;
@@ -261,14 +251,16 @@ public class PortraitPagedViewHandler implements PagedOrientationHandler {
}
@Override
- public float getTaskMenuX(float x, View thumbnailView, int overScroll,
- DeviceProfile deviceProfile) {
- if (deviceProfile.isLandscape) {
- return x + overScroll
- + (thumbnailView.getMeasuredWidth() - thumbnailView.getMeasuredHeight()) / 2f;
- } else {
- return x + overScroll;
+ public int getSplitAnimationTranslation(int translationOffset, DeviceProfile dp) {
+ if (dp.isLandscape) {
+ return translationOffset;
}
+ return 0;
+ }
+
+ @Override
+ public float getTaskMenuX(float x, View thumbnailView, int overScroll) {
+ return x + overScroll;
}
@Override
@@ -277,27 +269,43 @@ public class PortraitPagedViewHandler implements PagedOrientationHandler {
}
@Override
- public int getTaskMenuWidth(View view, DeviceProfile deviceProfile) {
- return deviceProfile.isLandscape && !deviceProfile.isTablet
- ? view.getMeasuredHeight()
- : view.getMeasuredWidth();
+ public int getTaskMenuWidth(View view) {
+ return view.getMeasuredWidth();
}
@Override
public void setTaskOptionsMenuLayoutOrientation(DeviceProfile deviceProfile,
LinearLayout taskMenuLayout, int dividerSpacing,
ShapeDrawable dividerDrawable) {
- taskMenuLayout.setOrientation(LinearLayout.VERTICAL);
- dividerDrawable.setIntrinsicHeight(dividerSpacing);
+ if (deviceProfile.isLandscape && !deviceProfile.isTablet) {
+ // Phone landscape
+ taskMenuLayout.setOrientation(LinearLayout.HORIZONTAL);
+ dividerDrawable.setIntrinsicWidth(dividerSpacing);
+ } else {
+ // Phone Portrait, LargeScreen Landscape/Portrait
+ taskMenuLayout.setOrientation(LinearLayout.VERTICAL);
+ dividerDrawable.setIntrinsicHeight(dividerSpacing);
+ }
taskMenuLayout.setDividerDrawable(dividerDrawable);
}
@Override
public void setLayoutParamsForTaskMenuOptionItem(LinearLayout.LayoutParams lp,
LinearLayout viewGroup, DeviceProfile deviceProfile) {
- viewGroup.setOrientation(LinearLayout.HORIZONTAL);
- lp.width = LinearLayout.LayoutParams.MATCH_PARENT;
- lp.height = WRAP_CONTENT;
+ if (deviceProfile.isLandscape && !deviceProfile.isTablet) {
+ // Phone landscape
+ viewGroup.setOrientation(LinearLayout.VERTICAL);
+ lp.width = 0;
+ lp.weight = 1;
+ Utilities.setStartMarginForView(viewGroup.findViewById(R.id.text), 0);
+ Utilities.setStartMarginForView(viewGroup.findViewById(R.id.icon), 0);
+ } else {
+ // Phone Portrait, LargeScreen Landscape/Portrait
+ viewGroup.setOrientation(LinearLayout.HORIZONTAL);
+ lp.width = LinearLayout.LayoutParams.MATCH_PARENT;
+ }
+
+ lp.height = LinearLayout.LayoutParams.WRAP_CONTENT;
}
@Override
@@ -312,59 +320,6 @@ public class PortraitPagedViewHandler implements PagedOrientationHandler {
return new PointF(0, 0);
}
- @Override
- public Pair<Float, Float> getDwbLayoutTranslations(int taskViewWidth,
- int taskViewHeight, StagedSplitBounds splitBounds, DeviceProfile deviceProfile,
- View[] thumbnailViews, int desiredTaskId, View banner) {
- float translationX = 0;
- float translationY = 0;
- FrameLayout.LayoutParams bannerParams = (FrameLayout.LayoutParams) banner.getLayoutParams();
- banner.setPivotX(0);
- banner.setPivotY(0);
- banner.setRotation(getDegreesRotated());
- if (splitBounds == null) {
- // Single, fullscreen case
- bannerParams.width = MATCH_PARENT;
- bannerParams.gravity = BOTTOM | CENTER_HORIZONTAL;
- return new Pair<>(translationX, translationY);
- }
-
- bannerParams.gravity = BOTTOM | ((deviceProfile.isLandscape) ? START : CENTER_HORIZONTAL);
-
- // Set correct width
- if (desiredTaskId == splitBounds.leftTopTaskId) {
- bannerParams.width = thumbnailViews[0].getMeasuredWidth();
- } else {
- bannerParams.width = thumbnailViews[1].getMeasuredWidth();
- }
-
- // Set translations
- if (deviceProfile.isLandscape) {
- if (desiredTaskId == splitBounds.rightBottomTaskId) {
- float leftTopTaskPercent = splitBounds.appsStackedVertically
- ? splitBounds.topTaskPercent
- : splitBounds.leftTaskPercent;
- float dividerThicknessPercent = splitBounds.appsStackedVertically
- ? splitBounds.dividerHeightPercent
- : splitBounds.dividerWidthPercent;
- translationX = ((taskViewWidth * leftTopTaskPercent)
- + (taskViewWidth * dividerThicknessPercent));
- }
- } else {
- if (desiredTaskId == splitBounds.leftTopTaskId) {
- FrameLayout.LayoutParams snapshotParams =
- (FrameLayout.LayoutParams) thumbnailViews[0]
- .getLayoutParams();
- float bottomRightTaskPlusDividerPercent = splitBounds.appsStackedVertically
- ? (1f - splitBounds.topTaskPercent)
- : (1f - splitBounds.leftTaskPercent);
- translationY = -((taskViewHeight - snapshotParams.topMargin)
- * bottomRightTaskPlusDividerPercent);
- }
- }
- return new Pair<>(translationX, translationY);
- }
-
/* ---------- The following are only used by TaskViewTouchHandler. ---------- */
@Override
@@ -412,293 +367,43 @@ public class PortraitPagedViewHandler implements PagedOrientationHandler {
@Override
public List<SplitPositionOption> getSplitPositionOptions(DeviceProfile dp) {
- return Utilities.getSplitPositionOptions(dp);
- }
-
- @Override
- public void getInitialSplitPlaceholderBounds(int placeholderHeight, int placeholderInset,
- DeviceProfile dp, @StagePosition int stagePosition, Rect out) {
- int screenWidth = dp.widthPx;
- int screenHeight = dp.heightPx;
- boolean pinToRight = stagePosition == STAGE_POSITION_BOTTOM_OR_RIGHT;
- int insetThickness;
- if (!dp.isLandscape) {
- insetThickness = dp.getInsets().top;
- } else {
- insetThickness = pinToRight ? dp.getInsets().right : dp.getInsets().left;
- }
- out.set(0, 0, screenWidth, placeholderHeight + insetThickness);
- if (!dp.isLandscape) {
- // portrait, phone or tablet - spans width of screen, nothing else to do
- out.inset(placeholderInset, 0);
-
- // Adjust the top to account for content off screen. This will help to animate the view
- // in with rounded corners.
- int totalHeight = (int) (1.0f * screenHeight / 2 * (screenWidth - 2 * placeholderInset)
- / screenWidth);
- out.top -= (totalHeight - placeholderHeight);
- return;
- }
-
- // Now we rotate the portrait rect depending on what side we want pinned
-
- float postRotateScale = (float) screenHeight / screenWidth;
- mTmpMatrix.reset();
- mTmpMatrix.postRotate(pinToRight ? 90 : 270);
- mTmpMatrix.postTranslate(pinToRight ? screenWidth : 0, pinToRight ? 0 : screenWidth);
- // The placeholder height stays constant after rotation, so we don't change width scale
- mTmpMatrix.postScale(1, postRotateScale);
-
- mTmpRectF.set(out);
- mTmpMatrix.mapRect(mTmpRectF);
- mTmpRectF.inset(0, placeholderInset);
- mTmpRectF.roundOut(out);
-
- // Adjust the top to account for content off screen. This will help to animate the view in
- // with rounded corners.
- int totalWidth = (int) (1.0f * screenWidth / 2 * (screenHeight - 2 * placeholderInset)
- / screenHeight);
- int width = out.width();
- if (pinToRight) {
- out.right += totalWidth - width;
- } else {
- out.left -= totalWidth - width;
- }
- }
-
- @Override
- public void updateStagedSplitIconParams(View out, float onScreenRectCenterX,
- float onScreenRectCenterY, float fullscreenScaleX, float fullscreenScaleY,
- int drawableWidth, int drawableHeight, DeviceProfile dp,
- @StagePosition int stagePosition) {
- boolean pinToRight = stagePosition == STAGE_POSITION_BOTTOM_OR_RIGHT;
- if (!dp.isLandscape) {
- float inset = dp.getInsets().top;
- out.setX(Math.round(onScreenRectCenterX / fullscreenScaleX
- - 1.0f * drawableWidth / 2));
- out.setY(Math.round((onScreenRectCenterY + (inset / 2f)) / fullscreenScaleY
- - 1.0f * drawableHeight / 2));
- } else {
- if (pinToRight) {
- float inset = dp.getInsets().right;
- out.setX(Math.round((onScreenRectCenterX - (inset / 2f)) / fullscreenScaleX
- - 1.0f * drawableWidth / 2));
- } else {
- float inset = dp.getInsets().left;
- out.setX(Math.round((onScreenRectCenterX + (inset / 2f)) / fullscreenScaleX
- - 1.0f * drawableWidth / 2));
- }
- out.setY(Math.round(onScreenRectCenterY / fullscreenScaleY
- - 1.0f * drawableHeight / 2));
- }
- }
-
- @Override
- public void getFinalSplitPlaceholderBounds(int splitDividerSize, DeviceProfile dp,
- @StagePosition int stagePosition, Rect out1, Rect out2) {
- int screenHeight = dp.heightPx;
- int screenWidth = dp.widthPx;
- out1.set(0, 0, screenWidth, screenHeight / 2 - splitDividerSize);
- out2.set(0, screenHeight / 2 + splitDividerSize, screenWidth, screenHeight);
- if (!dp.isLandscape) {
- // Portrait - the window bounds are always top and bottom half
- return;
- }
-
- // Now we rotate the portrait rect depending on what side we want pinned
- boolean pinToRight = stagePosition == STAGE_POSITION_BOTTOM_OR_RIGHT;
- float postRotateScale = (float) screenHeight / screenWidth;
-
- mTmpMatrix.reset();
- mTmpMatrix.postRotate(pinToRight ? 90 : 270);
- mTmpMatrix.postTranslate(pinToRight ? screenHeight : 0, pinToRight ? 0 : screenWidth);
- mTmpMatrix.postScale(1 / postRotateScale, postRotateScale);
-
- mTmpRectF.set(out1);
- mTmpMatrix.mapRect(mTmpRectF);
- mTmpRectF.roundOut(out1);
-
- mTmpRectF.set(out2);
- mTmpMatrix.mapRect(mTmpRectF);
- mTmpRectF.roundOut(out2);
- }
-
- @Override
- public void setSplitTaskSwipeRect(DeviceProfile dp, Rect outRect,
- StagedSplitBounds splitInfo, int desiredStagePosition) {
- boolean isLandscape = dp.isLandscape;
- float topLeftTaskPercent = splitInfo.appsStackedVertically
- ? splitInfo.topTaskPercent
- : splitInfo.leftTaskPercent;
- float dividerBarPercent = splitInfo.appsStackedVertically
- ? splitInfo.dividerHeightPercent
- : splitInfo.dividerWidthPercent;
-
- if (desiredStagePosition == SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT) {
- if (isLandscape) {
- outRect.right = outRect.left + (int) (outRect.width() * topLeftTaskPercent);
- } else {
- outRect.bottom = outRect.top + (int) (outRect.height() * topLeftTaskPercent);
- }
+ List<SplitPositionOption> options = new ArrayList<>(1);
+ // Add both left and right options if we're in tablet mode
+ // TODO: Add in correct icons
+ if (dp.isTablet && dp.isLandscape) {
+ options.add(new SplitPositionOption(
+ R.drawable.ic_split_screen, R.string.split_screen_position_right,
+ STAGE_POSITION_BOTTOM_OR_RIGHT, STAGE_TYPE_MAIN));
+ options.add(new SplitPositionOption(
+ R.drawable.ic_split_screen, R.string.split_screen_position_left,
+ STAGE_POSITION_TOP_OR_LEFT, STAGE_TYPE_MAIN));
} else {
- if (isLandscape) {
- outRect.left += (int) (outRect.width() * (topLeftTaskPercent + dividerBarPercent));
- } else {
- outRect.top += (int) (outRect.height() * (topLeftTaskPercent + dividerBarPercent));
- }
- }
- }
-
- @Override
- public void measureGroupedTaskViewThumbnailBounds(View primarySnapshot, View secondarySnapshot,
- int parentWidth, int parentHeight, StagedSplitBounds splitBoundsConfig,
- DeviceProfile dp, boolean isRtl) {
- int spaceAboveSnapshot = dp.overviewTaskThumbnailTopMarginPx;
- int totalThumbnailHeight = parentHeight - spaceAboveSnapshot;
- int dividerBar = splitBoundsConfig.appsStackedVertically
- ? (int) (splitBoundsConfig.dividerHeightPercent * parentHeight)
- : (int) (splitBoundsConfig.dividerWidthPercent * parentWidth);
- int primarySnapshotHeight;
- int primarySnapshotWidth;
- int secondarySnapshotHeight;
- int secondarySnapshotWidth;
- float taskPercent = splitBoundsConfig.appsStackedVertically ?
- splitBoundsConfig.topTaskPercent : splitBoundsConfig.leftTaskPercent;
- if (dp.isLandscape) {
- primarySnapshotHeight = totalThumbnailHeight;
- primarySnapshotWidth = (int) (parentWidth * taskPercent);
-
- secondarySnapshotHeight = totalThumbnailHeight;
- secondarySnapshotWidth = parentWidth - primarySnapshotWidth - dividerBar;
- int translationX = primarySnapshotWidth + dividerBar;
- if (isRtl) {
- primarySnapshot.setTranslationX(-translationX);
- secondarySnapshot.setTranslationX(0);
+ if (dp.isSeascape()) {
+ // Add left/right options
+ options.add(new SplitPositionOption(
+ R.drawable.ic_split_screen, R.string.split_screen_position_right,
+ STAGE_POSITION_BOTTOM_OR_RIGHT, STAGE_TYPE_MAIN));
+ } else if (dp.isLandscape) {
+ options.add(new SplitPositionOption(
+ R.drawable.ic_split_screen, R.string.split_screen_position_left,
+ STAGE_POSITION_TOP_OR_LEFT, STAGE_TYPE_MAIN));
} else {
- secondarySnapshot.setTranslationX(translationX);
- primarySnapshot.setTranslationX(0);
+ // Only add top option
+ options.add(new SplitPositionOption(
+ R.drawable.ic_split_screen, R.string.split_screen_position_top,
+ STAGE_POSITION_TOP_OR_LEFT, STAGE_TYPE_MAIN));
}
- secondarySnapshot.setTranslationY(spaceAboveSnapshot);
- } else {
- primarySnapshotWidth = parentWidth;
- primarySnapshotHeight = (int) (totalThumbnailHeight * taskPercent);
-
- secondarySnapshotWidth = parentWidth;
- secondarySnapshotHeight = totalThumbnailHeight - primarySnapshotHeight - dividerBar;
- int translationY = primarySnapshotHeight + spaceAboveSnapshot + dividerBar;
- secondarySnapshot.setTranslationY(translationY);
- secondarySnapshot.setTranslationX(0);
- primarySnapshot.setTranslationX(0);
- }
- primarySnapshot.measure(
- View.MeasureSpec.makeMeasureSpec(primarySnapshotWidth, View.MeasureSpec.EXACTLY),
- View.MeasureSpec.makeMeasureSpec(primarySnapshotHeight, View.MeasureSpec.EXACTLY));
- secondarySnapshot.measure(
- View.MeasureSpec.makeMeasureSpec(secondarySnapshotWidth, View.MeasureSpec.EXACTLY),
- View.MeasureSpec.makeMeasureSpec(secondarySnapshotHeight,
- View.MeasureSpec.EXACTLY));
- }
-
- @Override
- public void setTaskIconParams(FrameLayout.LayoutParams iconParams, int taskIconMargin,
- int taskIconHeight, int thumbnailTopMargin, boolean isRtl) {
- iconParams.gravity = TOP | CENTER_HORIZONTAL;
- iconParams.leftMargin = iconParams.rightMargin = 0;
- iconParams.topMargin = taskIconMargin;
- }
-
- @Override
- public void setSplitIconParams(View primaryIconView, View secondaryIconView,
- int taskIconHeight, int primarySnapshotWidth, int primarySnapshotHeight,
- int groupedTaskViewHeight, int groupedTaskViewWidth, boolean isRtl,
- DeviceProfile deviceProfile, StagedSplitBounds splitConfig) {
- FrameLayout.LayoutParams primaryIconParams =
- (FrameLayout.LayoutParams) primaryIconView.getLayoutParams();
- FrameLayout.LayoutParams secondaryIconParams =
- new FrameLayout.LayoutParams(primaryIconParams);
-
- if (deviceProfile.isLandscape) {
- // We calculate the "midpoint" of the thumbnail area, and place the icons there.
- // This is the place where the thumbnail area splits by default, in a near-50/50 split.
- // It is usually not exactly 50/50, due to insets/screen cutouts.
- int fullscreenInsetThickness = deviceProfile.isSeascape()
- ? deviceProfile.getInsets().right
- : deviceProfile.getInsets().left;
- int fullscreenMidpointFromBottom = ((deviceProfile.widthPx
- - fullscreenInsetThickness) / 2);
- float midpointFromBottomPct = (float) fullscreenMidpointFromBottom
- / deviceProfile.widthPx;
- float insetPct = (float) fullscreenInsetThickness / deviceProfile.widthPx;
- int spaceAboveSnapshots = 0;
- int overviewThumbnailAreaThickness = groupedTaskViewWidth - spaceAboveSnapshots;
- int bottomToMidpointOffset = (int) (overviewThumbnailAreaThickness
- * midpointFromBottomPct);
- int insetOffset = (int) (overviewThumbnailAreaThickness * insetPct);
-
- if (deviceProfile.isSeascape()) {
- primaryIconParams.gravity = TOP | (isRtl ? END : START);
- secondaryIconParams.gravity = TOP | (isRtl ? END : START);
- if (splitConfig.initiatedFromSeascape) {
- // if the split was initiated from seascape,
- // the task on the right (secondary) is slightly larger
- primaryIconView.setTranslationX(bottomToMidpointOffset - taskIconHeight);
- secondaryIconView.setTranslationX(bottomToMidpointOffset);
- } else {
- // if not,
- // the task on the left (primary) is slightly larger
- primaryIconView.setTranslationX(bottomToMidpointOffset + insetOffset
- - taskIconHeight);
- secondaryIconView.setTranslationX(bottomToMidpointOffset + insetOffset);
- }
- } else {
- primaryIconParams.gravity = TOP | (isRtl ? START : END);
- secondaryIconParams.gravity = TOP | (isRtl ? START : END);
- if (!splitConfig.initiatedFromSeascape) {
- // if the split was initiated from landscape,
- // the task on the left (primary) is slightly larger
- primaryIconView.setTranslationX(-bottomToMidpointOffset);
- secondaryIconView.setTranslationX(-bottomToMidpointOffset + taskIconHeight);
- } else {
- // if not,
- // the task on the right (secondary) is slightly larger
- primaryIconView.setTranslationX(-bottomToMidpointOffset - insetOffset);
- secondaryIconView.setTranslationX(-bottomToMidpointOffset - insetOffset
- + taskIconHeight);
- }
- }
- } else {
- primaryIconParams.gravity = TOP | CENTER_HORIZONTAL;
- // shifts icon half a width left (height is used here since icons are square)
- primaryIconView.setTranslationX(-(taskIconHeight / 2f));
- secondaryIconParams.gravity = TOP | CENTER_HORIZONTAL;
- secondaryIconView.setTranslationX(taskIconHeight / 2f);
- }
- primaryIconView.setTranslationY(0);
- secondaryIconView.setTranslationY(0);
-
- primaryIconView.setLayoutParams(primaryIconParams);
- secondaryIconView.setLayoutParams(secondaryIconParams);
- }
-
- @Override
- public int getDefaultSplitPosition(DeviceProfile deviceProfile) {
- if (!deviceProfile.isTablet) {
- throw new IllegalStateException("Default position available only for large screens");
- }
- if (deviceProfile.isLandscape) {
- return STAGE_POSITION_BOTTOM_OR_RIGHT;
- } else {
- return STAGE_POSITION_TOP_OR_LEFT;
}
+ return options;
}
@Override
- public Pair<FloatProperty, FloatProperty> getSplitSelectTaskOffset(FloatProperty primary,
- FloatProperty secondary, DeviceProfile deviceProfile) {
- if (deviceProfile.isLandscape) { // or seascape
- return new Pair<>(primary, secondary);
+ public FloatProperty getSplitSelectTaskOffset(FloatProperty primary, FloatProperty secondary,
+ DeviceProfile dp) {
+ if (dp.isLandscape) { // or seascape
+ return primary;
} else {
- return new Pair<>(secondary, primary);
+ return secondary;
}
}
}
diff --git a/src/com/android/launcher3/touch/SeascapePagedViewHandler.java b/src/com/android/launcher3/touch/SeascapePagedViewHandler.java
index 74b6a5b28e..91d44bd29c 100644
--- a/src/com/android/launcher3/touch/SeascapePagedViewHandler.java
+++ b/src/com/android/launcher3/touch/SeascapePagedViewHandler.java
@@ -16,29 +16,22 @@
package com.android.launcher3.touch;
-import static android.view.Gravity.BOTTOM;
-import static android.view.Gravity.CENTER_VERTICAL;
-import static android.view.Gravity.END;
-import static android.view.Gravity.START;
-
import static com.android.launcher3.touch.SingleAxisSwipeDetector.HORIZONTAL;
import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_BOTTOM_OR_RIGHT;
+import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT;
import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_TYPE_MAIN;
import android.content.res.Resources;
import android.graphics.PointF;
import android.graphics.Rect;
-import android.util.Pair;
import android.view.Surface;
import android.view.View;
-import android.widget.FrameLayout;
import android.widget.LinearLayout;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.util.SplitConfigurationOptions.SplitPositionOption;
-import com.android.launcher3.util.SplitConfigurationOptions.StagedSplitBounds;
import com.android.launcher3.views.BaseDragLayer;
import java.util.Collections;
@@ -52,7 +45,7 @@ public class SeascapePagedViewHandler extends LandscapePagedViewHandler {
}
@Override
- public int getSplitTranslationDirectionFactor(int stagePosition, DeviceProfile deviceProfile) {
+ public int getSplitTranslationDirectionFactor(int stagePosition) {
if (stagePosition == STAGE_POSITION_BOTTOM_OR_RIGHT) {
return -1;
} else {
@@ -61,6 +54,11 @@ public class SeascapePagedViewHandler extends LandscapePagedViewHandler {
}
@Override
+ public int getSplitAnimationTranslation(int translationOffset, DeviceProfile dp) {
+ return translationOffset;
+ }
+
+ @Override
public boolean getRecentsRtlSetting(Resources resources) {
return Utilities.isRtl(resources);
}
@@ -83,15 +81,13 @@ public class SeascapePagedViewHandler extends LandscapePagedViewHandler {
}
@Override
- public float getTaskMenuX(float x, View thumbnailView, int overScroll,
- DeviceProfile deviceProfile) {
+ public float getTaskMenuX(float x, View thumbnailView, int overScroll) {
return x;
}
@Override
public float getTaskMenuY(float y, View thumbnailView, int overScroll) {
- return y + overScroll +
- (thumbnailView.getMeasuredHeight() + thumbnailView.getMeasuredWidth()) / 2f;
+ return y + thumbnailView.getMeasuredHeight() + overScroll;
}
@Override
@@ -105,54 +101,6 @@ public class SeascapePagedViewHandler extends LandscapePagedViewHandler {
return new PointF(-margin, margin);
}
-
-
- @Override
- public Pair<Float, Float> getDwbLayoutTranslations(int taskViewWidth,
- int taskViewHeight, StagedSplitBounds splitBounds, DeviceProfile deviceProfile,
- View[] thumbnailViews, int desiredTaskId, View banner) {
- boolean isRtl = banner.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL;
- float translationX = 0;
- float translationY = 0;
- FrameLayout.LayoutParams bannerParams = (FrameLayout.LayoutParams) banner.getLayoutParams();
- banner.setPivotX(0);
- banner.setPivotY(0);
- banner.setRotation(getDegreesRotated());
- translationX = taskViewWidth - banner.getHeight();
- FrameLayout.LayoutParams snapshotParams =
- (FrameLayout.LayoutParams) thumbnailViews[0]
- .getLayoutParams();
- bannerParams.gravity = BOTTOM | (isRtl ? END : START);
-
- if (splitBounds == null) {
- // Single, fullscreen case
- bannerParams.width = taskViewHeight - snapshotParams.topMargin;
- translationY = banner.getHeight();
- return new Pair<>(translationX, translationY);
- }
-
- // Set correct width
- if (desiredTaskId == splitBounds.leftTopTaskId) {
- bannerParams.width = thumbnailViews[0].getMeasuredHeight();
- } else {
- bannerParams.width = thumbnailViews[1].getMeasuredHeight();
- }
-
- // Set translations
- if (desiredTaskId == splitBounds.rightBottomTaskId) {
- translationY = banner.getHeight();
- }
- if (desiredTaskId == splitBounds.leftTopTaskId) {
- float bottomRightTaskPlusDividerPercent = splitBounds.appsStackedVertically
- ? (1f - splitBounds.topTaskPercent)
- : (1f - splitBounds.leftTaskPercent);
- translationY = banner.getHeight()
- - ((taskViewHeight - snapshotParams.topMargin)
- * bottomRightTaskPlusDividerPercent);
- }
- return new Pair<>(translationX, translationY);
- }
-
@Override
public int getDistanceToBottomOfRect(DeviceProfile dp, Rect rect) {
return dp.widthPx - rect.right;
@@ -162,64 +110,8 @@ public class SeascapePagedViewHandler extends LandscapePagedViewHandler {
public List<SplitPositionOption> getSplitPositionOptions(DeviceProfile dp) {
// Add "right" option which is actually the top
return Collections.singletonList(new SplitPositionOption(
- R.drawable.ic_split_right, R.string.split_screen_position_right,
- STAGE_POSITION_BOTTOM_OR_RIGHT, STAGE_TYPE_MAIN));
- }
-
- @Override
- public void setTaskIconParams(FrameLayout.LayoutParams iconParams,
- int taskIconMargin, int taskIconHeight, int thumbnailTopMargin, boolean isRtl) {
- iconParams.gravity = (isRtl ? END : START) | CENTER_VERTICAL;
- iconParams.leftMargin = -taskIconHeight - taskIconMargin / 2;
- iconParams.rightMargin = 0;
- iconParams.topMargin = thumbnailTopMargin / 2;
- }
-
- @Override
- public void setSplitIconParams(View primaryIconView, View secondaryIconView,
- int taskIconHeight, int primarySnapshotWidth, int primarySnapshotHeight,
- int groupedTaskViewHeight, int groupedTaskViewWidth, boolean isRtl,
- DeviceProfile deviceProfile, StagedSplitBounds splitConfig) {
- super.setSplitIconParams(primaryIconView, secondaryIconView, taskIconHeight,
- primarySnapshotWidth, primarySnapshotHeight, groupedTaskViewHeight,
- groupedTaskViewWidth, isRtl, deviceProfile, splitConfig);
- FrameLayout.LayoutParams primaryIconParams =
- (FrameLayout.LayoutParams) primaryIconView.getLayoutParams();
- FrameLayout.LayoutParams secondaryIconParams =
- (FrameLayout.LayoutParams) secondaryIconView.getLayoutParams();
-
- // We calculate the "midpoint" of the thumbnail area, and place the icons there.
- // This is the place where the thumbnail area splits by default, in a near-50/50 split.
- // It is usually not exactly 50/50, due to insets/screen cutouts.
- int fullscreenInsetThickness = deviceProfile.getInsets().top;
- int fullscreenMidpointFromBottom = ((deviceProfile.heightPx
- - fullscreenInsetThickness) / 2);
- float midpointFromBottomPct = (float) fullscreenMidpointFromBottom / deviceProfile.heightPx;
- float insetPct = (float) fullscreenInsetThickness / deviceProfile.heightPx;
- int spaceAboveSnapshots = deviceProfile.overviewTaskThumbnailTopMarginPx;
- int overviewThumbnailAreaThickness = groupedTaskViewHeight - spaceAboveSnapshots;
- int bottomToMidpointOffset = (int) (overviewThumbnailAreaThickness * midpointFromBottomPct);
- int insetOffset = (int) (overviewThumbnailAreaThickness * insetPct);
-
- primaryIconParams.gravity = BOTTOM | (isRtl ? END : START);
- secondaryIconParams.gravity = BOTTOM | (isRtl ? END : START);
- primaryIconView.setTranslationX(0);
- secondaryIconView.setTranslationX(0);
- if (splitConfig.initiatedFromSeascape) {
- // if the split was initiated from seascape,
- // the task on the right (secondary) is slightly larger
- primaryIconView.setTranslationY(-bottomToMidpointOffset - insetOffset);
- secondaryIconView.setTranslationY(-bottomToMidpointOffset - insetOffset
- + taskIconHeight);
- } else {
- // if not,
- // the task on the left (primary) is slightly larger
- primaryIconView.setTranslationY(-bottomToMidpointOffset);
- secondaryIconView.setTranslationY(-bottomToMidpointOffset + taskIconHeight);
- }
-
- primaryIconView.setLayoutParams(primaryIconParams);
- secondaryIconView.setLayoutParams(secondaryIconParams);
+ R.drawable.ic_split_screen, R.string.split_screen_position_right,
+ STAGE_POSITION_TOP_OR_LEFT, STAGE_TYPE_MAIN));
}
/* ---------- The following are only used by TaskViewTouchHandler. ---------- */
diff --git a/src/com/android/launcher3/touch/SingleAxisSwipeDetector.java b/src/com/android/launcher3/touch/SingleAxisSwipeDetector.java
index 5c599c06bf..f751b7d505 100644
--- a/src/com/android/launcher3/touch/SingleAxisSwipeDetector.java
+++ b/src/com/android/launcher3/touch/SingleAxisSwipeDetector.java
@@ -106,15 +106,13 @@ public class SingleAxisSwipeDetector extends BaseSwipeDetector {
public SingleAxisSwipeDetector(@NonNull Context context, @NonNull Listener l,
@NonNull Direction dir) {
- super(context, ViewConfiguration.get(context), Utilities.isRtl(context.getResources()));
- mListener = l;
- mDir = dir;
+ this(ViewConfiguration.get(context), l, dir, Utilities.isRtl(context.getResources()));
}
@VisibleForTesting
- protected SingleAxisSwipeDetector(@NonNull Context context, @NonNull ViewConfiguration config,
- @NonNull Listener l, @NonNull Direction dir, boolean isRtl) {
- super(context, config, isRtl);
+ protected SingleAxisSwipeDetector(@NonNull ViewConfiguration config, @NonNull Listener l,
+ @NonNull Direction dir, boolean isRtl) {
+ super(config, isRtl);
mListener = l;
mDir = dir;
}
diff --git a/src/com/android/launcher3/touch/WorkspaceTouchListener.java b/src/com/android/launcher3/touch/WorkspaceTouchListener.java
index 17bbdf1769..4fa658e7d5 100644
--- a/src/com/android/launcher3/touch/WorkspaceTouchListener.java
+++ b/src/com/android/launcher3/touch/WorkspaceTouchListener.java
@@ -21,9 +21,7 @@ import static android.view.MotionEvent.ACTION_MOVE;
import static android.view.MotionEvent.ACTION_POINTER_UP;
import static android.view.MotionEvent.ACTION_UP;
-import static com.android.launcher3.LauncherState.ALL_APPS;
import static com.android.launcher3.LauncherState.NORMAL;
-import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ALLAPPS_CLOSE_TAP_OUTSIDE;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_WORKSPACE_LONGPRESS;
import android.graphics.PointF;
@@ -41,9 +39,9 @@ import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Launcher;
import com.android.launcher3.Workspace;
import com.android.launcher3.dragndrop.DragLayer;
-import com.android.launcher3.logger.LauncherAtom;
import com.android.launcher3.testing.TestLogging;
import com.android.launcher3.testing.TestProtocol;
+import com.android.launcher3.views.OptionsPopupView;
/**
* Helper class to handle touch on empty space in workspace and show options popup on long press
@@ -64,7 +62,7 @@ public class WorkspaceTouchListener extends GestureDetector.SimpleOnGestureListe
private final Rect mTempRect = new Rect();
private final Launcher mLauncher;
- private final Workspace<?> mWorkspace;
+ private final Workspace mWorkspace;
private final PointF mTouchDownPoint = new PointF();
private final float mTouchSlop;
@@ -72,7 +70,7 @@ public class WorkspaceTouchListener extends GestureDetector.SimpleOnGestureListe
private final GestureDetector mGestureDetector;
- public WorkspaceTouchListener(Launcher launcher, Workspace<?> workspace) {
+ public WorkspaceTouchListener(Launcher launcher, Workspace workspace) {
mLauncher = launcher;
mWorkspace = workspace;
// Use twice the touch slop as we are looking for long press which is more
@@ -121,9 +119,6 @@ public class WorkspaceTouchListener extends GestureDetector.SimpleOnGestureListe
mLongPressState = STATE_COMPLETED;
}
- boolean isInAllAppsBottomSheet = mLauncher.isInState(ALL_APPS)
- && mLauncher.getDeviceProfile().isTablet;
-
final boolean result;
if (mLongPressState == STATE_COMPLETED) {
// We have handled the touch, so workspace does not need to know anything anymore.
@@ -139,9 +134,8 @@ public class WorkspaceTouchListener extends GestureDetector.SimpleOnGestureListe
result = true;
} else {
- // We don't want to handle touch unless we're in AllApps bottom sheet, let workspace
- // handle it as usual.
- result = isInAllAppsBottomSheet;
+ // We don't want to handle touch, let workspace handle it as usual.
+ result = false;
}
if (action == ACTION_UP || action == ACTION_POINTER_UP) {
@@ -157,19 +151,6 @@ public class WorkspaceTouchListener extends GestureDetector.SimpleOnGestureListe
if (action == ACTION_UP || action == ACTION_CANCEL) {
cancelLongPress();
}
- if (action == ACTION_UP && isInAllAppsBottomSheet) {
- mLauncher.getStateManager().goToState(NORMAL);
- mLauncher.getStatsLogManager().logger()
- .withSrcState(ALL_APPS.statsLogOrdinal)
- .withDstState(NORMAL.statsLogOrdinal)
- .withContainerInfo(LauncherAtom.ContainerInfo.newBuilder()
- .setWorkspace(
- LauncherAtom.WorkspaceContainer.newBuilder()
- .setPageIndex(
- mLauncher.getWorkspace().getCurrentPage()))
- .build())
- .log(LAUNCHER_ALLAPPS_CLOSE_TAP_OUTSIDE);
- }
return result;
}
@@ -194,7 +175,7 @@ public class WorkspaceTouchListener extends GestureDetector.SimpleOnGestureListe
mWorkspace.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS,
HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);
mLauncher.getStatsLogManager().logger().log(LAUNCHER_WORKSPACE_LONGPRESS);
- mLauncher.showDefaultOptions(mTouchDownPoint.x, mTouchDownPoint.y);
+ OptionsPopupView.showDefaultOptions(mLauncher, mTouchDownPoint.x, mTouchDownPoint.y);
} else {
cancelLongPress();
}
diff --git a/src/com/android/launcher3/util/ActivityLifecycleCallbacksAdapter.java b/src/com/android/launcher3/util/ActivityLifecycleCallbacksAdapter.java
deleted file mode 100644
index baa8418242..0000000000
--- a/src/com/android/launcher3/util/ActivityLifecycleCallbacksAdapter.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package com.android.launcher3.util;
-
-import android.app.Activity;
-import android.app.Application.ActivityLifecycleCallbacks;
-import android.os.Bundle;
-
-public interface ActivityLifecycleCallbacksAdapter extends ActivityLifecycleCallbacks {
-
- default void onActivityCreated(Activity activity, Bundle bundle) {
- }
-
- default void onActivityDestroyed(Activity activity) {
- }
-
- default void onActivityPaused(Activity activity) {
- }
-
- default void onActivityResumed(Activity activity) {
- }
-
- default void onActivitySaveInstanceState(Activity activity, Bundle bundle) {
- }
-
- default void onActivityStarted(Activity activity) {
- }
-
- default void onActivityStopped(Activity activity) {
- }
-}
diff --git a/src/com/android/launcher3/util/DisplayController.java b/src/com/android/launcher3/util/DisplayController.java
index 7c73be51c6..e2c0a32bb0 100644
--- a/src/com/android/launcher3/util/DisplayController.java
+++ b/src/com/android/launcher3/util/DisplayController.java
@@ -15,45 +15,37 @@
*/
package com.android.launcher3.util;
-import static android.content.Intent.ACTION_CONFIGURATION_CHANGED;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
-import static com.android.launcher3.ResourceUtils.INVALID_RESOURCE_HANDLE;
import static com.android.launcher3.Utilities.dpiFromPx;
-import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_NAVIGATION_MODE_2_BUTTON;
-import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_NAVIGATION_MODE_3_BUTTON;
-import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_NAVIGATION_MODE_GESTURE_BUTTON;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
-import static com.android.launcher3.util.PackageManagerHelper.getPackageFilter;
-import static com.android.launcher3.util.window.WindowManagerProxy.MIN_TABLET_WIDTH;
+import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
+import static com.android.launcher3.util.WindowManagerCompat.MIN_TABLET_WIDTH;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.content.ComponentCallbacks;
import android.content.Context;
import android.content.Intent;
+import android.content.IntentFilter;
import android.content.res.Configuration;
import android.graphics.Point;
-import android.graphics.Rect;
import android.hardware.display.DisplayManager;
+import android.hardware.display.DisplayManager.DisplayListener;
import android.os.Build;
-import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.Log;
-import android.util.Pair;
import android.view.Display;
+import android.view.WindowMetrics;
import androidx.annotation.AnyThread;
import androidx.annotation.UiThread;
+import androidx.annotation.WorkerThread;
-import com.android.launcher3.ResourceUtils;
import com.android.launcher3.Utilities;
-import com.android.launcher3.logging.StatsLogManager.LauncherEvent;
-import com.android.launcher3.util.window.CachedDisplayInfo;
-import com.android.launcher3.util.window.WindowManagerProxy;
+import com.android.launcher3.uioverrides.ApiWrapper;
-import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Objects;
@@ -63,7 +55,7 @@ import java.util.Set;
* Utility class to cache properties of default display to avoid a system RPC on every call.
*/
@SuppressLint("NewApi")
-public class DisplayController implements ComponentCallbacks, SafeCloseable {
+public class DisplayController implements DisplayListener, ComponentCallbacks {
private static final String TAG = "DisplayController";
@@ -72,16 +64,12 @@ public class DisplayController implements ComponentCallbacks, SafeCloseable {
public static final int CHANGE_ACTIVE_SCREEN = 1 << 0;
public static final int CHANGE_ROTATION = 1 << 1;
- public static final int CHANGE_DENSITY = 1 << 2;
- public static final int CHANGE_SUPPORTED_BOUNDS = 1 << 3;
- public static final int CHANGE_NAVIGATION_MODE = 1 << 4;
+ public static final int CHANGE_FRAME_DELAY = 1 << 2;
+ public static final int CHANGE_DENSITY = 1 << 3;
+ public static final int CHANGE_SUPPORTED_BOUNDS = 1 << 4;
public static final int CHANGE_ALL = CHANGE_ACTIVE_SCREEN | CHANGE_ROTATION
- | CHANGE_DENSITY | CHANGE_SUPPORTED_BOUNDS | CHANGE_NAVIGATION_MODE;
-
- private static final String ACTION_OVERLAY_CHANGED = "android.intent.action.OVERLAY_CHANGED";
- private static final String NAV_BAR_INTERACTION_MODE_RES_NAME = "config_navBarInteractionMode";
- private static final String TARGET_OVERLAY_PACKAGE = "android";
+ | CHANGE_FRAME_DELAY | CHANGE_DENSITY | CHANGE_SUPPORTED_BOUNDS;
private final Context mContext;
private final DisplayManager mDM;
@@ -89,14 +77,8 @@ public class DisplayController implements ComponentCallbacks, SafeCloseable {
// Null for SDK < S
private final Context mWindowContext;
- // The callback in this listener updates DeviceProfile, which other listeners might depend on
- private DisplayInfoChangeListener mPriorityListener;
private final ArrayList<DisplayInfoChangeListener> mListeners = new ArrayList<>();
-
- private final SimpleBroadcastReceiver mReceiver = new SimpleBroadcastReceiver(this::onIntent);
-
private Info mInfo;
- private boolean mDestroyed = false;
private DisplayController(Context context) {
mContext = context;
@@ -108,33 +90,53 @@ public class DisplayController implements ComponentCallbacks, SafeCloseable {
mWindowContext.registerComponentCallbacks(this);
} else {
mWindowContext = null;
- mReceiver.register(mContext, ACTION_CONFIGURATION_CHANGED);
+ SimpleBroadcastReceiver configChangeReceiver =
+ new SimpleBroadcastReceiver(this::onConfigChanged);
+ mContext.registerReceiver(configChangeReceiver,
+ new IntentFilter(Intent.ACTION_CONFIGURATION_CHANGED));
}
- // Initialize navigation mode change listener
- mContext.registerReceiver(mReceiver,
- getPackageFilter(TARGET_OVERLAY_PACKAGE, ACTION_OVERLAY_CHANGED));
-
- WindowManagerProxy wmProxy = WindowManagerProxy.INSTANCE.get(context);
- mInfo = new Info(getDisplayInfoContext(display), display,
- wmProxy, wmProxy.estimateInternalDisplayBounds(context));
+ // Create a single holder for all internal displays. External display holders created
+ // lazily.
+ Set<PortraitSize> extraInternalDisplays = new ArraySet<>();
+ for (Display d : mDM.getDisplays()) {
+ if (ApiWrapper.isInternalDisplay(display) && d.getDisplayId() != DEFAULT_DISPLAY) {
+ Point size = new Point();
+ d.getRealSize(size);
+ extraInternalDisplays.add(new PortraitSize(size.x, size.y));
+ }
+ }
+ mInfo = new Info(getDisplayInfoContext(display), display, extraInternalDisplays);
+ mDM.registerDisplayListener(this, UI_HELPER_EXECUTOR.getHandler());
}
- /**
- * Returns the current navigation mode
- */
- public static NavigationMode getNavigationMode(Context context) {
- return INSTANCE.get(context).getInfo().navigationMode;
- }
+ @Override
+ public final void onDisplayAdded(int displayId) { }
@Override
- public void close() {
- mDestroyed = true;
- if (mWindowContext != null) {
- mWindowContext.unregisterComponentCallbacks(this);
- } else {
- // TODO: unregister broadcast receiver
+ public final void onDisplayRemoved(int displayId) { }
+
+ @WorkerThread
+ @Override
+ public final void onDisplayChanged(int displayId) {
+ if (displayId != DEFAULT_DISPLAY) {
+ return;
+ }
+ Display display = mDM.getDisplay(DEFAULT_DISPLAY);
+ if (display == null) {
+ return;
+ }
+ if (Utilities.ATLEAST_S) {
+ // Only check for refresh rate. Everything else comes from component callbacks
+ if (getSingleFrameMs(display) == mInfo.singleFrameMs) {
+ return;
+ }
}
+ handleInfoChange(display);
+ }
+
+ public static int getSingleFrameMs(Context context) {
+ return INSTANCE.get(context).getInfo().singleFrameMs;
}
/**
@@ -151,20 +153,12 @@ public class DisplayController implements ComponentCallbacks, SafeCloseable {
void onDisplayInfoChanged(Context context, Info info, int flags);
}
- private void onIntent(Intent intent) {
- if (mDestroyed) {
- return;
- }
- boolean reconfigure = false;
- if (ACTION_OVERLAY_CHANGED.equals(intent.getAction())) {
- reconfigure = true;
- } else if (ACTION_CONFIGURATION_CHANGED.equals(intent.getAction())) {
- Configuration config = mContext.getResources().getConfiguration();
- reconfigure = mInfo.fontScale != config.fontScale
- || mInfo.densityDpi != config.densityDpi;
- }
-
- if (reconfigure) {
+ /**
+ * Only used for pre-S
+ */
+ private void onConfigChanged(Intent intent) {
+ Configuration config = mContext.getResources().getConfiguration();
+ if (mInfo.fontScale != config.fontScale || mInfo.densityDpi != config.densityDpi) {
Log.d(TAG, "Configuration changed, notifying listeners");
Display display = mDM.getDisplay(DEFAULT_DISPLAY);
if (display != null) {
@@ -190,10 +184,6 @@ public class DisplayController implements ComponentCallbacks, SafeCloseable {
@Override
public final void onLowMemory() { }
- public void setPriorityListener(DisplayInfoChangeListener listener) {
- mPriorityListener = listener;
- }
-
public void addChangeListener(DisplayInfoChangeListener listener) {
mListeners.add(listener);
}
@@ -212,54 +202,27 @@ public class DisplayController implements ComponentCallbacks, SafeCloseable {
@AnyThread
private void handleInfoChange(Display display) {
- WindowManagerProxy wmProxy = WindowManagerProxy.INSTANCE.get(mContext);
Info oldInfo = mInfo;
+ Set<PortraitSize> extraDisplaysSizes = oldInfo.mAllSizes.size() > 1
+ ? oldInfo.mAllSizes : Collections.emptySet();
Context displayContext = getDisplayInfoContext(display);
- Info newInfo = new Info(displayContext, display, wmProxy, oldInfo.mPerDisplayBounds);
-
- if (newInfo.densityDpi != oldInfo.densityDpi || newInfo.fontScale != oldInfo.fontScale
- || newInfo.navigationMode != oldInfo.navigationMode) {
- // Cache may not be valid anymore, recreate without cache
- newInfo = new Info(displayContext, display, wmProxy,
- wmProxy.estimateInternalDisplayBounds(displayContext));
- }
-
+ Info newInfo = new Info(displayContext, display, extraDisplaysSizes);
int change = 0;
- if (!newInfo.displayId.equals(oldInfo.displayId)) {
+ if (!newInfo.mScreenSizeDp.equals(oldInfo.mScreenSizeDp)) {
change |= CHANGE_ACTIVE_SCREEN;
}
if (newInfo.rotation != oldInfo.rotation) {
change |= CHANGE_ROTATION;
}
+ if (newInfo.singleFrameMs != oldInfo.singleFrameMs) {
+ change |= CHANGE_FRAME_DELAY;
+ }
if (newInfo.densityDpi != oldInfo.densityDpi || newInfo.fontScale != oldInfo.fontScale) {
change |= CHANGE_DENSITY;
}
- if (newInfo.navigationMode != oldInfo.navigationMode) {
- change |= CHANGE_NAVIGATION_MODE;
- }
if (!newInfo.supportedBounds.equals(oldInfo.supportedBounds)) {
change |= CHANGE_SUPPORTED_BOUNDS;
-
- Point currentS = newInfo.currentSize;
- Pair<CachedDisplayInfo, WindowBounds[]> cachedBounds =
- oldInfo.mPerDisplayBounds.get(newInfo.displayId);
- Point expectedS = cachedBounds == null ? null : cachedBounds.first.size;
- if (newInfo.supportedBounds.size() != oldInfo.supportedBounds.size()) {
- Log.e("b/198965093",
- "Inconsistent number of displays"
- + "\ndisplay state: " + display.getState()
- + "\noldInfo.supportedBounds: " + oldInfo.supportedBounds
- + "\nnewInfo.supportedBounds: " + newInfo.supportedBounds);
- }
- if (expectedS != null
- && (Math.min(currentS.x, currentS.y) != Math.min(expectedS.x, expectedS.y)
- || Math.max(currentS.x, currentS.y) != Math.max(expectedS.x, expectedS.y))
- && display.getState() == Display.STATE_OFF) {
- Log.e("b/198965093",
- "Display size changed while display is off, ignoring change");
- return;
- }
}
if (change != 0) {
@@ -270,115 +233,80 @@ public class DisplayController implements ComponentCallbacks, SafeCloseable {
}
private void notifyChange(Context context, int flags) {
- if (mPriorityListener != null) {
- mPriorityListener.onDisplayInfoChanged(context, mInfo, flags);
- }
-
- int count = mListeners.size();
- for (int i = 0; i < count; i++) {
+ for (int i = mListeners.size() - 1; i >= 0; i--) {
mListeners.get(i).onDisplayInfoChanged(context, mInfo, flags);
}
}
public static class Info {
- // Cached property
- public final int rotation;
- public final String displayId;
- public final Point currentSize;
- public final Rect cutout;
+ public final int id;
+ public final int singleFrameMs;
- // Configuration property
+ // Configuration properties
+ public final int rotation;
public final float fontScale;
- private final int densityDpi;
- public final NavigationMode navigationMode;
+ public final int densityDpi;
private final PortraitSize mScreenSizeDp;
+ private final Set<PortraitSize> mAllSizes;
- public final Set<WindowBounds> supportedBounds = new ArraySet<>();
+ public final Point currentSize;
- private final ArrayMap<String, Pair<CachedDisplayInfo, WindowBounds[]>> mPerDisplayBounds =
- new ArrayMap<>();
+ public final Set<WindowBounds> supportedBounds = new ArraySet<>();
public Info(Context context, Display display) {
- /* don't need system overrides for external displays */
- this(context, display, new WindowManagerProxy(), new ArrayMap<>());
+ this(context, display, Collections.emptySet());
}
- // Used for testing
- public Info(Context context, Display display,
- WindowManagerProxy wmProxy,
- ArrayMap<String, Pair<CachedDisplayInfo, WindowBounds[]>> perDisplayBoundsCache) {
- CachedDisplayInfo displayInfo = wmProxy.getDisplayInfo(context, display);
- rotation = displayInfo.rotation;
- currentSize = displayInfo.size;
- displayId = displayInfo.id;
- cutout = displayInfo.cutout;
+ private Info(Context context, Display display, Set<PortraitSize> extraDisplaysSizes) {
+ id = display.getDisplayId();
+
+ rotation = display.getRotation();
Configuration config = context.getResources().getConfiguration();
fontScale = config.fontScale;
densityDpi = config.densityDpi;
mScreenSizeDp = new PortraitSize(config.screenHeightDp, config.screenWidthDp);
- navigationMode = parseNavigationMode(context);
- mPerDisplayBounds.putAll(perDisplayBoundsCache);
- Pair<CachedDisplayInfo, WindowBounds[]> cachedValue = mPerDisplayBounds.get(displayId);
+ singleFrameMs = getSingleFrameMs(display);
+ currentSize = new Point();
+
+ display.getRealSize(currentSize);
- WindowBounds realBounds = wmProxy.getRealBounds(context, display, displayInfo);
- if (cachedValue == null) {
- supportedBounds.add(realBounds);
+ if (extraDisplaysSizes.isEmpty() || !Utilities.ATLEAST_S) {
+ Point smallestSize = new Point();
+ Point largestSize = new Point();
+ display.getCurrentSizeRange(smallestSize, largestSize);
+
+ int portraitWidth = Math.min(currentSize.x, currentSize.y);
+ int portraitHeight = Math.max(currentSize.x, currentSize.y);
+
+ supportedBounds.add(new WindowBounds(portraitWidth, portraitHeight,
+ smallestSize.x, largestSize.y));
+ supportedBounds.add(new WindowBounds(portraitHeight, portraitWidth,
+ largestSize.x, smallestSize.y));
+ mAllSizes = Collections.singleton(new PortraitSize(currentSize.x, currentSize.y));
} else {
- // Verify that the real bounds are a match
- WindowBounds expectedBounds = cachedValue.second[displayInfo.rotation];
- if (!realBounds.equals(expectedBounds)) {
- WindowBounds[] clone = new WindowBounds[4];
- System.arraycopy(cachedValue.second, 0, clone, 0, 4);
- clone[displayInfo.rotation] = realBounds;
- cachedValue = Pair.create(displayInfo.normalize(), clone);
- mPerDisplayBounds.put(displayId, cachedValue);
- }
+ mAllSizes = new ArraySet<>(extraDisplaysSizes);
+ mAllSizes.add(new PortraitSize(currentSize.x, currentSize.y));
+ Set<WindowMetrics> metrics = WindowManagerCompat.getDisplayProfiles(
+ context, mAllSizes, densityDpi,
+ ApiWrapper.TASKBAR_DRAWN_IN_PROCESS);
+ metrics.forEach(wm -> supportedBounds.add(WindowBounds.fromWindowMetrics(wm)));
}
- mPerDisplayBounds.values().forEach(
- pair -> Collections.addAll(supportedBounds, pair.second));
- Log.d("b/211775278", "displayId: " + displayId + ", currentSize: " + currentSize);
- Log.d("b/211775278", "perDisplayBounds: " + mPerDisplayBounds);
}
/**
- * Returns {@code true} if the bounds represent a tablet.
+ * Returns true if the bounds represent a tablet
*/
public boolean isTablet(WindowBounds bounds) {
- return smallestSizeDp(bounds) >= MIN_TABLET_WIDTH;
- }
-
- /**
- * Returns smallest size in dp for given bounds.
- */
- public float smallestSizeDp(WindowBounds bounds) {
- return dpiFromPx(Math.min(bounds.bounds.width(), bounds.bounds.height()), densityDpi);
- }
-
- public int getDensityDpi() {
- return densityDpi;
+ return dpiFromPx(Math.min(bounds.bounds.width(), bounds.bounds.height()),
+ densityDpi) >= MIN_TABLET_WIDTH;
}
}
/**
- * Dumps the current state information
- */
- public void dump(PrintWriter pw) {
- Info info = mInfo;
- pw.println("DisplayController.Info:");
- pw.println(" id=" + info.displayId);
- pw.println(" rotation=" + info.rotation);
- pw.println(" fontScale=" + info.fontScale);
- pw.println(" densityDpi=" + info.densityDpi);
- pw.println(" navigationMode=" + info.navigationMode.name());
- pw.println(" currentSize=" + info.currentSize);
- pw.println(" supportedBounds=" + info.supportedBounds);
- }
-
- /**
* Utility class to hold a size information in an orientation independent way
*/
public static class PortraitSize {
@@ -403,35 +331,8 @@ public class DisplayController implements ComponentCallbacks, SafeCloseable {
}
}
- public enum NavigationMode {
- THREE_BUTTONS(false, 0, LAUNCHER_NAVIGATION_MODE_3_BUTTON),
- TWO_BUTTONS(true, 1, LAUNCHER_NAVIGATION_MODE_2_BUTTON),
- NO_BUTTON(true, 2, LAUNCHER_NAVIGATION_MODE_GESTURE_BUTTON);
-
- public final boolean hasGestures;
- public final int resValue;
- public final LauncherEvent launcherEvent;
-
- NavigationMode(boolean hasGestures, int resValue, LauncherEvent launcherEvent) {
- this.hasGestures = hasGestures;
- this.resValue = resValue;
- this.launcherEvent = launcherEvent;
- }
- }
-
- private static NavigationMode parseNavigationMode(Context context) {
- int modeInt = ResourceUtils.getIntegerByName(NAV_BAR_INTERACTION_MODE_RES_NAME,
- context.getResources(), INVALID_RESOURCE_HANDLE);
-
- if (modeInt == INVALID_RESOURCE_HANDLE) {
- Log.e(TAG, "Failed to get system resource ID. Incompatible framework version?");
- } else {
- for (NavigationMode m : NavigationMode.values()) {
- if (m.resValue == modeInt) {
- return m;
- }
- }
- }
- return Utilities.ATLEAST_S ? NavigationMode.NO_BUTTON : NavigationMode.THREE_BUTTONS;
+ private static int getSingleFrameMs(Display display) {
+ float refreshRate = display.getRefreshRate();
+ return refreshRate > 0 ? (int) (1000 / refreshRate) : 16;
}
}
diff --git a/src/com/android/launcher3/util/Executors.java b/src/com/android/launcher3/util/Executors.java
index 6978e0c2a4..6329540dc2 100644
--- a/src/com/android/launcher3/util/Executors.java
+++ b/src/com/android/launcher3/util/Executors.java
@@ -19,8 +19,6 @@ import android.os.HandlerThread;
import android.os.Looper;
import android.os.Process;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
@@ -36,9 +34,6 @@ public class Executors {
Math.max(Runtime.getRuntime().availableProcessors(), 2);
private static final int KEEP_ALIVE = 1;
- /** Dedicated executor instances for work depending on other packages. */
- private static final Map<String, LooperExecutor> PACKAGE_EXECUTORS = new ConcurrentHashMap<>();
-
/**
* An {@link ThreadPoolExecutor} to be used with async task with no limit on the queue size.
*/
@@ -81,17 +76,6 @@ public class Executors {
new LooperExecutor(createAndStartNewLooper("launcher-loader"));
/**
- * Returns and caches a single thread executor for a given package.
- *
- * @param packageName Package associated with the executor.
- */
- public static LooperExecutor getPackageExecutor(String packageName) {
- return PACKAGE_EXECUTORS.computeIfAbsent(
- packageName, p -> new LooperExecutor(
- createAndStartNewLooper(p, Process.THREAD_PRIORITY_DEFAULT)));
- }
-
- /**
* A simple ThreadFactory to set the thread name and priority when used with executors.
*/
public static class SimpleThreadFactory implements ThreadFactory {
diff --git a/src/com/android/launcher3/util/FlagOp.java b/src/com/android/launcher3/util/FlagOp.java
new file mode 100644
index 0000000000..bd40eb9fa8
--- /dev/null
+++ b/src/com/android/launcher3/util/FlagOp.java
@@ -0,0 +1,16 @@
+package com.android.launcher3.util;
+
+public interface FlagOp {
+
+ FlagOp NO_OP = i -> i;
+
+ int apply(int flags);
+
+ static FlagOp addFlag(int flag) {
+ return i -> i | flag;
+ }
+
+ static FlagOp removeFlag(int flag) {
+ return i -> i & ~flag;
+ }
+}
diff --git a/src/com/android/launcher3/util/FlingAnimation.java b/src/com/android/launcher3/util/FlingAnimation.java
index ac864e91b3..c9aa51c0de 100644
--- a/src/com/android/launcher3/util/FlingAnimation.java
+++ b/src/com/android/launcher3/util/FlingAnimation.java
@@ -1,14 +1,12 @@
package com.android.launcher3.util;
import static com.android.launcher3.LauncherState.NORMAL;
-import static com.android.launcher3.anim.AnimatorListeners.forEndCallback;
import android.animation.TimeInterpolator;
import android.animation.ValueAnimator;
import android.animation.ValueAnimator.AnimatorUpdateListener;
import android.graphics.PointF;
import android.graphics.Rect;
-import android.graphics.RectF;
import android.view.animation.AnimationUtils;
import android.view.animation.DecelerateInterpolator;
@@ -37,7 +35,7 @@ public class FlingAnimation implements AnimatorUpdateListener, Runnable {
protected final float mUX, mUY;
protected Rect mIconRect;
- protected RectF mFrom;
+ protected Rect mFrom;
protected int mDuration;
protected float mAnimationTimeFraction;
@@ -57,17 +55,17 @@ public class FlingAnimation implements AnimatorUpdateListener, Runnable {
@Override
public void run() {
mIconRect = mDropTarget.getIconRect(mDragObject);
- mDragObject.dragView.cancelAnimation();
- mDragObject.dragView.requestLayout();
// Initiate from
- Rect from = new Rect();
- mDragLayer.getViewRectRelativeToSelf(mDragObject.dragView, from);
-
- mFrom = new RectF(from);
- mFrom.inset(
- ((1 - mDragObject.dragView.getScaleX()) * from.width()) / 2f,
- ((1 - mDragObject.dragView.getScaleY()) * from.height()) / 2f);
+ mFrom = new Rect();
+ mDragLayer.getViewRectRelativeToSelf(mDragObject.dragView, mFrom);
+ float scale = mDragObject.dragView.getScaleX();
+ float xOffset = ((scale - 1f) * mDragObject.dragView.getMeasuredWidth()) / 2f;
+ float yOffset = ((scale - 1f) * mDragObject.dragView.getMeasuredHeight()) / 2f;
+ mFrom.left += xOffset;
+ mFrom.right -= xOffset;
+ mFrom.top += yOffset;
+ mFrom.bottom -= yOffset;
mDuration = Math.abs(mUY) > Math.abs(mUX) ? initFlingUpDuration() : initFlingLeftDuration();
mAnimationTimeFraction = ((float) mDuration) / (mDuration + DRAG_END_DELAY);
@@ -97,15 +95,17 @@ public class FlingAnimation implements AnimatorUpdateListener, Runnable {
}
};
+ Runnable onAnimationEndRunnable = new Runnable() {
+ @Override
+ public void run() {
+ mLauncher.getStateManager().goToState(NORMAL);
+ mDropTarget.completeDrop(mDragObject);
+ }
+ };
+
mDropTarget.onDrop(mDragObject, mDragOptions);
- ValueAnimator anim = ValueAnimator.ofFloat(0, 1);
- anim.setDuration(duration).setInterpolator(tInterpolator);
- anim.addUpdateListener(this);
- anim.addListener(forEndCallback(() -> {
- mLauncher.getStateManager().goToState(NORMAL);
- mDropTarget.completeDrop(mDragObject);
- }));
- mDragLayer.playDropAnimation(mDragObject.dragView, anim, DragLayer.ANIMATION_END_DISAPPEAR);
+ mDragLayer.animateView(mDragObject.dragView, this, duration, tInterpolator,
+ onAnimationEndRunnable, DragLayer.ANIMATION_END_DISAPPEAR, null);
}
/**
@@ -129,7 +129,7 @@ public class FlingAnimation implements AnimatorUpdateListener, Runnable {
}
double t = (-mUY - Math.sqrt(d)) / mAY;
- float sX = -mFrom.centerX() + mIconRect.exactCenterX();
+ float sX = -mFrom.exactCenterX() + mIconRect.exactCenterX();
// Find horizontal acceleration such that: u*t + a*t*t/2 = s
mAX = (float) ((sX - t * mUX) * 2 / (t * t));
@@ -157,7 +157,7 @@ public class FlingAnimation implements AnimatorUpdateListener, Runnable {
}
double t = (-mUX - Math.sqrt(d)) / mAX;
- float sY = -mFrom.centerY() + mIconRect.exactCenterY();
+ float sY = -mFrom.exactCenterY() + mIconRect.exactCenterY();
// Find vertical acceleration such that: u*t + a*t*t/2 = s
mAY = (float) ((sY - t * mUY) * 2 / (t * t));
diff --git a/src/com/android/launcher3/util/GridOccupancy.java b/src/com/android/launcher3/util/GridOccupancy.java
index 13014608c4..9c752a7043 100644
--- a/src/com/android/launcher3/util/GridOccupancy.java
+++ b/src/com/android/launcher3/util/GridOccupancy.java
@@ -7,7 +7,7 @@ import com.android.launcher3.model.data.ItemInfo;
/**
* Utility object to manage the occupancy in a grid.
*/
-public class GridOccupancy extends AbsGridOccupancy {
+public class GridOccupancy {
private final int mCountX;
private final int mCountY;
@@ -30,7 +30,24 @@ public class GridOccupancy extends AbsGridOccupancy {
* @return true if a vacant cell was found
*/
public boolean findVacantCell(int[] vacantOut, int spanX, int spanY) {
- return super.findVacantCell(vacantOut, cells, mCountX, mCountY, spanX, spanY);
+ for (int y = 0; (y + spanY) <= mCountY; y++) {
+ for (int x = 0; (x + spanX) <= mCountX; x++) {
+ boolean available = !cells[x][y];
+ out:
+ for (int i = x; i < x + spanX; i++) {
+ for (int j = y; j < y + spanY; j++) {
+ available = available && !cells[i][j];
+ if (!available) break out;
+ }
+ }
+ if (available) {
+ vacantOut[0] = x;
+ vacantOut[1] = y;
+ return true;
+ }
+ }
+ }
+ return false;
}
public void copyTo(GridOccupancy dest) {
diff --git a/src/com/android/launcher3/util/HorizontalInsettableView.java b/src/com/android/launcher3/util/HorizontalInsettableView.java
deleted file mode 100644
index 7979bc0f25..0000000000
--- a/src/com/android/launcher3/util/HorizontalInsettableView.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2021 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.launcher3.util;
-
-/**
- * Allows the implementing view to add insets to the left and right.
- */
-public interface HorizontalInsettableView {
-
- /**
- * Sets left and right insets for the view so it looks like the width of the view is
- * reduced when inset is increased.
- *
- * The inset is calculated based on the width of the view: e.g. when the width of
- * the view is 100px then if we apply 0.15f horizontal inset percentage the rendered width
- * of the view will be 70px with 15px of padding on the left and right sides.
- *
- * @param insetPercentage width percentage to inset the content from the left and from the right
- */
- void setHorizontalInsets(float insetPercentage);
-
-}
diff --git a/src/com/android/launcher3/util/IntArray.java b/src/com/android/launcher3/util/IntArray.java
index 1c787959e4..7252f7ac1d 100644
--- a/src/com/android/launcher3/util/IntArray.java
+++ b/src/com/android/launcher3/util/IntArray.java
@@ -17,14 +17,13 @@
package com.android.launcher3.util;
import java.util.Arrays;
-import java.util.Iterator;
import java.util.StringTokenizer;
/**
* Copy of the platform hidden implementation of android.util.IntArray.
* Implements a growing array of int primitives.
*/
-public class IntArray implements Cloneable, Iterable<Integer> {
+public class IntArray implements Cloneable {
private static final int MIN_CAPACITY_INCREMENT = 12;
private static final int[] EMPTY_INT = new int[0];
@@ -273,30 +272,4 @@ public class IntArray implements Cloneable, Iterable<Integer> {
throw new ArrayIndexOutOfBoundsException("length=" + len + "; index=" + index);
}
}
-
- @Override
- public Iterator<Integer> iterator() {
- return new ValueIterator();
- }
-
- @Thunk
- class ValueIterator implements Iterator<Integer> {
-
- private int mNextIndex = 0;
-
- @Override
- public boolean hasNext() {
- return mNextIndex < size();
- }
-
- @Override
- public Integer next() {
- return get(mNextIndex++);
- }
-
- @Override
- public void remove() {
- removeIndex(--mNextIndex);
- }
- }
} \ No newline at end of file
diff --git a/src/com/android/launcher3/util/IntSet.java b/src/com/android/launcher3/util/IntSet.java
index 4fd06fe24f..851f129a51 100644
--- a/src/com/android/launcher3/util/IntSet.java
+++ b/src/com/android/launcher3/util/IntSet.java
@@ -16,13 +16,11 @@
package com.android.launcher3.util;
import java.util.Arrays;
-import java.util.Iterator;
/**
* A wrapper over IntArray implementing a growing set of int primitives.
- * The elements in the array are sorted in ascending order.
*/
-public class IntSet implements Iterable<Integer> {
+public class IntSet {
final IntArray mArray = new IntArray();
@@ -36,25 +34,6 @@ public class IntSet implements Iterable<Integer> {
}
}
- /**
- * Appends the specified IntSet's values to the set if they does not exist, then returns the
- * original set that now also contains the new values.
- */
- public IntSet addAll(IntSet other) {
- other.forEach(this::add);
- return this;
- }
-
- /**
- * Removes the specified value from the set if it exist.
- */
- public void remove(int value) {
- int index = Arrays.binarySearch(mArray.mValues, 0, mArray.mSize, value);
- if (index >= 0) {
- mArray.removeIndex(index);
- }
- }
-
public boolean contains(int value) {
return Arrays.binarySearch(mArray.mValues, 0, mArray.mSize, value) >= 0;
}
@@ -82,9 +61,6 @@ public class IntSet implements Iterable<Integer> {
return (obj instanceof IntSet) && ((IntSet) obj).mArray.equals(mArray);
}
- /**
- * Returns the wrapped IntArray. The elements in the array are sorted in ascending order.
- */
public IntArray getArray() {
return mArray;
}
@@ -102,30 +78,4 @@ public class IntSet implements Iterable<Integer> {
Arrays.sort(set.mArray.mValues, 0, set.mArray.mSize);
return set;
}
-
- /**
- * Returns an IntSet with the given values.
- */
- public static IntSet wrap(int... array) {
- return wrap(IntArray.wrap(array));
- }
-
- /**
- * Returns an IntSet with the given values.
- */
- public static IntSet wrap(Iterable<Integer> iterable) {
- IntSet set = new IntSet();
- iterable.forEach(set::add);
- return set;
- }
-
- @Override
- public Iterator<Integer> iterator() {
- return mArray.iterator();
- }
-
- @Override
- public String toString() {
- return "IntSet{" + mArray.toConcatString() + '}';
- }
}
diff --git a/src/com/android/launcher3/util/ItemInfoMatcher.java b/src/com/android/launcher3/util/ItemInfoMatcher.java
index b6af3140fa..354609d463 100644
--- a/src/com/android/launcher3/util/ItemInfoMatcher.java
+++ b/src/com/android/launcher3/util/ItemInfoMatcher.java
@@ -19,74 +19,74 @@ package com.android.launcher3.util;
import android.content.ComponentName;
import android.os.UserHandle;
-import androidx.annotation.NonNull;
-
import com.android.launcher3.LauncherSettings.Favorites;
-import com.android.launcher3.model.data.FolderInfo;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.shortcuts.ShortcutKey;
-import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
-import java.util.function.Predicate;
/**
* A utility class to check for {@link ItemInfo}
*/
-public abstract class ItemInfoMatcher {
+public interface ItemInfoMatcher {
+
+ boolean matches(ItemInfo info, ComponentName cn);
/**
- * Empty component used for match testing
+ * Returns true if the itemInfo matches this check
*/
- private static final ComponentName EMPTY_COMPONENT = new ComponentName("", "");
+ default boolean matchesInfo(ItemInfo info) {
+ if (info != null) {
+ ComponentName cn = info.getTargetComponent();
+ return cn != null && matches(info, cn);
+ } else {
+ return false;
+ }
+ }
- public static Predicate<ItemInfo> ofUser(UserHandle user) {
- return info -> info != null && info.user.equals(user);
+ /**
+ * Returns a new matcher with returns true if either this or {@param matcher} returns true.
+ */
+ default ItemInfoMatcher or(ItemInfoMatcher matcher) {
+ return (info, cn) -> matches(info, cn) || matcher.matches(info, cn);
}
- public static Predicate<ItemInfo> ofComponents(
- HashSet<ComponentName> components, UserHandle user) {
- return info -> info != null && info.user.equals(user)
- && components.contains(getNonNullComponent(info));
+ /**
+ * Returns a new matcher with returns true if both this and {@param matcher} returns true.
+ */
+ default ItemInfoMatcher and(ItemInfoMatcher matcher) {
+ return (info, cn) -> matches(info, cn) && matcher.matches(info, cn);
}
- public static Predicate<ItemInfo> ofPackages(Set<String> packageNames, UserHandle user) {
- return info -> info != null && info.user.equals(user)
- && packageNames.contains(getNonNullComponent(info).getPackageName());
+ /**
+ * Returns a new matcher with returns the opposite value of this.
+ */
+ default ItemInfoMatcher negate() {
+ return (info, cn) -> !matches(info, cn);
}
- public static Predicate<ItemInfo> ofShortcutKeys(Set<ShortcutKey> keys) {
- return info -> info != null && info.itemType == Favorites.ITEM_TYPE_DEEP_SHORTCUT
- && keys.contains(ShortcutKey.fromItemInfo(info));
+ static ItemInfoMatcher ofUser(UserHandle user) {
+ return (info, cn) -> info.user.equals(user);
}
- /**
- * Returns a matcher for items within folders.
- */
- public static Predicate<ItemInfo> forFolderMatch(Predicate<ItemInfo> childOperator) {
- return info -> info instanceof FolderInfo && ((FolderInfo) info).contents.stream()
- .anyMatch(childOperator);
+ static ItemInfoMatcher ofComponents(HashSet<ComponentName> components, UserHandle user) {
+ return (info, cn) -> components.contains(cn) && info.user.equals(user);
}
- /**
- * Returns a matcher for items with provided ids
- */
- public static Predicate<ItemInfo> ofItemIds(IntSet ids) {
- return info -> info != null && ids.contains(info.id);
+ static ItemInfoMatcher ofPackages(Set<String> packageNames, UserHandle user) {
+ return (info, cn) -> packageNames.contains(cn.getPackageName()) && info.user.equals(user);
}
- /**
- * Returns a matcher for items with provided items
- */
- public static Predicate<ItemInfo> ofItems(Collection<? extends ItemInfo> items) {
- IntSet ids = new IntSet();
- items.forEach(item -> ids.add(item.id));
- return ofItemIds(ids);
+ static ItemInfoMatcher ofShortcutKeys(Set<ShortcutKey> keys) {
+ return (info, cn) -> info.itemType == Favorites.ITEM_TYPE_DEEP_SHORTCUT &&
+ keys.contains(ShortcutKey.fromItemInfo(info));
}
- private static ComponentName getNonNullComponent(@NonNull ItemInfo info) {
- ComponentName cn = info.getTargetComponent();
- return cn != null ? cn : EMPTY_COMPONENT;
+ /**
+ * Returns a matcher for items with provided ids
+ */
+ static ItemInfoMatcher ofItemIds(IntSet ids) {
+ return (info, cn) -> ids.contains(info.id);
}
}
diff --git a/src/com/android/launcher3/util/LauncherBindableItemsContainer.java b/src/com/android/launcher3/util/LauncherBindableItemsContainer.java
deleted file mode 100644
index a4cb30a374..0000000000
--- a/src/com/android/launcher3/util/LauncherBindableItemsContainer.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright (C) 2021 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.launcher3.util;
-
-import android.graphics.drawable.Drawable;
-import android.view.View;
-
-import com.android.launcher3.BubbleTextView;
-import com.android.launcher3.folder.Folder;
-import com.android.launcher3.folder.FolderIcon;
-import com.android.launcher3.graphics.PreloadIconDrawable;
-import com.android.launcher3.model.data.FolderInfo;
-import com.android.launcher3.model.data.ItemInfo;
-import com.android.launcher3.model.data.LauncherAppWidgetInfo;
-import com.android.launcher3.model.data.WorkspaceItemInfo;
-import com.android.launcher3.views.ActivityContext;
-import com.android.launcher3.widget.PendingAppWidgetHostView;
-
-import java.util.HashSet;
-import java.util.List;
-
-/**
- * Interface representing a container which can bind Launcher items with some utility methods
- */
-public interface LauncherBindableItemsContainer {
-
- /**
- * Called to update workspace items as a result of
- * {@link com.android.launcher3.model.BgDataModel.Callbacks#bindWorkspaceItemsChanged(List)}
- */
- default void updateWorkspaceItems(List<WorkspaceItemInfo> shortcuts, ActivityContext context) {
- final HashSet<WorkspaceItemInfo> updates = new HashSet<>(shortcuts);
- ItemOperator op = (info, v) -> {
- if (v instanceof BubbleTextView && updates.contains(info)) {
- WorkspaceItemInfo si = (WorkspaceItemInfo) info;
- BubbleTextView shortcut = (BubbleTextView) v;
- Drawable oldIcon = shortcut.getIcon();
- boolean oldPromiseState = (oldIcon instanceof PreloadIconDrawable)
- && ((PreloadIconDrawable) oldIcon).hasNotCompleted();
- shortcut.applyFromWorkspaceItem(si, si.isPromise() != oldPromiseState);
- } else if (info instanceof FolderInfo && v instanceof FolderIcon) {
- ((FolderIcon) v).updatePreviewItems(updates::contains);
- }
-
- // Iterate all items
- return false;
- };
-
- mapOverItems(op);
- Folder openFolder = Folder.getOpen(context);
- if (openFolder != null) {
- openFolder.iterateOverItems(op);
- }
- }
-
- /**
- * Called to update restored items as a result of
- * {@link com.android.launcher3.model.BgDataModel.Callbacks#bindRestoreItemsChange(HashSet)}}
- */
- default void updateRestoreItems(final HashSet<ItemInfo> updates, ActivityContext context) {
- ItemOperator op = (info, v) -> {
- if (info instanceof WorkspaceItemInfo && v instanceof BubbleTextView
- && updates.contains(info)) {
- ((BubbleTextView) v).applyLoadingState(false /* promiseStateChanged */);
- } else if (v instanceof PendingAppWidgetHostView
- && info instanceof LauncherAppWidgetInfo
- && updates.contains(info)) {
- ((PendingAppWidgetHostView) v).applyState();
- } else if (v instanceof FolderIcon && info instanceof FolderInfo) {
- ((FolderIcon) v).updatePreviewItems(updates::contains);
- }
- // process all the shortcuts
- return false;
- };
-
- mapOverItems(op);
- Folder folder = Folder.getOpen(context);
- if (folder != null) {
- folder.iterateOverItems(op);
- }
- }
-
- /**
- * Map the operator over the shortcuts and widgets.
- *
- * @param op the operator to map over the shortcuts
- */
- void mapOverItems(ItemOperator op);
-
- interface ItemOperator {
- /**
- * Process the next itemInfo, possibly with side-effect on the next item.
- *
- * @param info info for the shortcut
- * @param view view for the shortcut
- * @return true if done, false to continue the map
- */
- boolean evaluate(ItemInfo info, View view);
- }
-}
diff --git a/src/com/android/launcher3/util/LogConfig.java b/src/com/android/launcher3/util/LogConfig.java
index 6bc26e7315..528a6e952b 100644
--- a/src/com/android/launcher3/util/LogConfig.java
+++ b/src/com/android/launcher3/util/LogConfig.java
@@ -35,9 +35,4 @@ public class LogConfig {
* When turned on, we enable doodle related logging.
*/
public static final String DOODLE_LOGGING = "DoodleLogging";
-
- /**
- * When turned on, we enable suggest related logging.
- */
- public static final String SEARCH_LOGGING = "SearchLogging";
}
diff --git a/src/com/android/launcher3/util/MainThreadInitializedObject.java b/src/com/android/launcher3/util/MainThreadInitializedObject.java
index badcd35c23..f6003dd7bf 100644
--- a/src/com/android/launcher3/util/MainThreadInitializedObject.java
+++ b/src/com/android/launcher3/util/MainThreadInitializedObject.java
@@ -18,21 +18,13 @@ package com.android.launcher3.util;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import android.content.Context;
-import android.content.ContextWrapper;
import android.os.Looper;
-import android.util.Log;
-import androidx.annotation.UiThread;
import androidx.annotation.VisibleForTesting;
+import com.android.launcher3.graphics.LauncherPreviewRenderer.PreviewContext;
import com.android.launcher3.util.ResourceBasedOverride.Overrides;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
import java.util.concurrent.ExecutionException;
/**
@@ -48,8 +40,8 @@ public class MainThreadInitializedObject<T> {
}
public T get(Context context) {
- if (context instanceof SandboxContext) {
- return ((SandboxContext) context).getObject(this, mProvider);
+ if (context instanceof PreviewContext) {
+ return ((PreviewContext) context).getObject(this, mProvider);
}
if (mValue == null) {
@@ -88,80 +80,4 @@ public class MainThreadInitializedObject<T> {
T get(Context context);
}
-
- /**
- * Abstract Context which allows custom implementations for
- * {@link MainThreadInitializedObject} providers
- */
- public static abstract class SandboxContext extends ContextWrapper {
-
- private static final String TAG = "SandboxContext";
-
- protected final Set<MainThreadInitializedObject> mAllowedObjects;
- protected final Map<MainThreadInitializedObject, Object> mObjectMap = new HashMap<>();
- protected final ArrayList<Object> mOrderedObjects = new ArrayList<>();
-
- private final Object mDestroyLock = new Object();
- private boolean mDestroyed = false;
-
- public SandboxContext(Context base, MainThreadInitializedObject... allowedObjects) {
- super(base);
- mAllowedObjects = new HashSet<>(Arrays.asList(allowedObjects));
- }
-
- @Override
- public Context getApplicationContext() {
- return this;
- }
-
- public void onDestroy() {
- synchronized (mDestroyLock) {
- // Destroy in reverse order
- for (int i = mOrderedObjects.size() - 1; i >= 0; i--) {
- Object o = mOrderedObjects.get(i);
- if (o instanceof SafeCloseable) {
- ((SafeCloseable) o).close();
- }
- }
- mDestroyed = true;
- }
- }
-
- /**
- * Find a cached object from mObjectMap if we have already created one. If not, generate
- * an object using the provider.
- */
- private <T> T getObject(MainThreadInitializedObject<T> object, ObjectProvider<T> provider) {
- synchronized (mDestroyLock) {
- if (mDestroyed) {
- Log.e(TAG, "Static object access with a destroyed context");
- }
- if (!mAllowedObjects.contains(object)) {
- throw new IllegalStateException(
- "Leaking unknown objects " + object + " " + provider);
- }
- T t = (T) mObjectMap.get(object);
- if (t != null) {
- return t;
- }
- if (Looper.myLooper() == Looper.getMainLooper()) {
- t = createObject(provider);
- mObjectMap.put(object, t);
- mOrderedObjects.add(t);
- return t;
- }
- }
-
- try {
- return MAIN_EXECUTOR.submit(() -> getObject(object, provider)).get();
- } catch (InterruptedException | ExecutionException e) {
- throw new RuntimeException(e);
- }
- }
-
- @UiThread
- protected <T> T createObject(ObjectProvider<T> provider) {
- return provider.get(this);
- }
- }
}
diff --git a/src/com/android/launcher3/util/MultiAdditivePropertyFactory.java b/src/com/android/launcher3/util/MultiAdditivePropertyFactory.java
deleted file mode 100644
index 50f7027407..0000000000
--- a/src/com/android/launcher3/util/MultiAdditivePropertyFactory.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.launcher3.util;
-
-import android.util.ArrayMap;
-import android.util.FloatProperty;
-import android.util.Log;
-import android.util.Property;
-import android.view.View;
-
-/**
- * Allows to combine multiple values set by several sources.
- *
- * The various sources are meant to use [set], providing different `setterIndex` params. When it is
- * not set, 0 is used. This is meant to cover the case multiple animations are going on at the same
- * time.
- *
- * This class behaves similarly to [MultiValueAlpha], but is meant to be more abstract and reusable.
- * It sets the addition of all values.
- *
- * @param <T> Type where to apply the property.
- */
-public class MultiAdditivePropertyFactory<T extends View> {
-
- private static final boolean DEBUG = false;
- private static final String TAG = "MultiAdditivePropertyFactory";
- private final String mName;
- private final ArrayMap<Integer, MultiAdditiveProperty> mProperties =
- new ArrayMap<>();
-
- // This is an optimization for cases when set is called repeatedly with the same setterIndex.
- private float mAggregationOfOthers = 0f;
- private Integer mLastIndexSet = -1;
- private final Property<View, Float> mProperty;
-
- public MultiAdditivePropertyFactory(String name, Property<View, Float> property) {
- mName = name;
- mProperty = property;
- }
-
- /** Returns the [MultiFloatProperty] associated with [inx], creating it if not present. */
- public MultiAdditiveProperty get(Integer index) {
- return mProperties.computeIfAbsent(index,
- (k) -> new MultiAdditiveProperty(index, mName + "_" + index));
- }
-
- /**
- * Each [setValue] will be aggregated with the other properties values created by the
- * corresponding factory.
- */
- class MultiAdditiveProperty extends FloatProperty<T> {
- private final int mInx;
- private float mValue = 0f;
-
- MultiAdditiveProperty(int inx, String name) {
- super(name);
- mInx = inx;
- }
-
- @Override
- public void setValue(T obj, float newValue) {
- if (mLastIndexSet != mInx) {
- mAggregationOfOthers = 0f;
- mProperties.forEach((key, property) -> {
- if (key != mInx) {
- mAggregationOfOthers += property.mValue;
- }
- });
- mLastIndexSet = mInx;
- }
- float lastAggregatedValue = mAggregationOfOthers + newValue;
- mValue = newValue;
- apply(obj, lastAggregatedValue);
-
- if (DEBUG) {
- Log.d(TAG, "name=" + mName
- + " newValue=" + newValue + " mInx=" + mInx
- + " aggregated=" + lastAggregatedValue + " others= " + mProperties);
- }
- }
-
- @Override
- public Float get(T view) {
- // The scale of the view should match mLastAggregatedValue. Still, if it has been
- // changed without using this property, it can differ. As this get method is usually
- // used to set the starting point on an animation, this would result in some jumps
- // when the view scale is different than the last aggregated value. To stay on the
- // safe side, let's return the real view scale.
- return mProperty.get(view);
- }
-
- @Override
- public String toString() {
- return String.valueOf(mValue);
- }
- }
-
- protected void apply(View view, float value) {
- mProperty.set(view, value);
- }
-}
diff --git a/src/com/android/launcher3/util/MultiScalePropertyFactory.java b/src/com/android/launcher3/util/MultiScalePropertyFactory.java
deleted file mode 100644
index a7e6cc8679..0000000000
--- a/src/com/android/launcher3/util/MultiScalePropertyFactory.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.launcher3.util;
-
-import android.util.ArrayMap;
-import android.util.FloatProperty;
-import android.util.Log;
-import android.view.View;
-
-import com.android.launcher3.Utilities;
-
-/**
- * Allows to combine multiple values set by several sources.
- *
- * The various sources are meant to use [set], providing different `setterIndex` params. When it is
- * not set, 0 is used. This is meant to cover the case multiple animations are going on at the same
- * time.
- *
- * This class behaves similarly to [MultiValueAlpha], but is meant to be more abstract and reusable.
- * It sets the multiplication of all values, bounded to the max and the min values.
- *
- * @param <T> Type where to apply the property.
- */
-public class MultiScalePropertyFactory<T extends View> {
-
- private static final boolean DEBUG = false;
- private static final String TAG = "MultiScaleProperty";
- private final String mName;
- private final ArrayMap<Integer, MultiScaleProperty> mProperties =
- new ArrayMap<Integer, MultiScaleProperty>();
-
- // This is an optimization for cases when set is called repeatedly with the same setterIndex.
- private float mMinOfOthers = 0;
- private float mMaxOfOthers = 0;
- private float mMultiplicationOfOthers = 0;
- private Integer mLastIndexSet = -1;
- private float mLastAggregatedValue = 1.0f;
-
- public MultiScalePropertyFactory(String name) {
- mName = name;
- }
-
- /** Returns the [MultiFloatProperty] associated with [inx], creating it if not present. */
- public MultiScaleProperty get(Integer index) {
- return mProperties.computeIfAbsent(index,
- (k) -> new MultiScaleProperty(index, mName + "_" + index));
- }
-
- /**
- * Each [setValue] will be aggregated with the other properties values created by the
- * corresponding factory.
- */
- class MultiScaleProperty extends FloatProperty<T> {
- private final int mInx;
- private float mValue = 1.0f;
-
- MultiScaleProperty(int inx, String name) {
- super(name);
- mInx = inx;
- }
-
- @Override
- public void setValue(T obj, float newValue) {
- if (mLastIndexSet != mInx) {
- mMinOfOthers = Float.MAX_VALUE;
- mMaxOfOthers = Float.MIN_VALUE;
- mMultiplicationOfOthers = 1.0f;
- mProperties.forEach((key, property) -> {
- if (key != mInx) {
- mMinOfOthers = Math.min(mMinOfOthers, property.mValue);
- mMaxOfOthers = Math.max(mMaxOfOthers, property.mValue);
- mMultiplicationOfOthers *= property.mValue;
- }
- });
- mLastIndexSet = mInx;
- }
- float minValue = Math.min(mMinOfOthers, newValue);
- float maxValue = Math.max(mMaxOfOthers, newValue);
- float multValue = mMultiplicationOfOthers * newValue;
- mLastAggregatedValue = Utilities.boundToRange(multValue, minValue, maxValue);
- mValue = newValue;
- apply(obj, mLastAggregatedValue);
-
- if (DEBUG) {
- Log.d(TAG, "name=" + mName
- + " newValue=" + newValue + " mInx=" + mInx
- + " aggregated=" + mLastAggregatedValue + " others= " + mProperties);
- }
- }
-
- @Override
- public Float get(T view) {
- // The scale of the view should match mLastAggregatedValue. Still, if it has been
- // changed without using this property, it can differ. As this get method is usually
- // used to set the starting point on an animation, this would result in some jumps
- // when the view scale is different than the last aggregated value. To stay on the
- // safe side, let's return the real view scale.
- return view.getScaleX();
- }
-
- @Override
- public String toString() {
- return String.valueOf(mValue);
- }
- }
-
- protected void apply(View view, float value) {
- view.setScaleX(value);
- view.setScaleY(value);
- }
-}
diff --git a/src/com/android/launcher3/util/MultiValueAlpha.java b/src/com/android/launcher3/util/MultiValueAlpha.java
index 11cd07c838..5be95292b4 100644
--- a/src/com/android/launcher3/util/MultiValueAlpha.java
+++ b/src/com/android/launcher3/util/MultiValueAlpha.java
@@ -16,15 +16,12 @@
package com.android.launcher3.util;
-import android.animation.Animator;
-import android.animation.ObjectAnimator;
import android.util.FloatProperty;
import android.view.View;
import com.android.launcher3.anim.AlphaUpdateListener;
import java.util.Arrays;
-import java.util.function.Consumer;
/**
* Utility class to handle separating a single value as a factor of multiple values
@@ -86,8 +83,6 @@ public class MultiValueAlpha {
// Factor of all other alpha channels, only valid if mMyMask is present in mValidMask.
private float mOthers = 1;
- private Consumer<Float> mConsumer;
-
AlphaProperty(int myMask) {
mMyMask = myMask;
}
@@ -112,40 +107,19 @@ public class MultiValueAlpha {
mValidMask = mMyMask;
mValue = value;
- final float alpha = mOthers * mValue;
- mView.setAlpha(alpha);
+ mView.setAlpha(mOthers * mValue);
if (mUpdateVisibility) {
AlphaUpdateListener.updateVisibility(mView);
}
- if (mConsumer != null) {
- mConsumer.accept(mValue);
- }
}
public float getValue() {
return mValue;
}
- public void setConsumer(Consumer<Float> consumer) {
- mConsumer = consumer;
- if (mConsumer != null) {
- mConsumer.accept(mValue);
- }
- }
-
@Override
public String toString() {
return Float.toString(mValue);
}
-
- /**
- * Creates and returns an Animator from the current value to the given value. Future
- * animator on the same target automatically cancels the previous one.
- */
- public Animator animateToValue(float value) {
- ObjectAnimator animator = ObjectAnimator.ofFloat(this, VALUE, value);
- animator.setAutoCancel(true);
- return animator;
- }
}
}
diff --git a/src/com/android/launcher3/util/OnboardingPrefs.java b/src/com/android/launcher3/util/OnboardingPrefs.java
index f4cf21efe5..40bc9c3abc 100644
--- a/src/com/android/launcher3/util/OnboardingPrefs.java
+++ b/src/com/android/launcher3/util/OnboardingPrefs.java
@@ -20,7 +20,7 @@ import android.util.ArrayMap;
import androidx.annotation.StringDef;
-import com.android.launcher3.views.ActivityContext;
+import com.android.launcher3.Launcher;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -29,30 +29,15 @@ import java.util.Map;
/**
* Stores and retrieves onboarding-related data via SharedPreferences.
- *
- * @param <T> Context which owns these preferences.
*/
-public class OnboardingPrefs<T extends ActivityContext> {
+public class OnboardingPrefs<T extends Launcher> {
public static final String HOME_BOUNCE_SEEN = "launcher.apps_view_shown";
public static final String HOME_BOUNCE_COUNT = "launcher.home_bounce_count";
public static final String HOTSEAT_DISCOVERY_TIP_COUNT = "launcher.hotseat_discovery_tip_count";
public static final String HOTSEAT_LONGPRESS_TIP_SEEN = "launcher.hotseat_longpress_tip_seen";
- public static final String SEARCH_KEYBOARD_EDU_SEEN = "launcher.search_edu_seen";
+ public static final String SEARCH_EDU_SEEN = "launcher.search_edu_seen";
public static final String SEARCH_SNACKBAR_COUNT = "launcher.keyboard_snackbar_count";
- public static final String SEARCH_ONBOARDING_COUNT = "launcher.search_onboarding_count";
- public static final String TASKBAR_EDU_SEEN = "launcher.taskbar_edu_seen";
- public static final String ALL_APPS_VISITED_COUNT = "launcher.all_apps_visited_count";
- // When adding a new key, add it here as well, to be able to reset it from Developer Options.
- public static final Map<String, String[]> ALL_PREF_KEYS = Map.of(
- "All Apps Bounce", new String[] { HOME_BOUNCE_SEEN, HOME_BOUNCE_COUNT },
- "Hybrid Hotseat Education", new String[] { HOTSEAT_DISCOVERY_TIP_COUNT,
- HOTSEAT_LONGPRESS_TIP_SEEN },
- "Search Education", new String[] { SEARCH_KEYBOARD_EDU_SEEN, SEARCH_SNACKBAR_COUNT,
- SEARCH_ONBOARDING_COUNT},
- "Taskbar Education", new String[] { TASKBAR_EDU_SEEN },
- "All Apps Visited Count", new String[] {ALL_APPS_VISITED_COUNT}
- );
/**
* Events that either have happened or have not (booleans).
@@ -60,11 +45,11 @@ public class OnboardingPrefs<T extends ActivityContext> {
@StringDef(value = {
HOME_BOUNCE_SEEN,
HOTSEAT_LONGPRESS_TIP_SEEN,
- SEARCH_KEYBOARD_EDU_SEEN,
- TASKBAR_EDU_SEEN
+ SEARCH_EDU_SEEN
})
@Retention(RetentionPolicy.SOURCE)
- public @interface EventBoolKey {}
+ public @interface EventBoolKey {
+ }
/**
* Events that occur multiple times, which we count up to a max defined in {@link #MAX_COUNTS}.
@@ -72,23 +57,19 @@ public class OnboardingPrefs<T extends ActivityContext> {
@StringDef(value = {
HOME_BOUNCE_COUNT,
HOTSEAT_DISCOVERY_TIP_COUNT,
- SEARCH_SNACKBAR_COUNT,
- SEARCH_ONBOARDING_COUNT,
- ALL_APPS_VISITED_COUNT
+ SEARCH_SNACKBAR_COUNT
})
@Retention(RetentionPolicy.SOURCE)
- public @interface EventCountKey {}
+ public @interface EventCountKey {
+ }
private static final Map<String, Integer> MAX_COUNTS;
static {
- Map<String, Integer> maxCounts = new ArrayMap<>(5);
+ Map<String, Integer> maxCounts = new ArrayMap<>(4);
maxCounts.put(HOME_BOUNCE_COUNT, 3);
maxCounts.put(HOTSEAT_DISCOVERY_TIP_COUNT, 5);
maxCounts.put(SEARCH_SNACKBAR_COUNT, 3);
- // This is the sum of all onboarding cards. Currently there is only 1 card shown 3 times.
- maxCounts.put(SEARCH_ONBOARDING_COUNT, 3);
- maxCounts.put(ALL_APPS_VISITED_COUNT, 20);
MAX_COUNTS = Collections.unmodifiableMap(maxCounts);
}
@@ -140,14 +121,4 @@ public class OnboardingPrefs<T extends ActivityContext> {
mSharedPrefs.edit().putInt(eventKey, count).apply();
return hasReachedMaxCount(count, eventKey);
}
-
- /**
- * Sets the event count to the given value.
- *
- * @return Whether we have now reached the max count.
- */
- public boolean setEventCount(int count, @EventCountKey String eventKey) {
- mSharedPrefs.edit().putInt(eventKey, count).apply();
- return hasReachedMaxCount(count, eventKey);
- }
}
diff --git a/src/com/android/launcher3/util/PackageManagerHelper.java b/src/com/android/launcher3/util/PackageManagerHelper.java
index f42d30453b..08ec5912a4 100644
--- a/src/com/android/launcher3/util/PackageManagerHelper.java
+++ b/src/com/android/launcher3/util/PackageManagerHelper.java
@@ -202,8 +202,7 @@ public class PackageManagerHelper {
public static Intent getStyleWallpapersIntent(Context context) {
return new Intent(Intent.ACTION_SET_WALLPAPER).setComponent(
new ComponentName(context.getString(R.string.wallpaper_picker_package),
- context.getString(R.string.custom_activity_picker)
- ));
+ "com.android.customization.picker.CustomizationPickerActivity"));
}
/**
diff --git a/src/com/android/launcher3/util/PackageUserKey.java b/src/com/android/launcher3/util/PackageUserKey.java
index 92d97371e5..3a3b5a261e 100644
--- a/src/com/android/launcher3/util/PackageUserKey.java
+++ b/src/com/android/launcher3/util/PackageUserKey.java
@@ -1,24 +1,19 @@
package com.android.launcher3.util;
-import static com.android.launcher3.widget.WidgetSections.NO_CATEGORY;
-
import android.os.UserHandle;
import android.service.notification.StatusBarNotification;
-import android.text.TextUtils;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.android.launcher3.model.data.ItemInfo;
-import com.android.launcher3.model.data.PackageItemInfo;
-import java.util.Objects;
+import java.util.Arrays;
-/** Creates a hash key based on package name, widget category, and user. */
+/** Creates a hash key based on package name and user. */
public class PackageUserKey {
public String mPackageName;
- public int mWidgetCategory;
public UserHandle mUser;
private int mHashCode;
@@ -32,31 +27,14 @@ public class PackageUserKey {
return new PackageUserKey(notification.getPackageName(), notification.getUser());
}
- /** Creates a {@link PackageUserKey} from {@link PackageItemInfo}. */
- public static PackageUserKey fromPackageItemInfo(PackageItemInfo info) {
- if (TextUtils.isEmpty(info.packageName) && info.widgetCategory != NO_CATEGORY) {
- return new PackageUserKey(info.widgetCategory, info.user);
- }
- return new PackageUserKey(info.packageName, info.user);
- }
-
public PackageUserKey(String packageName, UserHandle user) {
update(packageName, user);
}
- public PackageUserKey(int widgetCategory, UserHandle user) {
- update(/* packageName= */ "", widgetCategory, user);
- }
-
public void update(String packageName, UserHandle user) {
- update(packageName, NO_CATEGORY, user);
- }
-
- private void update(String packageName, int widgetCategory, UserHandle user) {
mPackageName = packageName;
- mWidgetCategory = widgetCategory;
mUser = user;
- mHashCode = Objects.hash(packageName, widgetCategory, user);
+ mHashCode = Arrays.hashCode(new Object[] {packageName, user});
}
/**
@@ -81,14 +59,12 @@ public class PackageUserKey {
public boolean equals(Object obj) {
if (!(obj instanceof PackageUserKey)) return false;
PackageUserKey otherKey = (PackageUserKey) obj;
- return Objects.equals(mPackageName, otherKey.mPackageName)
- && mWidgetCategory == otherKey.mWidgetCategory
- && Objects.equals(mUser, otherKey.mUser);
+ return mPackageName.equals(otherKey.mPackageName) && mUser.equals(otherKey.mUser);
}
@NonNull
@Override
public String toString() {
- return mPackageName + "#" + mUser + ",category=" + mWidgetCategory;
+ return mPackageName + "#" + mUser;
}
}
diff --git a/src/com/android/launcher3/util/PluralMessageFormat.java b/src/com/android/launcher3/util/PluralMessageFormat.java
deleted file mode 100644
index 5e4ce8d982..0000000000
--- a/src/com/android/launcher3/util/PluralMessageFormat.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2021 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.launcher3.util;
-
-import android.content.Context;
-import android.icu.text.MessageFormat;
-
-import androidx.annotation.StringRes;
-
-import java.util.HashMap;
-import java.util.Locale;
-
-/** A helper class to format common ICU plural strings. */
-public class PluralMessageFormat {
-
- /**
- * Returns a plural string from a ICU format message template, which takes "count" as an
- * argument.
- *
- * <p>An example of ICU format message template provided by {@code stringId}:
- * {count, plural, =1{# widget} other{# widgets}}
- */
- public static final String getIcuPluralString(Context context, @StringRes int stringId,
- int count) {
- MessageFormat icuCountFormat = new MessageFormat(
- context.getResources().getString(stringId),
- Locale.getDefault());
- HashMap<String, Object> args = new HashMap();
- args.put("count", count);
- return icuCountFormat.format(args);
- }
-}
diff --git a/src/com/android/launcher3/util/RotationUtils.java b/src/com/android/launcher3/util/RotationUtils.java
deleted file mode 100644
index 3414a3de37..0000000000
--- a/src/com/android/launcher3/util/RotationUtils.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.launcher3.util;
-
-import static android.view.Surface.ROTATION_0;
-import static android.view.Surface.ROTATION_180;
-import static android.view.Surface.ROTATION_270;
-import static android.view.Surface.ROTATION_90;
-
-import android.graphics.Point;
-import android.graphics.Rect;
-
-/**
- * Utility methods based on {@code frameworks/base/core/java/android/util/RotationUtils.java}
- */
-public class RotationUtils {
-
- /**
- * Rotates an Rect according to the given rotation.
- */
- public static void rotateRect(Rect rect, int rotation) {
- switch (rotation) {
- case ROTATION_0:
- return;
- case ROTATION_90:
- rect.set(rect.top, rect.right, rect.bottom, rect.left);
- return;
- case ROTATION_180:
- rect.set(rect.right, rect.bottom, rect.left, rect.top);
- return;
- case ROTATION_270:
- rect.set(rect.bottom, rect.left, rect.top, rect.right);
- return;
- default:
- throw new IllegalArgumentException("unknown rotation: " + rotation);
- }
- }
-
- /**
- * Rotates an size according to the given rotation.
- */
- public static void rotateSize(Point size, int rotation) {
- switch (rotation) {
- case ROTATION_0:
- case ROTATION_180:
- return;
- case ROTATION_90:
- case ROTATION_270:
- size.set(size.y, size.x);
- return;
- default:
- throw new IllegalArgumentException("unknown rotation: " + rotation);
- }
- }
-
- /** @return the rotation needed to rotate from oldRotation to newRotation. */
- public static int deltaRotation(int oldRotation, int newRotation) {
- int delta = newRotation - oldRotation;
- if (delta < 0) delta += 4;
- return delta;
- }
-}
diff --git a/src/com/android/launcher3/util/SettingsCache.java b/src/com/android/launcher3/util/SettingsCache.java
index 0c5b7225d3..10611c7211 100644
--- a/src/com/android/launcher3/util/SettingsCache.java
+++ b/src/com/android/launcher3/util/SettingsCache.java
@@ -47,7 +47,7 @@ import java.util.concurrent.CopyOnWriteArrayList;
*
* Cache will also be updated if a key queried is missing (even if it has no listeners registered).
*/
-public class SettingsCache extends ContentObserver implements SafeCloseable {
+public class SettingsCache extends ContentObserver {
/** Hidden field Settings.Secure.NOTIFICATION_BADGING */
public static final Uri NOTIFICATION_BADGING_URI =
@@ -69,6 +69,7 @@ public class SettingsCache extends ContentObserver implements SafeCloseable {
private final Map<Uri, CopyOnWriteArrayList<OnChangeListener>> mListenerMap = new HashMap<>();
protected final ContentResolver mResolver;
+
/**
* Singleton instance
*/
@@ -81,11 +82,6 @@ public class SettingsCache extends ContentObserver implements SafeCloseable {
}
@Override
- public void close() {
- mResolver.unregisterContentObserver(this);
- }
-
- @Override
public void onChange(boolean selfChange, Uri uri) {
// We use default of 1, but if we're getting an onChange call, can assume a non-default
// value will exist
diff --git a/src/com/android/launcher3/util/SimpleBroadcastReceiver.java b/src/com/android/launcher3/util/SimpleBroadcastReceiver.java
index 4dfa5ccdeb..465a0e8b05 100644
--- a/src/com/android/launcher3/util/SimpleBroadcastReceiver.java
+++ b/src/com/android/launcher3/util/SimpleBroadcastReceiver.java
@@ -39,17 +39,10 @@ public class SimpleBroadcastReceiver extends BroadcastReceiver {
* Helper method to register multiple actions
*/
public void register(Context context, String... actions) {
- register(context, 0, actions);
- }
-
- /**
- * Helper method to register multiple actions with one or more {@code flags}.
- */
- public void register(Context context, int flags, String... actions) {
IntentFilter filter = new IntentFilter();
for (String action : actions) {
filter.addAction(action);
}
- context.registerReceiver(this, filter, flags);
+ context.registerReceiver(this, filter);
}
}
diff --git a/src/com/android/launcher3/util/SplitConfigurationOptions.java b/src/com/android/launcher3/util/SplitConfigurationOptions.java
index 6a336cce28..573c8bd367 100644
--- a/src/com/android/launcher3/util/SplitConfigurationOptions.java
+++ b/src/com/android/launcher3/util/SplitConfigurationOptions.java
@@ -18,8 +18,6 @@ package com.android.launcher3.util;
import static java.lang.annotation.RetentionPolicy.SOURCE;
-import android.graphics.Rect;
-
import androidx.annotation.IntDef;
import java.lang.annotation.Retention;
@@ -68,106 +66,20 @@ public final class SplitConfigurationOptions {
public @interface StageType {}
///////////////////////////////////
- /**
- * Default split ratio for launching app pair from overview.
- */
- public static final float DEFAULT_SPLIT_RATIO = 0.5f;
-
public static class SplitPositionOption {
- public final int iconResId;
- public final int textResId;
+ public final int mIconResId;
+ public final int mTextResId;
@StagePosition
- public final int stagePosition;
+ public final int mStagePosition;
@StageType
public final int mStageType;
public SplitPositionOption(int iconResId, int textResId, int stagePosition, int stageType) {
- this.iconResId = iconResId;
- this.textResId = textResId;
- this.stagePosition = stagePosition;
+ mIconResId = iconResId;
+ mTextResId = textResId;
+ mStagePosition = stagePosition;
mStageType = stageType;
}
}
-
- /**
- * NOTE: Engineers complained about too little ambiguity in the last survey, so there is a class
- * with the same name/functionality in wm.shell.util (which launcher3 cannot be built against)
- *
- * If you make changes here, consider making the same changes there
- */
- public static class StagedSplitBounds {
- public final Rect leftTopBounds;
- public final Rect rightBottomBounds;
- /** This rect represents the actual gap between the two apps */
- public final Rect visualDividerBounds;
- // This class is orientation-agnostic, so we compute both for later use
- public final float topTaskPercent;
- public final float leftTaskPercent;
- public final float dividerWidthPercent;
- public final float dividerHeightPercent;
- /**
- * If {@code true}, that means at the time of creation of this object, the
- * split-screened apps were vertically stacked. This is useful in scenarios like
- * rotation where the bounds won't change, but this variable can indicate what orientation
- * the bounds were originally in
- */
- public final boolean appsStackedVertically;
- /**
- * If {@code true}, that means at the time of creation of this object, the phone was in
- * seascape orientation. This is important on devices with insets, because they do not split
- * evenly -- one of the insets must be slightly larger to account for the inset.
- * From landscape, it is the leftTop task that expands slightly.
- * From seascape, it is the rightBottom task that expands slightly.
- */
- public final boolean initiatedFromSeascape;
- public final int leftTopTaskId;
- public final int rightBottomTaskId;
-
- public StagedSplitBounds(Rect leftTopBounds, Rect rightBottomBounds, int leftTopTaskId,
- int rightBottomTaskId) {
- this.leftTopBounds = leftTopBounds;
- this.rightBottomBounds = rightBottomBounds;
- this.leftTopTaskId = leftTopTaskId;
- this.rightBottomTaskId = rightBottomTaskId;
-
- if (rightBottomBounds.top > leftTopBounds.top) {
- // vertical apps, horizontal divider
- this.visualDividerBounds = new Rect(leftTopBounds.left, leftTopBounds.bottom,
- leftTopBounds.right, rightBottomBounds.top);
- appsStackedVertically = true;
- initiatedFromSeascape = false;
- } else {
- // horizontal apps, vertical divider
- this.visualDividerBounds = new Rect(leftTopBounds.right, leftTopBounds.top,
- rightBottomBounds.left, leftTopBounds.bottom);
- appsStackedVertically = false;
- // The following check is unreliable on devices without insets
- // (initiatedFromSeascape will always be set to false.) This happens to be OK for
- // all our current uses, but should be refactored.
- // TODO: Create a more reliable check, or refactor how splitting works on devices
- // with insets.
- if (rightBottomBounds.width() > leftTopBounds.width()) {
- initiatedFromSeascape = true;
- } else {
- initiatedFromSeascape = false;
- }
- }
-
- float totalWidth = rightBottomBounds.right - leftTopBounds.left;
- float totalHeight = rightBottomBounds.bottom - leftTopBounds.top;
- leftTaskPercent = leftTopBounds.width() / totalWidth;
- topTaskPercent = leftTopBounds.height() / totalHeight;
- dividerWidthPercent = visualDividerBounds.width() / totalWidth;
- dividerHeightPercent = visualDividerBounds.height() / totalHeight;
- }
- }
-
- public static class StagedSplitTaskPosition {
- public int taskId = -1;
- @StagePosition
- public int stagePosition = STAGE_POSITION_UNDEFINED;
- @StageType
- public int stageType = STAGE_TYPE_UNDEFINED;
- }
}
diff --git a/src/com/android/launcher3/util/UiThreadHelper.java b/src/com/android/launcher3/util/UiThreadHelper.java
index 7e6711f806..0f40179f79 100644
--- a/src/com/android/launcher3/util/UiThreadHelper.java
+++ b/src/com/android/launcher3/util/UiThreadHelper.java
@@ -25,13 +25,10 @@ import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
-import android.util.Log;
import android.view.View;
-import android.view.WindowInsets;
-import android.view.WindowInsetsController;
import android.view.inputmethod.InputMethodManager;
-import com.android.launcher3.Utilities;
+import com.android.launcher3.Launcher;
import com.android.launcher3.views.ActivityContext;
/**
@@ -52,25 +49,6 @@ public class UiThreadHelper {
public static void hideKeyboardAsync(ActivityContext activityContext, IBinder token) {
View root = activityContext.getDragLayer();
- if (Utilities.ATLEAST_R) {
- Preconditions.assertUIThread();
- // Hide keyboard with WindowInsetsController if could. In case
- // hideSoftInputFromWindow may get ignored by input connection being finished
- // when the screen is off.
- //
- // In addition, inside IMF, the keyboards are closed asynchronously that launcher no
- // longer need to post to the message queue.
- final WindowInsetsController wic = root.getWindowInsetsController();
- WindowInsets insets = root.getRootWindowInsets();
- boolean isImeShown = insets != null && insets.isVisible(WindowInsets.Type.ime());
- if (wic != null && isImeShown) {
- // this method cannot be called cross threads
- wic.hide(WindowInsets.Type.ime());
- activityContext.getStatsLogManager().logger()
- .log(LAUNCHER_ALLAPPS_KEYBOARD_CLOSED);
- return;
- }
- }
// Since the launcher context cannot be accessed directly from callback, adding secondary
// message to log keyboard close event asynchronously.
Bundle mHideKeyboardLoggerMsg = new Bundle();
@@ -78,7 +56,7 @@ public class UiThreadHelper {
STATS_LOGGER_KEY,
Message.obtain(
HANDLER.get(root.getContext()),
- () -> activityContext
+ () -> Launcher.cast(activityContext)
.getStatsLogManager()
.logger()
.log(LAUNCHER_ALLAPPS_KEYBOARD_CLOSED)
diff --git a/quickstep/src/com/android/quickstep/util/VibratorWrapper.java b/src/com/android/launcher3/util/VibratorWrapper.java
index 211bd08b33..b0defd445a 100644
--- a/quickstep/src/com/android/quickstep/util/VibratorWrapper.java
+++ b/src/com/android/launcher3/util/VibratorWrapper.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2021 The Android Open Source Project
+ * 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.
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.android.quickstep.util;
+package com.android.launcher3.util;
import static android.os.VibrationEffect.createPredefined;
import static android.provider.Settings.System.HAPTIC_FEEDBACK_ENABLED;
@@ -21,20 +21,15 @@ import static android.provider.Settings.System.HAPTIC_FEEDBACK_ENABLED;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
-import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.content.ContentResolver;
import android.content.Context;
import android.database.ContentObserver;
-import android.media.AudioAttributes;
import android.os.Build;
import android.os.VibrationEffect;
import android.os.Vibrator;
import android.provider.Settings;
-import com.android.launcher3.Utilities;
-import com.android.launcher3.util.MainThreadInitializedObject;
-
/**
* Wrapper around {@link Vibrator} to easily perform haptic feedback where necessary.
*/
@@ -44,15 +39,8 @@ public class VibratorWrapper {
public static final MainThreadInitializedObject<VibratorWrapper> INSTANCE =
new MainThreadInitializedObject<>(VibratorWrapper::new);
- public static final AudioAttributes VIBRATION_ATTRS = new AudioAttributes.Builder()
- .setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION)
- .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
- .build();
-
public static final VibrationEffect EFFECT_CLICK =
createPredefined(VibrationEffect.EFFECT_CLICK);
- public static final VibrationEffect EFFECT_TEXTURE_TICK =
- VibrationEffect.createPredefined(VibrationEffect.EFFECT_TEXTURE_TICK);
/**
* Haptic when entering overview.
@@ -90,27 +78,7 @@ public class VibratorWrapper {
/** Vibrates with the given effect if haptic feedback is available and enabled. */
public void vibrate(VibrationEffect vibrationEffect) {
if (mHasVibrator && mIsHapticFeedbackEnabled) {
- UI_HELPER_EXECUTOR.execute(() -> mVibrator.vibrate(vibrationEffect, VIBRATION_ATTRS));
- }
- }
-
- /**
- * Vibrates with a single primitive, if supported, or use a fallback effect instead. This only
- * vibrates if haptic feedback is available and enabled.
- */
- @SuppressLint("NewApi")
- public void vibrate(int primitiveId, float primitiveScale, VibrationEffect fallbackEffect) {
- if (mHasVibrator && mIsHapticFeedbackEnabled) {
- UI_HELPER_EXECUTOR.execute(() -> {
- if (Utilities.ATLEAST_R && primitiveId >= 0
- && mVibrator.areAllPrimitivesSupported(primitiveId)) {
- mVibrator.vibrate(VibrationEffect.startComposition()
- .addPrimitive(primitiveId, primitiveScale)
- .compose(), VIBRATION_ATTRS);
- } else {
- mVibrator.vibrate(fallbackEffect, VIBRATION_ATTRS);
- }
- });
+ UI_HELPER_EXECUTOR.execute(() -> mVibrator.vibrate(vibrationEffect));
}
}
}
diff --git a/src/com/android/launcher3/util/ViewCache.java b/src/com/android/launcher3/util/ViewCache.java
index 98e6822542..08b8744167 100644
--- a/src/com/android/launcher3/util/ViewCache.java
+++ b/src/com/android/launcher3/util/ViewCache.java
@@ -21,8 +21,6 @@ import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
-import com.android.launcher3.R;
-
/**
* Utility class to cache views at an activity level
*/
@@ -41,26 +39,18 @@ public class ViewCache {
mCache.put(layoutId, entry);
}
- T result;
if (entry.mCurrentSize > 0) {
entry.mCurrentSize --;
- result = (T) entry.mViews[entry.mCurrentSize];
+ T result = (T) entry.mViews[entry.mCurrentSize];
entry.mViews[entry.mCurrentSize] = null;
- } else {
- result = (T) LayoutInflater.from(context).inflate(layoutId, parent, false);
- result.setTag(R.id.cache_entry_tag_id, entry);
+ return result;
}
- return result;
+
+ return (T) LayoutInflater.from(context).inflate(layoutId, parent, false);
}
public void recycleView(int layoutId, View view) {
CacheEntry entry = mCache.get(layoutId);
- if (entry != view.getTag(R.id.cache_entry_tag_id)) {
- // Since this view was created, the cache has been reset. The view should not be
- // recycled since this means the environment could also have changed, requiring new
- // view setup.
- return;
- }
if (entry != null && entry.mCurrentSize < entry.mMaxSize) {
entry.mViews[entry.mCurrentSize] = view;
entry.mCurrentSize++;
diff --git a/src/com/android/launcher3/util/ViewOnDrawExecutor.java b/src/com/android/launcher3/util/ViewOnDrawExecutor.java
index 5d902917cd..82e24c24f5 100644
--- a/src/com/android/launcher3/util/ViewOnDrawExecutor.java
+++ b/src/com/android/launcher3/util/ViewOnDrawExecutor.java
@@ -16,21 +16,28 @@
package com.android.launcher3.util;
+import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
+
+import android.os.Process;
import android.view.View;
import android.view.View.OnAttachStateChangeListener;
import android.view.ViewTreeObserver.OnDrawListener;
+import androidx.annotation.VisibleForTesting;
+
import com.android.launcher3.Launcher;
+import java.util.ArrayList;
+import java.util.concurrent.Executor;
import java.util.function.Consumer;
/**
* An executor which runs all the tasks after the first onDraw is called on the target view.
*/
-public class ViewOnDrawExecutor implements OnDrawListener, Runnable,
+public class ViewOnDrawExecutor implements Executor, OnDrawListener, Runnable,
OnAttachStateChangeListener {
- private final RunnableList mTasks;
+ private final ArrayList<Runnable> mTasks = new ArrayList<>();
private Consumer<ViewOnDrawExecutor> mOnClearCallback;
private View mAttachedView;
@@ -39,16 +46,22 @@ public class ViewOnDrawExecutor implements OnDrawListener, Runnable,
private boolean mLoadAnimationCompleted;
private boolean mFirstDrawCompleted;
- private boolean mCancelled;
-
- public ViewOnDrawExecutor(RunnableList tasks) {
- mTasks = tasks;
+ public void attachTo(Launcher launcher) {
+ attachTo(launcher.getWorkspace(), true /* waitForLoadAnimation */,
+ launcher::clearPendingExecutor);
}
- public void attachTo(Launcher launcher) {
- mOnClearCallback = launcher::clearPendingExecutor;
- mAttachedView = launcher.getWorkspace();
+ /**
+ * Attached the executor to the existence of the view
+ */
+ public void attachTo(View attachedView, boolean waitForLoadAnimation,
+ Consumer<ViewOnDrawExecutor> onClearCallback) {
+ mOnClearCallback = onClearCallback;
+ mAttachedView = attachedView;
mAttachedView.addOnAttachStateChangeListener(this);
+ if (!waitForLoadAnimation) {
+ mLoadAnimationCompleted = true;
+ }
if (mAttachedView.isAttachedToWindow()) {
attachObserver();
@@ -62,6 +75,12 @@ public class ViewOnDrawExecutor implements OnDrawListener, Runnable,
}
@Override
+ public void execute(Runnable command) {
+ mTasks.add(command);
+ MODEL_EXECUTOR.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
+ }
+
+ @Override
public void onViewAttachedToWindow(View v) {
attachObserver();
}
@@ -86,17 +105,12 @@ public class ViewOnDrawExecutor implements OnDrawListener, Runnable,
public void run() {
// Post the pending tasks after both onDraw and onLoadAnimationCompleted have been called.
if (mLoadAnimationCompleted && mFirstDrawCompleted && !mCompleted) {
- markCompleted();
+ runAllTasks();
}
}
- /**
- * Executes all tasks immediately
- */
public void markCompleted() {
- if (!mCancelled) {
- mTasks.executeAllAndDestroy();
- }
+ mTasks.clear();
mCompleted = true;
if (mAttachedView != null) {
mAttachedView.getViewTreeObserver().removeOnDrawListener(this);
@@ -105,10 +119,21 @@ public class ViewOnDrawExecutor implements OnDrawListener, Runnable,
if (mOnClearCallback != null) {
mOnClearCallback.accept(this);
}
+ MODEL_EXECUTOR.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
+ }
+
+ protected boolean isCompleted() {
+ return mCompleted;
}
- public void cancel() {
- mCancelled = true;
+ /**
+ * Executes all tasks immediately
+ */
+ @VisibleForTesting
+ public void runAllTasks() {
+ for (final Runnable r : mTasks) {
+ r.run();
+ }
markCompleted();
}
}
diff --git a/src/com/android/launcher3/util/WallpaperOffsetInterpolator.java b/src/com/android/launcher3/util/WallpaperOffsetInterpolator.java
index 43e98201f4..b8554e418c 100644
--- a/src/com/android/launcher3/util/WallpaperOffsetInterpolator.java
+++ b/src/com/android/launcher3/util/WallpaperOffsetInterpolator.java
@@ -14,8 +14,6 @@ import android.os.SystemClock;
import android.util.Log;
import android.view.animation.Interpolator;
-import androidx.annotation.AnyThread;
-
import com.android.launcher3.Utilities;
import com.android.launcher3.Workspace;
import com.android.launcher3.anim.Interpolators;
@@ -32,7 +30,7 @@ public class WallpaperOffsetInterpolator extends BroadcastReceiver {
// Don't use all the wallpaper for parallax until you have at least this many pages
private static final int MIN_PARALLAX_PAGE_SPAN = 4;
- private final Workspace<?> mWorkspace;
+ private final Workspace mWorkspace;
private final boolean mIsRtl;
private final Handler mHandler;
@@ -43,7 +41,7 @@ public class WallpaperOffsetInterpolator extends BroadcastReceiver {
private boolean mLockedToDefaultPage;
private int mNumScreens;
- public WallpaperOffsetInterpolator(Workspace<?> workspace) {
+ public WallpaperOffsetInterpolator(Workspace workspace) {
mWorkspace = workspace;
mIsRtl = Utilities.isRtl(workspace.getResources());
mHandler = new OffsetHandler(workspace.getContext());
@@ -65,37 +63,31 @@ public class WallpaperOffsetInterpolator extends BroadcastReceiver {
*
* TODO: do different behavior if it's a live wallpaper?
*/
- private void wallpaperOffsetForScroll(int scroll, int numScrollableScreens, final int[] out) {
+ private void wallpaperOffsetForScroll(int scroll, int numScrollingPages, final int[] out) {
out[1] = 1;
// To match the default wallpaper behavior in the system, we default to either the left
// or right edge on initialization
- if (mLockedToDefaultPage || numScrollableScreens <= 1) {
+ if (mLockedToDefaultPage || numScrollingPages <= 1) {
out[0] = mIsRtl ? 1 : 0;
return;
}
// Distribute the wallpaper parallax over a minimum of MIN_PARALLAX_PAGE_SPAN workspace
// screens, not including the custom screen, and empty screens (if > MIN_PARALLAX_PAGE_SPAN)
- int numScreensForWallpaperParallax = mWallpaperIsLiveWallpaper ? numScrollableScreens :
- Math.max(MIN_PARALLAX_PAGE_SPAN, numScrollableScreens);
+ int numPagesForWallpaperParallax = mWallpaperIsLiveWallpaper ? numScrollingPages :
+ Math.max(MIN_PARALLAX_PAGE_SPAN, numScrollingPages);
// Offset by the custom screen
-
- // Don't confuse screens & pages in this function. In a phone UI, we often use screens &
- // pages interchangeably. However, in a n-panels UI, where n > 1, the screen in this class
- // means the scrollable screen. Each screen can consist of at most n panels.
- // Each panel has at most 1 page. Take 5 pages in 2 panels UI as an example, the Workspace
- // looks as follow:
- //
- // S: scrollable screen, P: page, <E>: empty
- // S0 S1 S2
- // _______ _______ ________
- // |P0|P1| |P2|P3| |P4|<E>|
- // ¯¯¯¯¯¯¯ ¯¯¯¯¯¯¯ ¯¯¯¯¯¯¯¯
- int endIndex = getNumPagesExcludingEmpty() - 1;
- final int leftPageIndex = mIsRtl ? endIndex : 0;
- final int rightPageIndex = mIsRtl ? 0 : endIndex;
+ int leftPageIndex;
+ int rightPageIndex;
+ if (mIsRtl) {
+ rightPageIndex = 0;
+ leftPageIndex = rightPageIndex + numScrollingPages - 1;
+ } else {
+ leftPageIndex = 0;
+ rightPageIndex = leftPageIndex + numScrollingPages - 1;
+ }
// Calculate the scroll range
int leftPageScrollX = mWorkspace.getScrollForPage(leftPageIndex);
@@ -111,56 +103,34 @@ public class WallpaperOffsetInterpolator extends BroadcastReceiver {
int adjustedScroll = scroll - leftPageScrollX -
mWorkspace.getLayoutTransitionOffsetForPage(0);
adjustedScroll = Utilities.boundToRange(adjustedScroll, 0, scrollRange);
- out[1] = (numScreensForWallpaperParallax - 1) * scrollRange;
+ out[1] = (numPagesForWallpaperParallax - 1) * scrollRange;
// The offset is now distributed 0..1 between the left and right pages that we care about,
// so we just map that between the pages that we are using for parallax
int rtlOffset = 0;
if (mIsRtl) {
// In RTL, the pages are right aligned, so adjust the offset from the end
- rtlOffset = out[1] - (numScrollableScreens - 1) * scrollRange;
+ rtlOffset = out[1] - (numScrollingPages - 1) * scrollRange;
}
- out[0] = rtlOffset + adjustedScroll * (numScrollableScreens - 1);
+ out[0] = rtlOffset + adjustedScroll * (numScrollingPages - 1);
}
public float wallpaperOffsetForScroll(int scroll) {
- wallpaperOffsetForScroll(scroll, getNumScrollableScreensExcludingEmpty(), sTempInt);
+ wallpaperOffsetForScroll(scroll, getNumScreensExcludingEmpty(), sTempInt);
return ((float) sTempInt[0]) / sTempInt[1];
}
- /**
- * Returns the number of screens that can be scrolled.
- *
- * <p>In an usual phone UI, the number of scrollable screens is equal to the number of
- * CellLayouts because each screen has exactly 1 CellLayout.
- *
- * <p>In a n-panels UI, a screen shows n panels. Each panel has at most 1 CellLayout. Take
- * 2-panels UI as an example: let's say there are 5 CellLayouts in the Workspace. the number of
- * scrollable screens will be 3 = ⌈5 / 2⌉.
- */
- private int getNumScrollableScreensExcludingEmpty() {
- float numOfPages = getNumPagesExcludingEmpty();
- return (int) Math.ceil(numOfPages / mWorkspace.getPanelCount());
- }
-
- /**
- * Returns the number of non-empty pages in the Workspace.
- *
- * <p>If a user starts dragging on the rightmost (or leftmost in RTL), an empty CellLayout is
- * added to the Workspace. This empty CellLayout add as a hover-over target for adding a new
- * page. To avoid janky motion effect, we ignore this empty CellLayout.
- */
- private int getNumPagesExcludingEmpty() {
- int numOfPages = mWorkspace.getChildCount();
- if (numOfPages >= MIN_PARALLAX_PAGE_SPAN && mWorkspace.hasExtraEmptyScreens()) {
- return numOfPages - mWorkspace.getPanelCount();
+ private int getNumScreensExcludingEmpty() {
+ int numScrollingPages = mWorkspace.getChildCount();
+ if (numScrollingPages >= MIN_PARALLAX_PAGE_SPAN && mWorkspace.hasExtraEmptyScreen()) {
+ return numScrollingPages - 1;
} else {
- return numOfPages;
+ return numScrollingPages;
}
}
public void syncWithScroll() {
- int numScreens = getNumScrollableScreensExcludingEmpty();
+ int numScreens = getNumScreensExcludingEmpty();
wallpaperOffsetForScroll(mWorkspace.getScrollX(), numScreens, sTempInt);
Message msg = Message.obtain(mHandler, MSG_UPDATE_OFFSET, sTempInt[0], sTempInt[1],
mWindowToken);
@@ -184,7 +154,6 @@ public class WallpaperOffsetInterpolator extends BroadcastReceiver {
}
}
- @AnyThread
private void updateOffset() {
Message.obtain(mHandler, MSG_SET_NUM_PARALLAX, getNumPagesForWallpaperParallax(), 0,
mWindowToken).sendToTarget();
@@ -209,12 +178,9 @@ public class WallpaperOffsetInterpolator extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
- UI_HELPER_EXECUTOR.execute(() -> {
- // Updating the boolean on a background thread is fine as the assignments are atomic
- mWallpaperIsLiveWallpaper =
- WallpaperManager.getInstance(context).getWallpaperInfo() != null;
- updateOffset();
- });
+ mWallpaperIsLiveWallpaper =
+ WallpaperManager.getInstance(mWorkspace.getContext()).getWallpaperInfo() != null;
+ updateOffset();
}
private static final int MSG_START_ANIMATION = 1;
diff --git a/src/com/android/launcher3/util/WindowBounds.java b/src/com/android/launcher3/util/WindowBounds.java
index a15679a822..c92770e8fd 100644
--- a/src/com/android/launcher3/util/WindowBounds.java
+++ b/src/com/android/launcher3/util/WindowBounds.java
@@ -33,27 +33,19 @@ public class WindowBounds {
public final Rect bounds;
public final Rect insets;
public final Point availableSize;
- public final int rotationHint;
public WindowBounds(Rect bounds, Rect insets) {
- this(bounds, insets, -1);
- }
-
- public WindowBounds(Rect bounds, Rect insets, int rotationHint) {
this.bounds = bounds;
this.insets = insets;
- this.rotationHint = rotationHint;
availableSize = new Point(bounds.width() - insets.left - insets.right,
bounds.height() - insets.top - insets.bottom);
}
- public WindowBounds(int width, int height, int availableWidth, int availableHeight,
- int rotationHint) {
+ public WindowBounds(int width, int height, int availableWidth, int availableHeight) {
this.bounds = new Rect(0, 0, width, height);
this.availableSize = new Point(availableWidth, availableHeight);
// We don't care about insets in this case
this.insets = new Rect(0, 0, width - availableWidth, height - availableHeight);
- this.rotationHint = rotationHint;
}
@Override
diff --git a/src/com/android/launcher3/util/WindowManagerCompat.java b/src/com/android/launcher3/util/WindowManagerCompat.java
new file mode 100644
index 0000000000..38a63de592
--- /dev/null
+++ b/src/com/android/launcher3/util/WindowManagerCompat.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2021 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.launcher3.util;
+
+import static com.android.launcher3.ResourceUtils.INVALID_RESOURCE_HANDLE;
+import static com.android.launcher3.Utilities.dpiFromPx;
+
+import android.annotation.TargetApi;
+import android.content.Context;
+import android.content.res.Configuration;
+import android.graphics.Insets;
+import android.graphics.Rect;
+import android.os.Build;
+import android.view.WindowInsets;
+import android.view.WindowInsets.Type;
+import android.view.WindowManager;
+import android.view.WindowMetrics;
+
+import com.android.launcher3.R;
+import com.android.launcher3.ResourceUtils;
+import com.android.launcher3.util.DisplayController.PortraitSize;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Utility class to simulate window manager APIs until proper APIs are available
+ */
+@TargetApi(Build.VERSION_CODES.S)
+public class WindowManagerCompat {
+
+ public static final int MIN_TABLET_WIDTH = 600;
+
+ /**
+ * Returns a set of supported render sizes for a set of internal displays.
+ * This is a temporary workaround which assumes only nav-bar insets change across displays
+ * @param consumeTaskBar if true, it assumes that task bar is part of the app window
+ * and ignores any insets because of task bar.
+ */
+ public static Set<WindowMetrics> getDisplayProfiles(
+ Context windowContext, Collection<PortraitSize> allDisplaySizes,
+ int densityDpi, boolean consumeTaskBar) {
+ WindowInsets metrics = windowContext.getSystemService(WindowManager.class)
+ .getMaximumWindowMetrics().getWindowInsets();
+ boolean hasNavbar = ResourceUtils.getIntegerByName(
+ "config_navBarInteractionMode",
+ windowContext.getResources(),
+ INVALID_RESOURCE_HANDLE) != 0;
+
+ WindowInsets.Builder insetsBuilder = new WindowInsets.Builder(metrics);
+
+ Set<WindowMetrics> result = new HashSet<>();
+ for (PortraitSize size : allDisplaySizes) {
+ int swDP = (int) dpiFromPx(size.width, densityDpi);
+ boolean isTablet = swDP >= MIN_TABLET_WIDTH;
+
+ final Insets portraitNav, landscapeNav;
+ if (isTablet && !consumeTaskBar) {
+ portraitNav = landscapeNav = Insets.of(0, 0, 0, windowContext.getResources()
+ .getDimensionPixelSize(R.dimen.taskbar_size));
+ } else if (hasNavbar) {
+ portraitNav = Insets.of(0, 0, 0,
+ getSystemResource(windowContext, "navigation_bar_height", swDP));
+ landscapeNav = isTablet
+ ? Insets.of(0, 0, 0, getSystemResource(windowContext,
+ "navigation_bar_height_landscape", swDP))
+ : Insets.of(0, 0, getSystemResource(windowContext,
+ "navigation_bar_width", swDP), 0);
+ } else {
+ portraitNav = landscapeNav = Insets.of(0, 0, 0, 0);
+ }
+
+ result.add(new WindowMetrics(
+ new Rect(0, 0, size.width, size.height),
+ insetsBuilder.setInsets(Type.navigationBars(), portraitNav).build()));
+ result.add(new WindowMetrics(
+ new Rect(0, 0, size.height, size.width),
+ insetsBuilder.setInsets(Type.navigationBars(), landscapeNav).build()));
+ }
+ return result;
+ }
+
+ private static int getSystemResource(Context context, String key, int swDp) {
+ int resourceId = context.getResources().getIdentifier(key, "dimen", "android");
+ if (resourceId > 0) {
+ Configuration conf = new Configuration();
+ conf.smallestScreenWidthDp = swDp;
+ return context.createConfigurationContext(conf)
+ .getResources().getDimensionPixelSize(resourceId);
+ }
+ return 0;
+ }
+}
diff --git a/src/com/android/launcher3/util/window/CachedDisplayInfo.java b/src/com/android/launcher3/util/window/CachedDisplayInfo.java
deleted file mode 100644
index 06b9829270..0000000000
--- a/src/com/android/launcher3/util/window/CachedDisplayInfo.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.launcher3.util.window;
-
-import static com.android.launcher3.util.RotationUtils.deltaRotation;
-import static com.android.launcher3.util.RotationUtils.rotateRect;
-import static com.android.launcher3.util.RotationUtils.rotateSize;
-
-import android.graphics.Point;
-import android.graphics.Rect;
-import android.view.Surface;
-
-import java.util.Objects;
-
-/**
- * Properties on a display
- */
-public class CachedDisplayInfo {
-
- public final String id;
- public final Point size;
- public final int rotation;
- public final Rect cutout;
-
- public CachedDisplayInfo() {
- this(new Point(0, 0), 0);
- }
-
- public CachedDisplayInfo(Point size, int rotation) {
- this("", size, rotation, new Rect());
- }
-
- public CachedDisplayInfo(String id, Point size, int rotation, Rect cutout) {
- this.id = id;
- this.size = size;
- this.rotation = rotation;
- this.cutout = cutout;
- }
-
- /**
- * Returns a CachedDisplayInfo where the properties are normalized to {@link Surface#ROTATION_0}
- */
- public CachedDisplayInfo normalize() {
- if (rotation == Surface.ROTATION_0) {
- return this;
- }
- Point newSize = new Point(size);
- rotateSize(newSize, deltaRotation(rotation, Surface.ROTATION_0));
-
- Rect newCutout = new Rect(cutout);
- rotateRect(newCutout, deltaRotation(rotation, Surface.ROTATION_0));
- return new CachedDisplayInfo(id, newSize, Surface.ROTATION_0, newCutout);
- }
-
- @Override
- public String toString() {
- return "CachedDisplayInfo{"
- + "id='" + id + '\''
- + ", size=" + size
- + ", rotation=" + rotation
- + ", cutout=" + cutout
- + '}';
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (!(o instanceof CachedDisplayInfo)) return false;
- CachedDisplayInfo that = (CachedDisplayInfo) o;
- return rotation == that.rotation && Objects.equals(id, that.id)
- && Objects.equals(size, that.size) && Objects.equals(cutout,
- that.cutout);
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(id, size, rotation, cutout);
- }
-}
diff --git a/src/com/android/launcher3/util/window/RefreshRateTracker.java b/src/com/android/launcher3/util/window/RefreshRateTracker.java
deleted file mode 100644
index 7814617b9e..0000000000
--- a/src/com/android/launcher3/util/window/RefreshRateTracker.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.launcher3.util.window;
-
-import static android.view.Display.DEFAULT_DISPLAY;
-
-import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
-
-import android.content.Context;
-import android.hardware.display.DisplayManager;
-import android.hardware.display.DisplayManager.DisplayListener;
-import android.view.Display;
-
-import androidx.annotation.WorkerThread;
-
-import com.android.launcher3.util.MainThreadInitializedObject;
-import com.android.launcher3.util.SafeCloseable;
-
-/**
- * Utility class to track refresh rate of the current device
- */
-public class RefreshRateTracker implements DisplayListener, SafeCloseable {
-
- private static final MainThreadInitializedObject<RefreshRateTracker> INSTANCE =
- new MainThreadInitializedObject<>(RefreshRateTracker::new);
-
- private int mSingleFrameMs = 1;
-
- private final DisplayManager mDM;
-
- private RefreshRateTracker(Context context) {
- mDM = context.getSystemService(DisplayManager.class);
- updateSingleFrameMs();
- mDM.registerDisplayListener(this, UI_HELPER_EXECUTOR.getHandler());
- }
-
- /**
- * Returns the single frame time in ms
- */
- public static int getSingleFrameMs(Context context) {
- return INSTANCE.get(context).mSingleFrameMs;
- }
-
- @Override
- public final void onDisplayAdded(int displayId) { }
-
- @Override
- public final void onDisplayRemoved(int displayId) { }
-
- @WorkerThread
- @Override
- public final void onDisplayChanged(int displayId) {
- if (displayId == DEFAULT_DISPLAY) {
- updateSingleFrameMs();
- }
- }
-
- private void updateSingleFrameMs() {
- Display display = mDM.getDisplay(DEFAULT_DISPLAY);
- if (display != null) {
- float refreshRate = display.getRefreshRate();
- mSingleFrameMs = refreshRate > 0 ? (int) (1000 / refreshRate) : 16;
- }
- }
-
- @Override
- public void close() {
- mDM.unregisterDisplayListener(this);
- }
-}
diff --git a/src/com/android/launcher3/util/window/WindowManagerProxy.java b/src/com/android/launcher3/util/window/WindowManagerProxy.java
deleted file mode 100644
index 9665bf91c5..0000000000
--- a/src/com/android/launcher3/util/window/WindowManagerProxy.java
+++ /dev/null
@@ -1,365 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.launcher3.util.window;
-
-import static android.view.Display.DEFAULT_DISPLAY;
-import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
-
-import static com.android.launcher3.ResourceUtils.INVALID_RESOURCE_HANDLE;
-import static com.android.launcher3.ResourceUtils.NAVBAR_HEIGHT;
-import static com.android.launcher3.ResourceUtils.NAVBAR_HEIGHT_LANDSCAPE;
-import static com.android.launcher3.ResourceUtils.NAVBAR_LANDSCAPE_LEFT_RIGHT_SIZE;
-import static com.android.launcher3.ResourceUtils.STATUS_BAR_HEIGHT;
-import static com.android.launcher3.ResourceUtils.STATUS_BAR_HEIGHT_LANDSCAPE;
-import static com.android.launcher3.ResourceUtils.STATUS_BAR_HEIGHT_PORTRAIT;
-import static com.android.launcher3.Utilities.dpiFromPx;
-import static com.android.launcher3.util.MainThreadInitializedObject.forOverride;
-import static com.android.launcher3.util.RotationUtils.deltaRotation;
-import static com.android.launcher3.util.RotationUtils.rotateRect;
-import static com.android.launcher3.util.RotationUtils.rotateSize;
-
-import android.annotation.TargetApi;
-import android.content.Context;
-import android.content.res.Configuration;
-import android.content.res.Resources;
-import android.graphics.Insets;
-import android.graphics.Point;
-import android.graphics.Rect;
-import android.hardware.display.DisplayManager;
-import android.os.Build;
-import android.util.ArrayMap;
-import android.util.Pair;
-import android.view.Display;
-import android.view.DisplayCutout;
-import android.view.Surface;
-import android.view.WindowInsets;
-import android.view.WindowManager;
-import android.view.WindowMetrics;
-
-import com.android.launcher3.R;
-import com.android.launcher3.ResourceUtils;
-import com.android.launcher3.Utilities;
-import com.android.launcher3.util.MainThreadInitializedObject;
-import com.android.launcher3.util.ResourceBasedOverride;
-import com.android.launcher3.util.WindowBounds;
-
-/**
- * Utility class for mocking some window manager behaviours
- */
-public class WindowManagerProxy implements ResourceBasedOverride {
-
- public static final int MIN_TABLET_WIDTH = 600;
-
- public static final MainThreadInitializedObject<WindowManagerProxy> INSTANCE =
- forOverride(WindowManagerProxy.class, R.string.window_manager_proxy_class);
-
- protected final boolean mTaskbarDrawnInProcess;
-
- /**
- * Creates a new instance of proxy, applying any overrides
- */
- public static WindowManagerProxy newInstance(Context context) {
- return Overrides.getObject(WindowManagerProxy.class, context,
- R.string.window_manager_proxy_class);
- }
-
- public WindowManagerProxy() {
- this(false);
- }
-
- protected WindowManagerProxy(boolean taskbarDrawnInProcess) {
- mTaskbarDrawnInProcess = taskbarDrawnInProcess;
- }
-
- /**
- * Returns a map of normalized info of internal displays to estimated window bounds
- * for that display
- */
- public ArrayMap<String, Pair<CachedDisplayInfo, WindowBounds[]>> estimateInternalDisplayBounds(
- Context context) {
- Display[] displays = getDisplays(context);
- ArrayMap<String, Pair<CachedDisplayInfo, WindowBounds[]>> result = new ArrayMap<>();
- for (Display display : displays) {
- if (isInternalDisplay(display)) {
- Context displayContext = Utilities.ATLEAST_S
- ? context.createWindowContext(display, TYPE_APPLICATION, null)
- : context.createDisplayContext(display);
- CachedDisplayInfo info = getDisplayInfo(displayContext, display).normalize();
- WindowBounds[] bounds = estimateWindowBounds(context, info);
- result.put(info.id, Pair.create(info, bounds));
- }
- }
- return result;
- }
-
- /**
- * Returns the real bounds for the provided display after applying any insets normalization
- */
- @TargetApi(Build.VERSION_CODES.R)
- public WindowBounds getRealBounds(Context windowContext,
- Display display, CachedDisplayInfo info) {
- if (!Utilities.ATLEAST_R) {
- Point smallestSize = new Point();
- Point largestSize = new Point();
- display.getCurrentSizeRange(smallestSize, largestSize);
-
- if (info.size.y > info.size.x) {
- // Portrait
- return new WindowBounds(info.size.x, info.size.y, smallestSize.x, largestSize.y,
- info.rotation);
- } else {
- // Landscape
- new WindowBounds(info.size.x, info.size.y, largestSize.x, smallestSize.y,
- info.rotation);
- }
- }
-
- WindowMetrics wm = windowContext.getSystemService(WindowManager.class)
- .getMaximumWindowMetrics();
-
- Rect insets = new Rect();
- normalizeWindowInsets(windowContext, wm.getWindowInsets(), insets);
- return new WindowBounds(wm.getBounds(), insets, info.rotation);
- }
-
- /**
- * Returns an updated insets, accounting for various Launcher UI specific overrides like taskbar
- */
- @TargetApi(Build.VERSION_CODES.R)
- public WindowInsets normalizeWindowInsets(Context context, WindowInsets oldInsets,
- Rect outInsets) {
- if (!Utilities.ATLEAST_R || !mTaskbarDrawnInProcess) {
- outInsets.set(oldInsets.getSystemWindowInsetLeft(), oldInsets.getSystemWindowInsetTop(),
- oldInsets.getSystemWindowInsetRight(), oldInsets.getSystemWindowInsetBottom());
- return oldInsets;
- }
-
- WindowInsets.Builder insetsBuilder = new WindowInsets.Builder(oldInsets);
- Insets navInsets = oldInsets.getInsets(WindowInsets.Type.navigationBars());
-
- Resources systemRes = context.getResources();
- Configuration config = systemRes.getConfiguration();
-
- boolean isTablet = config.smallestScreenWidthDp > MIN_TABLET_WIDTH;
- boolean isGesture = isGestureNav(context);
- boolean isPortrait = config.screenHeightDp > config.screenWidthDp;
-
- int bottomNav = isTablet
- ? 0
- : (isPortrait
- ? getDimenByName(systemRes, NAVBAR_HEIGHT)
- : (isGesture
- ? getDimenByName(systemRes, NAVBAR_HEIGHT_LANDSCAPE)
- : 0));
- Insets newNavInsets = Insets.of(navInsets.left, navInsets.top, navInsets.right, bottomNav);
- insetsBuilder.setInsets(WindowInsets.Type.navigationBars(), newNavInsets);
- insetsBuilder.setInsetsIgnoringVisibility(WindowInsets.Type.navigationBars(), newNavInsets);
-
- Insets statusBarInsets = oldInsets.getInsets(WindowInsets.Type.statusBars());
-
-
- int statusBarHeight = getDimenByName(systemRes,
- (isPortrait) ? STATUS_BAR_HEIGHT_PORTRAIT : STATUS_BAR_HEIGHT_LANDSCAPE,
- STATUS_BAR_HEIGHT);
-
- Insets newStatusBarInsets = Insets.of(
- statusBarInsets.left,
- Math.max(statusBarInsets.top, statusBarHeight),
- statusBarInsets.right,
- statusBarInsets.bottom);
- insetsBuilder.setInsets(WindowInsets.Type.statusBars(), newStatusBarInsets);
- insetsBuilder.setInsetsIgnoringVisibility(
- WindowInsets.Type.statusBars(), newStatusBarInsets);
-
- // Override the tappable insets to be 0 on the bottom for gesture nav (otherwise taskbar
- // would count towards it). This is used for the bottom protection in All Apps for example.
- if (isGesture) {
- Insets oldTappableInsets = oldInsets.getInsets(WindowInsets.Type.tappableElement());
- Insets newTappableInsets = Insets.of(oldTappableInsets.left, oldTappableInsets.top,
- oldTappableInsets.right, 0);
- insetsBuilder.setInsets(WindowInsets.Type.tappableElement(), newTappableInsets);
- }
-
- WindowInsets result = insetsBuilder.build();
- Insets systemWindowInsets = result.getInsetsIgnoringVisibility(
- WindowInsets.Type.systemBars() | WindowInsets.Type.displayCutout());
- outInsets.set(systemWindowInsets.left, systemWindowInsets.top, systemWindowInsets.right,
- systemWindowInsets.bottom);
- return result;
- }
-
- /**
- * Returns true if the display is an internal displays
- */
- protected boolean isInternalDisplay(Display display) {
- return display.getDisplayId() == Display.DEFAULT_DISPLAY;
- }
-
- /**
- * Returns a list of possible WindowBounds for the display keyed on the 4 surface rotations
- */
- public WindowBounds[] estimateWindowBounds(Context context, CachedDisplayInfo display) {
- int densityDpi = context.getResources().getConfiguration().densityDpi;
- int rotation = display.rotation;
- Rect safeCutout = display.cutout;
-
- int minSize = Math.min(display.size.x, display.size.y);
- int swDp = (int) dpiFromPx(minSize, densityDpi);
-
- Resources systemRes;
- {
- Configuration conf = new Configuration();
- conf.smallestScreenWidthDp = swDp;
- systemRes = context.createConfigurationContext(conf).getResources();
- }
-
- boolean isTablet = swDp >= MIN_TABLET_WIDTH;
- boolean isTabletOrGesture = isTablet
- || (Utilities.ATLEAST_R && isGestureNav(context));
-
- int statusBarHeightPortrait = getDimenByName(systemRes,
- STATUS_BAR_HEIGHT_PORTRAIT, STATUS_BAR_HEIGHT);
- int statusBarHeightLandscape = getDimenByName(systemRes,
- STATUS_BAR_HEIGHT_LANDSCAPE, STATUS_BAR_HEIGHT);
-
- int navBarHeightPortrait, navBarHeightLandscape, navbarWidthLandscape;
-
- navBarHeightPortrait = isTablet
- ? (mTaskbarDrawnInProcess
- ? 0 : systemRes.getDimensionPixelSize(R.dimen.taskbar_size))
- : getDimenByName(systemRes, NAVBAR_HEIGHT);
-
- navBarHeightLandscape = isTablet
- ? (mTaskbarDrawnInProcess
- ? 0 : systemRes.getDimensionPixelSize(R.dimen.taskbar_size))
- : (isTabletOrGesture
- ? getDimenByName(systemRes, NAVBAR_HEIGHT_LANDSCAPE) : 0);
- navbarWidthLandscape = isTabletOrGesture
- ? 0
- : getDimenByName(systemRes, NAVBAR_LANDSCAPE_LEFT_RIGHT_SIZE);
-
- WindowBounds[] result = new WindowBounds[4];
- Point tempSize = new Point();
- for (int i = 0; i < 4; i++) {
- int rotationChange = deltaRotation(rotation, i);
- tempSize.set(display.size.x, display.size.y);
- rotateSize(tempSize, rotationChange);
- Rect bounds = new Rect(0, 0, tempSize.x, tempSize.y);
-
- int navBarHeight, navbarWidth, statusBarHeight;
- if (tempSize.y > tempSize.x) {
- navBarHeight = navBarHeightPortrait;
- navbarWidth = 0;
- statusBarHeight = statusBarHeightPortrait;
- } else {
- navBarHeight = navBarHeightLandscape;
- navbarWidth = navbarWidthLandscape;
- statusBarHeight = statusBarHeightLandscape;
- }
-
- Rect insets = new Rect(safeCutout);
- rotateRect(insets, rotationChange);
- insets.top = Math.max(insets.top, statusBarHeight);
- insets.bottom = Math.max(insets.bottom, navBarHeight);
-
- if (i == Surface.ROTATION_270 || i == Surface.ROTATION_180) {
- // On reverse landscape (and in rare-case when the natural orientation of the
- // device is landscape), navigation bar is on the right.
- insets.left = Math.max(insets.left, navbarWidth);
- } else {
- insets.right = Math.max(insets.right, navbarWidth);
- }
- result[i] = new WindowBounds(bounds, insets, i);
- }
- return result;
- }
-
- /**
- * Wrapper around the utility method for easier emulation
- */
- protected int getDimenByName(Resources res, String resName) {
- return ResourceUtils.getDimenByName(resName, res, 0);
- }
-
- /**
- * Wrapper around the utility method for easier emulation
- */
- protected int getDimenByName(Resources res, String resName, String fallback) {
- int dimen = ResourceUtils.getDimenByName(resName, res, -1);
- return dimen > -1 ? dimen : getDimenByName(res, fallback);
- }
-
- protected boolean isGestureNav(Context context) {
- return ResourceUtils.getIntegerByName("config_navBarInteractionMode",
- context.getResources(), INVALID_RESOURCE_HANDLE) == 2;
- }
-
- /**
- * Returns a CachedDisplayInfo initialized for the current display
- */
- @TargetApi(Build.VERSION_CODES.S)
- public CachedDisplayInfo getDisplayInfo(Context displayContext, Display display) {
- int rotation = getRotation(displayContext);
- Rect cutoutRect = new Rect();
- Point size = new Point();
- if (Utilities.ATLEAST_S) {
- WindowMetrics wm = displayContext.getSystemService(WindowManager.class)
- .getMaximumWindowMetrics();
- DisplayCutout cutout = wm.getWindowInsets().getDisplayCutout();
- if (cutout != null) {
- cutoutRect.set(cutout.getSafeInsetLeft(), cutout.getSafeInsetTop(),
- cutout.getSafeInsetRight(), cutout.getSafeInsetBottom());
- }
-
- size.set(wm.getBounds().right, wm.getBounds().bottom);
- } else {
- display.getRealSize(size);
- }
- return new CachedDisplayInfo(getDisplayId(display), size, rotation, cutoutRect);
- }
-
- /**
- * Returns a unique ID representing the display
- */
- protected String getDisplayId(Display display) {
- return Integer.toString(display.getDisplayId());
- }
-
- /**
- * Returns rotation of the display associated with the context.
- */
- public int getRotation(Context context) {
- Display d = null;
- if (Utilities.ATLEAST_R) {
- try {
- d = context.getDisplay();
- } catch (UnsupportedOperationException e) {
- // Ignore
- }
- }
- if (d == null) {
- d = context.getSystemService(DisplayManager.class).getDisplay(DEFAULT_DISPLAY);
- }
- return d.getRotation();
- }
-
- /**
- * Returns all currently valid logical displays.
- */
- protected Display[] getDisplays(Context context) {
- return context.getSystemService(DisplayManager.class).getDisplays();
- }
-}
diff --git a/src/com/android/launcher3/views/AbstractSlideInView.java b/src/com/android/launcher3/views/AbstractSlideInView.java
index 47503b118e..92ca8a17b8 100644
--- a/src/com/android/launcher3/views/AbstractSlideInView.java
+++ b/src/com/android/launcher3/views/AbstractSlideInView.java
@@ -17,8 +17,6 @@ package com.android.launcher3.views;
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
-import static com.android.launcher3.LauncherAnimUtils.SUCCESS_TRANSITION_PROGRESS;
-import static com.android.launcher3.LauncherAnimUtils.TABLET_BOTTOM_SHEET_SUCCESS_TRANSITION_PROGRESS;
import static com.android.launcher3.anim.Interpolators.scrollInterpolatorForVelocity;
import android.animation.Animator;
@@ -30,7 +28,6 @@ import android.util.AttributeSet;
import android.util.Property;
import android.view.MotionEvent;
import android.view.View;
-import android.view.ViewGroup;
import android.view.animation.Interpolator;
import com.android.launcher3.AbstractFloatingView;
@@ -71,7 +68,7 @@ public abstract class AbstractSlideInView<T extends Context & ActivityContext>
protected final SingleAxisSwipeDetector mSwipeDetector;
protected final ObjectAnimator mOpenCloseAnimator;
- protected ViewGroup mContent;
+ protected View mContent;
protected final View mColorScrim;
protected Interpolator mScrollInterpolator;
@@ -115,16 +112,9 @@ public abstract class AbstractSlideInView<T extends Context & ActivityContext>
return -1;
}
- /**
- * Returns the range in height that the slide in view can be dragged.
- */
- protected float getShiftRange() {
- return mContent.getHeight();
- }
-
protected void setTranslationShift(float translationShift) {
mTranslationShift = translationShift;
- mContent.setTranslationY(mTranslationShift * getShiftRange());
+ mContent.setTranslationY(mTranslationShift * mContent.getHeight());
if (mColorScrim != null) {
mColorScrim.setAlpha(1 - mTranslationShift);
}
@@ -141,7 +131,8 @@ public abstract class AbstractSlideInView<T extends Context & ActivityContext>
mSwipeDetector.setDetectableScrollConditions(
directionsToDetectScroll, false);
mSwipeDetector.onTouchEvent(ev);
- return mSwipeDetector.isDraggingOrSettling() || !isEventOverContent(ev);
+ return mSwipeDetector.isDraggingOrSettling()
+ || !getPopupContainer().isEventOverView(mContent, ev);
}
@Override
@@ -150,23 +141,13 @@ public abstract class AbstractSlideInView<T extends Context & ActivityContext>
if (ev.getAction() == MotionEvent.ACTION_UP && mSwipeDetector.isIdleState()
&& !isOpeningAnimationRunning()) {
// If we got ACTION_UP without ever starting swipe, close the panel.
- if (!isEventOverContent(ev)) {
+ if (!getPopupContainer().isEventOverView(mContent, ev)) {
close(true);
}
}
return true;
}
- /**
- * Returns {@code true} if the touch event is over the visible area of the bottom sheet.
- *
- * By default will check if the touch event is over {@code mContent}, subclasses should override
- * this method if the visible area of the bottom sheet is different from {@code mContent}.
- */
- protected boolean isEventOverContent(MotionEvent ev) {
- return getPopupContainer().isEventOverView(mContent, ev);
- }
-
private boolean isOpeningAnimationRunning() {
return mIsOpen && mOpenCloseAnimator.isRunning();
}
@@ -178,7 +159,7 @@ public abstract class AbstractSlideInView<T extends Context & ActivityContext>
@Override
public boolean onDrag(float displacement) {
- float range = getShiftRange();
+ float range = mContent.getHeight();
displacement = Utilities.boundToRange(displacement, 0, range);
setTranslationShift(displacement / range);
return true;
@@ -186,10 +167,7 @@ public abstract class AbstractSlideInView<T extends Context & ActivityContext>
@Override
public void onDragEnd(float velocity) {
- float successfulShiftThreshold = mActivityContext.getDeviceProfile().isTablet
- ? TABLET_BOTTOM_SHEET_SUCCESS_TRANSITION_PROGRESS : SUCCESS_TRANSITION_PROGRESS;
- if ((mSwipeDetector.isFling(velocity) && velocity > 0)
- || mTranslationShift > successfulShiftThreshold) {
+ if ((mSwipeDetector.isFling(velocity) && velocity > 0) || mTranslationShift > 0.5f) {
mScrollInterpolator = scrollInterpolatorForVelocity(velocity);
mOpenCloseAnimator.setDuration(BaseSwipeDetector.calculateDuration(
velocity, TRANSLATION_SHIFT_CLOSED - mTranslationShift));
@@ -224,24 +202,19 @@ public abstract class AbstractSlideInView<T extends Context & ActivityContext>
mOpenCloseAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
- mOpenCloseAnimator.removeListener(this);
onCloseComplete();
}
});
if (mSwipeDetector.isIdleState()) {
mOpenCloseAnimator
.setDuration(defaultDuration)
- .setInterpolator(getIdleInterpolator());
+ .setInterpolator(Interpolators.ACCEL);
} else {
mOpenCloseAnimator.setInterpolator(mScrollInterpolator);
}
mOpenCloseAnimator.start();
}
- protected Interpolator getIdleInterpolator() {
- return Interpolators.ACCEL;
- }
-
protected void onCloseComplete() {
mIsOpen = false;
getPopupContainer().removeView(this);
diff --git a/src/com/android/launcher3/views/ActivityContext.java b/src/com/android/launcher3/views/ActivityContext.java
index 93078e4cf6..646b66942c 100644
--- a/src/com/android/launcher3/views/ActivityContext.java
+++ b/src/com/android/launcher3/views/ActivityContext.java
@@ -19,23 +19,12 @@ import android.content.Context;
import android.content.ContextWrapper;
import android.graphics.Rect;
import android.view.LayoutInflater;
-import android.view.View;
import android.view.View.AccessibilityDelegate;
-import androidx.annotation.Nullable;
-
import com.android.launcher3.DeviceProfile;
-import com.android.launcher3.allapps.ActivityAllAppsContainerView;
-import com.android.launcher3.allapps.search.SearchAdapterProvider;
import com.android.launcher3.dot.DotInfo;
import com.android.launcher3.dragndrop.DragController;
-import com.android.launcher3.folder.FolderIcon;
-import com.android.launcher3.logger.LauncherAtom;
-import com.android.launcher3.logging.StatsLogManager;
-import com.android.launcher3.model.StringCache;
import com.android.launcher3.model.data.ItemInfo;
-import com.android.launcher3.popup.PopupDataProvider;
-import com.android.launcher3.util.OnboardingPrefs;
import com.android.launcher3.util.ViewCache;
/**
@@ -97,13 +86,6 @@ public interface ActivityContext {
*/
BaseDragLayer getDragLayer();
- /**
- * The all apps container, if it exists in this context.
- */
- default ActivityAllAppsContainerView<?> getAppsView() {
- return null;
- }
-
DeviceProfile getDeviceProfile();
default ViewCache getViewCache() {
@@ -118,87 +100,15 @@ public interface ActivityContext {
}
/**
- * Returns the FolderIcon with the given item id, if it exists.
- */
- default @Nullable FolderIcon findFolderIcon(final int folderIconId) {
- return null;
- }
-
- default StatsLogManager getStatsLogManager() {
- return StatsLogManager.newInstance((Context) this);
- }
-
- /**
- * Returns {@code true} if popups should use color extraction.
- */
- default boolean shouldUseColorExtractionForPopup() {
- return true;
- }
-
- /**
- * Called just before logging the given item.
- */
- default void applyOverwritesToLogItem(LauncherAtom.ItemInfo.Builder itemInfoBuilder) { }
-
- /** Onboarding preferences for any onboarding data within this context. */
- default OnboardingPrefs<?> getOnboardingPrefs() {
- return null;
- }
-
- /** Returns {@code true} if items are currently being bound within this context. */
- default boolean isBindingItems() {
- return false;
- }
-
- /**
- * Returns the ActivityContext associated with the given Context, or throws an exception if
- * the Context is not associated with any ActivityContext.
+ * Returns the ActivityContext associated with the given Context.
*/
static <T extends Context & ActivityContext> T lookupContext(Context context) {
- T activityContext = lookupContextNoThrow(context);
- if (activityContext == null) {
- throw new IllegalArgumentException("Cannot find ActivityContext in parent tree");
- }
- return activityContext;
- }
-
- /**
- * Returns the ActivityContext associated with the given Context, or null if
- * the Context is not associated with any ActivityContext.
- */
- static <T extends Context & ActivityContext> T lookupContextNoThrow(Context context) {
if (context instanceof ActivityContext) {
return (T) context;
} else if (context instanceof ContextWrapper) {
- return lookupContextNoThrow(((ContextWrapper) context).getBaseContext());
+ return lookupContext(((ContextWrapper) context).getBaseContext());
} else {
- return null;
+ throw new IllegalArgumentException("Cannot find ActivityContext in parent tree");
}
}
-
- default View.OnClickListener getItemOnClickListener() {
- return v -> {
- // No op.
- };
- }
-
- @Nullable
- default PopupDataProvider getPopupDataProvider() {
- return null;
- }
-
- @Nullable
- default StringCache getStringCache() {
- return null;
- }
-
- /**
- * Creates and returns {@link SearchAdapterProvider} for build variant specific search result
- * views.
- */
- @Nullable
- default SearchAdapterProvider<?> createSearchAdapterProvider(
- ActivityAllAppsContainerView<?> appsView) {
- return null;
- }
}
diff --git a/src/com/android/launcher3/views/AllAppsButton.java b/src/com/android/launcher3/views/AllAppsButton.java
deleted file mode 100644
index b1e69c7de4..0000000000
--- a/src/com/android/launcher3/views/AllAppsButton.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.launcher3.views;
-
-import android.content.Context;
-import android.graphics.Bitmap;
-import android.util.AttributeSet;
-import android.view.ContextThemeWrapper;
-
-import com.android.launcher3.BubbleTextView;
-import com.android.launcher3.LauncherAppState;
-import com.android.launcher3.R;
-import com.android.launcher3.icons.FastBitmapDrawable;
-
-/**
- * Button in Taskbar that opens All Apps.
- */
-public class AllAppsButton extends BubbleTextView {
-
- public AllAppsButton(Context context) {
- this(context, null);
- }
-
- public AllAppsButton(Context context, AttributeSet attrs) {
- this(context, attrs, 0);
- }
-
- public AllAppsButton(Context context, AttributeSet attrs, int defStyle) {
- super(context, attrs, defStyle);
-
- Context theme = new ContextThemeWrapper(context, R.style.AllAppsButtonTheme);
- Bitmap bitmap = LauncherAppState.getInstance(context).getIconCache().getIconFactory()
- .createScaledBitmapWithShadow(theme.getDrawable(R.drawable.ic_all_apps_button));
- setIcon(new FastBitmapDrawable(bitmap));
- }
-}
diff --git a/src/com/android/launcher3/views/AppLauncher.java b/src/com/android/launcher3/views/AppLauncher.java
deleted file mode 100644
index 19e66abd78..0000000000
--- a/src/com/android/launcher3/views/AppLauncher.java
+++ /dev/null
@@ -1,213 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.launcher3.views;
-
-import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_APP_LAUNCH_TAP;
-import static com.android.launcher3.model.WidgetsModel.GO_DISABLE_WIDGETS;
-
-import android.app.ActivityOptions;
-import android.content.ActivityNotFoundException;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.LauncherApps;
-import android.graphics.Rect;
-import android.graphics.drawable.Drawable;
-import android.os.Bundle;
-import android.os.Process;
-import android.os.StrictMode;
-import android.os.UserHandle;
-import android.util.Log;
-import android.view.Display;
-import android.view.View;
-import android.widget.Toast;
-
-import androidx.annotation.Nullable;
-
-import com.android.launcher3.BubbleTextView;
-import com.android.launcher3.LauncherSettings;
-import com.android.launcher3.R;
-import com.android.launcher3.Utilities;
-import com.android.launcher3.logging.InstanceId;
-import com.android.launcher3.logging.InstanceIdSequence;
-import com.android.launcher3.logging.StatsLogManager;
-import com.android.launcher3.model.data.ItemInfo;
-import com.android.launcher3.model.data.WorkspaceItemInfo;
-import com.android.launcher3.util.ActivityOptionsWrapper;
-import com.android.launcher3.util.PackageManagerHelper;
-import com.android.launcher3.util.RunnableList;
-
-/** An {@link ActivityContext} that can also launch app activities and shortcuts safely. */
-public interface AppLauncher extends ActivityContext {
-
- String TAG = "AppLauncher";
-
- /**
- * Safely starts an activity.
- *
- * @param v View starting the activity.
- * @param intent Base intent being launched.
- * @param item Item associated with the view.
- * @return {@code true} if the activity starts successfully.
- */
- default boolean startActivitySafely(
- View v, Intent intent, @Nullable ItemInfo item) {
-
- Context context = (Context) this;
- if (isAppBlockedForSafeMode() && !PackageManagerHelper.isSystemApp(context, intent)) {
- Toast.makeText(context, R.string.safemode_shortcut_error, Toast.LENGTH_SHORT).show();
- return false;
- }
-
- Bundle optsBundle = (v != null) ? getActivityLaunchOptions(v, item).toBundle() : null;
- UserHandle user = item == null ? null : item.user;
-
- // Prepare intent
- intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- if (v != null) {
- intent.setSourceBounds(Utilities.getViewBounds(v));
- }
- try {
- boolean isShortcut = (item instanceof WorkspaceItemInfo)
- && (item.itemType == LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT
- || item.itemType == LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT)
- && !((WorkspaceItemInfo) item).isPromise();
- if (isShortcut) {
- // Shortcuts need some special checks due to legacy reasons.
- startShortcutIntentSafely(intent, optsBundle, item);
- } else if (user == null || user.equals(Process.myUserHandle())) {
- // Could be launching some bookkeeping activity
- context.startActivity(intent, optsBundle);
- } else {
- context.getSystemService(LauncherApps.class).startMainActivity(
- intent.getComponent(), user, intent.getSourceBounds(), optsBundle);
- }
- if (item != null) {
- InstanceId instanceId = new InstanceIdSequence().newInstanceId();
- logAppLaunch(getStatsLogManager(), item, instanceId);
- }
- return true;
- } catch (NullPointerException | ActivityNotFoundException | SecurityException e) {
- Toast.makeText(context, R.string.activity_not_found, Toast.LENGTH_SHORT).show();
- Log.e(TAG, "Unable to launch. tag=" + item + " intent=" + intent, e);
- }
- return false;
- }
-
- /** Returns {@code true} if an app launch is blocked due to safe mode. */
- default boolean isAppBlockedForSafeMode() {
- return false;
- }
-
- /**
- * Creates and logs a new app launch event.
- */
- default void logAppLaunch(StatsLogManager statsLogManager, ItemInfo info,
- InstanceId instanceId) {
- statsLogManager.logger().withItemInfo(info).withInstanceId(instanceId)
- .log(LAUNCHER_APP_LAUNCH_TAP);
- }
-
- /**
- * Returns launch options for an Activity.
- *
- * @param v View initiating a launch.
- * @param item Item associated with the view.
- */
- default ActivityOptionsWrapper getActivityLaunchOptions(View v, @Nullable ItemInfo item) {
- int left = 0, top = 0;
- int width = v.getMeasuredWidth(), height = v.getMeasuredHeight();
- if (v instanceof BubbleTextView) {
- // Launch from center of icon, not entire view
- Drawable icon = ((BubbleTextView) v).getIcon();
- if (icon != null) {
- Rect bounds = icon.getBounds();
- left = (width - bounds.width()) / 2;
- top = v.getPaddingTop();
- width = bounds.width();
- height = bounds.height();
- }
- }
- ActivityOptions options =
- ActivityOptions.makeClipRevealAnimation(v, left, top, width, height);
-
- options.setLaunchDisplayId(
- (v != null && v.getDisplay() != null) ? v.getDisplay().getDisplayId()
- : Display.DEFAULT_DISPLAY);
- RunnableList callback = new RunnableList();
- return new ActivityOptionsWrapper(options, callback);
- }
-
- /**
- * Safely launches an intent for a shortcut.
- *
- * @param intent Intent to start.
- * @param optsBundle Optional launch arguments.
- * @param info Shortcut information.
- */
- default void startShortcutIntentSafely(Intent intent, Bundle optsBundle, ItemInfo info) {
- try {
- StrictMode.VmPolicy oldPolicy = StrictMode.getVmPolicy();
- try {
- // Temporarily disable deathPenalty on all default checks. For eg, shortcuts
- // containing file Uri's would cause a crash as penaltyDeathOnFileUriExposure
- // is enabled by default on NYC.
- StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder().detectAll()
- .penaltyLog().build());
-
- if (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT) {
- String id = ((WorkspaceItemInfo) info).getDeepShortcutId();
- String packageName = intent.getPackage();
- startShortcut(packageName, id, intent.getSourceBounds(), optsBundle, info.user);
- } else {
- // Could be launching some bookkeeping activity
- ((Context) this).startActivity(intent, optsBundle);
- }
- } finally {
- StrictMode.setVmPolicy(oldPolicy);
- }
- } catch (SecurityException e) {
- if (!onErrorStartingShortcut(intent, info)) {
- throw e;
- }
- }
- }
-
- /**
- * A wrapper around the platform method with Launcher specific checks.
- */
- default void startShortcut(String packageName, String id, Rect sourceBounds,
- Bundle startActivityOptions, UserHandle user) {
- if (GO_DISABLE_WIDGETS) {
- return;
- }
- try {
- ((Context) this).getSystemService(LauncherApps.class).startShortcut(packageName, id,
- sourceBounds, startActivityOptions, user);
- } catch (SecurityException | IllegalStateException e) {
- Log.e(TAG, "Failed to start shortcut", e);
- }
- }
-
- /**
- * Invoked when a shortcut fails to launch.
- * @param intent Shortcut intent that failed to start.
- * @param info Shortcut information.
- * @return {@code true} if the error is handled by this callback.
- */
- default boolean onErrorStartingShortcut(Intent intent, ItemInfo info) {
- return false;
- }
-}
diff --git a/src/com/android/launcher3/views/ArrowTipView.java b/src/com/android/launcher3/views/ArrowTipView.java
index 8d16a8d982..e449a4bfbf 100644
--- a/src/com/android/launcher3/views/ArrowTipView.java
+++ b/src/com/android/launcher3/views/ArrowTipView.java
@@ -37,7 +37,6 @@ import androidx.core.content.ContextCompat;
import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.BaseDraggingActivity;
-import com.android.launcher3.DeviceProfile;
import com.android.launcher3.R;
import com.android.launcher3.anim.Interpolators;
import com.android.launcher3.dragndrop.DragLayer;
@@ -57,7 +56,6 @@ public class ArrowTipView extends AbstractFloatingView {
protected final BaseDraggingActivity mActivity;
private final Handler mHandler = new Handler();
private final int mArrowWidth;
- private final int mArrowMinOffset;
private boolean mIsPointingUp;
private Runnable mOnClosed;
private View mArrowView;
@@ -71,8 +69,6 @@ public class ArrowTipView extends AbstractFloatingView {
mActivity = BaseDraggingActivity.fromContext(context);
mIsPointingUp = isPointingUp;
mArrowWidth = context.getResources().getDimensionPixelSize(R.dimen.arrow_toast_arrow_width);
- mArrowMinOffset = context.getResources().getDimensionPixelSize(
- R.dimen.dynamic_grid_cell_border_spacing);
init(context);
}
@@ -130,60 +126,38 @@ public class ArrowTipView extends AbstractFloatingView {
/**
* Show the ArrowTipView (tooltip) center, start, or end aligned.
*
- * @param text The text to be shown in the tooltip.
- * @param gravity The gravity aligns the tooltip center, start, or end.
- * @param arrowMarginStart The margin from start to place arrow (ignored if center)
- * @param top The Y coordinate of the bottom of tooltip.
- * @return The tooltip.
- */
- public ArrowTipView show(String text, int gravity, int arrowMarginStart, int top) {
- return show(text, gravity, arrowMarginStart, top, true);
- }
-
- /**
- * Show the ArrowTipView (tooltip) center, start, or end aligned.
- *
* @param text The text to be shown in the tooltip.
* @param gravity The gravity aligns the tooltip center, start, or end.
* @param arrowMarginStart The margin from start to place arrow (ignored if center)
- * @param top The Y coordinate of the bottom of tooltip.
- * @param shouldAutoClose If Tooltip should be auto close.
+ * @param top The Y coordinate of the bottom of tooltip.
* @return The tooltip.
*/
- public ArrowTipView show(
- String text, int gravity, int arrowMarginStart, int top, boolean shouldAutoClose) {
+ public ArrowTipView show(String text, int gravity, int arrowMarginStart, int top) {
((TextView) findViewById(R.id.text)).setText(text);
ViewGroup parent = mActivity.getDragLayer();
parent.addView(this);
- DeviceProfile grid = mActivity.getDeviceProfile();
-
DragLayer.LayoutParams params = (DragLayer.LayoutParams) getLayoutParams();
params.gravity = gravity;
- params.leftMargin = mArrowMinOffset + grid.getInsets().left;
- params.rightMargin = mArrowMinOffset + grid.getInsets().right;
LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) mArrowView.getLayoutParams();
-
lp.gravity = gravity;
if (parent.getLayoutDirection() == LAYOUT_DIRECTION_RTL) {
arrowMarginStart = parent.getMeasuredWidth() - arrowMarginStart;
}
if (gravity == Gravity.END) {
- lp.setMarginEnd(Math.max(mArrowMinOffset,
- parent.getMeasuredWidth() - params.rightMargin - arrowMarginStart
- - mArrowWidth / 2));
+ lp.setMarginEnd(parent.getMeasuredWidth() - arrowMarginStart - mArrowWidth);
} else if (gravity == Gravity.START) {
- lp.setMarginStart(Math.max(mArrowMinOffset,
- arrowMarginStart - params.leftMargin - mArrowWidth / 2));
+ lp.setMarginStart(arrowMarginStart - mArrowWidth / 2);
}
requestLayout();
+
+ params.leftMargin = mActivity.getDeviceProfile().workspacePadding.left;
+ params.rightMargin = mActivity.getDeviceProfile().workspacePadding.right;
post(() -> setY(top - (mIsPointingUp ? 0 : getHeight())));
mIsOpen = true;
- if (shouldAutoClose) {
- mHandler.postDelayed(() -> handleClose(true), AUTO_CLOSE_TIMEOUT_MILLIS);
- }
+ mHandler.postDelayed(() -> handleClose(true), AUTO_CLOSE_TIMEOUT_MILLIS);
setAlpha(0);
animate()
.alpha(1f)
@@ -207,32 +181,10 @@ public class ArrowTipView extends AbstractFloatingView {
*/
@Nullable public ArrowTipView showAtLocation(String text, @Px int arrowXCoord, @Px int yCoord) {
return showAtLocation(
- text,
- arrowXCoord,
- /* yCoordDownPointingTip= */ yCoord,
- /* yCoordUpPointingTip= */ yCoord,
- /* shouldAutoClose= */ true);
- }
-
- /**
- * Show the ArrowTipView (tooltip) custom aligned. The tooltip is vertically flipped if it
- * cannot fit on screen in the requested orientation.
- *
- * @param text The text to be shown in the tooltip.
- * @param arrowXCoord The X coordinate for the arrow on the tooltip. The arrow is usually in the
- * center of tooltip unless the tooltip goes beyond screen margin.
- * @param yCoord The Y coordinate of the pointed tip end of the tooltip.
- * @param shouldAutoClose If Tooltip should be auto close.
- * @return The tool tip view. {@code null} if the tip can not be shown.
- */
- @Nullable public ArrowTipView showAtLocation(
- String text, @Px int arrowXCoord, @Px int yCoord, boolean shouldAutoClose) {
- return showAtLocation(
text,
arrowXCoord,
/* yCoordDownPointingTip= */ yCoord,
- /* yCoordUpPointingTip= */ yCoord,
- /* shouldAutoClose= */ shouldAutoClose);
+ /* yCoordUpPointingTip= */ yCoord);
}
/**
@@ -252,8 +204,7 @@ public class ArrowTipView extends AbstractFloatingView {
text,
arrowXCoord,
/* yCoordDownPointingTip= */ rect.top - margin,
- /* yCoordUpPointingTip= */ rect.bottom + margin,
- /* shouldAutoClose= */ true);
+ /* yCoordUpPointingTip= */ rect.bottom + margin);
}
/**
@@ -267,11 +218,10 @@ public class ArrowTipView extends AbstractFloatingView {
* tooltip is placed pointing downwards.
* @param yCoordUpPointingTip The Y coordinate of the pointed tip end of the tooltip when the
* tooltip is placed pointing upwards.
- * @param shouldAutoClose If Tooltip should be auto close.
* @return The tool tip view. {@code null} if the tip can not be shown.
*/
@Nullable private ArrowTipView showAtLocation(String text, @Px int arrowXCoord,
- @Px int yCoordDownPointingTip, @Px int yCoordUpPointingTip, boolean shouldAutoClose) {
+ @Px int yCoordDownPointingTip, @Px int yCoordUpPointingTip) {
ViewGroup parent = mActivity.getDragLayer();
@Px int parentViewWidth = parent.getWidth();
@Px int parentViewHeight = parent.getHeight();
@@ -329,9 +279,7 @@ public class ArrowTipView extends AbstractFloatingView {
});
mIsOpen = true;
- if (shouldAutoClose) {
- mHandler.postDelayed(() -> handleClose(true), AUTO_CLOSE_TIMEOUT_MILLIS);
- }
+ mHandler.postDelayed(() -> handleClose(true), AUTO_CLOSE_TIMEOUT_MILLIS);
setAlpha(0);
animate()
.alpha(1f)
diff --git a/src/com/android/launcher3/views/BaseDragLayer.java b/src/com/android/launcher3/views/BaseDragLayer.java
index f553fb4e8e..01c0b562e1 100644
--- a/src/com/android/launcher3/views/BaseDragLayer.java
+++ b/src/com/android/launcher3/views/BaseDragLayer.java
@@ -20,7 +20,7 @@ import static android.view.MotionEvent.ACTION_CANCEL;
import static android.view.MotionEvent.ACTION_DOWN;
import static android.view.MotionEvent.ACTION_UP;
-import static com.android.launcher3.util.window.RefreshRateTracker.getSingleFrameMs;
+import static com.android.launcher3.util.DisplayController.getSingleFrameMs;
import android.annotation.TargetApi;
import android.app.WallpaperManager;
@@ -40,7 +40,6 @@ import android.view.accessibility.AccessibilityEvent;
import android.widget.FrameLayout;
import com.android.launcher3.AbstractFloatingView;
-import com.android.launcher3.DeviceProfile;
import com.android.launcher3.InsettableFrameLayout;
import com.android.launcher3.Utilities;
import com.android.launcher3.util.MultiValueAlpha;
@@ -414,14 +413,6 @@ public abstract class BaseDragLayer<T extends Context & ActivityContext>
}
/**
- * Similar to {@link #mapCoordInSelfToDescendant(View descendant, float[] coord)}
- * but accepts a Rect instead of float[].
- */
- public void mapRectInSelfToDescendant(View descendant, Rect rect) {
- Utilities.mapRectInSelfToDescendant(descendant, this, rect);
- }
-
- /**
* Inverse of {@link #getDescendantCoordRelativeToSelf(View, float[])}.
*/
public void mapCoordInSelfToDescendant(View descendant, float[] coord) {
@@ -439,20 +430,18 @@ public abstract class BaseDragLayer<T extends Context & ActivityContext>
}
public void getViewRectRelativeToSelf(View v, Rect r) {
- int[] loc = getViewLocationRelativeToSelf(v);
- r.set(loc[0], loc[1], loc[0] + v.getMeasuredWidth(), loc[1] + v.getMeasuredHeight());
- }
-
- protected int[] getViewLocationRelativeToSelf(View v) {
int[] loc = new int[2];
getLocationInWindow(loc);
int x = loc[0];
int y = loc[1];
v.getLocationInWindow(loc);
- loc[0] -= x;
- loc[1] -= y;
- return loc;
+ int vX = loc[0];
+ int vY = loc[1];
+
+ int left = vX - x;
+ int top = vY - y;
+ r.set(left, top, left + v.getMeasuredWidth(), top + v.getMeasuredHeight());
}
@Override
@@ -554,14 +543,8 @@ public abstract class BaseDragLayer<T extends Context & ActivityContext>
public WindowInsets dispatchApplyWindowInsets(WindowInsets insets) {
if (Utilities.ATLEAST_Q) {
Insets gestureInsets = insets.getMandatorySystemGestureInsets();
- int gestureInsetBottom = gestureInsets.bottom;
- DeviceProfile dp = mActivity.getDeviceProfile();
- if (dp.isTaskbarPresent) {
- // Ignore taskbar gesture insets to avoid interfering with TouchControllers.
- gestureInsetBottom = Math.max(0, gestureInsetBottom - dp.taskbarSize);
- }
mSystemGestureRegion.set(gestureInsets.left, gestureInsets.top,
- gestureInsets.right, gestureInsetBottom);
+ gestureInsets.right, gestureInsets.bottom);
}
return super.dispatchApplyWindowInsets(insets);
}
diff --git a/src/com/android/launcher3/views/BubbleTextHolder.java b/src/com/android/launcher3/views/BubbleTextHolder.java
index 84f8049ded..47d356374e 100644
--- a/src/com/android/launcher3/views/BubbleTextHolder.java
+++ b/src/com/android/launcher3/views/BubbleTextHolder.java
@@ -20,16 +20,6 @@ import com.android.launcher3.BubbleTextView;
/**
* Views that contain {@link BubbleTextView} should implement this interface.
*/
-public interface BubbleTextHolder extends IconLabelDotView {
+public interface BubbleTextHolder {
BubbleTextView getBubbleText();
-
- @Override
- default void setIconVisible(boolean visible) {
- getBubbleText().setIconVisible(visible);
- }
-
- @Override
- default void setForceHideDot(boolean hide) {
- getBubbleText().setForceHideDot(hide);
- }
}
diff --git a/src/com/android/launcher3/views/ClipIconView.java b/src/com/android/launcher3/views/ClipIconView.java
index d1f90e987f..a66b3f942e 100644
--- a/src/com/android/launcher3/views/ClipIconView.java
+++ b/src/com/android/launcher3/views/ClipIconView.java
@@ -147,7 +147,8 @@ public class ClipIconView extends View implements ClipPathView {
* Update the icon UI to match the provided parameters during an animation frame
*/
public void update(RectF rect, float progress, float shapeProgressStart, float cornerRadius,
- int fgIconAlpha, boolean isOpening, View container, DeviceProfile dp) {
+ int fgIconAlpha, boolean isOpening, View container, DeviceProfile dp,
+ boolean isVerticalBarLayout) {
MarginLayoutParams lp = (MarginLayoutParams) container.getLayoutParams();
float dX = mIsRtl
@@ -168,7 +169,7 @@ public class ClipIconView extends View implements ClipPathView {
}
update(rect, progress, shapeProgressStart, cornerRadius, fgIconAlpha, isOpening, scale,
- minSize, lp, dp);
+ minSize, lp, isVerticalBarLayout, dp);
container.setPivotX(0);
container.setPivotY(0);
@@ -180,7 +181,7 @@ public class ClipIconView extends View implements ClipPathView {
private void update(RectF rect, float progress, float shapeProgressStart, float cornerRadius,
int fgIconAlpha, boolean isOpening, float scale, float minSize,
- MarginLayoutParams parentLp, DeviceProfile dp) {
+ MarginLayoutParams parentLp, boolean isVerticalBarLayout, DeviceProfile dp) {
float dX = mIsRtl
? rect.left - (dp.widthPx - parentLp.getMarginStart() - parentLp.width)
: rect.left - parentLp.getMarginStart();
@@ -192,7 +193,7 @@ public class ClipIconView extends View implements ClipPathView {
float shapeRevealProgress = boundToRange(mapToRange(max(shapeProgressStart, progress),
shapeProgressStart, 1f, 0, toMax, LINEAR), 0, 1);
- if (dp.isLandscape) {
+ if (isVerticalBarLayout) {
mOutline.right = (int) (rect.width() / scale);
} else {
mOutline.bottom = (int) (rect.height() / scale);
@@ -217,16 +218,16 @@ public class ClipIconView extends View implements ClipPathView {
mRevealAnimator.setCurrentFraction(shapeRevealProgress);
}
- float drawableScale = (dp.isLandscape ? mOutline.width() : mOutline.height())
+ float drawableScale = (isVerticalBarLayout ? mOutline.width() : mOutline.height())
/ minSize;
- setBackgroundDrawableBounds(drawableScale, dp.isLandscape);
+ setBackgroundDrawableBounds(drawableScale, isVerticalBarLayout);
if (isOpening) {
// Center align foreground
int height = mFinalDrawableBounds.height();
int width = mFinalDrawableBounds.width();
- int diffY = dp.isLandscape ? 0
+ int diffY = isVerticalBarLayout ? 0
: (int) (((height * drawableScale) - height) / 2);
- int diffX = dp.isLandscape ? (int) (((width * drawableScale) - width) / 2)
+ int diffX = isVerticalBarLayout ? (int) (((width * drawableScale) - width) / 2)
: 0;
sTmpRect.set(mFinalDrawableBounds);
sTmpRect.offset(diffX, diffY);
@@ -246,11 +247,11 @@ public class ClipIconView extends View implements ClipPathView {
invalidateOutline();
}
- private void setBackgroundDrawableBounds(float scale, boolean isLandscape) {
+ private void setBackgroundDrawableBounds(float scale, boolean isVerticalBarLayout) {
sTmpRect.set(mFinalDrawableBounds);
Utilities.scaleRectAboutCenter(sTmpRect, scale);
// Since the drawable is at the top of the view, we need to offset to keep it centered.
- if (isLandscape) {
+ if (isVerticalBarLayout) {
sTmpRect.offsetTo((int) (mFinalDrawableBounds.left * scale), sTmpRect.top);
} else {
sTmpRect.offsetTo(sTmpRect.left, (int) (mFinalDrawableBounds.top * scale));
@@ -268,7 +269,7 @@ public class ClipIconView extends View implements ClipPathView {
* Sets the icon for this view as part of initial setup
*/
public void setIcon(@Nullable Drawable drawable, int iconOffset, MarginLayoutParams lp,
- boolean isOpening, DeviceProfile dp) {
+ boolean isOpening, boolean isVerticalBarLayout, DeviceProfile dp) {
mIsAdaptiveIcon = drawable instanceof AdaptiveIconDrawable;
if (mIsAdaptiveIcon) {
boolean isFolderIcon = drawable instanceof FolderAdaptiveIcon;
@@ -303,7 +304,7 @@ public class ClipIconView extends View implements ClipPathView {
Utilities.scaleRectAboutCenter(mStartRevealRect, IconShape.getNormalizationScale());
}
- if (dp.isLandscape) {
+ if (isVerticalBarLayout) {
lp.width = (int) Math.max(lp.width, lp.height * dp.aspectRatio);
} else {
lp.height = (int) Math.max(lp.height, lp.width * dp.aspectRatio);
@@ -324,7 +325,7 @@ public class ClipIconView extends View implements ClipPathView {
bgDrawableStartScale = scale;
mOutline.set(0, 0, lp.width, lp.height);
}
- setBackgroundDrawableBounds(bgDrawableStartScale, dp.isLandscape);
+ setBackgroundDrawableBounds(bgDrawableStartScale, isVerticalBarLayout);
mEndRevealRect.set(0, 0, lp.width, lp.height);
setOutlineProvider(new ViewOutlineProvider() {
@Override
diff --git a/src/com/android/launcher3/views/FloatingIconView.java b/src/com/android/launcher3/views/FloatingIconView.java
index efc83ebcc9..872adec42e 100644
--- a/src/com/android/launcher3/views/FloatingIconView.java
+++ b/src/com/android/launcher3/views/FloatingIconView.java
@@ -17,6 +17,7 @@ package com.android.launcher3.views;
import static com.android.launcher3.Utilities.getBadge;
import static com.android.launcher3.Utilities.getFullDrawable;
+import static com.android.launcher3.config.FeatureFlags.ADAPTIVE_ICON_WINDOW_ANIM;
import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
import static com.android.launcher3.views.IconLabelDotView.setIconAndDotVisible;
@@ -43,12 +44,12 @@ import androidx.annotation.UiThread;
import androidx.annotation.WorkerThread;
import com.android.launcher3.BubbleTextView;
-import com.android.launcher3.DeviceProfile;
import com.android.launcher3.InsettableFrameLayout;
import com.android.launcher3.Launcher;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.dragndrop.DragLayer;
+import com.android.launcher3.dragndrop.FolderAdaptiveIcon;
import com.android.launcher3.folder.FolderIcon;
import com.android.launcher3.graphics.PreloadIconDrawable;
import com.android.launcher3.icons.FastBitmapDrawable;
@@ -58,8 +59,6 @@ import com.android.launcher3.model.data.ItemInfoWithIcon;
import com.android.launcher3.popup.SystemShortcut;
import com.android.launcher3.shortcuts.DeepShortcutView;
-import java.util.function.Supplier;
-
/**
* A view that is created to look like another view with the purpose of creating fluid animations.
*/
@@ -71,8 +70,6 @@ public class FloatingIconView extends FrameLayout implements
// Manages loading the icon on a worker thread
private static @Nullable IconLoadResult sIconLoadResult;
- private static long sFetchIconId = 0;
- private static long sRecycledFetchIconId = sFetchIconId;
public static final float SHAPE_PROGRESS_DURATION = 0.10f;
private static final RectF sTmpRectF = new RectF();
@@ -84,10 +81,12 @@ public class FloatingIconView extends FrameLayout implements
private final Launcher mLauncher;
private final boolean mIsRtl;
+ private boolean mIsVerticalBarLayout = false;
private boolean mIsOpening;
private IconLoadResult mIconLoadResult;
+ // Draw the drawable of the BubbleTextView behind ClipIconView to reveal the built in shadow.
private View mBtvDrawable;
private ClipIconView mClipIconView;
@@ -151,7 +150,7 @@ public class FloatingIconView extends FrameLayout implements
float shapeProgressStart, float cornerRadius, boolean isOpening) {
setAlpha(alpha);
mClipIconView.update(rect, progress, shapeProgressStart, cornerRadius, fgIconAlpha,
- isOpening, this, mLauncher.getDeviceProfile());
+ isOpening, this, mLauncher.getDeviceProfile(), mIsVerticalBarLayout);
}
@Override
@@ -248,15 +247,14 @@ public class FloatingIconView extends FrameLayout implements
* @param originalView The View that the FloatingIconView will replace.
* @param info ItemInfo of the originalView
* @param pos The position of the view.
- * @param btvIcon The drawable of the BubbleTextView. May be null if original view is not a BTV
- * @param outIconLoadResult We store the icon results into this object.
*/
@WorkerThread
@SuppressWarnings("WrongThread")
private static void getIconResult(Launcher l, View originalView, ItemInfo info, RectF pos,
- @Nullable Drawable btvIcon, IconLoadResult outIconLoadResult) {
+ Drawable btvIcon, IconLoadResult iconLoadResult) {
Drawable drawable;
- boolean supportsAdaptiveIcons = !info.isDisabled(); // Use original icon for disabled icons.
+ boolean supportsAdaptiveIcons = ADAPTIVE_ICON_WINDOW_ANIM.get()
+ && !info.isDisabled(); // Use original icon for disabled icons.
Drawable badge = null;
if (info instanceof SystemShortcut) {
@@ -274,9 +272,7 @@ public class FloatingIconView extends FrameLayout implements
int width = (int) pos.width();
int height = (int) pos.height();
if (supportsAdaptiveIcons) {
- boolean shouldThemeIcon = btvIcon instanceof FastBitmapDrawable
- && ((FastBitmapDrawable) btvIcon).isThemed();
- drawable = getFullDrawable(l, info, width, height, shouldThemeIcon, sTmpObjArray);
+ drawable = getFullDrawable(l, info, width, height, sTmpObjArray);
if (drawable instanceof AdaptiveIconDrawable) {
badge = getBadge(l, info, sTmpObjArray[0]);
} else {
@@ -289,27 +285,24 @@ public class FloatingIconView extends FrameLayout implements
// Similar to DragView, we simply use the BubbleTextView icon here.
drawable = btvIcon;
} else {
- drawable = getFullDrawable(l, info, width, height, true /* shouldThemeIcon */,
- sTmpObjArray);
+ drawable = getFullDrawable(l, info, width, height, sTmpObjArray);
}
}
}
drawable = drawable == null ? null : drawable.getConstantState().newDrawable();
int iconOffset = getOffsetForIconBounds(l, drawable, pos);
- // Clone right away as we are on the background thread instead of blocking the
- // main thread later
- Drawable btvClone = btvIcon == null ? null : btvIcon.getConstantState().newDrawable();
- synchronized (outIconLoadResult) {
- outIconLoadResult.btvDrawable = () -> btvClone;
- outIconLoadResult.drawable = drawable;
- outIconLoadResult.badge = badge;
- outIconLoadResult.iconOffset = iconOffset;
- if (outIconLoadResult.onIconLoaded != null) {
- l.getMainExecutor().execute(outIconLoadResult.onIconLoaded);
- outIconLoadResult.onIconLoaded = null;
+ synchronized (iconLoadResult) {
+ iconLoadResult.btvDrawable = btvIcon == null || drawable == btvIcon
+ ? null : btvIcon.getConstantState().newDrawable();
+ iconLoadResult.drawable = drawable;
+ iconLoadResult.badge = badge;
+ iconLoadResult.iconOffset = iconOffset;
+ if (iconLoadResult.onIconLoaded != null) {
+ l.getMainExecutor().execute(iconLoadResult.onIconLoaded);
+ iconLoadResult.onIconLoaded = null;
}
- outIconLoadResult.isIconLoaded = true;
+ iconLoadResult.isIconLoaded = true;
}
}
@@ -322,12 +315,12 @@ public class FloatingIconView extends FrameLayout implements
*/
@UiThread
private void setIcon(@Nullable Drawable drawable, @Nullable Drawable badge,
- @Nullable Supplier<Drawable> btvIcon, int iconOffset) {
- final DeviceProfile dp = mLauncher.getDeviceProfile();
+ @Nullable Drawable btvIcon, int iconOffset) {
final InsettableFrameLayout.LayoutParams lp =
(InsettableFrameLayout.LayoutParams) getLayoutParams();
mBadge = badge;
- mClipIconView.setIcon(drawable, iconOffset, lp, mIsOpening, dp);
+ mClipIconView.setIcon(drawable, iconOffset, lp, mIsOpening, mIsVerticalBarLayout,
+ mLauncher.getDeviceProfile());
if (drawable instanceof AdaptiveIconDrawable) {
final int originalHeight = lp.height;
final int originalWidth = lp.width;
@@ -335,7 +328,7 @@ public class FloatingIconView extends FrameLayout implements
mFinalDrawableBounds.set(0, 0, originalWidth, originalHeight);
float aspectRatio = mLauncher.getDeviceProfile().aspectRatio;
- if (dp.isLandscape) {
+ if (mIsVerticalBarLayout) {
lp.width = (int) Math.max(lp.width, lp.height * aspectRatio);
} else {
lp.height = (int) Math.max(lp.height, lp.width * aspectRatio);
@@ -343,32 +336,21 @@ public class FloatingIconView extends FrameLayout implements
setLayoutParams(lp);
final LayoutParams clipViewLp = (LayoutParams) mClipIconView.getLayoutParams();
- if (mBadge != null) {
- Rect badgeBounds = new Rect(0, 0, clipViewLp.width, clipViewLp.height);
- FastBitmapDrawable.setBadgeBounds(mBadge, badgeBounds);
- }
+ final int clipViewOgHeight = clipViewLp.height;
+ final int clipViewOgWidth = clipViewLp.width;
clipViewLp.width = lp.width;
clipViewLp.height = lp.height;
mClipIconView.setLayoutParams(clipViewLp);
- }
- setOriginalDrawableBackground(btvIcon);
- invalidate();
- }
+ if (mBadge != null) {
+ mBadge.setBounds(0, 0, clipViewOgWidth, clipViewOgHeight);
+ }
+ }
- /**
- * Draws the drawable of the BubbleTextView behind ClipIconView
- *
- * This is used to:
- * - Have icon displayed while Adaptive Icon is loading
- * - Displays the built in shadow to ensure a clean handoff
- *
- * Allows nullable as this may be cleared when drawing is deferred to ClipIconView.
- */
- private void setOriginalDrawableBackground(@Nullable Supplier<Drawable> btvIcon) {
- if (!mIsOpening) {
- mBtvDrawable.setBackground(btvIcon == null ? null : btvIcon.get());
+ if (!mIsOpening && btvIcon != null) {
+ mBtvDrawable.setBackground(btvIcon);
}
+ invalidate();
}
/**
@@ -416,7 +398,8 @@ public class FloatingIconView extends FrameLayout implements
@WorkerThread
@SuppressWarnings("WrongThread")
private static int getOffsetForIconBounds(Launcher l, Drawable drawable, RectF position) {
- if (!(drawable instanceof AdaptiveIconDrawable)) {
+ if (!(drawable instanceof AdaptiveIconDrawable)
+ || (drawable instanceof FolderAdaptiveIcon)) {
return 0;
}
int blurSizeOutline =
@@ -472,12 +455,10 @@ public class FloatingIconView extends FrameLayout implements
@Override
public void onAnimationStart(Animator animator) {
- if ((mIconLoadResult != null && mIconLoadResult.isIconLoaded)
- || (!mIsOpening && mBtvDrawable.getBackground() != null)) {
- // No need to wait for icon load since we can display the BubbleTextView drawable.
+ if (mIconLoadResult != null && mIconLoadResult.isIconLoaded) {
setVisibility(View.VISIBLE);
}
- if (!mIsOpening && mOriginalIcon != null) {
+ if (!mIsOpening) {
// When closing an app, we want the item on the workspace to be invisible immediately
setIconAndDotVisible(mOriginalIcon, false);
}
@@ -522,34 +503,24 @@ public class FloatingIconView extends FrameLayout implements
getLocationBoundsForView(l, v, isOpening, position);
final FastBitmapDrawable btvIcon;
- final Supplier<Drawable> btvDrawableSupplier;
if (v instanceof BubbleTextView) {
BubbleTextView btv = (BubbleTextView) v;
if (info instanceof ItemInfoWithIcon
&& (((ItemInfoWithIcon) info).runtimeStatusFlags
& ItemInfoWithIcon.FLAG_SHOW_DOWNLOAD_PROGRESS_MASK) != 0) {
btvIcon = btv.makePreloadIcon();
- btvDrawableSupplier = () -> btvIcon;
} else {
btvIcon = btv.getIcon();
- // Clone when needed
- btvDrawableSupplier = () -> btvIcon.getConstantState().newDrawable();
}
} else {
btvIcon = null;
- btvDrawableSupplier = null;
}
- IconLoadResult result = new IconLoadResult(info, btvIcon != null && btvIcon.isThemed());
- result.btvDrawable = btvDrawableSupplier;
+ IconLoadResult result = new IconLoadResult(info,
+ btvIcon == null ? false : btvIcon.isThemed());
- final long fetchIconId = sFetchIconId++;
- MODEL_EXECUTOR.getHandler().postAtFrontOfQueue(() -> {
- if (fetchIconId < sRecycledFetchIconId) {
- return;
- }
- getIconResult(l, v, info, position, btvIcon, result);
- });
+ MODEL_EXECUTOR.getHandler().postAtFrontOfQueue(() ->
+ getIconResult(l, v, info, position, btvIcon, result));
sIconLoadResult = result;
return result;
@@ -571,11 +542,6 @@ public class FloatingIconView extends FrameLayout implements
launcher, parent);
view.recycle();
- // Init properties before getting the drawable.
- view.mIsOpening = isOpening;
- view.mOriginalIcon = originalView;
- view.mPositionOut = positionOut;
-
// Get the drawable on the background thread
boolean shouldLoadIcon = originalView.getTag() instanceof ItemInfo && hideOriginal;
if (shouldLoadIcon) {
@@ -585,15 +551,19 @@ public class FloatingIconView extends FrameLayout implements
view.mIconLoadResult = fetchIcon(launcher, originalView,
(ItemInfo) originalView.getTag(), isOpening);
}
- view.setOriginalDrawableBackground(view.mIconLoadResult.btvDrawable);
}
sIconLoadResult = null;
+ view.mIsVerticalBarLayout = launcher.getDeviceProfile().isVerticalBarLayout();
+ view.mIsOpening = isOpening;
+ view.mOriginalIcon = originalView;
+ view.mPositionOut = positionOut;
+
// Match the position of the original view.
view.matchPositionOf(launcher, originalView, isOpening, positionOut);
// We need to add it to the overlay, but keep it invisible until animation starts..
- setIconAndDotVisible(view, false);
+ view.setVisibility(INVISIBLE);
parent.addView(view);
dragLayer.addView(view.mListenerView);
view.mListenerView.setListener(view::fastFinish);
@@ -602,8 +572,16 @@ public class FloatingIconView extends FrameLayout implements
view.mEndRunnable = null;
if (hideOriginal) {
- setIconAndDotVisible(originalView, true);
- view.finish(dragLayer);
+ if (isOpening) {
+ setIconAndDotVisible(originalView, true);
+ view.finish(dragLayer);
+ } else {
+ originalView.setVisibility(VISIBLE);
+ if (originalView instanceof IconLabelDotView) {
+ setIconAndDotVisible(originalView, true);
+ }
+ view.finish(dragLayer);
+ }
} else {
view.finish(dragLayer);
}
@@ -638,14 +616,12 @@ public class FloatingIconView extends FrameLayout implements
mLoadIconSignal = null;
mEndRunnable = null;
mFinalDrawableBounds.setEmpty();
- mIsOpening = false;
mPositionOut = null;
mListenerView.setListener(null);
mOriginalIcon = null;
mOnTargetChangeRunnable = null;
mBadge = null;
sTmpObjArray[0] = null;
- sRecycledFetchIconId = sFetchIconId;
mIconLoadResult = null;
mClipIconView.recycle();
mBtvDrawable.setBackground(null);
@@ -656,7 +632,7 @@ public class FloatingIconView extends FrameLayout implements
private static class IconLoadResult {
final ItemInfo itemInfo;
final boolean isThemed;
- Supplier<Drawable> btvDrawable;
+ Drawable btvDrawable;
Drawable drawable;
Drawable badge;
int iconOffset;
diff --git a/src/com/android/launcher3/views/FloatingSurfaceView.java b/src/com/android/launcher3/views/FloatingSurfaceView.java
index bfb75f0022..e2e3be7976 100644
--- a/src/com/android/launcher3/views/FloatingSurfaceView.java
+++ b/src/com/android/launcher3/views/FloatingSurfaceView.java
@@ -40,8 +40,8 @@ import com.android.launcher3.GestureNavContract;
import com.android.launcher3.Insettable;
import com.android.launcher3.Launcher;
import com.android.launcher3.R;
+import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.Executors;
-import com.android.launcher3.util.window.RefreshRateTracker;
/**
* Similar to {@link FloatingIconView} but displays a surface with the targetIcon. It then passes
@@ -62,6 +62,7 @@ public class FloatingSurfaceView extends AbstractFloatingView implements
private final SurfaceView mSurfaceView;
+
private View mIcon;
private GestureNavContract mContract;
@@ -96,19 +97,13 @@ public class FloatingSurfaceView extends AbstractFloatingView implements
// Remove after some time, to avoid flickering
Executors.MAIN_EXECUTOR.getHandler().postDelayed(mRemoveViewRunnable,
- RefreshRateTracker.getSingleFrameMs(mLauncher));
+ DisplayController.INSTANCE.get(mLauncher).getInfo().singleFrameMs);
}
private void removeViewFromParent() {
mPicture.beginRecording(1, 1);
mPicture.endRecording();
- mLauncher.getDragLayer().removeViewInLayout(this);
- }
-
- private void removeViewImmediate() {
- // Cancel any pending remove
- Executors.MAIN_EXECUTOR.getHandler().removeCallbacks(mRemoveViewRunnable);
- removeViewFromParent();
+ mLauncher.getDragLayer().removeView(this);
}
/**
@@ -120,7 +115,9 @@ public class FloatingSurfaceView extends AbstractFloatingView implements
view.mContract = contract;
view.mIsOpen = true;
- view.removeViewImmediate();
+ // Cancel any pending remove
+ Executors.MAIN_EXECUTOR.getHandler().removeCallbacks(view.mRemoveViewRunnable);
+ view.removeViewFromParent();
launcher.getDragLayer().addView(view);
}
@@ -132,7 +129,6 @@ public class FloatingSurfaceView extends AbstractFloatingView implements
@Override
public boolean onControllerInterceptTouchEvent(MotionEvent ev) {
close(false);
- removeViewImmediate();
return false;
}
@@ -162,9 +158,8 @@ public class FloatingSurfaceView extends AbstractFloatingView implements
if (mContract == null) {
return;
}
- View icon = mLauncher.getFirstMatchForAppClose(-1,
- mContract.componentName.getPackageName(), mContract.user,
- false /* supportsAllAppsState */);
+ View icon = mLauncher.getWorkspace().getFirstMatchForAppClose(-1,
+ mContract.componentName.getPackageName(), mContract.user);
boolean iconChanged = mIcon != icon;
if (iconChanged) {
@@ -187,7 +182,7 @@ public class FloatingSurfaceView extends AbstractFloatingView implements
lp.topMargin = Math.round(mIconPosition.top);
}
}
- if (mIcon != null && iconChanged && !mIconBounds.isEmpty()) {
+ if (iconChanged && !mIconBounds.isEmpty()) {
// Record the icon display
setCurrentIconVisible(true);
Canvas c = mPicture.beginRecording(mIconBounds.width(), mIconBounds.height());
@@ -201,7 +196,7 @@ public class FloatingSurfaceView extends AbstractFloatingView implements
private void sendIconInfo() {
if (mContract != null && !mIconPosition.isEmpty()) {
- mContract.sendEndPosition(mIconPosition, mLauncher, mSurfaceView.getSurfaceControl());
+ mContract.sendEndPosition(mIconPosition, mSurfaceView.getSurfaceControl());
}
}
diff --git a/src/com/android/launcher3/views/OptionsPopupView.java b/src/com/android/launcher3/views/OptionsPopupView.java
index 2a9a8a5d36..ecdd206224 100644
--- a/src/com/android/launcher3/views/OptionsPopupView.java
+++ b/src/com/android/launcher3/views/OptionsPopupView.java
@@ -37,9 +37,9 @@ import android.view.View.OnLongClickListener;
import android.widget.Toast;
import androidx.annotation.Nullable;
+import androidx.annotation.VisibleForTesting;
import androidx.core.content.ContextCompat;
-import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherSettings;
import com.android.launcher3.R;
@@ -59,7 +59,7 @@ import java.util.List;
/**
* Popup shown on long pressing an empty space in launcher
*/
-public class OptionsPopupView extends ArrowPopup<Launcher>
+public class OptionsPopupView extends ArrowPopup
implements OnClickListener, OnLongClickListener {
private final ArrayMap<View, OptionItem> mItemMap = new ArrayMap<>();
@@ -74,10 +74,6 @@ public class OptionsPopupView extends ArrowPopup<Launcher>
super(context, attrs, defStyleAttr);
}
- public void setTargetRect(RectF targetRect) {
- mTargetRect = targetRect;
- }
-
@Override
public void onClick(View view) {
handleViewClick(view);
@@ -94,7 +90,7 @@ public class OptionsPopupView extends ArrowPopup<Launcher>
return false;
}
if (item.eventId.getId() > 0) {
- mActivityContext.getStatsLogManager().logger().log(item.eventId);
+ mLauncher.getStatsLogManager().logger().log(item.eventId);
}
if (item.clickListener.onLongClick(view)) {
close(true);
@@ -175,20 +171,31 @@ public class OptionsPopupView extends ArrowPopup<Launcher>
return children;
}
+ @VisibleForTesting
+ public static ArrowPopup getOptionsPopup(Launcher launcher) {
+ return launcher.findViewById(R.id.popup_container);
+ }
+
+ public static void showDefaultOptions(Launcher launcher, float x, float y) {
+ float halfSize = launcher.getResources().getDimension(R.dimen.options_menu_thumb_size) / 2;
+ if (x < 0 || y < 0) {
+ x = launcher.getDragLayer().getWidth() / 2;
+ y = launcher.getDragLayer().getHeight() / 2;
+ }
+ RectF target = new RectF(x - halfSize, y - halfSize, x + halfSize, y + halfSize);
+ show(launcher, target, getOptions(launcher), false);
+ }
+
/**
* Returns the list of supported actions
*/
public static ArrayList<OptionItem> getOptions(Launcher launcher) {
ArrayList<OptionItem> options = new ArrayList<>();
- int resString = Utilities.existsStyleWallpapers(launcher) ?
- R.string.styles_wallpaper_button_text : R.string.wallpaper_button_text;
- int resDrawable = Utilities.existsStyleWallpapers(launcher) ?
- R.drawable.ic_palette : R.drawable.ic_wallpaper;
options.add(new OptionItem(launcher,
- resString,
- resDrawable,
- IGNORE,
- OptionsPopupView::startWallpaperPicker));
+ R.string.settings_button_text,
+ R.drawable.ic_setting,
+ LAUNCHER_SETTINGS_BUTTON_TAP_OR_LONGPRESS,
+ OptionsPopupView::startSettings));
if (!WidgetsModel.GO_DISABLE_WIDGETS) {
options.add(new OptionItem(launcher,
R.string.widget_button_text,
@@ -196,11 +203,15 @@ public class OptionsPopupView extends ArrowPopup<Launcher>
LAUNCHER_WIDGETSTRAY_BUTTON_TAP_OR_LONGPRESS,
OptionsPopupView::onWidgetsClicked));
}
+ int resString = Utilities.existsStyleWallpapers(launcher) ?
+ R.string.styles_wallpaper_button_text : R.string.wallpaper_button_text;
+ int resDrawable = Utilities.existsStyleWallpapers(launcher) ?
+ R.drawable.ic_palette : R.drawable.ic_wallpaper;
options.add(new OptionItem(launcher,
- R.string.settings_button_text,
- R.drawable.ic_setting,
- LAUNCHER_SETTINGS_BUTTON_TAP_OR_LONGPRESS,
- OptionsPopupView::startSettings));
+ resString,
+ resDrawable,
+ IGNORE,
+ OptionsPopupView::startWallpaperPicker));
return options;
}
@@ -215,11 +226,6 @@ public class OptionsPopupView extends ArrowPopup<Launcher>
Toast.makeText(launcher, R.string.safemode_widget_error, Toast.LENGTH_SHORT).show();
return null;
} else {
- AbstractFloatingView floatingView = AbstractFloatingView.getTopOpenViewWithType(
- launcher, TYPE_WIDGETS_FULL_SHEET);
- if (floatingView != null) {
- return (WidgetsFullSheet) floatingView;
- }
return WidgetsFullSheet.show(launcher, true /* animated */);
}
}
@@ -229,7 +235,7 @@ public class OptionsPopupView extends ArrowPopup<Launcher>
Launcher launcher = Launcher.getLauncher(view.getContext());
launcher.startActivity(new Intent(Intent.ACTION_APPLICATION_PREFERENCES)
.setPackage(launcher.getPackageName())
- .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK));
+ .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
return true;
}
@@ -240,10 +246,7 @@ public class OptionsPopupView extends ArrowPopup<Launcher>
private static boolean startWallpaperPicker(View v) {
Launcher launcher = Launcher.getLauncher(v.getContext());
if (!Utilities.isWallpaperAllowed(launcher)) {
- String message = launcher.getStringCache() != null
- ? launcher.getStringCache().disabledByAdminMessage
- : launcher.getString(R.string.msg_disabled_by_admin);
- Toast.makeText(launcher, message, Toast.LENGTH_SHORT).show();
+ Toast.makeText(launcher, R.string.msg_disabled_by_admin, Toast.LENGTH_SHORT).show();
return false;
}
Intent intent = new Intent(Intent.ACTION_SET_WALLPAPER)
@@ -282,7 +285,7 @@ public class OptionsPopupView extends ArrowPopup<Launcher>
public final OnLongClickListener clickListener;
public OptionItem(Context context, int labelRes, int iconRes, EventEnum eventId,
- OnLongClickListener clickListener) {
+ OnLongClickListener clickListener) {
this.labelRes = labelRes;
this.label = context.getText(labelRes);
this.icon = ContextCompat.getDrawable(context, iconRes);
@@ -291,7 +294,7 @@ public class OptionsPopupView extends ArrowPopup<Launcher>
}
public OptionItem(CharSequence label, Drawable icon, EventEnum eventId,
- OnLongClickListener clickListener) {
+ OnLongClickListener clickListener) {
this.labelRes = 0;
this.label = label;
this.icon = icon;
diff --git a/src/com/android/launcher3/views/RecyclerViewFastScroller.java b/src/com/android/launcher3/views/RecyclerViewFastScroller.java
index 11ca130179..1c2534d9fd 100644
--- a/src/com/android/launcher3/views/RecyclerViewFastScroller.java
+++ b/src/com/android/launcher3/views/RecyclerViewFastScroller.java
@@ -20,8 +20,6 @@ import static android.view.HapticFeedbackConstants.CLOCK_TICK;
import static androidx.recyclerview.widget.RecyclerView.SCROLL_STATE_IDLE;
-import static com.android.launcher3.util.UiThreadHelper.hideKeyboardAsync;
-
import android.animation.ObjectAnimator;
import android.content.Context;
import android.content.res.Resources;
@@ -42,10 +40,11 @@ import android.view.ViewConfiguration;
import android.view.WindowInsets;
import android.widget.TextView;
+import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.recyclerview.widget.RecyclerView;
-import com.android.launcher3.FastScrollRecyclerView;
+import com.android.launcher3.BaseRecyclerView;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.graphics.FastScrollThumbDrawable;
@@ -115,6 +114,7 @@ public class RecyclerViewFastScroller extends View {
private boolean mIsThumbDetached;
private final boolean mCanThumbDetach;
private boolean mIgnoreDragGesture;
+ private boolean mIsRecyclerViewFirstChildInParent = true;
private long mDownTimeStampMillis;
// This is the offset from the top of the scrollbar when the user first starts touching. To
@@ -129,8 +129,9 @@ public class RecyclerViewFastScroller extends View {
private String mPopupSectionName;
private Insets mSystemGestureInsets;
- protected FastScrollRecyclerView mRv;
+ protected BaseRecyclerView mRv;
private RecyclerView.OnScrollListener mOnScrollListener;
+ @Nullable private OnFastScrollChangeListener mOnFastScrollChangeListener;
private int mDownX;
private int mDownY;
@@ -174,7 +175,7 @@ public class RecyclerViewFastScroller extends View {
ta.recycle();
}
- public void setRecyclerView(FastScrollRecyclerView rv, TextView popupView) {
+ public void setRecyclerView(BaseRecyclerView rv, TextView popupView) {
if (mRv != null && mOnScrollListener != null) {
mRv.removeOnScrollListener(mOnScrollListener);
}
@@ -207,6 +208,7 @@ public class RecyclerViewFastScroller extends View {
int rvCurrentOffsetY = mRv.getCurrentScrollY();
if (mRvOffsetY != rvCurrentOffsetY) {
mRvOffsetY = mRv.getCurrentScrollY();
+ notifyScrollChanged();
}
return;
}
@@ -214,6 +216,7 @@ public class RecyclerViewFastScroller extends View {
mThumbOffsetY = y;
invalidate();
mRvOffsetY = mRv.getCurrentScrollY();
+ notifyScrollChanged();
}
public int getThumbOffsetY() {
@@ -308,7 +311,6 @@ public class RecyclerViewFastScroller extends View {
}
private void calcTouchOffsetAndPrepToFastScroll(int downY, int lastY) {
- hideKeyboardAsync(ActivityContext.lookupContext(getContext()), getWindowToken());
mIsDragging = true;
if (mCanThumbDetach) {
mIsThumbDetached = true;
@@ -440,7 +442,9 @@ public class RecyclerViewFastScroller extends View {
return false;
}
getHitRect(sTempRect);
- sTempRect.top += mRv.getScrollBarTop();
+ if (mIsRecyclerViewFirstChildInParent) {
+ sTempRect.top += mRv.getScrollBarTop();
+ }
if (outOffset != null) {
outOffset.set(sTempRect.left, sTempRect.top);
}
@@ -453,4 +457,27 @@ public class RecyclerViewFastScroller extends View {
// alpha is so low, it does not matter.
return false;
}
+
+ public void setIsRecyclerViewFirstChildInParent(boolean isRecyclerViewFirstChildInParent) {
+ mIsRecyclerViewFirstChildInParent = isRecyclerViewFirstChildInParent;
+ }
+
+ public void setOnFastScrollChangeListener(
+ @Nullable OnFastScrollChangeListener onFastScrollChangeListener) {
+ mOnFastScrollChangeListener = onFastScrollChangeListener;
+ }
+
+ private void notifyScrollChanged() {
+ if (mOnFastScrollChangeListener != null) {
+ mOnFastScrollChangeListener.onScrollChanged();
+ }
+ }
+
+ /**
+ * A callback that is invoked when there is a scroll change in {@link RecyclerViewFastScroller}.
+ */
+ public interface OnFastScrollChangeListener {
+ /** Called when the recycler view scroll has changed. */
+ void onScrollChanged();
+ }
}
diff --git a/src/com/android/launcher3/views/Snackbar.java b/src/com/android/launcher3/views/Snackbar.java
index e582114fc9..49fcd2ebde 100644
--- a/src/com/android/launcher3/views/Snackbar.java
+++ b/src/com/android/launcher3/views/Snackbar.java
@@ -28,9 +28,8 @@ import android.view.Gravity;
import android.view.MotionEvent;
import android.widget.TextView;
-import androidx.annotation.Nullable;
-
import com.android.launcher3.AbstractFloatingView;
+import com.android.launcher3.BaseDraggingActivity;
import com.android.launcher3.R;
import com.android.launcher3.anim.Interpolators;
import com.android.launcher3.compat.AccessibilityManagerCompat;
@@ -45,7 +44,7 @@ public class Snackbar extends AbstractFloatingView {
private static final long HIDE_DURATION_MS = 180;
private static final int TIMEOUT_DURATION_MS = 4000;
- private final ActivityContext mActivity;
+ private final BaseDraggingActivity mActivity;
private Runnable mOnDismissed;
public Snackbar(Context context, AttributeSet attrs) {
@@ -54,19 +53,12 @@ public class Snackbar extends AbstractFloatingView {
public Snackbar(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
- mActivity = ActivityContext.lookupContext(context);
+ mActivity = BaseDraggingActivity.fromContext(context);
inflate(context, R.layout.snackbar, this);
}
- /** Show a snackbar with just a label. */
- public static <T extends Context & ActivityContext> void show(T activity, int labelStringRedId,
- Runnable onDismissed) {
- show(activity, labelStringRedId, NO_ID, onDismissed, null);
- }
-
- /** Show a snackbar with a label and action. */
- public static <T extends Context & ActivityContext> void show(T activity, int labelStringResId,
- int actionStringResId, Runnable onDismissed, @Nullable Runnable onActionClicked) {
+ public static void show(BaseDraggingActivity activity, int labelStringResId,
+ int actionStringResId, Runnable onDismissed, Runnable onActionClicked) {
closeOpenViews(activity, true, TYPE_SNACKBAR);
Snackbar snackbar = new Snackbar(activity, null);
// Set some properties here since inflated xml only contains the children.
@@ -88,42 +80,20 @@ public class Snackbar extends AbstractFloatingView {
int maxMarginLeftRight = res.getDimensionPixelSize(R.dimen.snackbar_max_margin_left_right);
int minMarginLeftRight = res.getDimensionPixelSize(R.dimen.snackbar_min_margin_left_right);
int marginBottom = res.getDimensionPixelSize(R.dimen.snackbar_margin_bottom);
- int absoluteMaxWidth = res.getDimensionPixelSize(R.dimen.snackbar_max_width);
Rect insets = activity.getDeviceProfile().getInsets();
- int maxWidth = Math.min(
- dragLayer.getWidth() - minMarginLeftRight * 2 - insets.left - insets.right,
- absoluteMaxWidth);
- int minWidth = Math.min(
- dragLayer.getWidth() - maxMarginLeftRight * 2 - insets.left - insets.right,
- absoluteMaxWidth);
+ int maxWidth = dragLayer.getWidth() - minMarginLeftRight * 2 - insets.left - insets.right;
+ int minWidth = dragLayer.getWidth() - maxMarginLeftRight * 2 - insets.left - insets.right;
params.width = minWidth;
params.setMargins(0, 0, 0, marginBottom + insets.bottom);
TextView labelView = snackbar.findViewById(R.id.label);
- String labelText = res.getString(labelStringResId);
- labelView.setText(labelText);
-
TextView actionView = snackbar.findViewById(R.id.action);
- float actionWidth;
- if (actionStringResId != NO_ID) {
- String actionText = res.getString(actionStringResId);
- actionWidth = actionView.getPaint().measureText(actionText)
- + actionView.getPaddingRight() + actionView.getPaddingLeft();
- actionView.setText(actionText);
- actionView.setOnClickListener(v -> {
- if (onActionClicked != null) {
- onActionClicked.run();
- }
- snackbar.mOnDismissed = null;
- snackbar.close(true);
- });
- } else {
- actionWidth = 0;
- actionView.setVisibility(GONE);
- }
-
- int totalContentWidth = (int) (labelView.getPaint().measureText(labelText) + actionWidth)
+ String labelText = res.getString(labelStringResId);
+ String actionText = res.getString(actionStringResId);
+ int totalContentWidth = (int) (labelView.getPaint().measureText(labelText)
+ + actionView.getPaint().measureText(actionText))
+ labelView.getPaddingRight() + labelView.getPaddingLeft()
+ + actionView.getPaddingRight() + actionView.getPaddingLeft()
+ padding * 2;
if (totalContentWidth > params.width) {
// The text doesn't fit in our standard width so update width to accommodate.
@@ -143,8 +113,17 @@ public class Snackbar extends AbstractFloatingView {
params.width = maxWidth;
}
}
-
+ labelView.setText(labelText);
+ actionView.setText(actionText);
+ actionView.setOnClickListener(v -> {
+ if (onActionClicked != null) {
+ onActionClicked.run();
+ }
+ snackbar.mOnDismissed = null;
+ snackbar.close(true);
+ });
snackbar.mOnDismissed = onDismissed;
+
snackbar.setAlpha(0);
snackbar.setScaleX(0.8f);
snackbar.setScaleY(0.8f);
diff --git a/src/com/android/launcher3/views/TopRoundedCornerView.java b/src/com/android/launcher3/views/TopRoundedCornerView.java
new file mode 100644
index 0000000000..92cce92ae7
--- /dev/null
+++ b/src/com/android/launcher3/views/TopRoundedCornerView.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2018 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.launcher3.views;
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Path;
+import android.graphics.RectF;
+import android.util.AttributeSet;
+
+import com.android.launcher3.util.Themes;
+
+/**
+ * View with top rounded corners.
+ */
+public class TopRoundedCornerView extends SpringRelativeLayout {
+
+ private final RectF mRect = new RectF();
+ private final Path mClipPath = new Path();
+ private float[] mRadii;
+
+ public TopRoundedCornerView(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+
+ float radius = Themes.getDialogCornerRadius(context);
+ mRadii = new float[] {radius, radius, radius, radius, 0, 0, 0, 0};
+ }
+
+ public TopRoundedCornerView(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ @Override
+ public void draw(Canvas canvas) {
+ canvas.save();
+ canvas.clipPath(mClipPath);
+ super.draw(canvas);
+ canvas.restore();
+ }
+
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+ mRect.set(0, 0, getMeasuredWidth(), getMeasuredHeight());
+ mClipPath.reset();
+ mClipPath.addRoundRect(mRect, mRadii, Path.Direction.CW);
+ }
+}
diff --git a/src/com/android/launcher3/widget/AddItemWidgetsBottomSheet.java b/src/com/android/launcher3/widget/AddItemWidgetsBottomSheet.java
index 9442734646..1cc7f53bf9 100644
--- a/src/com/android/launcher3/widget/AddItemWidgetsBottomSheet.java
+++ b/src/com/android/launcher3/widget/AddItemWidgetsBottomSheet.java
@@ -25,12 +25,10 @@ import android.content.Context;
import android.graphics.Insets;
import android.graphics.Rect;
import android.util.AttributeSet;
-import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
import android.view.WindowInsets;
-import android.widget.ScrollView;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.R;
@@ -46,9 +44,6 @@ public class AddItemWidgetsBottomSheet extends AbstractSlideInView<AddItemActivi
private static final int DEFAULT_CLOSE_DURATION = 200;
private final Rect mInsets;
- private ScrollView mWidgetPreviewScrollView;
-
- private int mContentHorizontalMarginInPx;
public AddItemWidgetsBottomSheet(Context context, AttributeSet attrs) {
this(context, attrs, 0);
@@ -57,8 +52,6 @@ public class AddItemWidgetsBottomSheet extends AbstractSlideInView<AddItemActivi
public AddItemWidgetsBottomSheet(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mInsets = new Rect();
- mContentHorizontalMarginInPx = getResources().getDimensionPixelSize(
- R.dimen.widget_list_horizontal_margin);
}
/**
@@ -75,19 +68,6 @@ public class AddItemWidgetsBottomSheet extends AbstractSlideInView<AddItemActivi
}
@Override
- public boolean onControllerInterceptTouchEvent(MotionEvent ev) {
- if (ev.getAction() == MotionEvent.ACTION_DOWN) {
- mNoIntercept = false;
- // Suppress drag to dismiss gesture if the scroll view is being scrolled.
- if (getPopupContainer().isEventOverView(mWidgetPreviewScrollView, ev)
- && mWidgetPreviewScrollView.getScrollY() > 0) {
- mNoIntercept = true;
- }
- }
- return super.onControllerInterceptTouchEvent(ev);
- }
-
- @Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
int width = r - l;
int height = b - t;
@@ -105,10 +85,7 @@ public class AddItemWidgetsBottomSheet extends AbstractSlideInView<AddItemActivi
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
DeviceProfile deviceProfile = mActivityContext.getDeviceProfile();
int widthUsed;
- if (deviceProfile.isTablet) {
- int margin = deviceProfile.allAppsLeftRightMargin;
- widthUsed = Math.max(2 * margin, 2 * (mInsets.left + mInsets.right));
- } else if (mInsets.bottom > 0) {
+ if (mInsets.bottom > 0) {
widthUsed = mInsets.left + mInsets.right;
} else {
Rect padding = deviceProfile.workspacePadding;
@@ -116,8 +93,9 @@ public class AddItemWidgetsBottomSheet extends AbstractSlideInView<AddItemActivi
2 * (mInsets.left + mInsets.right));
}
+ int heightUsed = mInsets.top + deviceProfile.edgeMarginPx;
measureChildWithMargins(mContent, widthMeasureSpec,
- widthUsed, heightMeasureSpec, deviceProfile.bottomSheetTopPadding);
+ widthUsed, heightMeasureSpec, heightUsed);
setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec),
MeasureSpec.getSize(heightMeasureSpec));
}
@@ -126,7 +104,6 @@ public class AddItemWidgetsBottomSheet extends AbstractSlideInView<AddItemActivi
protected void onFinishInflate() {
super.onFinishInflate();
mContent = findViewById(R.id.add_item_bottom_sheet_content);
- mWidgetPreviewScrollView = findViewById(R.id.widget_preview_scroll_view);
}
private void animateOpen() {
@@ -169,26 +146,6 @@ public class AddItemWidgetsBottomSheet extends AbstractSlideInView<AddItemActivi
}
mContent.setPadding(mContent.getPaddingStart(),
mContent.getPaddingTop(), mContent.getPaddingEnd(), mInsets.bottom);
-
- int contentHorizontalMarginInPx = getResources().getDimensionPixelSize(
- R.dimen.widget_list_horizontal_margin);
- if (contentHorizontalMarginInPx != mContentHorizontalMarginInPx) {
- setContentHorizontalMargin(findViewById(R.id.widget_appName),
- contentHorizontalMarginInPx);
- setContentHorizontalMargin(findViewById(R.id.widget_drag_instruction),
- contentHorizontalMarginInPx);
- setContentHorizontalMargin(findViewById(R.id.widget_cell), contentHorizontalMarginInPx);
- setContentHorizontalMargin(findViewById(R.id.actions_container),
- contentHorizontalMarginInPx);
- mContentHorizontalMarginInPx = contentHorizontalMarginInPx;
- }
return windowInsets;
}
-
- private static void setContentHorizontalMargin(View view, int contentHorizontalMargin) {
- ViewGroup.MarginLayoutParams layoutParams =
- ((ViewGroup.MarginLayoutParams) view.getLayoutParams());
- layoutParams.setMarginStart(contentHorizontalMargin);
- layoutParams.setMarginEnd(contentHorizontalMargin);
- }
}
diff --git a/src/com/android/launcher3/widget/BaseLauncherAppWidgetHostView.java b/src/com/android/launcher3/widget/BaseLauncherAppWidgetHostView.java
deleted file mode 100644
index 2742882b1f..0000000000
--- a/src/com/android/launcher3/widget/BaseLauncherAppWidgetHostView.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Copyright (C) 2021 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.launcher3.widget;
-
-import android.content.Context;
-import android.graphics.Outline;
-import android.graphics.Rect;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewOutlineProvider;
-import android.widget.RemoteViews;
-
-import androidx.annotation.UiThread;
-
-import com.android.launcher3.R;
-import com.android.launcher3.util.Executors;
-
-/**
- * Launcher AppWidgetHostView with support for rounded corners and a fallback View.
- */
-public abstract class BaseLauncherAppWidgetHostView extends NavigableAppWidgetHostView {
-
- protected final LayoutInflater mInflater;
-
- private final Rect mEnforcedRectangle = new Rect();
- private final float mEnforcedCornerRadius;
- private final ViewOutlineProvider mCornerRadiusEnforcementOutline = new ViewOutlineProvider() {
- @Override
- public void getOutline(View view, Outline outline) {
- if (mEnforcedRectangle.isEmpty() || mEnforcedCornerRadius <= 0) {
- outline.setEmpty();
- } else {
- outline.setRoundRect(mEnforcedRectangle, mEnforcedCornerRadius);
- }
- }
- };
-
- public BaseLauncherAppWidgetHostView(Context context) {
- super(context);
-
- setExecutor(Executors.THREAD_POOL_EXECUTOR);
-
- mInflater = LayoutInflater.from(context);
- mEnforcedCornerRadius = RoundedCornerEnforcement.computeEnforcedRadius(getContext());
- }
-
- @Override
- protected View getErrorView() {
- return mInflater.inflate(R.layout.appwidget_error, this, false);
- }
-
- /**
- * Fall back to error layout instead of showing widget.
- */
- public void switchToErrorView() {
- // Update the widget with 0 Layout id, to reset the view to error view.
- updateAppWidget(new RemoteViews(getAppWidgetInfo().provider.getPackageName(), 0));
- }
-
- @Override
- protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
- try {
- super.onLayout(changed, left, top, right, bottom);
- } catch (final RuntimeException e) {
- post(this::switchToErrorView);
- }
-
- enforceRoundedCorners();
- }
-
- @UiThread
- private void resetRoundedCorners() {
- setOutlineProvider(ViewOutlineProvider.BACKGROUND);
- setClipToOutline(false);
- }
-
- @UiThread
- private void enforceRoundedCorners() {
- if (mEnforcedCornerRadius <= 0 || !RoundedCornerEnforcement.isRoundedCornerEnabled()) {
- resetRoundedCorners();
- return;
- }
- View background = RoundedCornerEnforcement.findBackground(this);
- if (background == null
- || RoundedCornerEnforcement.hasAppWidgetOptedOut(this, background)) {
- resetRoundedCorners();
- return;
- }
- RoundedCornerEnforcement.computeRoundedRectangle(this,
- background,
- mEnforcedRectangle);
- setOutlineProvider(mCornerRadiusEnforcementOutline);
- setClipToOutline(true);
- }
-
- /** Returns the corner radius currently enforced, in pixels. */
- public float getEnforcedCornerRadius() {
- return mEnforcedCornerRadius;
- }
-
- /** Returns true if the corner radius are enforced for this App Widget. */
- public boolean hasEnforcedCornerRadius() {
- return getClipToOutline();
- }
-}
diff --git a/src/com/android/launcher3/widget/BaseWidgetSheet.java b/src/com/android/launcher3/widget/BaseWidgetSheet.java
index 8962c4f5eb..9f0b9d9b1f 100644
--- a/src/com/android/launcher3/widget/BaseWidgetSheet.java
+++ b/src/com/android/launcher3/widget/BaseWidgetSheet.java
@@ -16,16 +16,12 @@
package com.android.launcher3.widget;
import android.content.Context;
-import android.graphics.Canvas;
-import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.Rect;
import android.util.AttributeSet;
-import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnLongClickListener;
-import android.view.WindowInsets;
import android.widget.Toast;
import androidx.annotation.GuardedBy;
@@ -46,9 +42,7 @@ import com.android.launcher3.testing.TestProtocol;
import com.android.launcher3.touch.ItemLongClickListener;
import com.android.launcher3.util.SystemUiController;
import com.android.launcher3.util.Themes;
-import com.android.launcher3.util.window.WindowManagerProxy;
import com.android.launcher3.views.AbstractSlideInView;
-import com.android.launcher3.views.ActivityContext;
import com.android.launcher3.views.ArrowTipView;
/**
@@ -57,8 +51,6 @@ import com.android.launcher3.views.ArrowTipView;
public abstract class BaseWidgetSheet extends AbstractSlideInView<Launcher>
implements OnClickListener, OnLongClickListener, DragSource,
PopupDataProvider.PopupDataChangeListener, Insettable {
- /** The default number of cells that can fit horizontally in a widget sheet. */
- protected static final int DEFAULT_MAX_HORIZONTAL_SPANS = 4;
protected static final String KEY_WIDGETS_EDUCATION_TIP_SEEN =
"launcher.widgets_education_tip_seen";
@@ -67,17 +59,8 @@ public abstract class BaseWidgetSheet extends AbstractSlideInView<Launcher>
/* Touch handling related member variables. */
private Toast mWidgetInstructionToast;
- private int mContentHorizontalMarginInPx;
-
- protected int mNavBarScrimHeight;
- private final Paint mNavBarScrimPaint;
-
public BaseWidgetSheet(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
- mContentHorizontalMarginInPx = getResources().getDimensionPixelSize(
- R.dimen.widget_list_horizontal_margin);
- mNavBarScrimPaint = new Paint();
- mNavBarScrimPaint.setColor(Themes.getAttrColor(context, R.attr.allAppsNavBarScrimColor));
}
protected int getScrimColor(Context context) {
@@ -87,9 +70,6 @@ public abstract class BaseWidgetSheet extends AbstractSlideInView<Launcher>
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
- WindowInsets windowInsets = WindowManagerProxy.INSTANCE.get(getContext())
- .normalizeWindowInsets(getContext(), getRootWindowInsets(), new Rect());
- mNavBarScrimHeight = getNavBarScrimHeight(windowInsets);
mActivityContext.getPopupDataProvider().setChangeListener(this);
}
@@ -117,9 +97,6 @@ public abstract class BaseWidgetSheet extends AbstractSlideInView<Launcher>
@Override
public boolean onLongClick(View v) {
- if (TestProtocol.sDebugTracing) {
- Log.d(TestProtocol.NO_DROP_TARGET, "1");
- }
TestLogging.recordEvent(TestProtocol.SEQUENCE_MAIN, "Widgets.onLongClick");
v.cancelLongPress();
if (!ItemLongClickListener.canStartDrag(mActivityContext)) return false;
@@ -135,40 +112,8 @@ public abstract class BaseWidgetSheet extends AbstractSlideInView<Launcher>
@Override
public void setInsets(Rect insets) {
mInsets.set(insets);
- int contentHorizontalMarginInPx = getResources().getDimensionPixelSize(
- R.dimen.widget_list_horizontal_margin);
- if (contentHorizontalMarginInPx != mContentHorizontalMarginInPx) {
- onContentHorizontalMarginChanged(contentHorizontalMarginInPx);
- mContentHorizontalMarginInPx = contentHorizontalMarginInPx;
- }
}
- private int getNavBarScrimHeight(WindowInsets insets) {
- if (Utilities.ATLEAST_Q) {
- return insets.getTappableElementInsets().bottom;
- } else {
- return insets.getStableInsetBottom();
- }
- }
-
- @Override
- public WindowInsets onApplyWindowInsets(WindowInsets insets) {
- mNavBarScrimHeight = getNavBarScrimHeight(insets);
- return super.onApplyWindowInsets(insets);
- }
-
- @Override
- protected void dispatchDraw(Canvas canvas) {
- super.dispatchDraw(canvas);
-
- if (mNavBarScrimHeight > 0) {
- canvas.drawRect(0, getHeight() - mNavBarScrimHeight, getWidth(), getHeight(),
- mNavBarScrimPaint);
- }
- }
-
- /** Called when the horizontal margin of the content view has changed. */
- protected abstract void onContentHorizontalMarginChanged(int contentHorizontalMarginInPx);
/**
* Measures the dimension of this view and its children by taking system insets, navigation bar,
@@ -178,10 +123,7 @@ public abstract class BaseWidgetSheet extends AbstractSlideInView<Launcher>
protected void doMeasure(int widthMeasureSpec, int heightMeasureSpec) {
DeviceProfile deviceProfile = mActivityContext.getDeviceProfile();
int widthUsed;
- if (deviceProfile.isTablet) {
- int margin = deviceProfile.allAppsLeftRightMargin;
- widthUsed = Math.max(2 * margin, 2 * (mInsets.left + mInsets.right));
- } else if (mInsets.bottom > 0) {
+ if (mInsets.bottom > 0) {
widthUsed = mInsets.left + mInsets.right;
} else {
Rect padding = deviceProfile.workspacePadding;
@@ -189,29 +131,14 @@ public abstract class BaseWidgetSheet extends AbstractSlideInView<Launcher>
2 * (mInsets.left + mInsets.right));
}
+ int heightUsed = mInsets.top + deviceProfile.edgeMarginPx;
measureChildWithMargins(mContent, widthMeasureSpec,
- widthUsed, heightMeasureSpec, deviceProfile.bottomSheetTopPadding);
+ widthUsed, heightMeasureSpec, heightUsed);
setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec),
MeasureSpec.getSize(heightMeasureSpec));
}
- /** Returns the number of cells that can fit horizontally in a given {@code content}. */
- protected int computeMaxHorizontalSpans(View content, int contentHorizontalPaddingPx) {
- DeviceProfile deviceProfile = mActivityContext.getDeviceProfile();
- int availableWidth = content.getMeasuredWidth()
- - contentHorizontalPaddingPx
- - (2 * mContentHorizontalMarginInPx);
- Point cellSize = deviceProfile.getCellSize();
- if (cellSize.x > 0) {
- return availableWidth / cellSize.x;
- }
- return DEFAULT_MAX_HORIZONTAL_SPANS;
- }
-
private boolean beginDraggingWidget(WidgetCell v) {
- if (TestProtocol.sDebugTracing) {
- Log.d(TestProtocol.NO_DROP_TARGET, "2");
- }
// Get the widget preview as the drag representation
WidgetImageView image = v.getWidgetView();
@@ -222,9 +149,7 @@ public abstract class BaseWidgetSheet extends AbstractSlideInView<Launcher>
}
PendingItemDragHelper dragHelper = new PendingItemDragHelper(v);
- // RemoteViews are being rendered in AppWidgetHostView in WidgetCell. And thus, the scale of
- // RemoteViews is equivalent to the AppWidgetHostView scale.
- dragHelper.setRemoteViewsPreview(v.getRemoteViewsPreview(), v.getAppWidgetHostViewScale());
+ dragHelper.setRemoteViewsPreview(v.getRemoteViewsPreview());
dragHelper.setAppWidgetHostViewPreview(v.getAppWidgetHostViewPreview());
if (image.getDrawable() != null) {
@@ -234,11 +159,11 @@ public abstract class BaseWidgetSheet extends AbstractSlideInView<Launcher>
dragHelper.startDrag(image.getBitmapBounds(), image.getDrawable().getIntrinsicWidth(),
image.getWidth(), new Point(loc[0], loc[1]), this, new DragOptions());
} else {
- NavigableAppWidgetHostView preview = v.getAppWidgetHostViewPreview();
+ View preview = v.getAppWidgetHostViewPreview();
int[] loc = new int[2];
getPopupContainer().getLocationInDragLayer(preview, loc);
- Rect r = new Rect();
- preview.getWorkspaceVisualDragBounds(r);
+
+ Rect r = new Rect(0, 0, preview.getWidth(), preview.getHeight());
dragHelper.startDrag(r, preview.getMeasuredWidth(), preview.getMeasuredWidth(),
new Point(loc[0], loc[1]), this, new DragOptions());
}
@@ -334,11 +259,4 @@ public abstract class BaseWidgetSheet extends AbstractSlideInView<Launcher>
return mActivityContext.getSharedPrefs().getBoolean(KEY_WIDGETS_EDUCATION_TIP_SEEN, false)
|| Utilities.IS_RUNNING_IN_TEST_HARNESS;
}
-
- @Override
- protected void setTranslationShift(float translationShift) {
- super.setTranslationShift(translationShift);
- Launcher launcher = ActivityContext.lookupContext(getContext());
- launcher.onWidgetsTransition(1 - translationShift);
- }
}
diff --git a/src/com/android/launcher3/widget/CachingWidgetPreviewLoader.java b/src/com/android/launcher3/widget/CachingWidgetPreviewLoader.java
new file mode 100644
index 0000000000..afceadd9a3
--- /dev/null
+++ b/src/com/android/launcher3/widget/CachingWidgetPreviewLoader.java
@@ -0,0 +1,289 @@
+/*
+ * Copyright (C) 2021 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.launcher3.widget;
+
+import android.graphics.Bitmap;
+import android.os.CancellationSignal;
+import android.util.Size;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.UiThread;
+import androidx.collection.ArrayMap;
+import androidx.collection.ArraySet;
+
+import com.android.launcher3.BaseActivity;
+import com.android.launcher3.model.WidgetItem;
+import com.android.launcher3.util.ComponentKey;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/** Wrapper around {@link DatabaseWidgetPreviewLoader} that contains caching logic. */
+public class CachingWidgetPreviewLoader implements WidgetPreviewLoader {
+
+ @NonNull private final WidgetPreviewLoader mDelegate;
+ @NonNull private final Map<ComponentKey, Map<Size, CacheResult>> mCache = new ArrayMap<>();
+
+ public CachingWidgetPreviewLoader(@NonNull WidgetPreviewLoader delegate) {
+ mDelegate = delegate;
+ }
+
+ /** Returns whether the preview is loaded for the item and size. */
+ public boolean isPreviewLoaded(@NonNull WidgetItem item, @NonNull Size previewSize) {
+ return getPreview(item, previewSize) != null;
+ }
+
+ /** Returns the cached preview for the item and size, or null if there is none. */
+ @Nullable
+ public Bitmap getPreview(@NonNull WidgetItem item, @NonNull Size previewSize) {
+ CacheResult cacheResult = getCacheResult(item, previewSize);
+ if (cacheResult instanceof CacheResult.Loaded) {
+ return ((CacheResult.Loaded) cacheResult).mBitmap;
+ } else {
+ return null;
+ }
+ }
+
+ @NonNull
+ private CacheResult getCacheResult(@NonNull WidgetItem item, @NonNull Size previewSize) {
+ synchronized (mCache) {
+ Map<Size, CacheResult> cacheResults = mCache.get(toComponentKey(item));
+ if (cacheResults == null) {
+ return CacheResult.MISS;
+ }
+
+ return cacheResults.getOrDefault(previewSize, CacheResult.MISS);
+ }
+ }
+
+ /**
+ * Puts the result in the cache for the item and size. Returns the value previously in the
+ * cache, or null if there was none.
+ */
+ @Nullable
+ private CacheResult putCacheResult(
+ @NonNull WidgetItem item,
+ @NonNull Size previewSize,
+ @Nullable CacheResult cacheResult) {
+ ComponentKey key = toComponentKey(item);
+ synchronized (mCache) {
+ Map<Size, CacheResult> cacheResults = mCache.getOrDefault(key, new ArrayMap<>());
+ CacheResult previous;
+ if (cacheResult == null) {
+ previous = cacheResults.remove(previewSize);
+ if (cacheResults.isEmpty()) {
+ mCache.remove(key);
+ } else {
+ previous = cacheResults.put(previewSize, cacheResult);
+ mCache.put(key, cacheResults);
+ }
+ } else {
+ previous = cacheResults.put(previewSize, cacheResult);
+ mCache.put(key, cacheResults);
+ }
+ return previous;
+ }
+ }
+
+ private void removeCacheResult(@NonNull WidgetItem item, @NonNull Size previewSize) {
+ ComponentKey key = toComponentKey(item);
+ synchronized (mCache) {
+ Map<Size, CacheResult> cacheResults = mCache.getOrDefault(key, new ArrayMap<>());
+ cacheResults.remove(previewSize);
+ mCache.put(key, cacheResults);
+ }
+ }
+
+ /**
+ * Gets the preview for the widget item and size, using the value in the cache if stored.
+ *
+ * @return a {@link CancellationSignal}, which can cancel the request before it loads
+ */
+ @Override
+ @UiThread
+ @NonNull
+ public CancellationSignal loadPreview(
+ @NonNull BaseActivity activity, @NonNull WidgetItem item, @NonNull Size previewSize,
+ @NonNull WidgetPreviewLoadedCallback callback) {
+ CancellationSignal signal = new CancellationSignal();
+ signal.setOnCancelListener(() -> {
+ synchronized (mCache) {
+ CacheResult cacheResult = getCacheResult(item, previewSize);
+ if (!(cacheResult instanceof CacheResult.Loading)) {
+ // If the key isn't actively loading, then this is a no-op. Cancelling loading
+ // shouldn't clear the cache if we've already loaded.
+ return;
+ }
+
+ CacheResult.Loading prev = (CacheResult.Loading) cacheResult;
+ CacheResult.Loading updated = prev.withoutCallback(callback);
+
+ if (updated.mCallbacks.isEmpty()) {
+ // If the last callback was removed, then cancel the underlying request in the
+ // delegate.
+ prev.mCancellationSignal.cancel();
+ removeCacheResult(item, previewSize);
+ } else {
+ // If there are other callbacks still active, then don't cancel the delegate's
+ // request, just remove this callback from the set.
+ putCacheResult(item, previewSize, updated);
+ }
+ }
+ });
+
+ synchronized (mCache) {
+ CacheResult cacheResult = getCacheResult(item, previewSize);
+ if (cacheResult instanceof CacheResult.Loaded) {
+ // If the bitmap is already present in the cache, invoke the callback immediately.
+ callback.onPreviewLoaded(((CacheResult.Loaded) cacheResult).mBitmap);
+ return signal;
+ }
+
+ if (cacheResult instanceof CacheResult.Loading) {
+ // If we're already loading the preview for this key, then just add the callback
+ // to the set we'll call after it loads.
+ CacheResult.Loading prev = (CacheResult.Loading) cacheResult;
+ putCacheResult(item, previewSize, prev.withCallback(callback));
+ return signal;
+ }
+
+ CancellationSignal delegateCancellationSignal =
+ mDelegate.loadPreview(
+ activity,
+ item,
+ previewSize,
+ preview -> {
+ CacheResult prev;
+ synchronized (mCache) {
+ prev = putCacheResult(
+ item, previewSize, new CacheResult.Loaded(preview));
+ }
+ if (prev instanceof CacheResult.Loading) {
+ // Notify each stored callback that the preview has loaded.
+ ((CacheResult.Loading) prev).mCallbacks
+ .forEach(c -> c.onPreviewLoaded(preview));
+ } else {
+ // If there isn't a loading object in the cache, then we were
+ // notified before adding this signal to the cache. Just
+ // call back to the provided callback, there can't be others.
+ callback.onPreviewLoaded(preview);
+ }
+ });
+ ArraySet<WidgetPreviewLoadedCallback> callbacks = new ArraySet<>();
+ callbacks.add(callback);
+ putCacheResult(
+ item,
+ previewSize,
+ new CacheResult.Loading(delegateCancellationSignal, callbacks));
+ }
+
+ return signal;
+ }
+
+ /** Clears all cached previews for {@code items}, cancelling any in-progress preview loading. */
+ public void clearPreviews(Iterable<WidgetItem> items) {
+ List<CacheResult> previousCacheResults = new ArrayList<>();
+ synchronized (mCache) {
+ for (WidgetItem item : items) {
+ Map<Size, CacheResult> previousMap = mCache.remove(toComponentKey(item));
+ if (previousMap != null) {
+ previousCacheResults.addAll(previousMap.values());
+ }
+ }
+ }
+
+ for (CacheResult previousCacheResult : previousCacheResults) {
+ if (previousCacheResult instanceof CacheResult.Loading) {
+ ((CacheResult.Loading) previousCacheResult).mCancellationSignal.cancel();
+ }
+ }
+ }
+
+ /** Clears all cached previews, cancelling any in-progress preview loading. */
+ public void clearAll() {
+ List<CacheResult> previousCacheResults;
+ synchronized (mCache) {
+ previousCacheResults =
+ mCache
+ .values()
+ .stream()
+ .flatMap(sizeToResult -> sizeToResult.values().stream())
+ .collect(Collectors.toList());
+ mCache.clear();
+ }
+
+ for (CacheResult previousCacheResult : previousCacheResults) {
+ if (previousCacheResult instanceof CacheResult.Loading) {
+ ((CacheResult.Loading) previousCacheResult).mCancellationSignal.cancel();
+ }
+ }
+ }
+
+ private abstract static class CacheResult {
+ static final CacheResult MISS = new CacheResult() {};
+
+ static final class Loading extends CacheResult {
+ @NonNull final CancellationSignal mCancellationSignal;
+ @NonNull final Set<WidgetPreviewLoadedCallback> mCallbacks;
+
+ Loading(@NonNull CancellationSignal cancellationSignal,
+ @NonNull Set<WidgetPreviewLoadedCallback> callbacks) {
+ mCancellationSignal = cancellationSignal;
+ mCallbacks = callbacks;
+ }
+
+ @NonNull
+ Loading withCallback(@NonNull WidgetPreviewLoadedCallback callback) {
+ if (mCallbacks.contains(callback)) return this;
+ Set<WidgetPreviewLoadedCallback> newCallbacks =
+ new ArraySet<>(mCallbacks.size() + 1);
+ newCallbacks.addAll(mCallbacks);
+ newCallbacks.add(callback);
+ return new Loading(mCancellationSignal, newCallbacks);
+ }
+
+ @NonNull
+ Loading withoutCallback(@NonNull WidgetPreviewLoadedCallback callback) {
+ if (!mCallbacks.contains(callback)) return this;
+ Set<WidgetPreviewLoadedCallback> newCallbacks =
+ new ArraySet<>(mCallbacks.size() - 1);
+ for (WidgetPreviewLoadedCallback existingCallback : mCallbacks) {
+ if (!existingCallback.equals(callback)) {
+ newCallbacks.add(existingCallback);
+ }
+ }
+ return new Loading(mCancellationSignal, newCallbacks);
+ }
+ }
+
+ static final class Loaded extends CacheResult {
+ @NonNull final Bitmap mBitmap;
+
+ Loaded(@NonNull Bitmap bitmap) {
+ mBitmap = bitmap;
+ }
+ }
+ }
+
+ @NonNull
+ private static ComponentKey toComponentKey(@NonNull WidgetItem item) {
+ return new ComponentKey(item.componentName, item.user);
+ }
+}
diff --git a/src/com/android/launcher3/widget/DatabaseWidgetPreviewLoader.java b/src/com/android/launcher3/widget/DatabaseWidgetPreviewLoader.java
index 7030f6dede..4ec7e60c86 100644
--- a/src/com/android/launcher3/widget/DatabaseWidgetPreviewLoader.java
+++ b/src/com/android/launcher3/widget/DatabaseWidgetPreviewLoader.java
@@ -16,10 +16,21 @@
package com.android.launcher3.widget;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
+import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
+import android.content.ComponentName;
+import android.content.ContentValues;
import android.content.Context;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Resources;
+import android.database.Cursor;
+import android.database.SQLException;
+import android.database.sqlite.SQLiteDatabase;
import android.graphics.Bitmap;
+import android.graphics.Bitmap.Config;
+import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
@@ -28,39 +39,72 @@ import android.graphics.PorterDuffXfermode;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
-import android.os.Handler;
+import android.os.CancellationSignal;
+import android.os.Process;
+import android.os.UserHandle;
import android.util.Log;
+import android.util.LongSparseArray;
+import android.util.Pair;
import android.util.Size;
import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import com.android.launcher3.BaseActivity;
import com.android.launcher3.DeviceProfile;
-import com.android.launcher3.LauncherAppState;
+import com.android.launcher3.LauncherFiles;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
-import com.android.launcher3.icons.BitmapRenderer;
+import com.android.launcher3.icons.GraphicsUtils;
+import com.android.launcher3.icons.IconCache;
import com.android.launcher3.icons.LauncherIcons;
import com.android.launcher3.icons.ShadowGenerator;
-import com.android.launcher3.icons.cache.HandlerRunnable;
import com.android.launcher3.model.WidgetItem;
import com.android.launcher3.pm.ShortcutConfigActivityInfo;
+import com.android.launcher3.pm.UserCache;
+import com.android.launcher3.util.ComponentKey;
import com.android.launcher3.util.Executors;
-import com.android.launcher3.views.ActivityContext;
+import com.android.launcher3.util.PackageUserKey;
+import com.android.launcher3.util.Preconditions;
+import com.android.launcher3.util.SQLiteCacheHelper;
+import com.android.launcher3.util.Thunk;
import com.android.launcher3.widget.util.WidgetSizes;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.WeakHashMap;
import java.util.concurrent.ExecutionException;
-import java.util.function.Consumer;
-/** Utility class to load widget previews */
-public class DatabaseWidgetPreviewLoader {
+/** {@link WidgetPreviewLoader} that loads preview images from a {@link CacheDb}. */
+public class DatabaseWidgetPreviewLoader implements WidgetPreviewLoader {
private static final String TAG = "WidgetPreviewLoader";
+ private static final boolean DEBUG = false;
+
+ private final HashMap<String, long[]> mPackageVersions = new HashMap<>();
+
+ /**
+ * Weak reference objects, do not prevent their referents from being made finalizable,
+ * finalized, and then reclaimed.
+ * Note: synchronized block used for this variable is expensive and the block should always
+ * be posted to a background thread.
+ */
+ @Thunk final Set<Bitmap> mUnusedBitmaps = Collections.newSetFromMap(new WeakHashMap<>());
private final Context mContext;
+ private final IconCache mIconCache;
+ private final UserCache mUserCache;
+ private final CacheDb mDb;
private final float mPreviewBoxCornerRadius;
- public DatabaseWidgetPreviewLoader(Context context) {
+ public DatabaseWidgetPreviewLoader(Context context, IconCache iconCache) {
mContext = context;
+ mIconCache = iconCache;
+ mUserCache = UserCache.INSTANCE.get(context);
+ mDb = new CacheDb(context);
float previewCornerRadius = RoundedCornerEnforcement.computeEnforcedRadius(context);
mPreviewBoxCornerRadius = previewCornerRadius > 0
? previewCornerRadius
@@ -73,29 +117,251 @@ public class DatabaseWidgetPreviewLoader {
*
* @return a request id which can be used to cancel the request.
*/
+ @Override
@NonNull
- public HandlerRunnable loadPreview(
+ public CancellationSignal loadPreview(
+ @NonNull BaseActivity activity,
@NonNull WidgetItem item,
@NonNull Size previewSize,
- @NonNull Consumer<Bitmap> callback) {
- Handler handler = Executors.UI_HELPER_EXECUTOR.getHandler();
- HandlerRunnable<Bitmap> request = new HandlerRunnable<>(handler,
- () -> generatePreview(item, previewSize.getWidth(), previewSize.getHeight()),
- MAIN_EXECUTOR,
- callback);
- Utilities.postAsyncCallback(handler, request);
- return request;
+ @NonNull WidgetPreviewLoadedCallback callback) {
+ int previewWidth = previewSize.getWidth();
+ int previewHeight = previewSize.getHeight();
+ String size = previewWidth + "x" + previewHeight;
+ WidgetCacheKey key = new WidgetCacheKey(item.componentName, item.user, size);
+
+ PreviewLoadTask task =
+ new PreviewLoadTask(activity, key, item, previewWidth, previewHeight, callback);
+ task.executeOnExecutor(Executors.THREAD_POOL_EXECUTOR);
+
+ CancellationSignal signal = new CancellationSignal();
+ signal.setOnCancelListener(task);
+ return signal;
+ }
+
+ /** Clears the database storing previews. */
+ public void refresh() {
+ mDb.clear();
+ }
+
+ /**
+ * The DB holds the generated previews for various components. Previews can also have different
+ * sizes (landscape vs portrait).
+ */
+ private static class CacheDb extends SQLiteCacheHelper {
+ private static final int DB_VERSION = 9;
+
+ private static final String TABLE_NAME = "shortcut_and_widget_previews";
+ private static final String COLUMN_COMPONENT = "componentName";
+ private static final String COLUMN_USER = "profileId";
+ private static final String COLUMN_SIZE = "size";
+ private static final String COLUMN_PACKAGE = "packageName";
+ private static final String COLUMN_LAST_UPDATED = "lastUpdated";
+ private static final String COLUMN_VERSION = "version";
+ private static final String COLUMN_PREVIEW_BITMAP = "preview_bitmap";
+
+ CacheDb(Context context) {
+ super(context, LauncherFiles.WIDGET_PREVIEWS_DB, DB_VERSION, TABLE_NAME);
+ }
+
+ @Override
+ public void onCreateTable(SQLiteDatabase database) {
+ database.execSQL("CREATE TABLE IF NOT EXISTS "
+ + TABLE_NAME
+ + " ("
+ + COLUMN_COMPONENT
+ + " TEXT NOT NULL, "
+ + COLUMN_USER
+ + " INTEGER NOT NULL, "
+ + COLUMN_SIZE
+ + " TEXT NOT NULL, "
+ + COLUMN_PACKAGE
+ + " TEXT NOT NULL, "
+ + COLUMN_LAST_UPDATED
+ + " INTEGER NOT NULL DEFAULT 0, "
+ + COLUMN_VERSION
+ + " INTEGER NOT NULL DEFAULT 0, "
+ + COLUMN_PREVIEW_BITMAP
+ + " BLOB, "
+ + "PRIMARY KEY ("
+ + COLUMN_COMPONENT
+ + ", "
+ + COLUMN_USER
+ + ", "
+ + COLUMN_SIZE
+ + ") "
+ +
+ ");");
+ }
+ }
+
+ @Thunk void writeToDb(WidgetCacheKey key, long[] versions, Bitmap preview) {
+ ContentValues values = new ContentValues();
+ values.put(CacheDb.COLUMN_COMPONENT, key.componentName.flattenToShortString());
+ values.put(CacheDb.COLUMN_USER, mUserCache.getSerialNumberForUser(key.user));
+ values.put(CacheDb.COLUMN_SIZE, key.mSize);
+ values.put(CacheDb.COLUMN_PACKAGE, key.componentName.getPackageName());
+ values.put(CacheDb.COLUMN_VERSION, versions[0]);
+ values.put(CacheDb.COLUMN_LAST_UPDATED, versions[1]);
+ values.put(CacheDb.COLUMN_PREVIEW_BITMAP, GraphicsUtils.flattenBitmap(preview));
+ mDb.insertOrReplace(values);
+ }
+
+ /** Removes the package from the preview database. */
+ public void removePackage(String packageName, UserHandle user) {
+ removePackage(packageName, user, mUserCache.getSerialNumberForUser(user));
+ }
+
+ /** Removes the package from the preview database. */
+ public void removePackage(String packageName, UserHandle user, long userSerial) {
+ synchronized (mPackageVersions) {
+ mPackageVersions.remove(packageName);
+ }
+
+ mDb.delete(
+ CacheDb.COLUMN_PACKAGE + " = ? AND " + CacheDb.COLUMN_USER + " = ?",
+ new String[]{packageName, Long.toString(userSerial)});
+ }
+
+ /**
+ * Updates the persistent DB:
+ * 1. Any preview generated for an old package version is removed
+ * 2. Any preview for an absent package is removed
+ * This ensures that we remove entries for packages which changed while the launcher was dead.
+ *
+ * @param packageUser if provided, specifies that list only contains previews for the
+ * given package/user, otherwise the list contains all previews
+ */
+ public void removeObsoletePreviews(ArrayList<? extends ComponentKey> list,
+ @Nullable PackageUserKey packageUser) {
+ Preconditions.assertWorkerThread();
+
+ LongSparseArray<HashSet<String>> validPackages = new LongSparseArray<>();
+
+ for (ComponentKey key : list) {
+ final long userId = mUserCache.getSerialNumberForUser(key.user);
+ HashSet<String> packages = validPackages.get(userId);
+ if (packages == null) {
+ packages = new HashSet<>();
+ validPackages.put(userId, packages);
+ }
+ packages.add(key.componentName.getPackageName());
+ }
+
+ LongSparseArray<HashSet<String>> packagesToDelete = new LongSparseArray<>();
+ long passedUserId = packageUser == null ? 0
+ : mUserCache.getSerialNumberForUser(packageUser.mUser);
+ Cursor c = null;
+ try {
+ c = mDb.query(
+ new String[]{CacheDb.COLUMN_USER, CacheDb.COLUMN_PACKAGE,
+ CacheDb.COLUMN_LAST_UPDATED, CacheDb.COLUMN_VERSION},
+ null, null);
+ while (c.moveToNext()) {
+ long userId = c.getLong(0);
+ String pkg = c.getString(1);
+ long lastUpdated = c.getLong(2);
+ long version = c.getLong(3);
+
+ if (packageUser != null && (!pkg.equals(packageUser.mPackageName)
+ || userId != passedUserId)) {
+ // This preview is associated with a different package/user, no need to remove.
+ continue;
+ }
+
+ HashSet<String> packages = validPackages.get(userId);
+ if (packages != null && packages.contains(pkg)) {
+ long[] versions = getPackageVersion(pkg);
+ if (versions[0] == version && versions[1] == lastUpdated) {
+ // Every thing checks out
+ continue;
+ }
+ }
+
+ // We need to delete this package.
+ packages = packagesToDelete.get(userId);
+ if (packages == null) {
+ packages = new HashSet<>();
+ packagesToDelete.put(userId, packages);
+ }
+ packages.add(pkg);
+ }
+
+ for (int i = 0; i < packagesToDelete.size(); i++) {
+ long userId = packagesToDelete.keyAt(i);
+ UserHandle user = mUserCache.getUserForSerialNumber(userId);
+ for (String pkg : packagesToDelete.valueAt(i)) {
+ removePackage(pkg, user, userId);
+ }
+ }
+ } catch (SQLException e) {
+ Log.e(TAG, "Error updating widget previews", e);
+ } finally {
+ if (c != null) {
+ c.close();
+ }
+ }
+ }
+
+ /**
+ * Reads the preview bitmap from the DB or null if the preview is not in the DB.
+ */
+ @Thunk Bitmap readFromDb(WidgetCacheKey key, Bitmap recycle, PreviewLoadTask loadTask) {
+ Cursor cursor = null;
+ try {
+ cursor = mDb.query(
+ new String[]{CacheDb.COLUMN_PREVIEW_BITMAP},
+ CacheDb.COLUMN_COMPONENT + " = ? AND " + CacheDb.COLUMN_USER + " = ? AND "
+ + CacheDb.COLUMN_SIZE + " = ?",
+ new String[]{
+ key.componentName.flattenToShortString(),
+ Long.toString(mUserCache.getSerialNumberForUser(key.user)),
+ key.mSize
+ });
+ // If cancelled, skip getting the blob and decoding it into a bitmap
+ if (loadTask.isCancelled()) {
+ return null;
+ }
+ if (cursor.moveToNext()) {
+ byte[] blob = cursor.getBlob(0);
+ BitmapFactory.Options opts = new BitmapFactory.Options();
+ opts.inBitmap = recycle;
+ try {
+ if (!loadTask.isCancelled()) {
+ return BitmapFactory.decodeByteArray(blob, 0, blob.length, opts);
+ }
+ } catch (Exception e) {
+ return null;
+ }
+ }
+ } catch (SQLException e) {
+ Log.w(TAG, "Error loading preview from DB", e);
+ } finally {
+ if (cursor != null) {
+ cursor.close();
+ }
+ }
+ return null;
}
/**
* Returns a generated preview for a widget and if the preview should be saved in persistent
* storage.
+ * @param launcher
+ * @param item
+ * @param recycle
+ * @param previewWidth
+ * @param previewHeight
+ * @return Pair<Bitmap, Boolean>
*/
- private Bitmap generatePreview(WidgetItem item, int previewWidth, int previewHeight) {
+ private Pair<Bitmap, Boolean> generatePreview(BaseActivity launcher, WidgetItem item,
+ Bitmap recycle,
+ int previewWidth, int previewHeight) {
if (item.widgetInfo != null) {
- return generateWidgetPreview(item.widgetInfo, previewWidth, null);
+ return generateWidgetPreview(launcher, item.widgetInfo,
+ previewWidth, recycle, null);
} else {
- return generateShortcutPreview(item.activityInfo, previewWidth, previewHeight);
+ return new Pair<>(generateShortcutPreview(launcher, item.activityInfo,
+ previewWidth, previewHeight, recycle), false);
}
}
@@ -103,12 +369,16 @@ public class DatabaseWidgetPreviewLoader {
* Generates the widget preview from either the {@link WidgetManagerHelper} or cache
* and add badge at the bottom right corner.
*
+ * @param launcher
* @param info information about the widget
* @param maxPreviewWidth width of the preview on either workspace or tray
+ * @param preview bitmap that can be recycled
* @param preScaledWidthOut return the width of the returned bitmap
+ * @return Pair<Bitmap (the preview) , Boolean (should be stored in db)>
*/
- public Bitmap generateWidgetPreview(LauncherAppWidgetProviderInfo info,
- int maxPreviewWidth, int[] preScaledWidthOut) {
+ public Pair<Bitmap, Boolean> generateWidgetPreview(BaseActivity launcher,
+ LauncherAppWidgetProviderInfo info,
+ int maxPreviewWidth, Bitmap preview, int[] preScaledWidthOut) {
// Load the preview image if possible
if (maxPreviewWidth < 0) maxPreviewWidth = Integer.MAX_VALUE;
@@ -139,97 +409,117 @@ public class DatabaseWidgetPreviewLoader {
int previewWidth;
int previewHeight;
- DeviceProfile dp = ActivityContext.lookupContext(mContext).getDeviceProfile();
+ boolean savePreviewImage = widgetPreviewExists || info.previewImage == 0;
if (widgetPreviewExists && drawable.getIntrinsicWidth() > 0
&& drawable.getIntrinsicHeight() > 0) {
previewWidth = drawable.getIntrinsicWidth();
previewHeight = drawable.getIntrinsicHeight();
} else {
+ DeviceProfile dp = launcher.getDeviceProfile();
Size widgetSize = WidgetSizes.getWidgetPaddedSizePx(mContext, info.provider, dp, spanX,
spanY);
previewWidth = widgetSize.getWidth();
previewHeight = widgetSize.getHeight();
}
+ // Scale to fit width only - let the widget preview be clipped in the
+ // vertical dimension
+ float scale = 1f;
if (preScaledWidthOut != null) {
preScaledWidthOut[0] = previewWidth;
}
- // Scale to fit width only - let the widget preview be clipped in the
- // vertical dimension
- final float scale = previewWidth > maxPreviewWidth
- ? (maxPreviewWidth / (float) (previewWidth)) : 1f;
+ if (previewWidth > maxPreviewWidth) {
+ scale = maxPreviewWidth / (float) (previewWidth);
+ }
if (scale != 1f) {
previewWidth = Math.max((int) (scale * previewWidth), 1);
previewHeight = Math.max((int) (scale * previewHeight), 1);
}
- final int previewWidthF = previewWidth;
- final int previewHeightF = previewHeight;
- final Drawable drawableF = drawable;
+ final Canvas c = new Canvas();
+ if (preview == null) {
+ // If no bitmap was provided, then allocate a new one with the right size.
+ preview = Bitmap.createBitmap(previewWidth, previewHeight, Config.ARGB_8888);
+ c.setBitmap(preview);
+ } else {
+ // If a bitmap was passed in, attempt to reconfigure the bitmap to the same dimensions
+ // as the preview.
+ try {
+ preview.reconfigure(previewWidth, previewHeight, preview.getConfig());
+ } catch (IllegalArgumentException e) {
+ // This occurs if the preview can't be reconfigured for any reason. In this case,
+ // allocate a new bitmap with the right size.
+ preview = Bitmap.createBitmap(previewWidth, previewHeight, Config.ARGB_8888);
+ }
+
+ c.setBitmap(preview);
+ c.drawColor(0, PorterDuff.Mode.CLEAR);
+ }
+
+ // Draw the scaled preview into the final bitmap
+ if (widgetPreviewExists) {
+ drawable.setBounds(0, 0, previewWidth, previewHeight);
+ drawable.draw(c);
+ } else {
+ RectF boxRect;
+
+ // Draw horizontal and vertical lines to represent individual columns.
+ final Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);
+
+ if (Utilities.ATLEAST_S) {
+ boxRect = new RectF(/* left= */ 0, /* top= */ 0, /* right= */
+ previewWidth, /* bottom= */ previewHeight);
- return BitmapRenderer.createHardwareBitmap(previewWidth, previewHeight, c -> {
- // Draw the scaled preview into the final bitmap
- if (widgetPreviewExists) {
- drawableF.setBounds(0, 0, previewWidthF, previewHeightF);
- drawableF.draw(c);
+ p.setStyle(Paint.Style.FILL);
+ p.setColor(Color.WHITE);
+ float roundedCorner = mContext.getResources().getDimension(
+ android.R.dimen.system_app_widget_background_radius);
+ c.drawRoundRect(boxRect, roundedCorner, roundedCorner, p);
} else {
- RectF boxRect;
-
- // Draw horizontal and vertical lines to represent individual columns.
- final Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);
-
- if (Utilities.ATLEAST_S) {
- boxRect = new RectF(/* left= */ 0, /* top= */ 0, /* right= */
- previewWidthF, /* bottom= */ previewHeightF);
-
- p.setStyle(Paint.Style.FILL);
- p.setColor(Color.WHITE);
- float roundedCorner = mContext.getResources().getDimension(
- android.R.dimen.system_app_widget_background_radius);
- c.drawRoundRect(boxRect, roundedCorner, roundedCorner, p);
- } else {
- boxRect = drawBoxWithShadow(c, previewWidthF, previewHeightF);
- }
+ boxRect = drawBoxWithShadow(c, previewWidth, previewHeight);
+ }
- p.setStyle(Paint.Style.STROKE);
- p.setStrokeWidth(mContext.getResources()
- .getDimension(R.dimen.widget_preview_cell_divider_width));
- p.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
+ p.setStyle(Paint.Style.STROKE);
+ p.setStrokeWidth(mContext.getResources()
+ .getDimension(R.dimen.widget_preview_cell_divider_width));
+ p.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
- float t = boxRect.left;
- float tileSize = boxRect.width() / spanX;
- for (int i = 1; i < spanX; i++) {
- t += tileSize;
- c.drawLine(t, 0, t, previewHeightF, p);
- }
+ float t = boxRect.left;
+ float tileSize = boxRect.width() / spanX;
+ for (int i = 1; i < spanX; i++) {
+ t += tileSize;
+ c.drawLine(t, 0, t, previewHeight, p);
+ }
- t = boxRect.top;
- tileSize = boxRect.height() / spanY;
- for (int i = 1; i < spanY; i++) {
- t += tileSize;
- c.drawLine(0, t, previewWidthF, t, p);
- }
+ t = boxRect.top;
+ tileSize = boxRect.height() / spanY;
+ for (int i = 1; i < spanY; i++) {
+ t += tileSize;
+ c.drawLine(0, t, previewWidth, t, p);
+ }
- // Draw icon in the center.
- try {
- Drawable icon = LauncherAppState.getInstance(mContext).getIconCache()
- .getFullResIcon(info.provider.getPackageName(), info.icon);
- if (icon != null) {
- int appIconSize = dp.iconSizePx;
- int iconSize = (int) Math.min(appIconSize * scale,
- Math.min(boxRect.width(), boxRect.height()));
-
- icon = mutateOnMainThread(icon);
- int hoffset = (previewWidthF - iconSize) / 2;
- int yoffset = (previewHeightF - iconSize) / 2;
- icon.setBounds(hoffset, yoffset, hoffset + iconSize, yoffset + iconSize);
- icon.draw(c);
- }
- } catch (Resources.NotFoundException e) {
+ // Draw icon in the center.
+ try {
+ Drawable icon =
+ mIconCache.getFullResIcon(info.provider.getPackageName(), info.icon);
+ if (icon != null) {
+ int appIconSize = launcher.getDeviceProfile().iconSizePx;
+ int iconSize = (int) Math.min(appIconSize * scale,
+ Math.min(boxRect.width(), boxRect.height()));
+
+ icon = mutateOnMainThread(icon);
+ int hoffset = (previewWidth - iconSize) / 2;
+ int yoffset = (previewHeight - iconSize) / 2;
+ icon.setBounds(hoffset, yoffset, hoffset + iconSize, yoffset + iconSize);
+ icon.draw(c);
}
+ } catch (Resources.NotFoundException e) {
+ savePreviewImage = false;
}
- });
+ c.setBitmap(null);
+ }
+ return new Pair<>(preview, savePreviewImage);
}
private RectF drawBoxWithShadow(Canvas c, int width, int height) {
@@ -247,29 +537,42 @@ public class DatabaseWidgetPreviewLoader {
return builder.bounds;
}
- private Bitmap generateShortcutPreview(
- ShortcutConfigActivityInfo info, int maxWidth, int maxHeight) {
- int iconSize = ActivityContext.lookupContext(mContext).getDeviceProfile().allAppsIconSizePx;
- int padding = mContext.getResources()
+ private Bitmap generateShortcutPreview(BaseActivity launcher, ShortcutConfigActivityInfo info,
+ int maxWidth, int maxHeight, Bitmap preview) {
+ int iconSize = launcher.getDeviceProfile().allAppsIconSizePx;
+ int padding = launcher.getResources()
.getDimensionPixelSize(R.dimen.widget_preview_shortcut_padding);
int size = iconSize + 2 * padding;
if (maxHeight < size || maxWidth < size) {
throw new RuntimeException("Max size is too small for preview");
}
- return BitmapRenderer.createHardwareBitmap(size, size, c -> {
- drawBoxWithShadow(c, size, size);
-
- LauncherIcons li = LauncherIcons.obtain(mContext);
- Drawable icon = li.createBadgedIconBitmap(
- mutateOnMainThread(info.getFullResIcon(
- LauncherAppState.getInstance(mContext).getIconCache())))
- .newIcon(mContext);
- li.recycle();
-
- icon.setBounds(padding, padding, padding + iconSize, padding + iconSize);
- icon.draw(c);
- });
+ final Canvas c = new Canvas();
+ if (preview == null || preview.getWidth() < size || preview.getHeight() < size) {
+ preview = Bitmap.createBitmap(size, size, Config.ARGB_8888);
+ c.setBitmap(preview);
+ } else {
+ if (preview.getWidth() > size || preview.getHeight() > size) {
+ preview.reconfigure(size, size, preview.getConfig());
+ }
+
+ // Reusing bitmap. Clear it.
+ c.setBitmap(preview);
+ c.drawColor(0, PorterDuff.Mode.CLEAR);
+ }
+
+ drawBoxWithShadow(c, size, size);
+
+ LauncherIcons li = LauncherIcons.obtain(mContext);
+ Drawable icon = li.createBadgedIconBitmap(
+ mutateOnMainThread(info.getFullResIcon(mIconCache)),
+ Process.myUserHandle(), 0).newIcon(launcher);
+ li.recycle();
+
+ icon.setBounds(padding, padding, padding + iconSize, padding + iconSize);
+ icon.draw(c);
+ c.setBitmap(null);
+ return preview;
}
private Drawable mutateOnMainThread(final Drawable drawable) {
@@ -282,4 +585,206 @@ public class DatabaseWidgetPreviewLoader {
throw new RuntimeException(e);
}
}
+
+ /**
+ * @return an array of containing versionCode and lastUpdatedTime for the package.
+ */
+ @Thunk long[] getPackageVersion(String packageName) {
+ synchronized (mPackageVersions) {
+ long[] versions = mPackageVersions.get(packageName);
+ if (versions == null) {
+ versions = new long[2];
+ try {
+ PackageInfo info = mContext.getPackageManager().getPackageInfo(packageName,
+ PackageManager.GET_UNINSTALLED_PACKAGES);
+ versions[0] = info.versionCode;
+ versions[1] = info.lastUpdateTime;
+ } catch (NameNotFoundException e) {
+ Log.e(TAG, "PackageInfo not found", e);
+ }
+ mPackageVersions.put(packageName, versions);
+ }
+ return versions;
+ }
+ }
+
+ private class PreviewLoadTask extends AsyncTask<Void, Void, Bitmap>
+ implements CancellationSignal.OnCancelListener {
+ @Thunk final WidgetCacheKey mKey;
+ private final WidgetItem mInfo;
+ private final int mPreviewHeight;
+ private final int mPreviewWidth;
+ private final WidgetPreviewLoadedCallback mCallback;
+ private final BaseActivity mActivity;
+ @Thunk long[] mVersions;
+ @Thunk Bitmap mBitmapToRecycle;
+
+ @Nullable private Bitmap mUnusedPreviewBitmap;
+ private boolean mSaveToDB = false;
+
+ PreviewLoadTask(BaseActivity activity, WidgetCacheKey key, WidgetItem info,
+ int previewWidth, int previewHeight, WidgetPreviewLoadedCallback callback) {
+ mActivity = activity;
+ mKey = key;
+ mInfo = info;
+ mPreviewHeight = previewHeight;
+ mPreviewWidth = previewWidth;
+ mCallback = callback;
+ if (DEBUG) {
+ Log.d(TAG, String.format("%s, %s, %d, %d",
+ mKey, mInfo, mPreviewHeight, mPreviewWidth));
+ }
+ }
+
+ @Override
+ protected Bitmap doInBackground(Void... params) {
+ Bitmap unusedBitmap = null;
+
+ // If already cancelled before this gets to run in the background, then return early
+ if (isCancelled()) {
+ return null;
+ }
+ synchronized (mUnusedBitmaps) {
+ // Check if we can re-use a bitmap
+ for (Bitmap candidate : mUnusedBitmaps) {
+ if (candidate != null && candidate.isMutable()
+ && candidate.getWidth() == mPreviewWidth
+ && candidate.getHeight() == mPreviewHeight) {
+ unusedBitmap = candidate;
+ mUnusedBitmaps.remove(unusedBitmap);
+ break;
+ }
+ }
+ }
+
+ // creating a bitmap is expensive. Do not do this inside synchronized block.
+ if (unusedBitmap == null) {
+ unusedBitmap = Bitmap.createBitmap(mPreviewWidth, mPreviewHeight, Config.ARGB_8888);
+ }
+ // If cancelled now, don't bother reading the preview from the DB
+ if (isCancelled()) {
+ return unusedBitmap;
+ }
+ Bitmap preview = readFromDb(mKey, unusedBitmap, this);
+ // Only consider generating the preview if we have not cancelled the task already
+ if (!isCancelled() && preview == null) {
+ // Fetch the version info before we generate the preview, so that, in-case the
+ // app was updated while we are generating the preview, we use the old version info,
+ // which would gets re-written next time.
+ boolean persistable = mInfo.activityInfo == null
+ || mInfo.activityInfo.isPersistable();
+ mVersions = persistable ? getPackageVersion(mKey.componentName.getPackageName())
+ : null;
+
+ // it's not in the db... we need to generate it
+ Pair<Bitmap, Boolean> pair = generatePreview(mActivity, mInfo, unusedBitmap,
+ mPreviewWidth, mPreviewHeight);
+ preview = pair.first;
+
+ if (preview != unusedBitmap) {
+ mUnusedPreviewBitmap = unusedBitmap;
+ }
+
+ this.mSaveToDB = pair.second;
+ }
+ return preview;
+ }
+
+ @Override
+ protected void onPostExecute(final Bitmap preview) {
+ mCallback.onPreviewLoaded(preview);
+
+ // Write the generated preview to the DB in the worker thread
+ if (mVersions != null) {
+ MODEL_EXECUTOR.post(new Runnable() {
+ @Override
+ public void run() {
+ if (mUnusedPreviewBitmap != null) {
+ // If we didn't end up using the bitmap, it can be added back into the
+ // recycled set.
+ synchronized (mUnusedBitmaps) {
+ mUnusedBitmaps.add(mUnusedPreviewBitmap);
+ }
+ }
+
+ if (!isCancelled() && mSaveToDB) {
+ // If we are still using this preview, then write it to the DB and then
+ // let the normal clear mechanism recycle the bitmap
+ writeToDb(mKey, mVersions, preview);
+ mBitmapToRecycle = preview;
+ } else {
+ // If we've already cancelled, then skip writing the bitmap to the DB
+ // and manually add the bitmap back to the recycled set
+ synchronized (mUnusedBitmaps) {
+ mUnusedBitmaps.add(preview);
+ }
+ }
+ }
+ });
+ } else {
+ // If we don't need to write to disk, then ensure the preview gets recycled by
+ // the normal clear mechanism
+ mBitmapToRecycle = preview;
+ }
+ }
+
+ @Override
+ protected void onCancelled(final Bitmap preview) {
+ // If we've cancelled while the task is running, then can return the bitmap to the
+ // recycled set immediately. Otherwise, it will be recycled after the preview is written
+ // to disk.
+ if (preview != null) {
+ MODEL_EXECUTOR.post(new Runnable() {
+ @Override
+ public void run() {
+ synchronized (mUnusedBitmaps) {
+ mUnusedBitmaps.add(preview);
+ }
+ }
+ });
+ }
+ }
+
+ @Override
+ public void onCancel() {
+ cancel(true);
+
+ // This only handles the case where the PreviewLoadTask is cancelled after the task has
+ // successfully completed (including having written to disk when necessary). In the
+ // other cases where it is cancelled while the task is running, it will be cleaned up
+ // in the tasks's onCancelled() call, and if cancelled while the task is writing to
+ // disk, it will be cancelled in the task's onPostExecute() call.
+ if (mBitmapToRecycle != null) {
+ MODEL_EXECUTOR.post(new Runnable() {
+ @Override
+ public void run() {
+ synchronized (mUnusedBitmaps) {
+ mUnusedBitmaps.add(mBitmapToRecycle);
+ }
+ mBitmapToRecycle = null;
+ }
+ });
+ }
+ }
+ }
+
+ private static final class WidgetCacheKey extends ComponentKey {
+
+ @Thunk final String mSize;
+
+ WidgetCacheKey(ComponentName componentName, UserHandle user, String size) {
+ super(componentName, user);
+ this.mSize = size;
+ }
+
+ @Override
+ public int hashCode() {
+ return super.hashCode() ^ mSize.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ return super.equals(o) && ((WidgetCacheKey) o).mSize.equals(mSize);
+ }
+ }
}
diff --git a/src/com/android/launcher3/widget/DeferredAppWidgetHostView.java b/src/com/android/launcher3/widget/DeferredAppWidgetHostView.java
index f42142ecf0..149ac57bfb 100644
--- a/src/com/android/launcher3/widget/DeferredAppWidgetHostView.java
+++ b/src/com/android/launcher3/widget/DeferredAppWidgetHostView.java
@@ -25,7 +25,6 @@ import android.text.StaticLayout;
import android.text.TextPaint;
import android.text.TextUtils;
import android.util.TypedValue;
-import android.view.View;
import android.widget.RemoteViews;
import com.android.launcher3.R;
@@ -56,11 +55,6 @@ public class DeferredAppWidgetHostView extends LauncherAppWidgetHostView {
}
@Override
- public void addView(View child) {
- // Not allowed
- }
-
- @Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
@@ -69,11 +63,8 @@ public class DeferredAppWidgetHostView extends LauncherAppWidgetHostView {
return;
}
- // Use double padding so that there is extra space between background and text if possible.
+ // Use double padding so that there is extra space between background and text
int availableWidth = getMeasuredWidth() - 2 * (getPaddingLeft() + getPaddingRight());
- if (availableWidth <= 0) {
- availableWidth = getMeasuredWidth() - (getPaddingLeft() + getPaddingRight());
- }
if (mSetupTextLayout != null && mSetupTextLayout.getText().equals(info.label)
&& mSetupTextLayout.getWidth() == availableWidth) {
return;
@@ -85,7 +76,7 @@ public class DeferredAppWidgetHostView extends LauncherAppWidgetHostView {
@Override
protected void onDraw(Canvas canvas) {
if (mSetupTextLayout != null) {
- canvas.translate((getWidth() - mSetupTextLayout.getWidth()) / 2,
+ canvas.translate(getPaddingLeft() * 2,
(getHeight() - mSetupTextLayout.getHeight()) / 2);
mSetupTextLayout.draw(canvas);
}
diff --git a/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java b/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java
index 08651523a6..63bc416fa4 100644
--- a/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java
+++ b/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java
@@ -16,47 +16,56 @@
package com.android.launcher3.widget;
-import android.annotation.TargetApi;
import android.appwidget.AppWidgetProviderInfo;
import android.content.Context;
import android.content.res.Configuration;
+import android.graphics.Canvas;
+import android.graphics.Outline;
import android.graphics.Rect;
-import android.os.Build;
+import android.graphics.RectF;
import android.os.Handler;
import android.os.SystemClock;
-import android.os.Trace;
-import android.util.Log;
import android.util.SparseBooleanArray;
import android.util.SparseIntArray;
+import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewDebug;
import android.view.ViewGroup;
+import android.view.ViewOutlineProvider;
import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.AdapterView;
import android.widget.Advanceable;
import android.widget.RemoteViews;
+import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import androidx.annotation.UiThread;
import com.android.launcher3.CheckLongPressHelper;
import com.android.launcher3.Launcher;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
+import com.android.launcher3.Workspace;
import com.android.launcher3.dragndrop.DragLayer;
+import com.android.launcher3.keyboard.ViewGroupFocusHelper;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.LauncherAppWidgetInfo;
+import com.android.launcher3.util.Executors;
import com.android.launcher3.util.Themes;
import com.android.launcher3.views.BaseDragLayer.TouchCompleteListener;
+import com.android.launcher3.widget.dragndrop.AppWidgetHostViewDragListener;
+
+import java.util.List;
/**
* {@inheritDoc}
*/
-public class LauncherAppWidgetHostView extends BaseLauncherAppWidgetHostView
+public class LauncherAppWidgetHostView extends NavigableAppWidgetHostView
implements TouchCompleteListener, View.OnLongClickListener,
LocalColorExtractor.Listener {
- private static final String TAG = "LauncherAppWidgetHostView";
+ private static final String LOG_TAG = "LauncherAppWidgetHostView";
// Related to the auto-advancing of widgets
private static final long ADVANCE_INTERVAL = 20000;
@@ -67,11 +76,11 @@ public class LauncherAppWidgetHostView extends BaseLauncherAppWidgetHostView
// Maximum duration for which updates can be deferred.
private static final long UPDATE_LOCK_TIMEOUT_MILLIS = 1000;
- private static final String TRACE_METHOD_NAME = "appwidget load-widget ";
+ protected final LayoutInflater mInflater;
- private final Rect mTempRect = new Rect();
private final CheckLongPressHelper mLongPressHelper;
protected final Launcher mLauncher;
+ private final Workspace mWorkspace;
@ViewDebug.ExportedProperty(category = "launcher")
private boolean mReinflateOnConfigChange;
@@ -82,33 +91,54 @@ public class LauncherAppWidgetHostView extends BaseLauncherAppWidgetHostView
private boolean mIsScrollable;
private boolean mIsAttachedToWindow;
private boolean mIsAutoAdvanceRegistered;
+ private boolean mIsInDragMode = false;
private Runnable mAutoAdvanceRunnable;
-
+ private RectF mLastLocationRegistered = null;
+ @Nullable private AppWidgetHostViewDragListener mDragListener;
+
+ // Used to store the widget sizes in drag layer coordinates.
+ private final Rect mCurrentWidgetSize = new Rect();
+ private final Rect mWidgetSizeAtDrag = new Rect();
+
+ private final RectF mTempRectF = new RectF();
+ private final Rect mEnforcedRectangle = new Rect();
+ private final float mEnforcedCornerRadius;
+ private final ViewOutlineProvider mCornerRadiusEnforcementOutline = new ViewOutlineProvider() {
+ @Override
+ public void getOutline(View view, Outline outline) {
+ if (mEnforcedRectangle.isEmpty() || mEnforcedCornerRadius <= 0) {
+ outline.setEmpty();
+ } else {
+ outline.setRoundRect(mEnforcedRectangle, mEnforcedCornerRadius);
+ }
+ }
+ };
+ private final Object mUpdateLock = new Object();
+ private final ViewGroupFocusHelper mDragLayerRelativeCoordinateHelper;
private long mDeferUpdatesUntilMillis = 0;
private RemoteViews mDeferredRemoteViews;
private boolean mHasDeferredColorChange = false;
private @Nullable SparseIntArray mDeferredColorChange = null;
-
- // The following member variables are only used during drag-n-drop.
- private boolean mIsInDragMode = false;
- /** The drag content width which is only set when the drag content scale is not 1f. */
- private int mDragContentWidth = 0;
- /** The drag content height which is only set when the drag content scale is not 1f. */
- private int mDragContentHeight = 0;
-
- private boolean mTrackingWidgetUpdate = false;
+ private boolean mEnableColorExtraction = true;
public LauncherAppWidgetHostView(Context context) {
super(context);
mLauncher = Launcher.getLauncher(context);
+ mWorkspace = mLauncher.getWorkspace();
mLongPressHelper = new CheckLongPressHelper(this, this);
+ mInflater = LayoutInflater.from(context);
setAccessibilityDelegate(mLauncher.getAccessibilityDelegate());
setBackgroundResource(R.drawable.widget_internal_focus_bg);
+ setExecutor(Executors.THREAD_POOL_EXECUTOR);
if (Utilities.ATLEAST_Q && Themes.getAttrBoolean(mLauncher, R.attr.isWorkspaceDarkText)) {
setOnLightBackground(true);
}
mColorExtractor = LocalColorExtractor.newInstance(getContext());
+ mColorExtractor.setListener(this);
+
+ mEnforcedCornerRadius = RoundedCornerEnforcement.computeEnforcedRadius(getContext());
+ mDragLayerRelativeCoordinateHelper = new ViewGroupFocusHelper(mLauncher.getDragLayer());
}
@Override
@@ -121,6 +151,14 @@ public class LauncherAppWidgetHostView extends BaseLauncherAppWidgetHostView
}
@Override
+ protected void onDraw(Canvas canvas) {
+ super.onDraw(canvas);
+ if (mIsInDragMode && mDragListener != null) {
+ mDragListener.onDragContentChanged();
+ }
+ }
+
+ @Override
public boolean onLongClick(View view) {
if (mIsScrollable) {
DragLayer dragLayer = mLauncher.getDragLayer();
@@ -131,30 +169,19 @@ public class LauncherAppWidgetHostView extends BaseLauncherAppWidgetHostView
}
@Override
- @TargetApi(Build.VERSION_CODES.Q)
- public void setAppWidget(int appWidgetId, AppWidgetProviderInfo info) {
- super.setAppWidget(appWidgetId, info);
- if (!mTrackingWidgetUpdate && Utilities.ATLEAST_Q) {
- mTrackingWidgetUpdate = true;
- Trace.beginAsyncSection(TRACE_METHOD_NAME + info.provider, appWidgetId);
- Log.i(TAG, "App widget created with id: " + appWidgetId);
- }
+ protected View getErrorView() {
+ return mInflater.inflate(R.layout.appwidget_error, this, false);
}
@Override
- @TargetApi(Build.VERSION_CODES.Q)
public void updateAppWidget(RemoteViews remoteViews) {
- if (mTrackingWidgetUpdate && remoteViews != null && Utilities.ATLEAST_Q) {
- Log.i(TAG, "App widget with id: " + getAppWidgetId() + " loaded");
- Trace.endAsyncSection(
- TRACE_METHOD_NAME + getAppWidgetInfo().provider, getAppWidgetId());
- mTrackingWidgetUpdate = false;
- }
- if (isDeferringUpdates()) {
- mDeferredRemoteViews = remoteViews;
- return;
+ synchronized (mUpdateLock) {
+ if (isDeferringUpdates()) {
+ mDeferredRemoteViews = remoteViews;
+ return;
+ }
+ mDeferredRemoteViews = null;
}
- mDeferredRemoteViews = null;
super.updateAppWidget(remoteViews);
@@ -205,7 +232,9 @@ public class LauncherAppWidgetHostView extends BaseLauncherAppWidgetHostView
* {@link #onColorsChanged} call after {@link #UPDATE_LOCK_TIMEOUT_MILLIS} have elapsed.
*/
public void beginDeferringUpdates() {
- mDeferUpdatesUntilMillis = SystemClock.uptimeMillis() + UPDATE_LOCK_TIMEOUT_MILLIS;
+ synchronized (mUpdateLock) {
+ mDeferUpdatesUntilMillis = SystemClock.uptimeMillis() + UPDATE_LOCK_TIMEOUT_MILLIS;
+ }
}
/**
@@ -217,19 +246,20 @@ public class LauncherAppWidgetHostView extends BaseLauncherAppWidgetHostView
RemoteViews remoteViews;
SparseIntArray deferredColors;
boolean hasDeferredColors;
- mDeferUpdatesUntilMillis = 0;
- remoteViews = mDeferredRemoteViews;
- mDeferredRemoteViews = null;
- deferredColors = mDeferredColorChange;
- hasDeferredColors = mHasDeferredColorChange;
- mDeferredColorChange = null;
- mHasDeferredColorChange = false;
-
+ synchronized (mUpdateLock) {
+ mDeferUpdatesUntilMillis = 0;
+ remoteViews = mDeferredRemoteViews;
+ mDeferredRemoteViews = null;
+ deferredColors = mDeferredColorChange;
+ hasDeferredColors = mHasDeferredColorChange;
+ mDeferredColorChange = null;
+ mHasDeferredColorChange = false;
+ }
if (remoteViews != null) {
updateAppWidget(remoteViews);
}
if (hasDeferredColors) {
- onColorsChanged(deferredColors);
+ onColorsChanged(null /* rectF */, deferredColors);
}
}
@@ -254,9 +284,13 @@ public class LauncherAppWidgetHostView extends BaseLauncherAppWidgetHostView
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
+
mIsAttachedToWindow = true;
checkIfAutoAdvance();
- mColorExtractor.setListener(this);
+
+ if (mLastLocationRegistered != null) {
+ mColorExtractor.addLocation(List.of(mLastLocationRegistered));
+ }
}
@Override
@@ -267,7 +301,7 @@ public class LauncherAppWidgetHostView extends BaseLauncherAppWidgetHostView
// state is updated. So isAttachedToWindow() will return true until next frame.
mIsAttachedToWindow = false;
checkIfAutoAdvance();
- mColorExtractor.setListener(null);
+ mColorExtractor.removeLocations();
}
@Override
@@ -295,65 +329,126 @@ public class LauncherAppWidgetHostView extends BaseLauncherAppWidgetHostView
}
}
+ public void switchToErrorView() {
+ // Update the widget with 0 Layout id, to reset the view to error view.
+ updateAppWidget(new RemoteViews(getAppWidgetInfo().provider.getPackageName(), 0));
+ }
+
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
- super.onLayout(changed, left, top, right, bottom);
+ try {
+ super.onLayout(changed, left, top, right, bottom);
+ } catch (final RuntimeException e) {
+ post(new Runnable() {
+ @Override
+ public void run() {
+ switchToErrorView();
+ }
+ });
+ }
+
mIsScrollable = checkScrollableRecursively(this);
+ updateColorExtraction();
+
+ enforceRoundedCorners();
+ }
+
+ /** Starts the drag mode. */
+ public void startDrag(AppWidgetHostViewDragListener dragListener) {
+ mIsInDragMode = true;
+ mDragListener = dragListener;
+ }
+ /** Handles a drag event occurred on a workspace page, {@code pageId}. */
+ public void handleDrag(Rect rectInDragLayer, int pageId) {
+ mWidgetSizeAtDrag.set(rectInDragLayer);
+ updateColorExtraction(mWidgetSizeAtDrag, pageId);
+ }
+
+ /** Ends the drag mode. */
+ public void endDrag() {
+ mIsInDragMode = false;
+ mDragListener = null;
+ mWidgetSizeAtDrag.setEmpty();
+ }
+
+ /**
+ * @param rectInDragLayer Rect of widget in drag layer coordinates.
+ * @param pageId The workspace page the widget is on.
+ */
+ private void updateColorExtraction(Rect rectInDragLayer, int pageId) {
+ if (!mEnableColorExtraction) return;
+ mColorExtractor.getExtractedRectForViewRect(mLauncher, pageId, rectInDragLayer, mTempRectF);
+
+ if (mTempRectF.isEmpty()) {
+ return;
+ }
+ if (!isSameLocation(mTempRectF, mLastLocationRegistered, /* epsilon= */ 1e-6f)) {
+ if (mLastLocationRegistered != null) {
+ mColorExtractor.removeLocations();
+ }
+ mLastLocationRegistered = new RectF(mTempRectF);
+ mColorExtractor.addLocation(List.of(mLastLocationRegistered));
+ }
+ }
+
+ /**
+ * Update the color extraction, using the current position of the app widget.
+ */
+ private void updateColorExtraction() {
if (!mIsInDragMode && getTag() instanceof LauncherAppWidgetInfo) {
LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) getTag();
- mTempRect.set(left, top, right, bottom);
- mColorExtractor.setWorkspaceLocation(mTempRect, (View) getParent(), info.screenId);
+ mDragLayerRelativeCoordinateHelper.viewToRect(this, mCurrentWidgetSize);
+ updateColorExtraction(mCurrentWidgetSize,
+ mWorkspace.getPageIndexForScreenId(info.screenId));
}
}
- @Override
- protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- super.onMeasure(widthMeasureSpec, heightMeasureSpec);
- if (mIsInDragMode && mDragContentWidth > 0 && mDragContentHeight > 0
- && getChildCount() == 1) {
- measureChild(getChildAt(0), MeasureSpec.getSize(mDragContentWidth),
- MeasureSpec.getSize(mDragContentHeight));
+ /**
+ * Enables the local color extraction.
+ *
+ * @param updateColors If true, this will update the color extraction using the current location
+ * of the App Widget.
+ */
+ public void enableColorExtraction(boolean updateColors) {
+ mEnableColorExtraction = true;
+ if (updateColors) {
+ updateColorExtraction();
}
}
- /** Starts the drag mode. */
- public void startDrag() {
- mIsInDragMode = true;
- // In the case of dragging a scaled preview from widgets picker, we should reuse the
- // previously measured dimension from WidgetCell#measureAndComputeWidgetPreviewScale, which
- // measures the dimension of a widget preview without its parent's bound before scaling
- // down.
- if ((getScaleX() != 1f || getScaleY() != 1f) && getChildCount() == 1) {
- mDragContentWidth = getChildAt(0).getMeasuredWidth();
- mDragContentHeight = getChildAt(0).getMeasuredHeight();
- }
+ /**
+ * Disables the local color extraction.
+ */
+ public void disableColorExtraction() {
+ mEnableColorExtraction = false;
}
- /** Handles a drag event occurred on a workspace page corresponding to the {@code screenId}. */
- public void handleDrag(Rect rectInView, View view, int screenId) {
- if (mIsInDragMode) {
- mColorExtractor.setWorkspaceLocation(rectInView, view, screenId);
- }
+ // Compare two location rectangles. Locations are always in the [0;1] range.
+ private static boolean isSameLocation(@NonNull RectF rect1, @Nullable RectF rect2,
+ float epsilon) {
+ if (rect2 == null) return false;
+ return isSameCoordinate(rect1.left, rect2.left, epsilon)
+ && isSameCoordinate(rect1.right, rect2.right, epsilon)
+ && isSameCoordinate(rect1.top, rect2.top, epsilon)
+ && isSameCoordinate(rect1.bottom, rect2.bottom, epsilon);
}
- /** Ends the drag mode. */
- public void endDrag() {
- mIsInDragMode = false;
- mDragContentWidth = 0;
- mDragContentHeight = 0;
- requestLayout();
+ private static boolean isSameCoordinate(float c1, float c2, float epsilon) {
+ return Math.abs(c1 - c2) < epsilon;
}
@Override
- public void onColorsChanged(SparseIntArray colors) {
- if (isDeferringUpdates()) {
- mDeferredColorChange = colors;
- mHasDeferredColorChange = true;
- return;
+ public void onColorsChanged(RectF rectF, SparseIntArray colors) {
+ synchronized (mUpdateLock) {
+ if (isDeferringUpdates()) {
+ mDeferredColorChange = colors;
+ mHasDeferredColorChange = true;
+ return;
+ }
+ mDeferredColorChange = null;
+ mHasDeferredColorChange = false;
}
- mDeferredColorChange = null;
- mHasDeferredColorChange = false;
// setColorResources will reapply the view, which must happen in the UI thread.
post(() -> setColorResources(colors));
@@ -457,8 +552,7 @@ public class LauncherAppWidgetHostView extends BaseLauncherAppWidgetHostView
}
// Remove and rebind the current widget (which was inflated in the wrong
// orientation), but don't delete it from the database
- mLauncher.removeItem(this, info, false /* deleteFromDb */,
- "widget removed because of configuration change");
+ mLauncher.removeItem(this, info, false /* deleteFromDb */);
mLauncher.bindAppWidget(info);
}
@@ -470,4 +564,40 @@ public class LauncherAppWidgetHostView extends BaseLauncherAppWidgetHostView
}
return false;
}
+
+ @UiThread
+ private void resetRoundedCorners() {
+ setOutlineProvider(ViewOutlineProvider.BACKGROUND);
+ setClipToOutline(false);
+ }
+
+ @UiThread
+ private void enforceRoundedCorners() {
+ if (mEnforcedCornerRadius <= 0 || !RoundedCornerEnforcement.isRoundedCornerEnabled()) {
+ resetRoundedCorners();
+ return;
+ }
+ View background = RoundedCornerEnforcement.findBackground(this);
+ if (background == null
+ || RoundedCornerEnforcement.hasAppWidgetOptedOut(this, background)) {
+ resetRoundedCorners();
+ return;
+ }
+ RoundedCornerEnforcement.computeRoundedRectangle(this,
+ background,
+ mEnforcedRectangle);
+ setOutlineProvider(mCornerRadiusEnforcementOutline);
+ setClipToOutline(true);
+ }
+
+ /** Returns the corner radius currently enforced, in pixels. */
+ public float getEnforcedCornerRadius() {
+ return mEnforcedCornerRadius;
+ }
+
+ /** Returns true if the corner radius are enforced for this App Widget. */
+ public boolean hasEnforcedCornerRadius() {
+ return getClipToOutline();
+ }
+
}
diff --git a/src/com/android/launcher3/widget/LauncherAppWidgetProviderInfo.java b/src/com/android/launcher3/widget/LauncherAppWidgetProviderInfo.java
index bba1016f34..d77d99dfa3 100644
--- a/src/com/android/launcher3/widget/LauncherAppWidgetProviderInfo.java
+++ b/src/com/android/launcher3/widget/LauncherAppWidgetProviderInfo.java
@@ -121,29 +121,29 @@ public class LauncherAppWidgetProviderInfo extends AppWidgetProviderInfo
localPadding.set(widgetPadding);
}
minSpanX = Math.max(minSpanX,
- getSpanX(localPadding, minResizeWidth, dp.cellLayoutBorderSpacePx.x,
+ getSpanX(localPadding, minResizeWidth, dp.cellLayoutBorderSpacingPx,
cellSize.x));
minSpanY = Math.max(minSpanY,
- getSpanY(localPadding, minResizeHeight, dp.cellLayoutBorderSpacePx.y,
+ getSpanY(localPadding, minResizeHeight, dp.cellLayoutBorderSpacingPx,
cellSize.y));
if (ATLEAST_S) {
if (maxResizeWidth > 0) {
- maxSpanX = Math.min(maxSpanX, getSpanX(localPadding, maxResizeWidth,
- dp.cellLayoutBorderSpacePx.x, cellSize.x));
+ maxSpanX = Math.min(maxSpanX,
+ getSpanX(localPadding, maxResizeWidth, dp.cellLayoutBorderSpacingPx,
+ cellSize.x));
}
if (maxResizeHeight > 0) {
- maxSpanY = Math.min(maxSpanY, getSpanY(localPadding, maxResizeHeight,
- dp.cellLayoutBorderSpacePx.y, cellSize.y));
+ maxSpanY = Math.min(maxSpanY,
+ getSpanY(localPadding, maxResizeHeight, dp.cellLayoutBorderSpacingPx,
+ cellSize.y));
}
}
spanX = Math.max(spanX,
- getSpanX(localPadding, minWidth, dp.cellLayoutBorderSpacePx.x,
- cellSize.x));
+ getSpanX(localPadding, minWidth, dp.cellLayoutBorderSpacingPx, cellSize.x));
spanY = Math.max(spanY,
- getSpanY(localPadding, minHeight, dp.cellLayoutBorderSpacePx.y,
- cellSize.y));
+ getSpanY(localPadding, minHeight, dp.cellLayoutBorderSpacingPx, cellSize.y));
}
if (ATLEAST_S) {
diff --git a/src/com/android/launcher3/widget/LocalColorExtractor.java b/src/com/android/launcher3/widget/LocalColorExtractor.java
index 96e75311c8..23d9e151f7 100644
--- a/src/com/android/launcher3/widget/LocalColorExtractor.java
+++ b/src/com/android/launcher3/widget/LocalColorExtractor.java
@@ -20,14 +20,18 @@ import android.app.WallpaperColors;
import android.appwidget.AppWidgetHostView;
import android.content.Context;
import android.graphics.Rect;
+import android.graphics.RectF;
import android.util.SparseIntArray;
import android.view.View;
import androidx.annotation.Nullable;
+import com.android.launcher3.Launcher;
import com.android.launcher3.R;
import com.android.launcher3.util.ResourceBasedOverride;
+import java.util.List;
+
/** Extracts the colors we need from the wallpaper at given locations. */
public class LocalColorExtractor implements ResourceBasedOverride {
@@ -40,7 +44,7 @@ public class LocalColorExtractor implements ResourceBasedOverride {
* their value, in a format that can be passed directly to
* {@link AppWidgetHostView#setColorResources(SparseIntArray)}.
*/
- void onColorsChanged(SparseIntArray extractedColors);
+ void onColorsChanged(RectF rect, SparseIntArray extractedColors);
}
/**
@@ -56,13 +60,15 @@ public class LocalColorExtractor implements ResourceBasedOverride {
// no-op
}
- /**
- * Sets the location used for color extraction
- * @param pos position to use for color extraction
- * @param child view whose coordinate space is used for {@code pos}
- * @param screenId the workspace screenId
- */
- public void setWorkspaceLocation(Rect pos, View child, int screenId) { }
+ /** Adds a list of locations to track with this listener. */
+ public void addLocation(List<RectF> locations) {
+ // no-op
+ }
+
+ /** Stops tracking any locations. */
+ public void removeLocations() {
+ // no-op
+ }
/**
* Updates the base context to contain the colors override
@@ -77,4 +83,32 @@ public class LocalColorExtractor implements ResourceBasedOverride {
return null;
}
+ /**
+ * Takes a view and returns its rect that can be used by the wallpaper local color extractor.
+ *
+ * @param launcher Launcher class class.
+ * @param pageId The page the workspace item is on.
+ * @param v The view.
+ * @param colorExtractionRectOut The location rect, but converted to a format expected by the
+ * wallpaper local color extractor.
+ */
+ public void getExtractedRectForView(Launcher launcher, int pageId, View v,
+ RectF colorExtractionRectOut) {
+ // no-op
+ }
+
+ /**
+ * Takes a rect in drag layer coordinates and returns the rect that can be used by the wallpaper
+ * local color extractor.
+ *
+ * @param launcher Launcher class.
+ * @param pageId The page the workspace item is on.
+ * @param rectInDragLayer The relevant bounds of the view in drag layer coordinates.
+ * @param colorExtractionRectOut The location rect, but converted to a format expected by the
+ * wallpaper local color extractor.
+ */
+ public void getExtractedRectForViewRect(Launcher launcher, int pageId, Rect rectInDragLayer,
+ RectF colorExtractionRectOut) {
+ // no-op
+ }
}
diff --git a/src/com/android/launcher3/widget/NavigableAppWidgetHostView.java b/src/com/android/launcher3/widget/NavigableAppWidgetHostView.java
index 241c93734c..6163b5199c 100644
--- a/src/com/android/launcher3/widget/NavigableAppWidgetHostView.java
+++ b/src/com/android/launcher3/widget/NavigableAppWidgetHostView.java
@@ -26,6 +26,7 @@ import android.view.View;
import android.view.ViewDebug;
import android.view.ViewGroup;
+import com.android.launcher3.BaseActivity;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Reorderable;
import com.android.launcher3.dragndrop.DraggableView;
@@ -49,8 +50,6 @@ public abstract class NavigableAppWidgetHostView extends AppWidgetHostView
*/
private final PointF mTranslationForCentering = new PointF(0, 0);
- private final PointF mTranslationForMoveFromCenterAnimation = new PointF(0, 0);
-
private final PointF mTranslationForReorderBounce = new PointF(0, 0);
private final PointF mTranslationForReorderPreview = new PointF(0, 0);
private float mScaleForReorderBounce = 1f;
@@ -60,7 +59,7 @@ public abstract class NavigableAppWidgetHostView extends AppWidgetHostView
@ViewDebug.ExportedProperty(category = "launcher")
private boolean mChildrenFocused;
- protected final ActivityContext mActivity;
+ protected final BaseActivity mActivity;
public NavigableAppWidgetHostView(Context context) {
super(context);
@@ -169,9 +168,9 @@ public abstract class NavigableAppWidgetHostView extends AppWidgetHostView
private void updateTranslation() {
super.setTranslationX(mTranslationForReorderBounce.x + mTranslationForReorderPreview.x
- + mTranslationForCentering.x + mTranslationForMoveFromCenterAnimation.x);
+ + mTranslationForCentering.x);
super.setTranslationY(mTranslationForReorderBounce.y + mTranslationForReorderPreview.y
- + mTranslationForCentering.y + mTranslationForMoveFromCenterAnimation.y);
+ + mTranslationForCentering.y);
}
public void setTranslationForCentering(float x, float y) {
@@ -179,11 +178,6 @@ public abstract class NavigableAppWidgetHostView extends AppWidgetHostView
updateTranslation();
}
- public void setTranslationForMoveFromCenterAnimation(float x, float y) {
- mTranslationForMoveFromCenterAnimation.set(x, y);
- updateTranslation();
- }
-
public void setReorderBounceOffset(float x, float y) {
mTranslationForReorderBounce.set(x, y);
updateTranslation();
diff --git a/src/com/android/launcher3/widget/PendingAddWidgetInfo.java b/src/com/android/launcher3/widget/PendingAddWidgetInfo.java
index 470a800366..cbec6427a6 100644
--- a/src/com/android/launcher3/widget/PendingAddWidgetInfo.java
+++ b/src/com/android/launcher3/widget/PendingAddWidgetInfo.java
@@ -70,7 +70,7 @@ public class PendingAddWidgetInfo extends PendingAddItemInfo {
public LauncherAtom.ItemInfo buildProto(FolderInfo folderInfo) {
LauncherAtom.ItemInfo info = super.buildProto(folderInfo);
return info.toBuilder()
- .addItemAttributes(LauncherAppWidgetInfo.getAttribute(sourceContainer))
+ .setAttribute(LauncherAppWidgetInfo.getAttribute(sourceContainer))
.build();
}
}
diff --git a/src/com/android/launcher3/widget/PendingAppWidgetHostView.java b/src/com/android/launcher3/widget/PendingAppWidgetHostView.java
index 130ee3a70c..57a6d3fb07 100644
--- a/src/com/android/launcher3/widget/PendingAppWidgetHostView.java
+++ b/src/com/android/launcher3/widget/PendingAppWidgetHostView.java
@@ -17,7 +17,7 @@
package com.android.launcher3.widget;
import static com.android.launcher3.graphics.PreloadIconDrawable.newPendingIcon;
-import static com.android.launcher3.icons.FastBitmapDrawable.getDisabledColorFilter;
+import static com.android.launcher3.model.data.PackageItemInfo.CONVERSATIONS;
import android.content.Context;
import android.graphics.Canvas;
@@ -89,8 +89,8 @@ public class PendingAppWidgetHostView extends LauncherAppWidgetHostView
setOnClickListener(ItemClickHandler.INSTANCE);
if (info.pendingItemInfo == null) {
- info.pendingItemInfo = new PackageItemInfo(info.providerName.getPackageName(),
- info.user);
+ info.pendingItemInfo = new PackageItemInfo(info.providerName.getPackageName());
+ info.pendingItemInfo.user = info.user;
cache.updateIconInBackground(this, info.pendingItemInfo);
} else {
reapplyItemInfo(info.pendingItemInfo);
@@ -159,7 +159,8 @@ public class PendingAppWidgetHostView extends LauncherAppWidgetHostView
disabledIcon.setIsDisabled(true);
mCenterDrawable = disabledIcon;
} else {
- widgetCategoryIcon.setColorFilter(getDisabledColorFilter());
+ widgetCategoryIcon.setColorFilter(
+ FastBitmapDrawable.getDisabledFColorFilter(/* disabledAlpha= */ 1f));
mCenterDrawable = widgetCategoryIcon;
}
mSettingIconDrawable = null;
@@ -267,8 +268,8 @@ public class PendingAppWidgetHostView extends LauncherAppWidgetHostView
if (availableWidth > 0) {
// Recreate the setup text.
mSetupTextLayout = new StaticLayout(
- getResources().getText(R.string.gadget_complete_setup_text), mPaint,
- availableWidth, Layout.Alignment.ALIGN_CENTER, 1, 0, true);
+ getResources().getText(R.string.gadget_setup_text), mPaint, availableWidth,
+ Layout.Alignment.ALIGN_CENTER, 1, 0, true);
int textHeight = mSetupTextLayout.getHeight();
// Extra icon size due to the setting icon
@@ -337,9 +338,10 @@ public class PendingAppWidgetHostView extends LauncherAppWidgetHostView
*/
@Nullable
private Drawable getWidgetCategoryIcon() {
- if (mInfo.pendingItemInfo.widgetCategory == WidgetSections.NO_CATEGORY) {
- return null;
+ switch (mInfo.pendingItemInfo.category) {
+ case CONVERSATIONS:
+ return getContext().getDrawable(R.drawable.ic_conversations_widget_category);
}
- return mInfo.pendingItemInfo.newIcon(getContext());
+ return null;
}
}
diff --git a/src/com/android/launcher3/widget/PendingItemDragHelper.java b/src/com/android/launcher3/widget/PendingItemDragHelper.java
index 46c0b99938..cea4de7b37 100644
--- a/src/com/android/launcher3/widget/PendingItemDragHelper.java
+++ b/src/com/android/launcher3/widget/PendingItemDragHelper.java
@@ -22,8 +22,6 @@ import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
-import android.util.Log;
-import android.util.Size;
import android.view.View;
import android.view.View.MeasureSpec;
import android.widget.RemoteViews;
@@ -42,9 +40,7 @@ import com.android.launcher3.graphics.DragPreviewProvider;
import com.android.launcher3.icons.FastBitmapDrawable;
import com.android.launcher3.icons.LauncherIcons;
import com.android.launcher3.icons.RoundDrawableWrapper;
-import com.android.launcher3.testing.TestProtocol;
import com.android.launcher3.widget.dragndrop.AppWidgetHostViewDragListener;
-import com.android.launcher3.widget.util.WidgetSizes;
/**
* Extension of {@link DragPreviewProvider} with logic specific to pending widgets/shortcuts
@@ -58,7 +54,6 @@ public class PendingItemDragHelper extends DragPreviewProvider {
private int[] mEstimatedCellSize;
@Nullable private RemoteViews mRemoteViewsPreview;
- private float mRemoteViewsPreviewScale = 1f;
@Nullable private NavigableAppWidgetHostView mAppWidgetHostViewPreview;
private final float mEnforcedRoundedCornersForWidget;
@@ -73,10 +68,8 @@ public class PendingItemDragHelper extends DragPreviewProvider {
* Sets a {@link RemoteViews} which shows an app widget preview provided by app developers in
* the pin widget flow.
*/
- public void setRemoteViewsPreview(@Nullable RemoteViews remoteViewsPreview,
- float previewScale) {
+ public void setRemoteViewsPreview(@Nullable RemoteViews remoteViewsPreview) {
mRemoteViewsPreview = remoteViewsPreview;
- mRemoteViewsPreviewScale = previewScale;
}
/** Sets a {@link NavigableAppWidgetHostView} which shows a preview layout of an app widget. */
@@ -96,9 +89,6 @@ public class PendingItemDragHelper extends DragPreviewProvider {
*/
public void startDrag(Rect previewBounds, int previewBitmapWidth, int previewViewWidth,
Point screenPos, DragSource source, DragOptions options) {
- if (TestProtocol.sDebugTracing) {
- Log.d(TestProtocol.NO_DROP_TARGET, "3");
- }
final Launcher launcher = Launcher.getLauncher(mView.getContext());
LauncherAppState app = LauncherAppState.getInstance(launcher);
@@ -130,14 +120,13 @@ public class PendingItemDragHelper extends DragPreviewProvider {
mAppWidgetHostViewPreview.setPadding(padding.left, padding.top, padding.right,
padding.bottom);
mAppWidgetHostViewPreview.updateAppWidget(/* remoteViews= */ mRemoteViewsPreview);
- Size widgetSizes = WidgetSizes.getWidgetPaddedSizePx(launcher,
- mAddInfo.componentName, deviceProfile, mAddInfo.spanX, mAddInfo.spanY);
+ int width =
+ deviceProfile.cellWidthPx * mAddInfo.spanX + padding.left + padding.right;
+ int height =
+ deviceProfile.cellHeightPx * mAddInfo.spanY + padding.top + padding.bottom;
mAppWidgetHostViewPreview.measure(
- MeasureSpec.makeMeasureSpec(widgetSizes.getWidth(), MeasureSpec.EXACTLY),
- MeasureSpec.makeMeasureSpec(widgetSizes.getHeight(), MeasureSpec.EXACTLY));
- mAppWidgetHostViewPreview.setClipChildren(false);
- mAppWidgetHostViewPreview.setClipToPadding(false);
- mAppWidgetHostViewPreview.setScaleToFit(mRemoteViewsPreviewScale);
+ MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
+ MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY));
}
if (mAppWidgetHostViewPreview != null) {
previewSizeBeforeScale[0] = mAppWidgetHostViewPreview.getMeasuredWidth();
@@ -145,9 +134,10 @@ public class PendingItemDragHelper extends DragPreviewProvider {
.addDragListener(new AppWidgetHostViewDragListener(launcher));
}
if (preview == null && mAppWidgetHostViewPreview == null) {
- Drawable p = new FastBitmapDrawable(new DatabaseWidgetPreviewLoader(launcher)
- .generateWidgetPreview(
- createWidgetInfo.info, maxWidth, previewSizeBeforeScale));
+ Drawable p = new FastBitmapDrawable(
+ app.getWidgetCache().generateWidgetPreview(launcher,
+ createWidgetInfo.info, maxWidth, null,
+ previewSizeBeforeScale).first);
if (RoundedCornerEnforcement.isRoundedCornerEnabled()) {
p = new RoundDrawableWrapper(p, mEnforcedRoundedCornersForWidget);
}
@@ -181,7 +171,8 @@ public class PendingItemDragHelper extends DragPreviewProvider {
PendingAddShortcutInfo createShortcutInfo = (PendingAddShortcutInfo) mAddInfo;
Drawable icon = createShortcutInfo.activityInfo.getFullResIcon(app.getIconCache());
LauncherIcons li = LauncherIcons.obtain(launcher);
- preview = new FastBitmapDrawable(li.createScaledBitmapWithoutShadow(icon));
+ preview = new FastBitmapDrawable(
+ li.createScaledBitmapWithoutShadow(icon, 0));
previewWidth = preview.getIntrinsicWidth();
previewHeight = preview.getIntrinsicHeight();
li.recycle();
@@ -208,6 +199,10 @@ public class PendingItemDragHelper extends DragPreviewProvider {
draggableView = DraggableView.ofType(DraggableView.DRAGGABLE_ICON);
}
+ // Since we are not going through the workspace for starting the drag, set drag related
+ // information on the workspace before starting the drag.
+ launcher.getWorkspace().prepareDragWithProvider(this);
+
int dragLayerX = screenPos.x + previewBounds.left
+ (int) ((scale * previewWidth - previewWidth) / 2);
int dragLayerY = screenPos.y + previewBounds.top
diff --git a/src/com/android/launcher3/widget/WidgetCell.java b/src/com/android/launcher3/widget/WidgetCell.java
index 2796721c63..5769ba0c69 100644
--- a/src/com/android/launcher3/widget/WidgetCell.java
+++ b/src/com/android/launcher3/widget/WidgetCell.java
@@ -16,48 +16,40 @@
package com.android.launcher3.widget;
-import static android.view.View.MeasureSpec.makeMeasureSpec;
-import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
-import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
-
import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_WIDGETS_TRAY;
import static com.android.launcher3.Utilities.ATLEAST_S;
import android.content.Context;
import android.graphics.Bitmap;
+import android.graphics.Rect;
import android.graphics.drawable.Drawable;
-import android.os.Process;
+import android.os.CancellationSignal;
import android.util.AttributeSet;
import android.util.Log;
import android.util.Size;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
-import android.view.ViewGroup;
+import android.view.View.OnLayoutChangeListener;
import android.view.ViewPropertyAnimator;
import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.FrameLayout;
-import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RemoteViews;
import android.widget.TextView;
-import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import com.android.launcher3.BaseActivity;
import com.android.launcher3.CheckLongPressHelper;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Launcher;
import com.android.launcher3.R;
import com.android.launcher3.icons.FastBitmapDrawable;
import com.android.launcher3.icons.RoundDrawableWrapper;
-import com.android.launcher3.icons.cache.HandlerRunnable;
import com.android.launcher3.model.WidgetItem;
-import com.android.launcher3.views.ActivityContext;
import com.android.launcher3.widget.util.WidgetSizes;
-import java.util.function.Consumer;
-
/**
* Represents the individual cell of the widget inside the widget tray. The preview is drawn
* horizontally centered, and scaled down if needed.
@@ -67,7 +59,7 @@ import java.util.function.Consumer;
* transition from the view to drag view, so when adding padding support, DnD would need to
* consider the appropriate scaling factor.
*/
-public class WidgetCell extends LinearLayout {
+public class WidgetCell extends LinearLayout implements OnLayoutChangeListener {
private static final String TAG = "WidgetCell";
private static final boolean DEBUG = false;
@@ -80,58 +72,35 @@ public class WidgetCell extends LinearLayout {
/** Widget preview width is calculated by multiplying this factor to the widget cell width. */
private static final float PREVIEW_SCALE = 0.8f;
- /**
- * The maximum dimension that can be used as the size in
- * {@link android.view.View.MeasureSpec#makeMeasureSpec(int, int)}.
- *
- * <p>This is equal to (1 << MeasureSpec.MODE_SHIFT) - 1.
- */
- private static final int MAX_MEASURE_SPEC_DIMENSION = (1 << 30) - 1;
-
- /**
- * The target preview width, in pixels, of a widget or a shortcut.
- *
- * <p>The actual preview width may be smaller than or equal to this value subjected to scaling.
- */
- protected int mTargetPreviewWidth;
-
- /**
- * The target preview height, in pixels, of a widget or a shortcut.
- *
- * <p>The actual preview height may be smaller than or equal to this value subjected to scaling.
- */
- protected int mTargetPreviewHeight;
-
+ protected int mPreviewWidth;
+ protected int mPreviewHeight;
protected int mPresetPreviewSize;
-
private int mCellSize;
-
- /**
- * The scale of the preview container.
- */
- private float mPreviewContainerScale = 1f;
+ private float mPreviewScale = 1f;
private FrameLayout mWidgetImageContainer;
private WidgetImageView mWidgetImage;
- private ImageView mWidgetBadge;
private TextView mWidgetName;
private TextView mWidgetDims;
private TextView mWidgetDescription;
protected WidgetItem mItem;
- private final DatabaseWidgetPreviewLoader mWidgetPreviewLoader;
+ private WidgetPreviewLoader mWidgetPreviewLoader;
- protected HandlerRunnable mActiveRequest;
+ protected CancellationSignal mActiveRequest;
private boolean mAnimatePreview = true;
- protected final ActivityContext mActivity;
+ private boolean mApplyBitmapDeferred = false;
+ private Drawable mDeferredDrawable;
+
+ protected final BaseActivity mActivity;
private final CheckLongPressHelper mLongPressHelper;
private final float mEnforcedCornerRadius;
+ private final int mShortcutPreviewPadding;
private RemoteViews mRemoteViewsPreview;
private NavigableAppWidgetHostView mAppWidgetHostViewPreview;
- private float mAppWidgetHostViewScale = 1f;
private int mSourceContainer = CONTAINER_WIDGETS_TRAY;
public WidgetCell(Context context) {
@@ -145,8 +114,7 @@ public class WidgetCell extends LinearLayout {
public WidgetCell(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
- mActivity = ActivityContext.lookupContext(context);
- mWidgetPreviewLoader = new DatabaseWidgetPreviewLoader(context);
+ mActivity = BaseActivity.fromContext(context);
mLongPressHelper = new CheckLongPressHelper(this);
mLongPressHelper.setLongPressTimeoutFactor(1);
@@ -155,12 +123,14 @@ public class WidgetCell extends LinearLayout {
setClipToPadding(false);
setAccessibilityDelegate(mActivity.getAccessibilityDelegate());
mEnforcedCornerRadius = RoundedCornerEnforcement.computeEnforcedRadius(context);
+ mShortcutPreviewPadding =
+ 2 * getResources().getDimensionPixelSize(R.dimen.widget_preview_shortcut_padding);
}
private void setContainerWidth() {
mCellSize = (int) (mActivity.getDeviceProfile().allAppsIconSizePx * WIDTH_SCALE);
mPresetPreviewSize = (int) (mCellSize * PREVIEW_SCALE);
- mTargetPreviewWidth = mTargetPreviewHeight = mPresetPreviewSize;
+ mPreviewWidth = mPreviewHeight = mPresetPreviewSize;
}
@Override
@@ -169,7 +139,6 @@ public class WidgetCell extends LinearLayout {
mWidgetImageContainer = findViewById(R.id.widget_preview_container);
mWidgetImage = findViewById(R.id.widget_preview);
- mWidgetBadge = findViewById(R.id.widget_badge);
mWidgetName = findViewById(R.id.widget_name);
mWidgetDims = findViewById(R.id.widget_dims);
mWidgetDescription = findViewById(R.id.widget_description);
@@ -184,11 +153,6 @@ public class WidgetCell extends LinearLayout {
return mRemoteViewsPreview;
}
- /** Returns the app widget host view scale, which is a value between [0f, 1f]. */
- public float getAppWidgetHostViewScale() {
- return mAppWidgetHostViewScale;
- }
-
/**
* Called to clear the view and free attached resources. (e.g., {@link Bitmap}
*/
@@ -199,13 +163,11 @@ public class WidgetCell extends LinearLayout {
mWidgetImage.animate().cancel();
mWidgetImage.setDrawable(null);
mWidgetImage.setVisibility(View.VISIBLE);
- mWidgetBadge.setImageDrawable(null);
- mWidgetBadge.setVisibility(View.GONE);
mWidgetName.setText(null);
mWidgetDims.setText(null);
mWidgetDescription.setText(null);
mWidgetDescription.setVisibility(GONE);
- mTargetPreviewWidth = mTargetPreviewHeight = mPresetPreviewSize;
+ mPreviewWidth = mPreviewHeight = mPresetPreviewSize;
if (mActiveRequest != null) {
mActiveRequest.cancel();
@@ -216,7 +178,6 @@ public class WidgetCell extends LinearLayout {
mWidgetImageContainer.removeView(mAppWidgetHostViewPreview);
}
mAppWidgetHostViewPreview = null;
- mAppWidgetHostViewScale = 1f;
mItem = null;
}
@@ -224,36 +185,7 @@ public class WidgetCell extends LinearLayout {
this.mSourceContainer = sourceContainer;
}
- /**
- * Applies the item to this view
- */
- public void applyFromCellItem(WidgetItem item) {
- applyFromCellItem(item, 1f);
- }
-
- /**
- * Applies the item to this view
- */
- public void applyFromCellItem(WidgetItem item, float previewScale) {
- applyFromCellItem(item, previewScale, this::applyPreview, null);
- }
-
- /**
- * Applies the item to this view
- * @param item item to apply
- * @param previewScale factor to scale the preview
- * @param callback callback when preview is loaded in case the preview is being loaded or cached
- * @param cachedPreview previously cached preview bitmap is present
- */
- public void applyFromCellItem(WidgetItem item, float previewScale,
- @NonNull Consumer<Bitmap> callback, @Nullable Bitmap cachedPreview) {
- // setPreviewSize
- DeviceProfile deviceProfile = mActivity.getDeviceProfile();
- Size widgetSize = WidgetSizes.getWidgetItemSizePx(getContext(), deviceProfile, item);
- mTargetPreviewWidth = widgetSize.getWidth();
- mTargetPreviewHeight = widgetSize.getHeight();
- mPreviewContainerScale = previewScale;
-
+ public void applyFromCellItem(WidgetItem item, WidgetPreviewLoader loader) {
applyPreviewOnAppWidgetHostView(item);
Context context = getContext();
@@ -275,15 +207,15 @@ public class WidgetCell extends LinearLayout {
}
}
+ mWidgetPreviewLoader = loader;
if (item.activityInfo != null) {
setTag(new PendingAddShortcutInfo(item.activityInfo));
} else {
setTag(new PendingAddWidgetInfo(item.widgetInfo, mSourceContainer));
}
-
- ensurePreviewWithCallback(callback, cachedPreview);
}
+
private void applyPreviewOnAppWidgetHostView(WidgetItem item) {
if (mRemoteViewsPreview != null) {
mAppWidgetHostViewPreview = createAppWidgetHostView(getContext());
@@ -317,6 +249,16 @@ public class WidgetCell extends LinearLayout {
@Nullable RemoteViews remoteViews) {
appWidgetHostViewPreview.setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_NO);
appWidgetHostViewPreview.setAppWidget(/* appWidgetId= */ -1, providerInfo);
+ Rect padding;
+ DeviceProfile deviceProfile = mActivity.getDeviceProfile();
+ if (deviceProfile.shouldInsetWidgets()) {
+ padding = new Rect();
+ appWidgetHostViewPreview.getWidgetInset(deviceProfile, padding);
+ } else {
+ padding = deviceProfile.inv.defaultWidgetPadding;
+ }
+ appWidgetHostViewPreview.setPadding(padding.left, padding.top, padding.right,
+ padding.bottom);
appWidgetHostViewPreview.updateAppWidget(remoteViews);
}
@@ -329,25 +271,47 @@ public class WidgetCell extends LinearLayout {
return mAppWidgetHostViewPreview;
}
+ /**
+ * Sets if applying bitmap preview should be deferred. The UI will still load the bitmap, but
+ * will not cause invalidate, so that when deferring is disabled later, all the bitmaps are
+ * ready.
+ * This prevents invalidates while the animation is running.
+ */
+ public void setApplyBitmapDeferred(boolean isDeferred) {
+ if (mApplyBitmapDeferred != isDeferred) {
+ mApplyBitmapDeferred = isDeferred;
+ if (!mApplyBitmapDeferred && mDeferredDrawable != null) {
+ applyPreview(mDeferredDrawable);
+ mDeferredDrawable = null;
+ }
+ }
+ }
+
public void setAnimatePreview(boolean shouldAnimate) {
mAnimatePreview = shouldAnimate;
}
- private void applyPreview(Bitmap bitmap) {
- if (bitmap != null) {
- Drawable drawable = new RoundDrawableWrapper(
- new FastBitmapDrawable(bitmap), mEnforcedCornerRadius);
+ public void applyPreview(Bitmap bitmap) {
+ FastBitmapDrawable drawable = new FastBitmapDrawable(bitmap);
+ applyPreview(new RoundDrawableWrapper(drawable, mEnforcedCornerRadius));
+ }
- // Scale down the preview size if it's wider than the cell.
+ private void applyPreview(Drawable drawable) {
+ if (mApplyBitmapDeferred) {
+ mDeferredDrawable = drawable;
+ return;
+ }
+ if (drawable != null) {
float scale = 1f;
- if (mTargetPreviewWidth > 0) {
- float maxWidth = mTargetPreviewWidth;
- float previewWidth = drawable.getIntrinsicWidth() * mPreviewContainerScale;
+ if (getWidth() > 0 && getHeight() > 0) {
+ // Scale down the preview size if it's wider than the cell.
+ float maxWidth = getWidth();
+ float previewWidth = drawable.getIntrinsicWidth() * mPreviewScale;
scale = Math.min(maxWidth / previewWidth, 1);
}
setContainerSize(
- Math.round(drawable.getIntrinsicWidth() * scale * mPreviewContainerScale),
- Math.round(drawable.getIntrinsicHeight() * scale * mPreviewContainerScale));
+ Math.round(drawable.getIntrinsicWidth() * scale),
+ Math.round(drawable.getIntrinsicHeight() * scale));
mWidgetImage.setDrawable(drawable);
mWidgetImage.setVisibility(View.VISIBLE);
if (mAppWidgetHostViewPreview != null) {
@@ -355,7 +319,6 @@ public class WidgetCell extends LinearLayout {
mAppWidgetHostViewPreview = null;
}
}
-
if (mAnimatePreview) {
mWidgetImageContainer.setAlpha(0f);
ViewPropertyAnimator anim = mWidgetImageContainer.animate();
@@ -363,72 +326,55 @@ public class WidgetCell extends LinearLayout {
} else {
mWidgetImageContainer.setAlpha(1f);
}
- if (mActiveRequest != null) {
- mActiveRequest.cancel();
- mActiveRequest = null;
- }
- }
-
- /** Used to show the badge when the widget is in the recommended section
- */
- public void showBadge() {
- if (Process.myUserHandle().equals(mItem.user)) {
- mWidgetBadge.setVisibility(View.GONE);
- } else {
- mWidgetBadge.setVisibility(View.VISIBLE);
- mWidgetBadge.setImageResource(R.drawable.ic_work_app_badge);
- }
}
private void setContainerSize(int width, int height) {
LayoutParams layoutParams = (LayoutParams) mWidgetImageContainer.getLayoutParams();
- layoutParams.width = width;
- layoutParams.height = height;
+ layoutParams.width = (int) (width * mPreviewScale);
+ layoutParams.height = (int) (height * mPreviewScale);
mWidgetImageContainer.setLayoutParams(layoutParams);
}
- /**
- * Ensures that the preview is already loaded or being loaded. If the preview is not loaded,
- * it applies the provided cachedPreview. If that is null, it starts a loader and notifies the
- * callback on successful load.
- */
- private void ensurePreviewWithCallback(Consumer<Bitmap> callback,
- @Nullable Bitmap cachedPreview) {
+ public void ensurePreview() {
if (mAppWidgetHostViewPreview != null) {
- int containerWidth = (int) (mTargetPreviewWidth * mPreviewContainerScale);
- int containerHeight = (int) (mTargetPreviewHeight * mPreviewContainerScale);
- setContainerSize(containerWidth, containerHeight);
- if (mAppWidgetHostViewPreview.getChildCount() == 1) {
- View widgetContent = mAppWidgetHostViewPreview.getChildAt(0);
- ViewGroup.LayoutParams layoutParams = widgetContent.getLayoutParams();
- // We only scale preview if both the width & height of the outermost view group are
- // not set to MATCH_PARENT.
- boolean shouldScale =
- layoutParams.width != MATCH_PARENT && layoutParams.height != MATCH_PARENT;
- if (shouldScale) {
- setNoClip(mWidgetImageContainer);
- setNoClip(mAppWidgetHostViewPreview);
- mAppWidgetHostViewScale = measureAndComputeWidgetPreviewScale();
- mAppWidgetHostViewPreview.setScaleToFit(mAppWidgetHostViewScale);
- }
- }
+ setContainerSize(mPreviewWidth, mPreviewHeight);
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(
- containerWidth, containerHeight, Gravity.FILL);
+ mPreviewWidth, mPreviewHeight, Gravity.FILL);
mAppWidgetHostViewPreview.setLayoutParams(params);
mWidgetImageContainer.addView(mAppWidgetHostViewPreview, /* index= */ 0);
mWidgetImage.setVisibility(View.GONE);
- applyPreview(null);
- return;
- }
- if (cachedPreview != null) {
- applyPreview(cachedPreview);
+ applyPreview((Drawable) null);
return;
}
if (mActiveRequest != null) {
return;
}
mActiveRequest = mWidgetPreviewLoader.loadPreview(
- mItem, new Size(mTargetPreviewWidth, mTargetPreviewHeight), callback);
+ BaseActivity.fromContext(getContext()), mItem,
+ new Size(mPreviewWidth, mPreviewHeight),
+ this::applyPreview);
+ }
+
+ /** Sets the widget preview image size in number of cells. */
+ public Size setPreviewSize(WidgetItem widgetItem) {
+ return setPreviewSize(widgetItem, 1f);
+ }
+
+ /** Sets the widget preview image size, in number of cells, and preview scale. */
+ public Size setPreviewSize(WidgetItem widgetItem, float previewScale) {
+ DeviceProfile deviceProfile = mActivity.getDeviceProfile();
+ Size widgetSize = WidgetSizes.getWidgetItemSizePx(getContext(), deviceProfile, widgetItem);
+ mPreviewWidth = widgetSize.getWidth();
+ mPreviewHeight = widgetSize.getHeight();
+ mPreviewScale = previewScale;
+ return widgetSize;
+ }
+
+ @Override
+ public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft,
+ int oldTop, int oldRight, int oldBottom) {
+ removeOnLayoutChangeListener(this);
+ ensurePreview();
}
@Override
@@ -444,6 +390,17 @@ public class WidgetCell extends LinearLayout {
mLongPressHelper.cancelLongPress();
}
+ /**
+ * Helper method to get the string info of the tag.
+ */
+ private String getTagToString() {
+ if (getTag() instanceof PendingAddWidgetInfo ||
+ getTag() instanceof PendingAddShortcutInfo) {
+ return getTag().toString();
+ }
+ return "";
+ }
+
private static NavigableAppWidgetHostView createAppWidgetHostView(Context context) {
return new NavigableAppWidgetHostView(context) {
@Override
@@ -454,7 +411,12 @@ public class WidgetCell extends LinearLayout {
}
private static boolean isLauncherContext(Context context) {
- return ActivityContext.lookupContext(context) instanceof Launcher;
+ try {
+ Launcher.getLauncher(context);
+ return true;
+ } catch (Exception e) {
+ return false;
+ }
}
@Override
@@ -467,62 +429,4 @@ public class WidgetCell extends LinearLayout {
super.onInitializeAccessibilityNodeInfo(info);
info.removeAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_CLICK);
}
-
- private static void setNoClip(ViewGroup view) {
- view.setClipChildren(false);
- view.setClipToPadding(false);
- }
-
- private float measureAndComputeWidgetPreviewScale() {
- if (mAppWidgetHostViewPreview.getChildCount() != 1) {
- return 1f;
- }
-
- // Measure the largest possible width & height that the app widget wants to display.
- mAppWidgetHostViewPreview.measure(
- makeMeasureSpec(MAX_MEASURE_SPEC_DIMENSION, MeasureSpec.UNSPECIFIED),
- makeMeasureSpec(MAX_MEASURE_SPEC_DIMENSION, MeasureSpec.UNSPECIFIED));
- if (mRemoteViewsPreview != null) {
- // If RemoteViews contains multiple sizes, the best fit sized RemoteViews will be
- // selected in onLayout. To work out the right measurement, let's layout and then
- // measure again.
- mAppWidgetHostViewPreview.layout(
- /* left= */ 0,
- /* top= */ 0,
- /* right= */ mTargetPreviewWidth,
- /* bottom= */ mTargetPreviewHeight);
- mAppWidgetHostViewPreview.measure(
- makeMeasureSpec(mTargetPreviewWidth, MeasureSpec.UNSPECIFIED),
- makeMeasureSpec(mTargetPreviewHeight, MeasureSpec.UNSPECIFIED));
-
- }
- View widgetContent = mAppWidgetHostViewPreview.getChildAt(0);
- int appWidgetContentWidth = widgetContent.getMeasuredWidth();
- int appWidgetContentHeight = widgetContent.getMeasuredHeight();
- if (appWidgetContentWidth == 0 || appWidgetContentHeight == 0) {
- return 1f;
- }
-
- // If the width / height of the widget content is set to wrap content, overrides the width /
- // height with the measured dimension. This avoids incorrect measurement after scaling.
- FrameLayout.LayoutParams layoutParam =
- (FrameLayout.LayoutParams) widgetContent.getLayoutParams();
- if (layoutParam.width == WRAP_CONTENT) {
- layoutParam.width = widgetContent.getMeasuredWidth();
- }
- if (layoutParam.height == WRAP_CONTENT) {
- layoutParam.height = widgetContent.getMeasuredHeight();
- }
- widgetContent.setLayoutParams(layoutParam);
-
- int horizontalPadding = mAppWidgetHostViewPreview.getPaddingStart()
- + mAppWidgetHostViewPreview.getPaddingEnd();
- int verticalPadding = mAppWidgetHostViewPreview.getPaddingTop()
- + mAppWidgetHostViewPreview.getPaddingBottom();
- return Math.min(
- (mTargetPreviewWidth - horizontalPadding) * mPreviewContainerScale
- / appWidgetContentWidth,
- (mTargetPreviewHeight - verticalPadding) * mPreviewContainerScale
- / appWidgetContentHeight);
- }
}
diff --git a/src/com/android/launcher3/widget/WidgetPreviewLoader.java b/src/com/android/launcher3/widget/WidgetPreviewLoader.java
new file mode 100644
index 0000000000..ff5c82f872
--- /dev/null
+++ b/src/com/android/launcher3/widget/WidgetPreviewLoader.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2021 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.launcher3.widget;
+
+import android.graphics.Bitmap;
+import android.os.CancellationSignal;
+import android.util.Size;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.UiThread;
+
+import com.android.launcher3.BaseActivity;
+import com.android.launcher3.model.WidgetItem;
+
+/** Asynchronous loader of preview bitmaps for {@link WidgetItem}s. */
+public interface WidgetPreviewLoader {
+ /**
+ * Loads a widget preview and calls back to {@code callback} when complete.
+ *
+ * @return a {@link CancellationSignal} which can be used to cancel the request.
+ */
+ @NonNull
+ @UiThread
+ CancellationSignal loadPreview(
+ @NonNull BaseActivity activity,
+ @NonNull WidgetItem item,
+ @NonNull Size previewSize,
+ @NonNull WidgetPreviewLoadedCallback callback);
+
+ /** Callback class for requests to {@link WidgetPreviewLoader}. */
+ interface WidgetPreviewLoadedCallback {
+ void onPreviewLoaded(@NonNull Bitmap preview);
+ }
+}
diff --git a/src/com/android/launcher3/widget/WidgetSections.java b/src/com/android/launcher3/widget/WidgetSections.java
deleted file mode 100644
index c45b09591f..0000000000
--- a/src/com/android/launcher3/widget/WidgetSections.java
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * Copyright (C) 2021 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.launcher3.widget;
-
-import static android.content.res.Resources.ID_NULL;
-
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.res.TypedArray;
-import android.content.res.XmlResourceParser;
-import android.util.ArrayMap;
-import android.util.AttributeSet;
-import android.util.SparseArray;
-import android.util.Xml;
-
-import androidx.annotation.DrawableRes;
-import androidx.annotation.StringRes;
-
-import com.android.launcher3.R;
-import com.android.launcher3.util.IntSet;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import java.io.IOException;
-import java.util.Map;
-
-/** A helper class to parse widget sections (categories) resource overlay. */
-public final class WidgetSections {
- /** The package is not categorized in the widget tray. */
- public static final int NO_CATEGORY = -1;
-
- private static final String TAG_SECTION_NAME = "section";
- private static final String TAG_WIDGET_NAME = "widget";
-
- private static SparseArray<WidgetSection> sWidgetSections;
- private static Map<ComponentName, IntSet> sWidgetsToCategories;
-
- /** Returns a list of widget sections that are shown in the widget picker. */
- public static synchronized SparseArray<WidgetSection> getWidgetSections(Context context) {
- if (sWidgetSections != null) {
- return sWidgetSections;
- }
- parseWidgetSectionsXml(context);
- return sWidgetSections;
- }
-
- /** Returns a map which maps app widget providers to app widget categories. */
- public static synchronized Map<ComponentName, IntSet> getWidgetsToCategory(
- Context context) {
- if (sWidgetsToCategories != null) {
- return sWidgetsToCategories;
- }
- parseWidgetSectionsXml(context);
- return sWidgetsToCategories;
- }
-
- private static synchronized void parseWidgetSectionsXml(Context context) {
- SparseArray<WidgetSection> widgetSections = new SparseArray();
- Map<ComponentName, IntSet> widgetsToCategories = new ArrayMap<>();
- try (XmlResourceParser parser = context.getResources().getXml(R.xml.widget_sections)) {
- final int depth = parser.getDepth();
- int type;
- while (((type = parser.next()) != XmlPullParser.END_TAG
- || parser.getDepth() > depth) && type != XmlPullParser.END_DOCUMENT) {
- if ((type == XmlPullParser.START_TAG)
- && TAG_SECTION_NAME.equals(parser.getName())) {
- AttributeSet sectionAttributes = Xml.asAttributeSet(parser);
- WidgetSection section = new WidgetSection(context, sectionAttributes);
- final int sectionDepth = parser.getDepth();
- while (((type = parser.next()) != XmlPullParser.END_TAG
- || parser.getDepth() > sectionDepth)
- && type != XmlPullParser.END_DOCUMENT) {
- if ((type == XmlPullParser.START_TAG)
- && TAG_WIDGET_NAME.equals(parser.getName())) {
- TypedArray a = context.obtainStyledAttributes(
- Xml.asAttributeSet(parser), R.styleable.WidgetSections);
- ComponentName provider = ComponentName.unflattenFromString(
- a.getString(R.styleable.WidgetSections_provider));
- boolean alsoKeepInApp = a.getBoolean(
- R.styleable.WidgetSections_alsoKeepInApp,
- /* defValue= */ false);
- final IntSet categories;
- if (widgetsToCategories.containsKey(provider)) {
- categories = widgetsToCategories.get(provider);
- } else {
- categories = new IntSet();
- widgetsToCategories.put(provider, categories);
- }
- if (alsoKeepInApp) {
- categories.add(NO_CATEGORY);
- }
- categories.add(section.mCategory);
- }
- }
- widgetSections.put(section.mCategory, section);
- }
- }
- sWidgetSections = widgetSections;
- sWidgetsToCategories = widgetsToCategories;
- } catch (IOException | XmlPullParserException e) {
- throw new RuntimeException(e);
- }
- }
-
- /** A data class which contains a widget section's information. */
- public static final class WidgetSection {
- public final int mCategory;
- @StringRes
- public final int mSectionTitle;
- @DrawableRes
- public final int mSectionDrawable;
-
- public WidgetSection(Context context, AttributeSet attrs) {
- TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.WidgetSections);
- mCategory = a.getInt(R.styleable.WidgetSections_category, NO_CATEGORY);
- mSectionTitle = a.getResourceId(R.styleable.WidgetSections_sectionTitle, ID_NULL);
- mSectionDrawable = a.getResourceId(R.styleable.WidgetSections_sectionDrawable, ID_NULL);
- }
- }
-}
diff --git a/src/com/android/launcher3/widget/WidgetsBottomSheet.java b/src/com/android/launcher3/widget/WidgetsBottomSheet.java
index bf521cc7eb..dedcc65d11 100644
--- a/src/com/android/launcher3/widget/WidgetsBottomSheet.java
+++ b/src/com/android/launcher3/widget/WidgetsBottomSheet.java
@@ -36,6 +36,8 @@ import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.TextView;
+import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.LauncherAppState;
import com.android.launcher3.R;
import com.android.launcher3.anim.PendingAnimation;
import com.android.launcher3.model.WidgetItem;
@@ -69,8 +71,8 @@ public class WidgetsBottomSheet extends BaseWidgetSheet {
private static final long EDUCATION_TIP_DELAY_MS = 300;
private ItemInfo mOriginalItemInfo;
- private int mMaxHorizontalSpan = DEFAULT_MAX_HORIZONTAL_SPANS;
- private final int mWidgetCellHorizontalPadding;
+ private final int mMaxTableHeight;
+ private int mMaxHorizontalSpan = 4;
private final OnLayoutChangeListener mLayoutChangeListenerToShowTips =
new OnLayoutChangeListener() {
@@ -108,11 +110,13 @@ public class WidgetsBottomSheet extends BaseWidgetSheet {
public WidgetsBottomSheet(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
setWillNotDraw(false);
+ DeviceProfile deviceProfile = mActivityContext.getDeviceProfile();
+ // Set the max table height to 2 / 3 of the grid height so that the bottom picker won't
+ // take over the entire view vertically.
+ mMaxTableHeight = deviceProfile.inv.numRows * 2 / 3 * deviceProfile.cellHeightPx;
if (!hasSeenEducationTip()) {
addOnLayoutChangeListener(mLayoutChangeListenerToShowTips);
}
- mWidgetCellHorizontalPadding = getResources().getDimensionPixelSize(
- R.dimen.widget_cell_horizontal_padding);
}
@Override
@@ -133,7 +137,10 @@ public class WidgetsBottomSheet extends BaseWidgetSheet {
private boolean updateMaxSpansPerRow() {
if (getMeasuredWidth() == 0) return false;
- int maxHorizontalSpan = computeMaxHorizontalSpans(mContent, mWidgetCellHorizontalPadding);
+ int paddingPx = 2 * getResources().getDimensionPixelOffset(
+ R.dimen.widget_cell_horizontal_padding);
+ int maxHorizontalSpan = findViewById(R.id.widgets_table).getMeasuredWidth()
+ / (mActivityContext.getDeviceProfile().cellWidthPx + paddingPx);
if (mMaxHorizontalSpan != maxHorizontalSpan) {
// Ensure the table layout is showing widgets in the right column after measure.
mMaxHorizontalSpan = maxHorizontalSpan;
@@ -156,9 +163,13 @@ public class WidgetsBottomSheet extends BaseWidgetSheet {
setTranslationShift(mTranslationShift);
+ // Ensure the scroll view height is not larger than mMaxTableHeight, which is a value
+ // smaller than the entire screen height.
ScrollView widgetsTableScrollView = findViewById(R.id.widgets_table_scroll_view);
- TableLayout widgetsTable = findViewById(R.id.widgets_table);
- if (widgetsTable.getMeasuredHeight() > widgetsTableScrollView.getMeasuredHeight()) {
+ if (widgetsTableScrollView.getMeasuredHeight() > mMaxTableHeight) {
+ ViewGroup.LayoutParams layoutParams = widgetsTableScrollView.getLayoutParams();
+ layoutParams.height = mMaxTableHeight;
+ widgetsTableScrollView.setLayoutParams(layoutParams);
findViewById(R.id.collapse_handle).setVisibility(VISIBLE);
}
}
@@ -183,16 +194,19 @@ public class WidgetsBottomSheet extends BaseWidgetSheet {
TableLayout widgetsTable = findViewById(R.id.widgets_table);
widgetsTable.removeAllViews();
- WidgetsTableUtils.groupWidgetItemsIntoTableWithReordering(widgets, mMaxHorizontalSpan)
- .forEach(row -> {
- TableRow tableRow = new TableRow(getContext());
- tableRow.setGravity(Gravity.TOP);
- row.forEach(widgetItem -> {
- WidgetCell widget = addItemCell(tableRow);
- widget.applyFromCellItem(widgetItem);
- });
- widgetsTable.addView(tableRow);
- });
+ WidgetsTableUtils.groupWidgetItemsIntoTable(widgets, mMaxHorizontalSpan).forEach(row -> {
+ TableRow tableRow = new TableRow(getContext());
+ tableRow.setGravity(Gravity.TOP);
+ row.forEach(widgetItem -> {
+ WidgetCell widget = addItemCell(tableRow);
+ widget.setPreviewSize(widgetItem);
+ widget.applyFromCellItem(widgetItem, LauncherAppState.getInstance(mActivityContext)
+ .getWidgetCache());
+ widget.ensurePreview();
+ widget.setVisibility(View.VISIBLE);
+ });
+ widgetsTable.addView(tableRow);
+ });
}
@Override
@@ -247,12 +261,10 @@ public class WidgetsBottomSheet extends BaseWidgetSheet {
@Override
public void setInsets(Rect insets) {
super.setInsets(insets);
- int bottomPadding = Math.max(insets.bottom, mNavBarScrimHeight);
mContent.setPadding(mContent.getPaddingStart(),
- mContent.getPaddingTop(), mContent.getPaddingEnd(),
- bottomPadding);
- if (bottomPadding > 0) {
+ mContent.getPaddingTop(), mContent.getPaddingEnd(), insets.bottom);
+ if (insets.bottom > 0) {
setupNavBarColor();
} else {
clearNavBarColor();
@@ -260,14 +272,6 @@ public class WidgetsBottomSheet extends BaseWidgetSheet {
}
@Override
- protected void onContentHorizontalMarginChanged(int contentHorizontalMarginInPx) {
- ViewGroup.MarginLayoutParams layoutParams =
- ((ViewGroup.MarginLayoutParams) findViewById(R.id.widgets_table).getLayoutParams());
- layoutParams.setMarginStart(contentHorizontalMarginInPx);
- layoutParams.setMarginEnd(contentHorizontalMarginInPx);
- }
-
- @Override
protected Pair<View, String> getAccessibilityTarget() {
return Pair.create(findViewById(R.id.title), getContext().getString(
mIsOpen ? R.string.widgets_list : R.string.widgets_list_closed));
diff --git a/src/com/android/launcher3/widget/custom/CustomWidgetManager.java b/src/com/android/launcher3/widget/custom/CustomWidgetManager.java
index 2e2a968a44..329a44452b 100644
--- a/src/com/android/launcher3/widget/custom/CustomWidgetManager.java
+++ b/src/com/android/launcher3/widget/custom/CustomWidgetManager.java
@@ -33,7 +33,6 @@ import com.android.launcher3.model.data.LauncherAppWidgetInfo;
import com.android.launcher3.uioverrides.plugins.PluginManagerWrapper;
import com.android.launcher3.util.MainThreadInitializedObject;
import com.android.launcher3.util.PackageUserKey;
-import com.android.launcher3.util.SafeCloseable;
import com.android.launcher3.widget.LauncherAppWidgetHostView;
import com.android.launcher3.widget.LauncherAppWidgetProviderInfo;
import com.android.systemui.plugins.CustomWidgetPlugin;
@@ -47,7 +46,7 @@ import java.util.stream.Stream;
/**
* CustomWidgetManager handles custom widgets implemented as a plugin.
*/
-public class CustomWidgetManager implements PluginListener<CustomWidgetPlugin>, SafeCloseable {
+public class CustomWidgetManager implements PluginListener<CustomWidgetPlugin> {
public static final MainThreadInitializedObject<CustomWidgetManager> INSTANCE =
new MainThreadInitializedObject<>(CustomWidgetManager::new);
@@ -72,8 +71,7 @@ public class CustomWidgetManager implements PluginListener<CustomWidgetPlugin>,
.addPluginListener(this, CustomWidgetPlugin.class, true);
}
- @Override
- public void close() {
+ public void onDestroy() {
PluginManagerWrapper.INSTANCE.get(mContext).removePluginListener(this);
}
diff --git a/src/com/android/launcher3/widget/dragndrop/AppWidgetHostViewDragListener.java b/src/com/android/launcher3/widget/dragndrop/AppWidgetHostViewDragListener.java
index 3e54b33068..4a60983624 100644
--- a/src/com/android/launcher3/widget/dragndrop/AppWidgetHostViewDragListener.java
+++ b/src/com/android/launcher3/widget/dragndrop/AppWidgetHostViewDragListener.java
@@ -24,6 +24,7 @@ import com.android.launcher3.widget.LauncherAppWidgetHostView;
/** A drag listener of {@link LauncherAppWidgetHostView}. */
public final class AppWidgetHostViewDragListener implements DragController.DragListener {
private final Launcher mLauncher;
+ private DropTarget.DragObject mDragObject;
private LauncherAppWidgetHostView mAppWidgetHostView;
public AppWidgetHostViewDragListener(Launcher launcher) {
@@ -33,8 +34,9 @@ public final class AppWidgetHostViewDragListener implements DragController.DragL
@Override
public void onDragStart(DropTarget.DragObject dragObject, DragOptions unused) {
if (dragObject.dragView.getContentView() instanceof LauncherAppWidgetHostView) {
+ mDragObject = dragObject;
mAppWidgetHostView = (LauncherAppWidgetHostView) dragObject.dragView.getContentView();
- mAppWidgetHostView.startDrag();
+ mAppWidgetHostView.startDrag(this);
} else {
mLauncher.getDragController().removeDragListener(this);
}
@@ -45,4 +47,11 @@ public final class AppWidgetHostViewDragListener implements DragController.DragL
mAppWidgetHostView.endDrag();
mLauncher.getDragController().removeDragListener(this);
}
+
+ /** Notifies when there is a content change in the drag view. */
+ public void onDragContentChanged() {
+ if (mDragObject.dragView != null) {
+ mDragObject.dragView.invalidate();
+ }
+ }
}
diff --git a/src/com/android/launcher3/widget/model/WidgetListSpaceEntry.java b/src/com/android/launcher3/widget/model/WidgetListSpaceEntry.java
deleted file mode 100644
index 7f24905f88..0000000000
--- a/src/com/android/launcher3/widget/model/WidgetListSpaceEntry.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2021 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.launcher3.widget.model;
-
-import android.os.Process;
-
-import com.android.launcher3.model.data.PackageItemInfo;
-
-import java.util.Collections;
-
-/**
- * Entry representing the top empty space
- */
-public class WidgetListSpaceEntry extends WidgetsListBaseEntry {
-
- public WidgetListSpaceEntry() {
- super(new PackageItemInfo(/* packageName= */ "", Process.myUserHandle()),
- /* titleSectionName= */ "",
- Collections.EMPTY_LIST);
- mPkgItem.title = "";
- }
-
- @Override
- public int getRank() {
- return RANK_WIDGETS_TOP_SPACE;
- }
-}
diff --git a/src/com/android/launcher3/widget/model/WidgetsListBaseEntry.java b/src/com/android/launcher3/widget/model/WidgetsListBaseEntry.java
index 1d1c9dce1a..abc79ff966 100644
--- a/src/com/android/launcher3/widget/model/WidgetsListBaseEntry.java
+++ b/src/com/android/launcher3/widget/model/WidgetsListBaseEntry.java
@@ -73,13 +73,11 @@ public abstract class WidgetsListBaseEntry {
}
@Retention(SOURCE)
- @IntDef({RANK_WIDGETS_TOP_SPACE, RANK_WIDGETS_LIST_HEADER, RANK_WIDGETS_LIST_SEARCH_HEADER,
- RANK_WIDGETS_LIST_CONTENT})
+ @IntDef({RANK_WIDGETS_LIST_HEADER, RANK_WIDGETS_LIST_SEARCH_HEADER, RANK_WIDGETS_LIST_CONTENT})
public @interface Rank {
}
- public static final int RANK_WIDGETS_TOP_SPACE = 1;
- public static final int RANK_WIDGETS_LIST_HEADER = 2;
- public static final int RANK_WIDGETS_LIST_SEARCH_HEADER = 3;
- public static final int RANK_WIDGETS_LIST_CONTENT = 4;
+ public static final int RANK_WIDGETS_LIST_HEADER = 1;
+ public static final int RANK_WIDGETS_LIST_SEARCH_HEADER = 2;
+ public static final int RANK_WIDGETS_LIST_CONTENT = 3;
}
diff --git a/src/com/android/launcher3/widget/picker/OnHeaderClickListener.java b/src/com/android/launcher3/widget/picker/OnHeaderClickListener.java
index 35f11bde47..73727515c2 100644
--- a/src/com/android/launcher3/widget/picker/OnHeaderClickListener.java
+++ b/src/com/android/launcher3/widget/picker/OnHeaderClickListener.java
@@ -24,5 +24,5 @@ public interface OnHeaderClickListener {
/**
* Calls when a header is clicked to show / hide widgets for a package.
*/
- void onHeaderClicked(boolean showWidgets, PackageUserKey key);
+ void onHeaderClicked(boolean showWidgets, PackageUserKey packageUserKey);
}
diff --git a/src/com/android/launcher3/widget/picker/SearchAndRecommendationsScrollController.java b/src/com/android/launcher3/widget/picker/SearchAndRecommendationsScrollController.java
index 716dcf3398..664377999d 100644
--- a/src/com/android/launcher3/widget/picker/SearchAndRecommendationsScrollController.java
+++ b/src/com/android/launcher3/widget/picker/SearchAndRecommendationsScrollController.java
@@ -15,148 +15,297 @@
*/
package com.android.launcher3.widget.picker;
-import static com.android.launcher3.anim.AnimatorListeners.forEndCallback;
-
-import android.animation.Animator;
-import android.animation.ObjectAnimator;
-import android.util.FloatProperty;
+import android.animation.ValueAnimator;
+import android.graphics.Point;
import android.view.MotionEvent;
import android.view.View;
-import android.view.ViewGroup;
+import android.view.ViewGroup.MarginLayoutParams;
+import android.widget.RelativeLayout;
import android.widget.TextView;
-import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
-import androidx.recyclerview.widget.RecyclerView;
-import com.android.launcher3.R;
-import com.android.launcher3.widget.picker.WidgetsSpaceViewHolderBinder.EmptySpaceView;
-import com.android.launcher3.widget.picker.search.WidgetsSearchBar;
+import com.android.launcher3.views.RecyclerViewFastScroller;
+import com.android.launcher3.widget.picker.WidgetsFullSheet.SearchAndRecommendationViewHolder;
+import com.android.launcher3.workprofile.PersonalWorkPagedView;
/**
* A controller which measures & updates {@link WidgetsFullSheet}'s views padding, margin and
* vertical displacement upon scrolling.
*/
final class SearchAndRecommendationsScrollController implements
- RecyclerView.OnChildAttachStateChangeListener {
-
- private static final FloatProperty<SearchAndRecommendationsScrollController> SCROLL_OFFSET =
- new FloatProperty<SearchAndRecommendationsScrollController>("scrollAnimOffset") {
- @Override
- public void setValue(SearchAndRecommendationsScrollController controller, float offset) {
- controller.mScrollOffset = offset;
- controller.updateHeaderScroll();
- }
-
- @Override
- public Float get(SearchAndRecommendationsScrollController controller) {
- return controller.mScrollOffset;
- }
- };
-
- private static final MotionEventProxyMethod INTERCEPT_PROXY = ViewGroup::onInterceptTouchEvent;
- private static final MotionEventProxyMethod TOUCH_PROXY = ViewGroup::onTouchEvent;
-
- final SearchAndRecommendationsView mContainer;
- final View mSearchBarContainer;
- final WidgetsSearchBar mSearchBar;
- final TextView mHeaderTitle;
- final WidgetsRecommendationTableLayout mRecommendedWidgetsTable;
- @Nullable final View mTabBar;
+ RecyclerViewFastScroller.OnFastScrollChangeListener, ValueAnimator.AnimatorUpdateListener {
+ private final boolean mHasWorkProfile;
+ private final SearchAndRecommendationViewHolder mViewHolder;
+ private final View mSearchAndRecommendationViewParent;
+ private final WidgetsRecyclerView mPrimaryRecyclerView;
+ private final WidgetsRecyclerView mSearchRecyclerView;
+ private final TextView mNoWidgetsView;
+ private final int mTabsHeight;
+ private final ValueAnimator mAnimator = ValueAnimator.ofInt(0, 0);
+ private final Point mTempOffset = new Point();
+ private int mBottomInset;
+
+ // The following are only non null if mHasWorkProfile is true.
+ @Nullable private final WidgetsRecyclerView mWorkRecyclerView;
+ @Nullable private final View mPrimaryWorkTabsView;
+ @Nullable private final PersonalWorkPagedView mPrimaryWorkViewPager;
private WidgetsRecyclerView mCurrentRecyclerView;
- private EmptySpaceView mCurrentEmptySpaceView;
+ private int mCurrentRecyclerViewScrollY = 0;
- private float mLastScroll = 0;
- private float mScrollOffset = 0;
- private Animator mOffsetAnimator;
+ private OnContentChangeListener mOnContentChangeListener = () -> onScrollChanged();
- private boolean mShouldForwardToRecyclerView = false;
+ /**
+ * The vertical distance, in pixels, until the search is pinned at the top of the screen when
+ * the user scrolls down the recycler view.
+ */
+ private int mCollapsibleHeightForSearch = 0;
+ /**
+ * The vertical distance, in pixels, until the recommendation table disappears from the top of
+ * the screen when the user scrolls down the recycler view.
+ */
+ private int mCollapsibleHeightForRecommendation = 0;
+ /**
+ * The vertical distance, in pixels, until the tabs is pinned at the top of the screen when the
+ * user scrolls down the recycler view.
+ *
+ * <p>Always 0 if there is no work profile.
+ */
+ private int mCollapsibleHeightForTabs = 0;
- private int mHeaderHeight;
+ private boolean mShouldForwardToRecyclerView = false;
SearchAndRecommendationsScrollController(
- SearchAndRecommendationsView searchAndRecommendationContainer) {
- mContainer = searchAndRecommendationContainer;
- mSearchBarContainer = mContainer.findViewById(R.id.search_bar_container);
- mSearchBar = mContainer.findViewById(R.id.widgets_search_bar);
- mHeaderTitle = mContainer.findViewById(R.id.title);
- mRecommendedWidgetsTable = mContainer.findViewById(R.id.recommended_widget_table);
- mTabBar = mContainer.findViewById(R.id.tabs);
-
- mContainer.setSearchAndRecommendationScrollController(this);
+ boolean hasWorkProfile,
+ int tabsHeight,
+ SearchAndRecommendationViewHolder viewHolder,
+ WidgetsRecyclerView primaryRecyclerView,
+ @Nullable WidgetsRecyclerView workRecyclerView,
+ WidgetsRecyclerView searchRecyclerView,
+ @Nullable View personalWorkTabsView,
+ @Nullable PersonalWorkPagedView primaryWorkViewPager,
+ TextView noWidgetsView) {
+ mHasWorkProfile = hasWorkProfile;
+ mViewHolder = viewHolder;
+ mViewHolder.mContainer.setSearchAndRecommendationScrollController(this);
+ mSearchAndRecommendationViewParent = (View) mViewHolder.mContainer.getParent();
+ mPrimaryRecyclerView = primaryRecyclerView;
+ mWorkRecyclerView = workRecyclerView;
+ mSearchRecyclerView = searchRecyclerView;
+ mPrimaryWorkTabsView = personalWorkTabsView;
+ mPrimaryWorkViewPager = primaryWorkViewPager;
+ mTabsHeight = tabsHeight;
+ mNoWidgetsView = noWidgetsView;
+ setCurrentRecyclerView(mPrimaryRecyclerView, /* animateReset= */ false);
}
public void setCurrentRecyclerView(WidgetsRecyclerView currentRecyclerView) {
- boolean animateReset = mCurrentRecyclerView != null;
+ setCurrentRecyclerView(currentRecyclerView, /* animateReset= */ true);
+ }
+
+ /** Sets the current active {@link WidgetsRecyclerView}. */
+ private void setCurrentRecyclerView(WidgetsRecyclerView currentRecyclerView,
+ boolean animateReset) {
+ if (mCurrentRecyclerView == currentRecyclerView) {
+ return;
+ }
if (mCurrentRecyclerView != null) {
- mCurrentRecyclerView.removeOnChildAttachStateChangeListener(this);
+ mCurrentRecyclerView.setOnContentChangeListener(null);
}
mCurrentRecyclerView = currentRecyclerView;
- mCurrentRecyclerView.addOnChildAttachStateChangeListener(this);
- findCurrentEmptyView();
+ mCurrentRecyclerView.setOnContentChangeListener(mOnContentChangeListener);
reset(animateReset);
}
- public int getHeaderHeight() {
- return mHeaderHeight;
+ /**
+ * Updates padding of {@link WidgetsFullSheet} contents to include {@code bottomInset} wherever
+ * necessary.
+ */
+ public boolean updateBottomInset(int bottomInset) {
+ mBottomInset = bottomInset;
+ return updateMarginAndPadding();
}
- private void updateHeaderScroll() {
- mLastScroll = getCurrentScroll();
- mHeaderTitle.setTranslationY(mLastScroll);
- mRecommendedWidgetsTable.setTranslationY(mLastScroll);
+ /**
+ * Updates the margin and padding of {@link WidgetsFullSheet} to accumulate collapsible views.
+ *
+ * @return {@code true} if margins or/and padding of views in the search and recommendations
+ * container have been updated.
+ */
+ public boolean updateMarginAndPadding() {
+ boolean hasMarginOrPaddingUpdated = false;
+ mCollapsibleHeightForSearch = measureHeightWithVerticalMargins(mViewHolder.mHeaderTitle);
+ mCollapsibleHeightForRecommendation =
+ measureHeightWithVerticalMargins(mViewHolder.mHeaderTitle)
+ + measureHeightWithVerticalMargins(mViewHolder.mCollapseHandle)
+ + measureHeightWithVerticalMargins((View) mViewHolder.mSearchBarContainer)
+ + measureHeightWithVerticalMargins(mViewHolder.mRecommendedWidgetsTable);
+
+ int topContainerHeight = measureHeightWithVerticalMargins(mViewHolder.mContainer);
+ int noWidgetsViewHeight = topContainerHeight - mBottomInset;
+
+ if (mHasWorkProfile) {
+ mCollapsibleHeightForTabs = measureHeightWithVerticalMargins(mViewHolder.mHeaderTitle)
+ + measureHeightWithVerticalMargins(mViewHolder.mRecommendedWidgetsTable);
+ // In a work profile setup, the full widget sheet contains the following views:
+ // ------- (pinned) -|
+ // Widgets (collapsible) -|---> LinearLayout for search & recommendations
+ // Search bar (pinned) -|
+ // Widgets recommendation (collapsible)-|
+ // Personal | Work (pinned)
+ // View Pager
+ //
+ // Views after the search & recommendations are not bound by RelativelyLayout param.
+ // To position them on the expected location, padding & margin are added to these views
+
+ // Tabs should have a padding of the height of the search & recommendations container.
+ RelativeLayout.LayoutParams tabsLayoutParams =
+ (RelativeLayout.LayoutParams) mPrimaryWorkTabsView.getLayoutParams();
+ tabsLayoutParams.topMargin = topContainerHeight;
+ mPrimaryWorkTabsView.setLayoutParams(tabsLayoutParams);
+
+ // Instead of setting the top offset directly, we split the top offset into two values:
+ // 1. topOffsetAfterAllViewsCollapsed: this is the top offset after all collapsible
+ // views are no longer visible on the screen.
+ // This value is set as the margin for the view pager.
+ // 2. mMaxCollapsibleDistance
+ // This value is set as the padding for the recycler views in order to work with
+ // clipToPadding="false", which is an attribute for not showing top / bottom padding
+ // when a recycler view has not reached the top or bottom of the list.
+ // e.g. a list of 10 entries, only 3 entries are visible at a time.
+ // case 1: recycler view is scrolled to the top. Top padding is visible/
+ // (top padding)
+ // item 1
+ // item 2
+ // item 3
+ //
+ // case 2: recycler view is scrolled to the middle. No padding is visible.
+ // item 4
+ // item 5
+ // item 6
+ //
+ // case 3: recycler view is scrolled to the end. bottom padding is visible.
+ // item 8
+ // item 9
+ // item 10
+ // (bottom padding): not set in this case.
+ //
+ // When the views are first inflated, the sum of topOffsetAfterAllViewsCollapsed and
+ // mMaxCollapsibleDistance should equal to the top container height.
+ int topOffsetAfterAllViewsCollapsed =
+ topContainerHeight + mTabsHeight - mCollapsibleHeightForTabs;
+
+ if (mPrimaryWorkTabsView.getVisibility() == View.VISIBLE) {
+ noWidgetsViewHeight += mTabsHeight;
+ }
- float searchYDisplacement = Math.max(mLastScroll, -mSearchBarContainer.getTop());
- mSearchBarContainer.setTranslationY(searchYDisplacement);
+ RelativeLayout.LayoutParams viewPagerLayoutParams =
+ (RelativeLayout.LayoutParams) mPrimaryWorkViewPager.getLayoutParams();
+ if (viewPagerLayoutParams.topMargin != topOffsetAfterAllViewsCollapsed) {
+ viewPagerLayoutParams.topMargin = topOffsetAfterAllViewsCollapsed;
+ mPrimaryWorkViewPager.setLayoutParams(viewPagerLayoutParams);
+ hasMarginOrPaddingUpdated = true;
+ }
- if (mTabBar != null) {
- float tabsDisplacement = Math.max(mLastScroll, -mTabBar.getTop()
- + mSearchBarContainer.getHeight());
- mTabBar.setTranslationY(tabsDisplacement);
+ if (mPrimaryRecyclerView.getPaddingTop() != mCollapsibleHeightForTabs) {
+ mPrimaryRecyclerView.setPadding(
+ mPrimaryRecyclerView.getPaddingLeft(),
+ mCollapsibleHeightForTabs,
+ mPrimaryRecyclerView.getPaddingRight(),
+ mPrimaryRecyclerView.getPaddingBottom());
+ hasMarginOrPaddingUpdated = true;
+ }
+ if (mWorkRecyclerView.getPaddingTop() != mCollapsibleHeightForTabs) {
+ mWorkRecyclerView.setPadding(
+ mWorkRecyclerView.getPaddingLeft(),
+ mCollapsibleHeightForTabs,
+ mWorkRecyclerView.getPaddingRight(),
+ mWorkRecyclerView.getPaddingBottom());
+ hasMarginOrPaddingUpdated = true;
+ }
+ } else {
+ if (mPrimaryRecyclerView.getPaddingTop() != topContainerHeight) {
+ mPrimaryRecyclerView.setPadding(
+ mPrimaryRecyclerView.getPaddingLeft(),
+ topContainerHeight,
+ mPrimaryRecyclerView.getPaddingRight(),
+ mPrimaryRecyclerView.getPaddingBottom());
+ hasMarginOrPaddingUpdated = true;
+ }
+ }
+ if (mSearchRecyclerView.getPaddingTop() != topContainerHeight) {
+ mSearchRecyclerView.setPadding(
+ mSearchRecyclerView.getPaddingLeft(),
+ topContainerHeight,
+ mSearchRecyclerView.getPaddingRight(),
+ mSearchRecyclerView.getPaddingBottom());
+ hasMarginOrPaddingUpdated = true;
+ }
+ if (mNoWidgetsView.getPaddingTop() != noWidgetsViewHeight) {
+ mNoWidgetsView.setPadding(
+ mNoWidgetsView.getPaddingLeft(),
+ noWidgetsViewHeight,
+ mNoWidgetsView.getPaddingRight(),
+ mNoWidgetsView.getPaddingBottom());
+ hasMarginOrPaddingUpdated = true;
}
+ return hasMarginOrPaddingUpdated;
}
- private float getCurrentScroll() {
- return mScrollOffset + (mCurrentEmptySpaceView == null ? 0 : mCurrentEmptySpaceView.getY());
+ @Override
+ public void onScrollChanged() {
+ int recyclerViewYOffset = mCurrentRecyclerView.getCurrentScrollY();
+ if (recyclerViewYOffset < 0) return;
+ mCurrentRecyclerViewScrollY = recyclerViewYOffset;
+ if (mAnimator.isStarted()) {
+ mAnimator.cancel();
+ }
+ applyVerticalTransition();
}
/**
- * Updates the scrollable header height
- *
- * @return {@code true} if the header height or dependent property changed.
+ * Changes the displacement of collapsible views (e.g. title & widget recommendations) and fixed
+ * views (e.g. recycler views, tabs) upon scrolling / content changes in the recycler view.
*/
- public boolean updateHeaderHeight() {
- boolean hasSizeUpdated = false;
+ private void applyVerticalTransition() {
+ if (mCollapsibleHeightForRecommendation > 0) {
+ int yDisplacement = Math.max(-mCurrentRecyclerViewScrollY,
+ -mCollapsibleHeightForRecommendation);
+ mViewHolder.mHeaderTitle.setTranslationY(yDisplacement);
+ mViewHolder.mRecommendedWidgetsTable.setTranslationY(yDisplacement);
+ }
- int headerHeight = mContainer.getMeasuredHeight();
- if (headerHeight != mHeaderHeight) {
- mHeaderHeight = headerHeight;
- hasSizeUpdated = true;
+ if (mCollapsibleHeightForSearch > 0) {
+ int searchYDisplacement = Math.max(-mCurrentRecyclerViewScrollY,
+ -mCollapsibleHeightForSearch);
+ mViewHolder.mSearchBarContainer.setTranslationY(searchYDisplacement);
}
- if (mCurrentEmptySpaceView != null
- && mCurrentEmptySpaceView.setFixedHeight(mHeaderHeight)) {
- hasSizeUpdated = true;
+ if (mHasWorkProfile && mCollapsibleHeightForTabs > 0) {
+ int yDisplacementForTabs = Math.max(-mCurrentRecyclerViewScrollY,
+ -mCollapsibleHeightForTabs);
+ mPrimaryWorkTabsView.setTranslationY(yDisplacementForTabs);
}
- return hasSizeUpdated;
}
/** Resets any previous view translation. */
public void reset(boolean animate) {
- if (mOffsetAnimator != null) {
- mOffsetAnimator.cancel();
- mOffsetAnimator = null;
+ if (mCurrentRecyclerViewScrollY == 0) {
+ return;
+ }
+ if (mAnimator.isStarted()) {
+ mAnimator.cancel();
}
- mScrollOffset = 0;
- if (!animate) {
- updateHeaderScroll();
+ if (animate) {
+ mAnimator.setIntValues(mCurrentRecyclerViewScrollY, 0);
+ mAnimator.addUpdateListener(this);
+ mAnimator.setDuration(300);
+ mAnimator.start();
} else {
- float startValue = mLastScroll - getCurrentScroll();
- mOffsetAnimator = ObjectAnimator.ofFloat(this, SCROLL_OFFSET, startValue, 0);
- mOffsetAnimator.addListener(forEndCallback(() -> mOffsetAnimator = null));
- mOffsetAnimator.start();
+ mCurrentRecyclerViewScrollY = 0;
+ applyVerticalTransition();
}
}
@@ -164,60 +313,61 @@ final class SearchAndRecommendationsScrollController implements
* Returns {@code true} if a touch event should be intercepted by this controller.
*/
public boolean onInterceptTouchEvent(MotionEvent event) {
- return (mShouldForwardToRecyclerView = proxyMotionEvent(event, INTERCEPT_PROXY));
+ calculateMotionEventOffset(mTempOffset);
+ event.offsetLocation(mTempOffset.x, mTempOffset.y);
+ try {
+ mShouldForwardToRecyclerView = mCurrentRecyclerView.onInterceptTouchEvent(event);
+ return mShouldForwardToRecyclerView;
+ } finally {
+ event.offsetLocation(-mTempOffset.x, -mTempOffset.y);
+ }
}
/**
* Returns {@code true} if this controller has intercepted and consumed a touch event.
*/
public boolean onTouchEvent(MotionEvent event) {
- return mShouldForwardToRecyclerView && proxyMotionEvent(event, TOUCH_PROXY);
- }
-
- private boolean proxyMotionEvent(MotionEvent event, MotionEventProxyMethod method) {
- float dx = mCurrentRecyclerView.getLeft() - mContainer.getLeft();
- float dy = mCurrentRecyclerView.getTop() - mContainer.getTop();
- event.offsetLocation(dx, dy);
- try {
- return method.proxyEvent(mCurrentRecyclerView, event);
- } finally {
- event.offsetLocation(-dx, -dy);
+ if (mShouldForwardToRecyclerView) {
+ calculateMotionEventOffset(mTempOffset);
+ event.offsetLocation(mTempOffset.x, mTempOffset.y);
+ try {
+ return mCurrentRecyclerView.onTouchEvent(event);
+ } finally {
+ event.offsetLocation(-mTempOffset.x, -mTempOffset.y);
+ }
}
+ return false;
}
- @Override
- public void onChildViewAttachedToWindow(@NonNull View view) {
- if (view instanceof EmptySpaceView) {
- findCurrentEmptyView();
- }
+ private void calculateMotionEventOffset(Point p) {
+ p.x = mViewHolder.mContainer.getLeft() - mCurrentRecyclerView.getLeft()
+ - mSearchAndRecommendationViewParent.getLeft();
+ p.y = mViewHolder.mContainer.getTop() - mCurrentRecyclerView.getTop()
+ - mSearchAndRecommendationViewParent.getTop();
}
- @Override
- public void onChildViewDetachedFromWindow(@NonNull View view) {
- if (view == mCurrentEmptySpaceView) {
- findCurrentEmptyView();
+ /** private the height, in pixel, + the vertical margins of a given view. */
+ private static int measureHeightWithVerticalMargins(View view) {
+ if (view.getVisibility() != View.VISIBLE) {
+ return 0;
}
+ MarginLayoutParams marginLayoutParams = (MarginLayoutParams) view.getLayoutParams();
+ return view.getMeasuredHeight() + marginLayoutParams.bottomMargin
+ + marginLayoutParams.topMargin;
}
- private void findCurrentEmptyView() {
- if (mCurrentEmptySpaceView != null) {
- mCurrentEmptySpaceView.setOnYChangeCallback(null);
- mCurrentEmptySpaceView = null;
- }
- int childCount = mCurrentRecyclerView.getChildCount();
- for (int i = 0; i < childCount; i++) {
- View view = mCurrentRecyclerView.getChildAt(i);
- if (view instanceof EmptySpaceView) {
- mCurrentEmptySpaceView = (EmptySpaceView) view;
- mCurrentEmptySpaceView.setFixedHeight(getHeaderHeight());
- mCurrentEmptySpaceView.setOnYChangeCallback(this::updateHeaderScroll);
- return;
- }
- }
+ @Override
+ public void onAnimationUpdate(ValueAnimator animation) {
+ mCurrentRecyclerViewScrollY = (Integer) animation.getAnimatedValue();
+ applyVerticalTransition();
}
- private interface MotionEventProxyMethod {
-
- boolean proxyEvent(ViewGroup view, MotionEvent event);
+ /**
+ * A listener to be notified when there is a content change in the recycler view that may affect
+ * the relative position of the search and recommendation container.
+ */
+ public interface OnContentChangeListener {
+ /** Notifies a content change in the recycler view. */
+ void onContentChanged();
}
}
diff --git a/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java b/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java
index a49cdc005a..f2fee0a526 100644
--- a/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java
+++ b/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java
@@ -27,11 +27,9 @@ import android.animation.PropertyValuesHolder;
import android.content.Context;
import android.content.pm.LauncherApps;
import android.content.res.Configuration;
-import android.content.res.Resources;
import android.graphics.Rect;
import android.os.Process;
import android.os.UserHandle;
-import android.os.UserManager;
import android.util.AttributeSet;
import android.util.Pair;
import android.util.SparseArray;
@@ -42,7 +40,6 @@ import android.view.ViewGroup;
import android.view.WindowInsets;
import android.view.animation.AnimationUtils;
import android.view.animation.Interpolator;
-import android.widget.Button;
import android.widget.TextView;
import androidx.annotation.Nullable;
@@ -56,17 +53,16 @@ import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.anim.PendingAnimation;
import com.android.launcher3.compat.AccessibilityManagerCompat;
-import com.android.launcher3.model.UserManagerState;
import com.android.launcher3.model.WidgetItem;
-import com.android.launcher3.pm.UserCache;
import com.android.launcher3.views.ArrowTipView;
import com.android.launcher3.views.RecyclerViewFastScroller;
-import com.android.launcher3.views.SpringRelativeLayout;
+import com.android.launcher3.views.TopRoundedCornerView;
import com.android.launcher3.views.WidgetsEduView;
import com.android.launcher3.widget.BaseWidgetSheet;
import com.android.launcher3.widget.LauncherAppWidgetHost.ProviderChangedListener;
import com.android.launcher3.widget.model.WidgetsListBaseEntry;
import com.android.launcher3.widget.picker.search.SearchModeListener;
+import com.android.launcher3.widget.picker.search.WidgetsSearchBar;
import com.android.launcher3.widget.util.WidgetsTableUtils;
import com.android.launcher3.workprofile.PersonalWorkPagedView;
import com.android.launcher3.workprofile.PersonalWorkSlidingTabStrip.OnActivePageChangedListener;
@@ -82,6 +78,7 @@ import java.util.stream.IntStream;
public class WidgetsFullSheet extends BaseWidgetSheet
implements ProviderChangedListener, OnActivePageChangedListener,
WidgetsRecyclerView.HeaderViewDimensionsProvider, SearchModeListener {
+ private static final String TAG = WidgetsFullSheet.class.getSimpleName();
private static final long DEFAULT_OPEN_DURATION = 267;
private static final long FADE_IN_DURATION = 150;
@@ -96,16 +93,14 @@ public class WidgetsFullSheet extends BaseWidgetSheet
private static final String KEY_WIDGETS_EDUCATION_DIALOG_SEEN =
"launcher.widgets_education_dialog_seen";
- private final UserManagerState mUserManagerState = new UserManagerState();
-
+ private final Rect mInsets = new Rect();
private final boolean mHasWorkProfile;
private final SparseArray<AdapterHolder> mAdapters = new SparseArray();
private final UserHandle mCurrentUser = Process.myUserHandle();
private final Predicate<WidgetsListBaseEntry> mPrimaryWidgetsFilter =
entry -> mCurrentUser.equals(entry.mPkgItem.user);
private final Predicate<WidgetsListBaseEntry> mWorkWidgetsFilter =
- entry -> !mCurrentUser.equals(entry.mPkgItem.user)
- && !mUserManagerState.isUserQuiet(entry.mPkgItem.user);
+ mPrimaryWidgetsFilter.negate();
@Nullable private ArrowTipView mLatestEducationalTip;
private final OnLayoutChangeListener mLayoutChangeListenerToShowTips =
new OnLayoutChangeListener() {
@@ -153,15 +148,19 @@ public class WidgetsFullSheet extends BaseWidgetSheet
};
private final int mTabsHeight;
- private final int mWidgetSheetContentHorizontalPadding;
+ private final int mViewPagerTopPadding;
+ private final int mSearchAndRecommendationContainerBottomMargin;
+ private final int mWidgetCellHorizontalPadding;
@Nullable private WidgetsRecyclerView mCurrentWidgetsRecyclerView;
@Nullable private PersonalWorkPagedView mViewPager;
private boolean mIsInSearchMode;
private boolean mIsNoWidgetsViewNeeded;
- private int mMaxSpansPerRow = DEFAULT_MAX_HORIZONTAL_SPANS;
+ private int mMaxSpansPerRow = 4;
+ private View mTabsView;
private TextView mNoWidgetsView;
- private SearchAndRecommendationsScrollController mSearchScrollController;
+ private SearchAndRecommendationViewHolder mSearchAndRecommendationViewHolder;
+ private SearchAndRecommendationsScrollController mSearchAndRecommendationsScrollController;
public WidgetsFullSheet(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
@@ -169,16 +168,20 @@ public class WidgetsFullSheet extends BaseWidgetSheet
mAdapters.put(AdapterHolder.PRIMARY, new AdapterHolder(AdapterHolder.PRIMARY));
mAdapters.put(AdapterHolder.WORK, new AdapterHolder(AdapterHolder.WORK));
mAdapters.put(AdapterHolder.SEARCH, new AdapterHolder(AdapterHolder.SEARCH));
-
- Resources resources = getResources();
mTabsHeight = mHasWorkProfile
- ? resources.getDimensionPixelSize(R.dimen.all_apps_header_pill_height)
+ ? getContext().getResources()
+ .getDimensionPixelSize(R.dimen.all_apps_header_pill_height)
: 0;
- mWidgetSheetContentHorizontalPadding = 2 * resources.getDimensionPixelSize(
+ mViewPagerTopPadding = mHasWorkProfile
+ ? getContext().getResources()
+ .getDimensionPixelSize(R.dimen.widget_picker_view_pager_top_padding)
+ : 0;
+ mSearchAndRecommendationContainerBottomMargin = getContext().getResources()
+ .getDimensionPixelSize(mHasWorkProfile
+ ? R.dimen.search_and_recommended_widgets_container_small_bottom_margin
+ : R.dimen.search_and_recommended_widgets_container_bottom_margin);
+ mWidgetCellHorizontalPadding = 2 * getResources().getDimensionPixelOffset(
R.dimen.widget_cell_horizontal_padding);
-
- mUserManagerState.init(UserCache.INSTANCE.get(context),
- context.getSystemService(UserManager.class));
}
public WidgetsFullSheet(Context context, AttributeSet attrs) {
@@ -189,11 +192,12 @@ public class WidgetsFullSheet extends BaseWidgetSheet
protected void onFinishInflate() {
super.onFinishInflate();
mContent = findViewById(R.id.container);
+ TopRoundedCornerView springLayout = (TopRoundedCornerView) mContent;
LayoutInflater layoutInflater = LayoutInflater.from(getContext());
int contentLayoutRes = mHasWorkProfile ? R.layout.widgets_full_sheet_paged_view
: R.layout.widgets_full_sheet_recyclerview;
- layoutInflater.inflate(contentLayoutRes, mContent, true);
+ layoutInflater.inflate(contentLayoutRes, springLayout, true);
RecyclerViewFastScroller fastScroller = findViewById(R.id.fast_scroller);
mAdapters.get(AdapterHolder.PRIMARY).setup(findViewById(R.id.primary_widgets_list_view));
@@ -203,43 +207,49 @@ public class WidgetsFullSheet extends BaseWidgetSheet
mViewPager.initParentViews(this);
mViewPager.getPageIndicator().setOnActivePageChangedListener(this);
mViewPager.getPageIndicator().setActiveMarker(AdapterHolder.PRIMARY);
+ mTabsView = findViewById(R.id.tabs);
findViewById(R.id.tab_personal)
.setOnClickListener((View view) -> mViewPager.snapToPage(0));
findViewById(R.id.tab_work)
.setOnClickListener((View view) -> mViewPager.snapToPage(1));
+ fastScroller.setIsRecyclerViewFirstChildInParent(false);
mAdapters.get(AdapterHolder.WORK).setup(findViewById(R.id.work_widgets_list_view));
- setDeviceManagementResources();
} else {
mViewPager = null;
}
+ layoutInflater.inflate(R.layout.widgets_full_sheet_search_and_recommendations, springLayout,
+ true);
mNoWidgetsView = findViewById(R.id.no_widgets_text);
- mSearchScrollController = new SearchAndRecommendationsScrollController(
+ mSearchAndRecommendationViewHolder = new SearchAndRecommendationViewHolder(
findViewById(R.id.search_and_recommendations_container));
- mSearchScrollController.setCurrentRecyclerView(
- findViewById(R.id.primary_widgets_list_view));
- mSearchScrollController.mRecommendedWidgetsTable.setWidgetCellLongClickListener(this);
- mSearchScrollController.mRecommendedWidgetsTable.setWidgetCellOnClickListener(this);
+ TopRoundedCornerView.LayoutParams layoutParams =
+ (TopRoundedCornerView.LayoutParams)
+ mSearchAndRecommendationViewHolder.mContainer.getLayoutParams();
+ layoutParams.bottomMargin = mSearchAndRecommendationContainerBottomMargin;
+ mSearchAndRecommendationViewHolder.mContainer.setLayoutParams(layoutParams);
+ mSearchAndRecommendationsScrollController = new SearchAndRecommendationsScrollController(
+ mHasWorkProfile,
+ mTabsHeight,
+ mSearchAndRecommendationViewHolder,
+ findViewById(R.id.primary_widgets_list_view),
+ mHasWorkProfile ? findViewById(R.id.work_widgets_list_view) : null,
+ findViewById(R.id.search_widgets_list_view),
+ mTabsView,
+ mViewPager,
+ mNoWidgetsView);
+ fastScroller.setOnFastScrollChangeListener(mSearchAndRecommendationsScrollController);
+
onRecommendedWidgetsBound();
onWidgetsBound();
- mSearchScrollController.mSearchBar.initialize(
+ mSearchAndRecommendationViewHolder.mSearchBar.initialize(
mActivityContext.getPopupDataProvider(), /* searchModeListener= */ this);
setUpEducationViewsIfNeeded();
}
- private void setDeviceManagementResources() {
- if (mActivityContext.getStringCache() != null) {
- Button personalTab = findViewById(R.id.tab_personal);
- personalTab.setText(mActivityContext.getStringCache().widgetsPersonalTab);
-
- Button workTab = findViewById(R.id.tab_work);
- workTab.setText(mActivityContext.getStringCache().widgetsWorkTab);
- }
- }
-
@Override
public void onActivePageChanged(int currentActivePage) {
AdapterHolder currentAdapterHolder = mAdapters.get(currentActivePage);
@@ -258,24 +268,18 @@ public class WidgetsFullSheet extends BaseWidgetSheet
reset();
resetExpandedHeaders();
mCurrentWidgetsRecyclerView = recyclerView;
- mSearchScrollController.setCurrentRecyclerView(recyclerView);
+ mSearchAndRecommendationsScrollController.setCurrentRecyclerView(recyclerView);
}
}
private void updateRecyclerViewVisibility(AdapterHolder adapterHolder) {
- // The first item is always an empty space entry. Look for any more items.
- boolean isWidgetAvailable = adapterHolder.mWidgetsListAdapter.hasVisibleEntries();
+ boolean isWidgetAvailable = adapterHolder.mWidgetsListAdapter.getItemCount() > 0;
adapterHolder.mWidgetsRecyclerView.setVisibility(isWidgetAvailable ? VISIBLE : GONE);
- if (adapterHolder.mAdapterType == AdapterHolder.SEARCH) {
- mNoWidgetsView.setText(R.string.no_search_results);
- } else if (adapterHolder.mAdapterType == AdapterHolder.WORK
- && mUserManagerState.isAnyProfileQuietModeEnabled()
- && mActivityContext.getStringCache() != null) {
- mNoWidgetsView.setText(mActivityContext.getStringCache().workProfilePausedTitle);
- } else {
- mNoWidgetsView.setText(R.string.no_widgets_available);
- }
+ mNoWidgetsView.setText(
+ adapterHolder.mAdapterType == AdapterHolder.SEARCH
+ ? R.string.no_search_results
+ : R.string.no_widgets_available);
mNoWidgetsView.setVisibility(isWidgetAvailable ? GONE : VISIBLE);
}
@@ -285,7 +289,7 @@ public class WidgetsFullSheet extends BaseWidgetSheet
mAdapters.get(AdapterHolder.WORK).mWidgetsRecyclerView.scrollToTop();
}
mAdapters.get(AdapterHolder.SEARCH).mWidgetsRecyclerView.scrollToTop();
- mSearchScrollController.reset(/* animate= */ true);
+ mSearchAndRecommendationsScrollController.reset(/* animate= */ true);
}
@VisibleForTesting
@@ -328,15 +332,14 @@ public class WidgetsFullSheet extends BaseWidgetSheet
@Override
public void setInsets(Rect insets) {
super.setInsets(insets);
- int bottomPadding = Math.max(insets.bottom, mNavBarScrimHeight);
- setBottomPadding(mAdapters.get(AdapterHolder.PRIMARY).mWidgetsRecyclerView, bottomPadding);
- setBottomPadding(mAdapters.get(AdapterHolder.SEARCH).mWidgetsRecyclerView, bottomPadding);
+
+ setBottomPadding(mAdapters.get(AdapterHolder.PRIMARY).mWidgetsRecyclerView, insets.bottom);
+ setBottomPadding(mAdapters.get(AdapterHolder.SEARCH).mWidgetsRecyclerView, insets.bottom);
if (mHasWorkProfile) {
- setBottomPadding(mAdapters.get(AdapterHolder.WORK).mWidgetsRecyclerView, bottomPadding);
+ setBottomPadding(mAdapters.get(AdapterHolder.WORK).mWidgetsRecyclerView, insets.bottom);
}
- ((MarginLayoutParams) mNoWidgetsView.getLayoutParams()).bottomMargin = bottomPadding;
-
- if (bottomPadding > 0) {
+ mSearchAndRecommendationsScrollController.updateBottomInset(insets.bottom);
+ if (insets.bottom > 0) {
setupNavBarColor();
} else {
clearNavBarColor();
@@ -354,50 +357,17 @@ public class WidgetsFullSheet extends BaseWidgetSheet
}
@Override
- protected void onContentHorizontalMarginChanged(int contentHorizontalMarginInPx) {
- setContentViewChildHorizontalMargin(mSearchScrollController.mContainer,
- contentHorizontalMarginInPx);
- if (mViewPager == null) {
- setContentViewChildHorizontalPadding(
- mAdapters.get(AdapterHolder.PRIMARY).mWidgetsRecyclerView,
- contentHorizontalMarginInPx);
- } else {
- setContentViewChildHorizontalPadding(
- mAdapters.get(AdapterHolder.PRIMARY).mWidgetsRecyclerView,
- contentHorizontalMarginInPx);
- setContentViewChildHorizontalPadding(
- mAdapters.get(AdapterHolder.WORK).mWidgetsRecyclerView,
- contentHorizontalMarginInPx);
- }
- setContentViewChildHorizontalPadding(
- mAdapters.get(AdapterHolder.SEARCH).mWidgetsRecyclerView,
- contentHorizontalMarginInPx);
- }
-
- private static void setContentViewChildHorizontalMargin(View view, int horizontalMarginInPx) {
- ViewGroup.MarginLayoutParams layoutParams =
- (ViewGroup.MarginLayoutParams) view.getLayoutParams();
- layoutParams.setMarginStart(horizontalMarginInPx);
- layoutParams.setMarginEnd(horizontalMarginInPx);
- }
-
- private static void setContentViewChildHorizontalPadding(View view, int horizontalPaddingInPx) {
- view.setPadding(horizontalPaddingInPx, view.getPaddingTop(), horizontalPaddingInPx,
- view.getPaddingBottom());
- }
-
- @Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
doMeasure(widthMeasureSpec, heightMeasureSpec);
- if (mSearchScrollController.updateHeaderHeight()) {
+ if (mSearchAndRecommendationsScrollController.updateMarginAndPadding()) {
doMeasure(widthMeasureSpec, heightMeasureSpec);
}
if (updateMaxSpansPerRow()) {
doMeasure(widthMeasureSpec, heightMeasureSpec);
- if (mSearchScrollController.updateHeaderHeight()) {
+ if (mSearchAndRecommendationsScrollController.updateMarginAndPadding()) {
doMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
@@ -407,13 +377,11 @@ public class WidgetsFullSheet extends BaseWidgetSheet
private boolean updateMaxSpansPerRow() {
if (getMeasuredWidth() == 0) return false;
- View content = mHasWorkProfile
- ? mViewPager
- : mAdapters.get(AdapterHolder.PRIMARY).mWidgetsRecyclerView;
- int maxHorizontalSpans = computeMaxHorizontalSpans(content,
- mWidgetSheetContentHorizontalPadding);
- if (mMaxSpansPerRow != maxHorizontalSpans) {
- mMaxSpansPerRow = maxHorizontalSpans;
+ int previousMaxSpansPerRow = mMaxSpansPerRow;
+ mMaxSpansPerRow = getMeasuredWidth()
+ / (mActivityContext.getDeviceProfile().cellWidthPx + mWidgetCellHorizontalPadding);
+
+ if (previousMaxSpansPerRow != mMaxSpansPerRow) {
mAdapters.get(AdapterHolder.PRIMARY).mWidgetsListAdapter.setMaxHorizontalSpansPerRow(
mMaxSpansPerRow);
mAdapters.get(AdapterHolder.SEARCH).mWidgetsListAdapter.setMaxHorizontalSpansPerRow(
@@ -460,7 +428,7 @@ public class WidgetsFullSheet extends BaseWidgetSheet
if (mHasWorkProfile) {
mViewPager.setVisibility(VISIBLE);
- mSearchScrollController.mTabBar.setVisibility(VISIBLE);
+ mTabsView.setVisibility(VISIBLE);
AdapterHolder workUserAdapterHolder = mAdapters.get(AdapterHolder.WORK);
workUserAdapterHolder.mWidgetsListAdapter.setWidgets(allWidgets);
onActivePageChanged(mViewPager.getCurrentPage());
@@ -470,9 +438,9 @@ public class WidgetsFullSheet extends BaseWidgetSheet
// Update recommended widgets section so that it occupies appropriate space on screen to
// leave enough space for presence/absence of mNoWidgetsView.
boolean isNoWidgetsViewNeeded =
- !mAdapters.get(AdapterHolder.PRIMARY).mWidgetsListAdapter.hasVisibleEntries()
+ mAdapters.get(AdapterHolder.PRIMARY).mWidgetsListAdapter.getItemCount() == 0
|| (mHasWorkProfile && mAdapters.get(AdapterHolder.WORK)
- .mWidgetsListAdapter.hasVisibleEntries());
+ .mWidgetsListAdapter.getItemCount() == 0);
if (mIsNoWidgetsViewNeeded != isNoWidgetsViewNeeded) {
mIsNoWidgetsViewNeeded = isNoWidgetsViewNeeded;
onRecommendedWidgetsBound();
@@ -496,6 +464,8 @@ public class WidgetsFullSheet extends BaseWidgetSheet
mViewPager.snapToPage(AdapterHolder.PRIMARY);
}
attachScrollbarToRecyclerView(mAdapters.get(AdapterHolder.PRIMARY).mWidgetsRecyclerView);
+
+ mSearchAndRecommendationsScrollController.updateMarginAndPadding();
}
@Override
@@ -508,10 +478,10 @@ public class WidgetsFullSheet extends BaseWidgetSheet
private void setViewVisibilityBasedOnSearch(boolean isInSearchMode) {
mIsInSearchMode = isInSearchMode;
if (isInSearchMode) {
- mSearchScrollController.mRecommendedWidgetsTable.setVisibility(GONE);
+ mSearchAndRecommendationViewHolder.mRecommendedWidgetsTable.setVisibility(GONE);
if (mHasWorkProfile) {
mViewPager.setVisibility(GONE);
- mSearchScrollController.mTabBar.setVisibility(GONE);
+ mTabsView.setVisibility(GONE);
} else {
mAdapters.get(AdapterHolder.PRIMARY).mWidgetsRecyclerView.setVisibility(GONE);
}
@@ -539,7 +509,8 @@ public class WidgetsFullSheet extends BaseWidgetSheet
}
List<WidgetItem> recommendedWidgets =
mActivityContext.getPopupDataProvider().getRecommendedWidgets();
- WidgetsRecommendationTableLayout table = mSearchScrollController.mRecommendedWidgetsTable;
+ WidgetsRecommendationTableLayout table =
+ mSearchAndRecommendationViewHolder.mRecommendedWidgetsTable;
if (recommendedWidgets.size() > 0) {
float noWidgetsViewHeight = 0;
if (mIsNoWidgetsViewNeeded) {
@@ -556,12 +527,12 @@ public class WidgetsFullSheet extends BaseWidgetSheet
makeMeasureSpec(mActivityContext.getDeviceProfile().availableHeightPx,
MeasureSpec.EXACTLY));
float maxTableHeight = (mContent.getMeasuredHeight()
- - mTabsHeight - getHeaderViewHeight()
+ - mTabsHeight - mViewPagerTopPadding - getHeaderViewHeight()
- noWidgetsViewHeight) * RECOMMENDATION_TABLE_HEIGHT_RATIO;
List<ArrayList<WidgetItem>> recommendedWidgetsInTable =
- WidgetsTableUtils.groupWidgetItemsIntoTableWithoutReordering(
- recommendedWidgets, mMaxSpansPerRow);
+ WidgetsTableUtils.groupWidgetItemsIntoTable(recommendedWidgets,
+ mMaxSpansPerRow);
table.setRecommendedWidgets(recommendedWidgetsInTable, maxTableHeight);
} else {
table.setVisibility(GONE);
@@ -619,10 +590,10 @@ public class WidgetsFullSheet extends BaseWidgetSheet
mNoIntercept = !getRecyclerView().shouldContainerScroll(ev, getPopupContainer());
}
- if (mSearchScrollController.mSearchBar.isSearchBarFocused()
+ if (mSearchAndRecommendationViewHolder.mSearchBar.isSearchBarFocused()
&& !getPopupContainer().isEventOverView(
- mSearchScrollController.mSearchBarContainer, ev)) {
- mSearchScrollController.mSearchBar.clearSearchBarFocus();
+ mSearchAndRecommendationViewHolder.mSearchBarContainer, ev)) {
+ mSearchAndRecommendationViewHolder.mSearchBar.clearSearchBarFocus();
}
}
return super.onControllerInterceptTouchEvent(ev);
@@ -663,8 +634,10 @@ public class WidgetsFullSheet extends BaseWidgetSheet
@Override
public int getHeaderViewHeight() {
- return measureHeightWithVerticalMargins(mSearchScrollController.mHeaderTitle)
- + measureHeightWithVerticalMargins(mSearchScrollController.mSearchBarContainer);
+ return measureHeightWithVerticalMargins(mSearchAndRecommendationViewHolder.mCollapseHandle)
+ + measureHeightWithVerticalMargins(mSearchAndRecommendationViewHolder.mHeaderTitle)
+ + measureHeightWithVerticalMargins(
+ (View) mSearchAndRecommendationViewHolder.mSearchBarContainer);
}
/** private the height, in pixel, + the vertical margins of a given view. */
@@ -681,14 +654,14 @@ public class WidgetsFullSheet extends BaseWidgetSheet
protected void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
if (mIsInSearchMode) {
- mSearchScrollController.mSearchBar.reset();
+ mSearchAndRecommendationViewHolder.mSearchBar.reset();
}
}
@Override
public boolean onBackPressed() {
if (mIsInSearchMode) {
- mSearchScrollController.mSearchBar.reset();
+ mSearchAndRecommendationViewHolder.mSearchBar.reset();
return true;
}
return super.onBackPressed();
@@ -701,10 +674,11 @@ public class WidgetsFullSheet extends BaseWidgetSheet
}
@Nullable private View getViewToShowEducationTip() {
- if (mSearchScrollController.mRecommendedWidgetsTable.getVisibility() == VISIBLE
- && mSearchScrollController.mRecommendedWidgetsTable.getChildCount() > 0) {
- return ((ViewGroup) mSearchScrollController.mRecommendedWidgetsTable.getChildAt(0))
- .getChildAt(0);
+ if (mSearchAndRecommendationViewHolder.mRecommendedWidgetsTable.getVisibility() == VISIBLE
+ && mSearchAndRecommendationViewHolder.mRecommendedWidgetsTable.getChildCount() > 0
+ ) {
+ return ((ViewGroup) mSearchAndRecommendationViewHolder.mRecommendedWidgetsTable
+ .getChildAt(0)).getChildAt(0);
}
AdapterHolder adapterHolder = mAdapters.get(mIsInSearchMode
@@ -721,7 +695,7 @@ public class WidgetsFullSheet extends BaseWidgetSheet
.findFirst()
.orElse(null);
if (viewHolderForTip != null) {
- return ((ViewGroup) viewHolderForTip.tableContainer.getChildAt(0)).getChildAt(0);
+ return ((ViewGroup) viewHolderForTip.mTableContainer.getChildAt(0)).getChildAt(0);
}
return null;
@@ -779,8 +753,8 @@ public class WidgetsFullSheet extends BaseWidgetSheet
mWidgetsListAdapter = new WidgetsListAdapter(
context,
LayoutInflater.from(context),
+ apps.getWidgetCache(),
apps.getIconCache(),
- this::getEmptySpaceHeight,
/* iconClickListener= */ WidgetsFullSheet.this,
/* iconLongClickListener= */ WidgetsFullSheet.this);
mWidgetsListAdapter.setHasStableIds(true);
@@ -800,24 +774,46 @@ public class WidgetsFullSheet extends BaseWidgetSheet
mWidgetsListItemAnimator.setSupportsChangeAnimations(false);
}
- private int getEmptySpaceHeight() {
- return mSearchScrollController.getHeaderHeight();
- }
-
void setup(WidgetsRecyclerView recyclerView) {
mWidgetsRecyclerView = recyclerView;
mWidgetsRecyclerView.setAdapter(mWidgetsListAdapter);
mWidgetsRecyclerView.setItemAnimator(mWidgetsListItemAnimator);
mWidgetsRecyclerView.setHeaderViewDimensionsProvider(WidgetsFullSheet.this);
mWidgetsRecyclerView.setEdgeEffectFactory(
- ((SpringRelativeLayout) mContent).createEdgeEffectFactory());
+ ((TopRoundedCornerView) mContent).createEdgeEffectFactory());
// Recycler view binds to fast scroller when it is attached to screen. Make sure
// search recycler view is bound to fast scroller if user is in search mode at the time
// of attachment.
if (mAdapterType == PRIMARY || mAdapterType == WORK) {
mWidgetsRecyclerView.addOnAttachStateChangeListener(mBindScrollbarInSearchMode);
}
+ mWidgetsListAdapter.setApplyBitmapDeferred(false, mWidgetsRecyclerView);
mWidgetsListAdapter.setMaxHorizontalSpansPerRow(mMaxSpansPerRow);
}
}
+
+ final class SearchAndRecommendationViewHolder {
+ final SearchAndRecommendationsView mContainer;
+ final View mCollapseHandle;
+ final View mSearchBarContainer;
+ final WidgetsSearchBar mSearchBar;
+ final TextView mHeaderTitle;
+ final WidgetsRecommendationTableLayout mRecommendedWidgetsTable;
+
+ SearchAndRecommendationViewHolder(
+ SearchAndRecommendationsView searchAndRecommendationContainer) {
+ mContainer = searchAndRecommendationContainer;
+ mCollapseHandle = mContainer.findViewById(R.id.collapse_handle);
+ mSearchBarContainer = mContainer.findViewById(R.id.search_bar_container);
+ mSearchBar = mContainer.findViewById(R.id.widgets_search_bar);
+ mHeaderTitle = mContainer.findViewById(R.id.title);
+ mRecommendedWidgetsTable = mContainer.findViewById(R.id.recommended_widget_table);
+ mRecommendedWidgetsTable.setWidgetCellOnTouchListener((view, event) -> {
+ getRecyclerView().onTouchEvent(event);
+ return false;
+ });
+ mRecommendedWidgetsTable.setWidgetCellLongClickListener(WidgetsFullSheet.this);
+ mRecommendedWidgetsTable.setWidgetCellOnClickListener(WidgetsFullSheet.this);
+ }
+ }
}
diff --git a/src/com/android/launcher3/widget/picker/WidgetsListAdapter.java b/src/com/android/launcher3/widget/picker/WidgetsListAdapter.java
index 0e5a7d7ba9..1125b82150 100644
--- a/src/com/android/launcher3/widget/picker/WidgetsListAdapter.java
+++ b/src/com/android/launcher3/widget/picker/WidgetsListAdapter.java
@@ -16,20 +16,19 @@
package com.android.launcher3.widget.picker;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_WIDGETSTRAY_APP_EXPANDED;
-import static com.android.launcher3.recyclerview.ViewHolderBinder.POSITION_DEFAULT;
-import static com.android.launcher3.recyclerview.ViewHolderBinder.POSITION_FIRST;
-import static com.android.launcher3.recyclerview.ViewHolderBinder.POSITION_LAST;
import android.content.Context;
import android.graphics.Rect;
import android.os.Process;
import android.util.Log;
+import android.util.Size;
import android.util.SparseArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnLongClickListener;
import android.view.ViewGroup;
+import android.widget.TableRow;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@@ -39,27 +38,32 @@ import androidx.recyclerview.widget.RecyclerView.Adapter;
import androidx.recyclerview.widget.RecyclerView.LayoutParams;
import androidx.recyclerview.widget.RecyclerView.ViewHolder;
+import com.android.launcher3.BaseActivity;
+import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.Launcher;
import com.android.launcher3.R;
import com.android.launcher3.icons.IconCache;
+import com.android.launcher3.model.WidgetItem;
import com.android.launcher3.model.data.PackageItemInfo;
import com.android.launcher3.recyclerview.ViewHolderBinder;
import com.android.launcher3.util.LabelComparator;
import com.android.launcher3.util.PackageUserKey;
-import com.android.launcher3.views.ActivityContext;
-import com.android.launcher3.widget.model.WidgetListSpaceEntry;
+import com.android.launcher3.widget.CachingWidgetPreviewLoader;
+import com.android.launcher3.widget.DatabaseWidgetPreviewLoader;
+import com.android.launcher3.widget.WidgetCell;
+import com.android.launcher3.widget.WidgetPreviewLoader.WidgetPreviewLoadedCallback;
import com.android.launcher3.widget.model.WidgetsListBaseEntry;
import com.android.launcher3.widget.model.WidgetsListContentEntry;
import com.android.launcher3.widget.model.WidgetsListHeaderEntry;
import com.android.launcher3.widget.model.WidgetsListSearchHeaderEntry;
+import com.android.launcher3.widget.util.WidgetSizes;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.OptionalInt;
-import java.util.function.IntSupplier;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
@@ -80,59 +84,67 @@ public class WidgetsListAdapter extends Adapter<ViewHolder> implements OnHeaderC
private static final boolean DEBUG = false;
/** Uniquely identifies widgets list view type within the app. */
- private static final int VIEW_TYPE_WIDGETS_SPACE = R.id.view_type_widgets_space;
private static final int VIEW_TYPE_WIDGETS_LIST = R.id.view_type_widgets_list;
private static final int VIEW_TYPE_WIDGETS_HEADER = R.id.view_type_widgets_header;
private static final int VIEW_TYPE_WIDGETS_SEARCH_HEADER = R.id.view_type_widgets_search_header;
private final Context mContext;
+ private final Launcher mLauncher;
+ private final CachingWidgetPreviewLoader mCachingPreviewLoader;
private final WidgetsDiffReporter mDiffReporter;
private final SparseArray<ViewHolderBinder> mViewHolderBinders = new SparseArray<>();
+ private final WidgetsListTableViewHolderBinder mWidgetsListTableViewHolderBinder;
private final WidgetListBaseRowEntryComparator mRowComparator =
new WidgetListBaseRowEntryComparator();
- private final List<WidgetsListBaseEntry> mAllEntries = new ArrayList<>();
+ private List<WidgetsListBaseEntry> mAllEntries = new ArrayList<>();
private ArrayList<WidgetsListBaseEntry> mVisibleEntries = new ArrayList<>();
@Nullable private PackageUserKey mWidgetsContentVisiblePackageUserKey = null;
private Predicate<WidgetsListBaseEntry> mHeaderAndSelectedContentFilter = entry ->
entry instanceof WidgetsListHeaderEntry
|| entry instanceof WidgetsListSearchHeaderEntry
- || PackageUserKey.fromPackageItemInfo(entry.mPkgItem)
+ || new PackageUserKey(entry.mPkgItem.packageName, entry.mPkgItem.user)
.equals(mWidgetsContentVisiblePackageUserKey);
@Nullable private Predicate<WidgetsListBaseEntry> mFilter = null;
@Nullable private RecyclerView mRecyclerView;
@Nullable private PackageUserKey mPendingClickHeader;
+ private final int mShortcutPreviewPadding;
private final int mSpacingBetweenEntries;
private int mMaxSpanSize = 4;
+ private final WidgetPreviewLoadedCallback mPreviewLoadedCallback =
+ ignored -> updateVisibleEntries();
+
public WidgetsListAdapter(Context context, LayoutInflater layoutInflater,
- IconCache iconCache, IntSupplier emptySpaceHeightProvider,
+ DatabaseWidgetPreviewLoader widgetPreviewLoader, IconCache iconCache,
OnClickListener iconClickListener, OnLongClickListener iconLongClickListener) {
mContext = context;
+ mLauncher = Launcher.getLauncher(context);
+ mCachingPreviewLoader = new CachingWidgetPreviewLoader(widgetPreviewLoader);
mDiffReporter = new WidgetsDiffReporter(iconCache, this);
WidgetsListDrawableFactory listDrawableFactory = new WidgetsListDrawableFactory(context);
-
- mViewHolderBinders.put(
- VIEW_TYPE_WIDGETS_LIST,
- new WidgetsListTableViewHolderBinder(
- layoutInflater, iconClickListener, iconLongClickListener,
- listDrawableFactory));
+ mWidgetsListTableViewHolderBinder = new WidgetsListTableViewHolderBinder(
+ layoutInflater, iconClickListener, iconLongClickListener,
+ mCachingPreviewLoader, listDrawableFactory, /* listAdapter= */ this);
+ mViewHolderBinders.put(VIEW_TYPE_WIDGETS_LIST, mWidgetsListTableViewHolderBinder);
mViewHolderBinders.put(
VIEW_TYPE_WIDGETS_HEADER,
new WidgetsListHeaderViewHolderBinder(
layoutInflater,
/* onHeaderClickListener= */ this,
- listDrawableFactory));
+ listDrawableFactory,
+ /* listAdapter= */ this));
mViewHolderBinders.put(
VIEW_TYPE_WIDGETS_SEARCH_HEADER,
new WidgetsListSearchHeaderViewHolderBinder(
layoutInflater,
/* onHeaderClickListener= */ this,
- listDrawableFactory));
- mViewHolderBinders.put(
- VIEW_TYPE_WIDGETS_SPACE,
- new WidgetsSpaceViewHolderBinder(emptySpaceHeightProvider));
+ listDrawableFactory,
+ /* listAdapter= */ this));
+ mShortcutPreviewPadding =
+ 2 * context.getResources()
+ .getDimensionPixelSize(R.dimen.widget_preview_shortcut_padding);
mSpacingBetweenEntries =
context.getResources().getDimensionPixelSize(R.dimen.widget_list_entry_spacing);
}
@@ -166,19 +178,33 @@ public class WidgetsListAdapter extends Adapter<ViewHolder> implements OnHeaderC
mFilter = filter;
}
+ /**
+ * Defers applying bitmap on all the {@link WidgetCell} in the {@param rv}.
+ *
+ * @see WidgetCell#setApplyBitmapDeferred(boolean)
+ */
+ public void setApplyBitmapDeferred(boolean isDeferred, RecyclerView rv) {
+ mWidgetsListTableViewHolderBinder.setApplyBitmapDeferred(isDeferred);
+
+ for (int i = rv.getChildCount() - 1; i >= 0; i--) {
+ ViewHolder viewHolder = rv.getChildViewHolder(rv.getChildAt(i));
+ if (viewHolder.getItemViewType() == VIEW_TYPE_WIDGETS_LIST) {
+ WidgetsRowViewHolder holder = (WidgetsRowViewHolder) viewHolder;
+ for (int j = holder.mTableContainer.getChildCount() - 1; j >= 0; j--) {
+ TableRow row = (TableRow) holder.mTableContainer.getChildAt(j);
+ for (int k = row.getChildCount() - 1; k >= 0; k--) {
+ ((WidgetCell) row.getChildAt(k)).setApplyBitmapDeferred(isDeferred);
+ }
+ }
+ }
+ }
+ }
+
@Override
public int getItemCount() {
return mVisibleEntries.size();
}
- /**
- * Returns true if the adapter has entries which will be visible to the user
- */
- public boolean hasVisibleEntries() {
- // Account for the 1st space entry
- return getItemCount() > 1;
- }
-
/** Returns all items that will be drawn in a recycler view. */
public List<WidgetsListBaseEntry> getItems() {
return mVisibleEntries;
@@ -191,9 +217,9 @@ public class WidgetsListAdapter extends Adapter<ViewHolder> implements OnHeaderC
/** Updates the widget list based on {@code tempEntries}. */
public void setWidgets(List<WidgetsListBaseEntry> tempEntries) {
- mAllEntries.clear();
- mAllEntries.add(new WidgetListSpaceEntry());
- tempEntries.stream().sorted(mRowComparator).forEach(mAllEntries::add);
+ mCachingPreviewLoader.clearAll();
+ mAllEntries = tempEntries.stream().sorted(mRowComparator)
+ .collect(Collectors.toList());
if (shouldClearVisibleEntries()) {
mVisibleEntries.clear();
}
@@ -204,10 +230,15 @@ public class WidgetsListAdapter extends Adapter<ViewHolder> implements OnHeaderC
public void setWidgetsOnSearch(List<WidgetsListBaseEntry> searchResults) {
// Forget the expanded package every time widget list is refreshed in search mode.
mWidgetsContentVisiblePackageUserKey = null;
+ cancelLoadingPreviews();
setWidgets(searchResults);
}
private void updateVisibleEntries() {
+ // If not all previews are ready, then defer this update and try again after the preview
+ // loads.
+ if (!ensureAllPreviewsReady()) return;
+
// Get the current top of the header with the matching key before adjusting the visible
// entries.
OptionalInt previousPositionForPackageUserKey =
@@ -216,9 +247,8 @@ public class WidgetsListAdapter extends Adapter<ViewHolder> implements OnHeaderC
getOffsetForPosition(previousPositionForPackageUserKey);
List<WidgetsListBaseEntry> newVisibleEntries = mAllEntries.stream()
- .filter(entry -> ((mFilter == null || mFilter.test(entry))
+ .filter(entry -> (mFilter == null || mFilter.test(entry))
&& mHeaderAndSelectedContentFilter.test(entry))
- || entry instanceof WidgetListSpaceEntry)
.map(entry -> {
if (entry instanceof WidgetsListBaseEntry.Header<?>
&& matchesKey(entry, mWidgetsContentVisiblePackageUserKey)) {
@@ -245,6 +275,54 @@ public class WidgetsListAdapter extends Adapter<ViewHolder> implements OnHeaderC
}
}
+ /**
+ * Checks that all preview images are loaded and starts loading for those that aren't ready.
+ *
+ * @return true if all previews are ready and the data can be updated, false otherwise.
+ */
+ private boolean ensureAllPreviewsReady() {
+ boolean allReady = true;
+ BaseActivity activity = BaseActivity.fromContext(mContext);
+ for (WidgetsListBaseEntry entry : mAllEntries) {
+ if (!(entry instanceof WidgetsListContentEntry)) continue;
+
+ WidgetsListContentEntry contentEntry = (WidgetsListContentEntry) entry;
+ if (!matchesKey(entry, mWidgetsContentVisiblePackageUserKey)) {
+ // If the entry isn't visible, clear any loaded previews.
+ mCachingPreviewLoader.clearPreviews(contentEntry.mWidgets);
+ continue;
+ }
+
+ for (int i = 0; i < entry.mWidgets.size(); i++) {
+ WidgetItem widgetItem = entry.mWidgets.get(i);
+ DeviceProfile deviceProfile = activity.getDeviceProfile();
+ Size widgetSize = WidgetSizes.getWidgetItemSizePx(mContext, deviceProfile,
+ widgetItem);
+ if (widgetItem.isShortcut()) {
+ widgetSize =
+ new Size(
+ widgetSize.getWidth() + mShortcutPreviewPadding,
+ widgetSize.getHeight() + mShortcutPreviewPadding);
+ }
+
+ if (widgetItem.hasPreviewLayout()
+ || mCachingPreviewLoader.isPreviewLoaded(widgetItem, widgetSize)) {
+ // The widget is ready if it can be rendered with a preview layout or if its
+ // preview bitmap is in the cache.
+ continue;
+ }
+
+ // If we've reached this point, we should load the preview for the widget.
+ allReady = false;
+ mCachingPreviewLoader.loadPreview(
+ activity,
+ widgetItem,
+ widgetSize,
+ mPreviewLoadedCallback);
+ }
+ }
+ return allReady;
+ }
/** Returns whether {@code entry} matches {@code key}. */
private static boolean isHeaderForPackageUserKey(
@@ -252,11 +330,10 @@ public class WidgetsListAdapter extends Adapter<ViewHolder> implements OnHeaderC
return entry instanceof WidgetsListBaseEntry.Header && matchesKey(entry, key);
}
- private static boolean matchesKey(@NonNull WidgetsListBaseEntry entry,
- @Nullable PackageUserKey key) {
+ private static boolean matchesKey(
+ @NonNull WidgetsListBaseEntry entry, @Nullable PackageUserKey key) {
if (key == null) return false;
return entry.mPkgItem.packageName.equals(key.mPackageName)
- && entry.mPkgItem.widgetCategory == key.mWidgetCategory
&& entry.mPkgItem.user.equals(key.mUser);
}
@@ -266,26 +343,16 @@ public class WidgetsListAdapter extends Adapter<ViewHolder> implements OnHeaderC
public void resetExpandedHeader() {
if (mWidgetsContentVisiblePackageUserKey != null) {
mWidgetsContentVisiblePackageUserKey = null;
+ cancelLoadingPreviews();
updateVisibleEntries();
}
}
@Override
- public void onBindViewHolder(ViewHolder holder, int position) {
- onBindViewHolder(holder, position, Collections.EMPTY_LIST);
- }
-
- @Override
- public void onBindViewHolder(ViewHolder holder, int pos, List<Object> payloads) {
+ public void onBindViewHolder(ViewHolder holder, int pos) {
ViewHolderBinder viewHolderBinder = mViewHolderBinders.get(getItemViewType(pos));
WidgetsListBaseEntry entry = mVisibleEntries.get(pos);
-
- // The first entry has an empty space, count from second entries.
- int listPos = (pos > 1) ? POSITION_DEFAULT : POSITION_FIRST;
- if (pos == (getItemCount() - 1)) {
- listPos |= POSITION_LAST;
- }
- viewHolderBinder.bindViewHolder(holder, mVisibleEntries.get(pos), listPos, payloads);
+ viewHolderBinder.bindViewHolder(holder, mVisibleEntries.get(pos), pos);
holder.itemView.setTag(R.id.tag_widget_entry, entry);
}
@@ -328,8 +395,6 @@ public class WidgetsListAdapter extends Adapter<ViewHolder> implements OnHeaderC
return VIEW_TYPE_WIDGETS_HEADER;
} else if (entry instanceof WidgetsListSearchHeaderEntry) {
return VIEW_TYPE_WIDGETS_SEARCH_HEADER;
- } else if (entry instanceof WidgetListSpaceEntry) {
- return VIEW_TYPE_WIDGETS_SPACE;
}
throw new UnsupportedOperationException("ViewHolderBinder not found for " + entry);
}
@@ -339,10 +404,11 @@ public class WidgetsListAdapter extends Adapter<ViewHolder> implements OnHeaderC
// Ignore invalid clicks, such as collapsing a package that isn't currently expanded.
if (!showWidgets && !packageUserKey.equals(mWidgetsContentVisiblePackageUserKey)) return;
+ cancelLoadingPreviews();
+
if (showWidgets) {
mWidgetsContentVisiblePackageUserKey = packageUserKey;
- ActivityContext.lookupContext(mContext)
- .getStatsLogManager().logger().log(LAUNCHER_WIDGETSTRAY_APP_EXPANDED);
+ mLauncher.getStatsLogManager().logger().log(LAUNCHER_WIDGETSTRAY_APP_EXPANDED);
} else {
mWidgetsContentVisiblePackageUserKey = null;
}
@@ -354,6 +420,16 @@ public class WidgetsListAdapter extends Adapter<ViewHolder> implements OnHeaderC
updateVisibleEntries();
}
+ private void cancelLoadingPreviews() {
+ mCachingPreviewLoader.clearAll();
+ }
+
+ /** Returns the position of the currently expanded header, or empty if it's not present. */
+ public OptionalInt getSelectedHeaderPosition() {
+ if (mWidgetsContentVisiblePackageUserKey == null) return OptionalInt.empty();
+ return getPositionForPackageUserKey(mWidgetsContentVisiblePackageUserKey);
+ }
+
/**
* Returns the position of {@code key} in {@link #mVisibleEntries}, or empty if it's not
* present.
@@ -435,10 +511,11 @@ public class WidgetsListAdapter extends Adapter<ViewHolder> implements OnHeaderC
.filter(entry -> entry instanceof WidgetsListHeaderEntry)
.map(entry -> entry.mPkgItem)
.collect(Collectors.toMap(
- entry -> PackageUserKey.fromPackageItemInfo(entry),
+ entry -> new PackageUserKey(entry.packageName, entry.user),
entry -> entry));
for (WidgetsListBaseEntry visibleEntry: mVisibleEntries) {
- PackageUserKey key = PackageUserKey.fromPackageItemInfo(visibleEntry.mPkgItem);
+ PackageUserKey key = new PackageUserKey(visibleEntry.mPkgItem.packageName,
+ visibleEntry.mPkgItem.user);
PackageItemInfo packageItemInfo = packagesInfo.get(key);
if (packageItemInfo != null
&& !visibleEntry.mPkgItem.title.equals(packageItemInfo.title)) {
diff --git a/src/com/android/launcher3/widget/picker/WidgetsListHeader.java b/src/com/android/launcher3/widget/picker/WidgetsListHeader.java
index 48df04fc85..ef2adbb809 100644
--- a/src/com/android/launcher3/widget/picker/WidgetsListHeader.java
+++ b/src/com/android/launcher3/widget/picker/WidgetsListHeader.java
@@ -15,7 +15,6 @@
*/
package com.android.launcher3.widget.picker;
-
import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
@@ -40,7 +39,6 @@ import com.android.launcher3.icons.PlaceHolderIconDrawable;
import com.android.launcher3.icons.cache.HandlerRunnable;
import com.android.launcher3.model.data.ItemInfoWithIcon;
import com.android.launcher3.model.data.PackageItemInfo;
-import com.android.launcher3.util.PluralMessageFormat;
import com.android.launcher3.views.ActivityContext;
import com.android.launcher3.widget.model.WidgetsListHeaderEntry;
import com.android.launcher3.widget.model.WidgetsListSearchHeaderEntry;
@@ -95,7 +93,7 @@ public final class WidgetsListHeader extends LinearLayout implements ItemInfoUpd
mTitle = findViewById(R.id.app_title);
mSubtitle = findViewById(R.id.app_subtitle);
mExpandToggle = findViewById(R.id.toggle);
- setAccessibilityDelegate(new AccessibilityDelegate() {
+ findViewById(R.id.app_container).setAccessibilityDelegate(new AccessibilityDelegate() {
@Override
public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) {
@@ -174,7 +172,13 @@ public final class WidgetsListHeader extends LinearLayout implements ItemInfoUpd
private void setIcon(PackageItemInfo info) {
Drawable icon;
- icon = info.newIcon(getContext());
+ switch (info.category) {
+ case PackageItemInfo.CONVERSATIONS:
+ icon = getContext().getDrawable(R.drawable.ic_conversations_widget_category);
+ break;
+ default:
+ icon = info.newIcon(getContext());
+ }
applyDrawables(icon);
mIconDrawable = icon;
if (mIconDrawable != null) {
@@ -213,18 +217,18 @@ public final class WidgetsListHeader extends LinearLayout implements ItemInfoUpd
String subtitle;
if (entry.widgetsCount > 0 && entry.shortcutsCount > 0) {
- String widgetsCount = PluralMessageFormat.getIcuPluralString(getContext(),
- R.string.widgets_count, entry.widgetsCount);
- String shortcutsCount = PluralMessageFormat.getIcuPluralString(getContext(),
- R.string.shortcuts_count, entry.shortcutsCount);
+ String widgetsCount = resources.getQuantityString(R.plurals.widgets_count,
+ entry.widgetsCount, entry.widgetsCount);
+ String shortcutsCount = resources.getQuantityString(R.plurals.shortcuts_count,
+ entry.shortcutsCount, entry.shortcutsCount);
subtitle = resources.getString(R.string.widgets_and_shortcuts_count, widgetsCount,
shortcutsCount);
} else if (entry.widgetsCount > 0) {
- subtitle = PluralMessageFormat.getIcuPluralString(getContext(),
- R.string.widgets_count, entry.widgetsCount);
+ subtitle = resources.getQuantityString(R.plurals.widgets_count,
+ entry.widgetsCount, entry.widgetsCount);
} else {
- subtitle = PluralMessageFormat.getIcuPluralString(getContext(),
- R.string.shortcuts_count, entry.shortcutsCount);
+ subtitle = resources.getQuantityString(R.plurals.shortcuts_count,
+ entry.shortcutsCount, entry.shortcutsCount);
}
mSubtitle.setText(subtitle);
mSubtitle.setVisibility(VISIBLE);
diff --git a/src/com/android/launcher3/widget/picker/WidgetsListHeaderViewHolderBinder.java b/src/com/android/launcher3/widget/picker/WidgetsListHeaderViewHolderBinder.java
index c6a72855c7..2f8f1bacfc 100644
--- a/src/com/android/launcher3/widget/picker/WidgetsListHeaderViewHolderBinder.java
+++ b/src/com/android/launcher3/widget/picker/WidgetsListHeaderViewHolderBinder.java
@@ -23,8 +23,6 @@ import com.android.launcher3.recyclerview.ViewHolderBinder;
import com.android.launcher3.util.PackageUserKey;
import com.android.launcher3.widget.model.WidgetsListHeaderEntry;
-import java.util.List;
-
/**
* Binds data from {@link WidgetsListHeaderEntry} to UI elements in {@link WidgetsListHeaderHolder}.
*/
@@ -33,13 +31,16 @@ public final class WidgetsListHeaderViewHolderBinder implements
private final LayoutInflater mLayoutInflater;
private final OnHeaderClickListener mOnHeaderClickListener;
private final WidgetsListDrawableFactory mListDrawableFactory;
+ private final WidgetsListAdapter mWidgetsListAdapter;
public WidgetsListHeaderViewHolderBinder(LayoutInflater layoutInflater,
OnHeaderClickListener onHeaderClickListener,
- WidgetsListDrawableFactory listDrawableFactory) {
+ WidgetsListDrawableFactory listDrawableFactory,
+ WidgetsListAdapter listAdapter) {
mLayoutInflater = layoutInflater;
mOnHeaderClickListener = onHeaderClickListener;
mListDrawableFactory = listDrawableFactory;
+ mWidgetsListAdapter = listAdapter;
}
@Override
@@ -52,17 +53,19 @@ public final class WidgetsListHeaderViewHolderBinder implements
@Override
public void bindViewHolder(WidgetsListHeaderHolder viewHolder, WidgetsListHeaderEntry data,
- @ListPosition int position, List<Object> payloads) {
+ int position) {
WidgetsListHeader widgetsListHeader = viewHolder.mWidgetsListHeader;
widgetsListHeader.applyFromItemInfoWithIcon(data);
widgetsListHeader.setExpanded(data.isWidgetListShown());
widgetsListHeader.setListDrawableState(
WidgetsListDrawableState.obtain(
- (position & POSITION_FIRST) != 0,
- (position & POSITION_LAST) != 0,
+ /* isFirst= */ position == 0,
+ /* isLast= */ position == mWidgetsListAdapter.getItemCount() - 1,
/* isExpanded= */ data.isWidgetListShown()));
widgetsListHeader.setOnExpandChangeListener(isExpanded ->
- mOnHeaderClickListener.onHeaderClicked(isExpanded,
- PackageUserKey.fromPackageItemInfo(data.mPkgItem)));
+ mOnHeaderClickListener.onHeaderClicked(
+ isExpanded,
+ new PackageUserKey(data.mPkgItem.packageName, data.mPkgItem.user)
+ ));
}
}
diff --git a/src/com/android/launcher3/widget/picker/WidgetsListLayoutManager.java b/src/com/android/launcher3/widget/picker/WidgetsListLayoutManager.java
new file mode 100644
index 0000000000..2b7f544c56
--- /dev/null
+++ b/src/com/android/launcher3/widget/picker/WidgetsListLayoutManager.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2021 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.launcher3.widget.picker;
+
+import android.content.Context;
+
+import androidx.annotation.Nullable;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.android.launcher3.widget.picker.SearchAndRecommendationsScrollController.OnContentChangeListener;
+
+/**
+ * A layout manager for the {@link WidgetsRecyclerView}.
+ *
+ * {@link #setOnContentChangeListener(OnContentChangeListener)} can be used to register a callback
+ * for when the content of the layout manager has changed, following measurement and animation.
+ */
+public final class WidgetsListLayoutManager extends LinearLayoutManager {
+ @Nullable
+ private OnContentChangeListener mOnContentChangeListener;
+
+ public WidgetsListLayoutManager(Context context) {
+ super(context);
+ }
+
+ @Override
+ public void onLayoutCompleted(RecyclerView.State state) {
+ super.onLayoutCompleted(state);
+ if (mOnContentChangeListener != null) {
+ mOnContentChangeListener.onContentChanged();
+ }
+ }
+
+ public void setOnContentChangeListener(@Nullable OnContentChangeListener listener) {
+ mOnContentChangeListener = listener;
+ }
+}
diff --git a/src/com/android/launcher3/widget/picker/WidgetsListSearchHeaderViewHolderBinder.java b/src/com/android/launcher3/widget/picker/WidgetsListSearchHeaderViewHolderBinder.java
index 2b27fc266a..31dd9ee0ae 100644
--- a/src/com/android/launcher3/widget/picker/WidgetsListSearchHeaderViewHolderBinder.java
+++ b/src/com/android/launcher3/widget/picker/WidgetsListSearchHeaderViewHolderBinder.java
@@ -24,8 +24,6 @@ import com.android.launcher3.util.PackageUserKey;
import com.android.launcher3.widget.model.WidgetsListHeaderEntry;
import com.android.launcher3.widget.model.WidgetsListSearchHeaderEntry;
-import java.util.List;
-
/**
* Binds data from {@link WidgetsListHeaderEntry} to UI elements in {@link WidgetsListHeaderHolder}.
*/
@@ -34,13 +32,16 @@ public final class WidgetsListSearchHeaderViewHolderBinder implements
private final LayoutInflater mLayoutInflater;
private final OnHeaderClickListener mOnHeaderClickListener;
private final WidgetsListDrawableFactory mListDrawableFactory;
+ private final WidgetsListAdapter mWidgetsListAdapter;
public WidgetsListSearchHeaderViewHolderBinder(LayoutInflater layoutInflater,
OnHeaderClickListener onHeaderClickListener,
- WidgetsListDrawableFactory listDrawableFactory) {
+ WidgetsListDrawableFactory listDrawableFactory,
+ WidgetsListAdapter listAdapter) {
mLayoutInflater = layoutInflater;
mOnHeaderClickListener = onHeaderClickListener;
mListDrawableFactory = listDrawableFactory;
+ mWidgetsListAdapter = listAdapter;
}
@Override
@@ -53,17 +54,17 @@ public final class WidgetsListSearchHeaderViewHolderBinder implements
@Override
public void bindViewHolder(WidgetsListSearchHeaderHolder viewHolder,
- WidgetsListSearchHeaderEntry data, @ListPosition int position, List<Object> payloads) {
+ WidgetsListSearchHeaderEntry data, int position) {
WidgetsListHeader widgetsListHeader = viewHolder.mWidgetsListHeader;
widgetsListHeader.applyFromItemInfoWithIcon(data);
widgetsListHeader.setExpanded(data.isWidgetListShown());
widgetsListHeader.setListDrawableState(
WidgetsListDrawableState.obtain(
- (position & POSITION_FIRST) != 0,
- (position & POSITION_LAST) != 0,
+ /* isFirst= */ position == 0,
+ /* isLast= */ position == mWidgetsListAdapter.getItemCount() - 1,
/* isExpanded= */ data.isWidgetListShown()));
widgetsListHeader.setOnExpandChangeListener(isExpanded ->
mOnHeaderClickListener.onHeaderClicked(isExpanded,
- PackageUserKey.fromPackageItemInfo(data.mPkgItem)));
+ new PackageUserKey(data.mPkgItem.packageName, data.mPkgItem.user)));
}
}
diff --git a/src/com/android/launcher3/widget/picker/WidgetsListTableViewHolderBinder.java b/src/com/android/launcher3/widget/picker/WidgetsListTableViewHolderBinder.java
index 05e26adacf..9c06558b5c 100644
--- a/src/com/android/launcher3/widget/picker/WidgetsListTableViewHolderBinder.java
+++ b/src/com/android/launcher3/widget/picker/WidgetsListTableViewHolderBinder.java
@@ -20,7 +20,7 @@ import static com.android.launcher3.widget.picker.WidgetsListDrawableState.MIDDL
import android.graphics.Bitmap;
import android.util.Log;
-import android.util.Pair;
+import android.util.Size;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
@@ -33,6 +33,7 @@ import android.widget.TableRow;
import com.android.launcher3.R;
import com.android.launcher3.model.WidgetItem;
import com.android.launcher3.recyclerview.ViewHolderBinder;
+import com.android.launcher3.widget.CachingWidgetPreviewLoader;
import com.android.launcher3.widget.WidgetCell;
import com.android.launcher3.widget.model.WidgetsListContentEntry;
import com.android.launcher3.widget.util.WidgetsTableUtils;
@@ -52,16 +53,32 @@ public final class WidgetsListTableViewHolderBinder
private final OnClickListener mIconClickListener;
private final OnLongClickListener mIconLongClickListener;
private final WidgetsListDrawableFactory mListDrawableFactory;
+ private final CachingWidgetPreviewLoader mWidgetPreviewLoader;
+ private final WidgetsListAdapter mWidgetsListAdapter;
+ private boolean mApplyBitmapDeferred = false;
public WidgetsListTableViewHolderBinder(
LayoutInflater layoutInflater,
OnClickListener iconClickListener,
OnLongClickListener iconLongClickListener,
- WidgetsListDrawableFactory listDrawableFactory) {
+ CachingWidgetPreviewLoader widgetPreviewLoader,
+ WidgetsListDrawableFactory listDrawableFactory,
+ WidgetsListAdapter listAdapter) {
mLayoutInflater = layoutInflater;
mIconClickListener = iconClickListener;
mIconLongClickListener = iconLongClickListener;
+ mWidgetPreviewLoader = widgetPreviewLoader;
mListDrawableFactory = listDrawableFactory;
+ mWidgetsListAdapter = listAdapter;
+ }
+
+ /**
+ * Defers applying bitmap on all the {@link WidgetCell} at
+ * {@link #bindViewHolder(WidgetsRowViewHolder, WidgetsListContentEntry, int)} if
+ * {@code applyBitmapDeferred} is {@code true}.
+ */
+ public void setApplyBitmapDeferred(boolean applyBitmapDeferred) {
+ mApplyBitmapDeferred = applyBitmapDeferred;
}
@Override
@@ -73,30 +90,27 @@ public final class WidgetsListTableViewHolderBinder
WidgetsRowViewHolder viewHolder =
new WidgetsRowViewHolder(mLayoutInflater.inflate(
R.layout.widgets_table_container, parent, false));
- viewHolder.tableContainer.setBackgroundDrawable(
+ viewHolder.mTableContainer.setBackgroundDrawable(
mListDrawableFactory.createContentBackgroundDrawable());
return viewHolder;
}
@Override
public void bindViewHolder(WidgetsRowViewHolder holder, WidgetsListContentEntry entry,
- @ListPosition int position, List<Object> payloads) {
- for (Object payload : payloads) {
- Pair<WidgetItem, Bitmap> pair = (Pair) payload;
- holder.previewCache.put(pair.first, pair.second);
- }
-
- WidgetsListTableView table = holder.tableContainer;
+ int position) {
+ WidgetsListTableView table = holder.mTableContainer;
if (DEBUG) {
Log.d(TAG, String.format("onBindViewHolder [widget#=%d, table.getChildCount=%d]",
entry.mWidgets.size(), table.getChildCount()));
}
- table.setListDrawableState(((position & POSITION_LAST) != 0) ? LAST : MIDDLE);
+
+ table.setListDrawableState(
+ position == mWidgetsListAdapter.getItemCount() - 1 ? LAST : MIDDLE);
+
List<ArrayList<WidgetItem>> widgetItemsTable =
- WidgetsTableUtils.groupWidgetItemsIntoTableWithReordering(
+ WidgetsTableUtils.groupWidgetItemsIntoTable(
entry.mWidgets, entry.getMaxSpanSizeInCells());
recycleTableBeforeBinding(table, widgetItemsTable);
-
// Bind the widget items.
for (int i = 0; i < widgetItemsTable.size(); i++) {
List<WidgetItem> widgetItemsPerRow = widgetItemsTable.get(i);
@@ -106,17 +120,16 @@ public final class WidgetsListTableViewHolderBinder
WidgetCell widget = (WidgetCell) row.getChildAt(j);
widget.clear();
WidgetItem widgetItem = widgetItemsPerRow.get(j);
+ Size previewSize = widget.setPreviewSize(widgetItem);
+ widget.applyFromCellItem(widgetItem, mWidgetPreviewLoader);
+ widget.setApplyBitmapDeferred(mApplyBitmapDeferred);
+ Bitmap preview = mWidgetPreviewLoader.getPreview(widgetItem, previewSize);
+ if (preview == null) {
+ widget.ensurePreview();
+ } else {
+ widget.applyPreview(preview);
+ }
widget.setVisibility(View.VISIBLE);
-
- // When preview loads, notify adapter to rebind the item and possibly animate
- widget.applyFromCellItem(widgetItem, 1f,
- bitmap -> {
- if (holder.getBindingAdapter() != null) {
- holder.getBindingAdapter().notifyItemChanged(
- holder.getBindingAdapterPosition(),
- Pair.create(widgetItem, bitmap));
- }
- }, holder.previewCache.get(widgetItem));
}
}
}
@@ -157,7 +170,6 @@ public final class WidgetsListTableViewHolderBinder
View preview = widget.findViewById(R.id.widget_preview_container);
preview.setOnClickListener(mIconClickListener);
preview.setOnLongClickListener(mIconLongClickListener);
- widget.setAnimatePreview(false);
tableRow.addView(widget);
}
}
@@ -166,10 +178,9 @@ public final class WidgetsListTableViewHolderBinder
@Override
public void unbindViewHolder(WidgetsRowViewHolder holder) {
- int numOfRows = holder.tableContainer.getChildCount();
- holder.previewCache.clear();
+ int numOfRows = holder.mTableContainer.getChildCount();
for (int i = 0; i < numOfRows; i++) {
- TableRow tableRow = (TableRow) holder.tableContainer.getChildAt(i);
+ TableRow tableRow = (TableRow) holder.mTableContainer.getChildAt(i);
int numOfCols = tableRow.getChildCount();
for (int j = 0; j < numOfCols; j++) {
WidgetCell widget = (WidgetCell) tableRow.getChildAt(j);
diff --git a/src/com/android/launcher3/widget/picker/WidgetsRecommendationTableLayout.java b/src/com/android/launcher3/widget/picker/WidgetsRecommendationTableLayout.java
index 06cc65e4c1..0b8ca3467c 100644
--- a/src/com/android/launcher3/widget/picker/WidgetsRecommendationTableLayout.java
+++ b/src/com/android/launcher3/widget/picker/WidgetsRecommendationTableLayout.java
@@ -32,6 +32,7 @@ import androidx.annotation.Nullable;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Launcher;
+import com.android.launcher3.LauncherAppState;
import com.android.launcher3.R;
import com.android.launcher3.model.WidgetItem;
import com.android.launcher3.widget.WidgetCell;
@@ -52,6 +53,7 @@ public final class WidgetsRecommendationTableLayout extends TableLayout {
private float mRecommendationTableMaxHeight = Float.MAX_VALUE;
@Nullable private OnLongClickListener mWidgetCellOnLongClickListener;
@Nullable private OnClickListener mWidgetCellOnClickListener;
+ @Nullable private OnTouchListener mWidgetCellOnTouchListener;
public WidgetsRecommendationTableLayout(Context context) {
this(context, /* attrs= */ null);
@@ -77,6 +79,11 @@ public final class WidgetsRecommendationTableLayout extends TableLayout {
mWidgetCellOnClickListener = widgetCellOnClickListener;
}
+ /** Sets a {@link android.view.View.OnTouchListener} for all widget cells in this table. */
+ public void setWidgetCellOnTouchListener(OnTouchListener widgetCellOnTouchListener) {
+ mWidgetCellOnTouchListener = widgetCellOnTouchListener;
+ }
+
/**
* Sets a list of recommended widgets that would like to be displayed in this table within the
* desired {@code recommendationTableMaxHeight}.
@@ -108,8 +115,10 @@ public final class WidgetsRecommendationTableLayout extends TableLayout {
for (WidgetItem widgetItem : widgetItems) {
WidgetCell widgetCell = addItemCell(tableRow);
- widgetCell.applyFromCellItem(widgetItem, data.mPreviewScale);
- widgetCell.showBadge();
+ widgetCell.setPreviewSize(widgetItem, data.mPreviewScale);
+ widgetCell.applyFromCellItem(widgetItem,
+ LauncherAppState.getInstance(getContext()).getWidgetCache());
+ widgetCell.ensurePreview();
}
addView(tableRow);
}
@@ -120,6 +129,7 @@ public final class WidgetsRecommendationTableLayout extends TableLayout {
WidgetCell widget = (WidgetCell) LayoutInflater.from(
getContext()).inflate(R.layout.widget_cell, parent, false);
+ widget.setOnTouchListener(mWidgetCellOnTouchListener);
View previewContainer = widget.findViewById(R.id.widget_preview_container);
previewContainer.setOnClickListener(mWidgetCellOnClickListener);
previewContainer.setOnLongClickListener(mWidgetCellOnLongClickListener);
diff --git a/src/com/android/launcher3/widget/picker/WidgetsRecyclerView.java b/src/com/android/launcher3/widget/picker/WidgetsRecyclerView.java
index bdf646bfaf..7671841878 100644
--- a/src/com/android/launcher3/widget/picker/WidgetsRecyclerView.java
+++ b/src/com/android/launcher3/widget/picker/WidgetsRecyclerView.java
@@ -23,25 +23,25 @@ import android.view.MotionEvent;
import android.view.View;
import android.widget.TableLayout;
+import androidx.annotation.Nullable;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.RecyclerView.OnItemTouchListener;
+import com.android.launcher3.BaseRecyclerView;
import com.android.launcher3.DeviceProfile;
-import com.android.launcher3.FastScrollRecyclerView;
import com.android.launcher3.R;
import com.android.launcher3.views.ActivityContext;
-import com.android.launcher3.widget.model.WidgetListSpaceEntry;
import com.android.launcher3.widget.model.WidgetsListBaseEntry;
import com.android.launcher3.widget.model.WidgetsListContentEntry;
import com.android.launcher3.widget.model.WidgetsListHeaderEntry;
import com.android.launcher3.widget.model.WidgetsListSearchHeaderEntry;
-import com.android.launcher3.widget.picker.WidgetsSpaceViewHolderBinder.EmptySpaceView;
+import com.android.launcher3.widget.picker.SearchAndRecommendationsScrollController.OnContentChangeListener;
/**
* The widgets recycler view.
*/
-public class WidgetsRecyclerView extends FastScrollRecyclerView implements OnItemTouchListener {
+public class WidgetsRecyclerView extends BaseRecyclerView implements OnItemTouchListener {
private WidgetsListAdapter mAdapter;
@@ -50,13 +50,10 @@ public class WidgetsRecyclerView extends FastScrollRecyclerView implements OnIte
private final Point mFastScrollerOffset = new Point();
private boolean mTouchDownOnScroller;
private HeaderViewDimensionsProvider mHeaderViewDimensionsProvider;
-
- // Cached sizes
private int mLastVisibleWidgetContentTableHeight = 0;
private int mWidgetHeaderHeight = 0;
- private int mWidgetEmptySpaceHeight = 0;
-
private final int mSpacingBetweenEntries;
+ @Nullable private OnContentChangeListener mOnContentChangeListener;
public WidgetsRecyclerView(Context context) {
this(context, null);
@@ -85,7 +82,9 @@ public class WidgetsRecyclerView extends FastScrollRecyclerView implements OnIte
super.onFinishInflate();
// create a layout manager with Launcher's context so that scroll position
// can be preserved during screen rotation.
- setLayoutManager(new LinearLayoutManager(getContext()));
+ WidgetsListLayoutManager layoutManager = new WidgetsListLayoutManager(getContext());
+ layoutManager.setOnContentChangeListener(mOnContentChangeListener);
+ setLayoutManager(layoutManager);
}
@Override
@@ -170,12 +169,10 @@ public class WidgetsRecyclerView extends FastScrollRecyclerView implements OnIte
// This assumes there is ever only one content shown in this recycler view.
mLastVisibleWidgetContentTableHeight = view.getMeasuredHeight();
} else if (view instanceof WidgetsListHeader
- && mWidgetHeaderHeight == 0
+ && mLastVisibleWidgetContentTableHeight == 0
&& view.getMeasuredHeight() > 0) {
// This assumes all header views are of the same height.
mWidgetHeaderHeight = view.getMeasuredHeight();
- } else if (view instanceof EmptySpaceView && view.getMeasuredHeight() > 0) {
- mWidgetEmptySpaceHeight = view.getMeasuredHeight();
}
}
@@ -239,6 +236,29 @@ public class WidgetsRecyclerView extends FastScrollRecyclerView implements OnIte
mHeaderViewDimensionsProvider = headerViewDimensionsProvider;
}
+ @Override
+ public void scrollToTop() {
+ if (mScrollbar != null) {
+ mScrollbar.reattachThumbToScroll();
+ }
+
+ if (getLayoutManager() instanceof LinearLayoutManager) {
+ if (getCurrentScrollY() == 0) {
+ // We are at the top, so don't scrollToPosition (would cause unnecessary relayout).
+ return;
+ }
+ }
+ scrollToPosition(0);
+ }
+
+ public void setOnContentChangeListener(@Nullable OnContentChangeListener listener) {
+ mOnContentChangeListener = listener;
+ WidgetsListLayoutManager layoutManager = (WidgetsListLayoutManager) getLayoutManager();
+ if (layoutManager != null) {
+ layoutManager.setOnContentChangeListener(listener);
+ }
+ }
+
/**
* Returns the sum of the height, in pixels, of this list adapter's items from index 0 until
* {@code untilIndex}.
@@ -263,8 +283,6 @@ public class WidgetsRecyclerView extends FastScrollRecyclerView implements OnIte
}
} else if (entry instanceof WidgetsListContentEntry) {
totalItemsHeight += mLastVisibleWidgetContentTableHeight;
- } else if (entry instanceof WidgetListSpaceEntry) {
- totalItemsHeight += mWidgetEmptySpaceHeight;
} else {
throw new UnsupportedOperationException("Can't estimate height for " + entry);
}
diff --git a/src/com/android/launcher3/widget/picker/WidgetsRowViewHolder.java b/src/com/android/launcher3/widget/picker/WidgetsRowViewHolder.java
index fe2d84bad4..618e2cbbd6 100644
--- a/src/com/android/launcher3/widget/picker/WidgetsRowViewHolder.java
+++ b/src/com/android/launcher3/widget/picker/WidgetsRowViewHolder.java
@@ -15,26 +15,20 @@
*/
package com.android.launcher3.widget.picker;
-import android.graphics.Bitmap;
import android.view.View;
import androidx.recyclerview.widget.RecyclerView.ViewHolder;
import com.android.launcher3.R;
-import com.android.launcher3.model.WidgetItem;
-
-import java.util.HashMap;
-import java.util.Map;
/** A {@link ViewHolder} for showing widgets of an app in the full widget picker. */
public final class WidgetsRowViewHolder extends ViewHolder {
- public final WidgetsListTableView tableContainer;
- public final Map<WidgetItem, Bitmap> previewCache = new HashMap<>();
+ public final WidgetsListTableView mTableContainer;
public WidgetsRowViewHolder(View v) {
super(v);
- tableContainer = v.findViewById(R.id.widgets_table);
+ mTableContainer = v.findViewById(R.id.widgets_table);
}
}
diff --git a/src/com/android/launcher3/widget/picker/WidgetsSpaceViewHolderBinder.java b/src/com/android/launcher3/widget/picker/WidgetsSpaceViewHolderBinder.java
deleted file mode 100644
index 1aa5753791..0000000000
--- a/src/com/android/launcher3/widget/picker/WidgetsSpaceViewHolderBinder.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright (C) 2021 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.launcher3.widget.picker;
-
-import static android.view.View.MeasureSpec.EXACTLY;
-import static android.view.View.MeasureSpec.makeMeasureSpec;
-
-import android.content.Context;
-import android.view.View;
-import android.view.ViewGroup;
-
-import androidx.recyclerview.widget.RecyclerView.ViewHolder;
-
-import com.android.launcher3.recyclerview.ViewHolderBinder;
-import com.android.launcher3.widget.model.WidgetListSpaceEntry;
-
-import java.util.List;
-import java.util.function.IntSupplier;
-
-/**
- * {@link ViewHolderBinder} for binding the top empty space
- */
-public class WidgetsSpaceViewHolderBinder
- implements ViewHolderBinder<WidgetListSpaceEntry, ViewHolder> {
-
- private final IntSupplier mEmptySpaceHeightProvider;
-
- public WidgetsSpaceViewHolderBinder(IntSupplier emptySpaceHeightProvider) {
- mEmptySpaceHeightProvider = emptySpaceHeightProvider;
- }
-
- @Override
- public ViewHolder newViewHolder(ViewGroup parent) {
- return new ViewHolder(new EmptySpaceView(parent.getContext())) { };
- }
-
- @Override
- public void bindViewHolder(ViewHolder holder, WidgetListSpaceEntry data,
- @ListPosition int position, List<Object> payloads) {
- ((EmptySpaceView) holder.itemView).setFixedHeight(mEmptySpaceHeightProvider.getAsInt());
- }
-
- /**
- * Empty view which allows listening for 'Y' changes
- */
- public static class EmptySpaceView extends View {
-
- private Runnable mOnYChangeCallback;
- private int mHeight = 0;
-
- private EmptySpaceView(Context context) {
- super(context);
- animate().setUpdateListener(v -> notifyYChanged());
- }
-
- /**
- * Sets the height for the empty view
- * @return true if the height changed, false otherwise
- */
- public boolean setFixedHeight(int height) {
- if (mHeight != height) {
- mHeight = height;
- requestLayout();
- return true;
- }
- return false;
- }
-
- @Override
- protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- super.onMeasure(widthMeasureSpec, makeMeasureSpec(mHeight, EXACTLY));
- }
-
- public void setOnYChangeCallback(Runnable callback) {
- mOnYChangeCallback = callback;
- }
-
- @Override
- protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
- super.onLayout(changed, left, top, right, bottom);
- notifyYChanged();
- }
-
- @Override
- public void offsetTopAndBottom(int offset) {
- super.offsetTopAndBottom(offset);
- notifyYChanged();
- }
-
- @Override
- public void setTranslationY(float translationY) {
- super.setTranslationY(translationY);
- notifyYChanged();
- }
-
- private void notifyYChanged() {
- if (mOnYChangeCallback != null) {
- mOnYChangeCallback.run();
- }
- }
- }
-}
diff --git a/src/com/android/launcher3/widget/picker/search/WidgetsSearchBarController.java b/src/com/android/launcher3/widget/picker/search/WidgetsSearchBarController.java
index a15508a617..2751a52796 100644
--- a/src/com/android/launcher3/widget/picker/search/WidgetsSearchBarController.java
+++ b/src/com/android/launcher3/widget/picker/search/WidgetsSearchBarController.java
@@ -95,6 +95,11 @@ public class WidgetsSearchBarController implements TextWatcher,
}
@Override
+ public void onAppendSearchResult(String query, ArrayList<WidgetsListBaseEntry> items) {
+ // Not needed.
+ }
+
+ @Override
public void clearSearchResult() {
// Any existing search session will be cancelled by setting text to empty.
mInput.setText("");
diff --git a/src/com/android/launcher3/widget/util/WidgetSizes.java b/src/com/android/launcher3/widget/util/WidgetSizes.java
index fb2d63ba74..451ed6efcc 100644
--- a/src/com/android/launcher3/widget/util/WidgetSizes.java
+++ b/src/com/android/launcher3/widget/util/WidgetSizes.java
@@ -17,6 +17,7 @@ package com.android.launcher3.widget.util;
import static android.appwidget.AppWidgetHostView.getDefaultPaddingForWidget;
+
import android.appwidget.AppWidgetHostView;
import android.appwidget.AppWidgetManager;
import android.content.ComponentName;
@@ -86,13 +87,7 @@ public final class WidgetSizes {
}
/**
- * Returns the size of a {@link WidgetItem}.
- *
- * <p>This size is used by the widget picker. It should NEVER be shared with app widgets.
- *
- * <p>For sizes shared with app widgets, please refer to
- * {@link #getWidgetPaddedSizes(Context, ComponentName, int, int)} &
- * {@link #getWidgetPaddedSizePx(Context, ComponentName, DeviceProfile, int, int)}.
+ * Returns the size of a WidgetItem.
*/
public static Size getWidgetItemSizePx(Context context, DeviceProfile profile,
WidgetItem widgetItem) {
@@ -101,21 +96,14 @@ public final class WidgetSizes {
.getDimensionPixelSize(R.dimen.widget_preview_shortcut_padding);
return new Size(dimension, dimension);
}
- Size widgetItemSize = getWidgetSizePx(profile, widgetItem.spanX,
- widgetItem.spanY, /* recycledCellSize= */ null);
- if (profile.shouldInsetWidgets()) {
- Rect inset = new Rect();
- AppWidgetHostView.getDefaultPaddingForWidget(context, widgetItem.componentName, inset);
- return new Size(widgetItemSize.getWidth() + inset.left + inset.right,
- widgetItemSize.getHeight() + inset.top + inset.bottom);
- }
- return widgetItemSize;
+ return getWidgetPaddedSizePx(context, widgetItem.componentName, profile, widgetItem.spanX,
+ widgetItem.spanY);
}
private static Size getWidgetSizePx(DeviceProfile profile, int spanX, int spanY,
@Nullable Point recycledCellSize) {
- final int hBorderSpacing = (spanX - 1) * profile.cellLayoutBorderSpacePx.x;
- final int vBorderSpacing = (spanY - 1) * profile.cellLayoutBorderSpacePx.y;
+ final int hBorderSpacing = (spanX - 1) * profile.cellLayoutBorderSpacingPx;
+ final int vBorderSpacing = (spanY - 1) * profile.cellLayoutBorderSpacingPx;
if (recycledCellSize == null) {
recycledCellSize = new Point();
}
diff --git a/src/com/android/launcher3/widget/util/WidgetsTableUtils.java b/src/com/android/launcher3/widget/util/WidgetsTableUtils.java
index 72e27bf37e..54aaf93ac0 100644
--- a/src/com/android/launcher3/widget/util/WidgetsTableUtils.java
+++ b/src/com/android/launcher3/widget/util/WidgetsTableUtils.java
@@ -45,20 +45,9 @@ public final class WidgetsTableUtils {
return item.spanX > otherItem.spanX ? 1 : -1;
};
- /**
- * Groups {@code widgetItems} items into a 2D array which matches their appearance in a UI
- * table. This takes liberty to rearrange widgets to make the table visually appealing.
- */
- public static List<ArrayList<WidgetItem>> groupWidgetItemsIntoTableWithReordering(
- List<WidgetItem> widgetItems, final int maxSpansPerRow) {
- List<WidgetItem> sortedWidgetItems = widgetItems.stream().sorted(WIDGET_SHORTCUT_COMPARATOR)
- .collect(Collectors.toList());
- return groupWidgetItemsIntoTableWithoutReordering(sortedWidgetItems, maxSpansPerRow);
- }
/**
- * Groups {@code widgetItems} into a 2D array which matches their appearance in a UI table while
- * maintaining their order.
+ * Groups widgets items into a 2D array which matches their appearance in a UI table.
*
* <p>Grouping:
* 1. Widgets and shortcuts never group together in the same row.
@@ -75,12 +64,13 @@ public final class WidgetsTableUtils {
* should be moved to a new row.
* Example 3: Row 1: 6x4. This is okay because this is the only item in the row.
*/
- public static List<ArrayList<WidgetItem>> groupWidgetItemsIntoTableWithoutReordering(
+ public static List<ArrayList<WidgetItem>> groupWidgetItemsIntoTable(
List<WidgetItem> widgetItems, final int maxSpansPerRow) {
-
+ List<WidgetItem> sortedWidgetItems = widgetItems.stream().sorted(WIDGET_SHORTCUT_COMPARATOR)
+ .collect(Collectors.toList());
List<ArrayList<WidgetItem>> widgetItemsTable = new ArrayList<>();
ArrayList<WidgetItem> widgetItemsAtRow = null;
- for (WidgetItem widgetItem : widgetItems) {
+ for (WidgetItem widgetItem : sortedWidgetItems) {
if (widgetItemsAtRow == null) {
widgetItemsAtRow = new ArrayList<>();
widgetItemsTable.add(widgetItemsAtRow);
diff --git a/src_build_config/com/android/launcher3/BuildConfig.java b/src_build_config/com/android/launcher3/BuildConfig.java
index 9a81d3f54c..49aadf61ff 100644
--- a/src_build_config/com/android/launcher3/BuildConfig.java
+++ b/src_build_config/com/android/launcher3/BuildConfig.java
@@ -17,11 +17,6 @@
package com.android.launcher3;
public final class BuildConfig {
- public static final String APPLICATION_ID = "com.android.launcher3";
- public static final boolean DEBUG = false;
- /**
- * Flag to state if the QSB is on the first screen and placed on the top,
- * this can be overwritten in other launchers with a different value, if needed.
- */
- public static final boolean QSB_ON_FIRST_SCREEN = true;
+ public static final String APPLICATION_ID = "com.android.launcher3";
+ public static final boolean DEBUG = false;
}
diff --git a/src_plugins/com/android/systemui/plugins/OneSearch.java b/src_plugins/com/android/systemui/plugins/OneSearch.java
deleted file mode 100644
index 534bc87df4..0000000000
--- a/src_plugins/com/android/systemui/plugins/OneSearch.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * 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.
- */
-
-package com.android.systemui.plugins;
-
-import android.os.Parcelable;
-
-import com.android.systemui.plugins.annotations.ProvidesInterface;
-
-import java.util.ArrayList;
-
-/**
- * Implement this interface to get suggest for one search.
- */
-@ProvidesInterface(action = OneSearch.ACTION, version = OneSearch.VERSION)
-public interface OneSearch extends Plugin {
- String ACTION = "com.android.systemui.action.PLUGIN_ONE_SEARCH";
- int VERSION = 6;
-
- /**
- * Get the content provider warmed up.
- */
- void warmUp();
-
- /**
- * Get the suggest search target list for the query.
- *
- * @param query The query to get the search suggests for.
- */
- ArrayList<Parcelable> getSuggests(Parcelable query);
-
- /** Get image bitmap with the URL. */
- Parcelable getImageBitmap(String imageUrl);
-
- void setSuggestOnChrome(boolean enable);
-
- /**
- * Notifies search events to plugin
- *
- * @param event the SearchTargetEvent event created due to user action
- */
- void notifyEvent(Parcelable event);
-}
diff --git a/src_plugins/com/android/systemui/plugins/LauncherOverlayPlugin.java b/src_plugins/com/android/systemui/plugins/OverlayPlugin.java
index 9e223556bc..1edb69273f 100644
--- a/src_plugins/com/android/systemui/plugins/LauncherOverlayPlugin.java
+++ b/src_plugins/com/android/systemui/plugins/OverlayPlugin.java
@@ -24,8 +24,8 @@ import com.android.systemui.plugins.shared.LauncherOverlayManager;
/**
* Implement this interface to add a -1 content on the home screen.
*/
-@ProvidesInterface(action = LauncherOverlayPlugin.ACTION, version = LauncherOverlayPlugin.VERSION)
-public interface LauncherOverlayPlugin extends Plugin {
+@ProvidesInterface(action = OverlayPlugin.ACTION, version = OverlayPlugin.VERSION)
+public interface OverlayPlugin extends Plugin {
String ACTION = "com.android.systemui.action.PLUGIN_LAUNCHER_OVERLAY";
int VERSION = 1;
diff --git a/src_plugins/com/android/systemui/plugins/OverscrollPlugin.java b/src_plugins/com/android/systemui/plugins/OverscrollPlugin.java
new file mode 100644
index 0000000000..a434d078bc
--- /dev/null
+++ b/src_plugins/com/android/systemui/plugins/OverscrollPlugin.java
@@ -0,0 +1,75 @@
+/*
+ * 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.
+ */
+package com.android.systemui.plugins;
+
+import android.view.MotionEvent;
+
+import com.android.systemui.plugins.annotations.ProvidesInterface;
+
+/**
+ * Implement this interface to receive a callback when the user swipes right
+ * to left on the gesture area. It won't fire if the user has quick switched to a previous app
+ * (swiped right) and the current app isn't yet the active one (i.e., if swiping left would take
+ * the user to a more recent app).
+ */
+@ProvidesInterface(action = com.android.systemui.plugins.OverscrollPlugin.ACTION,
+ version = com.android.systemui.plugins.OverscrollPlugin.VERSION)
+public interface OverscrollPlugin extends Plugin {
+
+ String ACTION = "com.android.systemui.action.PLUGIN_LAUNCHER_OVERSCROLL";
+ int VERSION = 4;
+
+ String DEVICE_STATE_LOCKED = "Locked";
+ String DEVICE_STATE_LAUNCHER = "Launcher";
+ String DEVICE_STATE_APP = "App";
+ String DEVICE_STATE_UNKNOWN = "Unknown";
+
+ /**
+ * @return true if the plugin is active and will accept overscroll gestures
+ */
+ boolean isActive();
+
+ /**
+ * Called when a touch has been recognized as an overscroll gesture.
+ * @param horizontalDistancePx Horizontal distance from the last finger location to the finger
+ * location when it first touched the screen.
+ * @param verticalDistancePx Horizontal distance from the last finger location to the finger
+ * location when it first touched the screen.
+ * @param thresholdPx Minimum distance for gesture.
+ * @param flingDistanceThresholdPx Minimum distance for gesture by fling.
+ * @param flingVelocityThresholdPx Minimum velocity for gesture by fling.
+ * @param deviceState String representing the current device state
+ * @param underlyingActivity String representing the currently active Activity
+ */
+ void onTouchEvent(MotionEvent event,
+ int horizontalDistancePx,
+ int verticalDistancePx,
+ int thresholdPx,
+ int flingDistanceThresholdPx,
+ int flingVelocityThresholdPx,
+ String deviceState,
+ String underlyingActivity);
+
+ /**
+ * @return `true` if overscroll gesture handling should override all other gestures.
+ */
+ boolean blockOtherGestures();
+
+ /**
+ * @return `true` if the overscroll gesture can pan the underlying app.
+ */
+ boolean allowsUnderlyingActivityOverscroll();
+}
diff --git a/src_plugins/com/android/systemui/plugins/OverviewScreenshotActions.java b/src_plugins/com/android/systemui/plugins/OverviewScreenshotActions.java
new file mode 100644
index 0000000000..8d9c0f4e18
--- /dev/null
+++ b/src_plugins/com/android/systemui/plugins/OverviewScreenshotActions.java
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+
+package com.android.systemui.plugins;
+
+import android.app.Activity;
+import android.graphics.Bitmap;
+import android.view.ViewGroup;
+
+import com.android.systemui.plugins.annotations.ProvidesInterface;
+
+/**
+ * Implement this interface to add action buttons for overview screenshots, e.g. share, edit etc.
+ */
+@ProvidesInterface(
+ action = OverviewScreenshotActions.ACTION, version = OverviewScreenshotActions.VERSION)
+public interface OverviewScreenshotActions extends Plugin {
+ String ACTION = "com.android.systemui.action.PLUGIN_OVERVIEW_SCREENSHOT_ACTIONS";
+ int VERSION = 1;
+
+ /**
+ * Setup the actions for the screenshot, including edit, save, etc.
+ * @param parent The parent view to add buttons on.
+ * @param screenshot The screenshot we will do actions on.
+ * @param activity THe host activity.
+ */
+ void setupActions(ViewGroup parent, Bitmap screenshot, Activity activity);
+}
diff --git a/src_plugins/com/android/systemui/plugins/RecentsExtraCard.java b/src_plugins/com/android/systemui/plugins/RecentsExtraCard.java
new file mode 100644
index 0000000000..cd9f33dd05
--- /dev/null
+++ b/src_plugins/com/android/systemui/plugins/RecentsExtraCard.java
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+
+package com.android.systemui.plugins;
+
+import android.app.Activity;
+import android.content.Context;
+import android.widget.FrameLayout;
+
+import com.android.systemui.plugins.annotations.ProvidesInterface;
+
+/**
+ * Implement this interface to allow extra card on recents overview.
+ */
+@ProvidesInterface(action = RecentsExtraCard.ACTION, version = RecentsExtraCard.VERSION)
+public interface RecentsExtraCard extends Plugin {
+
+ String ACTION = "com.android.systemui.action.PLUGIN_RECENTS_EXTRA_CARD";
+ int VERSION = 1;
+
+ /**
+ * Sets up the recents overview extra card and fills in data.
+ *
+ * @param context Plugin context
+ * @param frameLayout PlaceholderView
+ * @param activity Recents activity to hold extra view
+ */
+ void setupView(Context context, FrameLayout frameLayout, Activity activity);
+}
diff --git a/src_shortcuts_overrides/com/android/launcher3/model/WidgetsModel.java b/src_shortcuts_overrides/com/android/launcher3/model/WidgetsModel.java
index 702f3430aa..631067b929 100644
--- a/src_shortcuts_overrides/com/android/launcher3/model/WidgetsModel.java
+++ b/src_shortcuts_overrides/com/android/launcher3/model/WidgetsModel.java
@@ -4,10 +4,7 @@ package com.android.launcher3.model;
import static android.appwidget.AppWidgetProviderInfo.WIDGET_FEATURE_HIDE_FROM_PICKER;
import static com.android.launcher3.pm.ShortcutConfigActivityInfo.queryList;
-import static com.android.launcher3.widget.WidgetSections.NO_CATEGORY;
-import static java.util.stream.Collectors.groupingBy;
-import static java.util.stream.Collectors.mapping;
import static java.util.stream.Collectors.toList;
import android.appwidget.AppWidgetProviderInfo;
@@ -16,7 +13,6 @@ import android.content.Context;
import android.content.pm.PackageManager;
import android.os.UserHandle;
import android.util.Log;
-import android.util.Pair;
import androidx.annotation.Nullable;
import androidx.collection.ArrayMap;
@@ -31,12 +27,10 @@ import com.android.launcher3.icons.ComponentWithLabelAndIcon;
import com.android.launcher3.icons.IconCache;
import com.android.launcher3.model.data.PackageItemInfo;
import com.android.launcher3.pm.ShortcutConfigActivityInfo;
-import com.android.launcher3.util.IntSet;
import com.android.launcher3.util.PackageUserKey;
import com.android.launcher3.util.Preconditions;
import com.android.launcher3.widget.LauncherAppWidgetProviderInfo;
import com.android.launcher3.widget.WidgetManagerHelper;
-import com.android.launcher3.widget.WidgetSections;
import com.android.launcher3.widget.model.WidgetsListBaseEntry;
import com.android.launcher3.widget.model.WidgetsListContentEntry;
import com.android.launcher3.widget.model.WidgetsListHeaderEntry;
@@ -46,12 +40,12 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
-import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.function.Predicate;
+import java.util.stream.Collectors;
/**
* Widgets data model that is used by the adapters of the widget views and controllers.
@@ -67,6 +61,9 @@ public class WidgetsModel {
private static final String TAG = "WidgetsModel";
private static final boolean DEBUG = false;
+ private static final ComponentName CONVERSATION_WIDGET = ComponentName.createRelative(
+ "com.android.systemui", ".people.widget.PeopleSpaceWidgetProvider");
+
/* Map of widgets and shortcuts that are tracked per package. */
private final Map<PackageItemInfo, List<WidgetItem>> mWidgetsList = new HashMap<>();
@@ -153,6 +150,7 @@ public class WidgetsModel {
}
}
+ app.getWidgetCache().removeObsoletePreviews(widgetsAndShortcuts, packageUser);
return updatedItems;
}
@@ -171,15 +169,16 @@ public class WidgetsModel {
mWidgetsList.clear();
} else {
// Otherwise, only clear the widgets and shortcuts for the changed package.
- mWidgetsList.remove(packageItemInfoCache.getOrCreate(packageUser));
+ mWidgetsList.remove(
+ packageItemInfoCache.getOrCreate(new WidgetPackageOrCategoryKey(packageUser)));
}
// add and update.
mWidgetsList.putAll(rawWidgetsShortcuts.stream()
.filter(new WidgetValidityCheck(app))
- .flatMap(widgetItem -> getPackageUserKeys(app.getContext(), widgetItem).stream()
- .map(key -> new Pair<>(packageItemInfoCache.getOrCreate(key), widgetItem)))
- .collect(groupingBy(pair -> pair.first, mapping(pair -> pair.second, toList()))));
+ .collect(Collectors.groupingBy(item ->
+ packageItemInfoCache.getOrCreate(getWidgetPackageOrCategoryKey(item))
+ )));
// Update each package entry
IconCache iconCache = app.getIconCache();
@@ -211,9 +210,9 @@ public class WidgetsModel {
}
public WidgetItem getWidgetProviderInfoByProviderName(
- ComponentName providerName, UserHandle user) {
+ ComponentName providerName) {
List<WidgetItem> widgetsList = mWidgetsList.get(
- new PackageItemInfo(providerName.getPackageName(), user));
+ new PackageItemInfo(providerName.getPackageName()));
if (widgetsList == null) {
return null;
}
@@ -227,40 +226,18 @@ public class WidgetsModel {
}
/** Returns {@link PackageItemInfo} of a pending widget. */
- public static PackageItemInfo newPendingItemInfo(Context context, ComponentName provider,
- UserHandle user) {
- Map<ComponentName, IntSet> widgetsToCategories =
- WidgetSections.getWidgetsToCategory(context);
- if (widgetsToCategories.containsKey(provider)) {
- Iterator<Integer> categoriesIterator = widgetsToCategories.get(provider).iterator();
- int firstCategory = NO_CATEGORY;
- while (categoriesIterator.hasNext() && firstCategory == NO_CATEGORY) {
- firstCategory = categoriesIterator.next();
- }
- return new PackageItemInfo(provider.getPackageName(), firstCategory, user);
+ public static PackageItemInfo newPendingItemInfo(ComponentName provider) {
+ if (CONVERSATION_WIDGET.equals(provider)) {
+ return new PackageItemInfo(provider.getPackageName(), PackageItemInfo.CONVERSATIONS);
}
- return new PackageItemInfo(provider.getPackageName(), user);
+ return new PackageItemInfo(provider.getPackageName());
}
- private List<PackageUserKey> getPackageUserKeys(Context context, WidgetItem item) {
- Map<ComponentName, IntSet> widgetsToCategories =
- WidgetSections.getWidgetsToCategory(context);
- IntSet categories = widgetsToCategories.get(item.componentName);
- if (categories == null || categories.isEmpty()) {
- return Arrays.asList(
- new PackageUserKey(item.componentName.getPackageName(), item.user));
+ private WidgetPackageOrCategoryKey getWidgetPackageOrCategoryKey(WidgetItem item) {
+ if (CONVERSATION_WIDGET.equals(item.componentName)) {
+ return new WidgetPackageOrCategoryKey(PackageItemInfo.CONVERSATIONS, item.user);
}
- List<PackageUserKey> packageUserKeys = new ArrayList<>();
- categories.forEach(category -> {
- if (category == NO_CATEGORY) {
- packageUserKeys.add(
- new PackageUserKey(item.componentName.getPackageName(),
- item.user));
- } else {
- packageUserKeys.add(new PackageUserKey(category, item.user));
- }
- });
- return packageUserKeys;
+ return new WidgetPackageOrCategoryKey(item.componentName.getPackageName(), item.user);
}
private static class WidgetValidityCheck implements Predicate<WidgetItem> {
@@ -303,13 +280,53 @@ public class WidgetsModel {
}
}
+ /** A hash key for grouping widgets by package name or category. */
+ private static class WidgetPackageOrCategoryKey {
+ /**
+ * The package name of the widget provider.
+ *
+ * <p>This shouldn't be empty if {@link #mCategory} has a value,
+ * {@link PackageItemInfo#NO_CATEGORY}.
+ */
+ public final String mPackage;
+ /** A widget category. */
+ @PackageItemInfo.Category public final int mCategory;
+ public final UserHandle mUser;
+ private final int mHashCode;
+
+ WidgetPackageOrCategoryKey(PackageUserKey key) {
+ this(key.mPackageName, key.mUser);
+ }
+
+ WidgetPackageOrCategoryKey(String packageName, UserHandle user) {
+ this(packageName, PackageItemInfo.NO_CATEGORY, user);
+ }
+
+ WidgetPackageOrCategoryKey(@PackageItemInfo.Category int category, UserHandle user) {
+ this("", category, user);
+ }
+
+ private WidgetPackageOrCategoryKey(String packageName,
+ @PackageItemInfo.Category int category, UserHandle user) {
+ mPackage = packageName;
+ mCategory = category;
+ mUser = user;
+ mHashCode = Arrays.hashCode(new Object[]{mPackage, mCategory, mUser});
+ }
+
+ @Override
+ public int hashCode() {
+ return mHashCode;
+ }
+ }
+
private static final class PackageItemInfoCache {
- private final Map<PackageUserKey, PackageItemInfo> mMap = new ArrayMap<>();
+ private final Map<WidgetPackageOrCategoryKey, PackageItemInfo> mMap = new ArrayMap<>();
- PackageItemInfo getOrCreate(PackageUserKey key) {
+ PackageItemInfo getOrCreate(WidgetPackageOrCategoryKey key) {
PackageItemInfo pInfo = mMap.get(key);
if (pInfo == null) {
- pInfo = new PackageItemInfo(key.mPackageName, key.mWidgetCategory, key.mUser);
+ pInfo = new PackageItemInfo(key.mPackage, key.mCategory);
pInfo.user = key.mUser;
mMap.put(key, pInfo);
}
diff --git a/src_shortcuts_overrides/com/android/launcher3/util/AbsGridOccupancy.java b/src_shortcuts_overrides/com/android/launcher3/util/AbsGridOccupancy.java
deleted file mode 100644
index 968b281787..0000000000
--- a/src_shortcuts_overrides/com/android/launcher3/util/AbsGridOccupancy.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.launcher3.util;
-
-/**
- * Defines method to find the next vacant cell on a grid.
- * This uses the default top-down, left-right approach and can be over-written through
- * code swaps in different launchers.
- */
-public abstract class AbsGridOccupancy {
- /**
- * Find the first vacant cell, if there is one.
- *
- * @param vacantOut Holds the x and y coordinate of the vacant cell
- * @param spanX Horizontal cell span.
- * @param spanY Vertical cell span.
- *
- * @return true if a vacant cell was found
- */
- protected boolean findVacantCell(int[] vacantOut, boolean[][] cells, int countX, int countY,
- int spanX, int spanY) {
- for (int y = 0; (y + spanY) <= countY; y++) {
- for (int x = 0; (x + spanX) <= countX; x++) {
- boolean available = !cells[x][y];
- out:
- for (int i = x; i < x + spanX; i++) {
- for (int j = y; j < y + spanY; j++) {
- available = available && !cells[i][j];
- if (!available) break out;
- }
- }
- if (available) {
- vacantOut[0] = x;
- vacantOut[1] = y;
- return true;
- }
- }
- }
- return false;
- }
-}
diff --git a/src_ui_overrides/com/android/launcher3/uioverrides/ApiWrapper.java b/src_ui_overrides/com/android/launcher3/uioverrides/ApiWrapper.java
index 67157494d8..4407fe1149 100644
--- a/src_ui_overrides/com/android/launcher3/uioverrides/ApiWrapper.java
+++ b/src_ui_overrides/com/android/launcher3/uioverrides/ApiWrapper.java
@@ -17,8 +17,8 @@
package com.android.launcher3.uioverrides;
import android.app.Person;
-import android.content.Context;
import android.content.pm.ShortcutInfo;
+import android.view.Display;
import com.android.launcher3.Utilities;
@@ -31,9 +31,9 @@ public class ApiWrapper {
}
/**
- * Returns the minimum space that should be left empty at the end of hotseat
+ * Returns true if the display is an internal displays
*/
- public static int getHotseatEndOffset(Context context) {
- return 0;
+ public static boolean isInternalDisplay(Display display) {
+ return display.getDisplayId() == Display.DEFAULT_DISPLAY;
}
}
diff --git a/src_ui_overrides/com/android/launcher3/uioverrides/states/AllAppsState.java b/src_ui_overrides/com/android/launcher3/uioverrides/states/AllAppsState.java
index bf35dd8d08..978c321cb4 100644
--- a/src_ui_overrides/com/android/launcher3/uioverrides/states/AllAppsState.java
+++ b/src_ui_overrides/com/android/launcher3/uioverrides/states/AllAppsState.java
@@ -20,7 +20,6 @@ import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_ALLAP
import android.content.Context;
-import com.android.launcher3.DeviceProfile.DeviceProfileListenable;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherState;
import com.android.launcher3.R;
@@ -32,20 +31,23 @@ import com.android.launcher3.util.Themes;
public class AllAppsState extends LauncherState {
private static final float PARALLAX_COEFFICIENT = .125f;
- private static final float WORKSPACE_SCALE_FACTOR = 0.97f;
private static final int STATE_FLAGS = FLAG_WORKSPACE_INACCESSIBLE;
+ private static final PageAlphaProvider PAGE_ALPHA_PROVIDER = new PageAlphaProvider(DEACCEL_2) {
+ @Override
+ public float getPageAlpha(int pageIndex) {
+ return 0;
+ }
+ };
+
public AllAppsState(int id) {
super(id, LAUNCHER_STATE_ALLAPPS, STATE_FLAGS);
}
@Override
- public <DEVICE_PROFILE_CONTEXT extends Context & DeviceProfileListenable>
- int getTransitionDuration(DEVICE_PROFILE_CONTEXT context, boolean isToState) {
- return !context.getDeviceProfile().isTablet && isToState
- ? 600
- : isToState ? 500 : 300;
+ public int getTransitionDuration(Context context) {
+ return 320;
}
@Override
@@ -60,34 +62,13 @@ public class AllAppsState extends LauncherState {
@Override
public ScaleAndTranslation getWorkspaceScaleAndTranslation(Launcher launcher) {
- return new ScaleAndTranslation(WORKSPACE_SCALE_FACTOR, NO_OFFSET, NO_OFFSET);
- }
-
- @Override
- public ScaleAndTranslation getHotseatScaleAndTranslation(Launcher launcher) {
- if (launcher.getDeviceProfile().isTablet) {
- return getWorkspaceScaleAndTranslation(launcher);
- } else {
- ScaleAndTranslation overviewScaleAndTranslation = LauncherState.OVERVIEW
- .getWorkspaceScaleAndTranslation(launcher);
- return new ScaleAndTranslation(
- WORKSPACE_SCALE_FACTOR,
- overviewScaleAndTranslation.translationX,
- overviewScaleAndTranslation.translationY);
- }
+ return new ScaleAndTranslation(1f, 0,
+ -launcher.getAllAppsController().getShiftRange() * PARALLAX_COEFFICIENT);
}
@Override
public PageAlphaProvider getWorkspacePageAlphaProvider(Launcher launcher) {
- PageAlphaProvider superPageAlphaProvider = super.getWorkspacePageAlphaProvider(launcher);
- return new PageAlphaProvider(DEACCEL_2) {
- @Override
- public float getPageAlpha(int pageIndex) {
- return launcher.getDeviceProfile().isTablet
- ? superPageAlphaProvider.getPageAlpha(pageIndex)
- : 0;
- }
- };
+ return PAGE_ALPHA_PROVIDER;
}
@Override
@@ -97,8 +78,6 @@ public class AllAppsState extends LauncherState {
@Override
public int getWorkspaceScrimColor(Launcher launcher) {
- return launcher.getDeviceProfile().isTablet
- ? launcher.getResources().getColor(R.color.widgets_picker_scrim)
- : Themes.getAttrColor(launcher, R.attr.allAppsScrimColor);
+ return Themes.getAttrColor(launcher, R.attr.allAppsScrimColor);
}
}
diff --git a/src_ui_overrides/com/android/launcher3/uioverrides/states/OverviewState.java b/src_ui_overrides/com/android/launcher3/uioverrides/states/OverviewState.java
index 7a228c42b8..d1543175f4 100644
--- a/src_ui_overrides/com/android/launcher3/uioverrides/states/OverviewState.java
+++ b/src_ui_overrides/com/android/launcher3/uioverrides/states/OverviewState.java
@@ -34,7 +34,7 @@ public class OverviewState extends LauncherState {
}
@Override
- public int getTransitionDuration(Context context, boolean isToState) {
+ public int getTransitionDuration(Context context) {
return 250;
}
diff --git a/tests/Android.bp b/tests/Android.bp
index 54cded0fd3..da55c28684 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -11,95 +11,16 @@
// 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 {
// See: http://go/android-license-faq
- default_applicable_licenses: ["Android-Apache-2.0"],
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "packages_apps_Launcher3_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["packages_apps_Launcher3_license"],
}
-// Source code used for test
filegroup {
- name: "launcher-tests-src",
- srcs: [
- "src/**/*.java",
- "src/**/*.kt"
- ],
-}
-
-// Source code used for oop test helpers
-filegroup {
- name: "launcher-oop-tests-src",
- srcs: [
- "src/com/android/launcher3/ui/AbstractLauncherUiTest.java",
- "src/com/android/launcher3/ui/PortraitLandscapeRunner.java",
- "src/com/android/launcher3/util/TestUtil.java",
- "src/com/android/launcher3/util/Wait.java",
- "src/com/android/launcher3/util/WidgetUtils.java",
- "src/com/android/launcher3/util/rule/FailureWatcher.java",
- "src/com/android/launcher3/util/rule/LauncherActivityRule.java",
- "src/com/android/launcher3/util/rule/SamplerRule.java",
- "src/com/android/launcher3/util/rule/ScreenRecordRule.java",
- "src/com/android/launcher3/util/rule/ShellCommandRule.java",
- "src/com/android/launcher3/util/rule/SimpleActivityRule.java",
- "src/com/android/launcher3/util/rule/TestStabilityRule.java",
- "src/com/android/launcher3/ui/TaplTestsLauncher3.java",
- "src/com/android/launcher3/testcomponent/BaseTestingActivity.java",
- "src/com/android/launcher3/testcomponent/OtherBaseTestingActivity.java",
- "src/com/android/launcher3/testcomponent/CustomShortcutConfigActivity.java",
- "src/com/android/launcher3/testcomponent/TestCommandReceiver.java",
- "src/com/android/launcher3/testcomponent/TestLauncherActivity.java",
- ],
-}
-
-// Library with all the dependencies for building quickstep
-android_library {
- name: "Launcher3TestLib",
- srcs: [ ],
- resource_dirs: ["res"],
- static_libs: [
- "launcher-aosp-tapl",
- "androidx.test.core",
- "androidx.test.runner",
- "androidx.test.rules",
- "androidx.test.ext.junit",
- "androidx.test.espresso.core",
- "androidx.test.espresso.contrib",
- "androidx.test.espresso.intents",
- "androidx.test.uiautomator_uiautomator",
- "mockito-target-inline-minus-junit4",
- "launcher_log_protos_lite",
- "truth-prebuilt",
- "platform-test-rules",
- ],
- manifest: "AndroidManifest-common.xml",
- platform_apis: true,
-}
-
-android_library {
- name: "Launcher3TestResources",
- resource_dirs: ["res"],
-}
-
-android_test {
- name: "Launcher3Tests",
- srcs: [
- ":launcher-tests-src",
- ],
- static_libs: ["Launcher3TestLib"],
- libs: [
- "android.test.base",
- "android.test.runner",
- "android.test.mock",
- ],
- jni_libs: [
- "libdexmakerjvmtiagent",
- "libstaticjvmtiagent",
- ],
- use_embedded_native_libs: false,
- compile_multilib: "both",
- instrumentation_for: "Launcher3",
- manifest: "AndroidManifest.xml",
- platform_apis: true,
- test_config: "Launcher3Tests.xml",
- data: [":Launcher3"]
+ name: "launcher3-test-src-common",
+ srcs: ["src_common/**/*.java"],
}
diff --git a/tests/Android.mk b/tests/Android.mk
new file mode 100644
index 0000000000..6adc685981
--- /dev/null
+++ b/tests/Android.mk
@@ -0,0 +1,54 @@
+# Copyright (C) 2015 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.
+#
+
+LOCAL_PATH := $(call my-dir)
+
+#
+# Build rule for Launcher3Tests
+#
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := tests
+LOCAL_STATIC_JAVA_LIBRARIES := \
+ androidx.test.runner \
+ androidx.test.rules \
+ androidx.test.uiautomator_uiautomator \
+ mockito-target-minus-junit4 \
+ launcher_log_protos_lite
+
+LOCAL_PRIVATE_PLATFORM_APIS := true
+LOCAL_STATIC_JAVA_LIBRARIES += launcher-aosp-tapl
+
+LOCAL_SRC_FILES := \
+ $(call all-java-files-under, src) \
+ $(call all-java-files-under, src_common)
+
+
+LOCAL_FULL_LIBS_MANIFEST_FILES := $(LOCAL_PATH)/AndroidManifest-common.xml
+
+LOCAL_PACKAGE_NAME := Launcher3Tests
+
+LOCAL_INSTRUMENTATION_FOR := Launcher3
+
+LOCAL_TEST_CONFIG := Launcher3Tests.xml
+
+LOCAL_COMPATIBILITY_SUPPORT_FILES := $(call intermediates-dir-for,APPS,Launcher3)/package.apk:Launcher3.apk
+
+LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
+LOCAL_LICENSE_CONDITIONS := notice
+LOCAL_NOTICE_FILE := $(LOCAL_PATH)/../NOTICE
+include $(BUILD_PACKAGE)
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tests/AndroidManifest-common.xml b/tests/AndroidManifest-common.xml
index 9cc3aeda1f..918ec4af1a 100644
--- a/tests/AndroidManifest-common.xml
+++ b/tests/AndroidManifest-common.xml
@@ -16,7 +16,6 @@
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
package="com.android.launcher3.tests">
<uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES"/>
@@ -25,7 +24,7 @@
<uses-permission android:name="android.permission.READ_LOGS"/>
<uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS"/>
- <application android:debuggable="true" android:extractNativeLibs="true">
+ <application android:debuggable="true">
<uses-library android:name="android.test.runner"/>
<receiver
@@ -94,6 +93,7 @@
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
+ <category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
@@ -109,7 +109,7 @@
<activity
android:name="com.android.launcher3.testcomponent.TestLauncherActivity"
android:clearTaskOnLaunch="true"
- android:configChanges="keyboard|keyboardHidden|mcc|mnc|navigation|orientation|screenSize|screenLayout|smallestScreenSize"
+ android:configChanges="keyboard|keyboardHidden|mcc|mnc|navigation|orientation|screenSize|screenLayout|smallestScreenSize|density"
android:enabled="false"
android:label="Test launcher"
android:launchMode="singleTask"
@@ -137,7 +137,6 @@
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
- <category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
<intent-filter>
<action android:name="com.android.launcher3.intent.action.test_shortcut"/>
@@ -146,16 +145,6 @@
<meta-data android:name="android.app.shortcuts"
android:resource="@xml/shortcuts"/>
</activity>
- <activity
- android:name="com.android.launcher3.testcomponent.OtherBaseTestingActivity"
- android:label="OtherLauncherTestApp"
- android:exported="true"
- android:taskAffinity="com.android.launcher3.testcomponent.Affinity2">
- <intent-filter>
- <action android:name="android.intent.action.MAIN"/>
- <category android:name="android.intent.category.LAUNCHER"/>
- </intent-filter>
- </activity>
<activity-alias android:name="Activity2"
android:label="TestActivity2"
android:exported="true"
@@ -219,68 +208,32 @@
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity-alias>
- <activity-alias android:name="Activity9" android:exported="true"
- android:label="TestActivity9"
- android:targetActivity="com.android.launcher3.testcomponent.OtherBaseTestingActivity">
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.LAUNCHER" />
- </intent-filter>
- </activity-alias>
- <activity-alias android:name="Activity10" android:exported="true"
- android:label="TestActivity10"
- android:targetActivity="com.android.launcher3.testcomponent.OtherBaseTestingActivity">
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.LAUNCHER" />
- </intent-filter>
- </activity-alias>
- <activity-alias android:name="Activity11" android:exported="true"
- android:label="TestActivity11"
- android:targetActivity="com.android.launcher3.testcomponent.OtherBaseTestingActivity">
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.LAUNCHER" />
- </intent-filter>
- </activity-alias>
- <activity-alias android:name="Activity12" android:exported="true"
- android:label="TestActivity12"
- android:targetActivity="com.android.launcher3.testcomponent.OtherBaseTestingActivity">
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.LAUNCHER" />
- </intent-filter>
- </activity-alias>
- <activity-alias android:name="Activity13" android:exported="true"
- android:label="TestActivity13"
- android:targetActivity="com.android.launcher3.testcomponent.OtherBaseTestingActivity">
+ <activity-alias android:name="Activity9"
+ android:label="TestActivity9"
+ android:exported="true"
+ android:targetActivity="com.android.launcher3.testcomponent.BaseTestingActivity">
<intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.LAUNCHER" />
+ <action android:name="android.intent.action.MAIN"/>
+ <category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity-alias>
- <activity-alias android:name="Activity14" android:exported="true"
- android:label="TestActivity14"
- android:targetActivity="com.android.launcher3.testcomponent.OtherBaseTestingActivity">
+ <activity-alias android:name="Activity10"
+ android:label="TestActivity10"
+ android:exported="true"
+ android:targetActivity="com.android.launcher3.testcomponent.BaseTestingActivity">
<intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.LAUNCHER" />
+ <action android:name="android.intent.action.MAIN"/>
+ <category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity-alias>
- <activity-alias android:name="Activity15" android:exported="true"
- android:label="ThemeIconTestActivity"
- android:icon="@drawable/test_theme_icon"
- android:targetActivity="com.android.launcher3.testcomponent.OtherBaseTestingActivity">
+ <activity-alias android:name="Activity11"
+ android:label="TestActivity11"
+ android:exported="true"
+ android:targetActivity="com.android.launcher3.testcomponent.BaseTestingActivity">
<intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.LAUNCHER" />
+ <action android:name="android.intent.action.MAIN"/>
+ <category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity-alias>
-
- <!-- [b/197780098] Disable eager initialization of Jetpack libraries. -->
- <provider
- android:name="androidx.startup.InitializationProvider"
- android:authorities="${applicationId}.androidx-startup"
- tools:node="remove" />
</application>
</manifest>
diff --git a/tests/dummy_app/Android.bp b/tests/dummy_app/Android.bp
deleted file mode 100644
index 08ce2f7503..0000000000
--- a/tests/dummy_app/Android.bp
+++ /dev/null
@@ -1,29 +0,0 @@
-//
-// Copyright (C) 2021 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 {
- // See: http://go/android-license-faq
- default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
-android_app {
- name: "Aardwolf",
- srcs: ["src/**/*.java"],
- sdk_version: "current",
- dex_preopt: {
- enabled: false,
- },
-}
diff --git a/tests/dummy_app/Android.mk b/tests/dummy_app/Android.mk
new file mode 100644
index 0000000000..3472079d16
--- /dev/null
+++ b/tests/dummy_app/Android.mk
@@ -0,0 +1,21 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := samples
+
+# Only compile source java files in this apk.
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := Aardwolf
+LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
+LOCAL_LICENSE_CONDITIONS := notice
+LOCAL_NOTICE_FILE := $(LOCAL_PATH)/../../NOTICE
+
+LOCAL_SDK_VERSION := current
+
+LOCAL_DEX_PREOPT := false
+
+include $(BUILD_PACKAGE)
+
+# Use the following include to make our test apk.
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tests/res/drawable/test_theme_icon.xml b/tests/res/drawable/test_theme_icon.xml
deleted file mode 100644
index be5c4d90a1..0000000000
--- a/tests/res/drawable/test_theme_icon.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-Copyright (C) 2021 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.
--->
-<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
- <background android:drawable="@android:color/white"/>
- <foreground>
- <color android:color="#FFFF0000" />
- </foreground>
- <monochrome>
- <vector android:width="48dp" android:height="48dp" android:viewportWidth="48.0" android:viewportHeight="48.0">
- <path
- android:fillColor="#FF000000"
- android:pathData="M0,24L48,24 48,48, 0,48 Z"/>
- </vector>
- </monochrome>
-</adaptive-icon>
diff --git a/tests/res/raw/devices.json b/tests/res/raw/devices.json
deleted file mode 100644
index a78dd86464..0000000000
--- a/tests/res/raw/devices.json
+++ /dev/null
@@ -1,45 +0,0 @@
-{
- "pixel6pro": {
- "width": 1440,
- "height": 3120,
- "density": 560,
- "name": "pixel6pro",
- "cutout": "0, 130, 0, 0",
- "grids": [
- "normal",
- "reasonable",
- "practical",
- "big",
- "crazy_big"
- ],
- "resourceOverrides": {
- "status_bar_height": 98,
- "navigation_bar_height_landscape": 56,
- "navigation_bar_height": 56,
- "navigation_bar_width": 56
- }
- },
- "test": {
- "data needs updating": 0
- },
- "pixel5": {
- "width": 1080,
- "height": 2340,
- "density": 440,
- "name": "pixel5",
- "cutout": "0, 136, 0, 0",
- "grids": [
- "normal",
- "reasonable",
- "practical",
- "big",
- "crazy_big"
- ],
- "resourceOverrides": {
- "status_bar_height": 66,
- "navigation_bar_height_landscape": 44,
- "navigation_bar_height": 44,
- "navigation_bar_width": 44
- }
- }
-}
diff --git a/tests/src/com/android/launcher3/DeviceProfileBaseTest.kt b/tests/src/com/android/launcher3/DeviceProfileBaseTest.kt
deleted file mode 100644
index 6d0fcb6faa..0000000000
--- a/tests/src/com/android/launcher3/DeviceProfileBaseTest.kt
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.launcher3
-
-import android.content.Context
-import android.graphics.PointF
-import androidx.test.core.app.ApplicationProvider
-import com.android.launcher3.util.DisplayController.Info
-import com.android.launcher3.util.WindowBounds
-import org.junit.Before
-import org.mockito.ArgumentMatchers.any
-import org.mockito.Mockito.mock
-import org.mockito.Mockito.`when` as whenever
-
-abstract class DeviceProfileBaseTest {
-
- protected var context: Context? = null
- protected var inv: InvariantDeviceProfile? = null
- protected var info: Info = mock(Info::class.java)
- protected var windowBounds: WindowBounds? = null
- protected var isMultiWindowMode: Boolean = false
- protected var transposeLayoutWithOrientation: Boolean = false
- protected var useTwoPanels: Boolean = false
- protected var isGestureMode: Boolean = true
-
- @Before
- fun setUp() {
- context = ApplicationProvider.getApplicationContext()
- // make sure to reset values
- useTwoPanels = false
- isGestureMode = true
- }
-
- protected fun newDP(): DeviceProfile = DeviceProfile(
- context,
- inv,
- info,
- windowBounds,
- isMultiWindowMode,
- transposeLayoutWithOrientation,
- useTwoPanels,
- isGestureMode
- )
-
- protected fun initializeVarsForPhone(isLandscape: Boolean = false) {
- val (x, y) = if (isLandscape)
- Pair(3120, 1440)
- else
- Pair(1440, 3120)
-
- windowBounds = WindowBounds(x, y, x, y - 100, 0)
-
- whenever(info.isTablet(any())).thenReturn(false)
- whenever(info.getDensityDpi()).thenReturn(560)
-
- inv = newScalableInvariantDeviceProfile()
- }
-
- protected fun initializeVarsForTablet(isLandscape: Boolean = false) {
- val (x, y) = if (isLandscape)
- Pair(2560, 1600)
- else
- Pair(1600, 2560)
-
- windowBounds = WindowBounds(x, y, x, y - 100, 0)
-
- whenever(info.isTablet(any())).thenReturn(true)
- whenever(info.getDensityDpi()).thenReturn(320)
-
- inv = newScalableInvariantDeviceProfile()
- }
-
- /**
- * A very generic grid, just to make qsb tests work. For real calculations, make sure to use
- * values that better represent a real grid.
- */
- protected fun newScalableInvariantDeviceProfile(): InvariantDeviceProfile =
- InvariantDeviceProfile().apply {
- isScalable = true
- numColumns = 4
- numRows = 4
- numShownHotseatIcons = 4
- numDatabaseHotseatIcons = 6
- numShrunkenHotseatIcons = 5
- horizontalMargin = FloatArray(4) { 22f }
- borderSpaces = listOf(
- PointF(16f, 16f),
- PointF(16f, 16f),
- PointF(16f, 16f),
- PointF(16f, 16f)
- ).toTypedArray()
- allAppsBorderSpaces = listOf(
- PointF(16f, 16f),
- PointF(16f, 16f),
- PointF(16f, 16f),
- PointF(16f, 16f)
- ).toTypedArray()
- hotseatBorderSpaces = FloatArray(4) { 16f }
- hotseatColumnSpan = IntArray(4) { 4 }
- iconSize = FloatArray(4) { 56f }
- allAppsIconSize = FloatArray(4) { 56f }
- iconTextSize = FloatArray(4) { 14f }
- allAppsIconTextSize = FloatArray(4) { 14f }
- minCellSize = listOf(
- PointF(64f, 83f),
- PointF(64f, 83f),
- PointF(64f, 83f),
- PointF(64f, 83f)
- ).toTypedArray()
- allAppsCellSize = listOf(
- PointF(64f, 83f),
- PointF(64f, 83f),
- PointF(64f, 83f),
- PointF(64f, 83f)
- ).toTypedArray()
- inlineQsb = booleanArrayOf(
- false,
- false,
- false,
- false
- )
- }
-} \ No newline at end of file
diff --git a/tests/src/com/android/launcher3/DeviceProfileGridDimensionsTest.kt b/tests/src/com/android/launcher3/DeviceProfileGridDimensionsTest.kt
deleted file mode 100644
index 80259a59b4..0000000000
--- a/tests/src/com/android/launcher3/DeviceProfileGridDimensionsTest.kt
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.launcher3
-
-import android.graphics.PointF
-import androidx.test.ext.junit.runners.AndroidJUnit4
-import androidx.test.filters.SmallTest
-import com.android.launcher3.util.WindowBounds
-import com.google.common.truth.Truth.assertThat
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.mockito.ArgumentMatchers
-import org.mockito.Mockito.`when` as whenever
-
-/**
- * Test for [DeviceProfile] grid dimensions.
- *
- * This includes workspace, cell layout, shortcut and widget container, cell sizes, etc.
- */
-@SmallTest
-@RunWith(AndroidJUnit4::class)
-class DeviceProfileGridDimensionsTest : DeviceProfileBaseTest() {
-
- @Test
- fun getCellLayoutWidth_twoPanelLandscapeScalable4By4GridTablet_equalsSinglePanelWidth() {
- val tabletWidth = 2560
- val tabletHeight = 1600
- val availableWidth = 2560
- val availableHeight = 1500
- windowBounds = WindowBounds(tabletWidth, tabletHeight, availableWidth, availableHeight, 0)
- useTwoPanels = true
- whenever(info.isTablet(ArgumentMatchers.any())).thenReturn(true)
- whenever(info.densityDpi).thenReturn(320)
- inv = newScalableInvariantDeviceProfile()
-
- val dp = newDP()
-
- val expectedWorkspaceWidth = availableWidth
- val expectedCellLayoutWidth =
- (expectedWorkspaceWidth - (dp.workspacePadding.right + dp.workspacePadding.left)) /
- dp.panelCount
- assertThat(dp.cellLayoutWidth).isEqualTo(expectedCellLayoutWidth)
- }
-
- @Test
- fun getCellLayoutHeight_twoPanelLandscapeScalable4By4GridTablet_equalsSinglePanelHeight() {
- val tabletWidth = 2560
- val tabletHeight = 1600
- val availableWidth = 2560
- val availableHeight = 1500
- windowBounds = WindowBounds(tabletWidth, tabletHeight, availableWidth, availableHeight, 0)
- useTwoPanels = true
- whenever(info.isTablet(ArgumentMatchers.any())).thenReturn(true)
- whenever(info.densityDpi).thenReturn(320)
- inv = newScalableInvariantDeviceProfile()
-
- val dp = newDP()
-
- val expectedWorkspaceHeight = availableHeight
- val expectedCellLayoutHeight =
- expectedWorkspaceHeight - (dp.workspacePadding.top + dp.workspacePadding.bottom)
- assertThat(dp.cellLayoutHeight).isEqualTo(expectedCellLayoutHeight)
- }
-
- @Test
- fun getCellSize_twoPanelLandscapeScalable4By4GridTablet_equalsSinglePanelWidth() {
- val tabletWidth = 2560
- val tabletHeight = 1600
- val availableWidth = 2560
- val availableHeight = 1500
- windowBounds = WindowBounds(tabletWidth, tabletHeight, availableWidth, availableHeight, 0)
- useTwoPanels = true
- whenever(info.isTablet(ArgumentMatchers.any())).thenReturn(true)
- whenever(info.densityDpi).thenReturn(320)
- inv = newScalableInvariantDeviceProfile()
-
- val dp = newDP()
-
- val expectedWorkspaceWidth = availableWidth
- val expectedCellLayoutWidth =
- (expectedWorkspaceWidth - (dp.workspacePadding.right + dp.workspacePadding.left)) /
- dp.panelCount
- val expectedShortcutAndWidgetContainerWidth =
- expectedCellLayoutWidth -
- (dp.cellLayoutPaddingPx.left + dp.cellLayoutPaddingPx.right)
- assertThat(dp.getCellSize().x).isEqualTo(
- (expectedShortcutAndWidgetContainerWidth -
- ((inv!!.numColumns - 1) * dp.cellLayoutBorderSpacePx.x)) / inv!!.numColumns)
- val expectedWorkspaceHeight = availableHeight
- val expectedCellLayoutHeight =
- expectedWorkspaceHeight - (dp.workspacePadding.top + dp.workspacePadding.bottom)
- val expectedShortcutAndWidgetContainerHeight = expectedCellLayoutHeight -
- (dp.cellLayoutPaddingPx.top + dp.cellLayoutPaddingPx.bottom)
- assertThat(dp.getCellSize().y).isEqualTo(
- (expectedShortcutAndWidgetContainerHeight -
- ((inv!!.numRows - 1) * dp.cellLayoutBorderSpacePx.y)) / inv!!.numRows)
- }
-
- @Test
- fun getPanelCount_twoPanelLandscapeScalable4By4GridTablet_equalsTwoPanels() {
- val tabletWidth = 2560
- val tabletHeight = 1600
- val availableWidth = 2560
- val availableHeight = 1500
- windowBounds = WindowBounds(tabletWidth, tabletHeight, availableWidth, availableHeight, 0)
- useTwoPanels = true
- whenever(info.isTablet(ArgumentMatchers.any())).thenReturn(true)
- whenever(info.densityDpi).thenReturn(320)
- inv = newScalableInvariantDeviceProfile()
-
- val dp = newDP()
-
- assertThat(dp.panelCount).isEqualTo(2)
- }
-} \ No newline at end of file
diff --git a/tests/src/com/android/launcher3/HotseatShownIconsTest.kt b/tests/src/com/android/launcher3/HotseatShownIconsTest.kt
deleted file mode 100644
index 593239d6f7..0000000000
--- a/tests/src/com/android/launcher3/HotseatShownIconsTest.kt
+++ /dev/null
@@ -1,212 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.launcher3
-
-import androidx.test.ext.junit.runners.AndroidJUnit4
-import androidx.test.filters.SmallTest
-import com.android.launcher3.InvariantDeviceProfile.TYPE_MULTI_DISPLAY
-import com.android.launcher3.InvariantDeviceProfile.TYPE_PHONE
-import com.android.launcher3.InvariantDeviceProfile.TYPE_TABLET
-import com.google.common.truth.Truth.assertThat
-import org.junit.Test
-import org.junit.runner.RunWith
-
-/**
- * Test for [DeviceProfile]
- */
-@SmallTest
-@RunWith(AndroidJUnit4::class)
-class HotseatShownIconsTest : DeviceProfileBaseTest() {
-
- @Test
- fun hotseat_size_is_normal_for_handhelds() {
- initializeVarsForPhone()
- inv = newScalableInvariantDeviceProfile().apply {
- deviceType = TYPE_PHONE
- }
-
- val dp = newDP()
-
- assertThat(dp.isQsbInline).isFalse()
- assertThat(dp.numShownHotseatIcons).isEqualTo(4)
- }
-
- @Test
- fun hotseat_size_is_max_when_large_screen() {
- initializeVarsForTablet(isLandscape = true)
- inv = newScalableInvariantDeviceProfile().apply {
- deviceType = TYPE_MULTI_DISPLAY
- }
- useTwoPanels = true
-
- val dp = newDP()
-
- assertThat(dp.isQsbInline).isFalse()
- assertThat(dp.numShownHotseatIcons).isEqualTo(6)
- }
-
- @Test
- fun hotseat_size_is_shrunk_if_needed_when_large_screen() {
- initializeVarsForTablet(isLandscape = true)
- inv = newScalableInvariantDeviceProfile().apply {
- deviceType = TYPE_MULTI_DISPLAY
- inlineQsb = booleanArrayOf(
- false,
- false,
- false,
- true // two panels landscape
- )
- }
- useTwoPanels = true
-
- isGestureMode = false
- val dp = newDP()
-
- if (dp.hotseatQsbHeight > 0) {
- assertThat(dp.isQsbInline).isTrue()
- assertThat(dp.numShownHotseatIcons).isEqualTo(5)
- } else { // Launcher3 doesn't have QSB height
- assertThat(dp.isQsbInline).isFalse()
- assertThat(dp.numShownHotseatIcons).isEqualTo(6)
- }
- }
-
- /**
- * For consistency, the hotseat should shrink if any orientation on the device type has an
- * inline qsb
- */
- @Test
- fun hotseat_size_is_shrunk_even_in_portrait_when_large_screen() {
- initializeVarsForTablet()
- inv = newScalableInvariantDeviceProfile().apply {
- deviceType = TYPE_MULTI_DISPLAY
- inlineQsb = booleanArrayOf(
- false,
- false,
- false,
- true // two panels landscape
- )
- }
- useTwoPanels = true
-
- isGestureMode = false
- val dp = newDP()
-
- if (dp.hotseatQsbHeight > 0) {
- assertThat(dp.isQsbInline).isFalse()
- assertThat(dp.numShownHotseatIcons).isEqualTo(5)
- } else { // Launcher3 doesn't have QSB height
- assertThat(dp.isQsbInline).isFalse()
- assertThat(dp.numShownHotseatIcons).isEqualTo(6)
- }
- }
-
- @Test
- fun hotseat_size_is_default_when_small_screen() {
- initializeVarsForPhone()
- inv = newScalableInvariantDeviceProfile().apply {
- deviceType = TYPE_MULTI_DISPLAY
- }
- useTwoPanels = true
-
- val dp = newDP()
-
- assertThat(dp.numShownHotseatIcons).isEqualTo(4)
- }
-
- @Test
- fun hotseat_size_is_not_shrunk_on_gesture_tablet() {
- initializeVarsForTablet(isLandscape = true)
- inv = newScalableInvariantDeviceProfile().apply {
- deviceType = TYPE_TABLET
- inlineQsb = booleanArrayOf(
- false,
- true, // landscape
- false,
- false
- )
- numShownHotseatIcons = 6
- }
-
- isGestureMode = true
- val dp = newDP()
-
- if (dp.hotseatQsbHeight > 0) {
- assertThat(dp.isQsbInline).isTrue()
- assertThat(dp.numShownHotseatIcons).isEqualTo(6)
- } else { // Launcher3 doesn't have QSB height
- assertThat(dp.isQsbInline).isFalse()
- assertThat(dp.numShownHotseatIcons).isEqualTo(6)
- }
- }
-
- @Test
- fun hotseat_size_is_shrunk_if_needed_on_tablet() {
- initializeVarsForTablet(isLandscape = true)
- inv = newScalableInvariantDeviceProfile().apply {
- deviceType = TYPE_TABLET
- inlineQsb = booleanArrayOf(
- false,
- true, // landscape
- false,
- false
- )
- numShownHotseatIcons = 6
- }
-
- isGestureMode = false
- val dp = newDP()
-
- if (dp.hotseatQsbHeight > 0) {
- assertThat(dp.isQsbInline).isTrue()
- assertThat(dp.numShownHotseatIcons).isEqualTo(5)
- } else { // Launcher3 doesn't have QSB height
- assertThat(dp.isQsbInline).isFalse()
- assertThat(dp.numShownHotseatIcons).isEqualTo(6)
- }
- }
-
- /**
- * For consistency, the hotseat should shrink if any orientation on the device type has an
- * inline qsb
- */
- @Test
- fun hotseat_size_is_shrunk_even_in_portrait_on_tablet() {
- initializeVarsForTablet()
- inv = newScalableInvariantDeviceProfile().apply {
- deviceType = TYPE_TABLET
- inlineQsb = booleanArrayOf(
- false,
- true, // landscape
- false,
- false
- )
- numShownHotseatIcons = 6
- }
-
- isGestureMode = false
- val dp = newDP()
-
- if (dp.hotseatQsbHeight > 0) {
- assertThat(dp.isQsbInline).isFalse()
- assertThat(dp.numShownHotseatIcons).isEqualTo(5)
- } else { // Launcher3 doesn't have QSB height
- assertThat(dp.isQsbInline).isFalse()
- assertThat(dp.numShownHotseatIcons).isEqualTo(6)
- }
- }
-
-} \ No newline at end of file
diff --git a/tests/src/com/android/launcher3/InlineQsbTest.kt b/tests/src/com/android/launcher3/InlineQsbTest.kt
deleted file mode 100644
index 905c1e1a0f..0000000000
--- a/tests/src/com/android/launcher3/InlineQsbTest.kt
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.launcher3
-
-import androidx.test.ext.junit.runners.AndroidJUnit4
-import androidx.test.filters.SmallTest
-import com.google.common.truth.Truth.assertThat
-import org.junit.Test
-import org.junit.runner.RunWith
-
-/**
- * Test for [DeviceProfile]
- */
-@SmallTest
-@RunWith(AndroidJUnit4::class)
-class InlineQsbTest : DeviceProfileBaseTest() {
-
- @Test
- fun qsb_is_not_inline_for_phones() {
- initializeVarsForPhone()
-
- val dp = newDP()
-
- assertThat(dp.isQsbInline).isFalse()
- }
-
- @Test
- fun qsb_is_inline_for_tablet_portrait() {
- initializeVarsForTablet()
- inv = newScalableInvariantDeviceProfile().apply {
- inlineQsb = booleanArrayOf(
- false,
- true, // landscape
- false,
- false
- )
- }
-
- val dp = DeviceProfile(
- context,
- inv,
- info,
- windowBounds,
- isMultiWindowMode,
- transposeLayoutWithOrientation,
- useTwoPanels,
- isGestureMode
- )
-
- assertThat(dp.isQsbInline).isFalse()
- }
-
- @Test
- fun qsb_is_inline_for_tablet_landscape() {
- initializeVarsForTablet(isLandscape = true)
- inv = newScalableInvariantDeviceProfile().apply {
- inlineQsb = booleanArrayOf(
- false,
- true, // landscape
- false,
- false
- )
- numColumns = 6
- numRows = 5
- numShownHotseatIcons = 6
- }
-
- val dp = newDP()
-
- if (dp.hotseatQsbHeight > 0) {
- assertThat(dp.isQsbInline).isTrue()
- } else { // Launcher3 doesn't have QSB height
- assertThat(dp.isQsbInline).isFalse()
- }
- }
-
- /**
- * This test is to make sure that a tablet doesn't inline the QSB if the layout doesn't support
- */
- @Test
- fun qsb_is_not_inline_for_tablet_landscape_without_inline() {
- initializeVarsForTablet(isLandscape = true)
- useTwoPanels = true
-
- val dp = newDP()
-
- assertThat(dp.isQsbInline).isFalse()
- }
-
-} \ No newline at end of file
diff --git a/tests/src/com/android/launcher3/compat/PromiseIconUiTest.java b/tests/src/com/android/launcher3/compat/PromiseIconUiTest.java
index 92e3e64e4b..33066e403e 100644
--- a/tests/src/com/android/launcher3/compat/PromiseIconUiTest.java
+++ b/tests/src/com/android/launcher3/compat/PromiseIconUiTest.java
@@ -25,16 +25,14 @@ import androidx.test.runner.AndroidJUnit4;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherState;
+import com.android.launcher3.Workspace;
import com.android.launcher3.ui.AbstractLauncherUiTest;
-import com.android.launcher3.util.LauncherBindableItemsContainer.ItemOperator;
-import com.android.launcher3.util.rule.ScreenRecordRule.ScreenRecord;
import org.junit.After;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.util.UUID;
-import java.util.concurrent.TimeUnit;
/**
@@ -45,8 +43,6 @@ import java.util.concurrent.TimeUnit;
public class PromiseIconUiTest extends AbstractLauncherUiTest {
private int mSessionId = -1;
- // TODO(b/202985412): Revert to default timeout when PackageManager bug is fixed.
- private static final long PROMISE_ICON_TIMEOUT = TimeUnit.SECONDS.toMillis(60);
@Override
public void setUp() throws Exception {
@@ -77,10 +73,9 @@ public class PromiseIconUiTest extends AbstractLauncherUiTest {
}
@Test
- @ScreenRecord // b/202985412
public void testPromiseIcon_addedFromEligibleSession() throws Throwable {
final String appLabel = "Test Promise App " + UUID.randomUUID().toString();
- final ItemOperator findPromiseApp = (info, view) ->
+ final Workspace.ItemOperator findPromiseApp = (info, view) ->
info != null && TextUtils.equals(info.title, appLabel);
// Create and add test session
@@ -88,8 +83,7 @@ public class PromiseIconUiTest extends AbstractLauncherUiTest {
// Verify promise icon is added
waitForLauncherCondition("Test Promise App not found on workspace", launcher ->
- launcher.getWorkspace().getFirstMatch(findPromiseApp) != null,
- PROMISE_ICON_TIMEOUT);
+ launcher.getWorkspace().getFirstMatch(findPromiseApp) != null);
// Remove session
mTargetContext.getPackageManager().getPackageInstaller().abandonSession(mSessionId);
@@ -97,15 +91,13 @@ public class PromiseIconUiTest extends AbstractLauncherUiTest {
// Verify promise icon is removed
waitForLauncherCondition("Test Promise App not removed from workspace", launcher ->
- launcher.getWorkspace().getFirstMatch(findPromiseApp) == null,
- PROMISE_ICON_TIMEOUT);
+ launcher.getWorkspace().getFirstMatch(findPromiseApp) == null);
}
@Test
- @ScreenRecord // b/202985412
public void testPromiseIcon_notAddedFromIneligibleSession() throws Throwable {
final String appLabel = "Test Promise App " + UUID.randomUUID().toString();
- final ItemOperator findPromiseApp = (info, view) ->
+ final Workspace.ItemOperator findPromiseApp = (info, view) ->
info != null && TextUtils.equals(info.title, appLabel);
// Create and add test session without icon or label
@@ -116,7 +108,6 @@ public class PromiseIconUiTest extends AbstractLauncherUiTest {
// Verify promise icon is not added
waitForLauncherCondition("Test Promise App not found on workspace", launcher ->
- launcher.getWorkspace().getFirstMatch(findPromiseApp) == null,
- PROMISE_ICON_TIMEOUT);
+ launcher.getWorkspace().getFirstMatch(findPromiseApp) == null);
}
}
diff --git a/tests/src/com/android/launcher3/deviceemulator/DisplayEmulator.java b/tests/src/com/android/launcher3/deviceemulator/DisplayEmulator.java
deleted file mode 100644
index 31468c5336..0000000000
--- a/tests/src/com/android/launcher3/deviceemulator/DisplayEmulator.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.launcher3.deviceemulator;
-
-import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
-
-import android.content.ContentResolver;
-import android.content.ContentValues;
-import android.content.Context;
-import android.net.Uri;
-import android.os.UserHandle;
-import android.view.Display;
-import android.view.IWindowManager;
-import android.view.WindowManagerGlobal;
-
-import androidx.test.uiautomator.UiDevice;
-
-import com.android.launcher3.deviceemulator.models.DeviceEmulationData;
-import com.android.launcher3.tapl.LauncherInstrumentation;
-import com.android.launcher3.util.window.WindowManagerProxy;
-
-import java.util.concurrent.Callable;
-
-
-public class DisplayEmulator {
- Context mContext;
- LauncherInstrumentation mLauncher;
- DisplayEmulator(Context context, LauncherInstrumentation launcher) {
- mContext = context;
- mLauncher = launcher;
- }
-
- /**
- * By changing the WindowManagerProxy we can override the window insets information
- **/
- private IWindowManager changeWindowManagerInstance(DeviceEmulationData deviceData) {
- WindowManagerProxy.INSTANCE.initializeForTesting(
- new TestWindowManagerProxy(mContext, deviceData));
- return WindowManagerGlobal.getWindowManagerService();
- }
-
- public <T> T emulate(DeviceEmulationData device, String grid, Callable<T> runInEmulation)
- throws Exception {
- WindowManagerProxy original = WindowManagerProxy.INSTANCE.get(mContext);
- // Set up emulation
- final int userId = UserHandle.myUserId();
- WindowManagerProxy.INSTANCE.initializeForTesting(
- new TestWindowManagerProxy(mContext, device));
- IWindowManager wm = changeWindowManagerInstance(device);
- // Change density twice to force display controller to reset its state
- wm.setForcedDisplayDensityForUser(Display.DEFAULT_DISPLAY, device.density / 2, userId);
- wm.setForcedDisplayDensityForUser(Display.DEFAULT_DISPLAY, device.density, userId);
- wm.setForcedDisplaySize(Display.DEFAULT_DISPLAY, device.width, device.height);
- wm.setForcedDisplayScalingMode(Display.DEFAULT_DISPLAY, 1);
-
- // Set up grid
- setGrid(grid);
- try {
- return runInEmulation.call();
- } finally {
- // Clear emulation
- WindowManagerProxy.INSTANCE.initializeForTesting(original);
- UiDevice.getInstance(getInstrumentation()).executeShellCommand("cmd window reset");
- }
- }
-
- private void setGrid(String gridType) {
- // When the grid changes, the desktop arrangement get stored in SQL and we need to wait to
- // make sure there is no SQL operations running and get SQL_BUSY error, that's why we need
- // to call mLauncher.waitForLauncherInitialized();
- mLauncher.waitForLauncherInitialized();
- String testProviderAuthority = mContext.getPackageName() + ".grid_control";
- Uri gridUri = new Uri.Builder()
- .scheme(ContentResolver.SCHEME_CONTENT)
- .authority(testProviderAuthority)
- .appendPath("default_grid")
- .build();
- ContentValues values = new ContentValues();
- values.put("name", gridType);
- mContext.getContentResolver().update(gridUri, values, null, null);
- }
-}
diff --git a/tests/src/com/android/launcher3/deviceemulator/TestWindowManagerProxy.java b/tests/src/com/android/launcher3/deviceemulator/TestWindowManagerProxy.java
deleted file mode 100644
index cbea688a9a..0000000000
--- a/tests/src/com/android/launcher3/deviceemulator/TestWindowManagerProxy.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.launcher3.deviceemulator;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.graphics.Point;
-import android.graphics.Rect;
-import android.view.Display;
-import android.view.WindowInsets;
-
-import com.android.launcher3.deviceemulator.models.DeviceEmulationData;
-import com.android.launcher3.util.RotationUtils;
-import com.android.launcher3.util.WindowBounds;
-import com.android.launcher3.util.window.CachedDisplayInfo;
-import com.android.launcher3.util.window.WindowManagerProxy;
-
-public class TestWindowManagerProxy extends WindowManagerProxy {
-
- private final DeviceEmulationData mDevice;
-
- public TestWindowManagerProxy(Context context, DeviceEmulationData device) {
- super(true);
- mDevice = device;
- }
-
- @Override
- public boolean isInternalDisplay(Display display) {
- return display.getDisplayId() == Display.DEFAULT_DISPLAY;
- }
-
- @Override
- protected int getDimenByName(Resources res, String resName) {
- Integer mock = mDevice.resourceOverrides.get(resName);
- return mock != null ? mock : super.getDimenByName(res, resName);
- }
-
- @Override
- protected int getDimenByName(Resources res, String resName, String fallback) {
- return getDimenByName(res, resName);
- }
-
- @Override
- public CachedDisplayInfo getDisplayInfo(Context context, Display display) {
- int rotation = display.getRotation();
- Point size = new Point(mDevice.width, mDevice.height);
- RotationUtils.rotateSize(size, rotation);
- Rect cutout = new Rect(mDevice.cutout);
- RotationUtils.rotateRect(cutout, rotation);
- return new CachedDisplayInfo(getDisplayId(display), size, rotation, cutout);
- }
-
- @Override
- public WindowBounds getRealBounds(Context windowContext, Display display,
- CachedDisplayInfo info) {
- return estimateInternalDisplayBounds(windowContext)
- .get(getDisplayId(display)).second[display.getRotation()];
- }
-
- @Override
- public WindowInsets normalizeWindowInsets(Context context, WindowInsets oldInsets,
- Rect outInsets) {
- outInsets.set(getRealBounds(context, context.getDisplay(),
- getDisplayInfo(context, context.getDisplay())).insets);
- return oldInsets;
- }
-}
diff --git a/tests/src/com/android/launcher3/deviceemulator/models/DeviceEmulationData.java b/tests/src/com/android/launcher3/deviceemulator/models/DeviceEmulationData.java
deleted file mode 100644
index 8d275cc04b..0000000000
--- a/tests/src/com/android/launcher3/deviceemulator/models/DeviceEmulationData.java
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.launcher3.deviceemulator.models;
-
-import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
-
-import static com.android.launcher3.ResourceUtils.NAVBAR_HEIGHT;
-import static com.android.launcher3.ResourceUtils.NAVBAR_HEIGHT_LANDSCAPE;
-import static com.android.launcher3.ResourceUtils.NAVBAR_LANDSCAPE_LEFT_RIGHT_SIZE;
-import static com.android.launcher3.ResourceUtils.getDimenByName;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.graphics.Rect;
-import android.os.Build;
-import android.util.ArrayMap;
-
-import com.android.launcher3.InvariantDeviceProfile;
-import com.android.launcher3.util.DisplayController;
-import com.android.launcher3.util.IOUtils;
-import com.android.launcher3.util.IntArray;
-
-import org.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
-
-import java.io.InputStream;
-import java.util.Arrays;
-import java.util.Map;
-
-public class DeviceEmulationData {
-
- public final int width;
- public final int height;
- public final int density;
- public final String name;
- public final String[] grids;
- public final Rect cutout;
- public final Map<String, Integer> resourceOverrides;
-
- private static final String[] EMULATED_SYSTEM_RESOURCES = new String[]{
- NAVBAR_HEIGHT,
- NAVBAR_HEIGHT_LANDSCAPE,
- NAVBAR_LANDSCAPE_LEFT_RIGHT_SIZE,
- "status_bar_height",
- };
-
- public DeviceEmulationData(int width, int height, int density, Rect cutout, String name,
- String[] grid,
- Map<String, Integer> resourceOverrides) {
- this.width = width;
- this.height = height;
- this.density = density;
- this.name = name;
- this.grids = grid;
- this.cutout = cutout;
- this.resourceOverrides = resourceOverrides;
- }
-
- public static DeviceEmulationData deviceFromJSON(JSONObject json) throws JSONException {
- int width = json.getInt("width");
- int height = json.getInt("height");
- int density = json.getInt("density");
- String name = json.getString("name");
-
- JSONArray gridArray = json.getJSONArray("grids");
- String[] grids = new String[gridArray.length()];
- for (int i = 0, count = grids.length; i < count; i++) {
- grids[i] = gridArray.getString(i);
- }
-
- IntArray deviceCutout = IntArray.fromConcatString(json.getString("cutout"));
- Rect cutout = new Rect(deviceCutout.get(0), deviceCutout.get(1), deviceCutout.get(2),
- deviceCutout.get(3));
-
-
- JSONObject resourceOverridesJson = json.getJSONObject("resourceOverrides");
- Map<String, Integer> resourceOverrides = new ArrayMap<>();
- for (String key : resourceOverridesJson.keySet()) {
- resourceOverrides.put(key, resourceOverridesJson.getInt(key));
- }
- return new DeviceEmulationData(width, height, density, cutout, name, grids,
- resourceOverrides);
- }
-
- @Override
- public String toString() {
- JSONObject json = new JSONObject();
- try {
- json.put("width", width);
- json.put("height", height);
- json.put("density", density);
- json.put("name", name);
- json.put("cutout", IntArray.wrap(
- cutout.left, cutout.top, cutout.right, cutout.bottom).toConcatString());
-
- JSONArray gridArray = new JSONArray();
- Arrays.stream(grids).forEach(gridArray::put);
- json.put("grids", gridArray);
-
-
- JSONObject resourceOverrides = new JSONObject();
- for (Map.Entry<String, Integer> e : this.resourceOverrides.entrySet()) {
- resourceOverrides.put(e.getKey(), e.getValue());
- }
- json.put("resourceOverrides", resourceOverrides);
- } catch (Exception e) {
- e.printStackTrace();
- }
- return json.toString();
- }
-
- public static DeviceEmulationData getCurrentDeviceData(Context context) {
- DisplayController.Info info = DisplayController.INSTANCE.get(context).getInfo();
- String[] grids = InvariantDeviceProfile.INSTANCE.get(context)
- .parseAllGridOptions(context).stream()
- .map(go -> go.name).toArray(String[]::new);
- String code = Build.MODEL.replaceAll("\\s", "").toLowerCase();
-
- Map<String, Integer> resourceOverrides = new ArrayMap<>();
- for (String s : EMULATED_SYSTEM_RESOURCES) {
- resourceOverrides.put(s, getDimenByName(s, context.getResources(), 0));
- }
- return new DeviceEmulationData(info.currentSize.x, info.currentSize.y,
- info.getDensityDpi(), info.cutout, code, grids, resourceOverrides);
- }
-
- public static DeviceEmulationData getDevice(String deviceCode) throws Exception {
- return DeviceEmulationData.deviceFromJSON(readJSON().getJSONObject(deviceCode));
- }
-
- private static JSONObject readJSON() throws Exception {
- Context context = getInstrumentation().getContext();
- Resources myRes = context.getResources();
- int resId = myRes.getIdentifier("devices", "raw", context.getPackageName());
- try (InputStream is = myRes.openRawResource(resId)) {
- return new JSONObject(new String(IOUtils.toByteArray(is)));
- }
- }
-
-}
diff --git a/tests/src/com/android/launcher3/model/AbstractWorkspaceModelTest.kt b/tests/src/com/android/launcher3/model/AbstractWorkspaceModelTest.kt
deleted file mode 100644
index d26381dc2f..0000000000
--- a/tests/src/com/android/launcher3/model/AbstractWorkspaceModelTest.kt
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.launcher3.model
-
-import android.content.ComponentName
-import android.content.Context
-import android.content.Intent
-import android.graphics.Rect
-import com.android.launcher3.InvariantDeviceProfile
-import com.android.launcher3.LauncherAppState
-import com.android.launcher3.LauncherSettings
-import com.android.launcher3.model.data.WorkspaceItemInfo
-import com.android.launcher3.util.ContentWriter
-import com.android.launcher3.util.GridOccupancy
-import com.android.launcher3.util.IntArray
-import com.android.launcher3.util.IntSparseArrayMap
-import com.android.launcher3.util.LauncherModelHelper
-import java.util.UUID
-
-/**
- * Base class for workspace related tests.
- */
-abstract class AbstractWorkspaceModelTest {
- companion object {
- val emptyScreenSpaces = listOf(Rect(0, 0, 5, 5))
- val fullScreenSpaces = emptyList<Rect>()
- val nonEmptyScreenSpaces = listOf(Rect(1, 2, 3, 4))
- }
-
- protected lateinit var mTargetContext: Context
- protected lateinit var mIdp: InvariantDeviceProfile
- protected lateinit var mAppState: LauncherAppState
- protected lateinit var mModelHelper: LauncherModelHelper
- protected lateinit var mExistingScreens: IntArray
- protected lateinit var mNewScreens: IntArray
- protected lateinit var mScreenOccupancy: IntSparseArrayMap<GridOccupancy>
-
- open fun setup() {
- mModelHelper = LauncherModelHelper()
- mTargetContext = mModelHelper.sandboxContext
- mIdp = InvariantDeviceProfile.INSTANCE[mTargetContext]
- mIdp.numRows = 5
- mIdp.numColumns = mIdp.numRows
- mAppState = LauncherAppState.getInstance(mTargetContext)
- mExistingScreens = IntArray()
- mScreenOccupancy = IntSparseArrayMap()
- mNewScreens = IntArray()
- }
-
- open fun tearDown() {
- mModelHelper.destroy()
- }
-
-
- /**
- * Sets up workspaces with the given screen IDs with some items and a 2x2 space.
- */
- fun setupWorkspaces(screenIdsWithItems: List<Int>) {
- var nextItemId = 1
- screenIdsWithItems.forEach { screenId ->
- nextItemId = setupWorkspace(nextItemId, screenId, nonEmptyScreenSpaces)
- }
- }
-
- /**
- * Sets up the given workspaces with the given spaces, and fills the remaining space with items.
- */
- fun setupWorkspacesWithSpaces(
- screen0: List<Rect>? = null,
- screen1: List<Rect>? = null,
- screen2: List<Rect>? = null,
- screen3: List<Rect>? = null,
- ) = listOf(screen0, screen1, screen2, screen3)
- .let(this::setupWithSpaces)
-
- private fun setupWithSpaces(workspaceSpaces: List<List<Rect>?>) {
- var nextItemId = 1
- workspaceSpaces.forEachIndexed { screenId, spaces ->
- if (spaces != null) {
- nextItemId = setupWorkspace(nextItemId, screenId, spaces)
- }
- }
- }
-
- private fun setupWorkspace(startId: Int, screenId: Int, spaces: List<Rect>): Int {
- return mModelHelper.executeSimpleTask { dataModel ->
- writeWorkspaceWithSpaces(dataModel, startId, screenId, spaces)
- }
- }
-
- private fun writeWorkspaceWithSpaces(
- bgDataModel: BgDataModel,
- itemStartId: Int,
- screenId: Int,
- spaces: List<Rect>,
- ): Int {
- var itemId = itemStartId
- val occupancy = GridOccupancy(mIdp.numColumns, mIdp.numRows)
- occupancy.markCells(0, 0, mIdp.numColumns, mIdp.numRows, true)
- spaces.forEach { spaceRect ->
- occupancy.markCells(spaceRect, false)
- }
- mExistingScreens.add(screenId)
- mScreenOccupancy.append(screenId, occupancy)
- for (x in 0 until mIdp.numColumns) {
- for (y in 0 until mIdp.numRows) {
- if (!occupancy.cells[x][y]) {
- continue
- }
- val info = getExistingItem()
- info.id = itemId++
- info.screenId = screenId
- info.cellX = x
- info.cellY = y
- info.container = LauncherSettings.Favorites.CONTAINER_DESKTOP
- bgDataModel.addItem(mTargetContext, info, false)
- val writer = ContentWriter(mTargetContext)
- info.writeToValues(writer)
- writer.put(LauncherSettings.Favorites._ID, info.id)
- mTargetContext.contentResolver.insert(
- LauncherSettings.Favorites.CONTENT_URI,
- writer.getValues(mTargetContext)
- )
- }
- }
- return itemId
- }
-
- fun getExistingItem() = WorkspaceItemInfo()
- .apply { intent = Intent().setComponent(ComponentName("a", "b")) }
-
- fun getNewItem(): WorkspaceItemInfo {
- val itemPackage = UUID.randomUUID().toString()
- return WorkspaceItemInfo()
- .apply { intent = Intent().setComponent(ComponentName(itemPackage, itemPackage)) }
- }
-}
-
-data class NewItemSpace(
- val screenId: Int,
- val cellX: Int,
- val cellY: Int
-) {
- fun toIntArray() = intArrayOf(screenId, cellX, cellY)
-
- companion object {
- fun fromIntArray(array: kotlin.IntArray) = NewItemSpace(array[0], array[1], array[2])
- }
-} \ No newline at end of file
diff --git a/tests/src/com/android/launcher3/model/AddWorkspaceItemsTaskTest.kt b/tests/src/com/android/launcher3/model/AddWorkspaceItemsTaskTest.kt
deleted file mode 100644
index 65d938b91a..0000000000
--- a/tests/src/com/android/launcher3/model/AddWorkspaceItemsTaskTest.kt
+++ /dev/null
@@ -1,245 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.launcher3.model
-
-import android.util.Pair
-import androidx.test.ext.junit.runners.AndroidJUnit4
-import androidx.test.filters.SmallTest
-import com.android.launcher3.model.data.ItemInfo
-import com.android.launcher3.model.data.WorkspaceItemInfo
-import com.android.launcher3.util.Executors
-import com.android.launcher3.util.IntArray
-import com.android.launcher3.util.same
-import com.android.launcher3.util.eq
-import com.android.launcher3.util.any
-import com.google.common.truth.Truth.assertThat
-import org.junit.After
-import org.junit.Before
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.mockito.ArgumentCaptor
-import org.mockito.Captor
-import org.mockito.Mock
-import org.mockito.MockitoAnnotations
-import org.mockito.Mockito.verify
-import org.mockito.Mockito.verifyZeroInteractions
-import org.mockito.Mockito.times
-import org.mockito.Mockito.`when` as whenever
-
-/**
- * Tests for [AddWorkspaceItemsTask]
- */
-@SmallTest
-@RunWith(AndroidJUnit4::class)
-class AddWorkspaceItemsTaskTest : AbstractWorkspaceModelTest() {
-
- @Captor
- private lateinit var mAnimatedItemArgumentCaptor: ArgumentCaptor<ArrayList<ItemInfo>>
-
- @Captor
- private lateinit var mNotAnimatedItemArgumentCaptor: ArgumentCaptor<ArrayList<ItemInfo>>
-
- @Mock
- private lateinit var mDataModelCallbacks: BgDataModel.Callbacks
-
- @Mock
- private lateinit var mWorkspaceItemSpaceFinder: WorkspaceItemSpaceFinder
-
-
- @Before
- override fun setup() {
- super.setup()
- MockitoAnnotations.initMocks(this)
- Executors.MAIN_EXECUTOR.submit { mModelHelper.model.addCallbacks(mDataModelCallbacks) }
- .get()
- }
-
- @After
- override fun tearDown() {
- super.tearDown()
- }
-
- @Test
- fun givenNewItemAndNonEmptyPages_whenExecuteTask_thenAddNewItem() {
- val itemToAdd = getNewItem()
- val nonEmptyScreenIds = listOf(0, 1, 2)
- givenNewItemSpaces(NewItemSpace(1, 2, 2))
-
- val addedItems = testAddItems(nonEmptyScreenIds, itemToAdd)
-
- assertThat(addedItems.size).isEqualTo(1)
- assertThat(addedItems.first().itemInfo.screenId).isEqualTo(1)
- assertThat(addedItems.first().isAnimated).isTrue()
- verifyItemSpaceFinderCall(nonEmptyScreenIds, numberOfExpectedCall = 1)
- }
-
- @Test
- fun givenNewAndExistingItems_whenExecuteTask_thenOnlyAddNewItem() {
- val itemsToAdd = arrayOf(
- getNewItem(),
- getExistingItem()
- )
- givenNewItemSpaces(NewItemSpace(1, 0, 0))
- val nonEmptyScreenIds = listOf(0)
-
- val addedItems = testAddItems(nonEmptyScreenIds, *itemsToAdd)
-
- assertThat(addedItems.size).isEqualTo(1)
- assertThat(addedItems.first().itemInfo.screenId).isEqualTo(1)
- assertThat(addedItems.first().isAnimated).isTrue()
- verifyItemSpaceFinderCall(nonEmptyScreenIds, numberOfExpectedCall = 1)
- }
-
- @Test
- fun givenOnlyExistingItem_whenExecuteTask_thenDoNotAddItem() {
- val itemToAdd = getExistingItem()
- givenNewItemSpaces(NewItemSpace(1, 0, 0))
- val nonEmptyScreenIds = listOf(0)
-
- val addedItems = testAddItems(nonEmptyScreenIds, itemToAdd)
-
- assertThat(addedItems.size).isEqualTo(0)
- verifyZeroInteractions(mWorkspaceItemSpaceFinder, mDataModelCallbacks)
- }
-
- @Test
- fun givenNonSequentialScreenIds_whenExecuteTask_thenReturnNewScreenId() {
- val itemToAdd = getNewItem()
- givenNewItemSpaces(NewItemSpace(2, 1, 3))
- val nonEmptyScreenIds = listOf(0, 2, 3)
-
- val addedItems = testAddItems(nonEmptyScreenIds, itemToAdd)
-
- assertThat(addedItems.size).isEqualTo(1)
- assertThat(addedItems.first().itemInfo.screenId).isEqualTo(2)
- assertThat(addedItems.first().isAnimated).isTrue()
- verifyItemSpaceFinderCall(nonEmptyScreenIds, numberOfExpectedCall = 1)
- }
-
- @Test
- fun givenMultipleItems_whenExecuteTask_thenAddThem() {
- val itemsToAdd = arrayOf(
- getNewItem(),
- getExistingItem(),
- getNewItem(),
- getNewItem(),
- getExistingItem(),
- )
- givenNewItemSpaces(
- NewItemSpace(1, 3, 3),
- NewItemSpace(2, 0, 0),
- NewItemSpace(2, 0, 1),
- )
- val nonEmptyScreenIds = listOf(0, 1)
-
- val addedItems = testAddItems(nonEmptyScreenIds, *itemsToAdd)
-
- // Only the new items should be added
- assertThat(addedItems.size).isEqualTo(3)
-
- // Items that are added to the first screen should not be animated
- val itemsAddedToFirstScreen = addedItems.filter { it.itemInfo.screenId == 1 }
- assertThat(itemsAddedToFirstScreen.size).isEqualTo(1)
- assertThat(itemsAddedToFirstScreen.first().isAnimated).isFalse()
-
- // Items that are added to the second screen should be animated
- val itemsAddedToSecondScreen = addedItems.filter { it.itemInfo.screenId == 2 }
- assertThat(itemsAddedToSecondScreen.size).isEqualTo(2)
- itemsAddedToSecondScreen.forEach {
- assertThat(it.isAnimated).isTrue()
- }
- verifyItemSpaceFinderCall(nonEmptyScreenIds, numberOfExpectedCall = 3)
- }
-
- /**
- * Sets up the item space data that will be returned from WorkspaceItemSpaceFinder.
- */
- private fun givenNewItemSpaces(vararg newItemSpaces: NewItemSpace) {
- val spaceStack = newItemSpaces.toMutableList()
- whenever(
- mWorkspaceItemSpaceFinder.findSpaceForItem(
- any(),
- any(),
- any(),
- any(),
- any(),
- any()
- )
- )
- .then { spaceStack.removeFirst().toIntArray() }
- }
-
- /**
- * Verifies if WorkspaceItemSpaceFinder was called with proper arguments and how many times was
- * it called.
- */
- private fun verifyItemSpaceFinderCall(
- nonEmptyScreenIds: List<Int>,
- numberOfExpectedCall: Int
- ) {
- verify(mWorkspaceItemSpaceFinder, times(numberOfExpectedCall))
- .findSpaceForItem(
- same(mAppState), same(mModelHelper.bgDataModel),
- eq(IntArray.wrap(*nonEmptyScreenIds.toIntArray())), eq(IntArray()), eq(1), eq(1)
- )
- }
-
- /**
- * Sets up the workspaces with items, executes the task, collects the added items from the
- * model callback then returns it.
- */
- private fun testAddItems(
- nonEmptyScreenIds: List<Int>,
- vararg itemsToAdd: WorkspaceItemInfo
- ): List<AddedItem> {
- setupWorkspaces(nonEmptyScreenIds)
- val task = newTask(*itemsToAdd)
- var updateCount = 0
- mModelHelper.executeTaskForTest(task)
- .forEach {
- updateCount++
- it.run()
- }
-
- val addedItems = mutableListOf<AddedItem>()
- if (updateCount > 0) {
- verify(mDataModelCallbacks).bindAppsAdded(
- any(),
- mNotAnimatedItemArgumentCaptor.capture(), mAnimatedItemArgumentCaptor.capture()
- )
- addedItems.addAll(mAnimatedItemArgumentCaptor.value.map { AddedItem(it, true) })
- addedItems.addAll(mNotAnimatedItemArgumentCaptor.value.map { AddedItem(it, false) })
-
- }
-
- return addedItems
- }
-
- /**
- * Creates the task with the given items and replaces the WorkspaceItemSpaceFinder dependency
- * with a mock.
- */
- private fun newTask(vararg items: ItemInfo): AddWorkspaceItemsTask =
- items.map { Pair.create(it, Any()) }
- .toMutableList()
- .let { AddWorkspaceItemsTask(it, mWorkspaceItemSpaceFinder) }
-}
-
-private data class AddedItem(
- val itemInfo: ItemInfo,
- val isAnimated: Boolean
-)
diff --git a/tests/src/com/android/launcher3/model/GridSizeMigrationTaskV2Test.kt b/tests/src/com/android/launcher3/model/GridSizeMigrationTaskV2Test.kt
deleted file mode 100644
index 90d7b434df..0000000000
--- a/tests/src/com/android/launcher3/model/GridSizeMigrationTaskV2Test.kt
+++ /dev/null
@@ -1,510 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.launcher3.model
-
-import android.content.Context
-import android.content.Intent
-import android.database.sqlite.SQLiteDatabase
-import android.graphics.Point
-import android.os.Process
-import androidx.test.ext.junit.runners.AndroidJUnit4
-import androidx.test.filters.SmallTest
-import com.android.launcher3.InvariantDeviceProfile
-import com.android.launcher3.LauncherFiles
-import com.android.launcher3.LauncherSettings.Favorites.*
-import com.android.launcher3.config.FeatureFlags
-import com.android.launcher3.model.GridSizeMigrationTaskV2.DbReader
-import com.android.launcher3.pm.UserCache
-import com.android.launcher3.provider.LauncherDbUtils
-import com.android.launcher3.util.LauncherModelHelper
-import com.android.launcher3.util.LauncherModelHelper.*
-import com.google.common.truth.Truth.assertThat
-import org.junit.After
-import org.junit.Before
-import org.junit.Test
-import org.junit.runner.RunWith
-
-/** Unit tests for [GridSizeMigrationTaskV2] */
-@SmallTest
-@RunWith(AndroidJUnit4::class)
-class GridSizeMigrationTaskV2Test {
- private lateinit var modelHelper: LauncherModelHelper
- private lateinit var context: Context
- private lateinit var db: SQLiteDatabase
- private lateinit var validPackages: Set<String>
- private lateinit var idp: InvariantDeviceProfile
- private val testPackage1 = "com.android.launcher3.validpackage1"
- private val testPackage2 = "com.android.launcher3.validpackage2"
- private val testPackage3 = "com.android.launcher3.validpackage3"
- private val testPackage4 = "com.android.launcher3.validpackage4"
- private val testPackage5 = "com.android.launcher3.validpackage5"
- private val testPackage6 = "com.android.launcher3.validpackage6"
- private val testPackage7 = "com.android.launcher3.validpackage7"
- private val testPackage8 = "com.android.launcher3.validpackage8"
- private val testPackage9 = "com.android.launcher3.validpackage9"
- private val testPackage10 = "com.android.launcher3.validpackage10"
-
- @Before
- fun setUp() {
- modelHelper = LauncherModelHelper()
- context = modelHelper.sandboxContext
- db = modelHelper.provider.db
-
- validPackages = setOf(
- TEST_PACKAGE,
- testPackage1,
- testPackage2,
- testPackage3,
- testPackage4,
- testPackage5,
- testPackage6,
- testPackage7,
- testPackage8,
- testPackage9,
- testPackage10
- )
-
- idp = InvariantDeviceProfile.INSTANCE[context]
- val userSerial = UserCache.INSTANCE[context].getSerialNumberForUser(Process.myUserHandle())
- LauncherDbUtils.dropTable(db, TMP_TABLE)
- addTableToDb(db, userSerial, false, TMP_TABLE)
- }
-
- @After
- fun tearDown() {
- modelHelper.destroy()
- }
-
- /**
- * Old migration logic, should be modified once [FeatureFlags.ENABLE_NEW_MIGRATION_LOGIC] is
- * not needed anymore
- */
- @Test
- @Throws(Exception::class)
- fun testMigration() {
- // Src Hotseat icons
- modelHelper.addItem(APP_ICON, 0, HOTSEAT, 0, 0, testPackage1, 1, TMP_CONTENT_URI)
- modelHelper.addItem(SHORTCUT, 1, HOTSEAT, 0, 0, testPackage2, 2, TMP_CONTENT_URI)
- modelHelper.addItem(SHORTCUT, 3, HOTSEAT, 0, 0, testPackage3, 3, TMP_CONTENT_URI)
- modelHelper.addItem(APP_ICON, 4, HOTSEAT, 0, 0, testPackage4, 4, TMP_CONTENT_URI)
- // Src grid icons
- // _ _ _ _ _
- // _ _ _ _ 5
- // _ _ 6 _ 7
- // _ _ 8 _ 9
- // _ _ _ _ _
- modelHelper.addItem(APP_ICON, 0, DESKTOP, 4, 1, testPackage5, 5, TMP_CONTENT_URI)
- modelHelper.addItem(APP_ICON, 0, DESKTOP, 2, 2, testPackage6, 6, TMP_CONTENT_URI)
- modelHelper.addItem(APP_ICON, 0, DESKTOP, 4, 2, testPackage7, 7, TMP_CONTENT_URI)
- modelHelper.addItem(APP_ICON, 0, DESKTOP, 2, 3, testPackage8, 8, TMP_CONTENT_URI)
- modelHelper.addItem(APP_ICON, 0, DESKTOP, 4, 3, testPackage9, 9, TMP_CONTENT_URI)
-
- // Dest hotseat icons
- modelHelper.addItem(SHORTCUT, 1, HOTSEAT, 0, 0, testPackage2)
- // Dest grid icons
- modelHelper.addItem(APP_ICON, 0, DESKTOP, 2, 2, testPackage10)
-
- idp.numDatabaseHotseatIcons = 4
- idp.numColumns = 4
- idp.numRows = 4
- val srcReader = DbReader(db, TMP_TABLE, context, validPackages)
- val destReader = DbReader(db, TABLE_NAME, context, validPackages)
- val task = GridSizeMigrationTaskV2(
- context,
- db,
- srcReader,
- destReader,
- idp.numDatabaseHotseatIcons,
- Point(idp.numColumns, idp.numRows)
- )
- task.migrate(DeviceGridState(context), DeviceGridState(idp))
-
- // Check hotseat items
- var c = context.contentResolver.query(
- CONTENT_URI,
- arrayOf(SCREEN, INTENT),
- "container=$CONTAINER_HOTSEAT",
- null,
- SCREEN,
- null
- ) ?: throw IllegalStateException()
-
- assertThat(c.count).isEqualTo(idp.numDatabaseHotseatIcons)
-
- val screenIndex = c.getColumnIndex(SCREEN)
- var intentIndex = c.getColumnIndex(INTENT)
- c.moveToNext()
- assertThat(c.getInt(screenIndex).toLong()).isEqualTo(0)
- assertThat(c.getString(intentIndex)).contains(testPackage1)
- c.moveToNext()
- assertThat(c.getInt(screenIndex).toLong()).isEqualTo(1)
- assertThat(c.getString(intentIndex)).contains(testPackage2)
- c.moveToNext()
- assertThat(c.getInt(screenIndex).toLong()).isEqualTo(2)
- assertThat(c.getString(intentIndex)).contains(testPackage3)
- c.moveToNext()
- assertThat(c.getInt(screenIndex).toLong()).isEqualTo(3)
- assertThat(c.getString(intentIndex)).contains(testPackage4)
- c.close()
-
- // Check workspace items
- c = context.contentResolver.query(
- CONTENT_URI,
- arrayOf(CELLX, CELLY, INTENT),
- "container=$CONTAINER_DESKTOP",
- null,
- null,
- null
- ) ?: throw IllegalStateException()
-
- intentIndex = c.getColumnIndex(INTENT)
- val cellXIndex = c.getColumnIndex(CELLX)
- val cellYIndex = c.getColumnIndex(CELLY)
- val locMap = HashMap<String, Point>()
- while (c.moveToNext()) {
- locMap[Intent.parseUri(c.getString(intentIndex), 0).getPackage()] =
- Point(c.getInt(cellXIndex), c.getInt(cellYIndex))
- }
- c.close()
- // Expected dest grid icons
- // _ _ _ _
- // 5 6 7 8
- // 9 _ 10_
- // _ _ _ _
- assertThat(locMap.size.toLong()).isEqualTo(6)
- assertThat(locMap[testPackage5]).isEqualTo(Point(0, 1))
- assertThat(locMap[testPackage6]).isEqualTo(Point(1, 1))
- assertThat(locMap[testPackage7]).isEqualTo(Point(2, 1))
- assertThat(locMap[testPackage8]).isEqualTo(Point(3, 1))
- assertThat(locMap[testPackage9]).isEqualTo(Point(0, 2))
- assertThat(locMap[testPackage10]).isEqualTo(Point(2, 2))
- }
-
- @Test
- fun migrateToLargerHotseat() {
- val srcHotseatItems = intArrayOf(
- modelHelper.addItem(APP_ICON, 0, HOTSEAT, 0, 0, testPackage1, 1, TMP_CONTENT_URI),
- modelHelper.addItem(SHORTCUT, 1, HOTSEAT, 0, 0, testPackage2, 2, TMP_CONTENT_URI),
- modelHelper.addItem(APP_ICON, 2, HOTSEAT, 0, 0, testPackage3, 3, TMP_CONTENT_URI),
- modelHelper.addItem(SHORTCUT, 3, HOTSEAT, 0, 0, testPackage4, 4, TMP_CONTENT_URI)
- )
- val numSrcDatabaseHotseatIcons = srcHotseatItems.size
- idp.numDatabaseHotseatIcons = 6
- idp.numColumns = 4
- idp.numRows = 4
- val srcReader = DbReader(db, TMP_TABLE, context, validPackages)
- val destReader = DbReader(db, TABLE_NAME, context, validPackages)
- val task = GridSizeMigrationTaskV2(
- context,
- db,
- srcReader,
- destReader,
- idp.numDatabaseHotseatIcons,
- Point(idp.numColumns, idp.numRows)
- )
- task.migrate(DeviceGridState(context), DeviceGridState(idp))
-
- // Check hotseat items
- val c = context.contentResolver.query(
- CONTENT_URI,
- arrayOf(SCREEN, INTENT),
- "container=$CONTAINER_HOTSEAT",
- null,
- SCREEN,
- null
- ) ?: throw IllegalStateException()
-
- assertThat(c.count.toLong()).isEqualTo(numSrcDatabaseHotseatIcons.toLong())
- val screenIndex = c.getColumnIndex(SCREEN)
- val intentIndex = c.getColumnIndex(INTENT)
- c.moveToNext()
- assertThat(c.getInt(screenIndex)).isEqualTo(0)
- assertThat(c.getString(intentIndex)).contains(testPackage1)
-
- c.moveToNext()
- assertThat(c.getInt(screenIndex)).isEqualTo(1)
- assertThat(c.getString(intentIndex)).contains(testPackage2)
-
- c.moveToNext()
- assertThat(c.getInt(screenIndex)).isEqualTo(2)
- assertThat(c.getString(intentIndex)).contains(testPackage3)
-
- c.moveToNext()
- assertThat(c.getInt(screenIndex)).isEqualTo(3)
- assertThat(c.getString(intentIndex)).contains(testPackage4)
-
- c.close()
- }
-
- @Test
- fun migrateFromLargerHotseat() {
- modelHelper.addItem(APP_ICON, 0, HOTSEAT, 0, 0, testPackage1, 1, TMP_CONTENT_URI)
- modelHelper.addItem(SHORTCUT, 2, HOTSEAT, 0, 0, testPackage2, 2, TMP_CONTENT_URI)
- modelHelper.addItem(APP_ICON, 3, HOTSEAT, 0, 0, testPackage3, 3, TMP_CONTENT_URI)
- modelHelper.addItem(SHORTCUT, 4, HOTSEAT, 0, 0, testPackage4, 4, TMP_CONTENT_URI)
- modelHelper.addItem(APP_ICON, 5, HOTSEAT, 0, 0, testPackage5, 5, TMP_CONTENT_URI)
-
- idp.numDatabaseHotseatIcons = 4
- idp.numColumns = 4
- idp.numRows = 4
- val srcReader = DbReader(db, TMP_TABLE, context, validPackages)
- val destReader = DbReader(db, TABLE_NAME, context, validPackages)
- val task = GridSizeMigrationTaskV2(
- context,
- db,
- srcReader,
- destReader,
- idp.numDatabaseHotseatIcons,
- Point(idp.numColumns, idp.numRows)
- )
- task.migrate(DeviceGridState(context), DeviceGridState(idp))
-
- // Check hotseat items
- val c = context.contentResolver.query(
- CONTENT_URI,
- arrayOf(SCREEN, INTENT),
- "container=$CONTAINER_HOTSEAT",
- null,
- SCREEN,
- null
- ) ?: throw IllegalStateException()
-
- assertThat(c.count.toLong()).isEqualTo(idp.numDatabaseHotseatIcons.toLong())
- val screenIndex = c.getColumnIndex(SCREEN)
- val intentIndex = c.getColumnIndex(INTENT)
-
- c.moveToNext()
- assertThat(c.getInt(screenIndex)).isEqualTo(0)
- assertThat(c.getString(intentIndex)).contains(testPackage1)
-
- c.moveToNext()
- assertThat(c.getInt(screenIndex)).isEqualTo(1)
- assertThat(c.getString(intentIndex)).contains(testPackage2)
-
- c.moveToNext()
- assertThat(c.getInt(screenIndex)).isEqualTo(2)
- assertThat(c.getString(intentIndex)).contains(testPackage3)
-
- c.moveToNext()
- assertThat(c.getInt(screenIndex)).isEqualTo(3)
- assertThat(c.getString(intentIndex)).contains(testPackage4)
-
- c.close()
- }
-
- /**
- * Migrating from a smaller grid to a large one should keep the pages
- * if the column difference is less than 2
- */
- @Test
- @Throws(Exception::class)
- fun migrateFromSmallerGridSmallDifference() {
- enableNewMigrationLogic("4,4")
-
- // Setup src grid
- modelHelper.addItem(APP_ICON, 0, DESKTOP, 2, 2, testPackage1, 5, TMP_CONTENT_URI)
- modelHelper.addItem(APP_ICON, 0, DESKTOP, 2, 3, testPackage2, 6, TMP_CONTENT_URI)
- modelHelper.addItem(APP_ICON, 1, DESKTOP, 3, 1, testPackage3, 7, TMP_CONTENT_URI)
- modelHelper.addItem(APP_ICON, 1, DESKTOP, 3, 2, testPackage4, 8, TMP_CONTENT_URI)
- modelHelper.addItem(APP_ICON, 2, DESKTOP, 3, 3, testPackage5, 9, TMP_CONTENT_URI)
-
- idp.numDatabaseHotseatIcons = 4
- idp.numColumns = 6
- idp.numRows = 5
-
- val srcReader = DbReader(db, TMP_TABLE, context, validPackages)
- val destReader = DbReader(db, TABLE_NAME, context, validPackages)
- val task = GridSizeMigrationTaskV2(
- context,
- db,
- srcReader,
- destReader,
- idp.numDatabaseHotseatIcons,
- Point(idp.numColumns, idp.numRows)
- )
- task.migrate(DeviceGridState(context), DeviceGridState(idp))
-
- // Get workspace items
- val c = context.contentResolver.query(
- CONTENT_URI,
- arrayOf(INTENT, SCREEN),
- "container=$CONTAINER_DESKTOP",
- null,
- null,
- null
- ) ?: throw IllegalStateException()
- val intentIndex = c.getColumnIndex(INTENT)
- val screenIndex = c.getColumnIndex(SCREEN)
-
- // Get in which screen the icon is
- val locMap = HashMap<String, Int>()
- while (c.moveToNext()) {
- locMap[Intent.parseUri(c.getString(intentIndex), 0).getPackage()] =
- c.getInt(screenIndex)
- }
- c.close()
- assertThat(locMap.size).isEqualTo(5)
- assertThat(locMap[testPackage1]).isEqualTo(0)
- assertThat(locMap[testPackage2]).isEqualTo(0)
- assertThat(locMap[testPackage3]).isEqualTo(1)
- assertThat(locMap[testPackage4]).isEqualTo(1)
- assertThat(locMap[testPackage5]).isEqualTo(2)
-
- disableNewMigrationLogic()
- }
-
- /**
- * Migrating from a smaller grid to a large one should reflow the pages
- * if the column difference is more than 2
- */
- @Test
- @Throws(Exception::class)
- fun migrateFromSmallerGridBigDifference() {
- enableNewMigrationLogic("2,2")
-
- // Setup src grid
- modelHelper.addItem(APP_ICON, 0, DESKTOP, 0, 1, testPackage1, 5, TMP_CONTENT_URI)
- modelHelper.addItem(APP_ICON, 0, DESKTOP, 1, 1, testPackage2, 6, TMP_CONTENT_URI)
- modelHelper.addItem(APP_ICON, 1, DESKTOP, 0, 0, testPackage3, 7, TMP_CONTENT_URI)
- modelHelper.addItem(APP_ICON, 1, DESKTOP, 1, 0, testPackage4, 8, TMP_CONTENT_URI)
- modelHelper.addItem(APP_ICON, 2, DESKTOP, 0, 0, testPackage5, 9, TMP_CONTENT_URI)
-
- idp.numDatabaseHotseatIcons = 4
- idp.numColumns = 5
- idp.numRows = 5
- val srcReader = DbReader(db, TMP_TABLE, context, validPackages)
- val destReader = DbReader(db, TABLE_NAME, context, validPackages)
- val task = GridSizeMigrationTaskV2(
- context,
- db,
- srcReader,
- destReader,
- idp.numDatabaseHotseatIcons,
- Point(idp.numColumns, idp.numRows)
- )
- task.migrate(DeviceGridState(context), DeviceGridState(idp))
-
- // Get workspace items
- val c = context.contentResolver.query(
- CONTENT_URI,
- arrayOf(INTENT, SCREEN),
- "container=$CONTAINER_DESKTOP",
- null,
- null,
- null
- ) ?: throw IllegalStateException()
-
- val intentIndex = c.getColumnIndex(INTENT)
- val screenIndex = c.getColumnIndex(SCREEN)
-
- // Get in which screen the icon is
- val locMap = HashMap<String, Int>()
- while (c.moveToNext()) {
- locMap[Intent.parseUri(c.getString(intentIndex), 0).getPackage()] =
- c.getInt(screenIndex)
- }
- c.close()
-
- // All icons fit the first screen
- assertThat(locMap.size).isEqualTo(5)
- assertThat(locMap[testPackage1]).isEqualTo(0)
- assertThat(locMap[testPackage2]).isEqualTo(0)
- assertThat(locMap[testPackage3]).isEqualTo(0)
- assertThat(locMap[testPackage4]).isEqualTo(0)
- assertThat(locMap[testPackage5]).isEqualTo(0)
- disableNewMigrationLogic()
- }
-
- /**
- * Migrating from a larger grid to a smaller, we reflow from page 0
- */
- @Test
- @Throws(Exception::class)
- fun migrateFromLargerGrid() {
- enableNewMigrationLogic("5,5")
-
- // Setup src grid
- modelHelper.addItem(APP_ICON, 0, DESKTOP, 0, 1, testPackage1, 5, TMP_CONTENT_URI)
- modelHelper.addItem(APP_ICON, 0, DESKTOP, 1, 1, testPackage2, 6, TMP_CONTENT_URI)
- modelHelper.addItem(APP_ICON, 1, DESKTOP, 0, 0, testPackage3, 7, TMP_CONTENT_URI)
- modelHelper.addItem(APP_ICON, 1, DESKTOP, 1, 0, testPackage4, 8, TMP_CONTENT_URI)
- modelHelper.addItem(APP_ICON, 2, DESKTOP, 0, 0, testPackage5, 9, TMP_CONTENT_URI)
-
- idp.numDatabaseHotseatIcons = 4
- idp.numColumns = 4
- idp.numRows = 4
- val srcReader = DbReader(db, TMP_TABLE, context, validPackages)
- val destReader = DbReader(db, TABLE_NAME, context, validPackages)
- val task = GridSizeMigrationTaskV2(
- context,
- db,
- srcReader,
- destReader,
- idp.numDatabaseHotseatIcons,
- Point(idp.numColumns, idp.numRows)
- )
- task.migrate(DeviceGridState(context), DeviceGridState(idp))
-
- // Get workspace items
- val c = context.contentResolver.query(
- CONTENT_URI,
- arrayOf(INTENT, SCREEN),
- "container=$CONTAINER_DESKTOP",
- null,
- null,
- null
- ) ?: throw IllegalStateException()
- val intentIndex = c.getColumnIndex(INTENT)
- val screenIndex = c.getColumnIndex(SCREEN)
-
- // Get in which screen the icon is
- val locMap = HashMap<String, Int>()
- while (c.moveToNext()) {
- locMap[Intent.parseUri(c.getString(intentIndex), 0).getPackage()] =
- c.getInt(screenIndex)
- }
- c.close()
-
- // All icons fit the first screen
- assertThat(locMap.size).isEqualTo(5)
- assertThat(locMap[testPackage1]).isEqualTo(0)
- assertThat(locMap[testPackage2]).isEqualTo(0)
- assertThat(locMap[testPackage3]).isEqualTo(0)
- assertThat(locMap[testPackage4]).isEqualTo(0)
- assertThat(locMap[testPackage5]).isEqualTo(0)
-
- disableNewMigrationLogic()
- }
-
- private fun enableNewMigrationLogic(srcGridSize: String) {
- context.getSharedPreferences(FeatureFlags.FLAGS_PREF_NAME, Context.MODE_PRIVATE)
- .edit()
- .putBoolean(FeatureFlags.ENABLE_NEW_MIGRATION_LOGIC.key, true)
- .commit()
- context.getSharedPreferences(LauncherFiles.SHARED_PREFERENCES_KEY, Context.MODE_PRIVATE)
- .edit()
- .putString(DeviceGridState.KEY_WORKSPACE_SIZE, srcGridSize)
- .commit()
- FeatureFlags.initialize(context)
- }
-
- private fun disableNewMigrationLogic() {
- context.getSharedPreferences(FeatureFlags.FLAGS_PREF_NAME, Context.MODE_PRIVATE)
- .edit()
- .putBoolean(FeatureFlags.ENABLE_NEW_MIGRATION_LOGIC.key, false)
- .commit()
- }
-} \ No newline at end of file
diff --git a/tests/src/com/android/launcher3/model/WorkspaceItemSpaceFinderTest.kt b/tests/src/com/android/launcher3/model/WorkspaceItemSpaceFinderTest.kt
deleted file mode 100644
index bfb1ac64c4..0000000000
--- a/tests/src/com/android/launcher3/model/WorkspaceItemSpaceFinderTest.kt
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.launcher3.model
-
-import android.graphics.Rect
-import androidx.test.ext.junit.runners.AndroidJUnit4
-import androidx.test.filters.SmallTest
-import com.google.common.truth.Truth.assertThat
-import org.junit.After
-import org.junit.Before
-import org.junit.Test
-import org.junit.runner.RunWith
-
-/**
- * Tests for [WorkspaceItemSpaceFinder]
- */
-@SmallTest
-@RunWith(AndroidJUnit4::class)
-class WorkspaceItemSpaceFinderTest : AbstractWorkspaceModelTest() {
-
- private val mItemSpaceFinder = WorkspaceItemSpaceFinder()
-
- @Before
- override fun setup() {
- super.setup()
- }
-
- @After
- override fun tearDown() {
- super.tearDown()
- }
-
- private fun findSpace(spanX: Int, spanY: Int): NewItemSpace =
- mItemSpaceFinder.findSpaceForItem(
- mAppState, mModelHelper.bgDataModel,
- mExistingScreens, mNewScreens, spanX, spanY
- )
- .let { NewItemSpace.fromIntArray(it) }
-
- private fun assertRegionVacant(newItemSpace: NewItemSpace, spanX: Int, spanY: Int) {
- assertThat(
- mScreenOccupancy[newItemSpace.screenId]
- .isRegionVacant(newItemSpace.cellX, newItemSpace.cellY, spanX, spanY)
- ).isTrue()
- }
-
- @Test
- fun justEnoughSpaceOnFirstScreen_whenFindSpaceForItem_thenReturnFirstScreenId() {
- setupWorkspacesWithSpaces(
- // 3x2 space on screen 0, but it should be skipped
- screen0 = listOf(Rect(2, 0, 5, 2)),
- screen1 = listOf(Rect(2, 2, 3, 3)), // 1x1 space
- // 2 spaces of sizes 3x2 and 2x3
- screen2 = listOf(Rect(2, 0, 5, 2), Rect(0, 2, 2, 5)),
- )
-
- val spaceFound = findSpace(1, 1)
-
- assertThat(spaceFound.screenId).isEqualTo(1)
- assertRegionVacant(spaceFound, 1, 1)
- }
-
- @Test
- fun notEnoughSpaceOnFirstScreen_whenFindSpaceForItem_thenReturnSecondScreenId() {
- setupWorkspacesWithSpaces(
- // 3x2 space on screen 0, but it should be skipped
- screen0 = listOf(Rect(2, 0, 5, 2)),
- screen1 = listOf(Rect(2, 2, 3, 3)), // 1x1 space
- // 2 spaces of sizes 3x2 and 2x3
- screen2 = listOf(Rect(2, 0, 5, 2), Rect(0, 2, 2, 5)),
- )
-
- // Find a larger space
- val spaceFound = findSpace(2, 3)
-
- assertThat(spaceFound.screenId).isEqualTo(2)
- assertRegionVacant(spaceFound, 2, 3)
- }
-
- @Test
- fun notEnoughSpaceOnExistingScreens_returnNewScreenId() {
- setupWorkspacesWithSpaces(
- // 3x2 space on screen 0, but it should be skipped
- screen0 = listOf(Rect(2, 0, 5, 2)),
- // 2 spaces of sizes 3x2 and 2x3
- screen1 = listOf(Rect(2, 0, 5, 2), Rect(0, 2, 2, 5)),
- // 2 spaces of sizes 1x2 and 2x2
- screen2 = listOf(Rect(1, 0, 2, 2), Rect(3, 2, 5, 4)),
- )
-
- val oldScreens = mExistingScreens.clone()
- val spaceFound = findSpace(3, 3)
-
- assertThat(oldScreens.contains(spaceFound.screenId)).isFalse()
- assertThat(mNewScreens.contains(spaceFound.screenId)).isTrue()
- }
-
- @Test
- fun firstScreenIsEmptyButSecondIsNotEmpty_returnSecondScreenId() {
- setupWorkspacesWithSpaces(
- // 3x2 space on screen 0, but it should be skipped
- screen0 = listOf(Rect(2, 0, 5, 2)),
- // empty screens are skipped
- screen2 = listOf(Rect(2, 0, 5, 2)), // 3x2 space
- )
-
- val spaceFound = findSpace(2, 1)
-
- assertThat(spaceFound.screenId).isEqualTo(2)
- assertRegionVacant(spaceFound, 2, 1)
- }
-
- @Test
- fun twoEmptyMiddleScreens_returnThirdScreen() {
- setupWorkspacesWithSpaces(
- // 3x2 space on screen 0, but it should be skipped
- screen0 = listOf(Rect(2, 0, 5, 2)),
- // empty screens are skipped
- screen3 = listOf(Rect(1, 1, 4, 4)), // 3x3 space
- )
-
- val spaceFound = findSpace(2, 3)
-
- assertThat(spaceFound.screenId).isEqualTo(3)
- assertRegionVacant(spaceFound, 2, 3)
- }
-
- @Test
- fun allExistingPagesAreFull_returnNewScreenId() {
- setupWorkspacesWithSpaces(
- // 3x2 space on screen 0, but it should be skipped
- screen0 = listOf(Rect(2, 0, 5, 2)),
- screen1 = fullScreenSpaces,
- screen2 = fullScreenSpaces,
- )
-
- val spaceFound = findSpace(2, 3)
-
- assertThat(spaceFound.screenId).isEqualTo(3)
- assertThat(mNewScreens.contains(spaceFound.screenId)).isTrue()
- }
-
- @Test
- fun firstTwoPagesAreFull_and_ThirdPageIsEmpty_returnThirdPage() {
- setupWorkspacesWithSpaces(
- // 3x2 space on screen 0, but it should be skipped
- screen0 = listOf(Rect(2, 0, 5, 2)),
- screen1 = fullScreenSpaces, // full screens are skipped
- screen2 = fullScreenSpaces, // full screens are skipped
- screen3 = emptyScreenSpaces
- )
-
- val spaceFound = findSpace(3, 1)
-
- assertThat(spaceFound.screenId).isEqualTo(3)
- assertRegionVacant(spaceFound, 3, 1)
- }
-}
diff --git a/tests/src/com/android/launcher3/secondarydisplay/SDLauncherTest.java b/tests/src/com/android/launcher3/secondarydisplay/SDLauncherTest.java
deleted file mode 100644
index fd86cf1144..0000000000
--- a/tests/src/com/android/launcher3/secondarydisplay/SDLauncherTest.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2021 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.launcher3.secondarydisplay;
-
-import static androidx.test.core.app.ActivityScenario.launch;
-
-import androidx.test.core.app.ActivityScenario;
-import androidx.test.espresso.intent.Intents;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.MediumTest;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-/**
- * Tests for {@link SecondaryDisplayLauncher}
- */
-@MediumTest
-@RunWith(AndroidJUnit4.class)
-public class SDLauncherTest {
-
- @Before
- public void setUp() {
- Intents.init();
- }
-
- @After
- public void tearDown() {
- Intents.release();
- }
-
- @Test
- public void testAllAppsListOpens() {
- ActivityScenario<SecondaryDisplayLauncher> launcher =
- launch(SecondaryDisplayLauncher.class);
- launcher.onActivity(l -> l.showAppDrawer(true));
- }
-}
diff --git a/tests/src/com/android/launcher3/testcomponent/OtherBaseTestingActivity.java b/tests/src/com/android/launcher3/testcomponent/OtherBaseTestingActivity.java
deleted file mode 100644
index 8bcab6265c..0000000000
--- a/tests/src/com/android/launcher3/testcomponent/OtherBaseTestingActivity.java
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright (C) 2018 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.launcher3.testcomponent;
-
-/**
- * Extension of BaseTestingActivity to help test many activities open at once.
- */
-public class OtherBaseTestingActivity extends BaseTestingActivity {}
diff --git a/tests/src/com/android/launcher3/touch/SingleAxisSwipeDetectorTest.java b/tests/src/com/android/launcher3/touch/SingleAxisSwipeDetectorTest.java
index 260f5568e0..472e1a1c91 100644
--- a/tests/src/com/android/launcher3/touch/SingleAxisSwipeDetectorTest.java
+++ b/tests/src/com/android/launcher3/touch/SingleAxisSwipeDetectorTest.java
@@ -30,7 +30,6 @@ import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
-import android.content.Context;
import android.util.Log;
import android.view.MotionEvent;
import android.view.ViewConfiguration;
@@ -59,7 +58,6 @@ public class SingleAxisSwipeDetectorTest {
private TouchEventGenerator mGenerator;
private SingleAxisSwipeDetector mDetector;
private int mTouchSlop;
- Context mContext;
@Mock
private SingleAxisSwipeDetector.Listener mMockListener;
@@ -71,13 +69,12 @@ public class SingleAxisSwipeDetectorTest {
public void setup() {
MockitoAnnotations.initMocks(this);
mGenerator = new TouchEventGenerator((ev) -> mDetector.onTouchEvent(ev));
- mContext = InstrumentationRegistry.getTargetContext();
- ViewConfiguration orgConfig = ViewConfiguration.get(mContext);
+ ViewConfiguration orgConfig = ViewConfiguration
+ .get(InstrumentationRegistry.getTargetContext());
doReturn(orgConfig.getScaledMaximumFlingVelocity()).when(mMockConfig)
.getScaledMaximumFlingVelocity();
- mDetector = new SingleAxisSwipeDetector(mContext,
- mMockConfig, mMockListener, VERTICAL, false);
+ mDetector = new SingleAxisSwipeDetector(mMockConfig, mMockListener, VERTICAL, false);
mDetector.setDetectableScrollConditions(DIRECTION_BOTH, false);
mTouchSlop = orgConfig.getScaledTouchSlop();
doReturn(mTouchSlop).when(mMockConfig).getScaledTouchSlop();
@@ -87,8 +84,7 @@ public class SingleAxisSwipeDetectorTest {
@Test
public void testDragStart_verticalPositive() {
- mDetector = new SingleAxisSwipeDetector(mContext,
- mMockConfig, mMockListener, VERTICAL, false);
+ mDetector = new SingleAxisSwipeDetector(mMockConfig, mMockListener, VERTICAL, false);
mDetector.setDetectableScrollConditions(DIRECTION_POSITIVE, false);
mGenerator.put(0, 100, 100);
mGenerator.move(0, 100, 100 - mTouchSlop);
@@ -98,8 +94,7 @@ public class SingleAxisSwipeDetectorTest {
@Test
public void testDragStart_verticalNegative() {
- mDetector = new SingleAxisSwipeDetector(mContext,
- mMockConfig, mMockListener, VERTICAL, false);
+ mDetector = new SingleAxisSwipeDetector(mMockConfig, mMockListener, VERTICAL, false);
mDetector.setDetectableScrollConditions(DIRECTION_NEGATIVE, false);
mGenerator.put(0, 100, 100);
mGenerator.move(0, 100, 100 + mTouchSlop);
@@ -117,8 +112,7 @@ public class SingleAxisSwipeDetectorTest {
@Test
public void testDragStart_horizontalPositive() {
- mDetector = new SingleAxisSwipeDetector(mContext,
- mMockConfig, mMockListener, HORIZONTAL, false);
+ mDetector = new SingleAxisSwipeDetector(mMockConfig, mMockListener, HORIZONTAL, false);
mDetector.setDetectableScrollConditions(DIRECTION_POSITIVE, false);
mGenerator.put(0, 100, 100);
@@ -129,8 +123,7 @@ public class SingleAxisSwipeDetectorTest {
@Test
public void testDragStart_horizontalNegative() {
- mDetector = new SingleAxisSwipeDetector(mContext,
- mMockConfig, mMockListener, HORIZONTAL, false);
+ mDetector = new SingleAxisSwipeDetector(mMockConfig, mMockListener, HORIZONTAL, false);
mDetector.setDetectableScrollConditions(DIRECTION_NEGATIVE, false);
mGenerator.put(0, 100, 100);
@@ -141,8 +134,7 @@ public class SingleAxisSwipeDetectorTest {
@Test
public void testDragStart_horizontalRtlPositive() {
- mDetector = new SingleAxisSwipeDetector(mContext,
- mMockConfig, mMockListener, HORIZONTAL, true);
+ mDetector = new SingleAxisSwipeDetector(mMockConfig, mMockListener, HORIZONTAL, true);
mDetector.setDetectableScrollConditions(DIRECTION_POSITIVE, false);
mGenerator.put(0, 100, 100);
@@ -153,8 +145,7 @@ public class SingleAxisSwipeDetectorTest {
@Test
public void testDragStart_horizontalRtlNegative() {
- mDetector = new SingleAxisSwipeDetector(mContext,
- mMockConfig, mMockListener, HORIZONTAL, true);
+ mDetector = new SingleAxisSwipeDetector(mMockConfig, mMockListener, HORIZONTAL, true);
mDetector.setDetectableScrollConditions(DIRECTION_NEGATIVE, false);
mGenerator.put(0, 100, 100);
diff --git a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
index 6f8b9d2967..dcb6dc1b02 100644
--- a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
+++ b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
@@ -33,13 +33,12 @@ import android.content.pm.LauncherActivityInfo;
import android.content.pm.LauncherApps;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
-import android.graphics.Point;
import android.os.Debug;
import android.os.Process;
import android.os.RemoteException;
+import android.os.StrictMode;
import android.os.UserHandle;
import android.os.UserManager;
-import android.system.OsConstants;
import android.util.Log;
import androidx.test.InstrumentationRegistry;
@@ -53,10 +52,9 @@ import com.android.launcher3.LauncherAppState;
import com.android.launcher3.LauncherSettings;
import com.android.launcher3.LauncherState;
import com.android.launcher3.Utilities;
+import com.android.launcher3.common.WidgetUtils;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.statemanager.StateManager;
-import com.android.launcher3.tapl.HomeAllApps;
-import com.android.launcher3.tapl.HomeAppIcon;
import com.android.launcher3.tapl.LauncherInstrumentation;
import com.android.launcher3.tapl.LauncherInstrumentation.ContainerType;
import com.android.launcher3.tapl.TestHelpers;
@@ -65,10 +63,8 @@ import com.android.launcher3.testing.TestProtocol;
import com.android.launcher3.util.LooperExecutor;
import com.android.launcher3.util.PackageManagerHelper;
import com.android.launcher3.util.Wait;
-import com.android.launcher3.util.WidgetUtils;
import com.android.launcher3.util.rule.FailureWatcher;
import com.android.launcher3.util.rule.LauncherActivityRule;
-import com.android.launcher3.util.rule.SamplerRule;
import com.android.launcher3.util.rule.ScreenRecordRule;
import com.android.launcher3.util.rule.ShellCommandRule;
import com.android.launcher3.util.rule.TestStabilityRule;
@@ -88,7 +84,6 @@ import java.lang.annotation.Target;
import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
@@ -104,9 +99,11 @@ public abstract class AbstractLauncherUiTest {
public static final long DEFAULT_UI_TIMEOUT = 10000;
private static final String TAG = "AbstractLauncherUiTest";
+ private static String sStrictmodeDetectedActivityLeak;
private static boolean sDumpWasGenerated = false;
- private static boolean sActivityLeakReported = false;
+ private static boolean sActivityLeakReported;
private static final String SYSTEMUI_PACKAGE = "com.android.systemui";
+ protected static final ActivityLeakTracker ACTIVITY_LEAK_TRACKER = new ActivityLeakTracker();
protected LooperExecutor mMainThreadExecutor = MAIN_EXECUTOR;
protected final UiDevice mDevice = UiDevice.getInstance(getInstrumentation());
@@ -115,29 +112,49 @@ public abstract class AbstractLauncherUiTest {
protected String mTargetPackage;
private int mLauncherPid;
+ static {
+ if (TestHelpers.isInLauncherProcess()) {
+ StrictMode.VmPolicy.Builder builder =
+ new StrictMode.VmPolicy.Builder()
+ .penaltyLog()
+ .penaltyListener(Runnable::run, violation -> {
+ if (sStrictmodeDetectedActivityLeak == null) {
+ sStrictmodeDetectedActivityLeak = violation.toString() + ", "
+ + dumpHprofData() + ".";
+ }
+ });
+ StrictMode.setVmPolicy(builder.build());
+ }
+ }
+
public static void checkDetectedLeaks(LauncherInstrumentation launcher) {
if (sActivityLeakReported) return;
+ if (sStrictmodeDetectedActivityLeak != null) {
+ // Report from the test thread strictmode violations detected in the main thread.
+ sActivityLeakReported = true;
+ Assert.fail(sStrictmodeDetectedActivityLeak);
+ }
+
// Check whether activity leak detector has found leaked activities.
- Wait.atMost(() -> getActivityLeakErrorMessage(launcher),
+ Wait.atMost(AbstractLauncherUiTest::getActivityLeakErrorMessage,
() -> {
launcher.forceGc();
return MAIN_EXECUTOR.submit(
- () -> launcher.noLeakedActivities()).get();
+ () -> ACTIVITY_LEAK_TRACKER.noLeakedActivities()).get();
}, DEFAULT_UI_TIMEOUT, launcher);
}
- private static String getActivityLeakErrorMessage(LauncherInstrumentation launcher) {
+ private static String getActivityLeakErrorMessage() {
sActivityLeakReported = true;
- return "Activity leak detector has found leaked activities, "
- + dumpHprofData(launcher, false) + ".";
+ return "Activity leak detector has found leaked activities, " + dumpHprofData() + ".";
}
- public static String dumpHprofData(LauncherInstrumentation launcher, boolean intentionalLeak) {
- if (intentionalLeak) return "intentional leak; not generating dump";
-
+ public static String dumpHprofData() {
String result;
if (sDumpWasGenerated) {
+ Log.d("b/195319692", "dump has already been generated by another test",
+ new Exception());
result = "dump has already been generated by another test";
} else {
try {
@@ -152,13 +169,15 @@ public abstract class AbstractLauncherUiTest {
"am dumpheap " + device.getLauncherPackageName() + " " + fileName);
}
sDumpWasGenerated = true;
- result = "saved memory dump as an artifact";
+ Log.d("b/195319692", "sDumpWasGenerated := true", new Exception());
+ result = "memory dump filename: " + fileName;
} catch (Throwable e) {
Log.e(TAG, "dumpHprofData failed", e);
result = "failed to save memory dump";
}
}
- return result + ". Full list of activities: " + launcher.getRootedActivitiesList();
+ return result
+ + ". Full list of activities: " + ACTIVITY_LEAK_TRACKER.getActivitiesList();
}
protected AbstractLauncherUiTest() {
@@ -216,8 +235,7 @@ public abstract class AbstractLauncherUiTest {
}
protected TestRule getRulesInsideActivityMonitor() {
- final RuleChain inner = RuleChain
- .outerRule(new PortraitLandscapeRunner(this))
+ final RuleChain inner = RuleChain.outerRule(new PortraitLandscapeRunner(this))
.around(new FailureWatcher(mDevice, mLauncher));
return TestHelpers.isInLauncherProcess()
@@ -228,8 +246,7 @@ public abstract class AbstractLauncherUiTest {
@Rule
public TestRule mOrderSensitiveRules = RuleChain
- .outerRule(new SamplerRule())
- .around(new TestStabilityRule())
+ .outerRule(new TestStabilityRule())
.around(mActivityMonitor)
.around(getRulesInsideActivityMonitor());
@@ -237,12 +254,26 @@ public abstract class AbstractLauncherUiTest {
return mDevice;
}
+ private boolean hasSystemUiObject(String resId) {
+ return mDevice.hasObject(By.res(SYSTEMUI_PACKAGE, resId));
+ }
+
@Before
public void setUp() throws Exception {
mLauncher.onTestStart();
- Assert.assertTrue("Keyguard is visible, which is likely caused by a crash in SysUI",
+ Log.d(TAG, "Before disabling battery defender");
+ mDevice.executeShellCommand("setprop vendor.battery.defender.disable 1");
+ Log.d(TAG, "Before enabling stay awake");
+ mDevice.executeShellCommand("settings put global stay_on_while_plugged_in 3");
+ for (int i = 0; i < 10 && hasSystemUiObject("keyguard_status_view"); ++i) {
+ Log.d(TAG, "Before unlocking the phone");
+ mDevice.executeShellCommand("input keyevent 82");
+ mDevice.waitForIdle();
+ }
+ Assert.assertTrue("Keyguard still visible",
TestHelpers.wait(
Until.gone(By.res(SYSTEMUI_PACKAGE, "keyguard_status_view")), 60000));
+ Log.d(TAG, "Keyguard is not visible");
final String launcherPackageName = mDevice.getLauncherPackageName();
try {
@@ -269,6 +300,8 @@ public abstract class AbstractLauncherUiTest {
if (userManager != null) {
for (UserHandle userHandle : userManager.getUserProfiles()) {
if (!userHandle.isSystem()) {
+ Log.d(TestProtocol.WORK_PROFILE_REMOVED,
+ "removing user " + userHandle.getIdentifier());
mDevice.executeShellCommand("pm remove-user " + userHandle.getIdentifier());
}
}
@@ -333,12 +366,7 @@ public abstract class AbstractLauncherUiTest {
*/
protected <T> T getOnUiThread(final Callable<T> callback) {
try {
- return mMainThreadExecutor.submit(callback).get(DEFAULT_UI_TIMEOUT,
- TimeUnit.MILLISECONDS);
- } catch (TimeoutException e) {
- Log.e(TAG, "Timeout in getOnUiThread, sending SIGABRT", e);
- Process.sendSignal(Process.myPid(), OsConstants.SIGABRT);
- throw new RuntimeException(e);
+ return mMainThreadExecutor.submit(callback).get();
} catch (Throwable e) {
throw new RuntimeException(e);
}
@@ -357,20 +385,13 @@ public abstract class AbstractLauncherUiTest {
}
// Cannot be used in TaplTests between a Tapl call injecting a gesture and a tapl call
- // expecting the results of that gesture because the wait can hide flakeness.
+ // expecting
+ // the results of that gesture because the wait can hide flakeness.
protected void waitForState(String message, Supplier<LauncherState> state) {
waitForLauncherCondition(message,
launcher -> launcher.getStateManager().getCurrentStableState() == state.get());
}
- // Cannot be used in TaplTests between a Tapl call injecting a gesture and a tapl call
- // expecting the results of that gesture because the wait can hide flakeness.
- protected void waitForStateTransitionToEnd(String message, Supplier<LauncherState> state) {
- waitForLauncherCondition(message,
- launcher -> launcher.getStateManager().isInStableState(state.get())
- && !launcher.getStateManager().isInTransition());
- }
-
protected void waitForResumed(String message) {
waitForLauncherCondition(message, launcher -> launcher.hasBeenResumed());
}
@@ -514,7 +535,7 @@ public abstract class AbstractLauncherUiTest {
"Launcher still active", launcher -> launcher == null, DEFAULT_UI_TIMEOUT);
}
- protected boolean isInLaunchedApp(Launcher launcher) {
+ protected boolean isInBackground(Launcher launcher) {
return launcher == null || !launcher.hasBeenResumed();
}
@@ -554,7 +575,7 @@ public abstract class AbstractLauncherUiTest {
ordinal == TestProtocol.NORMAL_STATE_ORDINAL);
break;
}
- case HOME_ALL_APPS: {
+ case ALL_APPS: {
assertTrue(
"Launcher is not resumed in state: " + expectedContainerType,
isResumed);
@@ -569,8 +590,7 @@ public abstract class AbstractLauncherUiTest {
ordinal == TestProtocol.OVERVIEW_STATE_ORDINAL);
break;
}
- case TASKBAR_ALL_APPS:
- case LAUNCHED_APP: {
+ case BACKGROUND: {
assertTrue("Launcher is resumed in state: " + expectedContainerType,
!isResumed);
assertTrue(TestProtocol.stateOrdinalToString(ordinal),
@@ -583,11 +603,10 @@ public abstract class AbstractLauncherUiTest {
}
} else {
assertTrue(
- "Container type is not LAUNCHED_APP, TASKBAR_ALL_APPS "
- + "or FALLBACK_OVERVIEW: " + expectedContainerType,
- expectedContainerType == ContainerType.LAUNCHED_APP
- || expectedContainerType == ContainerType.TASKBAR_ALL_APPS
- || expectedContainerType == ContainerType.FALLBACK_OVERVIEW);
+ "Container type is not BACKGROUND or FALLBACK_OVERVIEW: "
+ + expectedContainerType,
+ expectedContainerType == ContainerType.BACKGROUND ||
+ expectedContainerType == ContainerType.FALLBACK_OVERVIEW);
}
}
@@ -607,30 +626,4 @@ public abstract class AbstractLauncherUiTest {
protected void onLauncherActivityClose(Launcher launcher) {
}
-
- protected HomeAppIcon createShortcutInCenterIfNotExist(String name) {
- Point dimension = mLauncher.getWorkspace().getIconGridDimensions();
- return createShortcutIfNotExist(name, dimension.x / 2, dimension.y / 2);
- }
-
- protected HomeAppIcon createShortcutIfNotExist(String name, Point cellPosition) {
- return createShortcutIfNotExist(name, cellPosition.x, cellPosition.y);
- }
-
- protected HomeAppIcon createShortcutIfNotExist(String name, int cellX, int cellY) {
- HomeAppIcon homeAppIcon = mLauncher.getWorkspace().tryGetWorkspaceAppIcon(name);
- if (homeAppIcon == null) {
- HomeAllApps allApps = mLauncher.getWorkspace().switchToAllApps();
- allApps.freeze();
- try {
- allApps.getAppIcon(name).dragToWorkspace(cellX, cellY);
- } finally {
- allApps.unfreeze();
- }
- homeAppIcon = mLauncher.getWorkspace().getWorkspaceAppIcon(name);
- }
- return homeAppIcon;
- }
-
-
}
diff --git a/tests/src/com/android/launcher3/ui/ActivityLeakTracker.java b/tests/src/com/android/launcher3/ui/ActivityLeakTracker.java
new file mode 100644
index 0000000000..2db7472912
--- /dev/null
+++ b/tests/src/com/android/launcher3/ui/ActivityLeakTracker.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2020 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.launcher3.ui;
+
+import android.app.Activity;
+import android.app.Application;
+import android.os.Bundle;
+
+import androidx.test.InstrumentationRegistry;
+
+import com.android.launcher3.tapl.TestHelpers;
+
+import java.util.WeakHashMap;
+import java.util.stream.Collectors;
+
+public class ActivityLeakTracker implements Application.ActivityLifecycleCallbacks {
+ private final WeakHashMap<Activity, Boolean> mActivities = new WeakHashMap<>();
+
+ private int mActivitiesCreated;
+
+ ActivityLeakTracker() {
+ if (!TestHelpers.isInLauncherProcess()) return;
+ final Application app =
+ (Application) InstrumentationRegistry.getTargetContext().getApplicationContext();
+ app.registerActivityLifecycleCallbacks(this);
+ }
+
+ public int getActivitiesCreated() {
+ return mActivitiesCreated;
+ }
+
+ @Override
+ public void onActivityCreated(Activity activity, Bundle bundle) {
+ mActivities.put(activity, true);
+ ++mActivitiesCreated;
+ }
+
+ @Override
+ public void onActivityStarted(Activity activity) {
+ }
+
+ @Override
+ public void onActivityResumed(Activity activity) {
+ }
+
+ @Override
+ public void onActivityPaused(Activity activity) {
+ }
+
+ @Override
+ public void onActivityStopped(Activity activity) {
+ }
+
+ @Override
+ public void onActivitySaveInstanceState(Activity activity, Bundle bundle) {
+ }
+
+ @Override
+ public void onActivityDestroyed(Activity activity) {
+ }
+
+ public boolean noLeakedActivities() {
+ for (Activity activity : mActivities.keySet()) {
+ if (activity.isDestroyed()) {
+ return false;
+ }
+ }
+
+ return mActivities.size() <= 2;
+ }
+
+ public String getActivitiesList() {
+ return mActivities.keySet().stream().map(a -> a.getClass().getSimpleName())
+ .collect(Collectors.joining(","));
+ }
+}
diff --git a/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java b/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java
index 8a97c6ba5b..4dd44f4193 100644
--- a/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java
+++ b/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java
@@ -18,17 +18,12 @@ package com.android.launcher3.ui;
import static androidx.test.InstrumentationRegistry.getInstrumentation;
-import static com.google.common.truth.Truth.assertThat;
-
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
-import android.content.Intent;
-import android.graphics.Point;
-
import androidx.test.filters.LargeTest;
import androidx.test.runner.AndroidJUnit4;
@@ -39,35 +34,22 @@ import com.android.launcher3.tapl.AllApps;
import com.android.launcher3.tapl.AppIcon;
import com.android.launcher3.tapl.AppIconMenu;
import com.android.launcher3.tapl.AppIconMenuItem;
-import com.android.launcher3.tapl.Folder;
-import com.android.launcher3.tapl.FolderIcon;
-import com.android.launcher3.tapl.HomeAllApps;
-import com.android.launcher3.tapl.HomeAppIcon;
-import com.android.launcher3.tapl.HomeAppIconMenu;
-import com.android.launcher3.tapl.HomeAppIconMenuItem;
import com.android.launcher3.tapl.Widgets;
import com.android.launcher3.tapl.Workspace;
-import com.android.launcher3.util.TestUtil;
import com.android.launcher3.util.rule.ScreenRecordRule.ScreenRecord;
+import com.android.launcher3.views.OptionsPopupView;
import com.android.launcher3.widget.picker.WidgetsFullSheet;
import com.android.launcher3.widget.picker.WidgetsRecyclerView;
import org.junit.Before;
-import org.junit.Rule;
+import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
-import java.io.IOException;
-import java.util.Map;
-
@LargeTest
@RunWith(AndroidJUnit4.class)
public class TaplTestsLauncher3 extends AbstractLauncherUiTest {
private static final String APP_NAME = "LauncherTestApp";
- private static final String DUMMY_APP_NAME = "Aardwolf";
- private static final String MAPS_APP_NAME = "Maps";
- private static final String STORE_APP_NAME = "Play Store";
- private static final String GMAIL_APP_NAME = "Gmail";
@Before
public void setUp() throws Exception {
@@ -98,8 +80,8 @@ public class TaplTestsLauncher3 extends AbstractLauncherUiTest {
assertTrue(message, failed);
}
- public static boolean isWorkspaceScrollable(Launcher launcher) {
- return launcher.getWorkspace().getPageCount() > launcher.getWorkspace().getPanelCount();
+ private boolean isWorkspaceScrollable(Launcher launcher) {
+ return launcher.getWorkspace().getPageCount() > 1;
}
private int getCurrentWorkspacePage(Launcher launcher) {
@@ -111,14 +93,23 @@ public class TaplTestsLauncher3 extends AbstractLauncherUiTest {
}
@Test
+ @ScreenRecord //b/187080582
public void testDevicePressMenu() throws Exception {
mDevice.pressMenu();
mDevice.waitForIdle();
executeOnLauncher(
- launcher -> assertNotNull("Launcher internal state didn't switch to Showing Menu",
- launcher.getOptionsPopup()));
+ launcher -> assertTrue("Launcher internal state didn't switch to Showing Menu",
+ OptionsPopupView.getOptionsPopup(launcher) != null));
// Check that pressHome works when the menu is shown.
- mLauncher.goHome();
+ mLauncher.pressHome();
+ }
+
+ @Ignore
+ public void testOpenHomeSettingsFromWorkspace() {
+ mDevice.pressMenu();
+ mDevice.waitForIdle();
+ mLauncher.getOptionsPopupMenu().getMenuItem("Home settings")
+ .launch(mDevice.getLauncherPackageName());
}
@Test
@@ -130,7 +121,7 @@ public class TaplTestsLauncher3 extends AbstractLauncherUiTest {
} finally {
allApps.unfreeze();
}
- mLauncher.goHome();
+ mLauncher.pressHome();
}
public static void runAllAppsTest(AbstractLauncherUiTest test, AllApps allApps) {
@@ -192,7 +183,6 @@ public class TaplTestsLauncher3 extends AbstractLauncherUiTest {
}
@Test
- @ScreenRecord // b/202433017
public void testWorkspace() throws Exception {
final Workspace workspace = mLauncher.getWorkspace();
@@ -205,9 +195,8 @@ public class TaplTestsLauncher3 extends AbstractLauncherUiTest {
workspace.ensureWorkspaceIsScrollable();
executeOnLauncher(
- launcher -> assertEquals(
- "Ensuring workspace scrollable didn't switch to next screen",
- workspace.pagesPerScreen(), getCurrentWorkspacePage(launcher)));
+ launcher -> assertEquals("Ensuring workspace scrollable didn't switch to page #1",
+ 1, getCurrentWorkspacePage(launcher)));
executeOnLauncher(
launcher -> assertTrue("ensureScrollable didn't make workspace scrollable",
isWorkspaceScrollable(launcher)));
@@ -223,12 +212,12 @@ public class TaplTestsLauncher3 extends AbstractLauncherUiTest {
workspace.flingForward();
executeOnLauncher(
- launcher -> assertEquals("Flinging forward didn't switch workspace to next screen",
- workspace.pagesPerScreen(), getCurrentWorkspacePage(launcher)));
+ launcher -> assertEquals("Flinging forward didn't switch workspace to page #1",
+ 1, getCurrentWorkspacePage(launcher)));
assertTrue("Launcher internal state is not Home", isInState(() -> LauncherState.NORMAL));
// Test starting a workspace app.
- final HomeAppIcon app = workspace.getWorkspaceAppIcon("Chrome");
+ final AppIcon app = workspace.getWorkspaceAppIcon("Chrome");
assertNotNull("No Chrome app in workspace", app);
}
@@ -241,7 +230,7 @@ public class TaplTestsLauncher3 extends AbstractLauncherUiTest {
"Launcher activity is the top activity; expecting another activity to be the "
+ "top "
+ "one",
- test.isInLaunchedApp(launcher)));
+ test.isInBackground(launcher)));
} finally {
allApps.unfreeze();
}
@@ -250,7 +239,7 @@ public class TaplTestsLauncher3 extends AbstractLauncherUiTest {
@Test
@PortraitLandscape
public void testAppIconLaunchFromAllAppsFromHome() throws Exception {
- final HomeAllApps allApps = mLauncher.getWorkspace().switchToAllApps();
+ final AllApps allApps = mLauncher.getWorkspace().switchToAllApps();
assertTrue("Launcher internal state is not All Apps",
isInState(() -> LauncherState.ALL_APPS));
@@ -282,7 +271,7 @@ public class TaplTestsLauncher3 extends AbstractLauncherUiTest {
executeOnLauncher(launcher -> assertTrue("Flinging backward didn't scroll widgets",
getWidgetsScroll(launcher) < flingForwardY));
- mLauncher.goHome();
+ mLauncher.pressHome();
waitForLauncherCondition("Widgets were not closed",
launcher -> getWidgetsView(launcher) == null);
}
@@ -292,14 +281,16 @@ public class TaplTestsLauncher3 extends AbstractLauncherUiTest {
}
private boolean isOptionsPopupVisible(Launcher launcher) {
- final ArrowPopup<?> popup = launcher.getOptionsPopup();
+ final ArrowPopup popup = OptionsPopupView.getOptionsPopup(launcher);
return popup != null && popup.isShown();
}
@Test
@PortraitLandscape
public void testLaunchMenuItem() throws Exception {
- final AllApps allApps = mLauncher.getWorkspace().switchToAllApps();
+ final AllApps allApps = mLauncher.
+ getWorkspace().
+ switchToAllApps();
allApps.freeze();
try {
final AppIconMenu menu = allApps.
@@ -324,7 +315,8 @@ public class TaplTestsLauncher3 extends AbstractLauncherUiTest {
// 1. Open all apps and wait for load complete.
// 2. Drag icon to homescreen.
// 3. Verify that the icon works on homescreen.
- final HomeAllApps allApps = mLauncher.getWorkspace().switchToAllApps();
+ final AllApps allApps = mLauncher.getWorkspace().
+ switchToAllApps();
allApps.freeze();
try {
allApps.getAppIcon(APP_NAME).dragToWorkspace(false, false);
@@ -335,7 +327,7 @@ public class TaplTestsLauncher3 extends AbstractLauncherUiTest {
executeOnLauncher(launcher -> assertTrue(
"Launcher activity is the top activity; expecting another activity to be the top "
+ "one",
- isInLaunchedApp(launcher)));
+ isInBackground(launcher)));
}
@Test
@@ -344,18 +336,18 @@ public class TaplTestsLauncher3 extends AbstractLauncherUiTest {
// 1. Open all apps and wait for load complete.
// 2. Find the app and long press it to show shortcuts.
// 3. Press icon center until shortcuts appear
- final HomeAllApps allApps = mLauncher
+ final AllApps allApps = mLauncher
.getWorkspace()
.switchToAllApps();
allApps.freeze();
try {
- final HomeAppIconMenu menu = allApps
+ final AppIconMenu menu = allApps
.getAppIcon(APP_NAME)
.openDeepShortcutMenu();
- final HomeAppIconMenuItem menuItem0 = menu.getMenuItem(0);
- final HomeAppIconMenuItem menuItem2 = menu.getMenuItem(2);
+ final AppIconMenuItem menuItem0 = menu.getMenuItem(0);
+ final AppIconMenuItem menuItem2 = menu.getMenuItem(2);
- final HomeAppIconMenuItem menuItem;
+ final AppIconMenuItem menuItem;
final String expectedShortcutName = "Shortcut 3";
if (menuItem0.getText().equals(expectedShortcutName)) {
@@ -374,169 +366,6 @@ public class TaplTestsLauncher3 extends AbstractLauncherUiTest {
}
}
- @Test
- @PortraitLandscape
- public void testDragToFolder() {
- // TODO: add the use case to drag an icon to an existing folder. Currently it either fails
- // on tablets or phones due to difference in resolution.
- final HomeAppIcon playStoreIcon = createShortcutIfNotExist(STORE_APP_NAME, 0, 1);
- final HomeAppIcon gmailIcon = createShortcutInCenterIfNotExist(GMAIL_APP_NAME);
-
- FolderIcon folderIcon = gmailIcon.dragToIcon(playStoreIcon);
- Folder folder = folderIcon.open();
- folder.getAppIcon(STORE_APP_NAME);
- folder.getAppIcon(GMAIL_APP_NAME);
- Workspace workspace = folder.close();
-
- assertNull(STORE_APP_NAME + " should be moved to a folder.",
- workspace.tryGetWorkspaceAppIcon(STORE_APP_NAME));
- assertNull(GMAIL_APP_NAME + " should be moved to a folder.",
- workspace.tryGetWorkspaceAppIcon(GMAIL_APP_NAME));
-
- final HomeAppIcon mapIcon = createShortcutInCenterIfNotExist(MAPS_APP_NAME);
- folderIcon = mapIcon.dragToIcon(folderIcon);
- folder = folderIcon.open();
- folder.getAppIcon(MAPS_APP_NAME);
- workspace = folder.close();
-
- assertNull(MAPS_APP_NAME + " should be moved to a folder.",
- workspace.tryGetWorkspaceAppIcon(MAPS_APP_NAME));
- }
-
- @Test
- @PortraitLandscape
- public void testPressBack() throws Exception {
- mLauncher.getWorkspace().switchToAllApps();
- mLauncher.pressBack();
- mLauncher.getWorkspace();
- waitForState("Launcher internal state didn't switch to Home", () -> LauncherState.NORMAL);
-
- startAppFast(resolveSystemApp(Intent.CATEGORY_APP_CALCULATOR));
- mLauncher.pressBack();
- mLauncher.getWorkspace();
- waitForState("Launcher internal state didn't switch to Home", () -> LauncherState.NORMAL);
- }
-
- @Test
- @PortraitLandscape
- public void testDeleteFromWorkspace() throws Exception {
- // test delete both built-in apps and user-installed app from workspace
- for (String appName : new String[]{"Gmail", "Play Store", APP_NAME}) {
- final HomeAppIcon homeAppIcon = createShortcutInCenterIfNotExist(appName);
- Workspace workspace = mLauncher.getWorkspace().deleteAppIcon(homeAppIcon);
- assertNull(appName + " app was found after being deleted from workspace",
- workspace.tryGetWorkspaceAppIcon(appName));
- }
- }
-
- private void verifyAppUninstalledFromAllApps(Workspace workspace, String appName) {
- final HomeAllApps allApps = workspace.switchToAllApps();
- allApps.freeze();
- try {
- assertNull(appName + " app was found on all apps after being uninstalled",
- allApps.tryGetAppIcon(appName));
- } finally {
- allApps.unfreeze();
- }
- }
-
- @Test
- @PortraitLandscape
- public void testUninstallFromWorkspace() throws Exception {
- TestUtil.installDummyApp();
- try {
- verifyAppUninstalledFromAllApps(
- createShortcutInCenterIfNotExist(DUMMY_APP_NAME).uninstall(), DUMMY_APP_NAME);
- } finally {
- TestUtil.uninstallDummyApp();
- }
- }
-
- @Test
- @PortraitLandscape
- public void testUninstallFromAllApps() throws Exception {
- TestUtil.installDummyApp();
- try {
- Workspace workspace = mLauncher.getWorkspace();
- final HomeAllApps allApps = workspace.switchToAllApps();
- allApps.freeze();
- try {
- workspace = allApps.getAppIcon(DUMMY_APP_NAME).uninstall();
- } finally {
- allApps.unfreeze();
- }
- verifyAppUninstalledFromAllApps(workspace, DUMMY_APP_NAME);
- } finally {
- TestUtil.uninstallDummyApp();
- }
- }
-
- @Test
- @PortraitLandscape
- public void testDragAppIconToWorkspaceCell() throws Exception {
- Point[] targets = getCornersAndCenterPositions();
-
- for (Point target : targets) {
- final HomeAllApps allApps = mLauncher.getWorkspace().switchToAllApps();
- allApps.freeze();
- try {
- allApps.getAppIcon(APP_NAME).dragToWorkspace(target.x, target.y);
- } finally {
- allApps.unfreeze();
- }
- // Reset the workspace for the next shortcut creation.
- initialize(this);
- }
-
- // test to move a shortcut to other cell.
- final HomeAppIcon launcherTestAppIcon = createShortcutInCenterIfNotExist(APP_NAME);
- for (Point target : targets) {
- launcherTestAppIcon.dragToWorkspace(target.x, target.y);
- }
- }
-
- @Test
- public void getIconsPosition_afterIconRemoved_notContained() throws IOException {
- Point[] gridPositions = getCornersAndCenterPositions();
- createShortcutIfNotExist(STORE_APP_NAME, gridPositions[0]);
- createShortcutIfNotExist(MAPS_APP_NAME, gridPositions[1]);
- TestUtil.installDummyApp();
- try {
- createShortcutIfNotExist(DUMMY_APP_NAME, gridPositions[2]);
- Map<String, Point> initialPositions =
- mLauncher.getWorkspace().getWorkspaceIconsPositions();
- assertThat(initialPositions.keySet())
- .containsAtLeast(DUMMY_APP_NAME, MAPS_APP_NAME, STORE_APP_NAME);
-
- mLauncher.getWorkspace().getWorkspaceAppIcon(DUMMY_APP_NAME).uninstall();
-
- assertNull(
- DUMMY_APP_NAME + " app was found after being uninstalled",
- mLauncher.getWorkspace().tryGetWorkspaceAppIcon(DUMMY_APP_NAME));
-
- Map<String, Point> finalPositions =
- mLauncher.getWorkspace().getWorkspaceIconsPositions();
- assertThat(finalPositions).doesNotContainKey(DUMMY_APP_NAME);
- } finally {
- TestUtil.uninstallDummyApp();
- }
- }
-
- /**
- * @return List of workspace grid coordinates. Those are not pixels. See {@link
- * Workspace#getIconGridDimensions()}
- */
- private Point[] getCornersAndCenterPositions() {
- final Point dimensions = mLauncher.getWorkspace().getIconGridDimensions();
- return new Point[] {
- new Point(0, 1),
- new Point(0, dimensions.y - 2),
- new Point(dimensions.x - 1, 1),
- new Point(dimensions.x - 1, dimensions.y - 2),
- new Point(dimensions.x / 2, dimensions.y / 2)
- };
- }
-
public static String getAppPackageName() {
return getInstrumentation().getContext().getPackageName();
}
diff --git a/tests/src/com/android/launcher3/ui/WorkProfileTest.java b/tests/src/com/android/launcher3/ui/WorkProfileTest.java
deleted file mode 100644
index 35b4ca6431..0000000000
--- a/tests/src/com/android/launcher3/ui/WorkProfileTest.java
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * Copyright (C) 2021 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.launcher3.ui;
-
-import static com.android.launcher3.LauncherState.ALL_APPS;
-import static com.android.launcher3.LauncherState.NORMAL;
-import static com.android.launcher3.allapps.AllAppsStore.DEFER_UPDATES_TEST;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import android.util.Log;
-import android.view.View;
-
-import androidx.recyclerview.widget.RecyclerView.ViewHolder;
-
-import com.android.launcher3.R;
-import com.android.launcher3.allapps.ActivityAllAppsContainerView;
-import com.android.launcher3.allapps.AllAppsPagedView;
-import com.android.launcher3.allapps.WorkAdapterProvider;
-import com.android.launcher3.allapps.WorkEduCard;
-import com.android.launcher3.allapps.WorkPausedCard;
-import com.android.launcher3.allapps.WorkProfileManager;
-import com.android.launcher3.tapl.LauncherInstrumentation;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-import java.util.Objects;
-import java.util.function.Predicate;
-
-public class WorkProfileTest extends AbstractLauncherUiTest {
-
- private static final int WORK_PAGE = ActivityAllAppsContainerView.AdapterHolder.WORK;
-
- private int mProfileUserId;
-
- @Before
- @Override
- public void setUp() throws Exception {
- super.setUp();
- String output =
- mDevice.executeShellCommand(
- "pm create-user --profileOf 0 --managed TestProfile");
- Log.d("b/203817455", "pm create-user; output: " + output);
- assertTrue("Failed to create work profile", output.startsWith("Success"));
-
- String[] tokens = output.split("\\s+");
- mProfileUserId = Integer.parseInt(tokens[tokens.length - 1]);
- mDevice.executeShellCommand("am start-user " + mProfileUserId);
-
- mDevice.pressHome();
- waitForLauncherCondition("Launcher didn't start", Objects::nonNull);
- waitForStateTransitionToEnd("Launcher internal state didn't switch to Normal",
- () -> NORMAL);
- waitForResumed("Launcher internal state is still Background");
- executeOnLauncher(launcher -> launcher.getStateManager().goToState(ALL_APPS));
- waitForStateTransitionToEnd("Launcher internal state didn't switch to All Apps",
- () -> ALL_APPS);
- }
-
- @After
- public void removeWorkProfile() throws Exception {
- mDevice.executeShellCommand("pm remove-user " + mProfileUserId);
- }
-
- @After
- public void resumeAppStoreUpdate() {
- executeOnLauncher(launcher -> {
- if (launcher == null || launcher.getAppsView() == null) {
- return;
- }
- launcher.getAppsView().getAppsStore().disableDeferUpdates(DEFER_UPDATES_TEST);
- });
- }
-
- private void waitForWorkTabSetup() {
- waitForLauncherCondition("Work tab not setup", launcher -> {
- if (launcher.getAppsView().getContentView() instanceof AllAppsPagedView) {
- launcher.getAppsView().getAppsStore().enableDeferUpdates(DEFER_UPDATES_TEST);
- return true;
- }
- return false;
- }, LauncherInstrumentation.WAIT_TIME_MS);
- }
-
- @Test
- public void workTabExists() {
- waitForLauncherCondition("Personal tab is missing",
- launcher -> launcher.getAppsView().isPersonalTabVisible(),
- LauncherInstrumentation.WAIT_TIME_MS);
- waitForLauncherCondition("Work tab is missing",
- launcher -> launcher.getAppsView().isWorkTabVisible(),
- LauncherInstrumentation.WAIT_TIME_MS);
- }
-
- @Test
- public void toggleWorks() {
- waitForWorkTabSetup();
-
- executeOnLauncher(launcher -> {
- AllAppsPagedView pagedView = (AllAppsPagedView) launcher.getAppsView().getContentView();
- pagedView.setCurrentPage(WORK_PAGE);
- });
-
- WorkProfileManager manager = getFromLauncher(l -> l.getAppsView().getWorkManager());
-
-
- waitForLauncherCondition("work profile initial state check failed", launcher ->
- manager.getWorkModeSwitch() != null
- && manager.getCurrentState() == WorkProfileManager.STATE_ENABLED
- && manager.getWorkModeSwitch().isEnabled(),
- LauncherInstrumentation.WAIT_TIME_MS);
-
- //start work profile toggle OFF test
- executeOnLauncher(l -> l.getAppsView().getWorkManager().getWorkModeSwitch().performClick());
-
- waitForLauncherCondition("Work profile toggle OFF failed", launcher -> {
- manager.reset(); // pulls current state from system
- return manager.getCurrentState() == WorkProfileManager.STATE_DISABLED;
- }, LauncherInstrumentation.WAIT_TIME_MS);
-
- waitForWorkCard("Work paused card not shown", view -> view instanceof WorkPausedCard);
-
- // start work profile toggle ON test
- executeOnLauncher(l -> {
- ActivityAllAppsContainerView<?> allApps = l.getAppsView();
- assertEquals("Work tab is not focused", allApps.getCurrentPage(), WORK_PAGE);
- View workPausedCard = allApps.getActiveRecyclerView()
- .findViewHolderForAdapterPosition(0).itemView;
- workPausedCard.findViewById(R.id.enable_work_apps).performClick();
- });
- waitForLauncherCondition("Work profile toggle ON failed", launcher -> {
- manager.reset(); // pulls current state from system
- return manager.getCurrentState() == WorkProfileManager.STATE_ENABLED;
- }, LauncherInstrumentation.WAIT_TIME_MS);
-
- }
-
- @Test
- public void testEdu() {
- waitForWorkTabSetup();
- executeOnLauncher(l -> {
- l.getSharedPrefs().edit().putInt(WorkAdapterProvider.KEY_WORK_EDU_STEP, 0).commit();
- ((AllAppsPagedView) l.getAppsView().getContentView()).setCurrentPage(WORK_PAGE);
- l.getAppsView().getWorkManager().reset();
- });
-
- waitForWorkCard("Work profile education not shown", view -> view instanceof WorkEduCard);
- }
-
- private void waitForWorkCard(String message, Predicate<View> workCardCheck) {
- waitForLauncherCondition(message, l -> {
- l.getAppsView().getAppsStore().disableDeferUpdates(DEFER_UPDATES_TEST);
- ViewHolder holder = l.getAppsView().getActiveRecyclerView()
- .findViewHolderForAdapterPosition(0);
- try {
- return holder != null && workCardCheck.test(holder.itemView);
- } finally {
- l.getAppsView().getAppsStore().enableDeferUpdates(DEFER_UPDATES_TEST);
- }
- }, LauncherInstrumentation.WAIT_TIME_MS);
- }
-}
diff --git a/tests/src/com/android/launcher3/ui/widget/AddConfigWidgetTest.java b/tests/src/com/android/launcher3/ui/widget/AddConfigWidgetTest.java
index 2c9785c93d..4978c0190d 100644
--- a/tests/src/com/android/launcher3/ui/widget/AddConfigWidgetTest.java
+++ b/tests/src/com/android/launcher3/ui/widget/AddConfigWidgetTest.java
@@ -15,24 +15,28 @@
*/
package com.android.launcher3.ui.widget;
+import static androidx.test.InstrumentationRegistry.getInstrumentation;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNotSame;
-import static org.junit.Assert.assertNull;
import android.appwidget.AppWidgetManager;
import android.content.Intent;
+import android.view.View;
import androidx.test.filters.LargeTest;
import androidx.test.runner.AndroidJUnit4;
+import com.android.launcher3.Workspace;
+import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.LauncherAppWidgetInfo;
-import com.android.launcher3.tapl.Widget;
-import com.android.launcher3.tapl.WidgetResizeFrame;
import com.android.launcher3.tapl.Widgets;
import com.android.launcher3.testcomponent.WidgetConfigActivity;
import com.android.launcher3.ui.AbstractLauncherUiTest;
import com.android.launcher3.ui.TestViewHelpers;
+import com.android.launcher3.util.Wait;
+import com.android.launcher3.util.Wait.Condition;
import com.android.launcher3.util.rule.ShellCommandRule;
import com.android.launcher3.widget.LauncherAppWidgetProviderInfo;
@@ -88,26 +92,48 @@ public class AddConfigWidgetTest extends AbstractLauncherUiTest {
// Drag widget to homescreen
WidgetConfigStartupMonitor monitor = new WidgetConfigStartupMonitor();
- WidgetResizeFrame resizeFrame =
- widgets.getWidget(mWidgetInfo.getLabel(mTargetContext.getPackageManager()))
- .dragConfigWidgetToWorkspace(acceptConfig);
+ widgets.getWidget(mWidgetInfo.getLabel(mTargetContext.getPackageManager()))
+ .dragToWorkspace(true, false);
// Widget id for which the config activity was opened
mWidgetId = monitor.getWidgetId();
// Verify that the widget id is valid and bound
assertNotNull(mAppWidgetManager.getAppWidgetInfo(mWidgetId));
+ setResult(acceptConfig);
if (acceptConfig) {
- assertNotNull("Widget resize frame not shown after widget added", resizeFrame);
- resizeFrame.dismiss();
-
- final Widget widget =
- mLauncher.getWorkspace().tryGetWidget(mWidgetInfo.label, DEFAULT_UI_TIMEOUT);
- assertNotNull("Widget not found on the workspace", widget);
+ // TODO(b/192655785) Assert widget resize frame is shown and then dismiss it.
+ Wait.atMost("", new WidgetSearchCondition(), DEFAULT_ACTIVITY_TIMEOUT, mLauncher);
+ assertNotNull(mAppWidgetManager.getAppWidgetInfo(mWidgetId));
} else {
- final Widget widget =
- mLauncher.getWorkspace().tryGetWidget(mWidgetInfo.label, DEFAULT_UI_TIMEOUT);
- assertNull("Widget unexpectedly found on the workspace", widget);
+ // Verify that the widget id is deleted.
+ Wait.atMost("", () -> mAppWidgetManager.getAppWidgetInfo(mWidgetId) == null,
+ DEFAULT_ACTIVITY_TIMEOUT, mLauncher);
+ }
+ }
+
+ private void setResult(boolean success) {
+ getInstrumentation().getTargetContext().sendBroadcast(
+ WidgetConfigActivity.getCommandIntent(WidgetConfigActivity.class,
+ success ? "clickOK" : "clickCancel"));
+ }
+
+ /**
+ * Condition for searching widget id
+ */
+ private class WidgetSearchCondition implements Condition, Workspace.ItemOperator {
+
+ @Override
+ public boolean isTrue() throws Throwable {
+ return mMainThreadExecutor.submit(mActivityMonitor.itemExists(this)).get();
+ }
+
+ @Override
+ public boolean evaluate(ItemInfo info, View view) {
+ return info instanceof LauncherAppWidgetInfo &&
+ ((LauncherAppWidgetInfo) info).providerName.getClassName().equals(
+ mWidgetInfo.provider.getClassName()) &&
+ ((LauncherAppWidgetInfo) info).appWidgetId == mWidgetId;
}
}
diff --git a/tests/src/com/android/launcher3/ui/widget/AddWidgetTest.java b/tests/src/com/android/launcher3/ui/widget/AddWidgetTest.java
index 194ee4f1c9..dad4f2b045 100644
--- a/tests/src/com/android/launcher3/ui/widget/AddWidgetTest.java
+++ b/tests/src/com/android/launcher3/ui/widget/AddWidgetTest.java
@@ -25,7 +25,6 @@ import androidx.test.runner.AndroidJUnit4;
import com.android.launcher3.model.data.LauncherAppWidgetInfo;
import com.android.launcher3.tapl.Widget;
-import com.android.launcher3.tapl.WidgetResizeFrame;
import com.android.launcher3.ui.AbstractLauncherUiTest;
import com.android.launcher3.ui.TestViewHelpers;
import com.android.launcher3.util.rule.ShellCommandRule;
@@ -54,20 +53,19 @@ public class AddWidgetTest extends AbstractLauncherUiTest {
final LauncherAppWidgetProviderInfo widgetInfo =
TestViewHelpers.findWidgetProvider(this, false /* hasConfigureScreen */);
- WidgetResizeFrame resizeFrame = mLauncher.
+ mLauncher.
getWorkspace().
openAllWidgets().
getWidget(widgetInfo.getLabel(mTargetContext.getPackageManager())).
- dragWidgetToWorkspace();
+ dragToWorkspace(false, false);
+ // Dismiss widget resize frame.
+ mDevice.pressHome();
assertTrue(mActivityMonitor.itemExists(
(info, view) -> info instanceof LauncherAppWidgetInfo &&
((LauncherAppWidgetInfo) info).providerName.getClassName().equals(
widgetInfo.provider.getClassName())).call());
- assertNotNull("Widget resize frame not shown after widget add", resizeFrame);
- resizeFrame.dismiss();
-
final Widget widget = mLauncher.getWorkspace().tryGetWidget(widgetInfo.label,
DEFAULT_UI_TIMEOUT);
assertNotNull("Widget not found on the workspace", widget);
diff --git a/tests/src/com/android/launcher3/ui/widget/BindWidgetTest.java b/tests/src/com/android/launcher3/ui/widget/BindWidgetTest.java
index fa39ce0604..9c6c3173ac 100644
--- a/tests/src/com/android/launcher3/ui/widget/BindWidgetTest.java
+++ b/tests/src/com/android/launcher3/ui/widget/BindWidgetTest.java
@@ -17,7 +17,7 @@ package com.android.launcher3.ui.widget;
import static androidx.test.InstrumentationRegistry.getTargetContext;
-import static com.android.launcher3.util.WidgetUtils.createWidgetInfo;
+import static com.android.launcher3.common.WidgetUtils.createWidgetInfo;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
diff --git a/tests/src/com/android/launcher3/ui/widget/RequestPinItemTest.java b/tests/src/com/android/launcher3/ui/widget/RequestPinItemTest.java
index 0db719e349..745dc220ba 100644
--- a/tests/src/com/android/launcher3/ui/widget/RequestPinItemTest.java
+++ b/tests/src/com/android/launcher3/ui/widget/RequestPinItemTest.java
@@ -15,9 +15,6 @@
*/
package com.android.launcher3.ui.widget;
-import static android.app.PendingIntent.FLAG_MUTABLE;
-import static android.app.PendingIntent.FLAG_ONE_SHOT;
-
import static com.android.launcher3.ui.TaplTestsLauncher3.getAppPackageName;
import static org.junit.Assert.assertNotNull;
@@ -33,6 +30,7 @@ import androidx.test.filters.LargeTest;
import androidx.test.runner.AndroidJUnit4;
import com.android.launcher3.LauncherSettings.Favorites;
+import com.android.launcher3.Workspace.ItemOperator;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.LauncherAppWidgetInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo;
@@ -42,7 +40,6 @@ import com.android.launcher3.testcomponent.AppWidgetNoConfig;
import com.android.launcher3.testcomponent.AppWidgetWithConfig;
import com.android.launcher3.testcomponent.RequestPinItemActivity;
import com.android.launcher3.ui.AbstractLauncherUiTest;
-import com.android.launcher3.util.LauncherBindableItemsContainer.ItemOperator;
import com.android.launcher3.util.Wait;
import com.android.launcher3.util.Wait.Condition;
import com.android.launcher3.util.rule.ScreenRecordRule.ScreenRecord;
@@ -81,7 +78,7 @@ public class RequestPinItemTest extends AbstractLauncherUiTest {
public void testEmpty() throws Throwable { /* needed while the broken tests are being fixed */ }
@Test
- @ScreenRecord // b/215673732
+ @ScreenRecord //b/192010616
public void testPinWidgetNoConfig() throws Throwable {
runTest("pinWidgetNoConfig", true, (info, view) -> info instanceof LauncherAppWidgetInfo &&
((LauncherAppWidgetInfo) info).appWidgetId == mAppWidgetId &&
@@ -90,7 +87,7 @@ public class RequestPinItemTest extends AbstractLauncherUiTest {
}
@Test
- @ScreenRecord // b/215673732
+ @ScreenRecord //b/192005114
public void testPinWidgetNoConfig_customPreview() throws Throwable {
// Command to set custom preview
Intent command = RequestPinItemActivity.getCommandIntent(
@@ -104,7 +101,6 @@ public class RequestPinItemTest extends AbstractLauncherUiTest {
}
@Test
- @ScreenRecord // b/215673732
public void testPinWidgetWithConfig() throws Throwable {
runTest("pinWidgetWithConfig", true,
(info, view) -> info instanceof LauncherAppWidgetInfo &&
@@ -147,7 +143,7 @@ public class RequestPinItemTest extends AbstractLauncherUiTest {
// Set callback
PendingIntent callback = PendingIntent.getBroadcast(mTargetContext, 0,
- new Intent(mCallbackAction), FLAG_ONE_SHOT | FLAG_MUTABLE);
+ new Intent(mCallbackAction), PendingIntent.FLAG_ONE_SHOT);
mTargetContext.sendBroadcast(RequestPinItemActivity.getCommandIntent(
RequestPinItemActivity.class, "setCallback").putExtra(
RequestPinItemActivity.EXTRA_PARAM + "0", callback));
@@ -172,7 +168,7 @@ public class RequestPinItemTest extends AbstractLauncherUiTest {
}
// Go back to home
- mLauncher.goHome();
+ mLauncher.pressHome();
Wait.atMost("", new ItemSearchCondition(itemMatcher), DEFAULT_ACTIVITY_TIMEOUT,
mLauncher);
}
diff --git a/tests/src/com/android/launcher3/ui/workspace/ThemeIconsTest.java b/tests/src/com/android/launcher3/ui/workspace/ThemeIconsTest.java
deleted file mode 100644
index e66810cc3d..0000000000
--- a/tests/src/com/android/launcher3/ui/workspace/ThemeIconsTest.java
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.launcher3.ui.workspace;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
-import android.content.ContentProviderClient;
-import android.content.ContentResolver;
-import android.content.ContentValues;
-import android.net.Uri;
-import android.view.View;
-import android.view.ViewGroup;
-
-import androidx.test.filters.LargeTest;
-
-import com.android.launcher3.BubbleTextView;
-import com.android.launcher3.icons.ThemedIconDrawable;
-import com.android.launcher3.tapl.HomeAllApps;
-import com.android.launcher3.tapl.HomeAppIcon;
-import com.android.launcher3.ui.AbstractLauncherUiTest;
-import com.android.launcher3.ui.TaplTestsLauncher3;
-
-import org.junit.Test;
-
-import java.util.ArrayDeque;
-import java.util.Queue;
-
-/**
- * Tests for theme icon support in Launcher
- *
- * Note running these tests will clear the workspace on the device.
- */
-@LargeTest
-public class ThemeIconsTest extends AbstractLauncherUiTest {
-
- private static final String APP_NAME = "ThemeIconTestActivity";
-
- @Test
- public void testIconWithoutTheme() throws Exception {
- setThemeEnabled(false);
- TaplTestsLauncher3.initialize(this);
-
- HomeAllApps allApps = mLauncher.getWorkspace().switchToAllApps();
- allApps.freeze();
-
- try {
- HomeAppIcon icon = allApps.getAppIcon(APP_NAME);
- executeOnLauncher(l -> verifyIconTheme(l.getAppsView(), false));
- icon.dragToWorkspace(false, false);
- executeOnLauncher(l -> verifyIconTheme(l.getWorkspace(), false));
- } finally {
- allApps.unfreeze();
- }
- }
-
- @Test
- public void testIconWithTheme() throws Exception {
- setThemeEnabled(true);
- TaplTestsLauncher3.initialize(this);
-
- HomeAllApps allApps = mLauncher.getWorkspace().switchToAllApps();
- allApps.freeze();
-
- try {
- HomeAppIcon icon = allApps.getAppIcon(APP_NAME);
- executeOnLauncher(l -> verifyIconTheme(l.getAppsView(), false));
- icon.dragToWorkspace(false, false);
- executeOnLauncher(l -> verifyIconTheme(l.getWorkspace(), true));
- } finally {
- allApps.unfreeze();
- }
- }
-
- private void verifyIconTheme(ViewGroup parent, boolean isThemed) {
- // Find the app icon
- Queue<View> viewQueue = new ArrayDeque<>();
- viewQueue.add(parent);
- BubbleTextView icon = null;
- while (!viewQueue.isEmpty()) {
- View view = viewQueue.poll();
- if (view instanceof ViewGroup) {
- parent = (ViewGroup) view;
- for (int i = parent.getChildCount() - 1; i >= 0; i--) {
- viewQueue.add(parent.getChildAt(i));
- }
- } else if (view instanceof BubbleTextView) {
- BubbleTextView btv = (BubbleTextView) view;
- if (APP_NAME.equals(btv.getText())) {
- icon = btv;
- break;
- }
- }
- }
-
- assertNotNull(icon.getIcon());
- assertEquals(isThemed, icon.getIcon() instanceof ThemedIconDrawable);
- }
-
- private void setThemeEnabled(boolean isEnabled) throws Exception {
- Uri uri = new Uri.Builder()
- .scheme(ContentResolver.SCHEME_CONTENT)
- .authority(mTargetPackage + ".grid_control")
- .appendPath("set_icon_themed")
- .build();
- ContentValues values = new ContentValues();
- values.put("boolean_value", isEnabled);
- try (ContentProviderClient client = mTargetContext.getContentResolver()
- .acquireContentProviderClient(uri)) {
- int result = client.update(uri, values, null);
- assertTrue(result > 0);
- }
- }
-}
diff --git a/tests/src/com/android/launcher3/ui/workspace/TwoPanelWorkspaceTest.java b/tests/src/com/android/launcher3/ui/workspace/TwoPanelWorkspaceTest.java
deleted file mode 100644
index f646b504a9..0000000000
--- a/tests/src/com/android/launcher3/ui/workspace/TwoPanelWorkspaceTest.java
+++ /dev/null
@@ -1,342 +0,0 @@
-/*
- * Copyright (C) 2021 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.launcher3.ui.workspace;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assume.assumeTrue;
-
-import androidx.test.filters.LargeTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import com.android.launcher3.CellLayout;
-import com.android.launcher3.Launcher;
-import com.android.launcher3.model.data.ItemInfo;
-import com.android.launcher3.tapl.Workspace;
-import com.android.launcher3.ui.AbstractLauncherUiTest;
-import com.android.launcher3.ui.TaplTestsLauncher3;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.Arrays;
-import java.util.Set;
-import java.util.stream.Collectors;
-
-/**
- * Tests for two panel workspace.
- *
- * Note running these tests will clear the workspace on the device.
- */
-@LargeTest
-@RunWith(AndroidJUnit4.class)
-public class TwoPanelWorkspaceTest extends AbstractLauncherUiTest {
-
- @Before
- public void setUp() throws Exception {
- super.setUp();
- TaplTestsLauncher3.initialize(this);
-
- assumeTrue(mLauncher.isTwoPanels());
-
- // Pre verifying the screens
- executeOnLauncher(launcher -> {
- assertPagesExist(launcher, 0, 1);
- assertItemsOnPage(launcher, 0, "Play Store", "Maps");
- assertPageEmpty(launcher, 1);
- });
- }
-
- @Test
- @PortraitLandscape
- public void testDragIconToRightPanel() {
- Workspace workspace = mLauncher.getWorkspace();
-
- workspace.dragIcon(workspace.getHotseatAppIcon("Chrome"), 1);
-
- executeOnLauncher(launcher -> {
- assertPagesExist(launcher, 0, 1);
- assertItemsOnPage(launcher, 0, "Maps", "Play Store");
- assertItemsOnPage(launcher, 1, "Chrome");
- });
- }
-
- @Test
- @PortraitLandscape
- public void testSinglePageDragIconWhenMultiplePageScrollingIsPossible() {
- Workspace workspace = mLauncher.getWorkspace();
-
- workspace.dragIcon(workspace.getHotseatAppIcon("Chrome"), 2);
-
- workspace.flingBackward();
-
- workspace.dragIcon(workspace.getWorkspaceAppIcon("Maps"), 3);
-
- executeOnLauncher(launcher -> {
- assertPagesExist(launcher, 0, 1, 2, 3);
- assertItemsOnPage(launcher, 0, "Play Store");
- assertPageEmpty(launcher, 1);
- assertItemsOnPage(launcher, 2, "Chrome");
- assertItemsOnPage(launcher, 3, "Maps");
- });
-
- workspace.dragIcon(workspace.getWorkspaceAppIcon("Maps"), 3);
-
- executeOnLauncher(launcher -> {
- assertPagesExist(launcher, 0, 1, 2, 3, 4, 5);
- assertItemsOnPage(launcher, 0, "Play Store");
- assertPageEmpty(launcher, 1);
- assertItemsOnPage(launcher, 2, "Chrome");
- assertPageEmpty(launcher, 3);
- assertPageEmpty(launcher, 4);
- assertItemsOnPage(launcher, 5, "Maps");
- });
-
- workspace.dragIcon(workspace.getWorkspaceAppIcon("Maps"), -1);
-
- executeOnLauncher(launcher -> {
- assertPagesExist(launcher, 0, 1, 2, 3);
- assertItemsOnPage(launcher, 0, "Play Store");
- assertPageEmpty(launcher, 1);
- assertItemsOnPage(launcher, 2, "Chrome");
- assertItemsOnPage(launcher, 3, "Maps");
- });
-
- workspace.dragIcon(workspace.getWorkspaceAppIcon("Maps"), -1);
-
- workspace.flingForward();
-
- workspace.dragIcon(workspace.getWorkspaceAppIcon("Chrome"), -2);
-
- executeOnLauncher(launcher -> {
- assertPagesExist(launcher, 0, 1);
- assertItemsOnPage(launcher, 0, "Chrome", "Play Store");
- assertItemsOnPage(launcher, 1, "Maps");
- });
- }
-
- @Test
- @PortraitLandscape
- public void testDragIconToPage2() {
- Workspace workspace = mLauncher.getWorkspace();
-
- workspace.dragIcon(workspace.getWorkspaceAppIcon("Maps"), 2);
-
- executeOnLauncher(launcher -> {
- assertPagesExist(launcher, 0, 1, 2, 3);
- assertItemsOnPage(launcher, 0, "Play Store");
- assertPageEmpty(launcher, 1);
- assertItemsOnPage(launcher, 2, "Maps");
- assertPageEmpty(launcher, 3);
- });
- }
-
- @Test
- @PortraitLandscape
- public void testDragIconToPage3() {
- Workspace workspace = mLauncher.getWorkspace();
-
- workspace.dragIcon(workspace.getHotseatAppIcon("Phone"), 3);
-
- executeOnLauncher(launcher -> {
- assertPagesExist(launcher, 0, 1, 2, 3);
- assertItemsOnPage(launcher, 0, "Play Store", "Maps");
- assertPageEmpty(launcher, 1);
- assertPageEmpty(launcher, 2);
- assertItemsOnPage(launcher, 3, "Phone");
- });
- }
-
- @Test
- @PortraitLandscape
- public void testMultiplePageDragIcon() {
- Workspace workspace = mLauncher.getWorkspace();
-
- workspace.dragIcon(workspace.getHotseatAppIcon("Messages"), 2);
-
- workspace.flingBackward();
-
- workspace.dragIcon(workspace.getWorkspaceAppIcon("Maps"), 5);
-
- executeOnLauncher(launcher -> {
- assertPagesExist(launcher, 0, 1, 2, 3, 4, 5);
- assertItemsOnPage(launcher, 0, "Play Store");
- assertPageEmpty(launcher, 1);
- assertItemsOnPage(launcher, 2, "Messages");
- assertPageEmpty(launcher, 3);
- assertPageEmpty(launcher, 4);
- assertItemsOnPage(launcher, 5, "Maps");
- });
-
- workspace.flingBackward();
-
- workspace.dragIcon(workspace.getWorkspaceAppIcon("Messages"), 4);
-
- executeOnLauncher(launcher -> {
- assertPagesExist(launcher, 0, 1, 4, 5, 6, 7);
- assertItemsOnPage(launcher, 0, "Play Store");
- assertPageEmpty(launcher, 1);
- assertPageEmpty(launcher, 4);
- assertItemsOnPage(launcher, 5, "Maps");
- assertItemsOnPage(launcher, 6, "Messages");
- assertPageEmpty(launcher, 7);
- });
-
- workspace.dragIcon(workspace.getWorkspaceAppIcon("Messages"), -3);
-
- executeOnLauncher(launcher -> {
- assertPagesExist(launcher, 0, 1, 4, 5);
- assertItemsOnPage(launcher, 0, "Play Store");
- assertItemsOnPage(launcher, 1, "Messages");
- assertPageEmpty(launcher, 4);
- assertItemsOnPage(launcher, 5, "Maps");
- });
- }
-
- @Test
- @PortraitLandscape
- public void testEmptyPageDoesNotGetRemovedIfPagePairIsNotEmpty() {
- Workspace workspace = mLauncher.getWorkspace();
-
- workspace.dragIcon(workspace.getWorkspaceAppIcon("Maps"), 3);
- workspace.dragIcon(workspace.getHotseatAppIcon("Chrome"), 0);
-
- executeOnLauncher(launcher -> {
- assertPagesExist(launcher, 0, 1, 2, 3);
- assertItemsOnPage(launcher, 0, "Play Store");
- assertPageEmpty(launcher, 1);
- assertItemsOnPage(launcher, 2, "Chrome");
- assertItemsOnPage(launcher, 3, "Maps");
- });
-
- workspace.dragIcon(workspace.getWorkspaceAppIcon("Maps"), -1);
-
- executeOnLauncher(launcher -> {
- assertPagesExist(launcher, 0, 1, 2, 3);
- assertItemsOnPage(launcher, 0, "Play Store");
- assertItemsOnPage(launcher, 1, "Maps");
- assertItemsOnPage(launcher, 2, "Chrome");
- assertPageEmpty(launcher, 3);
- });
-
- // Move Chrome to the right panel as well, to make sure pages are not deleted whichever
- // page is the empty one
- workspace.flingForward();
- workspace.dragIcon(workspace.getWorkspaceAppIcon("Chrome"), 1);
-
- executeOnLauncher(launcher -> {
- assertPagesExist(launcher, 0, 1, 2, 3);
- assertItemsOnPage(launcher, 0, "Play Store");
- assertItemsOnPage(launcher, 1, "Maps");
- assertPageEmpty(launcher, 2);
- assertItemsOnPage(launcher, 3, "Chrome");
- });
- }
-
- @Test
- @PortraitLandscape
- public void testEmptyPagesGetRemovedIfBothPagesAreEmpty() {
- Workspace workspace = mLauncher.getWorkspace();
-
- workspace.dragIcon(workspace.getWorkspaceAppIcon("Play Store"), 2);
- workspace.dragIcon(workspace.getHotseatAppIcon("Chrome"), 1);
-
- executeOnLauncher(launcher -> {
- assertPagesExist(launcher, 0, 1, 2, 3);
- assertItemsOnPage(launcher, 0, "Maps");
- assertPageEmpty(launcher, 1);
- assertItemsOnPage(launcher, 2, "Play Store");
- assertItemsOnPage(launcher, 3, "Chrome");
- });
-
- workspace.dragIcon(workspace.getWorkspaceAppIcon("Chrome"), -1);
- workspace.flingForward();
- workspace.dragIcon(workspace.getWorkspaceAppIcon("Play Store"), -2);
-
- executeOnLauncher(launcher -> {
- assertPagesExist(launcher, 0, 1);
- assertItemsOnPage(launcher, 0, "Play Store", "Maps");
- assertItemsOnPage(launcher, 1, "Chrome");
- });
- }
-
- @Test
- @PortraitLandscape
- public void testMiddleEmptyPagesGetRemoved() {
- Workspace workspace = mLauncher.getWorkspace();
-
- workspace.dragIcon(workspace.getWorkspaceAppIcon("Maps"), 2);
- workspace.dragIcon(workspace.getHotseatAppIcon("Messages"), 3);
-
- executeOnLauncher(launcher -> {
- assertPagesExist(launcher, 0, 1, 2, 3, 4, 5);
- assertItemsOnPage(launcher, 0, "Play Store");
- assertPageEmpty(launcher, 1);
- assertItemsOnPage(launcher, 2, "Maps");
- assertPageEmpty(launcher, 3);
- assertPageEmpty(launcher, 4);
- assertItemsOnPage(launcher, 5, "Messages");
- });
-
- workspace.flingBackward();
- workspace.dragIcon(workspace.getWorkspaceAppIcon("Maps"), 2);
-
- executeOnLauncher(launcher -> {
- assertPagesExist(launcher, 0, 1, 4, 5);
- assertItemsOnPage(launcher, 0, "Play Store");
- assertPageEmpty(launcher, 1);
- assertItemsOnPage(launcher, 4, "Maps");
- assertItemsOnPage(launcher, 5, "Messages");
- });
- }
-
- private void assertPageEmpty(Launcher launcher, int pageId) {
- CellLayout page = launcher.getWorkspace().getScreenWithId(pageId);
- assertNotNull("Page " + pageId + " does NOT exist.", page);
- assertEquals("Page " + pageId + " is NOT empty. Number of items on the page:", 0,
- page.getShortcutsAndWidgets().getChildCount());
- }
-
- private void assertPagesExist(Launcher launcher, int... pageIds) {
- int pageCount = launcher.getWorkspace().getPageCount();
- assertEquals("Existing page count does NOT match.", pageIds.length, pageCount);
- for (int i = 0; i < pageCount; i++) {
- CellLayout page = (CellLayout) launcher.getWorkspace().getPageAt(i);
- int pageId = launcher.getWorkspace().getIdForScreen(page);
- assertEquals("The page's id at index " + i + " does NOT match.", pageId,
- pageIds[i]);
- }
- }
-
- private void assertItemsOnPage(Launcher launcher, int pageId, String... itemTitles) {
- Set<String> itemTitleSet = Arrays.stream(itemTitles).collect(Collectors.toSet());
- CellLayout page = launcher.getWorkspace().getScreenWithId(pageId);
- int itemCount = page.getShortcutsAndWidgets().getChildCount();
- for (int i = 0; i < itemCount; i++) {
- ItemInfo itemInfo = (ItemInfo) page.getShortcutsAndWidgets().getChildAt(i).getTag();
- if (itemInfo != null) {
- assertTrue("There was an extra item on page " + pageId + ": " + itemInfo.title,
- itemTitleSet.remove(itemInfo.title));
- }
- }
- assertTrue("Could NOT find some of the items on page " + pageId + ": "
- + itemTitleSet.stream().collect(Collectors.joining(",")),
- itemTitleSet.isEmpty());
- }
-}
diff --git a/tests/src/com/android/launcher3/util/ActivityContextWrapper.java b/tests/src/com/android/launcher3/util/ActivityContextWrapper.java
deleted file mode 100644
index 2618a2e1f1..0000000000
--- a/tests/src/com/android/launcher3/util/ActivityContextWrapper.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2021 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.launcher3.util;
-
-import android.content.Context;
-import android.content.ContextWrapper;
-import android.view.ContextThemeWrapper;
-
-import com.android.launcher3.DeviceProfile;
-import com.android.launcher3.InvariantDeviceProfile;
-import com.android.launcher3.views.ActivityContext;
-import com.android.launcher3.views.BaseDragLayer;
-
-/**
- * {@link ContextWrapper} with internal Launcher interface for testing
- */
-public class ActivityContextWrapper extends ContextThemeWrapper implements ActivityContext {
-
- private final DeviceProfile mProfile;
- private final MyDragLayer mMyDragLayer;
-
- public ActivityContextWrapper(Context base) {
- super(base, android.R.style.Theme_DeviceDefault);
- mProfile = InvariantDeviceProfile.INSTANCE.get(base).getDeviceProfile(base).copy(base);
- mMyDragLayer = new MyDragLayer(this);
- }
-
- @Override
- public BaseDragLayer getDragLayer() {
- return mMyDragLayer;
- }
-
- @Override
- public DeviceProfile getDeviceProfile() {
- return mProfile;
- }
-
- private static class MyDragLayer extends BaseDragLayer<ActivityContextWrapper> {
-
- MyDragLayer(Context context) {
- super(context, null, 1);
- }
-
- @Override
- public void recreateControllers() {
- mControllers = new TouchController[0];
- }
- }
-}
diff --git a/tests/src/com/android/launcher3/util/KotlinMockitoHelpers.kt b/tests/src/com/android/launcher3/util/KotlinMockitoHelpers.kt
deleted file mode 100644
index 57db13ac45..0000000000
--- a/tests/src/com/android/launcher3/util/KotlinMockitoHelpers.kt
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.launcher3.util
-
-/**
- * Kotlin versions of popular mockito methods that can return null in situations when Kotlin expects
- * a non-null value. Kotlin will throw an IllegalStateException when this takes place ("x must not
- * be null"). To fix this, we can use methods that modify the return type to be nullable. This
- * causes Kotlin to skip the null checks.
- */
-
-import org.mockito.ArgumentCaptor
-import org.mockito.Mockito
-
-/**
- * Returns Mockito.eq() as nullable type to avoid java.lang.IllegalStateException when
- * null is returned.
- *
- * Generic T is nullable because implicitly bounded by Any?.
- */
-fun <T> eq(obj: T): T = Mockito.eq<T>(obj)
-
-/**
- * Returns Mockito.same() as nullable type to avoid java.lang.IllegalStateException when
- * null is returned.
- *
- * Generic T is nullable because implicitly bounded by Any?.
- */
-fun <T> same(obj: T): T = Mockito.same<T>(obj)
-
-/**
- * Returns Mockito.any() as nullable type to avoid java.lang.IllegalStateException when
- * null is returned.
- *
- * Generic T is nullable because implicitly bounded by Any?.
- */
-fun <T> any(type: Class<T>): T = Mockito.any<T>(type)
-inline fun <reified T> any(): T = any(T::class.java)
-
-/**
- * Kotlin type-inferred version of Mockito.nullable()
- */
-inline fun <reified T> nullable(): T? = Mockito.nullable(T::class.java)
-
-/**
- * Returns ArgumentCaptor.capture() as nullable type to avoid java.lang.IllegalStateException
- * when null is returned.
- *
- * Generic T is nullable because implicitly bounded by Any?.
- */
-fun <T> capture(argumentCaptor: ArgumentCaptor<T>): T = argumentCaptor.capture()
-
-/**
- * Helper function for creating an argumentCaptor in kotlin.
- *
- * Generic T is nullable because implicitly bounded by Any?.
- */
-inline fun <reified T : Any> argumentCaptor(): ArgumentCaptor<T> =
- ArgumentCaptor.forClass(T::class.java)
-
-/**
- * Helper function for creating new mocks, without the need to pass in a [Class] instance.
- *
- * Generic T is nullable because implicitly bounded by Any?.
- */
-inline fun <reified T : Any> mock(): T = Mockito.mock(T::class.java)
-
-/**
- * A kotlin implemented wrapper of [ArgumentCaptor] which prevents the following exception when
- * kotlin tests are mocking kotlin objects and the methods take non-null parameters:
- *
- * java.lang.NullPointerException: capture() must not be null
- */
-class KotlinArgumentCaptor<T> constructor(clazz: Class<T>) {
- private val wrapped: ArgumentCaptor<T> = ArgumentCaptor.forClass(clazz)
- fun capture(): T = wrapped.capture()
- val value: T
- get() = wrapped.value
-}
-
-/**
- * Helper function for creating an argumentCaptor in kotlin.
- *
- * Generic T is nullable because implicitly bounded by Any?.
- */
-inline fun <reified T : Any> kotlinArgumentCaptor(): KotlinArgumentCaptor<T> =
- KotlinArgumentCaptor(T::class.java)
-
-/**
- * Helper function for creating and using a single-use ArgumentCaptor in kotlin.
- *
- * val captor = argumentCaptor<Foo>()
- * verify(...).someMethod(captor.capture())
- * val captured = captor.value
- *
- * becomes:
- *
- * val captured = withArgCaptor<Foo> { verify(...).someMethod(capture()) }
- *
- * NOTE: this uses the KotlinArgumentCaptor to avoid the NullPointerException.
- */
-inline fun <reified T : Any> withArgCaptor(block: KotlinArgumentCaptor<T>.() -> Unit): T =
- kotlinArgumentCaptor<T>().apply { block() }.value
diff --git a/tests/src/com/android/launcher3/util/MultiAdditivePropertyTest.kt b/tests/src/com/android/launcher3/util/MultiAdditivePropertyTest.kt
deleted file mode 100644
index 309d055bad..0000000000
--- a/tests/src/com/android/launcher3/util/MultiAdditivePropertyTest.kt
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.launcher3.util
-
-import android.view.View
-import androidx.test.ext.junit.runners.AndroidJUnit4
-import androidx.test.filters.SmallTest
-import com.google.common.truth.Truth.assertThat
-import org.junit.Test
-import org.junit.runner.RunWith
-
-/** Unit tests for [MultiAdditivePropertyFactory] */
-@SmallTest
-@RunWith(AndroidJUnit4::class)
-class MultiAdditivePropertyTest {
-
- private val received = mutableListOf<Float>()
-
- private val factory =
- object : MultiAdditivePropertyFactory<View?>("Test", View.TRANSLATION_X) {
- override fun apply(obj: View?, value: Float) {
- received.add(value)
- }
- }
-
- private val p1 = factory.get(1)
- private val p2 = factory.get(2)
- private val p3 = factory.get(3)
-
- @Test
- fun set_sameIndexes_allApplied() {
- val v1 = 50f
- val v2 = 100f
- p1.set(null, v1)
- p1.set(null, v1)
- p1.set(null, v2)
-
- assertThat(received).containsExactly(v1, v1, v2)
- }
-
- @Test
- fun set_differentIndexes_aggregationApplied() {
- val v1 = 50f
- val v2 = 100f
- val v3 = 150f
- p1.set(null, v1)
- p2.set(null, v2)
- p3.set(null, v3)
-
- assertThat(received).containsExactly(v1, v1 + v2, v1 + v2 + v3)
- }
-}
diff --git a/tests/src/com/android/launcher3/util/MultiScalePropertyTest.kt b/tests/src/com/android/launcher3/util/MultiScalePropertyTest.kt
deleted file mode 100644
index 7d92214d9b..0000000000
--- a/tests/src/com/android/launcher3/util/MultiScalePropertyTest.kt
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.launcher3.util
-
-import android.view.View
-import androidx.test.ext.junit.runners.AndroidJUnit4
-import androidx.test.filters.SmallTest
-import com.google.common.truth.Truth.assertThat
-import org.junit.Test
-import org.junit.runner.RunWith
-
-/** Unit tests for [MultiScalePropertyFactory] */
-@SmallTest
-@RunWith(AndroidJUnit4::class)
-class MultiScalePropertyTest {
-
- private val received = mutableListOf<Float>()
-
- private val factory =
- object : MultiScalePropertyFactory<View?>("Test") {
- override fun apply(obj: View?, value: Float) {
- received.add(value)
- }
- }
-
- private val p1 = factory.get(1)
- private val p2 = factory.get(2)
- private val p3 = factory.get(3)
-
- @Test
- fun set_multipleSame_bothAppliedd() {
- p1.set(null, 0.5f)
- p1.set(null, 0.5f)
-
- assertThat(received).containsExactly(0.5f, 0.5f)
- }
-
- @Test
- fun set_differentIndexes_oneValuesNotCounted() {
- val v1 = 0.5f
- val v2 = 1.0f
- p1.set(null, v1)
- p2.set(null, v2)
-
- assertThat(received).containsExactly(v1, v1)
- }
-
- @Test
- fun set_onlyOneSetToOne_oneApplied() {
- p1.set(null, 1.0f)
-
- assertThat(received).containsExactly(1.0f)
- }
-
- @Test
- fun set_onlyOneLessThanOne_applied() {
- p1.set(null, 0.5f)
-
- assertThat(received).containsExactly(0.5f)
- }
-
- @Test
- fun set_differentIndexes_boundToMin() {
- val v1 = 0.5f
- val v2 = 0.6f
- p1.set(null, v1)
- p2.set(null, v2)
-
- assertThat(received).containsExactly(v1, v1)
- }
-
- @Test
- fun set_allHigherThanOne_boundToMax() {
- val v1 = 3.0f
- val v2 = 2.0f
- val v3 = 1.0f
- p1.set(null, v1)
- p2.set(null, v2)
- p3.set(null, v3)
-
- assertThat(received).containsExactly(v1, v1, v1)
- }
-
- @Test
- fun set_differentIndexes_firstModified_aggregationApplied() {
- val v1 = 0.5f
- val v2 = 0.6f
- val v3 = 4f
- p1.set(null, v1)
- p2.set(null, v2)
- p3.set(null, v3)
-
- assertThat(received).containsExactly(v1, v1, v1 * v2 * v3)
- }
-}
diff --git a/tests/src/com/android/launcher3/util/PackageUserKeyTest.java b/tests/src/com/android/launcher3/util/PackageUserKeyTest.java
deleted file mode 100644
index 99490eb7c9..0000000000
--- a/tests/src/com/android/launcher3/util/PackageUserKeyTest.java
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Copyright (C) 2021 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.launcher3.util;
-
-import static com.android.launcher3.widget.WidgetSections.NO_CATEGORY;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.os.UserHandle;
-
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
-
-import com.android.launcher3.model.data.PackageItemInfo;
-
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.ExpectedException;
-import org.junit.runner.RunWith;
-
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public final class PackageUserKeyTest {
- @Rule
- public ExpectedException exception = ExpectedException.none();
-
- private static final String TEST_PACKAGE = "com.android.test.package";
- private static final int CONVERSATIONS = 0;
- private static final int WEATHER = 1;
-
- @Test
- public void fromPackageItemInfo_shouldCreateExpectedObject() {
- PackageUserKey packageUserKey = PackageUserKey.fromPackageItemInfo(
- new PackageItemInfo(TEST_PACKAGE, UserHandle.CURRENT));
-
- assertThat(packageUserKey.mPackageName).isEqualTo(TEST_PACKAGE);
- assertThat(packageUserKey.mWidgetCategory).isEqualTo(NO_CATEGORY);
- assertThat(packageUserKey.mUser).isEqualTo(UserHandle.CURRENT);
- }
-
- @Test
- public void constructor_packageNameAndUserHandle_shouldCreateExpectedObject() {
- PackageUserKey packageUserKey = new PackageUserKey(TEST_PACKAGE, UserHandle.CURRENT);
-
- assertThat(packageUserKey.mPackageName).isEqualTo(TEST_PACKAGE);
- assertThat(packageUserKey.mWidgetCategory).isEqualTo(NO_CATEGORY);
- assertThat(packageUserKey.mUser).isEqualTo(UserHandle.CURRENT);
- }
-
- @Test
- public void constructor_widgetCategoryAndUserHandle_shouldCreateExpectedObject() {
- PackageUserKey packageUserKey = new PackageUserKey(CONVERSATIONS, UserHandle.CURRENT);
-
- assertThat(packageUserKey.mPackageName).isEqualTo("");
- assertThat(packageUserKey.mWidgetCategory).isEqualTo(CONVERSATIONS);
- assertThat(packageUserKey.mUser).isEqualTo(UserHandle.CURRENT);
- }
-
- @Test
- public void equals_sameObject_shouldReturnTrue() {
- PackageUserKey packageUserKey = new PackageUserKey(TEST_PACKAGE, UserHandle.CURRENT);
- PackageUserKey otherPackageUserKey = packageUserKey;
-
- assertThat(packageUserKey).isEqualTo(otherPackageUserKey);
- }
-
- @Test
- public void equals_differentObjectSameContent_shouldReturnTrue() {
- PackageUserKey packageUserKey = new PackageUserKey(TEST_PACKAGE, UserHandle.CURRENT);
- PackageUserKey otherPackageUserKey = new PackageUserKey(TEST_PACKAGE, UserHandle.CURRENT);
-
- assertThat(packageUserKey).isEqualTo(otherPackageUserKey);
- }
-
- @Test
- public void equals_compareAgainstNull_shouldReturnFalse() {
- PackageUserKey packageUserKey = new PackageUserKey(TEST_PACKAGE, UserHandle.CURRENT);
-
- assertThat(packageUserKey).isNotEqualTo(null);
- }
-
- @Test
- public void equals_differentPackage_shouldReturnFalse() {
- PackageUserKey packageUserKey = new PackageUserKey(TEST_PACKAGE, UserHandle.CURRENT);
- PackageUserKey otherPackageUserKey = new PackageUserKey(TEST_PACKAGE + "1",
- UserHandle.CURRENT);
-
- assertThat(packageUserKey).isNotEqualTo(otherPackageUserKey);
- }
-
-
- @Test
- public void equals_differentCategory_shouldReturnFalse() {
- PackageUserKey packageUserKey = new PackageUserKey(WEATHER, UserHandle.CURRENT);
- PackageUserKey otherPackageUserKey = new PackageUserKey(CONVERSATIONS, UserHandle.CURRENT);
-
- assertThat(packageUserKey).isNotEqualTo(otherPackageUserKey);
- }
-
- @Test
- public void equals_differentUser_shouldReturnFalse() {
- PackageUserKey packageUserKey = new PackageUserKey(TEST_PACKAGE, UserHandle.of(1));
- PackageUserKey otherPackageUserKey = new PackageUserKey(TEST_PACKAGE, UserHandle.of(2));
-
- assertThat(packageUserKey).isNotEqualTo(otherPackageUserKey);
- }
-
- @Test
- public void hashCode_sameObject_shouldBeTheSame() {
- PackageUserKey packageUserKey = new PackageUserKey(WEATHER, UserHandle.CURRENT);
- PackageUserKey otherPackageUserKey = packageUserKey;
-
- assertThat(packageUserKey.hashCode()).isEqualTo(otherPackageUserKey.hashCode());
- }
-
- @Test
- public void hashCode_differentObjectSameContent_shouldBeTheSame() {
- PackageUserKey packageUserKey = new PackageUserKey(TEST_PACKAGE, UserHandle.CURRENT);
- PackageUserKey otherPackageUserKey = new PackageUserKey(TEST_PACKAGE, UserHandle.CURRENT);
-
- assertThat(packageUserKey.hashCode()).isEqualTo(otherPackageUserKey.hashCode());
- }
-
- @Test
- public void hashCode_differentPackage_shouldBeDifferent() {
- PackageUserKey packageUserKey = new PackageUserKey(TEST_PACKAGE, UserHandle.CURRENT);
- PackageUserKey otherPackageUserKey = new PackageUserKey(TEST_PACKAGE + "1",
- UserHandle.CURRENT);
-
- assertThat(packageUserKey.hashCode()).isNotEqualTo(otherPackageUserKey.hashCode());
- }
-
-
- @Test
- public void hashCode_differentCategory_shouldBeDifferent() {
- PackageUserKey packageUserKey = new PackageUserKey(WEATHER, UserHandle.CURRENT);
- PackageUserKey otherPackageUserKey = new PackageUserKey(CONVERSATIONS, UserHandle.CURRENT);
-
- assertThat(packageUserKey.hashCode()).isNotEqualTo(otherPackageUserKey.hashCode());
- }
-
- @Test
- public void hashCode_differentUser_shouldBeDifferent() {
- PackageUserKey packageUserKey = new PackageUserKey(TEST_PACKAGE, UserHandle.of(1));
- PackageUserKey otherPackageUserKey = new PackageUserKey(TEST_PACKAGE, UserHandle.of(2));
-
- assertThat(packageUserKey.hashCode()).isNotEqualTo(otherPackageUserKey.hashCode());
- }
-}
diff --git a/tests/src/com/android/launcher3/util/ReflectionHelpers.java b/tests/src/com/android/launcher3/util/ReflectionHelpers.java
deleted file mode 100644
index d89975de8a..0000000000
--- a/tests/src/com/android/launcher3/util/ReflectionHelpers.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2021 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.launcher3.util;
-
-import java.lang.reflect.Field;
-
-public class ReflectionHelpers {
-
- /**
- * Reflectively get the value of a field.
- *
- * @param object Target object.
- * @param fieldName The field name.
- * @param <R> The return type.
- * @return Value of the field on the object.
- */
- public static <R> R getField(Object object, String fieldName) {
- try {
- Field field = object.getClass().getDeclaredField(fieldName);
- field.setAccessible(true);
- return (R) field.get(object);
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- }
-
- /**
- * Reflectively set the value of a field.
- *
- * @param object Target object.
- * @param fieldName The field name.
- * @param fieldNewValue New value.
- */
- public static void setField(Object object, String fieldName, Object fieldNewValue) {
- try {
- Field field = object.getClass().getDeclaredField(fieldName);
- field.setAccessible(true);
- field.set(object, fieldNewValue);
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- }
-
-}
diff --git a/tests/src/com/android/launcher3/util/Wait.java b/tests/src/com/android/launcher3/util/Wait.java
index 50bc32e509..fe6143c681 100644
--- a/tests/src/com/android/launcher3/util/Wait.java
+++ b/tests/src/com/android/launcher3/util/Wait.java
@@ -52,7 +52,7 @@ public class Wait {
throw new RuntimeException(t);
}
Log.d("Wait", "atMost: timed out: " + SystemClock.uptimeMillis());
- launcher.checkForAnomaly(false, false);
+ launcher.checkForAnomaly();
Assert.fail(message.get());
}
diff --git a/tests/src/com/android/launcher3/util/rule/FailureWatcher.java b/tests/src/com/android/launcher3/util/rule/FailureWatcher.java
index 4c41d7ec4f..dc59bddabd 100644
--- a/tests/src/com/android/launcher3/util/rule/FailureWatcher.java
+++ b/tests/src/com/android/launcher3/util/rule/FailureWatcher.java
@@ -2,7 +2,6 @@ package com.android.launcher3.util.rule;
import static androidx.test.InstrumentationRegistry.getInstrumentation;
-import android.content.Context;
import android.os.FileUtils;
import android.os.ParcelFileDescriptor.AutoCloseInputStream;
import android.util.Log;
@@ -14,9 +13,7 @@ import com.android.launcher3.ui.AbstractLauncherUiTest;
import org.junit.rules.TestWatcher;
import org.junit.runner.Description;
-import org.junit.runners.model.Statement;
-import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
@@ -32,7 +29,6 @@ public class FailureWatcher extends TestWatcher {
public FailureWatcher(UiDevice device, LauncherInstrumentation launcher) {
mDevice = device;
mLauncher = launcher;
- Log.d("b/196820244", "FailureWatcher.ctor", new Exception());
}
@Override
@@ -42,65 +38,17 @@ public class FailureWatcher extends TestWatcher {
}
@Override
- public Statement apply(Statement base, Description description) {
- return new Statement() {
- @Override
- public void evaluate() throws Throwable {
- boolean success = false;
- try {
- Log.d("b/196820244", "Before evaluate");
- mDevice.executeShellCommand("cmd statusbar tracing start");
- FailureWatcher.super.apply(base, description).evaluate();
- Log.d("b/196820244", "After evaluate");
- success = true;
- } finally {
- // Save artifact for Launcher Winscope trace.
- mDevice.executeShellCommand("cmd statusbar tracing stop");
- final Context nexusLauncherContext =
- getInstrumentation().getTargetContext()
- .createPackageContext("com.google.android.apps.nexuslauncher",
- 0);
- final File launcherTrace =
- new File(nexusLauncherContext.getFilesDir(), "launcher_trace.pb");
- if (success) {
- mDevice.executeShellCommand("rm " + launcherTrace);
- } else {
- mDevice.executeShellCommand("mv " + launcherTrace + " "
- + diagFile(description, "LauncherWinscope", "pb"));
- }
-
- // Detect touch events coming from physical screen.
- if (mLauncher.hadNontestEvents()) {
- throw new AssertionError(
- "Launcher received events not sent by the test. This may mean "
- + "that the touch screen of the lab device has sent false"
- + " events. See the logcat for TaplEvents tag and look "
- + "for events with deviceId != -1");
- }
- }
- }
- };
- }
-
- @Override
protected void failed(Throwable e, Description description) {
- onError(mLauncher, description, e);
+ onError(mDevice, description, e);
}
- static File diagFile(Description description, String prefix, String ext) {
- return new File(getInstrumentation().getTargetContext().getFilesDir(),
- prefix + "-" + description.getTestClass().getSimpleName() + "."
- + description.getMethodName() + "." + ext);
- }
-
- public static void onError(LauncherInstrumentation launcher, Description description,
- Throwable e) {
- final UiDevice device = launcher.getDevice();
- Log.d("b/196820244", "onError 1");
+ public static void onError(UiDevice device, Description description, Throwable e) {
if (device == null) return;
- Log.d("b/196820244", "onError 2");
- final File sceenshot = diagFile(description, "TestScreenshot", "png");
- final File hierarchy = diagFile(description, "Hierarchy", "zip");
+ final File parentFile = getInstrumentation().getTargetContext().getFilesDir();
+ final File sceenshot = new File(parentFile,
+ "TestScreenshot-" + description.getMethodName() + ".png");
+ final File hierarchy = new File(parentFile,
+ "Hierarchy-" + description.getMethodName() + ".zip");
// Dump window hierarchy
try (ZipOutputStream out = new ZipOutputStream(new FileOutputStream(hierarchy))) {
@@ -113,30 +61,13 @@ public class FailureWatcher extends TestWatcher {
out.putNextEntry(new ZipEntry("visible_windows.zip"));
dumpCommand("cmd window dump-visible-window-views", out);
out.closeEntry();
- } catch (IOException ex) {
- }
+ } catch (IOException ex) { }
Log.e(TAG, "Failed test " + description.getMethodName()
+ ",\nscreenshot will be saved to " + sceenshot
+ ",\nUI dump at: " + hierarchy
+ " (use go/web-hv to open the dump file)", e);
device.takeScreenshot(sceenshot);
-
- // Dump accessibility hierarchy
- try {
- device.dumpWindowHierarchy(diagFile(description, "AccessibilityHierarchy", "uix"));
- } catch (IOException ex) {
- Log.e(TAG, "Failed to save accessibility hierarchy", ex);
- }
-
- dumpCommand("logcat -d -s TestRunner", diagFile(description, "FilteredLogcat", "txt"));
-
- // Dump bugreport
- final String systemAnomalyMessage = launcher.getSystemAnomalyMessage(false, false);
- if (systemAnomalyMessage != null) {
- Log.d(TAG, "Saving bugreport, system anomaly message: " + systemAnomalyMessage, e);
- dumpCommand("bugreportz -s", diagFile(description, "Bugreport", "zip"));
- }
}
private static void dumpStringCommand(String cmd, OutputStream out) throws IOException {
@@ -144,14 +75,6 @@ public class FailureWatcher extends TestWatcher {
dumpCommand(cmd, out);
}
- private static void dumpCommand(String cmd, File out) {
- try (BufferedOutputStream buffered = new BufferedOutputStream(
- new FileOutputStream(out))) {
- dumpCommand(cmd, buffered);
- } catch (IOException ex) {
- }
- }
-
private static void dumpCommand(String cmd, OutputStream out) throws IOException {
try (AutoCloseInputStream in = new AutoCloseInputStream(getInstrumentation()
.getUiAutomation().executeShellCommand(cmd))) {
diff --git a/tests/src/com/android/launcher3/util/rule/LauncherActivityRule.java b/tests/src/com/android/launcher3/util/rule/LauncherActivityRule.java
index 2093682373..6a6ec3e41d 100644
--- a/tests/src/com/android/launcher3/util/rule/LauncherActivityRule.java
+++ b/tests/src/com/android/launcher3/util/rule/LauncherActivityRule.java
@@ -18,7 +18,7 @@ package com.android.launcher3.util.rule;
import android.app.Activity;
import com.android.launcher3.Launcher;
-import com.android.launcher3.util.LauncherBindableItemsContainer.ItemOperator;
+import com.android.launcher3.Workspace.ItemOperator;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;
diff --git a/tests/src/com/android/launcher3/util/rule/SamplerRule.java b/tests/src/com/android/launcher3/util/rule/SamplerRule.java
deleted file mode 100644
index 6125f2a8d2..0000000000
--- a/tests/src/com/android/launcher3/util/rule/SamplerRule.java
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.launcher3.util.rule;
-
-import android.os.SystemClock;
-
-import androidx.test.InstrumentationRegistry;
-
-import org.junit.rules.TestRule;
-import org.junit.runner.Description;
-import org.junit.runners.model.Statement;
-
-import java.io.BufferedOutputStream;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.OutputStreamWriter;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-
-/**
- * A rule that generates a file that helps diagnosing cases when the test process was terminated
- * because the test execution took too long, and tests that ran for too long even without being
- * terminated. If the process was terminated or the test was long, the test leaves an artifact with
- * stack traces of all threads, every SAMPLE_INTERVAL_MS. This will help understanding where we
- * stuck.
- */
-public class SamplerRule implements TestRule {
- private static final int TOO_LONG_TEST_MS = 180000;
- private static final int SAMPLE_INTERVAL_MS = 3000;
-
- public static Thread startThread(Description description) {
- Thread thread =
- new Thread() {
- @Override
- public void run() {
- // Write all-threads stack stace every SAMPLE_INTERVAL_MS while the test
- // is running.
- // After the test finishes, delete that file. If the test process is
- // terminated due to timeout, the trace file won't be deleted.
- final File file = getFile();
-
- final long startTime = SystemClock.elapsedRealtime();
- try (OutputStreamWriter outputStreamWriter =
- new OutputStreamWriter(
- new BufferedOutputStream(
- new FileOutputStream(file)))) {
- writeSamples(outputStreamWriter);
- } catch (IOException | InterruptedException e) {
- // Simply suppressing the exceptions, nothing to do here.
- } finally {
- // If the process is not killed, then there was no test timeout, and
- // we are not interested in the trace file, unless the test ran too
- // long.
- if (SystemClock.elapsedRealtime() - startTime < TOO_LONG_TEST_MS) {
- file.delete();
- }
- }
- }
-
- private File getFile() {
- final String strDate = new SimpleDateFormat("HH:mm:ss").format(new Date());
-
- final String descStr = description.getTestClass().getSimpleName() + "."
- + description.getMethodName();
- return artifactFile(
- "ThreadStackSamples-" + strDate + "-" + descStr + ".txt");
- }
-
- private void writeSamples(OutputStreamWriter writer)
- throws IOException, InterruptedException {
- int count = 0;
- while (true) {
- writer.write(
- "#"
- + (count++)
- + " =============================================\r\n");
- for (StackTraceElement[] stack : getAllStackTraces().values()) {
- writer.write("---------------------\r\n");
- for (StackTraceElement frame : stack) {
- writer.write(frame.toString() + "\r\n");
- }
- }
- writer.flush();
-
- sleep(SAMPLE_INTERVAL_MS);
- }
- }
- };
-
- thread.start();
- return thread;
- }
-
- @Override
- public Statement apply(Statement base, Description description) {
- return new Statement() {
- @Override
- public void evaluate() throws Throwable {
- final Thread traceThread = startThread(description);
- try {
- base.evaluate();
- } finally {
- traceThread.interrupt();
- traceThread.join();
- }
- }
- };
- }
-
- private static File artifactFile(String fileName) {
- return new File(
- InstrumentationRegistry.getInstrumentation().getTargetContext().getFilesDir(),
- fileName);
- }
-}
diff --git a/tests/src/com/android/launcher3/util/rule/ShellCommandRule.java b/tests/src/com/android/launcher3/util/rule/ShellCommandRule.java
index 08953fc4c8..2b2fef4ae6 100644
--- a/tests/src/com/android/launcher3/util/rule/ShellCommandRule.java
+++ b/tests/src/com/android/launcher3/util/rule/ShellCommandRule.java
@@ -21,6 +21,7 @@ import static com.android.launcher3.tapl.TestHelpers.getLauncherInMyProcess;
import android.content.ComponentName;
import android.content.pm.ActivityInfo;
+import android.util.Log;
import androidx.annotation.Nullable;
import androidx.test.InstrumentationRegistry;
@@ -102,6 +103,8 @@ public class ShellCommandRule implements TestRule {
*/
public static ShellCommandRule setDefaultLauncher() {
final ActivityInfo launcher = getLauncherInMyProcess();
+ Log.d("b/187080582", "Launcher: " + new ComponentName(launcher.packageName, launcher.name)
+ .flattenToString());
return new ShellCommandRule(getLauncherCommand(launcher), null, true, () ->
Assert.assertEquals("Setting default launcher failed",
new ComponentName(launcher.packageName, launcher.name)
diff --git a/tests/src/com/android/launcher3/util/rule/TestStabilityRule.java b/tests/src/com/android/launcher3/util/rule/TestStabilityRule.java
index f33a50ae5a..0e27b61b84 100644
--- a/tests/src/com/android/launcher3/util/rule/TestStabilityRule.java
+++ b/tests/src/com/android/launcher3/util/rule/TestStabilityRule.java
@@ -41,7 +41,9 @@ public class TestStabilityRule implements TestRule {
Pattern.compile("^("
+ "(?<local>(BuildFromAndroidStudio|"
+ "([0-9]+|[A-Z])-eng\\.[a-z]+\\.[0-9]+\\.[0-9]+))|"
- + "(?<platform>([A-Z][a-z]*[0-9]*|[0-9]+)*)"
+ + "(?<presubmit>([0-9]+|[A-Z])-P[0-9]+)|"
+ + "(?<postsubmit>([0-9]+|[A-Z])-[0-9]+)|"
+ + "(?<platform>[0-9]+|[A-Z])"
+ ")$");
private static final Pattern PLATFORM_BUILD =
Pattern.compile("^("
diff --git a/tests/src_common/README.md b/tests/src_common/README.md
new file mode 100644
index 0000000000..2bc9e73d86
--- /dev/null
+++ b/tests/src_common/README.md
@@ -0,0 +1 @@
+Common source code used by both android tests and robolectric tests \ No newline at end of file
diff --git a/tests/src/com/android/launcher3/util/WidgetUtils.java b/tests/src_common/com/android/launcher3/common/WidgetUtils.java
index 6fc84914f8..97500e3131 100644
--- a/tests/src/com/android/launcher3/util/WidgetUtils.java
+++ b/tests/src_common/com/android/launcher3/common/WidgetUtils.java
@@ -13,25 +13,19 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.android.launcher3.util;
-
-import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
-import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
+package com.android.launcher3.common;
import static com.android.launcher3.WorkspaceLayoutManager.FIRST_SCREEN_ID;
import android.appwidget.AppWidgetHost;
-import android.appwidget.AppWidgetManager;
-import android.appwidget.AppWidgetProviderInfo;
-import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
import android.os.Bundle;
-import android.os.Process;
import com.android.launcher3.LauncherSettings;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.LauncherAppWidgetInfo;
+import com.android.launcher3.util.ContentWriter;
import com.android.launcher3.widget.LauncherAppWidgetHost;
import com.android.launcher3.widget.LauncherAppWidgetProviderInfo;
import com.android.launcher3.widget.PendingAddWidgetInfo;
@@ -108,17 +102,4 @@ public class WidgetUtils {
resolver.insert(LauncherSettings.Favorites.CONTENT_URI,
writer.getValues(targetContext));
}
-
-
- /**
- * Creates a {@link AppWidgetProviderInfo} for the provided component name
- */
- public static AppWidgetProviderInfo createAppWidgetProviderInfo(ComponentName cn) {
- AppWidgetProviderInfo info = AppWidgetManager.getInstance(getApplicationContext())
- .getInstalledProvidersForPackage(
- getInstrumentation().getContext().getPackageName(), Process.myUserHandle())
- .get(0);
- info.provider = cn;
- return info;
- }
}
diff --git a/tests/src_disabled/WorkTabTest.java b/tests/src_disabled/WorkTabTest.java
new file mode 100644
index 0000000000..bfacc74220
--- /dev/null
+++ b/tests/src_disabled/WorkTabTest.java
@@ -0,0 +1,236 @@
+/*
+ * Copyright 2018, 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.launcher3.ui;
+
+import static com.android.launcher3.LauncherState.ALL_APPS;
+import static com.android.launcher3.LauncherState.NORMAL;
+import static com.android.launcher3.allapps.AllAppsStore.DEFER_UPDATES_TEST;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import android.os.Process;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.util.Log;
+import android.widget.TextView;
+
+import androidx.test.filters.LargeTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.launcher3.R;
+import com.android.launcher3.allapps.AllAppsContainerView;
+import com.android.launcher3.allapps.AllAppsPagedView;
+import com.android.launcher3.allapps.WorkModeSwitch;
+import com.android.launcher3.dragndrop.DragLayer;
+import com.android.launcher3.tapl.LauncherInstrumentation;
+import com.android.launcher3.testing.TestProtocol;
+import com.android.launcher3.views.WorkEduView;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.List;
+import java.util.Objects;
+import java.util.concurrent.atomic.AtomicInteger;
+
+@LargeTest
+@RunWith(AndroidJUnit4.class)
+public class WorkTabTest extends AbstractLauncherUiTest {
+
+ private int mProfileUserId;
+
+ private static final int WORK_PAGE = AllAppsContainerView.AdapterHolder.WORK;
+
+ @Before
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ String output =
+ mDevice.executeShellCommand(
+ "pm create-user --profileOf 0 --managed TestProfile");
+ assertTrue("Failed to create work profile", output.startsWith("Success"));
+
+ String[] tokens = output.split("\\s+");
+ mProfileUserId = Integer.parseInt(tokens[tokens.length - 1]);
+ Log.d(TestProtocol.WORK_PROFILE_REMOVED, "Created new user uid" + mProfileUserId);
+ mDevice.executeShellCommand("am start-user " + mProfileUserId);
+ }
+
+ @After
+ public void removeWorkProfile() throws Exception {
+ Log.d(TestProtocol.WORK_PROFILE_REMOVED, "(teardown) removing uid" + mProfileUserId,
+ new Exception());
+ mDevice.executeShellCommand("pm remove-user " + mProfileUserId);
+ }
+
+ @After
+ public void resumeAppStoreUpdate() {
+ executeOnLauncher(launcher -> {
+ if (launcher == null || launcher.getAppsView() == null) {
+ return;
+ }
+ launcher.getAppsView().getAppsStore().disableDeferUpdates(DEFER_UPDATES_TEST);
+ Log.d(TestProtocol.WORK_PROFILE_REMOVED, "resuming AppStore updates");
+ });
+ }
+
+ @Ignore("b/182844465")
+ @Test
+ public void workTabExists() {
+ mDevice.pressHome();
+ waitForLauncherCondition("Launcher didn't start", Objects::nonNull);
+ executeOnLauncher(launcher -> launcher.getStateManager().goToState(ALL_APPS));
+ waitForState("Launcher internal state didn't switch to All Apps", () -> ALL_APPS);
+ waitForLauncherCondition("Personal tab is missing",
+ launcher -> launcher.getAppsView().isPersonalTabVisible(), 60000);
+ waitForLauncherCondition("Work tab is missing",
+ launcher -> launcher.getAppsView().isWorkTabVisible(), 60000);
+ }
+
+ @Ignore("b/182844465")
+ @Test
+ public void toggleWorks() {
+ mDevice.pressHome();
+ waitForLauncherCondition("Launcher didn't start", Objects::nonNull);
+ executeOnLauncher(launcher -> launcher.getStateManager().goToState(ALL_APPS));
+ waitForState("Launcher internal state didn't switch to All Apps", () -> ALL_APPS);
+ getOnceNotNull("Apps view did not bind",
+ launcher -> launcher.getAppsView().getWorkModeSwitch(), 60000);
+
+ UserManager userManager = getFromLauncher(l -> l.getSystemService(UserManager.class));
+ assertEquals(2, userManager.getUserProfiles().size());
+ UserHandle workProfile = getFromLauncher(l -> {
+ UserHandle myHandle = Process.myUserHandle();
+ List<UserHandle> userProfiles = userManager.getUserProfiles();
+ return userProfiles.get(0) == myHandle ? userProfiles.get(1) : userProfiles.get(0);
+ });
+
+ waitForLauncherCondition("work profile can't be turned off",
+ l -> userManager.requestQuietModeEnabled(true, workProfile));
+
+ assertTrue(userManager.isQuietModeEnabled(workProfile));
+ executeOnLauncher(launcher -> {
+ WorkModeSwitch wf = launcher.getAppsView().getWorkModeSwitch();
+ ((AllAppsPagedView) launcher.getAppsView().getContentView()).snapToPageImmediately(
+ AllAppsContainerView.AdapterHolder.WORK);
+ wf.toggle();
+ });
+ waitForLauncherCondition("Work toggle did not work",
+ l -> l.getSystemService(UserManager.class).isQuietModeEnabled(workProfile));
+ }
+
+ @Ignore("b/182844465")
+ @Test
+ public void testWorkEduFlow() {
+ mDevice.pressHome();
+ waitForLauncherCondition("Launcher didn't start", Objects::nonNull);
+ executeOnLauncher(launcher -> launcher.getSharedPrefs().edit().remove(
+ WorkEduView.KEY_WORK_EDU_STEP).remove(
+ WorkEduView.KEY_LEGACY_WORK_EDU_SEEN).commit());
+
+ waitForLauncherCondition("Work tab not setup", launcher -> {
+ if (launcher.getAppsView().getContentView() instanceof AllAppsPagedView) {
+ launcher.getAppsView().getAppsStore().enableDeferUpdates(DEFER_UPDATES_TEST);
+ return true;
+ }
+ return false;
+ }, LauncherInstrumentation.WAIT_TIME_MS);
+
+ executeOnLauncher(launcher -> launcher.getStateManager().goToState(ALL_APPS));
+ WorkEduView workEduView = getEduView();
+ // verify personal app edu is seen first and click "next"
+ executeOnLauncher(l -> {
+ assertEquals(((TextView) workEduView.findViewById(R.id.content_text)).getText(),
+ l.getResources().getString(R.string.work_profile_edu_personal_apps));
+ workEduView.findViewById(R.id.proceed).callOnClick();
+ });
+
+ AtomicInteger attempt = new AtomicInteger(0);
+ // verify work edu is seen next
+ waitForLauncherCondition("Launcher did not show the next edu screen", l -> {
+ Log.d(TestProtocol.WORK_PROFILE_REMOVED,
+ "running test attempt" + attempt.getAndIncrement());
+ if (!(l.getAppsView().getContentView() instanceof AllAppsPagedView)) {
+ Log.d(TestProtocol.WORK_PROFILE_REMOVED, "Work tab not setup. Skipping test");
+ return false;
+ }
+ if (((AllAppsPagedView) l.getAppsView().getContentView()).getCurrentPage()
+ != WORK_PAGE) {
+ Log.d(TestProtocol.WORK_PROFILE_REMOVED, "Work page not highlighted");
+ }
+ return ((TextView) workEduView.findViewById(R.id.content_text)).getText().equals(
+ l.getResources().getString(R.string.work_profile_edu_work_apps));
+ });
+ }
+
+ @Ignore("b/182844465")
+ @Test
+ public void testWorkEduIntermittent() {
+ mDevice.pressHome();
+ waitForLauncherCondition("Launcher didn't start", Objects::nonNull);
+ executeOnLauncher(launcher -> launcher.getSharedPrefs().edit().remove(
+ WorkEduView.KEY_WORK_EDU_STEP).remove(
+ WorkEduView.KEY_LEGACY_WORK_EDU_SEEN).commit());
+
+
+ waitForLauncherCondition("Work tab not setup",
+ launcher -> launcher.getAppsView().getContentView() instanceof AllAppsPagedView,
+ 60000);
+ executeOnLauncher(launcher -> launcher.getStateManager().goToState(ALL_APPS));
+
+ // verify personal app edu is seen
+ getEduView();
+
+ // dismiss personal edu
+ mDevice.pressHome();
+ waitForState("Launcher did not go home", () -> NORMAL);
+
+ // open work tab
+ executeOnLauncher(launcher -> launcher.getStateManager().goToState(ALL_APPS));
+ waitForState("Launcher did not switch to all apps", () -> ALL_APPS);
+ waitForLauncherCondition("Work tab not setup",
+ launcher -> launcher.getAppsView().getContentView() instanceof AllAppsPagedView,
+ 60000);
+
+ executeOnLauncher(launcher -> {
+ AllAppsPagedView pagedView = (AllAppsPagedView) launcher.getAppsView().getContentView();
+ pagedView.setCurrentPage(WORK_PAGE);
+ });
+
+ WorkEduView workEduView = getEduView();
+
+ // verify work tab edu is shown
+ waitForLauncherCondition("Launcher did not show the next edu screen",
+ l -> ((TextView) workEduView.findViewById(R.id.content_text)).getText().equals(
+ l.getResources().getString(R.string.work_profile_edu_work_apps)));
+ }
+
+
+ private WorkEduView getEduView() {
+ waitForLauncherCondition("Edu did not show", l -> {
+ DragLayer dragLayer = l.getDragLayer();
+ return dragLayer.getChildCount() > 0 && dragLayer.getChildAt(
+ dragLayer.getChildCount() - 1) instanceof WorkEduView;
+ }, 6000);
+ return getFromLauncher(launcher -> (WorkEduView) launcher.getDragLayer().getChildAt(
+ launcher.getDragLayer().getChildCount() - 1));
+ }
+
+} \ No newline at end of file
diff --git a/tests/tapl/com/android/launcher3/tapl/AddToHomeScreenPrompt.java b/tests/tapl/com/android/launcher3/tapl/AddToHomeScreenPrompt.java
index 98eb32e818..0582bc9557 100644
--- a/tests/tapl/com/android/launcher3/tapl/AddToHomeScreenPrompt.java
+++ b/tests/tapl/com/android/launcher3/tapl/AddToHomeScreenPrompt.java
@@ -22,6 +22,8 @@ import androidx.test.uiautomator.By;
import androidx.test.uiautomator.BySelector;
import androidx.test.uiautomator.UiObject2;
+import com.android.launcher3.testing.TestProtocol;
+
import java.util.regex.Pattern;
public class AddToHomeScreenPrompt {
@@ -42,10 +44,19 @@ public class AddToHomeScreenPrompt {
public void addAutomatically() {
try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck()) {
- mLauncher.clickObject(
- mLauncher.waitForObjectInContainer(
- mWidgetCell.getParent().getParent().getParent().getParent(),
- By.text(ADD_AUTOMATICALLY)));
+ if (mLauncher.getNavigationModel()
+ != LauncherInstrumentation.NavigationModel.THREE_BUTTON) {
+ if (!mLauncher.isLauncher3()) {
+ mLauncher.expectEvent(
+ TestProtocol.SEQUENCE_TIS,
+ LauncherInstrumentation.EVENT_TOUCH_DOWN_TIS);
+ mLauncher.expectEvent(
+ TestProtocol.SEQUENCE_TIS, LauncherInstrumentation.EVENT_TOUCH_UP_TIS);
+ }
+ }
+ mLauncher.waitForObjectInContainer(
+ mWidgetCell.getParent().getParent().getParent().getParent(),
+ By.text(ADD_AUTOMATICALLY)).click();
mLauncher.waitUntilLauncherObjectGone(getSelector());
}
}
diff --git a/tests/tapl/com/android/launcher3/tapl/AllApps.java b/tests/tapl/com/android/launcher3/tapl/AllApps.java
index bfb115d1b8..1cb6b2debf 100644
--- a/tests/tapl/com/android/launcher3/tapl/AllApps.java
+++ b/tests/tapl/com/android/launcher3/tapl/AllApps.java
@@ -22,7 +22,6 @@ import android.os.Bundle;
import android.widget.TextView;
import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
import androidx.test.uiautomator.By;
import androidx.test.uiautomator.BySelector;
import androidx.test.uiautomator.Direction;
@@ -36,7 +35,7 @@ import java.util.stream.Collectors;
/**
* Operations on AllApps opened from Home. Also a parent for All Apps opened from Overview.
*/
-public abstract class AllApps extends LauncherInstrumentation.VisibleContainer {
+public class AllApps extends LauncherInstrumentation.VisibleContainer {
private static final int MAX_SCROLL_ATTEMPTS = 40;
private final int mHeight;
@@ -51,8 +50,14 @@ public abstract class AllApps extends LauncherInstrumentation.VisibleContainer {
// Wait for the recycler to populate.
mLauncher.waitForObjectInContainer(appListRecycler, By.clazz(TextView.class));
verifyNotFrozen("All apps freeze flags upon opening all apps");
- mIconHeight = mLauncher.getTestInfo(TestProtocol.REQUEST_ICON_HEIGHT)
- .getInt(TestProtocol.TEST_INFO_RESPONSE_FIELD);
+ mIconHeight = mLauncher.getTestInfo(
+ TestProtocol.REQUEST_ICON_HEIGHT).
+ getInt(TestProtocol.TEST_INFO_RESPONSE_FIELD);
+ }
+
+ @Override
+ protected LauncherInstrumentation.ContainerType getContainerType() {
+ return LauncherInstrumentation.ContainerType.ALL_APPS;
}
private boolean hasClickableIcon(UiObject2 allAppsContainer, UiObject2 appListRecycler,
@@ -74,7 +79,7 @@ public abstract class AllApps extends LauncherInstrumentation.VisibleContainer {
LauncherInstrumentation.log("hasClickableIcon: icon has insufficient height");
return false;
}
- if (hasSearchBox() && iconCenterInSearchBox(allAppsContainer, icon)) {
+ if (iconCenterInSearchBox(allAppsContainer, icon)) {
LauncherInstrumentation.log("hasClickableIcon: icon center is under search box");
return false;
}
@@ -93,21 +98,21 @@ public abstract class AllApps extends LauncherInstrumentation.VisibleContainer {
}
/**
- * Finds an icon. If the icon doesn't exist, return null.
- * Scrolls the app list when needed to make sure the icon is visible.
+ * Finds an icon. Fails if the icon doesn't exist. Scrolls the app list when needed to make
+ * sure the icon is visible.
*
* @param appName name of the app.
- * @return The app if found, and null if not found.
+ * @return The app.
*/
- @Nullable
- public AppIcon tryGetAppIcon(String appName) {
+ @NonNull
+ public AppIcon getAppIcon(String appName) {
try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck();
LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
"getting app icon " + appName + " on all apps")) {
final UiObject2 allAppsContainer = verifyActiveContainer();
final UiObject2 appListRecycler = mLauncher.waitForObjectInContainer(allAppsContainer,
"apps_list_view");
- final UiObject2 searchBox = hasSearchBox() ? getSearchBox(allAppsContainer) : null;
+ final UiObject2 searchBox = getSearchBox(allAppsContainer);
int deviceHeight = mLauncher.getRealDisplaySize().y;
int bottomGestureStartOnScreen = mLauncher.getBottomGestureStartOnScreen();
@@ -128,11 +133,8 @@ public abstract class AllApps extends LauncherInstrumentation.VisibleContainer {
mLauncher.getVisibleBounds(icon).top
< bottomGestureStartOnScreen)
.collect(Collectors.toList()),
- hasSearchBox()
- ? mLauncher.getVisibleBounds(searchBox).bottom
- - mLauncher.getVisibleBounds(allAppsContainer).top
- : 0);
- verifyActiveContainer();
+ mLauncher.getVisibleBounds(searchBox).bottom
+ - mLauncher.getVisibleBounds(allAppsContainer).top);
final int newScroll = getAllAppsScroll();
mLauncher.assertTrue(
"Scrolled in a wrong direction in AllApps: from " + scroll + " to "
@@ -142,54 +144,35 @@ public abstract class AllApps extends LauncherInstrumentation.VisibleContainer {
mLauncher.assertTrue(
"Exceeded max scroll attempts: " + MAX_SCROLL_ATTEMPTS,
++attempts <= MAX_SCROLL_ATTEMPTS);
+ verifyActiveContainer();
scroll = newScroll;
}
}
verifyActiveContainer();
}
+
// Ignore bottom offset selection here as there might not be any scroll more scroll
// region available.
- if (hasClickableIcon(
- allAppsContainer, appListRecycler, appIconSelector, deviceHeight)) {
+ mLauncher.assertTrue("Unable to scroll to a clickable icon: " + appName,
+ hasClickableIcon(allAppsContainer, appListRecycler, appIconSelector,
+ deviceHeight));
- final UiObject2 appIcon = mLauncher.waitForObjectInContainer(appListRecycler,
- appIconSelector);
- return createAppIcon(appIcon);
- } else {
- return null;
- }
+ final UiObject2 appIcon = mLauncher.waitForObjectInContainer(appListRecycler,
+ appIconSelector);
+ return new AppIcon(mLauncher, appIcon);
}
}
- /**
- * Finds an icon. Fails if the icon doesn't exist. Scrolls the app list when needed to make
- * sure the icon is visible.
- *
- * @param appName name of the app.
- * @return The app.
- */
- @NonNull
- public AppIcon getAppIcon(String appName) {
- AppIcon appIcon = tryGetAppIcon(appName);
- mLauncher.assertNotNull("Unable to scroll to a clickable icon: " + appName, appIcon);
- return appIcon;
- }
-
- @NonNull
- protected abstract AppIcon createAppIcon(UiObject2 icon);
-
- protected abstract boolean hasSearchBox();
-
private void scrollBackToBeginning() {
try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
"want to scroll back in all apps")) {
LauncherInstrumentation.log("Scrolling to the beginning");
final UiObject2 allAppsContainer = verifyActiveContainer();
- final UiObject2 searchBox = hasSearchBox() ? getSearchBox(allAppsContainer) : null;
+ final UiObject2 searchBox = getSearchBox(allAppsContainer);
int attempts = 0;
- final Rect margins = new Rect(
- 0, hasSearchBox() ? mLauncher.getVisibleBounds(searchBox).bottom + 1 : 0, 0, 5);
+ final Rect margins =
+ new Rect(0, mLauncher.getVisibleBounds(searchBox).bottom + 1, 0, 5);
for (int scroll = getAllAppsScroll();
scroll != 0;
@@ -201,11 +184,7 @@ public abstract class AllApps extends LauncherInstrumentation.VisibleContainer {
++attempts <= MAX_SCROLL_ATTEMPTS);
mLauncher.scroll(
- allAppsContainer,
- Direction.UP,
- margins,
- /* steps= */ 12,
- /* slowDown= */ false);
+ allAppsContainer, Direction.UP, margins, 12, false);
}
try (LauncherInstrumentation.Closable c1 = mLauncher.addContextLayer("scrolled up")) {
@@ -234,11 +213,7 @@ public abstract class AllApps extends LauncherInstrumentation.VisibleContainer {
final UiObject2 allAppsContainer = verifyActiveContainer();
// Start the gesture in the center to avoid starting at elements near the top.
mLauncher.scroll(
- allAppsContainer,
- Direction.DOWN,
- new Rect(0, 0, 0, mHeight / 2),
- /* steps= */ 10,
- /* slowDown= */ false);
+ allAppsContainer, Direction.DOWN, new Rect(0, 0, 0, mHeight / 2), 10, false);
verifyActiveContainer();
}
}
@@ -253,11 +228,7 @@ public abstract class AllApps extends LauncherInstrumentation.VisibleContainer {
final UiObject2 allAppsContainer = verifyActiveContainer();
// Start the gesture in the center, for symmetry with forward.
mLauncher.scroll(
- allAppsContainer,
- Direction.UP,
- new Rect(0, mHeight / 2, 0, 0),
- /* steps= */ 10,
- /*slowDown= */ false);
+ allAppsContainer, Direction.UP, new Rect(0, mHeight / 2, 0, 0), 10, false);
verifyActiveContainer();
}
}
@@ -282,4 +253,4 @@ public abstract class AllApps extends LauncherInstrumentation.VisibleContainer {
if (testInfo == null) return;
mLauncher.assertEquals(message, 0, testInfo.getInt(TestProtocol.TEST_INFO_RESPONSE_FIELD));
}
-} \ No newline at end of file
+}
diff --git a/tests/tapl/com/android/launcher3/tapl/AllAppsAppIcon.java b/tests/tapl/com/android/launcher3/tapl/AllAppsAppIcon.java
deleted file mode 100644
index 8adce29436..0000000000
--- a/tests/tapl/com/android/launcher3/tapl/AllAppsAppIcon.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.launcher3.tapl;
-
-import androidx.test.uiautomator.UiObject2;
-
-import java.util.regex.Pattern;
-
-/**
- * App icon in all apps.
- */
-final class AllAppsAppIcon extends HomeAppIcon {
-
- private static final Pattern LONG_CLICK_EVENT = Pattern.compile("onAllAppsItemLongClick");
-
- AllAppsAppIcon(LauncherInstrumentation launcher, UiObject2 icon) {
- super(launcher, icon);
- }
-
- @Override
- protected Pattern getLongClickEvent() {
- return LONG_CLICK_EVENT;
- }
-}
diff --git a/tests/tapl/com/android/launcher3/tapl/AllAppsFromOverview.java b/tests/tapl/com/android/launcher3/tapl/AllAppsFromOverview.java
new file mode 100644
index 0000000000..835790ddff
--- /dev/null
+++ b/tests/tapl/com/android/launcher3/tapl/AllAppsFromOverview.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2018 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.launcher3.tapl;
+
+import static com.android.launcher3.testing.TestProtocol.OVERVIEW_STATE_ORDINAL;
+
+import android.graphics.Point;
+
+import androidx.annotation.NonNull;
+import androidx.test.uiautomator.UiObject2;
+
+import com.android.launcher3.testing.TestProtocol;
+
+/**
+ * Operations on AllApps opened from Overview.
+ */
+public final class AllAppsFromOverview extends AllApps {
+
+ AllAppsFromOverview(LauncherInstrumentation launcher) {
+ super(launcher);
+ verifyActiveContainer();
+ }
+
+ /**
+ * Swipes down to switch back to Overview whence we came from.
+ *
+ * @return the overview panel.
+ */
+ @NonNull
+ public Overview switchBackToOverview() {
+ try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck();
+ LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
+ "want to switch back from all apps to overview")) {
+ final UiObject2 allAppsContainer = verifyActiveContainer();
+ // Swipe from the search box to the bottom.
+ final UiObject2 qsb = mLauncher.waitForObjectInContainer(
+ allAppsContainer, "search_container_all_apps");
+ final Point start = qsb.getVisibleCenter();
+ final int swipeHeight = mLauncher.getTestInfo(
+ TestProtocol.REQUEST_ALL_APPS_TO_OVERVIEW_SWIPE_HEIGHT).
+ getInt(TestProtocol.TEST_INFO_RESPONSE_FIELD);
+
+ final int endY = start.y + swipeHeight;
+ LauncherInstrumentation.log("AllAppsFromOverview.switchBackToOverview before swipe");
+ mLauncher.swipeToState(start.x, start.y, start.x, endY, 60, OVERVIEW_STATE_ORDINAL,
+ LauncherInstrumentation.GestureScope.INSIDE);
+
+ try (LauncherInstrumentation.Closable c1 = mLauncher.addContextLayer("swiped down")) {
+ return new Overview(mLauncher);
+ }
+ }
+ }
+}
diff --git a/tests/tapl/com/android/launcher3/tapl/AllAppsFromTaskbar.java b/tests/tapl/com/android/launcher3/tapl/AllAppsFromTaskbar.java
deleted file mode 100644
index 516402563d..0000000000
--- a/tests/tapl/com/android/launcher3/tapl/AllAppsFromTaskbar.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.launcher3.tapl;
-
-import androidx.annotation.NonNull;
-import androidx.test.uiautomator.UiObject2;
-
-/**
- * Operations on AllApps opened from the Taskbar.
- */
-public class AllAppsFromTaskbar extends AllApps {
-
- AllAppsFromTaskbar(LauncherInstrumentation launcher) {
- super(launcher);
- }
-
- @Override
- protected LauncherInstrumentation.ContainerType getContainerType() {
- return LauncherInstrumentation.ContainerType.TASKBAR_ALL_APPS;
- }
-
- @NonNull
- @Override
- public TaskbarAppIcon getAppIcon(String appName) {
- return (TaskbarAppIcon) super.getAppIcon(appName);
- }
-
- @NonNull
- @Override
- protected TaskbarAppIcon createAppIcon(UiObject2 icon) {
- return new TaskbarAppIcon(mLauncher, icon);
- }
-
- @Override
- protected boolean hasSearchBox() {
- return false;
- }
-}
diff --git a/tests/tapl/com/android/launcher3/tapl/AppIcon.java b/tests/tapl/com/android/launcher3/tapl/AppIcon.java
index e28f0af1bc..21099b4934 100644
--- a/tests/tapl/com/android/launcher3/tapl/AppIcon.java
+++ b/tests/tapl/com/android/launcher3/tapl/AppIcon.java
@@ -27,9 +27,11 @@ import com.android.launcher3.testing.TestProtocol;
import java.util.regex.Pattern;
/**
- * App icon, whether in all apps, workspace or the taskbar.
+ * App icon, whether in all apps or in workspace/
*/
-public abstract class AppIcon extends Launchable {
+public final class AppIcon extends Launchable {
+
+ private static final Pattern LONG_CLICK_EVENT = Pattern.compile("onAllAppsItemLongClick");
AppIcon(LauncherInstrumentation launcher, UiObject2 icon) {
super(launcher, icon);
@@ -39,19 +41,13 @@ public abstract class AppIcon extends Launchable {
return By.clazz(TextView.class).text(appName).pkg(launcher.getLauncherPackageName());
}
- static BySelector getAnyAppIconSelector() {
- return By.clazz(TextView.class);
- }
-
- protected abstract Pattern getLongClickEvent();
-
/**
* Long-clicks the icon to open its menu.
*/
public AppIconMenu openMenu() {
try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck()) {
- return createMenu(mLauncher.clickAndGet(
- mObject, /* resName= */ "popup_container", getLongClickEvent()));
+ return new AppIconMenu(mLauncher, mLauncher.clickAndGet(
+ mObject, "popup_container", LONG_CLICK_EVENT));
}
}
@@ -60,21 +56,19 @@ public abstract class AppIcon extends Launchable {
*/
public AppIconMenu openDeepShortcutMenu() {
try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck()) {
- return createMenu(mLauncher.clickAndGet(
- mObject, /* resName= */ "deep_shortcuts_container", getLongClickEvent()));
+ return new AppIconMenu(mLauncher, mLauncher.clickAndGet(
+ mObject, "deep_shortcuts_container", LONG_CLICK_EVENT));
}
}
- protected abstract AppIconMenu createMenu(UiObject2 menu);
-
@Override
protected void addExpectedEventsForLongClick() {
- mLauncher.expectEvent(TestProtocol.SEQUENCE_MAIN, getLongClickEvent());
+ mLauncher.expectEvent(TestProtocol.SEQUENCE_MAIN, LONG_CLICK_EVENT);
}
@Override
- protected void waitForLongPressConfirmation() {
- mLauncher.waitForLauncherObject("popup_container");
+ protected String getLongPressIndicator() {
+ return "popup_container";
}
@Override
diff --git a/tests/tapl/com/android/launcher3/tapl/AppIconMenu.java b/tests/tapl/com/android/launcher3/tapl/AppIconMenu.java
index 82d96309f1..7f28151b62 100644
--- a/tests/tapl/com/android/launcher3/tapl/AppIconMenu.java
+++ b/tests/tapl/com/android/launcher3/tapl/AppIconMenu.java
@@ -25,9 +25,9 @@ import java.util.List;
/**
* Context menu of an app icon.
*/
-public abstract class AppIconMenu {
- protected final LauncherInstrumentation mLauncher;
- protected final UiObject2 mDeepShortcutsContainer;
+public class AppIconMenu {
+ private final LauncherInstrumentation mLauncher;
+ private final UiObject2 mDeepShortcutsContainer;
AppIconMenu(LauncherInstrumentation launcher,
UiObject2 deepShortcutsContainer) {
@@ -42,17 +42,6 @@ public abstract class AppIconMenu {
final List<UiObject2> menuItems = mLauncher.getObjectsInContainer(mDeepShortcutsContainer,
"bubble_text");
assertTrue(menuItems.size() > itemNumber);
- return createMenuItem(menuItems.get(itemNumber));
+ return new AppIconMenuItem(mLauncher, menuItems.get(itemNumber));
}
-
- /**
- * Returns a menu item with the given text. Fails if it doesn't exist.
- */
- public AppIconMenuItem getMenuItem(String shortcutText) {
- final UiObject2 menuItem = mLauncher.waitForObjectInContainer(mDeepShortcutsContainer,
- AppIcon.getAppIconSelector(shortcutText, mLauncher));
- return createMenuItem(menuItem);
- }
-
- protected abstract AppIconMenuItem createMenuItem(UiObject2 menuItem);
}
diff --git a/tests/tapl/com/android/launcher3/tapl/AppIconMenuItem.java b/tests/tapl/com/android/launcher3/tapl/AppIconMenuItem.java
index 5cf5abab0b..ac0db0876c 100644
--- a/tests/tapl/com/android/launcher3/tapl/AppIconMenuItem.java
+++ b/tests/tapl/com/android/launcher3/tapl/AppIconMenuItem.java
@@ -23,7 +23,7 @@ import com.android.launcher3.testing.TestProtocol;
/**
* Menu item in an app icon menu.
*/
-public abstract class AppIconMenuItem extends Launchable {
+public class AppIconMenuItem extends Launchable {
AppIconMenuItem(LauncherInstrumentation launcher, UiObject2 shortcut) {
super(launcher, shortcut);
@@ -41,8 +41,8 @@ public abstract class AppIconMenuItem extends Launchable {
}
@Override
- protected void waitForLongPressConfirmation() {
- mLauncher.waitForLauncherObject("drop_target_bar");
+ protected String getLongPressIndicator() {
+ return "drop_target_bar";
}
@Override
diff --git a/tests/tapl/com/android/launcher3/tapl/Background.java b/tests/tapl/com/android/launcher3/tapl/Background.java
index 589e13cab5..4b1610efdd 100644
--- a/tests/tapl/com/android/launcher3/tapl/Background.java
+++ b/tests/tapl/com/android/launcher3/tapl/Background.java
@@ -30,14 +30,13 @@ import androidx.test.uiautomator.UiObject2;
import com.android.launcher3.testing.TestProtocol;
-import java.util.List;
import java.util.regex.Pattern;
/**
* Indicates the base state with a UI other than Overview running as foreground. It can also
* indicate Launcher as long as Launcher is not in Overview state.
*/
-public abstract class Background extends LauncherInstrumentation.VisibleContainer {
+public class Background extends LauncherInstrumentation.VisibleContainer {
private static final int ZERO_BUTTON_SWIPE_UP_GESTURE_DURATION = 500;
private static final Pattern SQUARE_BUTTON_EVENT = Pattern.compile("onOverviewToggle");
@@ -45,6 +44,11 @@ public abstract class Background extends LauncherInstrumentation.VisibleContaine
super(launcher);
}
+ @Override
+ protected LauncherInstrumentation.ContainerType getContainerType() {
+ return LauncherInstrumentation.ContainerType.BACKGROUND;
+ }
+
/**
* Swipes up or presses the square button to switch to Overview.
* Returns the base overview, which can be either in Launcher or the fallback recents.
@@ -58,89 +62,81 @@ public abstract class Background extends LauncherInstrumentation.VisibleContaine
"want to switch from background to overview")) {
verifyActiveContainer();
goToOverviewUnchecked();
- return mLauncher.isFallbackOverview()
- ? new BaseOverview(mLauncher) : new Overview(mLauncher);
+ return mLauncher.isFallbackOverview() ?
+ new BaseOverview(mLauncher) : new Overview(mLauncher);
}
}
-
protected boolean zeroButtonToOverviewGestureStartsInLauncher() {
- return mLauncher.isTablet();
- }
-
- protected boolean zeroButtonToOverviewGestureStateTransitionWhileHolding() {
return false;
}
protected void goToOverviewUnchecked() {
switch (mLauncher.getNavigationModel()) {
case ZERO_BUTTON: {
+ final int centerX = mLauncher.getDevice().getDisplayWidth() / 2;
+ final int startY = getSwipeStartY();
+ final int swipeHeight = mLauncher.getTestInfo(getSwipeHeightRequestName()).
+ getInt(TestProtocol.TEST_INFO_RESPONSE_FIELD);
+ final Point start = new Point(centerX, startY);
+ final Point end =
+ new Point(centerX, startY - swipeHeight - mLauncher.getTouchSlop());
+
final long downTime = SystemClock.uptimeMillis();
- sendDownPointerToEnterOverviewToLauncher(downTime);
- String swipeAndHoldToEnterOverviewActionName =
- "swiping and holding to enter overview";
- // If swiping from an app (e.g. Overview is in Background), we pause and hold on
- // swipe up to make overview appear, or else swiping without holding would take
- // us to the Home state. If swiping up from Home (e.g. Overview in Home or
- // Workspace state where the below condition is true), there is no need to pause,
- // and we will not test for an intermediate carousel as one will not exist.
- if (zeroButtonToOverviewGestureStateTransitionWhileHolding()) {
- mLauncher.runToState(
- () -> sendSwipeUpAndHoldToEnterOverviewGestureToLauncher(downTime),
- OVERVIEW_STATE_ORDINAL, swipeAndHoldToEnterOverviewActionName);
- sendUpPointerToEnterOverviewToLauncher(downTime);
- } else {
- // If swiping up from an app to overview, pause on intermediate carousel
- // until snapshots are visible. No intermediate carousel when swiping from
- // Home. The task swiped up is not a snapshot but the TaskViewSimulator. If
- // only a single task exists, no snapshots will be available during swipe up.
- mLauncher.executeAndWaitForLauncherEvent(
- () -> sendSwipeUpAndHoldToEnterOverviewGestureToLauncher(downTime),
- event -> TestProtocol.PAUSE_DETECTED_MESSAGE.equals(
- event.getClassName().toString()),
- () -> "Pause wasn't detected",
- swipeAndHoldToEnterOverviewActionName);
- try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
- "paused on swipe up to overview")) {
- if (mLauncher.getRecentTasks().size() > 1) {
- // When swiping up to grid-overview for tablets, the swiped tab will be
- // in the middle of the screen (TaskViewSimulator, not a snapshot), and
- // all remaining snapshots will be to the left of that task. In
- // non-tablet overview, snapshots can be on either side of the swiped
- // task, but we still check that they become visible after swiping and
- // pausing.
- mLauncher.waitForOverviewObject("snapshot");
- if (mLauncher.isTablet()) {
- List<UiObject2> tasks = mLauncher.getDevice().findObjects(
- mLauncher.getOverviewObjectSelector("snapshot"));
- final int centerX = mLauncher.getDevice().getDisplayWidth() / 2;
- mLauncher.assertTrue(
- "All tasks not to the left of the swiped task",
- tasks.stream()
- .allMatch(
- t -> t.getVisibleBounds().right < centerX));
- }
+ final LauncherInstrumentation.GestureScope gestureScope =
+ zeroButtonToOverviewGestureStartsInLauncher()
+ ? LauncherInstrumentation.GestureScope.INSIDE_TO_OUTSIDE
+ : LauncherInstrumentation.GestureScope.OUTSIDE_WITH_PILFER;
+
+ mLauncher.sendPointer(
+ downTime, downTime, MotionEvent.ACTION_DOWN, start, gestureScope);
+ mLauncher.executeAndWaitForLauncherEvent(
+ () -> mLauncher.movePointer(
+ downTime,
+ downTime,
+ ZERO_BUTTON_SWIPE_UP_GESTURE_DURATION,
+ start,
+ end,
+ gestureScope),
+ event -> TestProtocol.PAUSE_DETECTED_MESSAGE.equals(event.getClassName()),
+ () -> "Pause wasn't detected", "swiping and holding");
+ mLauncher.runToState(
+ () -> mLauncher.sendPointer(
+ downTime, SystemClock.uptimeMillis(), MotionEvent.ACTION_UP, end,
+ gestureScope),
+ OVERVIEW_STATE_ORDINAL, "sending UP event");
+ break;
+ }
- }
- String upPointerToEnterOverviewActionName =
- "sending UP pointer to enter overview";
- mLauncher.runToState(() -> sendUpPointerToEnterOverviewToLauncher(downTime),
- OVERVIEW_STATE_ORDINAL, upPointerToEnterOverviewActionName);
- }
+ case TWO_BUTTON: {
+ final int startX;
+ final int startY;
+ final int endX;
+ final int endY;
+ final int swipeLength = mLauncher.getTestInfo(getSwipeHeightRequestName()).
+ getInt(TestProtocol.TEST_INFO_RESPONSE_FIELD) + mLauncher.getTouchSlop();
+
+ if (mLauncher.getDevice().isNaturalOrientation()) {
+ startX = endX = mLauncher.getDevice().getDisplayWidth() / 2;
+ startY = getSwipeStartY();
+ endY = startY - swipeLength;
+ } else {
+ startX = getSwipeStartX();
+ // TODO(b/184059820) make horizontal swipe use swipe width not height, for the
+ // moment just double the swipe length.
+ endX = startX - swipeLength * 2;
+ startY = endY = mLauncher.getDevice().getDisplayHeight() / 2;
}
+
+ mLauncher.swipeToState(startX, startY, endX, endY, 10, OVERVIEW_STATE_ORDINAL,
+ LauncherInstrumentation.GestureScope.OUTSIDE_WITH_PILFER);
break;
}
case THREE_BUTTON:
- if (mLauncher.isTablet()) {
- mLauncher.expectEvent(TestProtocol.SEQUENCE_MAIN,
- LauncherInstrumentation.EVENT_TOUCH_DOWN);
- mLauncher.expectEvent(TestProtocol.SEQUENCE_MAIN,
- LauncherInstrumentation.EVENT_TOUCH_UP);
- }
mLauncher.expectEvent(TestProtocol.SEQUENCE_MAIN, SQUARE_BUTTON_EVENT);
mLauncher.runToState(
- () -> mLauncher.waitForNavigationUiObject("recent_apps").click(),
+ () -> mLauncher.waitForSystemUiObject("recent_apps").click(),
OVERVIEW_STATE_ORDINAL, "clicking Recents button");
break;
}
@@ -150,74 +146,18 @@ public abstract class Background extends LauncherInstrumentation.VisibleContaine
private void expectSwitchToOverviewEvents() {
}
- private void sendDownPointerToEnterOverviewToLauncher(long downTime) {
- final int centerX = mLauncher.getDevice().getDisplayWidth() / 2;
- final int startY = getSwipeStartY();
- final Point start = new Point(centerX, startY);
- final LauncherInstrumentation.GestureScope gestureScope =
- zeroButtonToOverviewGestureStartsInLauncher()
- ? LauncherInstrumentation.GestureScope.INSIDE_TO_OUTSIDE
- : LauncherInstrumentation.GestureScope.OUTSIDE_WITH_PILFER;
-
- mLauncher.sendPointer(downTime, downTime, MotionEvent.ACTION_DOWN, start, gestureScope);
-
- if (!mLauncher.isLauncher3()) {
- mLauncher.expectEvent(TestProtocol.SEQUENCE_PILFER,
- LauncherInstrumentation.EVENT_PILFER_POINTERS);
- }
- }
-
- private void sendSwipeUpAndHoldToEnterOverviewGestureToLauncher(long downTime) {
- final int centerX = mLauncher.getDevice().getDisplayWidth() / 2;
- final int startY = getSwipeStartY();
- final int swipeHeight = mLauncher.getTestInfo(getSwipeHeightRequestName()).getInt(
- TestProtocol.TEST_INFO_RESPONSE_FIELD);
- final Point start = new Point(centerX, startY);
- final Point end =
- new Point(centerX, startY - swipeHeight - mLauncher.getTouchSlop());
- final LauncherInstrumentation.GestureScope gestureScope =
- zeroButtonToOverviewGestureStartsInLauncher()
- ? LauncherInstrumentation.GestureScope.INSIDE_TO_OUTSIDE
- : LauncherInstrumentation.GestureScope.OUTSIDE_WITH_PILFER;
-
- mLauncher.movePointer(
- downTime,
- downTime,
- ZERO_BUTTON_SWIPE_UP_GESTURE_DURATION,
- start,
- end,
- gestureScope);
- }
-
- private void sendUpPointerToEnterOverviewToLauncher(long downTime) {
- final int centerX = mLauncher.getDevice().getDisplayWidth() / 2;
- final int startY = getSwipeStartY();
- final int swipeHeight = mLauncher.getTestInfo(getSwipeHeightRequestName()).getInt(
- TestProtocol.TEST_INFO_RESPONSE_FIELD);
- final Point end =
- new Point(centerX, startY - swipeHeight - mLauncher.getTouchSlop());
-
- final LauncherInstrumentation.GestureScope gestureScope =
- zeroButtonToOverviewGestureStartsInLauncher()
- ? LauncherInstrumentation.GestureScope.INSIDE_TO_OUTSIDE_WITHOUT_PILFER
- : LauncherInstrumentation.GestureScope.OUTSIDE_WITHOUT_PILFER;
-
- mLauncher.sendPointer(downTime, SystemClock.uptimeMillis(),
- MotionEvent.ACTION_UP, end, gestureScope);
- }
-
@NonNull
- public LaunchedAppState quickSwitchToPreviousApp() {
+ public Background quickSwitchToPreviousApp() {
boolean toRight = true;
quickSwitch(toRight);
- return new LaunchedAppState(mLauncher);
+ return new Background(mLauncher);
}
@NonNull
- public LaunchedAppState quickSwitchToPreviousAppSwipeLeft() {
+ public Background quickSwitchToPreviousAppSwipeLeft() {
boolean toRight = false;
quickSwitch(toRight);
- return new LaunchedAppState(mLauncher);
+ return new Background(mLauncher);
}
@NonNull
@@ -227,7 +167,11 @@ public abstract class Background extends LauncherInstrumentation.VisibleContaine
"want to quick switch to the previous app")) {
verifyActiveContainer();
final boolean launcherWasVisible = mLauncher.isLauncherVisible();
+ boolean transposeInLandscape = false;
switch (mLauncher.getNavigationModel()) {
+ case TWO_BUTTON:
+ transposeInLandscape = true;
+ // Fall through, zero button and two button modes behave the same.
case ZERO_BUTTON: {
final int startX;
final int startY;
@@ -235,17 +179,33 @@ public abstract class Background extends LauncherInstrumentation.VisibleContaine
final int endY;
final int cornerRadius = (int) Math.ceil(mLauncher.getWindowCornerRadius());
if (toRight) {
- // Swipe from the bottom left to the bottom right of the screen.
- startX = cornerRadius;
- startY = getSwipeStartY();
- endX = mLauncher.getDevice().getDisplayWidth() - cornerRadius;
- endY = startY;
+ if (mLauncher.getDevice().isNaturalOrientation() || !transposeInLandscape) {
+ // Swipe from the bottom left to the bottom right of the screen.
+ startX = cornerRadius;
+ startY = getSwipeStartY();
+ endX = mLauncher.getDevice().getDisplayWidth() - cornerRadius;
+ endY = startY;
+ } else {
+ // Swipe from the bottom right to the top right of the screen.
+ startX = getSwipeStartX();
+ startY = mLauncher.getRealDisplaySize().y - 1 - cornerRadius;
+ endX = startX;
+ endY = cornerRadius;
+ }
} else {
- // Swipe from the bottom right to the bottom left of the screen.
- startX = mLauncher.getDevice().getDisplayWidth() - cornerRadius;
- startY = getSwipeStartY();
- endX = cornerRadius;
- endY = startY;
+ if (mLauncher.getDevice().isNaturalOrientation() || !transposeInLandscape) {
+ // Swipe from the bottom right to the bottom left of the screen.
+ startX = mLauncher.getDevice().getDisplayWidth() - cornerRadius;
+ startY = getSwipeStartY();
+ endX = cornerRadius;
+ endY = startY;
+ } else {
+ // Swipe from the bottom left to the top left of the screen.
+ startX = getSwipeStartX();
+ startY = cornerRadius;
+ endX = startX;
+ endY = mLauncher.getRealDisplaySize().y - 1 - cornerRadius;
+ }
}
final boolean isZeroButton = mLauncher.getNavigationModel()
@@ -264,23 +224,11 @@ public abstract class Background extends LauncherInstrumentation.VisibleContaine
case THREE_BUTTON:
// Double press the recents button.
- UiObject2 recentsButton = mLauncher.waitForNavigationUiObject("recent_apps");
- if (mLauncher.isTablet()) {
- mLauncher.expectEvent(TestProtocol.SEQUENCE_MAIN,
- LauncherInstrumentation.EVENT_TOUCH_DOWN);
- mLauncher.expectEvent(TestProtocol.SEQUENCE_MAIN,
- LauncherInstrumentation.EVENT_TOUCH_UP);
- }
+ UiObject2 recentsButton = mLauncher.waitForSystemUiObject("recent_apps");
mLauncher.expectEvent(TestProtocol.SEQUENCE_MAIN, SQUARE_BUTTON_EVENT);
mLauncher.runToState(() -> recentsButton.click(), OVERVIEW_STATE_ORDINAL,
"clicking Recents button for the first time");
mLauncher.getOverview();
- if (mLauncher.isTablet()) {
- mLauncher.expectEvent(TestProtocol.SEQUENCE_MAIN,
- LauncherInstrumentation.EVENT_TOUCH_DOWN);
- mLauncher.expectEvent(TestProtocol.SEQUENCE_MAIN,
- LauncherInstrumentation.EVENT_TOUCH_UP);
- }
mLauncher.expectEvent(TestProtocol.SEQUENCE_MAIN, SQUARE_BUTTON_EVENT);
mLauncher.executeAndWaitForEvent(
() -> recentsButton.click(),
diff --git a/tests/tapl/com/android/launcher3/tapl/BaseOverview.java b/tests/tapl/com/android/launcher3/tapl/BaseOverview.java
index b7bca02e44..588b6b8f07 100644
--- a/tests/tapl/com/android/launcher3/tapl/BaseOverview.java
+++ b/tests/tapl/com/android/launcher3/tapl/BaseOverview.java
@@ -25,7 +25,6 @@ import androidx.test.uiautomator.UiObject2;
import java.util.Collections;
import java.util.List;
-import java.util.stream.Collectors;
/**
* Common overview panel for both Launcher and fallback recents
@@ -36,7 +35,6 @@ public class BaseOverview extends LauncherInstrumentation.VisibleContainer {
BaseOverview(LauncherInstrumentation launcher) {
super(launcher);
verifyActiveContainer();
- verifyActionsViewVisibility();
}
@Override
@@ -58,15 +56,10 @@ public class BaseOverview extends LauncherInstrumentation.VisibleContainer {
mLauncher.addContextLayer("want to fling forward in overview")) {
LauncherInstrumentation.log("Overview.flingForward before fling");
final UiObject2 overview = verifyActiveContainer();
- final int leftMargin =
- mLauncher.getTargetInsets().left + mLauncher.getEdgeSensitivityWidth();
- mLauncher.scroll(overview, Direction.LEFT, new Rect(leftMargin + 1, 0, 0, 0), 20,
- false);
- try (LauncherInstrumentation.Closable c2 =
- mLauncher.addContextLayer("flung forwards")) {
- verifyActiveContainer();
- verifyActionsViewVisibility();
- }
+ final int leftMargin = mLauncher.getTargetInsets().left;
+ mLauncher.scroll(
+ overview, Direction.LEFT, new Rect(leftMargin + 1, 0, 0, 0), 20, false);
+ verifyActiveContainer();
}
}
@@ -87,8 +80,6 @@ public class BaseOverview extends LauncherInstrumentation.VisibleContainer {
mLauncher.clickLauncherObject(
mLauncher.waitForObjectInContainer(verifyActiveContainer(), clearAllSelector));
-
- mLauncher.waitUntilLauncherObjectGone(clearAllSelector);
}
}
@@ -101,50 +92,10 @@ public class BaseOverview extends LauncherInstrumentation.VisibleContainer {
mLauncher.addContextLayer("want to fling backward in overview")) {
LauncherInstrumentation.log("Overview.flingBackward before fling");
final UiObject2 overview = verifyActiveContainer();
- final int rightMargin =
- mLauncher.getTargetInsets().right + mLauncher.getEdgeSensitivityWidth();
+ final int rightMargin = mLauncher.getTargetInsets().right;
mLauncher.scroll(
overview, Direction.RIGHT, new Rect(0, 0, rightMargin + 1, 0), 20, false);
- try (LauncherInstrumentation.Closable c2 =
- mLauncher.addContextLayer("flung backwards")) {
- verifyActiveContainer();
- verifyActionsViewVisibility();
- }
- }
- }
-
- /**
- * Scrolls the current task via flinging forward until it is off screen.
- *
- * If only one task is present, it is only partially scrolled off screen and will still be
- * the current task.
- */
- public void scrollCurrentTaskOffScreen() {
- try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck();
- LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
- "want to scroll current task off screen in overview")) {
verifyActiveContainer();
-
- OverviewTask task = getCurrentTask();
- mLauncher.assertNotNull("current task is null", task);
- mLauncher.scrollLeftByDistance(verifyActiveContainer(),
- task.getVisibleWidth() + mLauncher.getOverviewPageSpacing());
-
- try (LauncherInstrumentation.Closable c2 =
- mLauncher.addContextLayer("scrolled task off screen")) {
- verifyActiveContainer();
- verifyActionsViewVisibility();
-
- if (getTaskCount() > 1) {
- if (mLauncher.isTablet()) {
- mLauncher.assertTrue("current task is not grid height",
- getCurrentTask().getVisibleHeight() == mLauncher
- .getGridTaskRectForTablet().height());
- }
- mLauncher.assertTrue("Current task not scrolled off screen",
- !getCurrentTask().equals(task));
- }
- }
}
}
@@ -168,20 +119,6 @@ public class BaseOverview extends LauncherInstrumentation.VisibleContainer {
return new OverviewTask(mLauncher, widestTask, this);
}
- /**
- * Returns a list of all tasks fully visible in the tablet grid overview.
- */
- @NonNull
- public List<OverviewTask> getCurrentTasksForTablet() {
- final List<UiObject2> taskViews = getTasks();
- mLauncher.assertNotEquals("Unable to find a task", 0, taskViews.size());
-
- final int gridTaskWidth = mLauncher.getGridTaskRectForTablet().width();
-
- return taskViews.stream().filter(t -> t.getVisibleBounds().width() == gridTaskWidth).map(
- t -> new OverviewTask(mLauncher, t, this)).collect(Collectors.toList());
- }
-
@NonNull
private List<UiObject2> getTasks() {
try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
@@ -192,10 +129,6 @@ public class BaseOverview extends LauncherInstrumentation.VisibleContainer {
}
}
- int getTaskCount() {
- return getTasks().size();
- }
-
/**
* Returns whether Overview has tasks.
*/
@@ -213,64 +146,8 @@ public class BaseOverview extends LauncherInstrumentation.VisibleContainer {
try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
"want to get overview actions")) {
verifyActiveContainer();
- UiObject2 overviewActions = mLauncher.waitForOverviewObject("action_buttons");
+ UiObject2 overviewActions = mLauncher.waitForLauncherObject("action_buttons");
return new OverviewActions(overviewActions, mLauncher);
}
}
-
- /**
- * Returns if clear all button is visible.
- */
- public boolean isClearAllVisible() {
- return mLauncher.hasLauncherObject(mLauncher.getOverviewObjectSelector("clear_all"));
- }
-
- private void verifyActionsViewVisibility() {
- if (!hasTasks()) {
- return;
- }
- try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
- "want to assert overview actions view visibility")) {
- if (mLauncher.isTablet() && !isOverviewSnappedToFocusedTaskForTablet()) {
- mLauncher.waitUntilOverviewObjectGone("action_buttons");
- } else {
- mLauncher.waitForOverviewObject("action_buttons");
- }
- }
- }
-
- /**
- * Returns if focused task is currently snapped task in tablet grid overview.
- */
- private boolean isOverviewSnappedToFocusedTaskForTablet() {
- UiObject2 focusedTask = getFocusedTaskForTablet();
- if (focusedTask == null) {
- return false;
- }
- return Math.abs(
- focusedTask.getVisibleBounds().exactCenterX() - mLauncher.getExactScreenCenterX())
- < 1;
- }
-
- /**
- * Returns Overview focused task if it exists.
- *
- * @throws IllegalStateException if not run on a tablet device.
- */
- UiObject2 getFocusedTaskForTablet() {
- if (!mLauncher.isTablet()) {
- throw new IllegalStateException("Must be run on tablet device.");
- }
- final List<UiObject2> taskViews = getTasks();
- if (taskViews.size() == 0) {
- return null;
- }
- int focusedTaskHeight = mLauncher.getFocusedTaskHeightForTablet();
- for (UiObject2 task : taskViews) {
- if (task.getVisibleBounds().height() == focusedTaskHeight) {
- return task;
- }
- }
- return null;
- }
} \ No newline at end of file
diff --git a/tests/tapl/com/android/launcher3/tapl/Folder.java b/tests/tapl/com/android/launcher3/tapl/Folder.java
deleted file mode 100644
index 26f0a8b26d..0000000000
--- a/tests/tapl/com/android/launcher3/tapl/Folder.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 2021 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.launcher3.tapl;
-
-import android.graphics.Point;
-import android.graphics.Rect;
-import android.os.SystemClock;
-import android.view.MotionEvent;
-
-import androidx.annotation.NonNull;
-import androidx.test.uiautomator.UiObject2;
-
-public class Folder {
-
- protected static final String FOLDER_CONTENT_RES_ID = "folder_content";
-
- private final UiObject2 mContainer;
- private final LauncherInstrumentation mLauncher;
-
- Folder(LauncherInstrumentation launcher) {
- this.mLauncher = launcher;
- this.mContainer = launcher.waitForLauncherObject(FOLDER_CONTENT_RES_ID);
- }
-
- /**
- * Find an app icon with given name or raise assertion error.
- */
- @NonNull
- public HomeAppIcon getAppIcon(String appName) {
- try (LauncherInstrumentation.Closable ignored = mLauncher.addContextLayer(
- "Want to get app icon in folder")) {
- return new WorkspaceAppIcon(mLauncher,
- mLauncher.waitForObjectInContainer(
- mContainer,
- AppIcon.getAppIconSelector(appName, mLauncher)));
- }
- }
-
- private void touchOutsideFolder() {
- Rect containerBounds = mLauncher.getVisibleBounds(this.mContainer);
- final long downTime = SystemClock.uptimeMillis();
- Point containerLeftTopCorner = new Point(containerBounds.left - 1, containerBounds.top - 1);
- mLauncher.sendPointer(downTime, downTime, MotionEvent.ACTION_DOWN,
- containerLeftTopCorner, LauncherInstrumentation.GestureScope.INSIDE);
- mLauncher.sendPointer(downTime, downTime, MotionEvent.ACTION_UP,
- containerLeftTopCorner, LauncherInstrumentation.GestureScope.INSIDE);
- }
-
- /**
- * CLose opened folder if possible. It throws assertion error if the folder is already closed.
- */
- public Workspace close() {
- try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck();
- LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
- "Want to close opened folder")) {
- mLauncher.waitForLauncherObject(FOLDER_CONTENT_RES_ID);
- touchOutsideFolder();
- mLauncher.waitUntilLauncherObjectGone(FOLDER_CONTENT_RES_ID);
- return mLauncher.getWorkspace();
- }
- }
-}
diff --git a/tests/tapl/com/android/launcher3/tapl/FolderDragTarget.java b/tests/tapl/com/android/launcher3/tapl/FolderDragTarget.java
deleted file mode 100644
index 2c60668ba8..0000000000
--- a/tests/tapl/com/android/launcher3/tapl/FolderDragTarget.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2021 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.launcher3.tapl;
-
-import android.graphics.Rect;
-
-public interface FolderDragTarget {
-
- /** This method requires public access, however should not be called in tests. */
- Rect getDropLocationBounds();
-
- /** This method requires public access, however should not be called in tests. */
- FolderIcon getTargetFolder(Rect bounds);
-}
diff --git a/tests/tapl/com/android/launcher3/tapl/FolderIcon.java b/tests/tapl/com/android/launcher3/tapl/FolderIcon.java
deleted file mode 100644
index 9b4717fe12..0000000000
--- a/tests/tapl/com/android/launcher3/tapl/FolderIcon.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (C) 2021 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.launcher3.tapl;
-
-import android.graphics.Rect;
-
-import androidx.annotation.NonNull;
-import androidx.test.uiautomator.UiObject2;
-
-import com.android.launcher3.testing.TestProtocol;
-
-/**
- * Folder Icon, an app folder in workspace.
- */
-public class FolderIcon implements FolderDragTarget {
-
- protected final UiObject2 mObject;
- protected final LauncherInstrumentation mLauncher;
-
- FolderIcon(LauncherInstrumentation launcher, UiObject2 icon) {
- mObject = icon;
- mLauncher = launcher;
- }
-
- /**
- * Open and return a folder or raise assertion error.
- */
- @NonNull
- public Folder open() {
- try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck();
- LauncherInstrumentation.Closable c = mLauncher.addContextLayer("open folder")) {
- mLauncher.executeAndWaitForLauncherEvent(() -> mLauncher.clickLauncherObject(mObject),
- event -> TestProtocol.FOLDER_OPENED_MESSAGE.equals(
- event.getClassName().toString()),
- () -> "Fail to open folder.",
- "open folder");
- }
- return new Folder(mLauncher);
- }
-
- /** This method requires public access, however should not be called in tests. */
- @Override
- public Rect getDropLocationBounds() {
- return mLauncher.getVisibleBounds(mObject.getParent());
- }
-
- /** This method requires public access, however should not be called in tests. */
- @Override
- public FolderIcon getTargetFolder(Rect bounds) {
- return this;
- }
-}
diff --git a/tests/tapl/com/android/launcher3/tapl/Home.java b/tests/tapl/com/android/launcher3/tapl/Home.java
index ee9dd1aca0..0060844ced 100644
--- a/tests/tapl/com/android/launcher3/tapl/Home.java
+++ b/tests/tapl/com/android/launcher3/tapl/Home.java
@@ -63,8 +63,4 @@ public abstract class Home extends Background {
return true;
}
- @Override
- protected boolean zeroButtonToOverviewGestureStateTransitionWhileHolding() {
- return true;
- }
} \ No newline at end of file
diff --git a/tests/tapl/com/android/launcher3/tapl/HomeAllApps.java b/tests/tapl/com/android/launcher3/tapl/HomeAllApps.java
deleted file mode 100644
index c275f3b320..0000000000
--- a/tests/tapl/com/android/launcher3/tapl/HomeAllApps.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.launcher3.tapl;
-
-import androidx.annotation.NonNull;
-import androidx.test.uiautomator.UiObject2;
-
-public class HomeAllApps extends AllApps {
-
- HomeAllApps(LauncherInstrumentation launcher) {
- super(launcher);
- }
-
- @Override
- protected LauncherInstrumentation.ContainerType getContainerType() {
- return LauncherInstrumentation.ContainerType.HOME_ALL_APPS;
- }
-
- @NonNull
- @Override
- public HomeAppIcon getAppIcon(String appName) {
- return (AllAppsAppIcon) super.getAppIcon(appName);
- }
-
- @NonNull
- @Override
- protected HomeAppIcon createAppIcon(UiObject2 icon) {
- return new AllAppsAppIcon(mLauncher, icon);
- }
-
- @Override
- protected boolean hasSearchBox() {
- return true;
- }
-}
diff --git a/tests/tapl/com/android/launcher3/tapl/HomeAppIcon.java b/tests/tapl/com/android/launcher3/tapl/HomeAppIcon.java
deleted file mode 100644
index 71d8ba9a41..0000000000
--- a/tests/tapl/com/android/launcher3/tapl/HomeAppIcon.java
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.launcher3.tapl;
-
-import android.graphics.Point;
-import android.graphics.Rect;
-
-import androidx.annotation.NonNull;
-import androidx.test.uiautomator.UiObject2;
-
-import java.util.function.Supplier;
-
-/**
- * App icon on the workspace or all apps.
- */
-public abstract class HomeAppIcon extends AppIcon implements FolderDragTarget, WorkspaceDragSource {
-
- private final String mAppName;
-
- HomeAppIcon(LauncherInstrumentation launcher, UiObject2 icon) {
- super(launcher, icon);
- mAppName = icon.getText();
- }
-
- /**
- * Drag the AppIcon to the given position of other icon. The drag must result in a folder.
- *
- * @param target the destination icon.
- */
- @NonNull
- public FolderIcon dragToIcon(FolderDragTarget target) {
- try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck();
- LauncherInstrumentation.Closable c = mLauncher.addContextLayer("want to drag icon")) {
- final Rect dropBounds = target.getDropLocationBounds();
- Workspace.dragIconToWorkspace(
- mLauncher, this,
- () -> {
- final Rect bounds = target.getDropLocationBounds();
- return new Point(bounds.centerX(), bounds.centerY());
- });
- FolderIcon result = target.getTargetFolder(dropBounds);
- mLauncher.assertTrue("Can't find the target folder.", result != null);
- return result;
- }
- }
-
- /** This method requires public access, however should not be called in tests. */
- @Override
- public Rect getDropLocationBounds() {
- return mLauncher.getVisibleBounds(mObject);
- }
-
- /** This method requires public access, however should not be called in tests. */
- @Override
- public FolderIcon getTargetFolder(Rect bounds) {
- for (FolderIcon folderIcon : mLauncher.getWorkspace().getFolderIcons()) {
- final Rect folderIconBounds = folderIcon.getDropLocationBounds();
- if (bounds.contains(folderIconBounds.centerX(), folderIconBounds.centerY())) {
- return folderIcon;
- }
- }
- return null;
- }
-
- @Override
- public HomeAppIconMenu openDeepShortcutMenu() {
- return (HomeAppIconMenu) super.openDeepShortcutMenu();
- }
-
- @Override
- protected HomeAppIconMenu createMenu(UiObject2 menu) {
- return new HomeAppIconMenu(mLauncher, menu);
- }
-
- /**
- * Uninstall the appIcon by dragging it to the 'uninstall' drop point of the drop_target_bar.
- *
- * @return validated workspace after the existing appIcon being uninstalled.
- */
- public Workspace uninstall() {
- try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck();
- LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
- "uninstalling app icon")) {
- return Workspace.uninstallAppIcon(
- mLauncher, this,
- this::addExpectedEventsForLongClick
- );
- }
- }
-
- /**
- * Drag an object to the given cell in workspace. The target cell must be empty.
- *
- * @param cellX zero based column number, starting from the left of the screen.
- * @param cellY zero based row number, starting from the top of the screen.
- */
- public HomeAppIcon dragToWorkspace(int cellX, int cellY) {
- try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck();
- LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
- String.format("want to drag the icon to cell(%d, %d)", cellX, cellY))
- ) {
- final Supplier<Point> dest = () -> Workspace.getCellCenter(mLauncher, cellX, cellY);
- Workspace.dragIconToWorkspace(
- mLauncher,
- /* launchable= */ this,
- dest,
- () -> addExpectedEventsForLongClick(),
- /*expectDropEvents= */ null);
- try (LauncherInstrumentation.Closable ignore = mLauncher.addContextLayer("dragged")) {
- WorkspaceAppIcon appIcon =
- (WorkspaceAppIcon) mLauncher.getWorkspace().getWorkspaceAppIcon(mAppName);
- mLauncher.assertTrue(
- String.format(
- "The %s icon should be in the cell (%d, %d).", mAppName, cellX,
- cellY),
- appIcon.isInCell(cellX, cellY));
- return appIcon;
- }
- }
- }
-
-
- /** This method requires public access, however should not be called in tests. */
- @Override
- public Launchable getLaunchable() {
- return this;
- }
-}
diff --git a/tests/tapl/com/android/launcher3/tapl/HomeAppIconMenu.java b/tests/tapl/com/android/launcher3/tapl/HomeAppIconMenu.java
deleted file mode 100644
index 71fb6c0841..0000000000
--- a/tests/tapl/com/android/launcher3/tapl/HomeAppIconMenu.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.launcher3.tapl;
-
-import androidx.test.uiautomator.UiObject2;
-
-/**
- * Context menu of a home screen app icon.
- */
-public final class HomeAppIconMenu extends AppIconMenu {
-
- HomeAppIconMenu(LauncherInstrumentation launcher,
- UiObject2 deepShortcutsContainer) {
- super(launcher, deepShortcutsContainer);
- }
-
- @Override
- public HomeAppIconMenuItem getMenuItem(int itemNumber) {
- return (HomeAppIconMenuItem) super.getMenuItem(itemNumber);
- }
-
- @Override
- protected HomeAppIconMenuItem createMenuItem(UiObject2 menuItem) {
- return new HomeAppIconMenuItem(mLauncher, menuItem);
- }
-}
diff --git a/tests/tapl/com/android/launcher3/tapl/HomeAppIconMenuItem.java b/tests/tapl/com/android/launcher3/tapl/HomeAppIconMenuItem.java
deleted file mode 100644
index 1ff0c10506..0000000000
--- a/tests/tapl/com/android/launcher3/tapl/HomeAppIconMenuItem.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.launcher3.tapl;
-
-import androidx.test.uiautomator.UiObject2;
-
-/**
- * Menu item in a home screen app icon menu.
- */
-public final class HomeAppIconMenuItem extends AppIconMenuItem implements WorkspaceDragSource {
-
- HomeAppIconMenuItem(LauncherInstrumentation launcher,
- UiObject2 shortcut) {
- super(launcher, shortcut);
- }
-
- /** This method requires public access, however should not be called in tests. */
- @Override
- public Launchable getLaunchable() {
- return this;
- }
-}
diff --git a/tests/tapl/com/android/launcher3/tapl/HomeQsb.java b/tests/tapl/com/android/launcher3/tapl/HomeQsb.java
deleted file mode 100644
index 5f921996cd..0000000000
--- a/tests/tapl/com/android/launcher3/tapl/HomeQsb.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.launcher3.tapl;
-
-/**
- * Operations on home screen qsb.
- */
-public class HomeQsb {
-
- private final LauncherInstrumentation mLauncher;
-
- HomeQsb(LauncherInstrumentation launcher) {
- mLauncher = launcher;
- mLauncher.waitForLauncherObject("search_container_hotseat");
- }
-
- /**
- * Show search result page from tapping qsb.
- */
- public SearchResultFromQsb showSearchResult() {
- try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
- "want to open search result page");
- LauncherInstrumentation.Closable e = mLauncher.eventsCheck()) {
- mLauncher.clickLauncherObject(
- mLauncher.waitForLauncherObject("search_container_hotseat"));
- try (LauncherInstrumentation.Closable c2 = mLauncher.addContextLayer(
- "clicked qsb to open search result page")) {
- return new SearchResultFromQsb(mLauncher);
- }
- }
- }
-}
diff --git a/tests/tapl/com/android/launcher3/tapl/Launchable.java b/tests/tapl/com/android/launcher3/tapl/Launchable.java
index 33fea2d10d..a15131dbfc 100644
--- a/tests/tapl/com/android/launcher3/tapl/Launchable.java
+++ b/tests/tapl/com/android/launcher3/tapl/Launchable.java
@@ -16,25 +16,19 @@
package com.android.launcher3.tapl;
-import static com.android.launcher3.testing.TestProtocol.SPRING_LOADED_STATE_ORDINAL;
+import static android.view.accessibility.AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED;
import android.graphics.Point;
-import android.view.MotionEvent;
import androidx.test.uiautomator.By;
import androidx.test.uiautomator.BySelector;
import androidx.test.uiautomator.UiObject2;
import androidx.test.uiautomator.Until;
-import com.android.launcher3.testing.TestProtocol;
-
/**
* Ancestor for AppIcon and AppMenuItem.
*/
-public abstract class Launchable {
-
- protected static final int DEFAULT_DRAG_STEPS = 10;
-
+abstract class Launchable {
protected final LauncherInstrumentation mLauncher;
protected final UiObject2 mObject;
@@ -51,7 +45,7 @@ public abstract class Launchable {
/**
* Clicks the object to launch its app.
*/
- public LaunchedAppState launch(String expectedPackageName) {
+ public Background launch(String expectedPackageName) {
try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck()) {
return launch(By.pkg(expectedPackageName));
}
@@ -61,96 +55,54 @@ public abstract class Launchable {
protected abstract String launchableType();
- private LaunchedAppState launch(BySelector selector) {
- try (LauncherInstrumentation.Closable c1 = mLauncher.addContextLayer(
- "want to launch an app from " + launchableType())) {
- LauncherInstrumentation.log("Launchable.launch before click "
- + mObject.getVisibleCenter() + " in " + mLauncher.getVisibleBounds(mObject));
+ private Background launch(BySelector selector) {
+ LauncherInstrumentation.log("Launchable.launch before click "
+ + mObject.getVisibleCenter() + " in " + mLauncher.getVisibleBounds(mObject));
+ final String label = mObject.getText();
- mLauncher.clickLauncherObject(mObject);
-
- try (LauncherInstrumentation.Closable c2 = mLauncher.addContextLayer("clicked")) {
- expectActivityStartEvents();
- return assertAppLaunched(selector);
- }
- }
- }
+ mLauncher.executeAndWaitForEvent(
+ () -> {
+ mLauncher.clickLauncherObject(mObject);
+ expectActivityStartEvents();
+ },
+ event -> event.getEventType() == TYPE_WINDOW_STATE_CHANGED,
+ () -> "Launching an app didn't open a new window: " + label,
+ "clicking " + launchableType());
- protected LaunchedAppState assertAppLaunched(BySelector selector) {
mLauncher.assertTrue(
- "App didn't start: (" + selector + ")",
- mLauncher.getDevice().wait(Until.hasObject(selector),
+ "App didn't start: " + label + " (" + selector + ")",
+ TestHelpers.wait(Until.hasObject(selector),
LauncherInstrumentation.WAIT_TIME_MS));
- return new LaunchedAppState(mLauncher);
- }
-
- Point startDrag(long downTime, Runnable expectLongClickEvents, boolean runToSpringLoadedState) {
- final Point iconCenter = getObject().getVisibleCenter();
- final Point dragStartCenter = new Point(iconCenter.x,
- iconCenter.y - getStartDragThreshold());
-
- if (runToSpringLoadedState) {
- mLauncher.runToState(() -> movePointerForStartDrag(
- downTime,
- iconCenter,
- dragStartCenter,
- expectLongClickEvents),
- SPRING_LOADED_STATE_ORDINAL, "long-pressing and triggering drag start");
- } else {
- movePointerForStartDrag(
- downTime,
- iconCenter,
- dragStartCenter,
- expectLongClickEvents);
- }
-
- return dragStartCenter;
+ return new Background(mLauncher);
}
/**
- * Waits for a confirmation that a long press has successfully been triggered.
+ * Drags an object to the center of homescreen.
*
- * This method waits for a view to either appear or disappear to confirm that the long press
- * has been triggered and fails if no confirmation is received before the default timeout.
+ * @param startsActivity whether it's expected to start an activity.
+ * @param isWidgetShortcut whether we drag a widget shortcut
*/
- protected abstract void waitForLongPressConfirmation();
-
- /**
- * Drags this Launchable a short distance before starting a full drag.
- *
- * This is necessary for shortcuts, which require being dragged beyond a threshold to close
- * their container and start drag callbacks.
- */
- private void movePointerForStartDrag(
- long downTime,
- Point iconCenter,
- Point dragStartCenter,
- Runnable expectLongClickEvents) {
- mLauncher.sendPointer(
- downTime,
- downTime,
- MotionEvent.ACTION_DOWN,
- iconCenter,
- LauncherInstrumentation.GestureScope.INSIDE);
- LauncherInstrumentation.log("movePointerForStartDrag: sent down");
- expectLongClickEvents.run();
- waitForLongPressConfirmation();
- LauncherInstrumentation.log("movePointerForStartDrag: indicator");
- mLauncher.movePointer(
- iconCenter,
- dragStartCenter,
- DEFAULT_DRAG_STEPS,
- /* isDecelerating= */ false,
- downTime,
- downTime,
- /* slowDown= */ true,
- LauncherInstrumentation.GestureScope.INSIDE);
- }
-
- private int getStartDragThreshold() {
- return mLauncher.getTestInfo(TestProtocol.REQUEST_START_DRAG_THRESHOLD).getInt(
- TestProtocol.TEST_INFO_RESPONSE_FIELD);
+ public void dragToWorkspace(boolean startsActivity, boolean isWidgetShortcut) {
+ try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck()) {
+ final Point launchableCenter = getObject().getVisibleCenter();
+ final Point displaySize = mLauncher.getRealDisplaySize();
+ final int width = displaySize.x / 2;
+ Workspace.dragIconToWorkspace(
+ mLauncher,
+ this,
+ new Point(
+ launchableCenter.x >= width
+ ? launchableCenter.x - width / 2
+ : launchableCenter.x + width / 2,
+ displaySize.y / 2),
+ getLongPressIndicator(),
+ startsActivity,
+ isWidgetShortcut,
+ () -> addExpectedEventsForLongClick());
+ }
}
protected abstract void addExpectedEventsForLongClick();
+
+ protected abstract String getLongPressIndicator();
}
diff --git a/tests/tapl/com/android/launcher3/tapl/LaunchedAppState.java b/tests/tapl/com/android/launcher3/tapl/LaunchedAppState.java
deleted file mode 100644
index 046d36b0ba..0000000000
--- a/tests/tapl/com/android/launcher3/tapl/LaunchedAppState.java
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.launcher3.tapl;
-
-import static com.android.launcher3.testing.TestProtocol.REQUEST_DISABLE_MANUAL_TASKBAR_STASHING;
-import static com.android.launcher3.testing.TestProtocol.REQUEST_ENABLE_MANUAL_TASKBAR_STASHING;
-import static com.android.launcher3.testing.TestProtocol.REQUEST_STASHED_TASKBAR_HEIGHT;
-
-import android.graphics.Point;
-import android.graphics.Rect;
-import android.os.SystemClock;
-import android.view.MotionEvent;
-
-import androidx.test.uiautomator.By;
-
-import com.android.launcher3.testing.TestProtocol;
-
-/**
- * Background state operations specific to when an app has been launched.
- */
-public final class LaunchedAppState extends Background {
-
- // More drag steps than Launchables to give the window manager time to register the drag.
- private static final int DEFAULT_DRAG_STEPS = 35;
-
- LaunchedAppState(LauncherInstrumentation launcher) {
- super(launcher);
- }
-
- @Override
- protected LauncherInstrumentation.ContainerType getContainerType() {
- return LauncherInstrumentation.ContainerType.LAUNCHED_APP;
- }
-
- /**
- * Returns the taskbar.
- *
- * The taskbar must already be visible when calling this method.
- */
- public Taskbar getTaskbar() {
- try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
- "want to get the taskbar")) {
- mLauncher.waitForLauncherObject("taskbar_view");
-
- return new Taskbar(mLauncher);
- }
- }
-
- /**
- * Returns the Taskbar in a visible state.
- *
- * The taskbar must already be hidden when calling this method.
- */
- public Taskbar showTaskbar() {
- mLauncher.getTestInfo(REQUEST_ENABLE_MANUAL_TASKBAR_STASHING);
-
- try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck();
- LauncherInstrumentation.Closable c1 = mLauncher.addContextLayer(
- "want to show the taskbar")) {
- mLauncher.waitUntilLauncherObjectGone("taskbar_view");
-
- final long downTime = SystemClock.uptimeMillis();
- final int unstashTargetY = mLauncher.getRealDisplaySize().y
- - (mLauncher.getTestInfo(REQUEST_STASHED_TASKBAR_HEIGHT)
- .getInt(TestProtocol.TEST_INFO_RESPONSE_FIELD) / 2);
- final Point unstashTarget = new Point(
- mLauncher.getRealDisplaySize().x / 2, unstashTargetY);
-
- mLauncher.sendPointer(downTime, downTime, MotionEvent.ACTION_DOWN, unstashTarget,
- LauncherInstrumentation.GestureScope.OUTSIDE_WITH_PILFER);
- LauncherInstrumentation.log("showTaskbar: sent down");
-
- try (LauncherInstrumentation.Closable c2 = mLauncher.addContextLayer("pressed down")) {
- mLauncher.waitForLauncherObject("taskbar_view");
- mLauncher.sendPointer(downTime, downTime, MotionEvent.ACTION_UP, unstashTarget,
- LauncherInstrumentation.GestureScope.OUTSIDE_WITH_PILFER);
-
- return new Taskbar(mLauncher);
- }
- } finally {
- mLauncher.getTestInfo(REQUEST_DISABLE_MANUAL_TASKBAR_STASHING);
- }
- }
-
- static void dragToSplitscreen(
- LauncherInstrumentation launcher,
- Launchable launchable,
- String expectedNewPackageName,
- String expectedExistingPackageName) {
- try (LauncherInstrumentation.Closable c1 = launcher.addContextLayer(
- "want to drag taskbar item to splitscreen")) {
- final Point displaySize = launcher.getRealDisplaySize();
- // Drag to the center of the top-left quadrant of the screen, this point will work in
- // both portrait and landscape.
- final Point endPoint = new Point(displaySize.x / 4, displaySize.y / 4);
- final long downTime = SystemClock.uptimeMillis();
- // Use mObject before starting drag since the system drag and drop moves the original
- // view.
- Point itemVisibleCenter = launchable.mObject.getVisibleCenter();
- Rect itemVisibleBounds = launcher.getVisibleBounds(launchable.mObject);
- String itemLabel = launchable.mObject.getText();
-
- Point dragStart = launchable.startDrag(
- downTime,
- launchable::addExpectedEventsForLongClick,
- /* runToSpringLoadedState= */ false);
-
- try (LauncherInstrumentation.Closable c2 = launcher.addContextLayer(
- "started item drag")) {
- launcher.movePointer(
- dragStart,
- endPoint,
- DEFAULT_DRAG_STEPS,
- /* isDecelerating= */ true,
- downTime,
- SystemClock.uptimeMillis(),
- /* slowDown= */ false,
- LauncherInstrumentation.GestureScope.INSIDE);
-
- try (LauncherInstrumentation.Closable c3 = launcher.addContextLayer(
- "moved pointer to drop point")) {
- LauncherInstrumentation.log("SplitscreenDragSource.dragToSplitscreen: "
- + "before drop " + itemVisibleCenter + " in " + itemVisibleBounds);
- launcher.sendPointer(
- downTime,
- SystemClock.uptimeMillis(),
- MotionEvent.ACTION_UP,
- endPoint,
- LauncherInstrumentation.GestureScope.INSIDE_TO_OUTSIDE_WITHOUT_PILFER);
- LauncherInstrumentation.log("SplitscreenDragSource.dragToSplitscreen: "
- + "after drop");
-
- try (LauncherInstrumentation.Closable c4 = launcher.addContextLayer(
- "dropped item")) {
- launchable.assertAppLaunched(By.pkg(expectedNewPackageName));
- launchable.assertAppLaunched(By.pkg(expectedExistingPackageName));
- }
- }
- }
- }
- }
-}
diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
index 9d25b1ba90..19094f82c6 100644
--- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
+++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
@@ -21,7 +21,6 @@ import static android.content.pm.PackageManager.DONT_KILL_APP;
import static android.content.pm.PackageManager.MATCH_ALL;
import static android.content.pm.PackageManager.MATCH_DISABLED_COMPONENTS;
-import static com.android.launcher3.tapl.Folder.FOLDER_CONTENT_RES_ID;
import static com.android.launcher3.tapl.TestHelpers.getOverviewPackageName;
import static com.android.launcher3.testing.TestProtocol.NORMAL_STATE_ORDINAL;
@@ -66,7 +65,6 @@ import androidx.test.uiautomator.UiObject2;
import androidx.test.uiautomator.Until;
import com.android.launcher3.ResourceUtils;
-import com.android.launcher3.testing.TestInformationRequest;
import com.android.launcher3.testing.TestProtocol;
import com.android.systemui.shared.system.ContextUtils;
import com.android.systemui.shared.system.QuickStepContract;
@@ -77,14 +75,11 @@ import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Deque;
import java.util.LinkedList;
import java.util.List;
-import java.util.Optional;
-import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.function.Consumer;
import java.util.function.Function;
@@ -99,23 +94,17 @@ import java.util.stream.Collectors;
public final class LauncherInstrumentation {
private static final String TAG = "Tapl";
- private static final int ZERO_BUTTON_STEPS_FROM_BACKGROUND_TO_HOME = 15;
+ private static final int ZERO_BUTTON_STEPS_FROM_BACKGROUND_TO_HOME = 20;
private static final int GESTURE_STEP_MS = 16;
- private static final long FORCE_PAUSE_TIMEOUT_MS = TimeUnit.SECONDS.toMillis(2);
- static final Pattern EVENT_TOUCH_DOWN = getTouchEventPattern("ACTION_DOWN");
- static final Pattern EVENT_TOUCH_UP = getTouchEventPattern("ACTION_UP");
+ private static final Pattern EVENT_TOUCH_DOWN = getTouchEventPattern("ACTION_DOWN");
+ private static final Pattern EVENT_TOUCH_UP = getTouchEventPattern("ACTION_UP");
private static final Pattern EVENT_TOUCH_CANCEL = getTouchEventPattern("ACTION_CANCEL");
- static final Pattern EVENT_PILFER_POINTERS = Pattern.compile("pilferPointers");
+ private static final Pattern EVENT_PILFER_POINTERS = Pattern.compile("pilferPointers");
static final Pattern EVENT_START = Pattern.compile("start:");
static final Pattern EVENT_TOUCH_DOWN_TIS = getTouchEventPatternTIS("ACTION_DOWN");
static final Pattern EVENT_TOUCH_UP_TIS = getTouchEventPatternTIS("ACTION_UP");
- static final Pattern EVENT_TOUCH_CANCEL_TIS = getTouchEventPatternTIS("ACTION_CANCEL");
-
- static final Pattern EVENT_KEY_BACK_DOWN = getKeyEventPattern("ACTION_DOWN", "KEYCODE_BACK");
- static final Pattern EVENT_KEY_BACK_UP = getKeyEventPattern("ACTION_UP", "KEYCODE_BACK");
-
private final String mLauncherPackage;
private Boolean mIsLauncher3;
private long mTestStartTime = -1;
@@ -123,23 +112,21 @@ public final class LauncherInstrumentation {
// Types for launcher containers that the user is interacting with. "Background" is a
// pseudo-container corresponding to inactive launcher covered by another app.
public enum ContainerType {
- WORKSPACE, HOME_ALL_APPS, OVERVIEW, WIDGETS, FALLBACK_OVERVIEW, LAUNCHED_APP,
- TASKBAR_ALL_APPS
+ WORKSPACE, ALL_APPS, OVERVIEW, WIDGETS, BACKGROUND, FALLBACK_OVERVIEW
}
- public enum NavigationModel {ZERO_BUTTON, THREE_BUTTON}
+ public enum NavigationModel {ZERO_BUTTON, TWO_BUTTON, THREE_BUTTON}
// Where the gesture happens: outside of Launcher, inside or from inside to outside and
// whether the gesture recognition triggers pilfer.
public enum GestureScope {
- OUTSIDE_WITHOUT_PILFER, OUTSIDE_WITH_PILFER, INSIDE, INSIDE_TO_OUTSIDE,
- INSIDE_TO_OUTSIDE_WITHOUT_PILFER,
- INSIDE_TO_OUTSIDE_WITH_KEYCODE, // For gestures that will trigger a keycode from TIS.
- OUTSIDE_WITH_KEYCODE,
+ OUTSIDE_WITHOUT_PILFER, OUTSIDE_WITH_PILFER, INSIDE, INSIDE_TO_OUTSIDE
}
+ ;
+
// Base class for launcher containers.
- abstract static class VisibleContainer {
+ static abstract class VisibleContainer {
protected final LauncherInstrumentation mLauncher;
protected VisibleContainer(LauncherInstrumentation launcher) {
@@ -170,7 +157,6 @@ public final class LauncherInstrumentation {
private static final String OVERVIEW_RES_ID = "overview_panel";
private static final String WIDGETS_RES_ID = "primary_widgets_list_view";
private static final String CONTEXT_MENU_RES_ID = "popup_container";
- private static final String TASKBAR_RES_ID = "taskbar_view";
public static final int WAIT_TIME_MS = 60000;
private static final String SYSTEMUI_PACKAGE = "com.android.systemui";
private static final String ANDROID_PACKAGE = "android";
@@ -206,10 +192,6 @@ public final class LauncherInstrumentation {
return getTouchEventPattern("TouchInteractionService.onInputEvent", action);
}
- private static Pattern getKeyEventPattern(String action, String keyCode) {
- return Pattern.compile("Key event: KeyEvent.*action=" + action + ".*keyCode=" + keyCode);
- }
-
/**
* Constructs the root of TAPL hierarchy. You get all other objects from it.
*/
@@ -260,24 +242,11 @@ public final class LauncherInstrumentation {
if (pm.getComponentEnabledSetting(cn) != COMPONENT_ENABLED_STATE_ENABLED) {
if (TestHelpers.isInLauncherProcess()) {
pm.setComponentEnabledSetting(cn, COMPONENT_ENABLED_STATE_ENABLED, DONT_KILL_APP);
- // b/195031154
- SystemClock.sleep(5000);
} else {
try {
final int userId = ContextUtils.getUserId(getContext());
- final String launcherPidCommand = "pidof " + pi.packageName;
- final String initialPid = mDevice.executeShellCommand(launcherPidCommand)
- .replaceAll("\\s", "");
mDevice.executeShellCommand(
"pm enable --user " + userId + " " + cn.flattenToString());
- // Wait for Launcher restart after enabling test provider.
- for (int i = 0; i < 100; ++i) {
- final String currentPid = mDevice.executeShellCommand(launcherPidCommand)
- .replaceAll("\\s", "");
- if (!currentPid.isEmpty() && !currentPid.equals(initialPid)) break;
- if (i == 99) fail("Launcher didn't restart after enabling test provider");
- SystemClock.sleep(100);
- }
} catch (IOException e) {
fail(e.toString());
}
@@ -298,17 +267,9 @@ public final class LauncherInstrumentation {
}
Bundle getTestInfo(String request) {
- return getTestInfo(request, /*arg=*/ null);
- }
-
- Bundle getTestInfo(String request, String arg) {
- return getTestInfo(request, arg, null);
- }
-
- Bundle getTestInfo(String request, String arg, Bundle extra) {
try (ContentProviderClient client = getContext().getContentResolver()
.acquireContentProviderClient(mTestProviderUri)) {
- return client.call(request, arg, extra);
+ return client.call(request, null, null);
} catch (DeadObjectException e) {
fail("Launcher crashed");
return null;
@@ -317,64 +278,11 @@ public final class LauncherInstrumentation {
}
}
- Bundle getTestInfo(TestInformationRequest request) {
- Bundle extra = new Bundle();
- extra.putParcelable(TestProtocol.TEST_INFO_REQUEST_FIELD, request);
- return getTestInfo(request.getRequestName(), null, extra);
- }
-
Insets getTargetInsets() {
- return getTestInfo(TestProtocol.REQUEST_TARGET_INSETS)
- .getParcelable(TestProtocol.TEST_INFO_RESPONSE_FIELD);
- }
-
- Insets getWindowInsets() {
return getTestInfo(TestProtocol.REQUEST_WINDOW_INSETS)
.getParcelable(TestProtocol.TEST_INFO_RESPONSE_FIELD);
}
- public boolean isTablet() {
- return getTestInfo(TestProtocol.REQUEST_IS_TABLET)
- .getBoolean(TestProtocol.TEST_INFO_RESPONSE_FIELD);
- }
-
- public boolean isTwoPanels() {
- return getTestInfo(TestProtocol.REQUEST_IS_TWO_PANELS)
- .getBoolean(TestProtocol.TEST_INFO_RESPONSE_FIELD);
- }
-
- int getFocusedTaskHeightForTablet() {
- return getTestInfo(TestProtocol.REQUEST_GET_FOCUSED_TASK_HEIGHT_FOR_TABLET).getInt(
- TestProtocol.TEST_INFO_RESPONSE_FIELD);
- }
-
- Rect getGridTaskRectForTablet() {
- return ((Rect) getTestInfo(TestProtocol.REQUEST_GET_GRID_TASK_SIZE_RECT_FOR_TABLET)
- .getParcelable(TestProtocol.TEST_INFO_RESPONSE_FIELD));
- }
-
- int getOverviewPageSpacing() {
- return getTestInfo(TestProtocol.REQUEST_GET_OVERVIEW_PAGE_SPACING)
- .getInt(TestProtocol.TEST_INFO_RESPONSE_FIELD);
- }
-
- float getExactScreenCenterX() {
- return getRealDisplaySize().x / 2f;
- }
-
- private void setForcePauseTimeout(long timeout) {
- getTestInfo(TestProtocol.REQUEST_SET_FORCE_PAUSE_TIMEOUT, Long.toString(timeout));
- }
-
- public void setEnableRotation(boolean on) {
- getTestInfo(TestProtocol.REQUEST_ENABLE_ROTATION, Boolean.toString(on));
- }
-
- public boolean hadNontestEvents() {
- return getTestInfo(TestProtocol.REQUEST_GET_HAD_NONTEST_EVENTS)
- .getBoolean(TestProtocol.TEST_INFO_RESPONSE_FIELD);
- }
-
void setActiveContainer(VisibleContainer container) {
sActiveContainer = new WeakReference<>(container);
}
@@ -402,6 +310,8 @@ public final class LauncherInstrumentation {
public static NavigationModel getNavigationModel(int currentInteractionMode) {
if (QuickStepContract.isGesturalMode(currentInteractionMode)) {
return NavigationModel.ZERO_BUTTON;
+ } else if (QuickStepContract.isSwipeUpMode(currentInteractionMode)) {
+ return NavigationModel.TWO_BUTTON;
} else if (QuickStepContract.isLegacyMode(currentInteractionMode)) {
return NavigationModel.THREE_BUTTON;
}
@@ -435,19 +345,17 @@ public final class LauncherInstrumentation {
}
}
- public String getSystemAnomalyMessage(
- boolean ignoreNavmodeChangeStates, boolean ignoreOnlySystemUiViews) {
+ private String getSystemAnomalyMessage() {
try {
{
final StringBuilder sb = new StringBuilder();
- UiObject2 object =
- mDevice.findObject(By.res("android", "alertTitle").pkg("android"));
+ UiObject2 object = mDevice.findObject(By.res("android", "alertTitle"));
if (object != null) {
sb.append("TITLE: ").append(object.getText());
}
- object = mDevice.findObject(By.res("android", "message").pkg("android"));
+ object = mDevice.findObject(By.res("android", "message"));
if (object != null) {
sb.append(" PACKAGE: ").append(object.getApplicationPackage())
.append(" MESSAGE: ").append(object.getText());
@@ -460,19 +368,8 @@ public final class LauncherInstrumentation {
if (hasSystemUiObject("keyguard_status_view")) return "Phone is locked";
- if (!ignoreOnlySystemUiViews) {
- final String visibleApps = mDevice.findObjects(getAnyObjectSelector())
- .stream()
- .map(LauncherInstrumentation::getApplicationPackageSafe)
- .distinct()
- .filter(pkg -> pkg != null)
- .collect(Collectors.joining(","));
- if (SYSTEMUI_PACKAGE.equals(visibleApps)) return "Only System UI views are visible";
- }
- if (!ignoreNavmodeChangeStates) {
- if (!mDevice.wait(Until.hasObject(getAnyObjectSelector()), WAIT_TIME_MS)) {
- return "Screen is empty";
- }
+ if (!mDevice.wait(Until.hasObject(getAnyObjectSelector()), WAIT_TIME_MS)) {
+ return "Screen is empty";
}
final String navigationModeError = getNavigationModeMismatchError(true);
@@ -484,14 +381,8 @@ public final class LauncherInstrumentation {
return null;
}
- private void checkForAnomaly() {
- checkForAnomaly(false, false);
- }
-
- public void checkForAnomaly(
- boolean ignoreNavmodeChangeStates, boolean ignoreOnlySystemUiViews) {
- final String systemAnomalyMessage =
- getSystemAnomalyMessage(ignoreNavmodeChangeStates, ignoreOnlySystemUiViews);
+ public void checkForAnomaly() {
+ final String systemAnomalyMessage = getSystemAnomalyMessage();
if (systemAnomalyMessage != null) {
Assert.fail(formatSystemHealthMessage(formatErrorWithEvents(
"http://go/tapl : Tests are broken by a non-Launcher system error: "
@@ -500,15 +391,12 @@ public final class LauncherInstrumentation {
}
private String getVisiblePackages() {
- final String apps = mDevice.findObjects(getAnyObjectSelector())
+ return mDevice.findObjects(getAnyObjectSelector())
.stream()
.map(LauncherInstrumentation::getApplicationPackageSafe)
.distinct()
- .filter(pkg -> pkg != null && !SYSTEMUI_PACKAGE.equals(pkg))
+ .filter(pkg -> pkg != null && !"com.android.systemui".equals(pkg))
.collect(Collectors.joining(", "));
- return !apps.isEmpty()
- ? "active app: " + apps
- : "the test doesn't see views from any app, including Launcher";
}
private static String getApplicationPackageSafe(UiObject2 object) {
@@ -526,7 +414,7 @@ public final class LauncherInstrumentation {
if (hasLauncherObject(OVERVIEW_RES_ID)) return "Overview";
if (hasLauncherObject(WORKSPACE_RES_ID)) return "Workspace";
if (hasLauncherObject(APPS_RES_ID)) return "AllApps";
- return "LaunchedApp (" + getVisiblePackages() + ")";
+ return "Background (" + getVisiblePackages() + ")";
}
public void setSystemHealthSupplier(Function<Long, String> supplier) {
@@ -559,11 +447,11 @@ public final class LauncherInstrumentation {
: TestHelpers.getSystemHealthMessage(getContext(), mTestStartTime);
if (systemHealth != null) {
- message += ";\nPerhaps linked to system health problems:\n<<<<<<<<<<<<<<<<<<\n"
+ return message
+ + ";\nPerhaps linked to system health problems:\n<<<<<<<<<<<<<<<<<<\n"
+ systemHealth + "\n>>>>>>>>>>>>>>>>>>";
}
}
- Log.d(TAG, "About to throw the error: " + message, new Exception());
return message;
}
@@ -611,8 +499,9 @@ public final class LauncherInstrumentation {
void fail(String message) {
checkForAnomaly();
Assert.fail(formatSystemHealthMessage(formatErrorWithEvents(
- "http://go/tapl test failure: " + message + ";\nContext: " + getContextDescription()
- + "; now visible state is " + getVisibleStateMessage(), true)));
+ "http://go/tapl test failure:\nContext: " + getContextDescription()
+ + " - visible state is " + getVisibleStateMessage()
+ + ";\nDetails: " + message, true)));
}
private String getContextDescription() {
@@ -665,33 +554,29 @@ public final class LauncherInstrumentation {
public String getNavigationModeMismatchError(boolean waitForCorrectState) {
final int waitTime = waitForCorrectState ? WAIT_TIME_MS : 0;
final NavigationModel navigationModel = getNavigationModel();
- String resPackage = getNavigationButtonResPackage();
+
if (navigationModel == NavigationModel.THREE_BUTTON) {
- if (!mDevice.wait(Until.hasObject(By.res(resPackage, "recent_apps")), waitTime)) {
+ if (!mDevice.wait(Until.hasObject(By.res(SYSTEMUI_PACKAGE, "recent_apps")), waitTime)) {
return "Recents button not present in 3-button mode";
}
} else {
- if (!mDevice.wait(Until.gone(By.res(resPackage, "recent_apps")), waitTime)) {
+ if (!mDevice.wait(Until.gone(By.res(SYSTEMUI_PACKAGE, "recent_apps")), waitTime)) {
return "Recents button is present in non-3-button mode";
}
}
if (navigationModel == NavigationModel.ZERO_BUTTON) {
- if (!mDevice.wait(Until.gone(By.res(resPackage, "home")), waitTime)) {
+ if (!mDevice.wait(Until.gone(By.res(SYSTEMUI_PACKAGE, "home")), waitTime)) {
return "Home button is present in gestural mode";
}
} else {
- if (!mDevice.wait(Until.hasObject(By.res(resPackage, "home")), waitTime)) {
+ if (!mDevice.wait(Until.hasObject(By.res(SYSTEMUI_PACKAGE, "home")), waitTime)) {
return "Home button not present in non-gestural mode";
}
}
return null;
}
- private String getNavigationButtonResPackage() {
- return isTablet() ? getLauncherPackageName() : SYSTEMUI_PACKAGE;
- }
-
private UiObject2 verifyContainerType(ContainerType containerType) {
waitForLauncherInitialized();
@@ -718,54 +603,35 @@ public final class LauncherInstrumentation {
waitUntilLauncherObjectGone(APPS_RES_ID);
waitUntilLauncherObjectGone(OVERVIEW_RES_ID);
waitUntilLauncherObjectGone(WIDGETS_RES_ID);
- waitUntilLauncherObjectGone(TASKBAR_RES_ID);
-
return waitForLauncherObject(WORKSPACE_RES_ID);
}
case WIDGETS: {
waitUntilLauncherObjectGone(WORKSPACE_RES_ID);
waitUntilLauncherObjectGone(APPS_RES_ID);
waitUntilLauncherObjectGone(OVERVIEW_RES_ID);
- waitUntilLauncherObjectGone(TASKBAR_RES_ID);
-
return waitForLauncherObject(WIDGETS_RES_ID);
}
- case TASKBAR_ALL_APPS:
- case HOME_ALL_APPS: {
+ case ALL_APPS: {
waitUntilLauncherObjectGone(WORKSPACE_RES_ID);
waitUntilLauncherObjectGone(OVERVIEW_RES_ID);
waitUntilLauncherObjectGone(WIDGETS_RES_ID);
- waitUntilLauncherObjectGone(TASKBAR_RES_ID);
-
return waitForLauncherObject(APPS_RES_ID);
}
case OVERVIEW: {
waitUntilLauncherObjectGone(APPS_RES_ID);
waitUntilLauncherObjectGone(WORKSPACE_RES_ID);
waitUntilLauncherObjectGone(WIDGETS_RES_ID);
- waitUntilLauncherObjectGone(TASKBAR_RES_ID);
return waitForLauncherObject(OVERVIEW_RES_ID);
}
case FALLBACK_OVERVIEW: {
- waitUntilLauncherObjectGone(APPS_RES_ID);
- waitUntilLauncherObjectGone(WORKSPACE_RES_ID);
- waitUntilLauncherObjectGone(WIDGETS_RES_ID);
- waitUntilLauncherObjectGone(TASKBAR_RES_ID);
-
return waitForFallbackLauncherObject(OVERVIEW_RES_ID);
}
- case LAUNCHED_APP: {
+ case BACKGROUND: {
waitUntilLauncherObjectGone(WORKSPACE_RES_ID);
waitUntilLauncherObjectGone(APPS_RES_ID);
waitUntilLauncherObjectGone(OVERVIEW_RES_ID);
waitUntilLauncherObjectGone(WIDGETS_RES_ID);
-
- if (isTablet() && !isFallbackOverview()) {
- waitForLauncherObject(TASKBAR_RES_ID);
- } else {
- waitUntilLauncherObjectGone(TASKBAR_RES_ID);
- }
return null;
}
default:
@@ -817,66 +683,12 @@ public final class LauncherInstrumentation {
}
/**
- * Get the resource ID of visible floating view.
- */
- private Optional<String> getFloatingResId() {
- if (hasLauncherObject(CONTEXT_MENU_RES_ID)) {
- return Optional.of(CONTEXT_MENU_RES_ID);
- }
- if (hasLauncherObject(FOLDER_CONTENT_RES_ID)) {
- return Optional.of(FOLDER_CONTENT_RES_ID);
- }
- return Optional.empty();
- }
-
- /**
- * Using swiping up gesture to dismiss closable floating views, such as Menu or Folder Content.
- */
- private void swipeUpToCloseFloatingView(boolean gestureStartFromLauncher) {
- final Point displaySize = getRealDisplaySize();
-
- final Optional<String> floatingRes = getFloatingResId();
-
- if (!floatingRes.isPresent()) {
- return;
- }
-
- GestureScope gestureScope = gestureStartFromLauncher
- // Without the navigation bar layer, the gesture scope on tablets remains inside the
- // launcher process.
- ? (isTablet() ? GestureScope.INSIDE : GestureScope.INSIDE_TO_OUTSIDE)
- : GestureScope.OUTSIDE_WITH_PILFER;
- linearGesture(
- displaySize.x / 2, displaySize.y - 1,
- displaySize.x / 2, 0,
- ZERO_BUTTON_STEPS_FROM_BACKGROUND_TO_HOME,
- false, gestureScope);
-
- try (LauncherInstrumentation.Closable c1 = addContextLayer(
- String.format("Swiped up from floating view %s to home", floatingRes.get()))) {
- waitUntilLauncherObjectGone(floatingRes.get());
- waitForLauncherObject(getAnyObjectSelector());
- }
- }
-
- /**
- * @return the Workspace object.
- * @deprecated use goHome().
- * Presses nav bar home button.
- */
- @Deprecated
- public Workspace pressHome() {
- return goHome();
- }
-
- /**
* Presses nav bar home button.
*
* @return the Workspace object.
*/
- public Workspace goHome() {
- try (LauncherInstrumentation.Closable e = eventsCheck();
- LauncherInstrumentation.Closable c = addContextLayer("want to switch to home")) {
+ public Workspace pressHome() {
+ try (LauncherInstrumentation.Closable e = eventsCheck()) {
waitForLauncherInitialized();
// Click home, then wait for any accessibility event, then wait until accessibility
// events stop.
@@ -884,23 +696,27 @@ public final class LauncherInstrumentation {
// otherwise waitForIdle may return immediately in case when there was a big enough
// pause in accessibility events prior to pressing Home.
final String action;
+ final boolean launcherWasVisible = isLauncherVisible();
if (getNavigationModel() == NavigationModel.ZERO_BUTTON) {
- checkForAnomaly(false, true);
- setForcePauseTimeout(FORCE_PAUSE_TIMEOUT_MS);
+ checkForAnomaly();
final Point displaySize = getRealDisplaySize();
- // The swipe up to home gesture starts from inside the launcher when the user is
- // already home. Otherwise, the gesture can start inside the launcher process if the
- // taskbar is visible.
- boolean gestureStartFromLauncher = isTablet()
- ? !isLauncher3()
- || hasLauncherObject(WORKSPACE_RES_ID)
- || hasLauncherObject(TASKBAR_RES_ID)
- : isLauncherVisible();
-
- // CLose floating views before going back to home.
- swipeUpToCloseFloatingView(gestureStartFromLauncher);
+ if (hasLauncherObject(CONTEXT_MENU_RES_ID)) {
+ linearGesture(
+ displaySize.x / 2, displaySize.y - 1,
+ displaySize.x / 2, 0,
+ ZERO_BUTTON_STEPS_FROM_BACKGROUND_TO_HOME,
+ false, GestureScope.INSIDE_TO_OUTSIDE);
+ try (LauncherInstrumentation.Closable c = addContextLayer(
+ "Swiped up from context menu to home")) {
+ waitUntilLauncherObjectGone(CONTEXT_MENU_RES_ID);
+ // Swiping up can temporarily bring Nexus Launcher if the current
+ // Launcher is a Launcher3 one. Wait for the current launcher to reappear.
+ SystemClock.sleep(5000); // b/187080582
+ waitForLauncherObject(getAnyObjectSelector());
+ }
+ }
if (hasLauncherObject(WORKSPACE_RES_ID)) {
log(action = "already at home");
} else {
@@ -910,66 +726,36 @@ public final class LauncherInstrumentation {
swipeToState(
displaySize.x / 2, displaySize.y - 1,
- displaySize.x / 2, displaySize.y / 2,
+ displaySize.x / 2, 0,
ZERO_BUTTON_STEPS_FROM_BACKGROUND_TO_HOME, NORMAL_STATE_ORDINAL,
- gestureStartFromLauncher ? GestureScope.INSIDE_TO_OUTSIDE
+ launcherWasVisible
+ ? GestureScope.INSIDE_TO_OUTSIDE
: GestureScope.OUTSIDE_WITH_PILFER);
}
} else {
log("Hierarchy before clicking home:");
dumpViewHierarchy();
action = "clicking home button";
- if (isTablet()) {
- expectEvent(TestProtocol.SEQUENCE_MAIN, EVENT_TOUCH_DOWN);
- expectEvent(TestProtocol.SEQUENCE_MAIN, EVENT_TOUCH_UP);
+ if (!isLauncher3() && getNavigationModel() == NavigationModel.TWO_BUTTON) {
+ expectEvent(TestProtocol.SEQUENCE_TIS, EVENT_TOUCH_DOWN_TIS);
+ expectEvent(TestProtocol.SEQUENCE_TIS, EVENT_TOUCH_UP_TIS);
}
runToState(
- waitForNavigationUiObject("home")::click,
+ waitForSystemUiObject("home")::click,
NORMAL_STATE_ORDINAL,
!hasLauncherObject(WORKSPACE_RES_ID)
&& (hasLauncherObject(APPS_RES_ID)
|| hasLauncherObject(OVERVIEW_RES_ID)),
action);
}
- try (LauncherInstrumentation.Closable c1 = addContextLayer(
+ try (LauncherInstrumentation.Closable c = addContextLayer(
"performed action to switch to Home - " + action)) {
return getWorkspace();
}
}
}
- /**
- * Press navbar back button or swipe back if in gesture navigation mode.
- */
- public void pressBack() {
- try (Closable e = eventsCheck(); Closable c = addContextLayer("want to press back")) {
- waitForLauncherInitialized();
- final boolean launcherVisible =
- isTablet() ? isLauncherContainerVisible() : isLauncherVisible();
- if (getNavigationModel() == NavigationModel.ZERO_BUTTON) {
- final Point displaySize = getRealDisplaySize();
- final GestureScope gestureScope =
- launcherVisible ? GestureScope.INSIDE_TO_OUTSIDE_WITH_KEYCODE
- : GestureScope.OUTSIDE_WITH_KEYCODE;
- // TODO(b/225505986): change startY and endY back to displaySize.y / 2 once the
- // issue is solved.
- linearGesture(0, displaySize.y / 4, displaySize.x / 2, displaySize.y / 4,
- 10, false, gestureScope);
- } else {
- waitForNavigationUiObject("back").click();
- if (isTablet()) {
- expectEvent(TestProtocol.SEQUENCE_MAIN, EVENT_TOUCH_DOWN);
- expectEvent(TestProtocol.SEQUENCE_MAIN, EVENT_TOUCH_UP);
- }
- }
- if (launcherVisible) {
- expectEvent(TestProtocol.SEQUENCE_MAIN, EVENT_KEY_BACK_DOWN);
- expectEvent(TestProtocol.SEQUENCE_MAIN, EVENT_KEY_BACK_UP);
- }
- }
- }
-
private static BySelector getAnyObjectSelector() {
return By.textStartsWith("");
}
@@ -979,11 +765,6 @@ public final class LauncherInstrumentation {
return hasLauncherObject(getAnyObjectSelector());
}
- boolean isLauncherContainerVisible() {
- final String[] containerResources = {WORKSPACE_RES_ID, OVERVIEW_RES_ID, APPS_RES_ID};
- return Arrays.stream(containerResources).anyMatch(r -> hasLauncherObject(r));
- }
-
/**
* Gets the Workspace object if the current state is "active home", i.e. workspace. Fails if the
* launcher is not in that state.
@@ -998,14 +779,14 @@ public final class LauncherInstrumentation {
}
/**
- * Gets the LaunchedApp object if another app is active. Fails if the launcher is not in that
- * state.
+ * Gets the Workspace object if the current state is "background home", i.e. some other app is
+ * active. Fails if the launcher is not in that state.
*
- * @return LaunchedApp object.
+ * @return Background object.
*/
@NonNull
- public LaunchedAppState getLaunchedAppState() {
- return new LaunchedAppState(this);
+ public Background getBackground() {
+ return new Background(this);
}
/**
@@ -1042,26 +823,51 @@ public final class LauncherInstrumentation {
}
/**
- * Gets the homescreen All Apps object if the current state is showing the all apps panel opened
- * by swiping from workspace. Fails if the launcher is not in that state. Please don't call this
- * method if App Apps was opened by swiping up from Overview, as it won't fail and will return
- * an incorrect object.
+ * Gets the All Apps object if the current state is showing the all apps panel opened by swiping
+ * from workspace. Fails if the launcher is not in that state. Please don't call this method if
+ * App Apps was opened by swiping up from Overview, as it won't fail and will return an
+ * incorrect object.
*
- * @return Home All Apps object.
+ * @return All Aps object.
*/
@NonNull
- public HomeAllApps getAllApps() {
+ public AllApps getAllApps() {
try (LauncherInstrumentation.Closable c = addContextLayer("want to get all apps object")) {
- return new HomeAllApps(this);
+ return new AllApps(this);
}
}
- void waitUntilLauncherObjectGone(String resId) {
- waitUntilGoneBySelector(getLauncherObjectSelector(resId));
+ /**
+ * Gets the All Apps object if the current state is showing the all apps panel opened by swiping
+ * from overview. Fails if the launcher is not in that state. Please don't call this method if
+ * App Apps was opened by swiping up from home, as it won't fail and will return an
+ * incorrect object.
+ *
+ * @return All Aps object.
+ */
+ @NonNull
+ public AllAppsFromOverview getAllAppsFromOverview() {
+ try (LauncherInstrumentation.Closable c = addContextLayer("want to get all apps object")) {
+ return new AllAppsFromOverview(this);
+ }
}
- void waitUntilOverviewObjectGone(String resId) {
- waitUntilGoneBySelector(getOverviewObjectSelector(resId));
+ /**
+ * Gets the Options Popup Menu object if the current state is showing the popup menu. Fails if
+ * the launcher is not in that state.
+ *
+ * @return Options Popup Menu object.
+ */
+ @NonNull
+ public OptionsPopupMenu getOptionsPopupMenu() {
+ try (LauncherInstrumentation.Closable c = addContextLayer(
+ "want to get context menu object")) {
+ return new OptionsPopupMenu(this);
+ }
+ }
+
+ void waitUntilLauncherObjectGone(String resId) {
+ waitUntilGoneBySelector(getLauncherObjectSelector(resId));
}
void waitUntilLauncherObjectGone(BySelector selector) {
@@ -1086,15 +892,6 @@ public final class LauncherInstrumentation {
return object;
}
- @NonNull
- UiObject2 waitForNavigationUiObject(String resId) {
- String resPackage = getNavigationButtonResPackage();
- final UiObject2 object = mDevice.wait(
- Until.findObject(By.res(resPackage, resId)), WAIT_TIME_MS);
- assertNotNull("Can't find a navigation UI object with id: " + resId, object);
- return object;
- }
-
@Nullable
UiObject2 findObjectInContainer(UiObject2 container, BySelector selector) {
try {
@@ -1133,7 +930,7 @@ public final class LauncherInstrumentation {
void waitForObjectEnabled(UiObject2 object, String waitReason) {
try {
assertTrue("Timed out waiting for object to be enabled for " + waitReason + " "
- + object.getResourceName(),
+ + object.getResourceName(),
object.wait(Until.enabled(true), WAIT_TIME_MS));
} catch (StaleObjectException e) {
fail("The object disappeared from screen");
@@ -1142,30 +939,13 @@ public final class LauncherInstrumentation {
@NonNull
UiObject2 waitForObjectInContainer(UiObject2 container, BySelector selector) {
- return waitForObjectsInContainer(container, selector).get(0);
- }
-
- @NonNull
- List<UiObject2> waitForObjectsInContainer(
- UiObject2 container, BySelector selector) {
try {
- final List<UiObject2> objects = container.wait(
- Until.findObjects(selector),
+ final UiObject2 object = container.wait(
+ Until.findObject(selector),
WAIT_TIME_MS);
- assertNotNull("Can't find views in Launcher, id: " + selector + " in container: "
- + container.getResourceName(), objects);
- assertTrue("Can't find views in Launcher, id: " + selector + " in container: "
- + container.getResourceName(), objects.size() > 0);
- return objects;
- } catch (StaleObjectException e) {
- fail("The container disappeared from screen");
- return null;
- }
- }
-
- List<UiObject2> getChildren(UiObject2 container) {
- try {
- return container.getChildren();
+ assertNotNull("Can't find a view in Launcher, id: " + selector + " in container: "
+ + container.getResourceName(), object);
+ return object;
} catch (StaleObjectException e) {
fail("The container disappeared from screen");
return null;
@@ -1185,11 +965,6 @@ public final class LauncherInstrumentation {
}
@NonNull
- UiObject2 waitForOverviewObject(String resName) {
- return waitForObjectBySelector(getOverviewObjectSelector(resName));
- }
-
- @NonNull
UiObject2 waitForLauncherObject(String resName) {
return waitForObjectBySelector(getLauncherObjectSelector(resName));
}
@@ -1274,7 +1049,7 @@ public final class LauncherInstrumentation {
() -> "Failed to receive an event for the state change: expected ["
+ TestProtocol.stateOrdinalToString(expectedState)
+ "], actual: " + eventListToString(actualEvents),
- actionName);
+ actionName);
}
private boolean isSwitchToStateEvent(
@@ -1295,9 +1070,9 @@ public final class LauncherInstrumentation {
"swiping");
}
- int getBottomGestureSize() {
- return Math.max(getWindowInsets().bottom, ResourceUtils.getNavbarSize(
- ResourceUtils.NAVBAR_BOTTOM_GESTURE_SIZE, getResources())) + 1;
+ private int getBottomGestureSize() {
+ return ResourceUtils.getNavbarSize(
+ ResourceUtils.NAVBAR_BOTTOM_GESTURE_SIZE, getResources()) + 1;
}
int getBottomGestureMarginInContainer(UiObject2 container) {
@@ -1305,21 +1080,14 @@ public final class LauncherInstrumentation {
return getVisibleBounds(container).bottom - bottomGestureStartOnScreen;
}
- int getRightGestureMarginInContainer(UiObject2 container) {
- final int rightGestureStartOnScreen = getRightGestureStartOnScreen();
- return getVisibleBounds(container).right - rightGestureStartOnScreen;
- }
-
int getBottomGestureStartOnScreen() {
return getRealDisplaySize().y - getBottomGestureSize();
}
- int getRightGestureStartOnScreen() {
- return getRealDisplaySize().x - getWindowInsets().right - 1;
- }
-
- void clickObject(UiObject2 object) {
- waitForObjectEnabled(object, "clickObject");
+ void clickLauncherObject(UiObject2 object) {
+ waitForObjectEnabled(object, "clickLauncherObject");
+ expectEvent(TestProtocol.SEQUENCE_MAIN, LauncherInstrumentation.EVENT_TOUCH_DOWN);
+ expectEvent(TestProtocol.SEQUENCE_MAIN, LauncherInstrumentation.EVENT_TOUCH_UP);
if (!isLauncher3() && getNavigationModel() != NavigationModel.THREE_BUTTON) {
expectEvent(TestProtocol.SEQUENCE_TIS, LauncherInstrumentation.EVENT_TOUCH_DOWN_TIS);
expectEvent(TestProtocol.SEQUENCE_TIS, LauncherInstrumentation.EVENT_TOUCH_UP_TIS);
@@ -1327,14 +1095,10 @@ public final class LauncherInstrumentation {
object.click();
}
- void clickLauncherObject(UiObject2 object) {
- expectEvent(TestProtocol.SEQUENCE_MAIN, LauncherInstrumentation.EVENT_TOUCH_DOWN);
- expectEvent(TestProtocol.SEQUENCE_MAIN, LauncherInstrumentation.EVENT_TOUCH_UP);
- clickObject(object);
- }
-
void scrollToLastVisibleRow(
- UiObject2 container, Collection<UiObject2> items, int topPaddingInContainer) {
+ UiObject2 container,
+ Collection<UiObject2> items,
+ int topPaddingInContainer) {
final UiObject2 lowestItem = Collections.max(items, (i1, i2) ->
Integer.compare(getVisibleBounds(i1).top, getVisibleBounds(i2).top));
@@ -1357,19 +1121,6 @@ public final class LauncherInstrumentation {
containerRect.height() - distance - bottomGestureMarginInContainer,
0,
bottomGestureMarginInContainer),
- /* steps= */ 10,
- /* slowDown= */ true);
- }
-
- void scrollLeftByDistance(UiObject2 container, int distance) {
- final Rect containerRect = getVisibleBounds(container);
- final int rightGestureMarginInContainer = getRightGestureMarginInContainer(container);
- final int leftGestureMargin = getTargetInsets().left + getEdgeSensitivityWidth();
- scroll(
- container,
- Direction.LEFT,
- new Rect(leftGestureMargin, 0,
- containerRect.width() - distance - rightGestureMarginInContainer, 0),
10,
true);
}
@@ -1425,7 +1176,7 @@ public final class LauncherInstrumentation {
event -> TestProtocol.SCROLL_FINISHED_MESSAGE.equals(event.getClassName()),
() -> "Didn't receive a scroll end message: " + startX + ", " + startY
+ ", " + endX + ", " + endY,
- "scrolling");
+ "scrolling");
}
// Inject a swipe gesture. Inject exactly 'steps' motion points, incrementing event time by a
@@ -1438,15 +1189,14 @@ public final class LauncherInstrumentation {
final Point start = new Point(startX, startY);
final Point end = new Point(endX, endY);
sendPointer(downTime, downTime, MotionEvent.ACTION_DOWN, start, gestureScope);
- final long endTime = movePointer(
- start, end, steps, false, downTime, downTime, slowDown, gestureScope);
+ final long endTime = movePointer(start, end, steps, downTime, slowDown, gestureScope);
sendPointer(downTime, endTime, MotionEvent.ACTION_UP, end, gestureScope);
}
- long movePointer(Point start, Point end, int steps, boolean isDecelerating, long downTime,
- long startTime, boolean slowDown, GestureScope gestureScope) {
- long endTime = movePointer(downTime, startTime, steps * GESTURE_STEP_MS,
- isDecelerating, start, end, gestureScope);
+ long movePointer(Point start, Point end, int steps, long downTime, boolean slowDown,
+ GestureScope gestureScope) {
+ long endTime = movePointer(
+ downTime, downTime, steps * GESTURE_STEP_MS, start, end, gestureScope);
if (slowDown) {
endTime = movePointer(downTime, endTime + GESTURE_STEP_MS, 5 * GESTURE_STEP_MS, end,
end, gestureScope);
@@ -1484,50 +1234,46 @@ public final class LauncherInstrumentation {
0, 0, 1.0f, 1.0f, 0, 0, InputDevice.SOURCE_TOUCHSCREEN, 0);
}
- private boolean hasTIS() {
- return getTestInfo(TestProtocol.REQUEST_HAS_TIS).getBoolean(TestProtocol.REQUEST_HAS_TIS);
- }
-
-
public void sendPointer(long downTime, long currentTime, int action, Point point,
GestureScope gestureScope) {
- final boolean hasTIS = hasTIS();
+ final boolean notLauncher3 = !isLauncher3();
switch (action) {
case MotionEvent.ACTION_DOWN:
if (gestureScope != GestureScope.OUTSIDE_WITH_PILFER
- && gestureScope != GestureScope.OUTSIDE_WITHOUT_PILFER
- && gestureScope != GestureScope.OUTSIDE_WITH_KEYCODE) {
+ && gestureScope != GestureScope.OUTSIDE_WITHOUT_PILFER) {
expectEvent(TestProtocol.SEQUENCE_MAIN, EVENT_TOUCH_DOWN);
}
- if (hasTIS && getNavigationModel() != NavigationModel.THREE_BUTTON) {
+ if (notLauncher3 && getNavigationModel() != NavigationModel.THREE_BUTTON) {
expectEvent(TestProtocol.SEQUENCE_TIS, EVENT_TOUCH_DOWN_TIS);
}
break;
case MotionEvent.ACTION_UP:
- if (hasTIS && gestureScope != GestureScope.INSIDE
- && gestureScope != GestureScope.INSIDE_TO_OUTSIDE_WITHOUT_PILFER
+ if (notLauncher3 && gestureScope != GestureScope.INSIDE
&& (gestureScope == GestureScope.OUTSIDE_WITH_PILFER
|| gestureScope == GestureScope.INSIDE_TO_OUTSIDE)) {
expectEvent(TestProtocol.SEQUENCE_PILFER, EVENT_PILFER_POINTERS);
}
if (gestureScope != GestureScope.OUTSIDE_WITH_PILFER
- && gestureScope != GestureScope.OUTSIDE_WITHOUT_PILFER
- && gestureScope != GestureScope.OUTSIDE_WITH_KEYCODE) {
+ && gestureScope != GestureScope.OUTSIDE_WITHOUT_PILFER) {
expectEvent(TestProtocol.SEQUENCE_MAIN,
gestureScope == GestureScope.INSIDE
|| gestureScope == GestureScope.OUTSIDE_WITHOUT_PILFER
? EVENT_TOUCH_UP : EVENT_TOUCH_CANCEL);
}
- if (hasTIS && getNavigationModel() != NavigationModel.THREE_BUTTON) {
- expectEvent(TestProtocol.SEQUENCE_TIS,
- gestureScope == GestureScope.INSIDE_TO_OUTSIDE_WITH_KEYCODE
- || gestureScope == GestureScope.OUTSIDE_WITH_KEYCODE
- ? EVENT_TOUCH_CANCEL_TIS : EVENT_TOUCH_UP_TIS);
+ if (notLauncher3 && getNavigationModel() != NavigationModel.THREE_BUTTON) {
+ expectEvent(TestProtocol.SEQUENCE_TIS, EVENT_TOUCH_UP_TIS);
}
break;
}
final MotionEvent event = getMotionEvent(downTime, currentTime, action, point.x, point.y);
+ // b/190748682
+ switch (action) {
+ case MotionEvent.ACTION_DOWN:
+ case MotionEvent.ACTION_UP:
+ log("b/190748682: injecting " + event);
+ break;
+ }
assertTrue("injectInputEvent failed",
mInstrumentation.getUiAutomation().injectInputEvent(event, true, false));
event.recycle();
@@ -1535,55 +1281,21 @@ public final class LauncherInstrumentation {
public long movePointer(long downTime, long startTime, long duration, Point from, Point to,
GestureScope gestureScope) {
- return movePointer(
- downTime, startTime, duration, false, from, to, gestureScope);
- }
-
- public long movePointer(long downTime, long startTime, long duration, boolean isDecelerating,
- Point from, Point to, GestureScope gestureScope) {
log("movePointer: " + from + " to " + to);
final Point point = new Point();
long steps = duration / GESTURE_STEP_MS;
-
long currentTime = startTime;
+ for (long i = 0; i < steps; ++i) {
+ sleep(GESTURE_STEP_MS);
- if (isDecelerating) {
- // formula: V = V0 - D*T, assuming V = 0 when T = duration
+ currentTime += GESTURE_STEP_MS;
+ final float progress = (currentTime - startTime) / (float) duration;
- // vx0: initial speed at the x-dimension, set as twice the avg speed
- // dx: the constant deceleration at the x-dimension
- double vx0 = 2.0 * (to.x - from.x) / duration;
- double dx = vx0 / duration;
- // vy0: initial speed at the y-dimension, set as twice the avg speed
- // dy: the constant deceleration at the y-dimension
- double vy0 = 2.0 * (to.y - from.y) / duration;
- double dy = vy0 / duration;
+ point.x = from.x + (int) (progress * (to.x - from.x));
+ point.y = from.y + (int) (progress * (to.y - from.y));
- for (long i = 0; i < steps; ++i) {
- sleep(GESTURE_STEP_MS);
- currentTime += GESTURE_STEP_MS;
-
- // formula: P = P0 + V0*T - (D*T^2/2)
- final double t = (i + 1) * GESTURE_STEP_MS;
- point.x = from.x + (int) (vx0 * t - 0.5 * dx * t * t);
- point.y = from.y + (int) (vy0 * t - 0.5 * dy * t * t);
-
- sendPointer(downTime, currentTime, MotionEvent.ACTION_MOVE, point, gestureScope);
- }
- } else {
- for (long i = 0; i < steps; ++i) {
- sleep(GESTURE_STEP_MS);
- currentTime += GESTURE_STEP_MS;
-
- final float progress = (currentTime - startTime) / (float) duration;
- point.x = from.x + (int) (progress * (to.x - from.x));
- point.y = from.y + (int) (progress * (to.y - from.y));
-
- sendPointer(downTime, currentTime, MotionEvent.ACTION_MOVE, point, gestureScope);
-
- }
+ sendPointer(downTime, currentTime, MotionEvent.ACTION_MOVE, point, gestureScope);
}
-
return currentTime;
}
@@ -1645,16 +1357,25 @@ public final class LauncherInstrumentation {
}
Point getRealDisplaySize() {
- final Rect displayBounds = getContext().getSystemService(WindowManager.class)
- .getMaximumWindowMetrics()
- .getBounds();
- return new Point(displayBounds.width(), displayBounds.height());
+ final Point size = new Point();
+ getContext().getSystemService(WindowManager.class).getDefaultDisplay().getRealSize(size);
+ return size;
}
public void enableDebugTracing() {
getTestInfo(TestProtocol.REQUEST_ENABLE_DEBUG_TRACING);
}
+ boolean overviewShareEnabled() {
+ return getTestInfo(TestProtocol.REQUEST_OVERVIEW_SHARE_ENABLED).getBoolean(
+ TestProtocol.TEST_INFO_RESPONSE_FIELD);
+ }
+
+ boolean overviewContentPushEnabled() {
+ return getTestInfo(TestProtocol.REQUEST_OVERVIEW_CONTENT_PUSH_ENABLED).getBoolean(
+ TestProtocol.TEST_INFO_RESPONSE_FIELD);
+ }
+
private void disableSensorRotation() {
getTestInfo(TestProtocol.REQUEST_MOCK_SENSOR_ROTATION);
}
@@ -1692,53 +1413,6 @@ public final class LauncherInstrumentation {
getTestInfo(TestProtocol.REQUEST_CLEAR_DATA);
}
- /**
- * Reloads the workspace with a test layout that includes the Test Activity app icon on the
- * hotseat.
- */
- public void useTestWorkspaceLayoutOnReload() {
- getTestInfo(TestProtocol.REQUEST_USE_TEST_WORKSPACE_LAYOUT);
- }
-
- /** Reloads the workspace with the default layout defined by the user's grid size selection. */
- public void useDefaultWorkspaceLayoutOnReload() {
- getTestInfo(TestProtocol.REQUEST_USE_DEFAULT_WORKSPACE_LAYOUT);
- }
-
- /** Shows the taskbar if it is hidden, otherwise does nothing. */
- public void showTaskbarIfHidden() {
- getTestInfo(TestProtocol.REQUEST_UNSTASH_TASKBAR_IF_STASHED);
- }
-
- public List<String> getHotseatIconNames() {
- return getTestInfo(TestProtocol.REQUEST_HOTSEAT_ICON_NAMES)
- .getStringArrayList(TestProtocol.TEST_INFO_RESPONSE_FIELD);
- }
-
- private String[] getActivities() {
- return getTestInfo(TestProtocol.REQUEST_GET_ACTIVITIES)
- .getStringArray(TestProtocol.TEST_INFO_RESPONSE_FIELD);
- }
-
- public String getRootedActivitiesList() {
- return String.join(", ", getActivities());
- }
-
- public boolean noLeakedActivities() {
- final String[] activities = getActivities();
- for (String activity : activities) {
- if (activity.contains("(destroyed)")) {
- return false;
- }
- }
- return activities.length <= 2;
- }
-
- public int getActivitiesCreated() {
- return getTestInfo(TestProtocol.REQUEST_GET_ACTIVITIES_CREATED_COUNT)
- .getInt(TestProtocol.TEST_INFO_RESPONSE_FIELD);
- }
-
public Closable eventsCheck() {
Assert.assertTrue("Nested event checking", mEventChecker == null);
disableSensorRotation();
@@ -1791,7 +1465,7 @@ public final class LauncherInstrumentation {
try {
return object.getVisibleBounds();
} catch (StaleObjectException e) {
- fail("Object disappeared from screen");
+ fail("Object " + object + " disappeared from screen");
return null;
} catch (Throwable t) {
fail(t.toString());
@@ -1800,12 +1474,9 @@ public final class LauncherInstrumentation {
}
float getWindowCornerRadius() {
- // TODO(b/197326121): Check if the touch is overlapping with the corners by offsetting
- final float tmpBuffer = 100f;
final Resources resources = getResources();
if (!supportsRoundedCornersOnWindows(resources)) {
- Log.d(TAG, "No rounded corners");
- return tmpBuffer;
+ return 0f;
}
// Radius that should be used in case top or bottom aren't defined.
@@ -1823,12 +1494,11 @@ public final class LauncherInstrumentation {
// Always use the smallest radius to make sure the rounded corners will
// completely cover the display.
- Log.d(TAG, "Rounded corners top: " + topRadius + " bottom: " + bottomRadius);
- return Math.max(topRadius, bottomRadius) + tmpBuffer;
+ return Math.min(topRadius, bottomRadius);
}
private static boolean supportsRoundedCornersOnWindows(Resources resources) {
return ResourceUtils.getBoolByName(
"config_supportsRoundedCornersOnWindows", resources, false);
}
-}
+} \ No newline at end of file
diff --git a/tests/tapl/com/android/launcher3/tapl/OptionsPopupMenu.java b/tests/tapl/com/android/launcher3/tapl/OptionsPopupMenu.java
new file mode 100644
index 0000000000..787dc70063
--- /dev/null
+++ b/tests/tapl/com/android/launcher3/tapl/OptionsPopupMenu.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2020 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.launcher3.tapl;
+
+import androidx.annotation.NonNull;
+import androidx.test.uiautomator.By;
+import androidx.test.uiautomator.UiObject2;
+
+public class OptionsPopupMenu {
+
+ private final LauncherInstrumentation mLauncher;
+ private final UiObject2 mDeepShortcutsContainer;
+
+ OptionsPopupMenu(LauncherInstrumentation launcher) {
+ mLauncher = launcher;
+ mDeepShortcutsContainer = launcher.waitForLauncherObject("popup_container");
+ }
+
+ /**
+ * Returns a menu item with a given label. Fails if it doesn't exist.
+ */
+ @NonNull
+ public OptionsPopupMenuItem getMenuItem(@NonNull final String label) {
+ final UiObject2 menuItem = mLauncher.waitForObjectInContainer(mDeepShortcutsContainer,
+ By.text(label));
+ return new OptionsPopupMenuItem(mLauncher, menuItem);
+ }
+}
diff --git a/tests/tapl/com/android/launcher3/tapl/OptionsPopupMenuItem.java b/tests/tapl/com/android/launcher3/tapl/OptionsPopupMenuItem.java
new file mode 100644
index 0000000000..42b6bc9b3a
--- /dev/null
+++ b/tests/tapl/com/android/launcher3/tapl/OptionsPopupMenuItem.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2020 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.launcher3.tapl;
+
+import androidx.annotation.NonNull;
+import androidx.test.uiautomator.By;
+import androidx.test.uiautomator.UiObject2;
+import androidx.test.uiautomator.Until;
+
+import com.android.launcher3.testing.TestProtocol;
+
+public class OptionsPopupMenuItem {
+
+ private final LauncherInstrumentation mLauncher;
+ private final UiObject2 mObject;
+
+ OptionsPopupMenuItem(@NonNull LauncherInstrumentation launcher, @NonNull UiObject2 shortcut) {
+ mLauncher = launcher;
+ mObject = shortcut;
+ }
+
+ /**
+ * Clicks the option.
+ */
+ @NonNull
+ public void launch(@NonNull String expectedPackageName) {
+ try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck()) {
+ LauncherInstrumentation.log("OptionsPopupMenuItem before click "
+ + mObject.getVisibleCenter() + " in " + mLauncher.getVisibleBounds(mObject));
+ mLauncher.clickLauncherObject(mObject);
+ mLauncher.expectEvent(TestProtocol.SEQUENCE_MAIN, LauncherInstrumentation.EVENT_START);
+ mLauncher.assertTrue(
+ "App didn't start: " + By.pkg(expectedPackageName),
+ mLauncher.getDevice().wait(Until.hasObject(By.pkg(expectedPackageName)),
+ LauncherInstrumentation.WAIT_TIME_MS));
+ }
+ }
+}
diff --git a/tests/tapl/com/android/launcher3/tapl/Overview.java b/tests/tapl/com/android/launcher3/tapl/Overview.java
index 66a51a56a2..4d673a8cde 100644
--- a/tests/tapl/com/android/launcher3/tapl/Overview.java
+++ b/tests/tapl/com/android/launcher3/tapl/Overview.java
@@ -16,7 +16,12 @@
package com.android.launcher3.tapl;
+import static com.android.launcher3.testing.TestProtocol.ALL_APPS_STATE_ORDINAL;
+
+import androidx.annotation.NonNull;
+
import com.android.launcher3.tapl.LauncherInstrumentation.ContainerType;
+import com.android.launcher3.testing.TestProtocol;
/**
* Overview pane.
@@ -25,6 +30,7 @@ public final class Overview extends BaseOverview {
Overview(LauncherInstrumentation launcher) {
super(launcher);
+ verifyActiveContainer();
}
@Override
@@ -32,6 +38,38 @@ public final class Overview extends BaseOverview {
return LauncherInstrumentation.ContainerType.OVERVIEW;
}
+ /**
+ * Swipes up to All Apps.
+ *
+ * @return the App Apps object.
+ */
+ @NonNull
+ public AllAppsFromOverview switchToAllApps() {
+ try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck();
+ LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
+ "want to switch from overview to all apps")) {
+ verifyActiveContainer();
+
+ // Swipe from an app icon to the top.
+ LauncherInstrumentation.log("Overview.switchToAllApps before swipe");
+ mLauncher.swipeToState(
+ mLauncher.getDevice().getDisplayWidth() / 2,
+ mLauncher.getTestInfo(
+ TestProtocol.REQUEST_HOTSEAT_TOP).
+ getInt(TestProtocol.TEST_INFO_RESPONSE_FIELD),
+ mLauncher.getDevice().getDisplayWidth() / 2,
+ 0,
+ 12,
+ ALL_APPS_STATE_ORDINAL,
+ LauncherInstrumentation.GestureScope.INSIDE);
+
+ try (LauncherInstrumentation.Closable c1 = mLauncher.addContextLayer(
+ "swiped all way up from overview")) {
+ return new AllAppsFromOverview(mLauncher);
+ }
+ }
+ }
+
@Override
public void dismissAllTasks() {
super.dismissAllTasks();
diff --git a/tests/tapl/com/android/launcher3/tapl/OverviewActions.java b/tests/tapl/com/android/launcher3/tapl/OverviewActions.java
index 2f44bb6aa4..950c052636 100644
--- a/tests/tapl/com/android/launcher3/tapl/OverviewActions.java
+++ b/tests/tapl/com/android/launcher3/tapl/OverviewActions.java
@@ -34,6 +34,27 @@ public class OverviewActions {
}
/**
+ * Clicks content push button.
+ */
+ @NonNull
+ public Overview clickAndDismissContentPush() {
+ if (mLauncher.overviewContentPushEnabled()) {
+ try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck();
+ LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
+ "want to click content push button and exit screenshot ui")) {
+ UiObject2 exo = mLauncher.waitForObjectInContainer(mOverviewActions,
+ "action_content_push");
+ mLauncher.clickLauncherObject(exo);
+ try (LauncherInstrumentation.Closable c1 = mLauncher.addContextLayer(
+ "clicked content push button")) {
+ return new Overview(mLauncher);
+ }
+ }
+ }
+ return new Overview(mLauncher);
+ }
+
+ /**
* Clicks screenshot button and closes screenshot ui.
*/
@NonNull
@@ -48,7 +69,7 @@ public class OverviewActions {
try (LauncherInstrumentation.Closable c1 = mLauncher.addContextLayer(
"clicked screenshot button")) {
UiObject2 closeScreenshot = mLauncher.waitForSystemUiObject(
- "screenshot_dismiss_image");
+ "global_screenshot_dismiss_image");
if (mLauncher.getNavigationModel()
!= LauncherInstrumentation.NavigationModel.THREE_BUTTON) {
mLauncher.expectEvent(TestProtocol.SEQUENCE_TIS,
@@ -66,6 +87,35 @@ public class OverviewActions {
}
/**
+ * Click share button, then drags sharesheet down to remove it.
+ *
+ * Share is currently hidden behind flag, test is kept in case share becomes a default feature.
+ * If share is completely removed then remove this test as well.
+ */
+ @NonNull
+ public Overview clickAndDismissShare() {
+ if (mLauncher.overviewShareEnabled()) {
+ try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck();
+ LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
+ "want to click share button and dismiss sharesheet")) {
+ UiObject2 share = mLauncher.waitForObjectInContainer(mOverviewActions,
+ "action_share");
+ mLauncher.clickLauncherObject(share);
+ try (LauncherInstrumentation.Closable c1 = mLauncher.addContextLayer(
+ "clicked share button")) {
+ mLauncher.waitForAndroidObject("contentPanel");
+ mLauncher.getDevice().pressBack();
+ try (LauncherInstrumentation.Closable c2 = mLauncher.addContextLayer(
+ "dismissed sharesheet")) {
+ return new Overview(mLauncher);
+ }
+ }
+ }
+ }
+ return new Overview(mLauncher);
+ }
+
+ /**
* Click select button
*
* @return The select mode buttons that are now shown instead of action buttons.
diff --git a/tests/tapl/com/android/launcher3/tapl/OverviewTask.java b/tests/tapl/com/android/launcher3/tapl/OverviewTask.java
index c8caa42b6d..657b74d116 100644
--- a/tests/tapl/com/android/launcher3/tapl/OverviewTask.java
+++ b/tests/tapl/com/android/launcher3/tapl/OverviewTask.java
@@ -24,9 +24,7 @@ import androidx.test.uiautomator.UiObject2;
import com.android.launcher3.testing.TestProtocol;
-import java.util.List;
import java.util.regex.Pattern;
-import java.util.stream.Collectors;
/**
* A recent task in the overview panel carousel.
@@ -49,85 +47,28 @@ public final class OverviewTask {
mOverview.verifyActiveContainer();
}
- int getVisibleHeight() {
- return mTask.getVisibleBounds().height();
- }
-
- int getVisibleWidth() {
- return mTask.getVisibleBounds().width();
- }
-
- int getTaskCenterX() {
- return mTask.getVisibleCenter().x;
- }
-
/**
- * Dismisses the task by swiping up.
+ * Swipes the task up.
*/
public void dismiss() {
try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck();
LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
- "want to dismiss an overview task")) {
+ "want to dismiss a task")) {
verifyActiveContainer();
- int taskCountBeforeDismiss = mOverview.getTaskCount();
- mLauncher.assertNotEquals("Unable to find a task", 0, taskCountBeforeDismiss);
- if (taskCountBeforeDismiss == 1) {
- dismissBySwipingUp();
- return;
- }
-
- boolean taskWasFocused = mLauncher.isTablet() && getVisibleHeight() == mLauncher
- .getFocusedTaskHeightForTablet();
- List<Integer> originalTasksCenterX = getCurrentTasksCenterXList();
- boolean isClearAllVisibleBeforeDismiss = mOverview.isClearAllVisible();
-
- dismissBySwipingUp();
-
- try (LauncherInstrumentation.Closable c2 = mLauncher.addContextLayer("dismissed")) {
- if (taskWasFocused) {
- mLauncher.assertNotNull("No task became focused",
- mOverview.getFocusedTaskForTablet());
- }
- if (!isClearAllVisibleBeforeDismiss) {
- List<Integer> currentTasksCenterX = getCurrentTasksCenterXList();
- if (originalTasksCenterX.size() == currentTasksCenterX.size()) {
- // Check for the same number of visible tasks before and after to
- // avoid asserting on cases of shifting all tasks to close the distance
- // between clear all and tasks at the end of the grid.
- mLauncher.assertTrue("Task centers not aligned",
- originalTasksCenterX.equals(currentTasksCenterX));
- }
- }
- }
+ // Dismiss the task via flinging it up.
+ final Rect taskBounds = mLauncher.getVisibleBounds(mTask);
+ final int centerX = taskBounds.centerX();
+ final int centerY = taskBounds.centerY();
+ mLauncher.linearGesture(centerX, centerY, centerX, 0, 10, false,
+ LauncherInstrumentation.GestureScope.INSIDE);
+ mLauncher.waitForIdle();
}
}
- private void dismissBySwipingUp() {
- verifyActiveContainer();
- // Dismiss the task via flinging it up.
- final Rect taskBounds = mLauncher.getVisibleBounds(mTask);
- final int centerX = taskBounds.centerX();
- final int centerY = taskBounds.centerY();
- mLauncher.executeAndWaitForLauncherEvent(
- () -> mLauncher.linearGesture(centerX, centerY, centerX, 0, 10, false,
- LauncherInstrumentation.GestureScope.INSIDE),
- event -> TestProtocol.DISMISS_ANIMATION_ENDS_MESSAGE.equals(event.getClassName()),
- () -> "Didn't receive a dismiss animation ends message: " + centerX + ", "
- + centerY, "swiping to dismiss");
- }
-
- private List<Integer> getCurrentTasksCenterXList() {
- return mLauncher.isTablet()
- ? mOverview.getCurrentTasksForTablet().stream()
- .map(OverviewTask::getTaskCenterX)
- .collect(Collectors.toList())
- : List.of(mOverview.getCurrentTask().getTaskCenterX());
- }
-
/**
* Clicks at the task.
*/
- public LaunchedAppState open() {
+ public Background open() {
try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck()) {
verifyActiveContainer();
mLauncher.executeAndWaitForEvent(
@@ -137,7 +78,7 @@ public final class OverviewTask {
+ mTask.getParent().getContentDescription(),
"clicking an overview task");
mLauncher.expectEvent(TestProtocol.SEQUENCE_MAIN, TASK_START_EVENT);
- return new LaunchedAppState(mLauncher);
+ return new Background(mLauncher);
}
}
}
diff --git a/tests/tapl/com/android/launcher3/tapl/SearchResultFromQsb.java b/tests/tapl/com/android/launcher3/tapl/SearchResultFromQsb.java
deleted file mode 100644
index 82652c7f27..0000000000
--- a/tests/tapl/com/android/launcher3/tapl/SearchResultFromQsb.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.launcher3.tapl;
-
-import android.widget.TextView;
-
-import androidx.test.uiautomator.By;
-import androidx.test.uiautomator.UiObject2;
-
-/**
- * Operations on search result page opened from home screen qsb.
- */
-public class SearchResultFromQsb {
- // The input resource id in the search box.
- private static final String INPUT_RES = "input";
- private final LauncherInstrumentation mLauncher;
-
- SearchResultFromQsb(LauncherInstrumentation launcher) {
- mLauncher = launcher;
- mLauncher.waitForLauncherObject("search_container_all_apps");
- }
-
- /** Set the input to the search input edit text and update search results. */
- public void searchForInput(String input) {
- try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
- "want to search for result with an input");
- LauncherInstrumentation.Closable e = mLauncher.eventsCheck()) {
- mLauncher.waitForLauncherObject(INPUT_RES).setText(input);
- }
- }
-
- /** Find the app from search results with app name. */
- public Launchable findAppIcon(String appName) {
- UiObject2 icon = mLauncher.waitForLauncherObject(By.clazz(TextView.class).text(appName));
- return new AllAppsAppIcon(mLauncher, icon);
- }
-}
diff --git a/tests/tapl/com/android/launcher3/tapl/SplitscreenDragSource.java b/tests/tapl/com/android/launcher3/tapl/SplitscreenDragSource.java
deleted file mode 100644
index ce1c3c0e9d..0000000000
--- a/tests/tapl/com/android/launcher3/tapl/SplitscreenDragSource.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.launcher3.tapl;
-
-/** Launchable that can serve as a source for dragging and dropping to splitscreen. */
-interface SplitscreenDragSource {
-
- /**
- * Drags this app icon to the left (landscape) or bottom (portrait) of the screen, launching it
- * in splitscreen.
- *
- * @param expectedNewPackageName package name of the app being dragged
- * @param expectedExistingPackageName package name of the already-launched app
- */
- default void dragToSplitscreen(
- String expectedNewPackageName, String expectedExistingPackageName) {
- Launchable launchable = getLaunchable();
- LauncherInstrumentation launcher = launchable.mLauncher;
- try (LauncherInstrumentation.Closable e = launcher.eventsCheck()) {
- LaunchedAppState.dragToSplitscreen(
- launcher, launchable, expectedNewPackageName, expectedExistingPackageName);
- }
- }
-
- Launchable getLaunchable();
-}
diff --git a/tests/tapl/com/android/launcher3/tapl/Taskbar.java b/tests/tapl/com/android/launcher3/tapl/Taskbar.java
deleted file mode 100644
index b5a08c3ba6..0000000000
--- a/tests/tapl/com/android/launcher3/tapl/Taskbar.java
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.launcher3.tapl;
-
-import static com.android.launcher3.testing.TestProtocol.REQUEST_DISABLE_MANUAL_TASKBAR_STASHING;
-import static com.android.launcher3.testing.TestProtocol.REQUEST_ENABLE_MANUAL_TASKBAR_STASHING;
-
-import android.graphics.Point;
-import android.os.SystemClock;
-import android.text.TextUtils;
-import android.view.MotionEvent;
-import android.widget.TextView;
-
-import androidx.annotation.NonNull;
-import androidx.test.uiautomator.By;
-import androidx.test.uiautomator.BySelector;
-import androidx.test.uiautomator.UiObject2;
-
-import java.util.List;
-import java.util.stream.Collectors;
-
-/**
- * Operations on the Taskbar from LaunchedApp.
- */
-public final class Taskbar {
-
- private final LauncherInstrumentation mLauncher;
-
- Taskbar(LauncherInstrumentation launcher) {
- mLauncher = launcher;
- }
-
- /**
- * Returns an app icon with the given name. This fails if the icon is not found.
- */
- @NonNull
- public TaskbarAppIcon getAppIcon(String appName) {
- try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
- "want to get a taskbar icon")) {
- return new TaskbarAppIcon(mLauncher, mLauncher.waitForObjectInContainer(
- mLauncher.waitForLauncherObject("taskbar_view"),
- AppIcon.getAppIconSelector(appName, mLauncher)));
- }
- }
-
- /**
- * Hides this taskbar.
- *
- * The taskbar must already be visible when calling this method.
- */
- public void hide() {
- mLauncher.getTestInfo(REQUEST_ENABLE_MANUAL_TASKBAR_STASHING);
-
- try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
- "want to hide the taskbar");
- LauncherInstrumentation.Closable e = mLauncher.eventsCheck()) {
- mLauncher.waitForLauncherObject("taskbar_view");
-
- final long downTime = SystemClock.uptimeMillis();
- Point stashTarget = new Point(
- mLauncher.getRealDisplaySize().x - 1, mLauncher.getRealDisplaySize().y - 1);
-
- mLauncher.sendPointer(downTime, downTime, MotionEvent.ACTION_DOWN, stashTarget,
- LauncherInstrumentation.GestureScope.INSIDE);
- LauncherInstrumentation.log("hideTaskbar: sent down");
-
- try (LauncherInstrumentation.Closable c2 = mLauncher.addContextLayer("pressed down")) {
- mLauncher.waitUntilLauncherObjectGone("taskbar_view");
- mLauncher.sendPointer(downTime, downTime, MotionEvent.ACTION_UP, stashTarget,
- LauncherInstrumentation.GestureScope.INSIDE);
- }
- } finally {
- mLauncher.getTestInfo(REQUEST_DISABLE_MANUAL_TASKBAR_STASHING);
- }
- }
-
- /**
- * Opens the Taskbar all apps page.
- */
- public AllAppsFromTaskbar openAllApps() {
- try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
- "want to open taskbar all apps");
- LauncherInstrumentation.Closable e = mLauncher.eventsCheck()) {
-
- mLauncher.clickLauncherObject(mLauncher.waitForObjectInContainer(
- mLauncher.waitForLauncherObject("taskbar_view"), getAllAppsButtonSelector()));
-
- return new AllAppsFromTaskbar(mLauncher);
- }
- }
-
- /** Returns a list of app icon names on the Taskbar */
- public List<String> getIconNames() {
- try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
- "want to get all taskbar icons")) {
- return mLauncher.waitForObjectsInContainer(
- mLauncher.waitForLauncherObject("taskbar_view"),
- AppIcon.getAnyAppIconSelector())
- .stream()
- .map(UiObject2::getText)
- .filter(text -> !TextUtils.isEmpty(text)) // Filter out the all apps button
- .collect(Collectors.toList());
- }
- }
-
- private static BySelector getAllAppsButtonSelector() {
- // Look for an icon with no text
- return By.clazz(TextView.class).text("");
- }
-}
diff --git a/tests/tapl/com/android/launcher3/tapl/TaskbarAppIcon.java b/tests/tapl/com/android/launcher3/tapl/TaskbarAppIcon.java
deleted file mode 100644
index 099acd4716..0000000000
--- a/tests/tapl/com/android/launcher3/tapl/TaskbarAppIcon.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.launcher3.tapl;
-
-import androidx.test.uiautomator.UiObject2;
-
-import java.util.regex.Pattern;
-
-/**
- * App icon specifically on the Taskbar.
- */
-public final class TaskbarAppIcon extends AppIcon implements SplitscreenDragSource {
-
- private static final Pattern LONG_CLICK_EVENT = Pattern.compile("onTaskbarItemLongClick");
-
- TaskbarAppIcon(LauncherInstrumentation launcher, UiObject2 icon) {
- super(launcher, icon);
- }
-
- @Override
- protected Pattern getLongClickEvent() {
- return LONG_CLICK_EVENT;
- }
-
- @Override
- public TaskbarAppIconMenu openDeepShortcutMenu() {
- return (TaskbarAppIconMenu) super.openDeepShortcutMenu();
- }
-
- @Override
- protected TaskbarAppIconMenu createMenu(UiObject2 menu) {
- return new TaskbarAppIconMenu(mLauncher, menu);
- }
-
- @Override
- public Launchable getLaunchable() {
- return this;
- }
-}
diff --git a/tests/tapl/com/android/launcher3/tapl/TaskbarAppIconMenu.java b/tests/tapl/com/android/launcher3/tapl/TaskbarAppIconMenu.java
deleted file mode 100644
index 1f137c5406..0000000000
--- a/tests/tapl/com/android/launcher3/tapl/TaskbarAppIconMenu.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.launcher3.tapl;
-
-import androidx.test.uiautomator.UiObject2;
-
-/**
- * Context menu of a Taskbar app icon.
- */
-public final class TaskbarAppIconMenu extends AppIconMenu {
-
- TaskbarAppIconMenu(LauncherInstrumentation launcher, UiObject2 deepShortcutsContainer) {
- super(launcher, deepShortcutsContainer);
- }
-
- @Override
- public TaskbarAppIconMenuItem getMenuItem(String shortcutText) {
- return (TaskbarAppIconMenuItem) super.getMenuItem(shortcutText);
- }
-
- @Override
- protected TaskbarAppIconMenuItem createMenuItem(UiObject2 menuItem) {
- return new TaskbarAppIconMenuItem(mLauncher, menuItem);
- }
-}
diff --git a/tests/tapl/com/android/launcher3/tapl/TaskbarAppIconMenuItem.java b/tests/tapl/com/android/launcher3/tapl/TaskbarAppIconMenuItem.java
deleted file mode 100644
index 69a8a08800..0000000000
--- a/tests/tapl/com/android/launcher3/tapl/TaskbarAppIconMenuItem.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.launcher3.tapl;
-
-import androidx.test.uiautomator.UiObject2;
-
-import com.android.launcher3.testing.TestProtocol;
-
-import java.util.regex.Pattern;
-
-/**
- * Menu item in a Taskbar app icon menu.
- */
-public final class TaskbarAppIconMenuItem extends AppIconMenuItem implements SplitscreenDragSource {
-
- private static final Pattern LONG_CLICK_EVENT = Pattern.compile("onTaskbarItemLongClick");
-
- TaskbarAppIconMenuItem(
- LauncherInstrumentation launcher, UiObject2 shortcut) {
- super(launcher, shortcut);
- }
-
- @Override
- protected void addExpectedEventsForLongClick() {
- mLauncher.expectEvent(TestProtocol.SEQUENCE_MAIN, LONG_CLICK_EVENT);
- }
-
- @Override
- protected void waitForLongPressConfirmation() {
- // On long-press, the popup container closes and the system drag-and-drop begins. This
- // only leaves launcher views that were previously visible.
- mLauncher.waitUntilLauncherObjectGone("popup_container");
- }
-
- @Override
- protected String launchableType() {
- return "taskbar app icon menu item";
- }
-
- @Override
- public Launchable getLaunchable() {
- return this;
- }
-}
diff --git a/tests/tapl/com/android/launcher3/tapl/Widget.java b/tests/tapl/com/android/launcher3/tapl/Widget.java
index 2346249564..35203185ed 100644
--- a/tests/tapl/com/android/launcher3/tapl/Widget.java
+++ b/tests/tapl/com/android/launcher3/tapl/Widget.java
@@ -16,12 +16,7 @@
package com.android.launcher3.tapl;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.test.uiautomator.By;
-import androidx.test.uiautomator.BySelector;
import androidx.test.uiautomator.UiObject2;
-import androidx.test.uiautomator.Until;
import com.android.launcher3.testing.TestProtocol;
@@ -30,7 +25,7 @@ import java.util.regex.Pattern;
/**
* Widget in workspace or a widget list.
*/
-public final class Widget extends Launchable implements WorkspaceDragSource {
+public final class Widget extends Launchable {
private static final Pattern LONG_CLICK_EVENT = Pattern.compile("Widgets.onLongClick");
@@ -39,8 +34,8 @@ public final class Widget extends Launchable implements WorkspaceDragSource {
}
@Override
- protected void waitForLongPressConfirmation() {
- mLauncher.waitForLauncherObject("drop_target_bar");
+ protected String getLongPressIndicator() {
+ return "drop_target_bar";
}
@Override
@@ -56,61 +51,4 @@ public final class Widget extends Launchable implements WorkspaceDragSource {
protected String launchableType() {
return "widget";
}
-
- /** This method requires public access, however should not be called in tests. */
- @Override
- public Launchable getLaunchable() {
- return this;
- }
-
- /**
- * Drags a non-configurable widget from the widgets container to the workspace and returns the
- * resize frame that is shown after the widget is added.
- */
- @NonNull
- public WidgetResizeFrame dragWidgetToWorkspace() {
- return dragWidgetToWorkspace(/* configurable= */ false, /* acceptsConfig= */ false);
- }
-
- /**
- * Drags a configurable widget from the widgets container to the workspace, either accepts or
- * cancels the configuration based on {@code acceptsConfig}, and returns the resize frame that
- * is shown if the widget is added.
- */
- @Nullable
- public WidgetResizeFrame dragConfigWidgetToWorkspace(boolean acceptsConfig) {
- return dragWidgetToWorkspace(/* configurable= */ true, acceptsConfig);
- }
-
- /**
- * Drags a widget from the widgets container to the workspace and returns the resize frame that
- * is shown after the widget is added.
- *
- * <p> If {@code configurable} is true, then either accepts or cancels the configuration based
- * on {@code acceptsConfig}.
- */
- @Nullable
- private WidgetResizeFrame dragWidgetToWorkspace(
- boolean configurable, boolean acceptsConfig) {
- dragToWorkspace(/* startsActivity= */ configurable, /* isWidgetShortcut= */ false);
-
- if (configurable) {
- // Configure the widget.
- BySelector selector = By.text(acceptsConfig ? "OK" : "Cancel");
- mLauncher.getDevice()
- .wait(Until.findObject(selector), LauncherInstrumentation.WAIT_TIME_MS)
- .click();
-
- // If the widget configuration was cancelled, then the widget wasn't added to the home
- // screen. In that case, we cannot return a resize frame.
- if (!acceptsConfig) {
- return null;
- }
- }
-
- try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
- "want to get widget resize frame")) {
- return new WidgetResizeFrame(mLauncher);
- }
- }
}
diff --git a/tests/tapl/com/android/launcher3/tapl/WidgetResizeFrame.java b/tests/tapl/com/android/launcher3/tapl/WidgetResizeFrame.java
deleted file mode 100644
index 8f51d04c3d..0000000000
--- a/tests/tapl/com/android/launcher3/tapl/WidgetResizeFrame.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2021 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.launcher3.tapl;
-
-/** The resize frame that is shown for a widget on the workspace. */
-public class WidgetResizeFrame {
-
- private final LauncherInstrumentation mLauncher;
-
- WidgetResizeFrame(LauncherInstrumentation launcher) {
- mLauncher = launcher;
- launcher.waitForLauncherObject("widget_resize_frame");
- }
-
- /** Dismisses the resize frame. */
- public void dismiss() {
- try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck();
- LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
- "want to dismiss widget resize frame")) {
- // Dismiss the resize frame by pressing the home button.
- mLauncher.getDevice().pressHome();
- }
- }
-}
diff --git a/tests/tapl/com/android/launcher3/tapl/Widgets.java b/tests/tapl/com/android/launcher3/tapl/Widgets.java
index 7fd68c09e9..99d988926a 100644
--- a/tests/tapl/com/android/launcher3/tapl/Widgets.java
+++ b/tests/tapl/com/android/launcher3/tapl/Widgets.java
@@ -77,8 +77,7 @@ public final class Widgets extends LauncherInstrumentation.VisibleContainer {
mLauncher.scroll(
widgetsContainer,
Direction.UP,
- new Rect(0, 0, mLauncher.getRightGestureMarginInContainer(widgetsContainer) + 1,
- 0),
+ new Rect(0, 0, mLauncher.getVisibleBounds(widgetsContainer).width(), 0),
FLING_STEPS, false);
try (LauncherInstrumentation.Closable c1 = mLauncher.addContextLayer("flung back")) {
verifyActiveContainer();
@@ -115,21 +114,17 @@ public final class Widgets extends LauncherInstrumentation.VisibleContainer {
final BySelector labelSelector = By.clazz("android.widget.TextView").text(labelText);
final BySelector previewSelector = By.res(mLauncher.getLauncherPackageName(),
"widget_preview");
- final int bottomGestureStartOnScreen = mLauncher.getBottomGestureStartOnScreen();
int i = 0;
for (; ; ) {
- final Collection<UiObject2> tableRows = mLauncher.getChildren(widgetsContainer);
+ final Collection<UiObject2> tableRows = widgetsContainer.getChildren();
for (UiObject2 row : tableRows) {
- final Collection<UiObject2> widgetCells = mLauncher.getChildren(row);
+ final Collection<UiObject2> widgetCells = row.getChildren();
for (UiObject2 widget : widgetCells) {
final UiObject2 label = mLauncher.findObjectInContainer(widget,
labelSelector);
if (label == null) {
continue;
}
- if (widget.getVisibleCenter().y >= bottomGestureStartOnScreen) {
- continue;
- }
mLauncher.assertEquals(
"View is not WidgetCell",
"com.android.launcher3.widget.WidgetCell",
diff --git a/tests/tapl/com/android/launcher3/tapl/Workspace.java b/tests/tapl/com/android/launcher3/tapl/Workspace.java
index eb7f05bd1e..43134d95ad 100644
--- a/tests/tapl/com/android/launcher3/tapl/Workspace.java
+++ b/tests/tapl/com/android/launcher3/tapl/Workspace.java
@@ -16,12 +16,10 @@
package com.android.launcher3.tapl;
-import static android.view.accessibility.AccessibilityEvent.TYPE_VIEW_SCROLLED;
-
import static com.android.launcher3.testing.TestProtocol.ALL_APPS_STATE_ORDINAL;
import static com.android.launcher3.testing.TestProtocol.NORMAL_STATE_ORDINAL;
+import static com.android.launcher3.testing.TestProtocol.SPRING_LOADED_STATE_ORDINAL;
-import static junit.framework.TestCase.assertNotNull;
import static junit.framework.TestCase.assertTrue;
import android.graphics.Point;
@@ -33,30 +31,19 @@ import android.view.MotionEvent;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.test.uiautomator.By;
-import androidx.test.uiautomator.BySelector;
import androidx.test.uiautomator.Direction;
-import androidx.test.uiautomator.UiDevice;
import androidx.test.uiautomator.UiObject2;
-import androidx.test.uiautomator.Until;
+import com.android.launcher3.ResourceUtils;
import com.android.launcher3.testing.TestProtocol;
-import com.android.launcher3.testing.WorkspaceCellCenterRequest;
-import java.util.List;
-import java.util.Map;
-import java.util.function.Supplier;
import java.util.regex.Pattern;
-import java.util.stream.Collectors;
/**
* Operations on the workspace screen.
*/
public final class Workspace extends Home {
private static final int FLING_STEPS = 10;
- private static final int DEFAULT_DRAG_STEPS = 10;
- private static final String DROP_BAR_RES_ID = "drop_target_bar";
- private static final String DELETE_TARGET_TEXT_ID = "delete_target_text";
- private static final String UNINSTALL_TARGET_TEXT_ID = "uninstall_target_text";
static final Pattern EVENT_CTRL_W_DOWN = Pattern.compile(
"Key event: KeyEvent.*?action=ACTION_DOWN.*?keyCode=KEYCODE_W"
@@ -64,7 +51,7 @@ public final class Workspace extends Home {
static final Pattern EVENT_CTRL_W_UP = Pattern.compile(
"Key event: KeyEvent.*?action=ACTION_UP.*?keyCode=KEYCODE_W"
+ ".*?metaState=META_CTRL_ON");
- static final Pattern LONG_CLICK_EVENT = Pattern.compile("onWorkspaceItemLongClick");
+ private static final Pattern LONG_CLICK_EVENT = Pattern.compile("onWorkspaceItemLongClick");
private final UiObject2 mHotseat;
@@ -76,67 +63,56 @@ public final class Workspace extends Home {
/**
* Swipes up to All Apps.
*
- * @return the All Apps object.
+ * @return the App Apps object.
*/
@NonNull
- public HomeAllApps switchToAllApps() {
+ public AllApps switchToAllApps() {
try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck();
LauncherInstrumentation.Closable c =
mLauncher.addContextLayer("want to switch from workspace to all apps")) {
verifyActiveContainer();
final int deviceHeight = mLauncher.getDevice().getDisplayHeight();
- final int bottomGestureMargin = mLauncher.getBottomGestureSize();
+ final int bottomGestureMargin = ResourceUtils.getNavbarSize(
+ ResourceUtils.NAVBAR_BOTTOM_GESTURE_SIZE, mLauncher.getResources());
final int windowCornerRadius = (int) Math.ceil(mLauncher.getWindowCornerRadius());
final int startY = deviceHeight - Math.max(bottomGestureMargin, windowCornerRadius) - 1;
final int swipeHeight = mLauncher.getTestInfo(
- TestProtocol.REQUEST_HOME_TO_ALL_APPS_SWIPE_HEIGHT)
- .getInt(TestProtocol.TEST_INFO_RESPONSE_FIELD);
+ TestProtocol.REQUEST_HOME_TO_ALL_APPS_SWIPE_HEIGHT).
+ getInt(TestProtocol.TEST_INFO_RESPONSE_FIELD);
LauncherInstrumentation.log(
"switchToAllApps: deviceHeight = " + deviceHeight + ", startY = " + startY
+ ", swipeHeight = " + swipeHeight + ", slop = "
+ mLauncher.getTouchSlop());
mLauncher.swipeToState(
- windowCornerRadius,
+ 0,
startY,
- windowCornerRadius,
+ 0,
startY - swipeHeight - mLauncher.getTouchSlop(),
12,
ALL_APPS_STATE_ORDINAL, LauncherInstrumentation.GestureScope.INSIDE);
try (LauncherInstrumentation.Closable c1 = mLauncher.addContextLayer(
"swiped to all apps")) {
- return new HomeAllApps(mLauncher);
+ return new AllApps(mLauncher);
}
}
}
/**
- * Returns the home qsb.
- *
- * The qsb must already be visible when calling this method.
- */
- public HomeQsb getQsb() {
- try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
- "want to get the home qsb")) {
- return new HomeQsb(mLauncher);
- }
- }
-
- /**
* Returns an icon for the app, if currently visible.
*
* @param appName name of the app
* @return app icon, if found, null otherwise.
*/
@Nullable
- public HomeAppIcon tryGetWorkspaceAppIcon(String appName) {
+ public AppIcon tryGetWorkspaceAppIcon(String appName) {
try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
"want to get a workspace icon")) {
final UiObject2 workspace = verifyActiveContainer();
final UiObject2 icon = workspace.findObject(
AppIcon.getAppIconSelector(appName, mLauncher));
- return icon != null ? new WorkspaceAppIcon(mLauncher, icon) : null;
+ return icon != null ? new AppIcon(mLauncher, icon) : null;
}
}
@@ -148,10 +124,10 @@ public final class Workspace extends Home {
* @return app icon.
*/
@NonNull
- public HomeAppIcon getWorkspaceAppIcon(String appName) {
+ public AppIcon getWorkspaceAppIcon(String appName) {
try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
"want to get a workspace icon")) {
- return new WorkspaceAppIcon(mLauncher,
+ return new AppIcon(mLauncher,
mLauncher.waitForObjectInContainer(
verifyActiveContainer(),
AppIcon.getAppIconSelector(appName, mLauncher)));
@@ -168,7 +144,16 @@ public final class Workspace extends Home {
if (!isWorkspaceScrollable(workspace)) {
try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
"dragging icon to a second page of workspace to make it scrollable")) {
- dragIcon(workspace, getHotseatAppIcon("Chrome"), pagesPerScreen());
+ dragIconToWorkspace(
+ mLauncher,
+ getHotseatAppIcon("Chrome"),
+ new Point(mLauncher.getDevice().getDisplayWidth(),
+ mLauncher.getVisibleBounds(workspace).centerY()),
+ "popup_container",
+ false,
+ false,
+ () -> mLauncher.expectEvent(
+ TestProtocol.SEQUENCE_MAIN, LONG_CLICK_EVENT));
verifyActiveContainer();
}
}
@@ -177,283 +162,48 @@ public final class Workspace extends Home {
}
}
- /**
- * Returns the number of pages that are visible on the screen simultaneously.
- */
- public int pagesPerScreen() {
- return mLauncher.isTwoPanels() ? 2 : 1;
- }
-
- /**
- * Drags an icon to the (currentPage + pageDelta) page.
- * If the target page doesn't exist yet, a new page will be created.
- * In case the target page can't be created (e.g. existing pages are 0, 1, current: 0,
- * pageDelta: 3, the latest page that can be created is 2) the icon will be dragged onto the
- * page that can be created and is closest to the target page.
- *
- * @param homeAppIcon - icon to drag.
- * @param pageDelta - how many pages should the icon be dragged from the current page.
- * It can be a negative value. currentPage + pageDelta should be greater
- * than or equal to 0.
- */
- public void dragIcon(HomeAppIcon homeAppIcon, int pageDelta) {
- if (mHotseat.getVisibleBounds().height() > mHotseat.getVisibleBounds().width()) {
- throw new UnsupportedOperationException(
- "dragIcon does NOT support dragging when the hotseat is on the side.");
- }
- try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck()) {
- final UiObject2 workspace = verifyActiveContainer();
- try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
- "dragging icon to page with delta: " + pageDelta)) {
- dragIcon(workspace, homeAppIcon, pageDelta);
- verifyActiveContainer();
- }
- }
- }
-
- private void dragIcon(UiObject2 workspace, HomeAppIcon homeAppIcon, int pageDelta) {
- int pageWidth = mLauncher.getDevice().getDisplayWidth() / pagesPerScreen();
- int targetX = (pageWidth / 2) + pageWidth * pageDelta;
- dragIconToWorkspace(
- mLauncher,
- homeAppIcon,
- new Point(targetX, mLauncher.getVisibleBounds(workspace).centerY()),
- false,
- false,
- () -> mLauncher.expectEvent(
- TestProtocol.SEQUENCE_MAIN, LONG_CLICK_EVENT));
- verifyActiveContainer();
- }
-
private boolean isWorkspaceScrollable(UiObject2 workspace) {
- return workspace.getChildCount() > (mLauncher.isTwoPanels() ? 2 : 1);
+ return workspace.getChildCount() > 1;
}
@NonNull
- public HomeAppIcon getHotseatAppIcon(String appName) {
- return new WorkspaceAppIcon(mLauncher, mLauncher.waitForObjectInContainer(
+ public AppIcon getHotseatAppIcon(String appName) {
+ return new AppIcon(mLauncher, mLauncher.waitForObjectInContainer(
mHotseat, AppIcon.getAppIconSelector(appName, mLauncher)));
}
- /**
- * @return map of text -> center of the view. In case of icons with the same name, the one with
- * lower x coordinate is selected.
- */
- public Map<String, Point> getWorkspaceIconsPositions() {
- final UiObject2 workspace = verifyActiveContainer();
- List<UiObject2> workspaceIcons =
- mLauncher.waitForObjectsInContainer(workspace, AppIcon.getAnyAppIconSelector());
- return workspaceIcons.stream()
- .collect(
- Collectors.toMap(
- /* keyMapper= */ UiObject2::getText,
- /* valueMapper= */ UiObject2::getVisibleCenter,
- /* mergeFunction= */ (p1, p2) -> p1.x < p2.x ? p1 : p2));
- }
- /*
- * Get the center point of the delete/uninstall icon in the drop target bar.
- */
- private static Point getDropPointFromDropTargetBar(
- LauncherInstrumentation launcher, String targetId) {
- return launcher.waitForObjectInContainer(
- launcher.waitForLauncherObject(DROP_BAR_RES_ID),
- targetId).getVisibleCenter();
- }
-
- /**
- * Delete the appIcon from the workspace.
- *
- * @param homeAppIcon to be deleted.
- * @return validated workspace after the existing appIcon being deleted.
- */
- public Workspace deleteAppIcon(HomeAppIcon homeAppIcon) {
- try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck();
- LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
- "removing app icon from workspace")) {
- dragIconToWorkspace(
- mLauncher,
- homeAppIcon,
- () -> getDropPointFromDropTargetBar(mLauncher, DELETE_TARGET_TEXT_ID),
- () -> mLauncher.expectEvent(TestProtocol.SEQUENCE_MAIN, LONG_CLICK_EVENT),
- /* expectDropEvents= */ null);
-
- try (LauncherInstrumentation.Closable c1 = mLauncher.addContextLayer(
- "dragged the app to the drop bar")) {
- return new Workspace(mLauncher);
- }
- }
- }
-
- /**
- * Uninstall the appIcon by dragging it to the 'uninstall' drop point of the drop_target_bar.
- *
- * @param launcher the root TAPL instrumentation object of {@link
- * LauncherInstrumentation} type.
- * @param homeAppIcon to be uninstalled.
- * @param launcher the root TAPL instrumentation object of {@link
- * LauncherInstrumentation} type.
- * @param homeAppIcon to be uninstalled.
- * @param expectLongClickEvents the runnable to be executed to verify expected longclick event.
- * @return validated workspace after the existing appIcon being uninstalled.
- */
- static Workspace uninstallAppIcon(LauncherInstrumentation launcher, HomeAppIcon homeAppIcon,
+ static void dragIconToWorkspace(
+ LauncherInstrumentation launcher, Launchable launchable, Point dest,
+ String longPressIndicator, boolean startsActivity, boolean isWidgetShortcut,
Runnable expectLongClickEvents) {
- try (LauncherInstrumentation.Closable c = launcher.addContextLayer(
- "uninstalling app icon")) {
- dragIconToWorkspace(
- launcher,
- homeAppIcon,
- () -> getDropPointFromDropTargetBar(launcher, UNINSTALL_TARGET_TEXT_ID),
- expectLongClickEvents,
- /* expectDropEvents= */null);
-
- launcher.waitUntilLauncherObjectGone(DROP_BAR_RES_ID);
-
- final BySelector installerAlert = By.text(Pattern.compile(
- "Do you want to uninstall this app\\?",
- Pattern.DOTALL | Pattern.MULTILINE));
- final UiDevice device = launcher.getDevice();
- assertTrue("uninstall alert is not shown", device.wait(
- Until.hasObject(installerAlert), LauncherInstrumentation.WAIT_TIME_MS));
- final UiObject2 ok = device.findObject(By.text("OK"));
- assertNotNull("OK button is not shown", ok);
- launcher.clickObject(ok);
- assertTrue("Uninstall alert is not dismissed after clicking OK", device.wait(
- Until.gone(installerAlert), LauncherInstrumentation.WAIT_TIME_MS));
-
- try (LauncherInstrumentation.Closable c1 = launcher.addContextLayer(
- "uninstalled app by dragging to the drop bar")) {
- return new Workspace(launcher);
- }
- }
- }
-
- /**
- * Get cell layout's grids size. The return point's x and y values are the cell counts in X and
- * Y directions respectively, not the values in pixels.
- */
- public Point getIconGridDimensions() {
- int[] countXY = mLauncher.getTestInfo(
- TestProtocol.REQUEST_WORKSPACE_CELL_LAYOUT_SIZE).getIntArray(
- TestProtocol.TEST_INFO_RESPONSE_FIELD);
- return new Point(countXY[0], countXY[1]);
- }
-
- static Point getCellCenter(LauncherInstrumentation launcher, int cellX, int cellY) {
- return launcher.getTestInfo(WorkspaceCellCenterRequest.builder().setCellX(
- cellX).setCellY(cellY).build()).getParcelable(
- TestProtocol.TEST_INFO_RESPONSE_FIELD);
- }
-
- /**
- * Finds folder icons in the current workspace.
- *
- * @return a list of folder icons.
- */
- List<FolderIcon> getFolderIcons() {
- final UiObject2 workspace = verifyActiveContainer();
- return mLauncher.getObjectsInContainer(workspace, "folder_icon_name").stream().map(
- o -> new FolderIcon(mLauncher, o)).collect(Collectors.toList());
- }
-
- private static void dropDraggedIcon(LauncherInstrumentation launcher, Point dest, long downTime,
- @Nullable Runnable expectedEvents) {
+ LauncherInstrumentation.log("dragIconToWorkspace: begin");
+ final Point launchableCenter = launchable.getObject().getVisibleCenter();
+ final long downTime = SystemClock.uptimeMillis();
+ launcher.runToState(
+ () -> {
+ launcher.sendPointer(downTime, downTime, MotionEvent.ACTION_DOWN,
+ launchableCenter, LauncherInstrumentation.GestureScope.INSIDE);
+ LauncherInstrumentation.log("dragIconToWorkspace: sent down");
+ expectLongClickEvents.run();
+ launcher.waitForLauncherObject(longPressIndicator);
+ LauncherInstrumentation.log("dragIconToWorkspace: indicator");
+ launcher.movePointer(launchableCenter, dest, 10, downTime, true,
+ LauncherInstrumentation.GestureScope.INSIDE);
+ },
+ SPRING_LOADED_STATE_ORDINAL,
+ "long-pressing and moving");
+ LauncherInstrumentation.log("dragIconToWorkspace: moved pointer");
launcher.runToState(
() -> launcher.sendPointer(
downTime, SystemClock.uptimeMillis(), MotionEvent.ACTION_UP, dest,
LauncherInstrumentation.GestureScope.INSIDE),
NORMAL_STATE_ORDINAL,
"sending UP event");
- if (expectedEvents != null) {
- expectedEvents.run();
- }
- LauncherInstrumentation.log("dropIcon: end");
- launcher.waitUntilLauncherObjectGone("drop_target_bar");
- }
-
- static void dragIconToWorkspace(LauncherInstrumentation launcher, Launchable launchable,
- Point dest, boolean startsActivity, boolean isWidgetShortcut,
- Runnable expectLongClickEvents) {
- Runnable expectDropEvents = null;
if (startsActivity || isWidgetShortcut) {
- expectDropEvents = () -> launcher.expectEvent(TestProtocol.SEQUENCE_MAIN,
- LauncherInstrumentation.EVENT_START);
+ launcher.expectEvent(TestProtocol.SEQUENCE_MAIN, LauncherInstrumentation.EVENT_START);
}
- dragIconToWorkspace(
- launcher, launchable, () -> dest, expectLongClickEvents, expectDropEvents);
- }
-
- /**
- * Drag icon in workspace to else where and drop it immediately.
- * (There is no slow down time before drop event)
- * This function expects the launchable is inside the workspace and there is no drop event.
- */
- static void dragIconToWorkspace(
- LauncherInstrumentation launcher, Launchable launchable, Supplier<Point> destSupplier) {
- dragIconToWorkspace(
- launcher,
- launchable,
- destSupplier,
- /* isDecelerating= */ false,
- () -> launcher.expectEvent(TestProtocol.SEQUENCE_MAIN, LONG_CLICK_EVENT),
- /* expectDropEvents= */ null);
- }
-
- static void dragIconToWorkspace(
- LauncherInstrumentation launcher,
- Launchable launchable,
- Supplier<Point> dest,
- Runnable expectLongClickEvents,
- @Nullable Runnable expectDropEvents) {
- dragIconToWorkspace(launcher, launchable, dest, /* isDecelerating */ true,
- expectLongClickEvents, expectDropEvents);
- }
-
- static void dragIconToWorkspace(
- LauncherInstrumentation launcher,
- Launchable launchable,
- Supplier<Point> dest,
- boolean isDecelerating,
- Runnable expectLongClickEvents,
- @Nullable Runnable expectDropEvents) {
- try (LauncherInstrumentation.Closable ignored = launcher.addContextLayer(
- "want to drag icon to workspace")) {
- final long downTime = SystemClock.uptimeMillis();
- Point dragStart = launchable.startDrag(
- downTime,
- expectLongClickEvents,
- /* runToSpringLoadedState= */ true);
- Point targetDest = dest.get();
- int displayX = launcher.getRealDisplaySize().x;
-
- // Since the destination can be on another page, we need to drag to the edge first
- // until we reach the target page
- while (targetDest.x > displayX || targetDest.x < 0) {
- int edgeX = targetDest.x > 0 ? displayX : 0;
- Point screenEdge = new Point(edgeX, targetDest.y);
- Point finalDragStart = dragStart;
- executeAndWaitForPageScroll(launcher,
- () -> launcher.movePointer(finalDragStart, screenEdge, DEFAULT_DRAG_STEPS,
- true, downTime, downTime, true,
- LauncherInstrumentation.GestureScope.INSIDE));
- targetDest.x += displayX * (targetDest.x > 0 ? -1 : 1);
- dragStart = screenEdge;
- }
-
- // targetDest.x is now between 0 and displayX so we found the target page,
- // we just have to put move the icon to the destination and drop it
- launcher.movePointer(dragStart, targetDest, DEFAULT_DRAG_STEPS, isDecelerating,
- downTime, SystemClock.uptimeMillis(), false,
- LauncherInstrumentation.GestureScope.INSIDE);
- dropDraggedIcon(launcher, targetDest, downTime, expectDropEvents);
- }
- }
-
- private static void executeAndWaitForPageScroll(LauncherInstrumentation launcher,
- Runnable command) {
- launcher.executeAndWaitForEvent(command,
- event -> event.getEventType() == TYPE_VIEW_SCROLLED,
- () -> "Page scroll didn't happen", "Scrolling page");
+ LauncherInstrumentation.log("dragIconToWorkspace: end");
+ launcher.waitUntilLauncherObjectGone("drop_target_bar");
}
/**
@@ -532,4 +282,4 @@ public final class Workspace extends Home {
return widget != null ? new Widget(mLauncher, widget) : null;
}
}
-}
+} \ No newline at end of file
diff --git a/tests/tapl/com/android/launcher3/tapl/WorkspaceAppIcon.java b/tests/tapl/com/android/launcher3/tapl/WorkspaceAppIcon.java
deleted file mode 100644
index 114e6a586f..0000000000
--- a/tests/tapl/com/android/launcher3/tapl/WorkspaceAppIcon.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.launcher3.tapl;
-
-import android.graphics.Point;
-
-import androidx.test.uiautomator.UiObject2;
-
-import java.util.regex.Pattern;
-
-/**
- * App icon in workspace.
- */
-final class WorkspaceAppIcon extends HomeAppIcon {
-
- WorkspaceAppIcon(LauncherInstrumentation launcher, UiObject2 icon) {
- super(launcher, icon);
- }
-
- @Override
- protected Pattern getLongClickEvent() {
- return Workspace.LONG_CLICK_EVENT;
- }
-
- boolean isInCell(int cellX, int cellY) {
- final Point center = Workspace.getCellCenter(mLauncher, cellX, cellY);
- return mObject.getParent().getVisibleBounds().contains(center.x, center.y);
- }
-}
diff --git a/tests/tapl/com/android/launcher3/tapl/WorkspaceDragSource.java b/tests/tapl/com/android/launcher3/tapl/WorkspaceDragSource.java
deleted file mode 100644
index d8d4420005..0000000000
--- a/tests/tapl/com/android/launcher3/tapl/WorkspaceDragSource.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.launcher3.tapl;
-
-import android.graphics.Point;
-
-/** Launchable that can serve as a source for dragging and dropping to the workspace. */
-interface WorkspaceDragSource {
-
- /**
- * Drags an object to the center of homescreen.
- *
- * @param startsActivity whether it's expected to start an activity.
- * @param isWidgetShortcut whether we drag a widget shortcut
- */
- default void dragToWorkspace(boolean startsActivity, boolean isWidgetShortcut) {
- Launchable launchable = getLaunchable();
- LauncherInstrumentation launcher = launchable.mLauncher;
- try (LauncherInstrumentation.Closable e = launcher.eventsCheck()) {
- final Point launchableCenter = launchable.getObject().getVisibleCenter();
- final Point displaySize = launcher.getRealDisplaySize();
- final int width = displaySize.x / 2;
- Workspace.dragIconToWorkspace(
- launcher,
- launchable,
- new Point(
- launchableCenter.x >= width
- ? launchableCenter.x - width / 2
- : launchableCenter.x + width / 2,
- displaySize.y / 2),
- startsActivity,
- isWidgetShortcut,
- launchable::addExpectedEventsForLongClick);
- }
- }
-
- /** This method requires public access, however should not be called in tests. */
- Launchable getLaunchable();
-}