diff options
Diffstat (limited to 'libs')
306 files changed, 3065 insertions, 4308 deletions
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java index 2eacaaf28bba..ccf95527efea 100644 --- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java +++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java @@ -98,14 +98,6 @@ public class WindowLayoutComponentImpl implements WindowLayoutComponent { mTaskFragmentOrganizer = taskFragmentOrganizer; } - /** Registers to listen to {@link CommonFoldingFeature} changes */ - public void addFoldingStateChangedCallback( - java.util.function.Consumer<List<CommonFoldingFeature>> consumer) { - synchronized (mLock) { - mFoldingFeatureProducer.addDataChangedCallback(consumer); - } - } - /** * Adds a listener interested in receiving updates to {@link WindowLayoutInfo} * diff --git a/libs/WindowManager/Shell/res/values-am/strings.xml b/libs/WindowManager/Shell/res/values-am/strings.xml index 21172e2267bc..9cb4435c82f3 100644 --- a/libs/WindowManager/Shell/res/values-am/strings.xml +++ b/libs/WindowManager/Shell/res/values-am/strings.xml @@ -32,23 +32,23 @@ <string name="accessibility_action_pip_resize" msgid="4623966104749543182">"መጠን ይቀይሩ"</string> <string name="accessibility_action_pip_stash" msgid="4060775037619702641">"Stash"</string> <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Unstash"</string> - <string name="dock_forced_resizable" msgid="7429086980048964687">"መተግበሪያ ከተከፈለ ማያ ገጽ ጋር ላይሠራ ይችላል"</string> + <string name="dock_forced_resizable" msgid="7429086980048964687">"መተግበሪያ ከተከፈለ ማያ ገፅ ጋር ላይሠራ ይችላል"</string> <string name="dock_non_resizeble_failed_to_dock_text" msgid="2733543750291266047">"መተግበሪያው የተከፈለ ማያ ገጽን አይደግፍም"</string> <string name="dock_multi_instances_not_supported_text" msgid="5242868470666346929">"ይህ መተግበሪያ መከፈት የሚችለው በ1 መስኮት ብቻ ነው።"</string> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"መተግበሪያ በሁለተኛ ማሳያ ላይ ላይሠራ ይችላል።"</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"መተግበሪያ በሁለተኛ ማሳያዎች ላይ ማስጀመርን አይደግፍም።"</string> - <string name="accessibility_divider" msgid="6407584574218956849">"የተከፈለ የማያ ገጽ ከፋይ"</string> - <string name="divider_title" msgid="1963391955593749442">"የተከፈለ የማያ ገጽ ከፋይ"</string> - <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"የግራ ሙሉ ማያ ገጽ"</string> + <string name="accessibility_divider" msgid="6407584574218956849">"የተከፈለ የማያ ገፅ ከፋይ"</string> + <string name="divider_title" msgid="1963391955593749442">"የተከፈለ የማያ ገፅ ከፋይ"</string> + <string name="accessibility_action_divider_left_full" msgid="1792313656305328536">"የግራ ሙሉ ማያ ገፅ"</string> <string name="accessibility_action_divider_left_70" msgid="8859845045360659250">"ግራ 70%"</string> <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"ግራ 50%"</string> <string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"ግራ 30%"</string> - <string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"የቀኝ ሙሉ ማያ ገጽ"</string> - <string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"የላይ ሙሉ ማያ ገጽ"</string> + <string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"የቀኝ ሙሉ ማያ ገፅ"</string> + <string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"የላይ ሙሉ ማያ ገፅ"</string> <string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"ከላይ 70%"</string> <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"ከላይ 50%"</string> <string name="accessibility_action_divider_top_30" msgid="3572788224908570257">"ከላይ 30%"</string> - <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"የታች ሙሉ ማያ ገጽ"</string> + <string name="accessibility_action_divider_bottom_full" msgid="2831868345092314060">"የታች ሙሉ ማያ ገፅ"</string> <string name="accessibility_split_left" msgid="1713683765575562458">"ወደ ግራ ከፋፍል"</string> <string name="accessibility_split_right" msgid="8441001008181296837">"ወደ ቀኝ ከፋፍል"</string> <string name="accessibility_split_top" msgid="2789329702027147146">"ወደ ላይ ከፋፍል"</string> @@ -84,7 +84,7 @@ <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"አልተስተካከለም?\nለማህደር መታ ያድርጉ"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"ምንም የካሜራ ችግሮች የሉም? ለማሰናበት መታ ያድርጉ።"</string> <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"ተጨማሪ ይመልከቱ እና ያድርጉ"</string> - <string name="letterbox_education_split_screen_text" msgid="449233070804658627">"ለተከፈለ ማያ ገጽ ሌላ መተግበሪያ ይጎትቱ"</string> + <string name="letterbox_education_split_screen_text" msgid="449233070804658627">"ለተከፈለ ማያ ገፅ ሌላ መተግበሪያ ይጎትቱ"</string> <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"ቦታውን ለመቀየር ከመተግበሪያው ውጪ ሁለቴ መታ ያድርጉ"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"ገባኝ"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"ለተጨማሪ መረጃ ይዘርጉ።"</string> @@ -102,11 +102,11 @@ <string name="app_icon_text" msgid="2823268023931811747">"የመተግበሪያ አዶ"</string> <string name="fullscreen_text" msgid="1162316685217676079">"ሙሉ ማያ"</string> <string name="desktop_text" msgid="1077633567027630454">"የዴስክቶፕ ሁነታ"</string> - <string name="split_screen_text" msgid="1396336058129570886">"የተከፈለ ማያ ገጽ"</string> + <string name="split_screen_text" msgid="1396336058129570886">"የተከፈለ ማያ ገፅ"</string> <string name="more_button_text" msgid="3655388105592893530">"ተጨማሪ"</string> <string name="float_button_text" msgid="9221657008391364581">"ተንሳፋፊ"</string> <string name="select_text" msgid="5139083974039906583">"ምረጥ"</string> - <string name="screenshot_text" msgid="1477704010087786671">"ቅጽበታዊ ገጽ እይታ"</string> + <string name="screenshot_text" msgid="1477704010087786671">"ቅጽበታዊ ገፅ እይታ"</string> <string name="close_text" msgid="4986518933445178928">"ዝጋ"</string> <string name="collapse_menu_text" msgid="7515008122450342029">"ምናሌ ዝጋ"</string> <string name="expand_menu_text" msgid="3847736164494181168">"ምናሌን ክፈት"</string> diff --git a/libs/WindowManager/Shell/res/values-am/strings_tv.xml b/libs/WindowManager/Shell/res/values-am/strings_tv.xml index a6be57889a4e..84c1c6763d43 100644 --- a/libs/WindowManager/Shell/res/values-am/strings_tv.xml +++ b/libs/WindowManager/Shell/res/values-am/strings_tv.xml @@ -20,7 +20,7 @@ <string name="notification_channel_tv_pip" msgid="2576686079160402435">"ሥዕል-ላይ-ሥዕል"</string> <string name="pip_notification_unknown_title" msgid="2729870284350772311">"(ርዕስ የሌለው ፕሮግራም)"</string> <string name="pip_close" msgid="2955969519031223530">"ዝጋ"</string> - <string name="pip_fullscreen" msgid="7278047353591302554">"ሙሉ ማያ ገጽ"</string> + <string name="pip_fullscreen" msgid="7278047353591302554">"ሙሉ ማያ ገፅ"</string> <string name="pip_move" msgid="158770205886688553">"ውሰድ"</string> <string name="pip_expand" msgid="1051966011679297308">"ዘርጋ"</string> <string name="pip_collapse" msgid="3903295106641385962">"ሰብስብ"</string> diff --git a/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml b/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml index 8de9d11def2b..c415c868ac04 100644 --- a/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml +++ b/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml @@ -89,7 +89,7 @@ <string name="letterbox_education_got_it" msgid="4057634570866051177">"Važi"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Proširite za još informacija."</string> <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"Želite li da restartujete radi boljeg prikaza?"</string> - <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"Možete da restartujete aplikaciju da bi izgledala bolje na ekranu, s tim što možete da izgubite ono što ste uradili ili nesačuvane promene, ako ih ima"</string> + <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"Možete da restartujete aplikaciju da bi izgledala bolje na ekranu, ali možete da izgubite napredak ili nesačuvane promene"</string> <string name="letterbox_restart_cancel" msgid="1342209132692537805">"Otkaži"</string> <string name="letterbox_restart_restart" msgid="8529976234412442973">"Restartuj"</string> <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Ne prikazuj ponovo"</string> diff --git a/libs/WindowManager/Shell/res/values-cs/strings.xml b/libs/WindowManager/Shell/res/values-cs/strings.xml index 70e29705806f..ac22b8569e16 100644 --- a/libs/WindowManager/Shell/res/values-cs/strings.xml +++ b/libs/WindowManager/Shell/res/values-cs/strings.xml @@ -79,7 +79,7 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Bublina"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Spravovat"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Bublina byla zavřena."</string> - <string name="restart_button_description" msgid="6712141648865547958">"Klepnutím tuto aplikaci kvůli lepšímu zobrazení restartujete."</string> + <string name="restart_button_description" msgid="6712141648865547958">"Pokud je problém se zobrazením aplikace, klepněte na ni a restartujte ji."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Problémy s fotoaparátem?\nKlepnutím vyřešíte"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Nepomohlo to?\nKlepnutím se vrátíte"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Žádné problémy s fotoaparátem? Klepnutím zavřete."</string> diff --git a/libs/WindowManager/Shell/res/values-de/strings.xml b/libs/WindowManager/Shell/res/values-de/strings.xml index 6ce475aa3c84..c17f97fbad0f 100644 --- a/libs/WindowManager/Shell/res/values-de/strings.xml +++ b/libs/WindowManager/Shell/res/values-de/strings.xml @@ -20,7 +20,7 @@ <string name="pip_phone_close" msgid="5783752637260411309">"Schließen"</string> <string name="pip_phone_expand" msgid="2579292903468287504">"Maximieren"</string> <string name="pip_phone_settings" msgid="5468987116750491918">"Einstellungen"</string> - <string name="pip_phone_enter_split" msgid="7042877263880641911">"„Geteilter Bildschirm“ aktivieren"</string> + <string name="pip_phone_enter_split" msgid="7042877263880641911">"Splitscreen aktivieren"</string> <string name="pip_menu_title" msgid="5393619322111827096">"Menü"</string> <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Menü „Bild im Bild“"</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> ist in Bild im Bild"</string> @@ -32,8 +32,8 @@ <string name="accessibility_action_pip_resize" msgid="4623966104749543182">"Größe anpassen"</string> <string name="accessibility_action_pip_stash" msgid="4060775037619702641">"In Stash legen"</string> <string name="accessibility_action_pip_unstash" msgid="7467499339610437646">"Aus Stash entfernen"</string> - <string name="dock_forced_resizable" msgid="7429086980048964687">"Die App funktioniert bei geteiltem Bildschirm unter Umständen nicht"</string> - <string name="dock_non_resizeble_failed_to_dock_text" msgid="2733543750291266047">"„Geteilter Bildschirm“ wird in dieser App nicht unterstützt"</string> + <string name="dock_forced_resizable" msgid="7429086980048964687">"Die App funktioniert im Splitscreen-Modus unter Umständen nicht"</string> + <string name="dock_non_resizeble_failed_to_dock_text" msgid="2733543750291266047">"Splitscreen wird in dieser App nicht unterstützt"</string> <string name="dock_multi_instances_not_supported_text" msgid="5242868470666346929">"Diese App kann nur in einem einzigen Fenster geöffnet werden."</string> <string name="forced_resizable_secondary_display" msgid="1768046938673582671">"Die App funktioniert auf einem sekundären Display möglicherweise nicht."</string> <string name="activity_launch_on_secondary_display_failed_text" msgid="4226485344988071769">"Die App unterstützt den Start auf sekundären Displays nicht."</string> @@ -84,7 +84,7 @@ <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Das Problem ist nicht behoben?\nZum Rückgängigmachen tippen."</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Keine Probleme mit der Kamera? Zum Schließen tippen."</string> <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Mehr sehen und erledigen"</string> - <string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Weitere App hineinziehen, um den Bildschirm zu teilen"</string> + <string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Für Splitscreen-Modus weitere App hineinziehen"</string> <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Außerhalb einer App doppeltippen, um die Position zu ändern"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"Ok"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Für weitere Informationen maximieren."</string> @@ -102,13 +102,12 @@ <string name="app_icon_text" msgid="2823268023931811747">"App-Symbol"</string> <string name="fullscreen_text" msgid="1162316685217676079">"Vollbild"</string> <string name="desktop_text" msgid="1077633567027630454">"Desktopmodus"</string> - <string name="split_screen_text" msgid="1396336058129570886">"Geteilter Bildschirm"</string> + <string name="split_screen_text" msgid="1396336058129570886">"Splitscreen"</string> <string name="more_button_text" msgid="3655388105592893530">"Mehr"</string> <string name="float_button_text" msgid="9221657008391364581">"Frei schwebend"</string> <string name="select_text" msgid="5139083974039906583">"Auswählen"</string> <string name="screenshot_text" msgid="1477704010087786671">"Screenshot"</string> <string name="close_text" msgid="4986518933445178928">"Schließen"</string> <string name="collapse_menu_text" msgid="7515008122450342029">"Menü schließen"</string> - <!-- no translation found for expand_menu_text (3847736164494181168) --> - <skip /> + <string name="expand_menu_text" msgid="3847736164494181168">"Menü öffnen"</string> </resources> diff --git a/libs/WindowManager/Shell/res/values-es/strings.xml b/libs/WindowManager/Shell/res/values-es/strings.xml index ea44bead6766..9c5e0c48f6cb 100644 --- a/libs/WindowManager/Shell/res/values-es/strings.xml +++ b/libs/WindowManager/Shell/res/values-es/strings.xml @@ -79,7 +79,7 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Burbuja"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Gestionar"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Burbuja cerrada."</string> - <string name="restart_button_description" msgid="6712141648865547958">"Toca para reiniciar esta aplicación y obtener una mejor vista."</string> + <string name="restart_button_description" msgid="6712141648865547958">"Toca para reiniciar esta aplicación y verlo mejor."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"¿Problemas con la cámara?\nToca para reajustar"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"¿No se ha solucionado?\nToca para revertir"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"¿No hay problemas con la cámara? Toca para cerrar."</string> diff --git a/libs/WindowManager/Shell/res/values-et/strings.xml b/libs/WindowManager/Shell/res/values-et/strings.xml index 90feff32cc2b..fb23d11ef74a 100644 --- a/libs/WindowManager/Shell/res/values-et/strings.xml +++ b/libs/WindowManager/Shell/res/values-et/strings.xml @@ -89,7 +89,7 @@ <string name="letterbox_education_got_it" msgid="4057634570866051177">"Selge"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Laiendage lisateabe saamiseks."</string> <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"Kas taaskäivitada parema vaate saavutamiseks?"</string> - <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"Saate rakenduse taaskäivitada, et see näeks ekraanikuval parem välja, kuid võite kaotada edenemise või salvestamata muudatused"</string> + <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"Saate rakenduse taaskäivitada, et see näeks ekraanikuval parem välja, kuid võite kaotada edenemise või salvestamata muudatused."</string> <string name="letterbox_restart_cancel" msgid="1342209132692537805">"Tühista"</string> <string name="letterbox_restart_restart" msgid="8529976234412442973">"Taaskäivita"</string> <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Ära kuva uuesti"</string> diff --git a/libs/WindowManager/Shell/res/values-fa/strings.xml b/libs/WindowManager/Shell/res/values-fa/strings.xml index 13a2ea2db140..edff47a0be1a 100644 --- a/libs/WindowManager/Shell/res/values-fa/strings.xml +++ b/libs/WindowManager/Shell/res/values-fa/strings.xml @@ -59,7 +59,7 @@ <string name="accessibility_action_stop_one_handed" msgid="1369940261782179442">"خروج از «حالت یکدستی»"</string> <string name="bubbles_settings_button_description" msgid="1301286017420516912">"تنظیمات برای حبابکهای <xliff:g id="APP_NAME">%1$s</xliff:g>"</string> <string name="bubble_overflow_button_content_description" msgid="8160974472718594382">"سرریز"</string> - <string name="bubble_accessibility_action_add_back" msgid="1830101076853540953">"افزودن برگشت به پشته"</string> + <string name="bubble_accessibility_action_add_back" msgid="1830101076853540953">"افزودن برگشتن به پشته"</string> <string name="bubble_content_description_single" msgid="8495748092720065813">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> از <xliff:g id="APP_NAME">%2$s</xliff:g>"</string> <string name="bubble_content_description_stack" msgid="8071515017164630429">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> از <xliff:g id="APP_NAME">%2$s</xliff:g> و <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g> مورد بیشتر"</string> <string name="bubble_accessibility_action_move_top_left" msgid="2644118920500782758">"انتقال به بالا سمت راست"</string> diff --git a/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml b/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml index 7814b7d38fed..6d19e55217f6 100644 --- a/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml +++ b/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml @@ -79,7 +79,7 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Bulle"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Gérer"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Bulle ignorée."</string> - <string name="restart_button_description" msgid="6712141648865547958">"Touchez pour redémarrer cette application afin d\'obtenir un meilleur affichage."</string> + <string name="restart_button_description" msgid="6712141648865547958">"Pour obtenir un meilleur affichage, touchez pour redémarrer cette application."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Problèmes d\'appareil photo?\nTouchez pour réajuster"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Problème non résolu?\nTouchez pour rétablir"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Aucun problème d\'appareil photo? Touchez pour ignorer."</string> diff --git a/libs/WindowManager/Shell/res/values-fr/strings.xml b/libs/WindowManager/Shell/res/values-fr/strings.xml index da5b5c9bfeba..5fb91f7b6948 100644 --- a/libs/WindowManager/Shell/res/values-fr/strings.xml +++ b/libs/WindowManager/Shell/res/values-fr/strings.xml @@ -79,7 +79,7 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Bulle"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Gérer"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Bulle fermée."</string> - <string name="restart_button_description" msgid="6712141648865547958">"Appuyez pour redémarrer cette appli et avoir une meilleure vue."</string> + <string name="restart_button_description" msgid="6712141648865547958">"Pour un meilleur affichage, appuyez pour redémarrer cette appli."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Problèmes d\'appareil photo ?\nAppuyez pour réajuster"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Problème non résolu ?\nAppuyez pour rétablir"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Aucun problème d\'appareil photo ? Appuyez pour ignorer."</string> @@ -89,7 +89,7 @@ <string name="letterbox_education_got_it" msgid="4057634570866051177">"OK"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Développez pour obtenir plus d\'informations"</string> <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"Redémarrer pour améliorer l\'affichage ?"</string> - <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"Vous pouvez redémarrer l\'appli pour en améliorer son aspect sur votre écran, mais vous risquez de perdre votre progression ou les modifications non enregistrées"</string> + <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"Vous pouvez redémarrer l\'appli pour un meilleur rendu sur votre écran, mais il se peut que vous perdiez votre progression ou les modifications non enregistrées"</string> <string name="letterbox_restart_cancel" msgid="1342209132692537805">"Annuler"</string> <string name="letterbox_restart_restart" msgid="8529976234412442973">"Redémarrer"</string> <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Ne plus afficher"</string> diff --git a/libs/WindowManager/Shell/res/values-hi/strings.xml b/libs/WindowManager/Shell/res/values-hi/strings.xml index fb5040b36a89..b0b0e9c6f5bc 100644 --- a/libs/WindowManager/Shell/res/values-hi/strings.xml +++ b/libs/WindowManager/Shell/res/values-hi/strings.xml @@ -89,7 +89,7 @@ <string name="letterbox_education_got_it" msgid="4057634570866051177">"ठीक है"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"ज़्यादा जानकारी के लिए बड़ा करें."</string> <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"बेहतर व्यू पाने के लिए ऐप्लिकेशन को रीस्टार्ट करना है?"</string> - <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"स्क्रीन पर ऐप्लिकेशन का बेहतर व्यू पाने के लिए उसे रीस्टार्ट करें. हालांकि, आपने जो बदलाव सेव नहीं किए हैं या अब तक जो काम किए हैं उनका डेटा, ऐप्लिकेशन रीस्टार्ट करने पर मिट सकता है"</string> + <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"स्क्रीन पर ऐप्लिकेशन का बेहतर व्यू पाने के लिए उसे रीस्टार्ट करें. हालांकि, इससे अब तक किया गया काम और सेव न किए गए बदलाव मिट सकते हैं"</string> <string name="letterbox_restart_cancel" msgid="1342209132692537805">"रद्द करें"</string> <string name="letterbox_restart_restart" msgid="8529976234412442973">"रीस्टार्ट करें"</string> <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"फिर से न दिखाएं"</string> diff --git a/libs/WindowManager/Shell/res/values-hr/strings.xml b/libs/WindowManager/Shell/res/values-hr/strings.xml index 2535657c7d86..08721f0e6746 100644 --- a/libs/WindowManager/Shell/res/values-hr/strings.xml +++ b/libs/WindowManager/Shell/res/values-hr/strings.xml @@ -79,7 +79,7 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Oblačić"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Upravljanje"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Oblačić odbačen."</string> - <string name="restart_button_description" msgid="6712141648865547958">"Dodirnite da biste ponovo pokrenuli tu aplikaciju kako biste bolje vidjeli."</string> + <string name="restart_button_description" msgid="6712141648865547958">"Dodirnite za ponovno pokretanje te aplikacije i bolji prikaz."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Problemi s fotoaparatom?\nDodirnite za popravak"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Problem nije riješen?\nDodirnite za vraćanje"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Nemate problema s fotoaparatom? Dodirnite za odbacivanje."</string> diff --git a/libs/WindowManager/Shell/res/values-in/strings.xml b/libs/WindowManager/Shell/res/values-in/strings.xml index 5747deb405ab..3f6d9c551aa6 100644 --- a/libs/WindowManager/Shell/res/values-in/strings.xml +++ b/libs/WindowManager/Shell/res/values-in/strings.xml @@ -88,7 +88,7 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"Ketuk dua kali di luar aplikasi untuk mengubah posisinya"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"Oke"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Luaskan untuk melihat informasi selengkapnya."</string> - <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"Mulai ulang untuk tampilan yang lebih baik?"</string> + <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"Mulai ulang untuk melihat tampilan yang lebih baik?"</string> <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"Anda dapat memulai ulang aplikasi agar terlihat lebih baik di layar, tetapi Anda mungkin kehilangan progres atau perubahan yang belum disimpan"</string> <string name="letterbox_restart_cancel" msgid="1342209132692537805">"Batal"</string> <string name="letterbox_restart_restart" msgid="8529976234412442973">"Mulai ulang"</string> diff --git a/libs/WindowManager/Shell/res/values-is/strings.xml b/libs/WindowManager/Shell/res/values-is/strings.xml index 145d26d35b75..20c16be3eaca 100644 --- a/libs/WindowManager/Shell/res/values-is/strings.xml +++ b/libs/WindowManager/Shell/res/values-is/strings.xml @@ -79,7 +79,7 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Blaðra"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Stjórna"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Blöðru lokað."</string> - <string name="restart_button_description" msgid="6712141648865547958">"Ýta til að endurræsa forritið og fá betri sýn."</string> + <string name="restart_button_description" msgid="6712141648865547958">"Ýttu til að endurræsa forritið og fá betri sýn."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Myndavélavesen?\nÝttu til að breyta stærð"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Ennþá vesen?\nÝttu til að afturkalla"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Ekkert myndavélavesen? Ýttu til að hunsa."</string> diff --git a/libs/WindowManager/Shell/res/values-ja/strings.xml b/libs/WindowManager/Shell/res/values-ja/strings.xml index 6c1bafee9d82..8f2f6d8e882f 100644 --- a/libs/WindowManager/Shell/res/values-ja/strings.xml +++ b/libs/WindowManager/Shell/res/values-ja/strings.xml @@ -54,7 +54,7 @@ <string name="accessibility_split_top" msgid="2789329702027147146">"上に分割"</string> <string name="accessibility_split_bottom" msgid="8694551025220868191">"下に分割"</string> <string name="one_handed_tutorial_title" msgid="4583241688067426350">"片手モードの使用"</string> - <string name="one_handed_tutorial_description" msgid="3486582858591353067">"終了するには、画面を下から上にスワイプするか、アプリの任意の場所をタップします"</string> + <string name="one_handed_tutorial_description" msgid="3486582858591353067">"終了するには、画面を下から上にスワイプするか、アプリの上側の任意の場所をタップします"</string> <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"片手モードを開始します"</string> <string name="accessibility_action_stop_one_handed" msgid="1369940261782179442">"片手モードを終了します"</string> <string name="bubbles_settings_button_description" msgid="1301286017420516912">"<xliff:g id="APP_NAME">%1$s</xliff:g> のバブルの設定"</string> @@ -79,7 +79,7 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"バブル"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"管理"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"ふきだしが非表示になっています。"</string> - <string name="restart_button_description" msgid="6712141648865547958">"タップしてこのアプリを再起動すると、表示が適切になります。"</string> + <string name="restart_button_description" msgid="6712141648865547958">"タップしてこのアプリを再起動すると、より見やすく表示されます。"</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"カメラに関する問題の場合は、\nタップすると修正できます"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"修正されなかった場合は、\nタップすると元に戻ります"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"カメラに関する問題でない場合は、タップすると閉じます。"</string> diff --git a/libs/WindowManager/Shell/res/values-kk/strings.xml b/libs/WindowManager/Shell/res/values-kk/strings.xml index 7c9120e22b30..c40cd2fb24aa 100644 --- a/libs/WindowManager/Shell/res/values-kk/strings.xml +++ b/libs/WindowManager/Shell/res/values-kk/strings.xml @@ -79,7 +79,7 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Көпіршік"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Басқару"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Қалқыма хабар жабылды."</string> - <string name="restart_button_description" msgid="6712141648865547958">"Ыңғайлы көріністі реттеу үшін қолданбаны түртіп, өшіріп қосыңыз."</string> + <string name="restart_button_description" msgid="6712141648865547958">"Түртсеңіз, қолданба жабылып, ыңғайлы көрініспен қайта ашылады."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Камерада қателер шықты ма?\nЖөндеу үшін түртіңіз."</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Жөнделмеді ме?\nҚайтару үшін түртіңіз."</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Камерада қателер шықпады ма? Жабу үшін түртіңіз."</string> diff --git a/libs/WindowManager/Shell/res/values-ko/strings.xml b/libs/WindowManager/Shell/res/values-ko/strings.xml index 39d717dd461a..55697ca23a86 100644 --- a/libs/WindowManager/Shell/res/values-ko/strings.xml +++ b/libs/WindowManager/Shell/res/values-ko/strings.xml @@ -79,7 +79,7 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"버블"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"관리"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"대화창을 닫았습니다."</string> - <string name="restart_button_description" msgid="6712141648865547958">"보기를 개선하려면 탭하여 앱을 다시 시작합니다."</string> + <string name="restart_button_description" msgid="6712141648865547958">"더 편하게 보기를 원하면 탭하여 앱을 다시 시작하세요."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"카메라 문제가 있나요?\n해결하려면 탭하세요."</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"해결되지 않았나요?\n되돌리려면 탭하세요."</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"카메라에 문제가 없나요? 닫으려면 탭하세요."</string> diff --git a/libs/WindowManager/Shell/res/values-ky/strings.xml b/libs/WindowManager/Shell/res/values-ky/strings.xml index f210ea29da00..19df267e1d27 100644 --- a/libs/WindowManager/Shell/res/values-ky/strings.xml +++ b/libs/WindowManager/Shell/res/values-ky/strings.xml @@ -24,7 +24,7 @@ <string name="pip_menu_title" msgid="5393619322111827096">"Меню"</string> <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"Сүрөт ичиндеги сүрөт менюсу"</string> <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> – сүрөт ичиндеги сүрөт"</string> - <string name="pip_notification_message" msgid="8854051911700302620">"Эгер <xliff:g id="NAME">%s</xliff:g> колдонмосу бул функцияны пайдаланбасын десеңиз, жөндөөлөрдү ачып туруп, аны өчүрүп коюңуз."</string> + <string name="pip_notification_message" msgid="8854051911700302620">"Эгер <xliff:g id="NAME">%s</xliff:g> колдонмосу бул функцияны пайдаланбасын десеңиз, параметрлерди ачып туруп, аны өчүрүп коюңуз."</string> <string name="pip_play" msgid="3496151081459417097">"Ойнотуу"</string> <string name="pip_pause" msgid="690688849510295232">"Тындыруу"</string> <string name="pip_skip_to_next" msgid="8403429188794867653">"Кийинкисине өткөрүп жиберүү"</string> diff --git a/libs/WindowManager/Shell/res/values-mk/strings.xml b/libs/WindowManager/Shell/res/values-mk/strings.xml index 427433c7f2d4..1567d61d833f 100644 --- a/libs/WindowManager/Shell/res/values-mk/strings.xml +++ b/libs/WindowManager/Shell/res/values-mk/strings.xml @@ -79,7 +79,7 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Балонче"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Управувајте"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Балончето е отфрлено."</string> - <string name="restart_button_description" msgid="6712141648865547958">"Допрете за да ја рестартирате апликацијава за подобар приказ."</string> + <string name="restart_button_description" msgid="6712141648865547958">"За подобар приказ, допрете за да ја рестартирате апликацијава."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Проблеми со камерата?\nДопрете за да се совпадне повторно"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Не се поправи?\nДопрете за враќање"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Нема проблеми со камерата? Допрете за отфрлање."</string> diff --git a/libs/WindowManager/Shell/res/values-or/strings.xml b/libs/WindowManager/Shell/res/values-or/strings.xml index e4c70537c452..267b8a38a6d7 100644 --- a/libs/WindowManager/Shell/res/values-or/strings.xml +++ b/libs/WindowManager/Shell/res/values-or/strings.xml @@ -26,7 +26,7 @@ <string name="pip_notification_title" msgid="1347104727641353453">"<xliff:g id="NAME">%s</xliff:g> \"ଛବି-ଭିତରେ-ଛବି\"ରେ ଅଛି"</string> <string name="pip_notification_message" msgid="8854051911700302620">"ଏହି ବୈଶିଷ୍ଟ୍ୟ <xliff:g id="NAME">%s</xliff:g> ବ୍ୟବହାର ନକରିବାକୁ ଯଦି ଆପଣ ଚାହାଁନ୍ତି, ସେଟିଙ୍ଗ ଖୋଲିବାକୁ ଟାପ୍ କରନ୍ତୁ ଏବଂ ଏହା ଅଫ୍ କରିଦିଅନ୍ତୁ।"</string> <string name="pip_play" msgid="3496151081459417097">"ପ୍ଲେ କରନ୍ତୁ"</string> - <string name="pip_pause" msgid="690688849510295232">"ପଜ୍ କରନ୍ତୁ"</string> + <string name="pip_pause" msgid="690688849510295232">"ବିରତ କରନ୍ତୁ"</string> <string name="pip_skip_to_next" msgid="8403429188794867653">"ପରବର୍ତ୍ତୀକୁ ଯାଆନ୍ତୁ"</string> <string name="pip_skip_to_prev" msgid="7172158111196394092">"ପୂର୍ବବର୍ତ୍ତୀକୁ ଛାଡ଼ନ୍ତୁ"</string> <string name="accessibility_action_pip_resize" msgid="4623966104749543182">"ରିସାଇଜ୍ କରନ୍ତୁ"</string> diff --git a/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml b/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml index ed0cdb61dacf..04ee54046439 100644 --- a/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml +++ b/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml @@ -79,7 +79,7 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Balão"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Gerir"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Balão ignorado."</string> - <string name="restart_button_description" msgid="6712141648865547958">"Toque para reiniciar esta app e ficar com uma melhor visão."</string> + <string name="restart_button_description" msgid="6712141648865547958">"Toque para reiniciar esta app e ver melhor."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Problemas com a câmara?\nToque aqui para reajustar"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Não foi corrigido?\nToque para reverter"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Nenhum problema com a câmara? Toque para ignorar."</string> diff --git a/libs/WindowManager/Shell/res/values-ro/strings.xml b/libs/WindowManager/Shell/res/values-ro/strings.xml index 8a64b1686543..58ad60a87982 100644 --- a/libs/WindowManager/Shell/res/values-ro/strings.xml +++ b/libs/WindowManager/Shell/res/values-ro/strings.xml @@ -79,7 +79,7 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Balon"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Gestionează"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Balonul a fost respins."</string> - <string name="restart_button_description" msgid="6712141648865547958">"Atinge ca să repornești aplicația pentru o vizualizare mai bună."</string> + <string name="restart_button_description" msgid="6712141648865547958">"Atinge ca să repornești aplicația pentru o afișare mai bună."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Ai probleme cu camera foto?\nAtinge pentru a reîncadra"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Nu ai remediat problema?\nAtinge pentru a reveni"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Nu ai probleme cu camera foto? Atinge pentru a închide."</string> diff --git a/libs/WindowManager/Shell/res/values-sr/strings.xml b/libs/WindowManager/Shell/res/values-sr/strings.xml index 307efc9d6a2e..85798cf9f784 100644 --- a/libs/WindowManager/Shell/res/values-sr/strings.xml +++ b/libs/WindowManager/Shell/res/values-sr/strings.xml @@ -89,7 +89,7 @@ <string name="letterbox_education_got_it" msgid="4057634570866051177">"Важи"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"Проширите за још информација."</string> <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"Желите ли да рестартујете ради бољег приказа?"</string> - <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"Можете да рестартујете апликацију да би изгледала боље на екрану, с тим што можете да изгубите оно што сте урадили или несачуване промене, ако их има"</string> + <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"Можете да рестартујете апликацију да би изгледала боље на екрану, али можете да изгубите напредак или несачуване промене"</string> <string name="letterbox_restart_cancel" msgid="1342209132692537805">"Откажи"</string> <string name="letterbox_restart_restart" msgid="8529976234412442973">"Рестартуј"</string> <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"Не приказуј поново"</string> diff --git a/libs/WindowManager/Shell/res/values-ta/strings.xml b/libs/WindowManager/Shell/res/values-ta/strings.xml index fd5f0e646d9b..5bb4c27ed6c7 100644 --- a/libs/WindowManager/Shell/res/values-ta/strings.xml +++ b/libs/WindowManager/Shell/res/values-ta/strings.xml @@ -79,7 +79,7 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"பபிள்"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"நிர்வகி"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"குமிழ் நிராகரிக்கப்பட்டது."</string> - <string name="restart_button_description" msgid="6712141648865547958">"இங்கு தட்டுவதன் மூலம் இந்த ஆப்ஸை மீண்டும் தொடங்கி, ஆப்ஸ் காட்டப்படும் விதத்தை இன்னும் சிறப்பாக்கலாம்."</string> + <string name="restart_button_description" msgid="6712141648865547958">"இங்கு தட்டி ஆப்ஸை மீண்டும் தொடங்கி, ஆப்ஸ் காட்சியை இன்னும் சிறப்பாக்கலாம்."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"கேமரா தொடர்பான சிக்கல்களா?\nமீண்டும் பொருத்த தட்டவும்"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"சிக்கல்கள் சரிசெய்யப்படவில்லையா?\nமாற்றியமைக்க தட்டவும்"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"கேமரா தொடர்பான சிக்கல்கள் எதுவும் இல்லையா? நிராகரிக்க தட்டவும்."</string> diff --git a/libs/WindowManager/Shell/res/values-vi/strings.xml b/libs/WindowManager/Shell/res/values-vi/strings.xml index 7d974005dd31..0281c1c8c396 100644 --- a/libs/WindowManager/Shell/res/values-vi/strings.xml +++ b/libs/WindowManager/Shell/res/values-vi/strings.xml @@ -79,7 +79,7 @@ <string name="notification_bubble_title" msgid="6082910224488253378">"Bong bóng"</string> <string name="manage_bubbles_text" msgid="7730624269650594419">"Quản lý"</string> <string name="accessibility_bubble_dismissed" msgid="8367471990421247357">"Đã đóng bong bóng."</string> - <string name="restart_button_description" msgid="6712141648865547958">"Nhấn để khởi động lại ứng dụng này để xem tốt hơn."</string> + <string name="restart_button_description" msgid="6712141648865547958">"Nhấn để khởi động lại ứng dụng để có trải nghiệm xem tốt hơn."</string> <string name="camera_compat_treatment_suggested_button_description" msgid="8103916969024076767">"Có vấn đề với máy ảnh?\nHãy nhấn để sửa lỗi"</string> <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Bạn chưa khắc phục vấn đề?\nHãy nhấn để hủy bỏ"</string> <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Không có vấn đề với máy ảnh? Hãy nhấn để đóng."</string> diff --git a/libs/WindowManager/Shell/res/values-watch/colors.xml b/libs/WindowManager/Shell/res/values-watch/colors.xml new file mode 100644 index 000000000000..82492bf2af80 --- /dev/null +++ b/libs/WindowManager/Shell/res/values-watch/colors.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* + * Copyright 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. + */ +--> +<resources> + <color name="splash_window_background_default">@color/splash_screen_bg_dark</color> +</resources> + diff --git a/libs/WindowManager/Shell/res/values-watch/dimen.xml b/libs/WindowManager/Shell/res/values-watch/dimen.xml new file mode 100644 index 000000000000..362e72cb4d2d --- /dev/null +++ b/libs/WindowManager/Shell/res/values-watch/dimen.xml @@ -0,0 +1,22 @@ +<?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. +--> +<resources> + <!-- The acceptable area ratio of fg icon area/bg icon area, i.e. (48 X 48) / (72 x 72) --> + <item type="dimen" format="float" name="splash_icon_enlarge_foreground_threshold">0.44</item> + <!-- Scaling factor applied to splash icons without provided background i.e. (60 / 48) --> + <item type="dimen" format="float" name="splash_icon_no_background_scale_factor">1.25</item> +</resources> diff --git a/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml b/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml index 6f399e51be4d..3d33ecaccc38 100644 --- a/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml +++ b/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml @@ -24,7 +24,7 @@ <string name="pip_menu_title" msgid="5393619322111827096">"選單"</string> <string name="pip_menu_accessibility_title" msgid="8129016817688656249">"畫中畫選單"</string> <string name="pip_notification_title" msgid="1347104727641353453">"「<xliff:g id="NAME">%s</xliff:g>」目前在畫中畫模式"</string> - <string name="pip_notification_message" msgid="8854051911700302620">"如果您不想「<xliff:g id="NAME">%s</xliff:g>」使用此功能,請輕按以開啟設定,然後停用此功能。"</string> + <string name="pip_notification_message" msgid="8854051911700302620">"如果你不想「<xliff:g id="NAME">%s</xliff:g>」使用此功能,請輕按以開啟設定,然後停用此功能。"</string> <string name="pip_play" msgid="3496151081459417097">"播放"</string> <string name="pip_pause" msgid="690688849510295232">"暫停"</string> <string name="pip_skip_to_next" msgid="8403429188794867653">"跳到下一個"</string> @@ -88,8 +88,8 @@ <string name="letterbox_education_reposition_text" msgid="4589957299813220661">"在應用程式外輕按兩下即可調整位置"</string> <string name="letterbox_education_got_it" msgid="4057634570866051177">"知道了"</string> <string name="letterbox_education_expand_button_description" msgid="1729796567101129834">"展開即可查看詳情。"</string> - <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"要重新啟動改善檢視畫面嗎?"</string> - <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"您可重新啟動應用程式,讓系統更新檢視畫面;但系統可能不會儲存目前進度及您作出的任何變更"</string> + <string name="letterbox_restart_dialog_title" msgid="8543049527871033505">"要重新啟動以改善檢視畫面嗎?"</string> + <string name="letterbox_restart_dialog_description" msgid="6096946078246557848">"你可重新啟動應用程式,讓系統更新檢視畫面;但系統可能不會儲存目前進度及你作出的任何變更"</string> <string name="letterbox_restart_cancel" msgid="1342209132692537805">"取消"</string> <string name="letterbox_restart_restart" msgid="8529976234412442973">"重新啟動"</string> <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"不要再顯示"</string> diff --git a/libs/WindowManager/Shell/res/values/dimen.xml b/libs/WindowManager/Shell/res/values/dimen.xml index 64fed1cacca9..ac73e1d87ba2 100644 --- a/libs/WindowManager/Shell/res/values/dimen.xml +++ b/libs/WindowManager/Shell/res/values/dimen.xml @@ -421,4 +421,9 @@ <!-- The height of the area at the top of the screen where a freeform task will transition to fullscreen if dragged until the top bound of the task is within the area. --> <dimen name="desktop_mode_transition_area_height">16dp</dimen> + + <!-- The acceptable area ratio of fg icon area/bg icon area, i.e. (72 x 72) / (108 x 108) --> + <item type="dimen" format="float" name="splash_icon_enlarge_foreground_threshold">0.44</item> + <!-- Scaling factor applied to splash icons without provided background i.e. (192 / 160) --> + <item type="dimen" format="float" name="splash_icon_no_background_scale_factor">1.2</item> </resources> diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipAccessibilityInteractionConnection.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipAccessibilityInteractionConnection.java index 4a06d84ce90d..8c2879e0d816 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipAccessibilityInteractionConnection.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipAccessibilityInteractionConnection.java @@ -383,6 +383,9 @@ public class PipAccessibilityInteractionConnection { } @Override - public void attachAccessibilityOverlayToWindow(SurfaceControl sc) {} + public void attachAccessibilityOverlayToWindow( + SurfaceControl sc, + int interactionId, + IAccessibilityInteractionConnectionCallback callback) {} } }
\ No newline at end of file diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipAction.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipAction.java index 5f6b3fe1e250..fc0b876e1bde 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipAction.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipAction.java @@ -77,6 +77,19 @@ abstract class TvPipAction { return mActionType; } + static String getActionTypeString(@ActionType int actionType) { + switch (actionType) { + case ACTION_FULLSCREEN: return "ACTION_FULLSCREEN"; + case ACTION_CLOSE: return "ACTION_CLOSE"; + case ACTION_MOVE: return "ACTION_MOVE"; + case ACTION_EXPAND_COLLAPSE: return "ACTION_EXPAND_COLLAPSE"; + case ACTION_CUSTOM: return "ACTION_CUSTOM"; + case ACTION_CUSTOM_CLOSE: return "ACTION_CUSTOM_CLOSE"; + default: + return "UNDEFINED"; + } + } + abstract void populateButton(@NonNull TvWindowMenuActionButton button, Handler mainHandler); abstract PendingIntent getPendingIntent(); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipActionsProvider.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipActionsProvider.java index 3b44f10ebe62..11c2665c9665 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipActionsProvider.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipActionsProvider.java @@ -56,8 +56,10 @@ public class TvPipActionsProvider implements TvPipAction.SystemActionsHandler { private final List<Listener> mListeners = new ArrayList<>(); private final TvPipAction.SystemActionsHandler mSystemActionsHandler; - private final List<TvPipAction> mActionsList; + private final List<TvPipAction> mActionsList = new ArrayList<>(); + private final TvPipSystemAction mFullscreenAction; private final TvPipSystemAction mDefaultCloseAction; + private final TvPipSystemAction mMoveAction; private final TvPipSystemAction mExpandCollapseAction; private final List<RemoteAction> mMediaActions = new ArrayList<>(); @@ -67,26 +69,27 @@ public class TvPipActionsProvider implements TvPipAction.SystemActionsHandler { TvPipAction.SystemActionsHandler systemActionsHandler) { mSystemActionsHandler = systemActionsHandler; - mActionsList = new ArrayList<>(); - mActionsList.add(new TvPipSystemAction(ACTION_FULLSCREEN, R.string.pip_fullscreen, + mFullscreenAction = new TvPipSystemAction(ACTION_FULLSCREEN, R.string.pip_fullscreen, R.drawable.pip_ic_fullscreen_white, ACTION_TO_FULLSCREEN, context, - mSystemActionsHandler)); - + mSystemActionsHandler); mDefaultCloseAction = new TvPipSystemAction(ACTION_CLOSE, R.string.pip_close, R.drawable.pip_ic_close_white, ACTION_CLOSE_PIP, context, mSystemActionsHandler); - mActionsList.add(mDefaultCloseAction); - - mActionsList.add(new TvPipSystemAction(ACTION_MOVE, R.string.pip_move, - R.drawable.pip_ic_move_white, ACTION_MOVE_PIP, context, mSystemActionsHandler)); - + mMoveAction = new TvPipSystemAction(ACTION_MOVE, R.string.pip_move, + R.drawable.pip_ic_move_white, ACTION_MOVE_PIP, context, mSystemActionsHandler); mExpandCollapseAction = new TvPipSystemAction(ACTION_EXPAND_COLLAPSE, R.string.pip_collapse, R.drawable.pip_ic_collapse, ACTION_TOGGLE_EXPANDED_PIP, context, mSystemActionsHandler); - mActionsList.add(mExpandCollapseAction); + initActions(); pipMediaController.addActionListener(this::onMediaActionsChanged); } + private void initActions() { + mActionsList.add(mFullscreenAction); + mActionsList.add(mDefaultCloseAction); + mActionsList.add(mMoveAction); + } + @Override public void executeAction(@TvPipAction.ActionType int actionType) { if (mSystemActionsHandler != null) { @@ -199,6 +202,14 @@ public class TvPipActionsProvider implements TvPipAction.SystemActionsHandler { } } + void reset() { + mActionsList.clear(); + mMediaActions.clear(); + mAppActions.clear(); + + initActions(); + } + List<TvPipAction> getActionsList() { return mActionsList; } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipBoundsState.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipBoundsState.java index e1737eccc6e1..3f3951a2d4f0 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipBoundsState.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipBoundsState.java @@ -81,6 +81,7 @@ public class TvPipBoundsState extends PipBoundsState { super(context, pipSizeSpecHandler, pipDisplayLayoutState); mContext = context; updateDefaultGravity(); + mTvPipGravity = mDefaultGravity; mPreviousCollapsedGravity = mDefaultGravity; mIsTvExpandedPipSupported = context.getPackageManager().hasSystemFeature( PackageManager.FEATURE_EXPANDED_PICTURE_IN_PICTURE); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipController.java index 02eeb2ac4fd5..2482acf60267 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipController.java @@ -478,6 +478,7 @@ public class TvPipController implements PipTransitionController.PipTransitionCal mActionBroadcastReceiver.unregister(); mTvPipMenuController.closeMenu(); + mTvPipActionsProvider.reset(); mTvPipBoundsState.resetTvPipState(); mTvPipBoundsController.reset(); setState(STATE_NO_PIP); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java index dc91a11dc64f..84dcd4db7bb2 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java @@ -112,28 +112,15 @@ public class SplashscreenContentDrawer { */ static final long MAX_ANIMATION_DURATION = MINIMAL_ANIMATION_DURATION + TIME_WINDOW_DURATION; - // The acceptable area ratio of foreground_icon_area/background_icon_area, if there is an - // icon which it's non-transparent foreground area is similar to it's background area, then - // do not enlarge the foreground drawable. - // For example, an icon with the foreground 108*108 opaque pixels and it's background - // also 108*108 pixels, then do not enlarge this icon if only need to show foreground icon. - private static final float ENLARGE_FOREGROUND_ICON_THRESHOLD = (72f * 72f) / (108f * 108f); - - /** - * If the developer doesn't specify a background for the icon, we slightly scale it up. - * - * The background is either manually specified in the theme or the Adaptive Icon - * background is used if it's different from the window background. - */ - private static final float NO_BACKGROUND_SCALE = 192f / 160; private final Context mContext; private final HighResIconProvider mHighResIconProvider; - private int mIconSize; private int mDefaultIconSize; private int mBrandingImageWidth; private int mBrandingImageHeight; private int mMainWindowShiftLength; + private float mEnlargeForegroundIconThreshold; + private float mNoBackgroundScale; private int mLastPackageContextConfigHash; private final TransactionPool mTransactionPool; private final SplashScreenWindowAttrs mTmpAttrs = new SplashScreenWindowAttrs(); @@ -336,6 +323,10 @@ public class SplashscreenContentDrawer { com.android.wm.shell.R.dimen.starting_surface_brand_image_height); mMainWindowShiftLength = mContext.getResources().getDimensionPixelSize( com.android.wm.shell.R.dimen.starting_surface_exit_animation_window_shift_length); + mEnlargeForegroundIconThreshold = mContext.getResources().getFloat( + com.android.wm.shell.R.dimen.splash_icon_enlarge_foreground_threshold); + mNoBackgroundScale = mContext.getResources().getFloat( + com.android.wm.shell.R.dimen.splash_icon_no_background_scale_factor); } /** @@ -604,14 +595,14 @@ public class SplashscreenContentDrawer { // There is no background below the icon, so scale the icon up if (mTmpAttrs.mIconBgColor == Color.TRANSPARENT || mTmpAttrs.mIconBgColor == mThemeColor) { - mFinalIconSize *= NO_BACKGROUND_SCALE; + mFinalIconSize *= mNoBackgroundScale; } createIconDrawable(iconDrawable, false /* legacy */, false /* loadInDetail */); } else { final float iconScale = (float) mIconSize / (float) mDefaultIconSize; final int densityDpi = mContext.getResources().getConfiguration().densityDpi; final int scaledIconDpi = - (int) (0.5f + iconScale * densityDpi * NO_BACKGROUND_SCALE); + (int) (0.5f + iconScale * densityDpi * mNoBackgroundScale); Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "getIcon"); iconDrawable = mHighResIconProvider.getIcon( mActivityInfo, densityDpi, scaledIconDpi); @@ -693,8 +684,8 @@ public class SplashscreenContentDrawer { // Reference AdaptiveIcon description, outer is 108 and inner is 72, so we // scale by 192/160 if we only draw adaptiveIcon's foreground. final float noBgScale = - iconColor.mFgNonTranslucentRatio < ENLARGE_FOREGROUND_ICON_THRESHOLD - ? NO_BACKGROUND_SCALE : 1f; + iconColor.mFgNonTranslucentRatio < mEnlargeForegroundIconThreshold + ? mNoBackgroundScale : 1f; // Using AdaptiveIconDrawable here can help keep the shape consistent with the // current settings. mFinalIconSize = (int) (0.5f + mIconSize * noBgScale); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskViewTransitions.java b/libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskViewTransitions.java index 16f0e3987e24..daf8be60651a 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskViewTransitions.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/taskview/TaskViewTransitions.java @@ -165,19 +165,6 @@ public class TaskViewTransitions implements Transitions.TransitionHandler { return null; } - /** - * Returns all the pending transitions for a given `taskView`. - * @param taskView the pending transition should be for this. - */ - ArrayList<PendingTransition> findAllPending(TaskViewTaskController taskView) { - ArrayList<PendingTransition> list = new ArrayList<>(); - for (int i = mPending.size() - 1; i >= 0; --i) { - if (mPending.get(i).mTaskView != taskView) continue; - list.add(mPending.get(i)); - } - return list; - } - private PendingTransition findPending(IBinder claimed) { for (int i = 0; i < mPending.size(); ++i) { if (mPending.get(i).mClaimed != claimed) continue; @@ -273,10 +260,9 @@ public class TaskViewTransitions implements Transitions.TransitionHandler { // Task view isn't visible, the bounds will next visibility update. return; } - PendingTransition pendingOpen = findPendingOpeningTransition(taskView); - if (pendingOpen != null) { - // There is already an opening transition in-flight, the window bounds will be - // set in prepareOpenAnimation (via the window crop) if needed. + if (hasPending()) { + // There is already a transition in-flight, the window bounds will be set in + // prepareOpenAnimation. return; } WindowContainerTransaction wct = new WindowContainerTransaction(); diff --git a/libs/WindowManager/Shell/tests/flicker/Android.bp b/libs/WindowManager/Shell/tests/flicker/Android.bp index 208ae84645c3..09477232c9e0 100644 --- a/libs/WindowManager/Shell/tests/flicker/Android.bp +++ b/libs/WindowManager/Shell/tests/flicker/Android.bp @@ -24,6 +24,11 @@ package { } filegroup { + name: "WMShellFlickerTestsUtils-src", + srcs: ["src/com/android/wm/shell/flicker/utils/*.kt"], +} + +filegroup { name: "WMShellFlickerTestsBase-src", srcs: ["src/com/android/wm/shell/flicker/*.kt"], } @@ -39,20 +44,55 @@ filegroup { } filegroup { - name: "WMShellFlickerTestsSplitScreen-src", + name: "WMShellFlickerTestsSplitScreenBase-src", srcs: [ - "src/com/android/wm/shell/flicker/splitscreen/*.kt", "src/com/android/wm/shell/flicker/splitscreen/benchmark/*.kt", ], } filegroup { + name: "WMShellFlickerTestsSplitScreenEnter-src", + srcs: [ + "src/com/android/wm/shell/flicker/splitscreen/Enter*.kt", + ], +} + +filegroup { + name: "WMShellFlickerTestsSplitScreenOther-src", + srcs: [ + "src/com/android/wm/shell/flicker/splitscreen/*.kt", + ], +} + +filegroup { name: "WMShellFlickerServiceTests-src", srcs: [ "src/com/android/wm/shell/flicker/service/**/*.kt", ], } +java_library { + name: "wm-shell-flicker-utils", + platform_apis: true, + optimize: { + enabled: false, + }, + srcs: [ + ":WMShellFlickerTestsUtils-src", + ], + static_libs: [ + "androidx.test.ext.junit", + "flickertestapplib", + "flickerlib", + "flickerlib-helpers", + "platform-test-annotations", + "wm-flicker-common-app-helpers", + "wm-flicker-common-assertions", + "launcher-helper-lib", + "launcher-aosp-tapl", + ], +} + java_defaults { name: "WMShellFlickerTestsDefault", manifest: "manifests/AndroidManifest.xml", @@ -65,6 +105,7 @@ java_defaults { test_suites: ["device-tests"], libs: ["android.test.runner"], static_libs: [ + "wm-shell-flicker-utils", "androidx.test.ext.junit", "flickertestapplib", "flickerlib", @@ -94,7 +135,9 @@ android_test { exclude_srcs: [ ":WMShellFlickerTestsBubbles-src", ":WMShellFlickerTestsPip-src", - ":WMShellFlickerTestsSplitScreen-src", + ":WMShellFlickerTestsSplitScreenEnter-src", + ":WMShellFlickerTestsSplitScreenOther-src", + ":WMShellFlickerTestsSplitScreenBase-src", ":WMShellFlickerServiceTests-src", ], } @@ -124,14 +167,31 @@ android_test { } android_test { - name: "WMShellFlickerTestsSplitScreen", + name: "WMShellFlickerTestsSplitScreenEnter", defaults: ["WMShellFlickerTestsDefault"], additional_manifests: ["manifests/AndroidManifestSplitScreen.xml"], package_name: "com.android.wm.shell.flicker.splitscreen", instrumentation_target_package: "com.android.wm.shell.flicker.splitscreen", srcs: [ ":WMShellFlickerTestsBase-src", - ":WMShellFlickerTestsSplitScreen-src", + ":WMShellFlickerTestsSplitScreenBase-src", + ":WMShellFlickerTestsSplitScreenEnter-src", + ], +} + +android_test { + name: "WMShellFlickerTestsSplitScreenOther", + defaults: ["WMShellFlickerTestsDefault"], + additional_manifests: ["manifests/AndroidManifestSplitScreen.xml"], + package_name: "com.android.wm.shell.flicker.splitscreen", + instrumentation_target_package: "com.android.wm.shell.flicker.splitscreen", + srcs: [ + ":WMShellFlickerTestsBase-src", + ":WMShellFlickerTestsSplitScreenBase-src", + ":WMShellFlickerTestsSplitScreenOther-src", + ], + exclude_srcs: [ + ":WMShellFlickerTestsSplitScreenEnter-src", ], } diff --git a/libs/WindowManager/Shell/tests/flicker/AndroidTestTemplate.xml b/libs/WindowManager/Shell/tests/flicker/AndroidTestTemplate.xml index c8a96377800f..87b20ed6305e 100644 --- a/libs/WindowManager/Shell/tests/flicker/AndroidTestTemplate.xml +++ b/libs/WindowManager/Shell/tests/flicker/AndroidTestTemplate.xml @@ -90,9 +90,9 @@ <option name="directory-keys" value="/data/user/0/com.android.wm.shell.flicker.bubbles/files"/> <option name="directory-keys" - value="/data/user/0/com.android.server.wm.flicker.pip/files"/> + value="/data/user/0/com.android.wm.shell.flicker.pip/files"/> <option name="directory-keys" - value="/data/user/0/com.android.server.wm.flicker.splitscreen/files"/> + value="/data/user/0/com.android.wm.shell.flicker.splitscreen/files"/> <option name="directory-keys" value="/data/user/0/com.android.server.wm.flicker.service/files"/> <option name="collect-on-run-ended-only" value="true"/> diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/BaseTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/BaseTest.kt index d2fe9fec460c..735fbfb341f5 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/BaseTest.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/BaseTest.kt @@ -21,6 +21,7 @@ import android.tools.common.traces.component.ComponentNameMatcher import android.tools.device.flicker.legacy.LegacyFlickerTest import androidx.test.platform.app.InstrumentationRegistry import com.android.launcher3.tapl.LauncherInstrumentation +import com.android.wm.shell.flicker.utils.ICommonAssertions /** * Base test class containing common assertions for [ComponentNameMatcher.NAV_BAR], diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/BaseAppCompat.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/BaseAppCompat.kt index 69c8ecd5644d..77f14f1b66a3 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/BaseAppCompat.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/BaseAppCompat.kt @@ -24,11 +24,10 @@ import android.tools.device.flicker.legacy.LegacyFlickerTest import com.android.server.wm.flicker.helpers.LetterboxAppHelper import com.android.server.wm.flicker.helpers.setRotation import com.android.wm.shell.flicker.BaseTest -import com.android.wm.shell.flicker.appWindowIsVisibleAtEnd -import com.android.wm.shell.flicker.appWindowIsVisibleAtStart -import com.android.wm.shell.flicker.appWindowKeepVisible -import com.android.wm.shell.flicker.layerKeepVisible - +import com.android.wm.shell.flicker.utils.appWindowIsVisibleAtEnd +import com.android.wm.shell.flicker.utils.appWindowIsVisibleAtStart +import com.android.wm.shell.flicker.utils.appWindowKeepVisible +import com.android.wm.shell.flicker.utils.layerKeepVisible import org.junit.Assume import org.junit.Before import org.junit.Rule @@ -37,9 +36,7 @@ abstract class BaseAppCompat(flicker: LegacyFlickerTest) : BaseTest(flicker) { protected val context: Context = instrumentation.context protected val letterboxApp = LetterboxAppHelper(instrumentation) - @JvmField - @Rule - val letterboxRule: LetterboxRule = LetterboxRule() + @JvmField @Rule val letterboxRule: LetterboxRule = LetterboxRule() /** {@inheritDoc} */ override val transition: FlickerBuilder.() -> Unit diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/LetterboxRule.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/LetterboxRule.kt index 5a1136f97c6f..744e8c2eb06f 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/LetterboxRule.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/LetterboxRule.kt @@ -23,16 +23,14 @@ import org.junit.rules.TestRule import org.junit.runner.Description import org.junit.runners.model.Statement -/** - * JUnit Rule to handle letterboxStyles and states - */ +/** JUnit Rule to handle letterboxStyles and states */ class LetterboxRule( - private val withLetterboxEducationEnabled: Boolean = false, - private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation(), - private val cmdHelper: CommandsHelper = CommandsHelper.getInstance(instrumentation) + private val withLetterboxEducationEnabled: Boolean = false, + private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation(), + private val cmdHelper: CommandsHelper = CommandsHelper.getInstance(instrumentation) ) : TestRule { - private val execAdb: (String) -> String = {cmd -> cmdHelper.executeShellCommand(cmd)} + private val execAdb: (String) -> String = { cmd -> cmdHelper.executeShellCommand(cmd) } private lateinit var _letterboxStyle: MutableMap<String, String> val letterboxStyle: Map<String, String> @@ -62,8 +60,7 @@ class LetterboxRule( var hasLetterboxEducationStateChanged = false if ("$withLetterboxEducationEnabled" != isLetterboxEducationEnabled) { hasLetterboxEducationStateChanged = true - execAdb("wm set-letterbox-style --isEducationEnabled " + - withLetterboxEducationEnabled) + execAdb("wm set-letterbox-style --isEducationEnabled " + withLetterboxEducationEnabled) } return try { object : Statement() { @@ -74,8 +71,8 @@ class LetterboxRule( } } finally { if (hasLetterboxEducationStateChanged) { - execAdb("wm set-letterbox-style --isEducationEnabled " + - isLetterboxEducationEnabled + execAdb( + "wm set-letterbox-style --isEducationEnabled " + isLetterboxEducationEnabled ) } resetLetterboxStyle() @@ -100,9 +97,10 @@ class LetterboxRule( execAdb("wm reset-letterbox-style") } - private fun asInt(str: String?): Int? = try { - str?.toInt() - } catch (e: NumberFormatException) { - null - } -}
\ No newline at end of file + private fun asInt(str: String?): Int? = + try { + str?.toInt() + } catch (e: NumberFormatException) { + null + } +} diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/OpenTransparentActivityTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/OpenTransparentActivityTest.kt index e6ca261a317f..2fa1ec386781 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/OpenTransparentActivityTest.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/OpenTransparentActivityTest.kt @@ -54,9 +54,7 @@ class OpenTransparentActivityTest(flicker: LegacyFlickerTest) : TransparentBaseA /** {@inheritDoc} */ override val transition: FlickerBuilder.() -> Unit get() = { - setup { - letterboxTranslucentLauncherApp.launchViaIntent(wmHelper) - } + setup { letterboxTranslucentLauncherApp.launchViaIntent(wmHelper) } transitions { waitAndGetLaunchTransparent()?.click() ?: error("Launch Transparent not found") } @@ -66,9 +64,7 @@ class OpenTransparentActivityTest(flicker: LegacyFlickerTest) : TransparentBaseA } } - /** - * Checks the transparent activity is launched on top of the opaque one - */ + /** Checks the transparent activity is launched on top of the opaque one */ @Postsubmit @Test fun translucentActivityIsLaunchedOnTopOfOpaqueActivity() { @@ -79,18 +75,14 @@ class OpenTransparentActivityTest(flicker: LegacyFlickerTest) : TransparentBaseA } } - /** - * Checks that the activity is letterboxed - */ + /** Checks that the activity is letterboxed */ @Postsubmit @Test fun translucentActivityIsLetterboxed() { flicker.assertLayers { isVisible(ComponentNameMatcher.LETTERBOX) } } - /** - * Checks that the translucent activity inherits bounds from the opaque one. - */ + /** Checks that the translucent activity inherits bounds from the opaque one. */ @Postsubmit @Test fun translucentActivityInheritsBoundsFromOpaqueActivity() { @@ -100,29 +92,26 @@ class OpenTransparentActivityTest(flicker: LegacyFlickerTest) : TransparentBaseA } } - /** - * Checks that the translucent activity has rounded corners - */ + /** Checks that the translucent activity has rounded corners */ @Postsubmit @Test fun translucentActivityHasRoundedCorners() { - flicker.assertLayersEnd { - this.hasRoundedCorners(letterboxTranslucentApp) - } + flicker.assertLayersEnd { this.hasRoundedCorners(letterboxTranslucentApp) } } companion object { /** * Creates the test configurations. * - * See [FlickerTestFactory.rotationTests] for configuring screen orientation and - * navigation modes. + * See [FlickerTestFactory.rotationTests] for configuring screen orientation and navigation + * modes. */ @Parameterized.Parameters(name = "{0}") @JvmStatic fun getParams(): Collection<FlickerTest> { - return LegacyFlickerTestFactory - .nonRotationTests(supportedRotations = listOf(Rotation.ROTATION_90)) + return LegacyFlickerTestFactory.nonRotationTests( + supportedRotations = listOf(Rotation.ROTATION_90) + ) } } } diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/QuickSwitchLauncherToLetterboxAppTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/QuickSwitchLauncherToLetterboxAppTest.kt index d3f3c5b7c672..b74aa1d7bf73 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/QuickSwitchLauncherToLetterboxAppTest.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/QuickSwitchLauncherToLetterboxAppTest.kt @@ -49,8 +49,7 @@ import org.junit.runners.Parameterized @RunWith(Parameterized::class) @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class) @FixMethodOrder(MethodSorters.NAME_ASCENDING) -open class QuickSwitchLauncherToLetterboxAppTest(flicker: LegacyFlickerTest) : - BaseAppCompat(flicker) { +class QuickSwitchLauncherToLetterboxAppTest(flicker: LegacyFlickerTest) : BaseAppCompat(flicker) { /** {@inheritDoc} */ override val transition: FlickerBuilder.() -> Unit = { diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/TransparentBaseAppCompat.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/TransparentBaseAppCompat.kt index ea0392cee95a..9792c859cced 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/TransparentBaseAppCompat.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/appcompat/TransparentBaseAppCompat.kt @@ -33,20 +33,20 @@ import org.junit.Rule abstract class TransparentBaseAppCompat(flicker: LegacyFlickerTest) : BaseTest(flicker) { protected val context: Context = instrumentation.context - protected val letterboxTranslucentLauncherApp = LetterboxAppHelper( - instrumentation, - launcherName = ActivityOptions.LaunchTransparentActivity.LABEL, - component = ActivityOptions.LaunchTransparentActivity.COMPONENT.toFlickerComponent() - ) - protected val letterboxTranslucentApp = LetterboxAppHelper( - instrumentation, - launcherName = ActivityOptions.TransparentActivity.LABEL, - component = ActivityOptions.TransparentActivity.COMPONENT.toFlickerComponent() - ) + protected val letterboxTranslucentLauncherApp = + LetterboxAppHelper( + instrumentation, + launcherName = ActivityOptions.LaunchTransparentActivity.LABEL, + component = ActivityOptions.LaunchTransparentActivity.COMPONENT.toFlickerComponent() + ) + protected val letterboxTranslucentApp = + LetterboxAppHelper( + instrumentation, + launcherName = ActivityOptions.TransparentActivity.LABEL, + component = ActivityOptions.TransparentActivity.COMPONENT.toFlickerComponent() + ) - @JvmField - @Rule - val letterboxRule: LetterboxRule = LetterboxRule() + @JvmField @Rule val letterboxRule: LetterboxRule = LetterboxRule() @Before fun before() { @@ -54,10 +54,7 @@ abstract class TransparentBaseAppCompat(flicker: LegacyFlickerTest) : BaseTest(f } protected fun FlickerTestData.waitAndGetLaunchTransparent(): UiObject2? = - device.wait( - Until.findObject(By.text("Launch Transparent")), - FIND_TIMEOUT - ) + device.wait(Until.findObject(By.text("Launch Transparent")), FIND_TIMEOUT) protected fun FlickerTestData.goBack() = device.pressBack() } diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/ChangeActiveActivityFromBubbleTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/ChangeActiveActivityFromBubbleTest.kt index bc565bc5fd42..9cc9fb94353d 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/ChangeActiveActivityFromBubbleTest.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/ChangeActiveActivityFromBubbleTest.kt @@ -22,7 +22,6 @@ import android.platform.test.annotations.Presubmit import android.tools.device.flicker.junit.FlickerParametersRunnerFactory import android.tools.device.flicker.legacy.FlickerBuilder import android.tools.device.flicker.legacy.LegacyFlickerTest -import androidx.test.filters.RequiresDevice import androidx.test.uiautomator.By import androidx.test.uiautomator.UiObject2 import androidx.test.uiautomator.Until @@ -40,12 +39,10 @@ import org.junit.runners.Parameterized * Switch in different bubble notifications * ``` */ -@RequiresDevice @RunWith(Parameterized::class) @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class) @FlakyTest(bugId = 217777115) -open class ChangeActiveActivityFromBubbleTest(flicker: LegacyFlickerTest) : - BaseBubbleScreen(flicker) { +class ChangeActiveActivityFromBubbleTest(flicker: LegacyFlickerTest) : BaseBubbleScreen(flicker) { /** {@inheritDoc} */ override val transition: FlickerBuilder.() -> Unit get() = buildTransition { diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/ChangeActiveActivityFromBubbleTestCfArm.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/ChangeActiveActivityFromBubbleTestCfArm.kt deleted file mode 100644 index abc6b9f9a746..000000000000 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/ChangeActiveActivityFromBubbleTestCfArm.kt +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (C) 2023 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.wm.shell.flicker.bubble - -import android.tools.device.flicker.junit.FlickerParametersRunnerFactory -import android.tools.device.flicker.legacy.LegacyFlickerTest -import org.junit.runner.RunWith -import org.junit.runners.Parameterized - -@RunWith(Parameterized::class) -@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class) -open class ChangeActiveActivityFromBubbleTestCfArm(flicker: LegacyFlickerTest) : - ChangeActiveActivityFromBubbleTest(flicker) diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/DragToDismissBubbleScreenTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/DragToDismissBubbleScreenTest.kt index 3f28ae848d1f..9ca7bf113589 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/DragToDismissBubbleScreenTest.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/DragToDismissBubbleScreenTest.kt @@ -20,12 +20,12 @@ import android.content.Context import android.graphics.Point import android.platform.test.annotations.Presubmit import android.tools.common.flicker.subject.layers.LayersTraceSubject +import android.tools.common.traces.component.ComponentNameMatcher import android.tools.device.flicker.junit.FlickerParametersRunnerFactory import android.tools.device.flicker.legacy.FlickerBuilder import android.tools.device.flicker.legacy.LegacyFlickerTest import android.util.DisplayMetrics import android.view.WindowManager -import androidx.test.filters.RequiresDevice import androidx.test.uiautomator.By import androidx.test.uiautomator.Until import org.junit.Test @@ -42,10 +42,9 @@ import org.junit.runners.Parameterized * Dismiss a bubble notification * ``` */ -@RequiresDevice @RunWith(Parameterized::class) @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class) -open class DragToDismissBubbleScreenTest(flicker: LegacyFlickerTest) : BaseBubbleScreen(flicker) { +class DragToDismissBubbleScreenTest(flicker: LegacyFlickerTest) : BaseBubbleScreen(flicker) { private val wm = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager private val displaySize = DisplayMetrics() @@ -80,7 +79,8 @@ open class DragToDismissBubbleScreenTest(flicker: LegacyFlickerTest) : BaseBubbl override fun visibleLayersShownMoreThanOneConsecutiveEntry() { flicker.assertLayers { this.visibleLayersShownMoreThanOneConsecutiveEntry( - LayersTraceSubject.VISIBLE_FOR_MORE_THAN_ONE_ENTRY_IGNORE_LAYERS + listOf(testApp) + LayersTraceSubject.VISIBLE_FOR_MORE_THAN_ONE_ENTRY_IGNORE_LAYERS + + listOf(testApp, ComponentNameMatcher(className = "Bubbles!#")) ) } } diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/DragToDismissBubbleScreenTestCfArm.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/DragToDismissBubbleScreenTestCfArm.kt deleted file mode 100644 index ee55eca31072..000000000000 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/DragToDismissBubbleScreenTestCfArm.kt +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (C) 2023 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.wm.shell.flicker.bubble - -import android.tools.device.flicker.junit.FlickerParametersRunnerFactory -import android.tools.device.flicker.legacy.LegacyFlickerTest -import org.junit.runner.RunWith -import org.junit.runners.Parameterized - -@RunWith(Parameterized::class) -@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class) -class DragToDismissBubbleScreenTestCfArm(flicker: LegacyFlickerTest) : - DragToDismissBubbleScreenTest(flicker) diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/OpenActivityFromBubbleTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/OpenActivityFromBubbleTest.kt index 508539411aa0..4959672d865b 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/OpenActivityFromBubbleTest.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/OpenActivityFromBubbleTest.kt @@ -20,7 +20,6 @@ import android.platform.test.annotations.Presubmit import android.tools.device.flicker.junit.FlickerParametersRunnerFactory import android.tools.device.flicker.legacy.FlickerBuilder import android.tools.device.flicker.legacy.LegacyFlickerTest -import androidx.test.filters.RequiresDevice import androidx.test.uiautomator.By import androidx.test.uiautomator.Until import org.junit.Test @@ -39,10 +38,9 @@ import org.junit.runners.Parameterized * The activity for the bubble is launched * ``` */ -@RequiresDevice @RunWith(Parameterized::class) @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class) -open class OpenActivityFromBubbleTest(flicker: LegacyFlickerTest) : BaseBubbleScreen(flicker) { +class OpenActivityFromBubbleTest(flicker: LegacyFlickerTest) : BaseBubbleScreen(flicker) { /** {@inheritDoc} */ override val transition: FlickerBuilder.() -> Unit diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/OpenActivityFromBubbleTestCfArm.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/OpenActivityFromBubbleTestCfArm.kt deleted file mode 100644 index 6a46d23ad2a1..000000000000 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/OpenActivityFromBubbleTestCfArm.kt +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (C) 2023 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.wm.shell.flicker.bubble - -import android.tools.device.flicker.junit.FlickerParametersRunnerFactory -import android.tools.device.flicker.legacy.LegacyFlickerTest -import org.junit.runner.RunWith -import org.junit.runners.Parameterized - -@RunWith(Parameterized::class) -@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class) -class OpenActivityFromBubbleTestCfArm(flicker: LegacyFlickerTest) : - OpenActivityFromBubbleTest(flicker) diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/SendBubbleNotificationTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/SendBubbleNotificationTest.kt index a926bb7d85c3..0d95574aca06 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/SendBubbleNotificationTest.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/SendBubbleNotificationTest.kt @@ -20,7 +20,6 @@ import android.platform.test.annotations.Presubmit import android.tools.device.flicker.junit.FlickerParametersRunnerFactory import android.tools.device.flicker.legacy.FlickerBuilder import android.tools.device.flicker.legacy.LegacyFlickerTest -import androidx.test.filters.RequiresDevice import androidx.test.uiautomator.By import androidx.test.uiautomator.Until import org.junit.Test @@ -38,10 +37,9 @@ import org.junit.runners.Parameterized * Send a bubble notification * ``` */ -@RequiresDevice @RunWith(Parameterized::class) @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class) -open class SendBubbleNotificationTest(flicker: LegacyFlickerTest) : BaseBubbleScreen(flicker) { +class SendBubbleNotificationTest(flicker: LegacyFlickerTest) : BaseBubbleScreen(flicker) { /** {@inheritDoc} */ override val transition: FlickerBuilder.() -> Unit diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/SendBubbleNotificationTestCfArm.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/SendBubbleNotificationTestCfArm.kt deleted file mode 100644 index a401cb494822..000000000000 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/SendBubbleNotificationTestCfArm.kt +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (C) 2023 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.wm.shell.flicker.bubble - -import android.tools.device.flicker.junit.FlickerParametersRunnerFactory -import android.tools.device.flicker.legacy.LegacyFlickerTest -import org.junit.runner.RunWith -import org.junit.runners.Parameterized - -@RunWith(Parameterized::class) -@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class) -open class SendBubbleNotificationTestCfArm(flicker: LegacyFlickerTest) : - SendBubbleNotificationTest(flicker) diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/AutoEnterPipFromSplitScreenOnGoToHomeTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/AutoEnterPipFromSplitScreenOnGoToHomeTest.kt index 8bd44c3a7fd0..c335d3dc7f4b 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/AutoEnterPipFromSplitScreenOnGoToHomeTest.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/AutoEnterPipFromSplitScreenOnGoToHomeTest.kt @@ -28,7 +28,7 @@ import android.tools.device.traces.parsers.toFlickerComponent import androidx.test.filters.RequiresDevice import com.android.server.wm.flicker.helpers.SimpleAppHelper import com.android.server.wm.flicker.testapp.ActivityOptions -import com.android.wm.shell.flicker.SplitScreenUtils +import com.android.wm.shell.flicker.utils.SplitScreenUtils import org.junit.Assume import org.junit.FixMethodOrder import org.junit.Test diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/AutoEnterPipOnGoToHomeTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/AutoEnterPipOnGoToHomeTest.kt index 2f7a25ea586d..bf686d6c3825 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/AutoEnterPipOnGoToHomeTest.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/AutoEnterPipOnGoToHomeTest.kt @@ -16,6 +16,7 @@ package com.android.wm.shell.flicker.pip +import android.platform.test.annotations.FlakyTest import android.platform.test.annotations.Presubmit import android.tools.device.flicker.junit.FlickerParametersRunnerFactory import android.tools.device.flicker.legacy.FlickerBuilder @@ -72,7 +73,7 @@ open class AutoEnterPipOnGoToHomeTest(flicker: LegacyFlickerTest) : } } - @Presubmit + @FlakyTest(bugId = 293133362) @Test override fun pipLayerReduces() { flicker.assertLayers { @@ -84,7 +85,7 @@ open class AutoEnterPipOnGoToHomeTest(flicker: LegacyFlickerTest) : } /** Checks that [pipApp] window is animated towards default position in right bottom corner */ - @Presubmit + @FlakyTest(bugId = 255578530) @Test fun pipLayerMovesTowardsRightBottomCorner() { // in gestural nav the swipe makes PiP first go upwards @@ -107,4 +108,10 @@ open class AutoEnterPipOnGoToHomeTest(flicker: LegacyFlickerTest) : Assume.assumeFalse(flicker.scenario.isGesturalNavigation) super.focusChanges() } + + @FlakyTest(bugId = 289943985) + @Test + override fun visibleLayersShownMoreThanOneConsecutiveEntry() { + super.visibleLayersShownMoreThanOneConsecutiveEntry() + } } diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ClosePipBySwipingDownTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ClosePipBySwipingDownTest.kt index 68bc9a28967e..ca28f5210f6b 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ClosePipBySwipingDownTest.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ClosePipBySwipingDownTest.kt @@ -21,7 +21,6 @@ import android.tools.common.traces.component.ComponentNameMatcher import android.tools.device.flicker.junit.FlickerParametersRunnerFactory import android.tools.device.flicker.legacy.FlickerBuilder import android.tools.device.flicker.legacy.LegacyFlickerTest -import androidx.test.filters.RequiresDevice import org.junit.FixMethodOrder import org.junit.Test import org.junit.runner.RunWith @@ -49,11 +48,10 @@ import org.junit.runners.Parameterized * apps are running before setup * ``` */ -@RequiresDevice @RunWith(Parameterized::class) @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class) @FixMethodOrder(MethodSorters.NAME_ASCENDING) -open class ClosePipBySwipingDownTest(flicker: LegacyFlickerTest) : ClosePipTransition(flicker) { +class ClosePipBySwipingDownTest(flicker: LegacyFlickerTest) : ClosePipTransition(flicker) { override val thisTransition: FlickerBuilder.() -> Unit = { transitions { val pipRegion = wmHelper.getWindowRegion(pipApp).bounds diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ClosePipBySwipingDownTestCfArm.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ClosePipBySwipingDownTestCfArm.kt deleted file mode 100644 index 7a668897fbbe..000000000000 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ClosePipBySwipingDownTestCfArm.kt +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (C) 2023 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.wm.shell.flicker.pip - -import android.tools.common.Rotation -import android.tools.device.flicker.junit.FlickerParametersRunnerFactory -import android.tools.device.flicker.legacy.LegacyFlickerTest -import android.tools.device.flicker.legacy.LegacyFlickerTestFactory -import org.junit.FixMethodOrder -import org.junit.runner.RunWith -import org.junit.runners.MethodSorters -import org.junit.runners.Parameterized - -@RunWith(Parameterized::class) -@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class) -@FixMethodOrder(MethodSorters.NAME_ASCENDING) -class ClosePipBySwipingDownTestCfArm(flicker: LegacyFlickerTest) : - ClosePipBySwipingDownTest(flicker) { - companion object { - /** - * Creates the test configurations. - * - * See [LegacyFlickerTestFactory.nonRotationTests] for configuring repetitions, screen - * orientation and navigation modes. - */ - @Parameterized.Parameters(name = "{0}") - @JvmStatic - fun getParams() = - LegacyFlickerTestFactory.nonRotationTests( - supportedRotations = listOf(Rotation.ROTATION_0) - ) - } -} diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ClosePipWithDismissButtonTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ClosePipWithDismissButtonTest.kt index dc48696f3197..4da628cfd90c 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ClosePipWithDismissButtonTest.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ClosePipWithDismissButtonTest.kt @@ -20,7 +20,6 @@ import android.platform.test.annotations.Presubmit import android.tools.device.flicker.junit.FlickerParametersRunnerFactory import android.tools.device.flicker.legacy.FlickerBuilder import android.tools.device.flicker.legacy.LegacyFlickerTest -import androidx.test.filters.RequiresDevice import org.junit.FixMethodOrder import org.junit.Test import org.junit.runner.RunWith @@ -49,11 +48,10 @@ import org.junit.runners.Parameterized * apps are running before setup * ``` */ -@RequiresDevice @RunWith(Parameterized::class) @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class) @FixMethodOrder(MethodSorters.NAME_ASCENDING) -open class ClosePipWithDismissButtonTest(flicker: LegacyFlickerTest) : ClosePipTransition(flicker) { +class ClosePipWithDismissButtonTest(flicker: LegacyFlickerTest) : ClosePipTransition(flicker) { override val thisTransition: FlickerBuilder.() -> Unit = { transitions { pipApp.closePipWindow(wmHelper) } } diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ClosePipWithDismissButtonTestCfArm.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ClosePipWithDismissButtonTestCfArm.kt deleted file mode 100644 index 718b14babc4f..000000000000 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ClosePipWithDismissButtonTestCfArm.kt +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (C) 2023 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.wm.shell.flicker.pip - -import android.tools.common.Rotation -import android.tools.device.flicker.junit.FlickerParametersRunnerFactory -import android.tools.device.flicker.legacy.LegacyFlickerTest -import android.tools.device.flicker.legacy.LegacyFlickerTestFactory -import org.junit.FixMethodOrder -import org.junit.runner.RunWith -import org.junit.runners.MethodSorters -import org.junit.runners.Parameterized - -@RunWith(Parameterized::class) -@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class) -@FixMethodOrder(MethodSorters.NAME_ASCENDING) -open class ClosePipWithDismissButtonTestCfArm(flicker: LegacyFlickerTest) : - ClosePipWithDismissButtonTest(flicker) { - companion object { - /** - * Creates the test configurations. - * - * See [LegacyFlickerTestFactory.nonRotationTests] for configuring repetitions, screen - * orientation and navigation modes. - */ - @Parameterized.Parameters(name = "{0}") - @JvmStatic - fun getParams() = - LegacyFlickerTestFactory.nonRotationTests( - supportedRotations = listOf(Rotation.ROTATION_0) - ) - } -} diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipOnUserLeaveHintTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipOnUserLeaveHintTest.kt index 5e392628aa6a..e0b18dea971d 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipOnUserLeaveHintTest.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipOnUserLeaveHintTest.kt @@ -20,7 +20,6 @@ import android.platform.test.annotations.Presubmit import android.tools.device.flicker.junit.FlickerParametersRunnerFactory import android.tools.device.flicker.legacy.FlickerBuilder import android.tools.device.flicker.legacy.LegacyFlickerTest -import androidx.test.filters.RequiresDevice import org.junit.Assume import org.junit.FixMethodOrder import org.junit.Test @@ -40,11 +39,10 @@ import org.junit.runners.Parameterized * Press Home button or swipe up to go Home and put [pipApp] in pip mode * ``` */ -@RequiresDevice @RunWith(Parameterized::class) @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class) @FixMethodOrder(MethodSorters.NAME_ASCENDING) -open class EnterPipOnUserLeaveHintTest(flicker: LegacyFlickerTest) : EnterPipTransition(flicker) { +class EnterPipOnUserLeaveHintTest(flicker: LegacyFlickerTest) : EnterPipTransition(flicker) { override val thisTransition: FlickerBuilder.() -> Unit = { transitions { tapl.goHome() } } override val defaultEnterPip: FlickerBuilder.() -> Unit = { diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipOnUserLeaveHintTestCfArm.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipOnUserLeaveHintTestCfArm.kt deleted file mode 100644 index 2b3e76a964c4..000000000000 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipOnUserLeaveHintTestCfArm.kt +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (C) 2023 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.wm.shell.flicker.pip - -import android.tools.device.flicker.junit.FlickerParametersRunnerFactory -import android.tools.device.flicker.legacy.LegacyFlickerTest -import org.junit.FixMethodOrder -import org.junit.runner.RunWith -import org.junit.runners.MethodSorters -import org.junit.runners.Parameterized - -/** This test will fail because of b/264261596 */ -@RunWith(Parameterized::class) -@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class) -@FixMethodOrder(MethodSorters.NAME_ASCENDING) -class EnterPipOnUserLeaveHintTestCfArm(flicker: LegacyFlickerTest) : - EnterPipOnUserLeaveHintTest(flicker) diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientation.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientation.kt index ec35837bc8dd..c003da60c50a 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientation.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientation.kt @@ -28,7 +28,6 @@ import android.tools.device.flicker.legacy.FlickerBuilder import android.tools.device.flicker.legacy.LegacyFlickerTest import android.tools.device.flicker.legacy.LegacyFlickerTestFactory import android.tools.device.helpers.WindowUtils -import androidx.test.filters.RequiresDevice import com.android.server.wm.flicker.entireScreenCovered import com.android.server.wm.flicker.helpers.FixedOrientationAppHelper import com.android.server.wm.flicker.testapp.ActivityOptions.Pip.ACTION_ENTER_PIP @@ -65,11 +64,10 @@ import org.junit.runners.Parameterized * apps are running before setup * ``` */ -@RequiresDevice @RunWith(Parameterized::class) @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class) @FixMethodOrder(MethodSorters.NAME_ASCENDING) -open class EnterPipToOtherOrientation(flicker: LegacyFlickerTest) : PipTransition(flicker) { +class EnterPipToOtherOrientation(flicker: LegacyFlickerTest) : PipTransition(flicker) { private val testApp = FixedOrientationAppHelper(instrumentation) private val startingBounds = WindowUtils.getDisplayBounds(Rotation.ROTATION_90) private val endingBounds = WindowUtils.getDisplayBounds(Rotation.ROTATION_0) diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientationCfArm.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientationCfArm.kt deleted file mode 100644 index 92642197e9be..000000000000 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientationCfArm.kt +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (C) 2023 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.wm.shell.flicker.pip - -import android.tools.common.Rotation -import android.tools.common.flicker.assertions.FlickerTest -import android.tools.device.flicker.junit.FlickerParametersRunnerFactory -import android.tools.device.flicker.legacy.LegacyFlickerTest -import android.tools.device.flicker.legacy.LegacyFlickerTestFactory -import org.junit.FixMethodOrder -import org.junit.runner.RunWith -import org.junit.runners.MethodSorters -import org.junit.runners.Parameterized - -/** This test fails because of b/264261596 */ -@RunWith(Parameterized::class) -@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class) -@FixMethodOrder(MethodSorters.NAME_ASCENDING) -open class EnterPipToOtherOrientationCfArm(flicker: LegacyFlickerTest) : - EnterPipToOtherOrientation(flicker) { - companion object { - /** - * Creates the test configurations. - * - * See [LegacyFlickerTestFactory.nonRotationTests] for configuring screen orientation and - * navigation modes. - */ - @Parameterized.Parameters(name = "{0}") - @JvmStatic - fun getParams(): Collection<FlickerTest> { - return LegacyFlickerTestFactory.nonRotationTests( - supportedRotations = listOf(Rotation.ROTATION_0) - ) - } - } -} diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipViaAppUiButtonTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipViaAppUiButtonTest.kt index 76c811cbbeea..f9efffe8f5cd 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipViaAppUiButtonTest.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipViaAppUiButtonTest.kt @@ -19,7 +19,6 @@ package com.android.wm.shell.flicker.pip import android.tools.device.flicker.junit.FlickerParametersRunnerFactory import android.tools.device.flicker.legacy.FlickerBuilder import android.tools.device.flicker.legacy.LegacyFlickerTest -import androidx.test.filters.RequiresDevice import org.junit.FixMethodOrder import org.junit.runner.RunWith import org.junit.runners.MethodSorters @@ -46,7 +45,6 @@ import org.junit.runners.Parameterized * apps are running before setup * ``` */ -@RequiresDevice @RunWith(Parameterized::class) @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class) @FixMethodOrder(MethodSorters.NAME_ASCENDING) diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipViaAppUiButtonTestCfArm.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipViaAppUiButtonTestCfArm.kt deleted file mode 100644 index 78e80497747c..000000000000 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipViaAppUiButtonTestCfArm.kt +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (C) 2023 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.wm.shell.flicker.pip - -import android.tools.common.Rotation -import android.tools.device.flicker.junit.FlickerParametersRunnerFactory -import android.tools.device.flicker.legacy.LegacyFlickerTest -import android.tools.device.flicker.legacy.LegacyFlickerTestFactory -import org.junit.FixMethodOrder -import org.junit.runner.RunWith -import org.junit.runners.MethodSorters -import org.junit.runners.Parameterized - -@RunWith(Parameterized::class) -@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class) -@FixMethodOrder(MethodSorters.NAME_ASCENDING) -class EnterPipViaAppUiButtonTestCfArm(flicker: LegacyFlickerTest) : - EnterPipViaAppUiButtonTest(flicker) { - companion object { - /** - * Creates the test configurations. - * - * See [LegacyFlickerTestFactory.nonRotationTests] for configuring repetitions, screen - * orientation and navigation modes. - */ - @Parameterized.Parameters(name = "{0}") - @JvmStatic - fun getParams() = - LegacyFlickerTestFactory.nonRotationTests( - supportedRotations = listOf(Rotation.ROTATION_0) - ) - } -} diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipToAppViaExpandButtonTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipToAppViaExpandButtonTest.kt index b80b7483ba4d..c4e63c3fc408 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipToAppViaExpandButtonTest.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipToAppViaExpandButtonTest.kt @@ -19,7 +19,6 @@ package com.android.wm.shell.flicker.pip import android.tools.device.flicker.junit.FlickerParametersRunnerFactory import android.tools.device.flicker.legacy.FlickerBuilder import android.tools.device.flicker.legacy.LegacyFlickerTest -import androidx.test.filters.RequiresDevice import org.junit.FixMethodOrder import org.junit.runner.RunWith import org.junit.runners.MethodSorters @@ -48,11 +47,10 @@ import org.junit.runners.Parameterized * apps are running before setup * ``` */ -@RequiresDevice @RunWith(Parameterized::class) @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class) @FixMethodOrder(MethodSorters.NAME_ASCENDING) -open class ExitPipToAppViaExpandButtonTest(flicker: LegacyFlickerTest) : +class ExitPipToAppViaExpandButtonTest(flicker: LegacyFlickerTest) : ExitPipToAppTransition(flicker) { override val thisTransition: FlickerBuilder.() -> Unit = { setup { diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipToAppViaExpandButtonTestCfArm.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipToAppViaExpandButtonTestCfArm.kt deleted file mode 100644 index e25c0d6eddc0..000000000000 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipToAppViaExpandButtonTestCfArm.kt +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (C) 2023 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.wm.shell.flicker.pip - -import android.tools.common.Rotation -import android.tools.device.flicker.junit.FlickerParametersRunnerFactory -import android.tools.device.flicker.legacy.LegacyFlickerTest -import android.tools.device.flicker.legacy.LegacyFlickerTestFactory -import org.junit.FixMethodOrder -import org.junit.runner.RunWith -import org.junit.runners.MethodSorters -import org.junit.runners.Parameterized - -@RunWith(Parameterized::class) -@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class) -@FixMethodOrder(MethodSorters.NAME_ASCENDING) -class ExitPipToAppViaExpandButtonTestCfArm(flicker: LegacyFlickerTest) : - ExitPipToAppViaExpandButtonTest(flicker) { - companion object { - /** - * Creates the test configurations. - * - * See [LegacyFlickerTestFactory.nonRotationTests] for configuring screen orientation and - * navigation modes. - */ - @Parameterized.Parameters(name = "{0}") - @JvmStatic - fun getParams() = - LegacyFlickerTestFactory.nonRotationTests( - supportedRotations = listOf(Rotation.ROTATION_0) - ) - } -} diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipToAppViaIntentTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipToAppViaIntentTest.kt index f003ed8a77e0..839bbd4673a5 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipToAppViaIntentTest.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipToAppViaIntentTest.kt @@ -19,7 +19,6 @@ package com.android.wm.shell.flicker.pip import android.tools.device.flicker.junit.FlickerParametersRunnerFactory import android.tools.device.flicker.legacy.FlickerBuilder import android.tools.device.flicker.legacy.LegacyFlickerTest -import androidx.test.filters.RequiresDevice import org.junit.FixMethodOrder import org.junit.runner.RunWith import org.junit.runners.MethodSorters @@ -47,11 +46,10 @@ import org.junit.runners.Parameterized * apps are running before setup * ``` */ -@RequiresDevice @RunWith(Parameterized::class) @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class) @FixMethodOrder(MethodSorters.NAME_ASCENDING) -open class ExitPipToAppViaIntentTest(flicker: LegacyFlickerTest) : ExitPipToAppTransition(flicker) { +class ExitPipToAppViaIntentTest(flicker: LegacyFlickerTest) : ExitPipToAppTransition(flicker) { override val thisTransition: FlickerBuilder.() -> Unit = { setup { // launch an app behind the pip one diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipToAppViaIntentTestCfArm.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipToAppViaIntentTestCfArm.kt deleted file mode 100644 index be19f3cd1970..000000000000 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipToAppViaIntentTestCfArm.kt +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (C) 2023 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.wm.shell.flicker.pip - -import android.tools.common.Rotation -import android.tools.device.flicker.junit.FlickerParametersRunnerFactory -import android.tools.device.flicker.legacy.LegacyFlickerTest -import android.tools.device.flicker.legacy.LegacyFlickerTestFactory -import org.junit.FixMethodOrder -import org.junit.runner.RunWith -import org.junit.runners.MethodSorters -import org.junit.runners.Parameterized - -@RunWith(Parameterized::class) -@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class) -@FixMethodOrder(MethodSorters.NAME_ASCENDING) -class ExitPipToAppViaIntentTestCfArm(flicker: LegacyFlickerTest) : - ExitPipToAppViaIntentTest(flicker) { - companion object { - /** - * Creates the test configurations. - * - * See [LegacyFlickerTestFactory.nonRotationTests] for configuring repetitions, screen - * orientation and navigation modes. - */ - @Parameterized.Parameters(name = "{0}") - @JvmStatic - fun getParams() = - LegacyFlickerTestFactory.nonRotationTests( - supportedRotations = listOf(Rotation.ROTATION_0) - ) - } -} diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExpandPipOnDoubleClickTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExpandPipOnDoubleClickTest.kt index a1d3a117482e..ea67e3ddae69 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExpandPipOnDoubleClickTest.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExpandPipOnDoubleClickTest.kt @@ -23,7 +23,6 @@ import android.tools.device.flicker.junit.FlickerParametersRunnerFactory import android.tools.device.flicker.legacy.FlickerBuilder import android.tools.device.flicker.legacy.LegacyFlickerTest import android.tools.device.flicker.legacy.LegacyFlickerTestFactory -import androidx.test.filters.RequiresDevice import org.junit.FixMethodOrder import org.junit.Test import org.junit.runner.RunWith @@ -51,11 +50,10 @@ import org.junit.runners.Parameterized * apps are running before setup * ``` */ -@RequiresDevice @RunWith(Parameterized::class) @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class) @FixMethodOrder(MethodSorters.NAME_ASCENDING) -open class ExpandPipOnDoubleClickTest(flicker: LegacyFlickerTest) : PipTransition(flicker) { +class ExpandPipOnDoubleClickTest(flicker: LegacyFlickerTest) : PipTransition(flicker) { override val thisTransition: FlickerBuilder.() -> Unit = { transitions { pipApp.doubleClickPipWindow(wmHelper) } } diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExpandPipOnDoubleClickTestTestCfArm.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExpandPipOnDoubleClickTestTestCfArm.kt deleted file mode 100644 index 3095cac94598..000000000000 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExpandPipOnDoubleClickTestTestCfArm.kt +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (C) 2023 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.wm.shell.flicker.pip - -import android.tools.common.Rotation -import android.tools.device.flicker.junit.FlickerParametersRunnerFactory -import android.tools.device.flicker.legacy.LegacyFlickerTest -import android.tools.device.flicker.legacy.LegacyFlickerTestFactory -import org.junit.FixMethodOrder -import org.junit.runner.RunWith -import org.junit.runners.MethodSorters -import org.junit.runners.Parameterized - -@RunWith(Parameterized::class) -@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class) -@FixMethodOrder(MethodSorters.NAME_ASCENDING) -class ExpandPipOnDoubleClickTestTestCfArm(flicker: LegacyFlickerTest) : - ExpandPipOnDoubleClickTest(flicker) { - companion object { - /** - * Creates the test configurations. - * - * See [LegacyFlickerTestFactory.nonRotationTests] for configuring screen orientation and - * navigation modes. - */ - @Parameterized.Parameters(name = "{0}") - @JvmStatic - fun getParams() = - LegacyFlickerTestFactory.nonRotationTests( - supportedRotations = listOf(Rotation.ROTATION_0) - ) - } -} diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExpandPipOnPinchOpenTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExpandPipOnPinchOpenTest.kt index 8c8d280aea9a..0f30cef3fda5 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExpandPipOnPinchOpenTest.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExpandPipOnPinchOpenTest.kt @@ -22,7 +22,6 @@ import android.tools.device.flicker.junit.FlickerParametersRunnerFactory import android.tools.device.flicker.legacy.FlickerBuilder import android.tools.device.flicker.legacy.LegacyFlickerTest import android.tools.device.flicker.legacy.LegacyFlickerTestFactory -import androidx.test.filters.RequiresDevice import org.junit.FixMethodOrder import org.junit.Test import org.junit.runner.RunWith @@ -30,11 +29,10 @@ import org.junit.runners.MethodSorters import org.junit.runners.Parameterized /** Test expanding a pip window via pinch out gesture. */ -@RequiresDevice @RunWith(Parameterized::class) @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class) @FixMethodOrder(MethodSorters.NAME_ASCENDING) -open class ExpandPipOnPinchOpenTest(flicker: LegacyFlickerTest) : PipTransition(flicker) { +class ExpandPipOnPinchOpenTest(flicker: LegacyFlickerTest) : PipTransition(flicker) { override val thisTransition: FlickerBuilder.() -> Unit = { transitions { pipApp.pinchOpenPipWindow(wmHelper, 0.25f, 30) } } diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExpandPipOnPinchOpenTestCfArm.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExpandPipOnPinchOpenTestCfArm.kt deleted file mode 100644 index 1a1ce6823f3b..000000000000 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExpandPipOnPinchOpenTestCfArm.kt +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (C) 2023 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.wm.shell.flicker.pip - -import android.tools.common.Rotation -import android.tools.device.flicker.junit.FlickerParametersRunnerFactory -import android.tools.device.flicker.legacy.LegacyFlickerTest -import android.tools.device.flicker.legacy.LegacyFlickerTestFactory -import org.junit.FixMethodOrder -import org.junit.runner.RunWith -import org.junit.runners.MethodSorters -import org.junit.runners.Parameterized - -@RunWith(Parameterized::class) -@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class) -@FixMethodOrder(MethodSorters.NAME_ASCENDING) -class ExpandPipOnPinchOpenTestCfArm(flicker: LegacyFlickerTest) : - ExpandPipOnPinchOpenTest(flicker) { - companion object { - /** - * Creates the test configurations. - * - * See [LegacyFlickerTestFactory.nonRotationTests] for configuring screen orientation and - * navigation modes. - */ - @Parameterized.Parameters(name = "{0}") - @JvmStatic - fun getParams() = - LegacyFlickerTestFactory.nonRotationTests( - supportedRotations = listOf(Rotation.ROTATION_0) - ) - } -} diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipDownOnShelfHeightChange.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipDownOnShelfHeightChange.kt index 4f88184e3c20..2993af7df600 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipDownOnShelfHeightChange.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipDownOnShelfHeightChange.kt @@ -16,12 +16,13 @@ package com.android.wm.shell.flicker.pip +import android.platform.test.annotations.FlakyTest import android.platform.test.annotations.Presubmit import android.tools.device.flicker.junit.FlickerParametersRunnerFactory import android.tools.device.flicker.legacy.FlickerBuilder import android.tools.device.flicker.legacy.LegacyFlickerTest import androidx.test.filters.RequiresDevice -import com.android.wm.shell.flicker.Direction +import com.android.wm.shell.flicker.utils.Direction import org.junit.FixMethodOrder import org.junit.Test import org.junit.runner.RunWith @@ -63,8 +64,11 @@ class MovePipDownOnShelfHeightChange(flicker: LegacyFlickerTest) : } /** Checks that the visible region of [pipApp] window always moves down during the animation. */ - @Presubmit @Test fun pipWindowMovesDown() = pipWindowMoves(Direction.DOWN) + @FlakyTest(bugId = 292813143) @Test fun pipWindowMovesDown() = pipWindowMoves(Direction.DOWN) /** Checks that the visible region of [pipApp] layer always moves down during the animation. */ - @Presubmit @Test fun pipLayerMovesDown() = pipLayerMoves(Direction.DOWN) + @FlakyTest(bugId = 292813143) + @Presubmit + @Test + fun pipLayerMovesDown() = pipLayerMoves(Direction.DOWN) } diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipOnImeVisibilityChangeTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipOnImeVisibilityChangeTest.kt index dffc822e7aec..c10860a5396f 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipOnImeVisibilityChangeTest.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipOnImeVisibilityChangeTest.kt @@ -25,7 +25,6 @@ import android.tools.device.flicker.legacy.FlickerBuilder import android.tools.device.flicker.legacy.LegacyFlickerTest import android.tools.device.flicker.legacy.LegacyFlickerTestFactory import android.tools.device.helpers.WindowUtils -import androidx.test.filters.RequiresDevice import com.android.server.wm.flicker.helpers.ImeAppHelper import com.android.server.wm.flicker.helpers.setRotation import org.junit.FixMethodOrder @@ -35,11 +34,10 @@ import org.junit.runners.MethodSorters import org.junit.runners.Parameterized /** Test Pip launch. To run this test: `atest WMShellFlickerTests:PipKeyboardTest` */ -@RequiresDevice @RunWith(Parameterized::class) @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class) @FixMethodOrder(MethodSorters.NAME_ASCENDING) -open class MovePipOnImeVisibilityChangeTest(flicker: LegacyFlickerTest) : PipTransition(flicker) { +class MovePipOnImeVisibilityChangeTest(flicker: LegacyFlickerTest) : PipTransition(flicker) { private val imeApp = ImeAppHelper(instrumentation) override val thisTransition: FlickerBuilder.() -> Unit = { diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipOnImeVisibilityChangeTestCfArm.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipOnImeVisibilityChangeTestCfArm.kt deleted file mode 100644 index 63292a4f2ca3..000000000000 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipOnImeVisibilityChangeTestCfArm.kt +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (C) 2023 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.wm.shell.flicker.pip - -import android.tools.common.Rotation -import android.tools.common.flicker.assertions.FlickerTest -import android.tools.device.flicker.junit.FlickerParametersRunnerFactory -import android.tools.device.flicker.legacy.LegacyFlickerTest -import android.tools.device.flicker.legacy.LegacyFlickerTestFactory -import org.junit.FixMethodOrder -import org.junit.runner.RunWith -import org.junit.runners.MethodSorters -import org.junit.runners.Parameterized - -@RunWith(Parameterized::class) -@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class) -@FixMethodOrder(MethodSorters.NAME_ASCENDING) -class MovePipOnImeVisibilityChangeTestCfArm(flicker: LegacyFlickerTest) : - MovePipOnImeVisibilityChangeTest(flicker) { - companion object { - private const val TAG_IME_VISIBLE = "imeIsVisible" - - @Parameterized.Parameters(name = "{0}") - @JvmStatic - fun getParams(): Collection<FlickerTest> { - return LegacyFlickerTestFactory.nonRotationTests( - supportedRotations = listOf(Rotation.ROTATION_0) - ) - } - } -} diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipShelfHeightTransition.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipShelfHeightTransition.kt index 9a2fa095c8cb..a8fb63de244b 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipShelfHeightTransition.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipShelfHeightTransition.kt @@ -22,7 +22,7 @@ import android.tools.common.flicker.subject.region.RegionSubject import android.tools.device.flicker.legacy.LegacyFlickerTest import android.tools.device.flicker.legacy.LegacyFlickerTestFactory import com.android.server.wm.flicker.helpers.FixedOrientationAppHelper -import com.android.wm.shell.flicker.Direction +import com.android.wm.shell.flicker.utils.Direction import org.junit.Test import org.junit.runners.Parameterized diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipUpOnShelfHeightChangeTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipUpOnShelfHeightChangeTest.kt index afb4af6c5b21..992f1bc4ace3 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipUpOnShelfHeightChangeTest.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipUpOnShelfHeightChangeTest.kt @@ -21,7 +21,7 @@ import android.tools.device.flicker.junit.FlickerParametersRunnerFactory import android.tools.device.flicker.legacy.FlickerBuilder import android.tools.device.flicker.legacy.LegacyFlickerTest import androidx.test.filters.RequiresDevice -import com.android.wm.shell.flicker.Direction +import com.android.wm.shell.flicker.utils.Direction import org.junit.FixMethodOrder import org.junit.Test import org.junit.runner.RunWith diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ShowPipAndRotateDisplay.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ShowPipAndRotateDisplay.kt index 0ff9cfff873e..e588f8793b82 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ShowPipAndRotateDisplay.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ShowPipAndRotateDisplay.kt @@ -23,7 +23,6 @@ import android.tools.device.flicker.legacy.FlickerBuilder import android.tools.device.flicker.legacy.LegacyFlickerTest import android.tools.device.flicker.legacy.LegacyFlickerTestFactory import android.tools.device.helpers.WindowUtils -import androidx.test.filters.RequiresDevice import com.android.server.wm.flicker.helpers.SimpleAppHelper import com.android.server.wm.flicker.helpers.setRotation import org.junit.FixMethodOrder @@ -55,11 +54,10 @@ import org.junit.runners.Parameterized * apps are running before setup * ``` */ -@RequiresDevice @RunWith(Parameterized::class) @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class) @FixMethodOrder(MethodSorters.NAME_ASCENDING) -open class ShowPipAndRotateDisplay(flicker: LegacyFlickerTest) : PipTransition(flicker) { +class ShowPipAndRotateDisplay(flicker: LegacyFlickerTest) : PipTransition(flicker) { private val testApp = SimpleAppHelper(instrumentation) private val screenBoundsStart = WindowUtils.getDisplayBounds(flicker.scenario.startRotation) private val screenBoundsEnd = WindowUtils.getDisplayBounds(flicker.scenario.endRotation) diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ShowPipAndRotateDisplayCfArm.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ShowPipAndRotateDisplayCfArm.kt deleted file mode 100644 index 25164711b2e5..000000000000 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ShowPipAndRotateDisplayCfArm.kt +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (C) 2023 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.wm.shell.flicker.pip - -import android.tools.common.flicker.assertions.FlickerTest -import android.tools.device.flicker.junit.FlickerParametersRunnerFactory -import android.tools.device.flicker.legacy.LegacyFlickerTest -import android.tools.device.flicker.legacy.LegacyFlickerTestFactory -import org.junit.FixMethodOrder -import org.junit.runner.RunWith -import org.junit.runners.MethodSorters -import org.junit.runners.Parameterized - -@RunWith(Parameterized::class) -@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class) -@FixMethodOrder(MethodSorters.NAME_ASCENDING) -class ShowPipAndRotateDisplayCfArm(flicker: LegacyFlickerTest) : ShowPipAndRotateDisplay(flicker) { - companion object { - /** - * Creates the test configurations. - * - * See [LegacyFlickerTestFactory.nonRotationTests] for configuring repetitions, screen - * orientation and navigation modes. - */ - @Parameterized.Parameters(name = "{0}") - @JvmStatic - fun getParams(): Collection<FlickerTest> { - return LegacyFlickerTestFactory.rotationTests() - } - } -} diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/tv/TvPipMenuTests.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/tv/TvPipMenuTests.kt index 0432a8497fbe..d4cd6da4acb1 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/tv/TvPipMenuTests.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/tv/TvPipMenuTests.kt @@ -20,8 +20,8 @@ import android.graphics.Rect import androidx.test.filters.RequiresDevice import androidx.test.uiautomator.UiObject2 import com.android.server.wm.flicker.testapp.ActivityOptions -import com.android.wm.shell.flicker.SYSTEM_UI_PACKAGE_NAME -import com.android.wm.shell.flicker.wait +import com.android.wm.shell.flicker.utils.SYSTEM_UI_PACKAGE_NAME +import com.android.wm.shell.flicker.utils.wait import org.junit.Assert.assertNull import org.junit.Assert.assertTrue import org.junit.Before diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/tv/TvPipNotificationTests.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/tv/TvPipNotificationTests.kt index 90406c510bad..4402e2153e9b 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/tv/TvPipNotificationTests.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/tv/TvPipNotificationTests.kt @@ -21,11 +21,11 @@ import android.app.PendingIntent import android.os.Bundle import android.service.notification.StatusBarNotification import androidx.test.filters.RequiresDevice -import com.android.wm.shell.flicker.NotificationListener.Companion.findNotification -import com.android.wm.shell.flicker.NotificationListener.Companion.startNotificationListener -import com.android.wm.shell.flicker.NotificationListener.Companion.stopNotificationListener -import com.android.wm.shell.flicker.NotificationListener.Companion.waitForNotificationToAppear -import com.android.wm.shell.flicker.NotificationListener.Companion.waitForNotificationToDisappear +import com.android.wm.shell.flicker.utils.NotificationListener.Companion.findNotification +import com.android.wm.shell.flicker.utils.NotificationListener.Companion.startNotificationListener +import com.android.wm.shell.flicker.utils.NotificationListener.Companion.stopNotificationListener +import com.android.wm.shell.flicker.utils.NotificationListener.Companion.waitForNotificationToAppear +import com.android.wm.shell.flicker.utils.NotificationListener.Companion.waitForNotificationToDisappear import org.junit.After import org.junit.Assert.assertNotNull import org.junit.Assert.assertNull diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/tv/TvPipTestBase.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/tv/TvPipTestBase.kt index 6104b7bdacba..47bff8de377e 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/tv/TvPipTestBase.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/tv/TvPipTestBase.kt @@ -24,7 +24,7 @@ import android.tools.device.helpers.wakeUpAndGoToHomeScreen import android.tools.device.traces.parsers.WindowManagerStateHelper import android.view.Surface.ROTATION_0 import android.view.Surface.rotationToString -import com.android.wm.shell.flicker.SYSTEM_UI_PACKAGE_NAME +import com.android.wm.shell.flicker.utils.SYSTEM_UI_PACKAGE_NAME import org.junit.After import org.junit.Assert.assertFalse import org.junit.Assume.assumeTrue diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/tv/TvUtils.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/tv/TvUtils.kt index b0adbe1d07ce..4aee61ade10e 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/tv/TvUtils.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/tv/TvUtils.kt @@ -22,7 +22,7 @@ import androidx.test.uiautomator.BySelector import androidx.test.uiautomator.UiDevice import androidx.test.uiautomator.UiObject2 import androidx.test.uiautomator.Until -import com.android.wm.shell.flicker.SYSTEM_UI_PACKAGE_NAME +import com.android.wm.shell.flicker.utils.SYSTEM_UI_PACKAGE_NAME /** Id of the root view in the com.android.wm.shell.pip.tv.PipMenuActivity */ private const val TV_PIP_MENU_ROOT_ID = "tv_pip_menu" diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/Utils.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/Utils.kt index 610cedefe594..a0023c0d969e 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/Utils.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/Utils.kt @@ -22,9 +22,7 @@ import android.platform.test.rule.PressHomeRule import android.platform.test.rule.UnlockScreenRule import android.tools.common.NavBar import android.tools.common.Rotation -import android.tools.device.apphelpers.MessagingAppHelper import android.tools.device.flicker.rules.ChangeDisplayOrientationRule -import android.tools.device.flicker.rules.LaunchAppRule import android.tools.device.flicker.rules.RemoveAllTasksButHomeRule import androidx.test.platform.app.InstrumentationRegistry import org.junit.rules.RuleChain @@ -37,9 +35,6 @@ object Utils { .around( NavigationModeRule(navigationMode.value, /* changeNavigationModeAfterTest */ false) ) - .around( - LaunchAppRule(MessagingAppHelper(instrumentation), clearCacheAfterParsing = false) - ) .around(RemoveAllTasksButHomeRule()) .around( ChangeDisplayOrientationRule( diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/OWNERS b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/OWNERS new file mode 100644 index 000000000000..3ab6a1ee061d --- /dev/null +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/OWNERS @@ -0,0 +1,2 @@ +# Android > Android OS & Apps > Framework (Java + Native) > Window Manager > WM Shell > Split Screen +# Bug component: 928697 diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/SplitScreenUtils.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/SplitScreenUtils.kt deleted file mode 100644 index e640dc404623..000000000000 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/SplitScreenUtils.kt +++ /dev/null @@ -1,387 +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.wm.shell.flicker.service.splitscreen - -import android.app.Instrumentation -import android.graphics.Point -import android.os.SystemClock -import android.tools.common.traces.component.ComponentNameMatcher -import android.tools.common.traces.component.IComponentMatcher -import android.tools.common.traces.component.IComponentNameMatcher -import android.tools.device.apphelpers.StandardAppHelper -import android.tools.device.traces.parsers.WindowManagerStateHelper -import android.tools.device.traces.parsers.toFlickerComponent -import android.view.InputDevice -import android.view.MotionEvent -import android.view.ViewConfiguration -import androidx.test.uiautomator.By -import androidx.test.uiautomator.BySelector -import androidx.test.uiautomator.UiDevice -import androidx.test.uiautomator.UiObject2 -import androidx.test.uiautomator.Until -import com.android.launcher3.tapl.LauncherInstrumentation -import com.android.server.wm.flicker.helpers.ImeAppHelper -import com.android.server.wm.flicker.helpers.NonResizeableAppHelper -import com.android.server.wm.flicker.helpers.NotificationAppHelper -import com.android.server.wm.flicker.helpers.SimpleAppHelper -import com.android.server.wm.flicker.testapp.ActivityOptions -import com.android.wm.shell.flicker.LAUNCHER_UI_PACKAGE_NAME -import com.android.wm.shell.flicker.SYSTEM_UI_PACKAGE_NAME -import org.junit.Assert.assertNotNull - -object SplitScreenUtils { - private const val TIMEOUT_MS = 3_000L - private const val DRAG_DURATION_MS = 1_000L - private const val NOTIFICATION_SCROLLER = "notification_stack_scroller" - private const val DIVIDER_BAR = "docked_divider_handle" - private const val OVERVIEW_SNAPSHOT = "snapshot" - private const val GESTURE_STEP_MS = 16L - private val LONG_PRESS_TIME_MS = ViewConfiguration.getLongPressTimeout() * 2L - private val SPLIT_DECOR_MANAGER = ComponentNameMatcher("", "SplitDecorManager#") - - private val notificationScrollerSelector: BySelector - get() = By.res(SYSTEM_UI_PACKAGE_NAME, NOTIFICATION_SCROLLER) - private val notificationContentSelector: BySelector - get() = By.text("Flicker Test Notification") - private val dividerBarSelector: BySelector - get() = By.res(SYSTEM_UI_PACKAGE_NAME, DIVIDER_BAR) - private val overviewSnapshotSelector: BySelector - get() = By.res(LAUNCHER_UI_PACKAGE_NAME, OVERVIEW_SNAPSHOT) - - fun getPrimary(instrumentation: Instrumentation): StandardAppHelper = - SimpleAppHelper( - instrumentation, - ActivityOptions.SplitScreen.Primary.LABEL, - ActivityOptions.SplitScreen.Primary.COMPONENT.toFlickerComponent() - ) - - fun getSecondary(instrumentation: Instrumentation): StandardAppHelper = - SimpleAppHelper( - instrumentation, - ActivityOptions.SplitScreen.Secondary.LABEL, - ActivityOptions.SplitScreen.Secondary.COMPONENT.toFlickerComponent() - ) - - fun getNonResizeable(instrumentation: Instrumentation): NonResizeableAppHelper = - NonResizeableAppHelper(instrumentation) - - fun getSendNotification(instrumentation: Instrumentation): NotificationAppHelper = - NotificationAppHelper(instrumentation) - - fun getIme(instrumentation: Instrumentation): ImeAppHelper = ImeAppHelper(instrumentation) - - fun waitForSplitComplete( - wmHelper: WindowManagerStateHelper, - primaryApp: IComponentMatcher, - secondaryApp: IComponentMatcher, - ) { - wmHelper - .StateSyncBuilder() - .withWindowSurfaceAppeared(primaryApp) - .withWindowSurfaceAppeared(secondaryApp) - .withSplitDividerVisible() - .waitForAndVerify() - } - - fun enterSplit( - wmHelper: WindowManagerStateHelper, - tapl: LauncherInstrumentation, - device: UiDevice, - primaryApp: StandardAppHelper, - secondaryApp: StandardAppHelper - ) { - primaryApp.launchViaIntent(wmHelper) - secondaryApp.launchViaIntent(wmHelper) - tapl.goHome() - wmHelper.StateSyncBuilder().withHomeActivityVisible().waitForAndVerify() - splitFromOverview(tapl, device) - waitForSplitComplete(wmHelper, primaryApp, secondaryApp) - } - - fun splitFromOverview(tapl: LauncherInstrumentation, device: UiDevice) { - // Note: The initial split position in landscape is different between tablet and phone. - // In landscape, tablet will let the first app split to right side, and phone will - // split to left side. - if (tapl.isTablet) { - // TAPL's currentTask on tablet is sometimes not what we expected if the overview - // contains more than 3 task views. We need to use uiautomator directly to find the - // second task to split. - tapl.workspace.switchToOverview().overviewActions.clickSplit() - val snapshots = device.wait(Until.findObjects(overviewSnapshotSelector), TIMEOUT_MS) - if (snapshots == null || snapshots.size < 1) { - error("Fail to find a overview snapshot to split.") - } - - // Find the second task in the upper right corner in split select mode by sorting - // 'left' in descending order and 'top' in ascending order. - snapshots.sortWith { t1: UiObject2, t2: UiObject2 -> - t2.getVisibleBounds().left - t1.getVisibleBounds().left - } - snapshots.sortWith { t1: UiObject2, t2: UiObject2 -> - t1.getVisibleBounds().top - t2.getVisibleBounds().top - } - snapshots[0].click() - } else { - tapl.workspace - .switchToOverview() - .currentTask - .tapMenu() - .tapSplitMenuItem() - .currentTask - .open() - } - SystemClock.sleep(TIMEOUT_MS) - } - - fun enterSplitViaIntent( - wmHelper: WindowManagerStateHelper, - primaryApp: StandardAppHelper, - secondaryApp: StandardAppHelper - ) { - val stringExtras = - mapOf(ActivityOptions.SplitScreen.Primary.EXTRA_LAUNCH_ADJACENT to "true") - primaryApp.launchViaIntent(wmHelper, null, null, stringExtras) - SplitScreenUtils.waitForSplitComplete(wmHelper, primaryApp, secondaryApp) - } - - fun dragFromNotificationToSplit( - instrumentation: Instrumentation, - device: UiDevice, - wmHelper: WindowManagerStateHelper - ) { - val displayBounds = - wmHelper.currentState.layerState.displays.firstOrNull { !it.isVirtual }?.layerStackSpace - ?: error("Display not found") - - // Pull down the notifications - device.swipe( - displayBounds.centerX(), - 5, - displayBounds.centerX(), - displayBounds.bottom, - 50 /* steps */ - ) - SystemClock.sleep(TIMEOUT_MS) - - // Find the target notification - val notificationScroller = - device.wait(Until.findObject(notificationScrollerSelector), TIMEOUT_MS) - ?: error("Unable to find view $notificationScrollerSelector") - var notificationContent = notificationScroller.findObject(notificationContentSelector) - - while (notificationContent == null) { - device.swipe( - displayBounds.centerX(), - displayBounds.centerY(), - displayBounds.centerX(), - displayBounds.centerY() - 150, - 20 /* steps */ - ) - notificationContent = notificationScroller.findObject(notificationContentSelector) - } - - // Drag to split - val dragStart = notificationContent.visibleCenter - val dragMiddle = Point(dragStart.x + 50, dragStart.y) - val dragEnd = Point(displayBounds.width / 4, displayBounds.width / 4) - val downTime = SystemClock.uptimeMillis() - - touch(instrumentation, MotionEvent.ACTION_DOWN, downTime, downTime, TIMEOUT_MS, dragStart) - // It needs a horizontal movement to trigger the drag - touchMove( - instrumentation, - downTime, - SystemClock.uptimeMillis(), - DRAG_DURATION_MS, - dragStart, - dragMiddle - ) - touchMove( - instrumentation, - downTime, - SystemClock.uptimeMillis(), - DRAG_DURATION_MS, - dragMiddle, - dragEnd - ) - // Wait for a while to start splitting - SystemClock.sleep(TIMEOUT_MS) - touch( - instrumentation, - MotionEvent.ACTION_UP, - downTime, - SystemClock.uptimeMillis(), - GESTURE_STEP_MS, - dragEnd - ) - SystemClock.sleep(TIMEOUT_MS) - } - - fun touch( - instrumentation: Instrumentation, - action: Int, - downTime: Long, - eventTime: Long, - duration: Long, - point: Point - ) { - val motionEvent = - MotionEvent.obtain(downTime, eventTime, action, point.x.toFloat(), point.y.toFloat(), 0) - motionEvent.source = InputDevice.SOURCE_TOUCHSCREEN - instrumentation.uiAutomation.injectInputEvent(motionEvent, true) - motionEvent.recycle() - SystemClock.sleep(duration) - } - - fun touchMove( - instrumentation: Instrumentation, - downTime: Long, - eventTime: Long, - duration: Long, - from: Point, - to: Point - ) { - val steps: Long = duration / GESTURE_STEP_MS - var currentTime = eventTime - var currentX = from.x.toFloat() - var currentY = from.y.toFloat() - val stepX = (to.x.toFloat() - from.x.toFloat()) / steps.toFloat() - val stepY = (to.y.toFloat() - from.y.toFloat()) / steps.toFloat() - - for (i in 1..steps) { - val motionMove = - MotionEvent.obtain( - downTime, - currentTime, - MotionEvent.ACTION_MOVE, - currentX, - currentY, - 0 - ) - motionMove.source = InputDevice.SOURCE_TOUCHSCREEN - instrumentation.uiAutomation.injectInputEvent(motionMove, true) - motionMove.recycle() - - currentTime += GESTURE_STEP_MS - if (i == steps - 1) { - currentX = to.x.toFloat() - currentY = to.y.toFloat() - } else { - currentX += stepX - currentY += stepY - } - SystemClock.sleep(GESTURE_STEP_MS) - } - } - - fun createShortcutOnHotseatIfNotExist(tapl: LauncherInstrumentation, appName: String) { - tapl.workspace.deleteAppIcon(tapl.workspace.getHotseatAppIcon(0)) - val allApps = tapl.workspace.switchToAllApps() - allApps.freeze() - try { - allApps.getAppIcon(appName).dragToHotseat(0) - } finally { - allApps.unfreeze() - } - } - - fun dragDividerToResizeAndWait(device: UiDevice, wmHelper: WindowManagerStateHelper) { - val displayBounds = - wmHelper.currentState.layerState.displays.firstOrNull { !it.isVirtual }?.layerStackSpace - ?: error("Display not found") - val dividerBar = device.wait(Until.findObject(dividerBarSelector), TIMEOUT_MS) - dividerBar.drag(Point(displayBounds.width * 1 / 3, displayBounds.height * 2 / 3), 200) - - wmHelper - .StateSyncBuilder() - .withWindowSurfaceDisappeared(SPLIT_DECOR_MANAGER) - .waitForAndVerify() - } - - fun dragDividerToDismissSplit( - device: UiDevice, - wmHelper: WindowManagerStateHelper, - dragToRight: Boolean, - dragToBottom: Boolean - ) { - val displayBounds = - wmHelper.currentState.layerState.displays.firstOrNull { !it.isVirtual }?.layerStackSpace - ?: error("Display not found") - val dividerBar = device.wait(Until.findObject(dividerBarSelector), TIMEOUT_MS) - dividerBar.drag( - Point( - if (dragToRight) { - displayBounds.width * 4 / 5 - } else { - displayBounds.width * 1 / 5 - }, - if (dragToBottom) { - displayBounds.height * 4 / 5 - } else { - displayBounds.height * 1 / 5 - } - ) - ) - } - - fun doubleTapDividerToSwitch(device: UiDevice) { - val dividerBar = device.wait(Until.findObject(dividerBarSelector), TIMEOUT_MS) - val interval = - (ViewConfiguration.getDoubleTapTimeout() + ViewConfiguration.getDoubleTapMinTime()) / 2 - dividerBar.click() - SystemClock.sleep(interval.toLong()) - dividerBar.click() - } - - fun copyContentInSplit( - instrumentation: Instrumentation, - device: UiDevice, - sourceApp: IComponentNameMatcher, - destinationApp: IComponentNameMatcher, - ) { - // Copy text from sourceApp - val textView = - device.wait( - Until.findObject(By.res(sourceApp.packageName, "SplitScreenTest")), - TIMEOUT_MS - ) - assertNotNull("Unable to find the TextView", textView) - textView.click(LONG_PRESS_TIME_MS) - - val copyBtn = device.wait(Until.findObject(By.text("Copy")), TIMEOUT_MS) - assertNotNull("Unable to find the copy button", copyBtn) - copyBtn.click() - - // Paste text to destinationApp - val editText = - device.wait( - Until.findObject(By.res(destinationApp.packageName, "plain_text_input")), - TIMEOUT_MS - ) - assertNotNull("Unable to find the EditText", editText) - editText.click(LONG_PRESS_TIME_MS) - - val pasteBtn = device.wait(Until.findObject(By.text("Paste")), TIMEOUT_MS) - assertNotNull("Unable to find the paste button", pasteBtn) - pasteBtn.click() - - // Verify text - if (!textView.text.contentEquals(editText.text)) { - error("Fail to copy content in split") - } - } -} diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/benchmark/UnlockKeyguardToSplitScreenGesturalNavLandscapeBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/benchmark/UnlockKeyguardToSplitScreenGesturalNavLandscapeBenchmark.kt deleted file mode 100644 index c402aa4444d8..000000000000 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/benchmark/UnlockKeyguardToSplitScreenGesturalNavLandscapeBenchmark.kt +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (C) 2023 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.wm.shell.flicker.service.splitscreen.benchmark - -import android.platform.test.annotations.PlatinumTest -import android.platform.test.annotations.Presubmit -import androidx.test.filters.RequiresDevice -import com.android.wm.shell.flicker.service.splitscreen.scenarios.UnlockKeyguardToSplitScreen -import org.junit.Test -import org.junit.runner.RunWith -import org.junit.runners.BlockJUnit4ClassRunner - -@RequiresDevice -@RunWith(BlockJUnit4ClassRunner::class) -class UnlockKeyguardToSplitScreenGesturalNavLandscapeBenchmark : UnlockKeyguardToSplitScreen() { - @PlatinumTest(focusArea = "sysui") - @Presubmit - @Test - override fun unlockKeyguardToSplitScreen() = super.unlockKeyguardToSplitScreen() -} diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/benchmark/UnlockKeyguardToSplitScreenGesturalNavPortraitBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/benchmark/UnlockKeyguardToSplitScreenGesturalNavPortraitBenchmark.kt deleted file mode 100644 index 840401c23a91..000000000000 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/benchmark/UnlockKeyguardToSplitScreenGesturalNavPortraitBenchmark.kt +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (C) 2023 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.wm.shell.flicker.service.splitscreen.benchmark - -import android.platform.test.annotations.PlatinumTest -import android.platform.test.annotations.Presubmit -import androidx.test.filters.RequiresDevice -import com.android.wm.shell.flicker.service.splitscreen.scenarios.UnlockKeyguardToSplitScreen -import org.junit.Test -import org.junit.runner.RunWith -import org.junit.runners.BlockJUnit4ClassRunner - -@RequiresDevice -@RunWith(BlockJUnit4ClassRunner::class) -class UnlockKeyguardToSplitScreenGesturalNavPortraitBenchmark : UnlockKeyguardToSplitScreen() { - @PlatinumTest(focusArea = "sysui") - @Presubmit - @Test - override fun unlockKeyguardToSplitScreen() = super.unlockKeyguardToSplitScreen() -} diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/CopyContentInSplitGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/CopyContentInSplitGesturalNavLandscape.kt deleted file mode 100644 index a5c512267508..000000000000 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/CopyContentInSplitGesturalNavLandscape.kt +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (C) 2023 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.wm.shell.flicker.service.splitscreen.flicker - -import android.tools.common.Rotation -import android.tools.common.flicker.FlickerConfig -import android.tools.common.flicker.annotation.ExpectedScenarios -import android.tools.common.flicker.annotation.FlickerConfigProvider -import android.tools.common.flicker.config.FlickerConfig -import android.tools.common.flicker.config.FlickerServiceConfig -import android.tools.device.flicker.junit.FlickerServiceJUnit4ClassRunner -import com.android.wm.shell.flicker.service.splitscreen.scenarios.CopyContentInSplit -import org.junit.Test -import org.junit.runner.RunWith - -@RunWith(FlickerServiceJUnit4ClassRunner::class) -class CopyContentInSplitGesturalNavLandscape : CopyContentInSplit(Rotation.ROTATION_90) { - @ExpectedScenarios([]) @Test override fun copyContentInSplit() = super.copyContentInSplit() - - companion object { - @JvmStatic - @FlickerConfigProvider - fun flickerConfigProvider(): FlickerConfig = - FlickerConfig().use(FlickerServiceConfig.DEFAULT) - } -} diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/CopyContentInSplitGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/CopyContentInSplitGesturalNavPortrait.kt deleted file mode 100644 index 092fb6720e57..000000000000 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/CopyContentInSplitGesturalNavPortrait.kt +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (C) 2023 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.wm.shell.flicker.service.splitscreen.flicker - -import android.tools.common.Rotation -import android.tools.common.flicker.FlickerConfig -import android.tools.common.flicker.annotation.ExpectedScenarios -import android.tools.common.flicker.annotation.FlickerConfigProvider -import android.tools.common.flicker.config.FlickerConfig -import android.tools.common.flicker.config.FlickerServiceConfig -import android.tools.device.flicker.junit.FlickerServiceJUnit4ClassRunner -import com.android.wm.shell.flicker.service.splitscreen.scenarios.CopyContentInSplit -import org.junit.Test -import org.junit.runner.RunWith - -@RunWith(FlickerServiceJUnit4ClassRunner::class) -class CopyContentInSplitGesturalNavPortrait : CopyContentInSplit(Rotation.ROTATION_0) { - @ExpectedScenarios([]) @Test override fun copyContentInSplit() = super.copyContentInSplit() - - companion object { - @JvmStatic - @FlickerConfigProvider - fun flickerConfigProvider(): FlickerConfig = - FlickerConfig().use(FlickerServiceConfig.DEFAULT) - } -} diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/DismissSplitScreenByDividerGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/DismissSplitScreenByDividerGesturalNavLandscape.kt deleted file mode 100644 index 8cb25fe531b8..000000000000 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/DismissSplitScreenByDividerGesturalNavLandscape.kt +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (C) 2023 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.wm.shell.flicker.service.splitscreen.flicker - -import android.tools.common.Rotation -import android.tools.common.flicker.FlickerConfig -import android.tools.common.flicker.annotation.ExpectedScenarios -import android.tools.common.flicker.annotation.FlickerConfigProvider -import android.tools.common.flicker.config.FlickerConfig -import android.tools.common.flicker.config.FlickerServiceConfig -import android.tools.device.flicker.junit.FlickerServiceJUnit4ClassRunner -import com.android.wm.shell.flicker.service.splitscreen.scenarios.DismissSplitScreenByDivider -import org.junit.Test -import org.junit.runner.RunWith - -@RunWith(FlickerServiceJUnit4ClassRunner::class) -class DismissSplitScreenByDividerGesturalNavLandscape : - DismissSplitScreenByDivider(Rotation.ROTATION_90) { - - @ExpectedScenarios(["SPLIT_SCREEN_EXIT"]) - @Test - override fun dismissSplitScreenByDivider() = super.dismissSplitScreenByDivider() - - companion object { - @JvmStatic - @FlickerConfigProvider - fun flickerConfigProvider(): FlickerConfig = - FlickerConfig().use(FlickerServiceConfig.DEFAULT) - } -} diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/DismissSplitScreenByDividerGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/DismissSplitScreenByDividerGesturalNavPortrait.kt deleted file mode 100644 index fa1be63296e0..000000000000 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/DismissSplitScreenByDividerGesturalNavPortrait.kt +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (C) 2023 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.wm.shell.flicker.service.splitscreen.flicker - -import android.tools.common.Rotation -import android.tools.common.flicker.FlickerConfig -import android.tools.common.flicker.annotation.ExpectedScenarios -import android.tools.common.flicker.annotation.FlickerConfigProvider -import android.tools.common.flicker.config.FlickerConfig -import android.tools.common.flicker.config.FlickerServiceConfig -import android.tools.device.flicker.junit.FlickerServiceJUnit4ClassRunner -import com.android.wm.shell.flicker.service.splitscreen.scenarios.DismissSplitScreenByDivider -import org.junit.Test -import org.junit.runner.RunWith - -@RunWith(FlickerServiceJUnit4ClassRunner::class) -class DismissSplitScreenByDividerGesturalNavPortrait : - DismissSplitScreenByDivider(Rotation.ROTATION_0) { - - @ExpectedScenarios(["SPLIT_SCREEN_EXIT"]) - @Test - override fun dismissSplitScreenByDivider() = super.dismissSplitScreenByDivider() - - companion object { - @JvmStatic - @FlickerConfigProvider - fun flickerConfigProvider(): FlickerConfig = - FlickerConfig().use(FlickerServiceConfig.DEFAULT) - } -} diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/DismissSplitScreenByGoHomeGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/DismissSplitScreenByGoHomeGesturalNavLandscape.kt deleted file mode 100644 index aa35237b615f..000000000000 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/DismissSplitScreenByGoHomeGesturalNavLandscape.kt +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (C) 2023 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.wm.shell.flicker.service.splitscreen.flicker - -import android.tools.common.Rotation -import android.tools.common.flicker.FlickerConfig -import android.tools.common.flicker.annotation.ExpectedScenarios -import android.tools.common.flicker.annotation.FlickerConfigProvider -import android.tools.common.flicker.config.FlickerConfig -import android.tools.common.flicker.config.FlickerServiceConfig -import android.tools.device.flicker.junit.FlickerServiceJUnit4ClassRunner -import com.android.wm.shell.flicker.service.splitscreen.scenarios.DismissSplitScreenByGoHome -import org.junit.Test -import org.junit.runner.RunWith - -@RunWith(FlickerServiceJUnit4ClassRunner::class) -class DismissSplitScreenByGoHomeGesturalNavLandscape : - DismissSplitScreenByGoHome(Rotation.ROTATION_90) { - - @ExpectedScenarios(["SPLIT_SCREEN_EXIT"]) - @Test - override fun dismissSplitScreenByGoHome() = super.dismissSplitScreenByGoHome() - - companion object { - @JvmStatic - @FlickerConfigProvider - fun flickerConfigProvider(): FlickerConfig = - FlickerConfig().use(FlickerServiceConfig.DEFAULT) - } -} diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/DismissSplitScreenByGoHomeGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/DismissSplitScreenByGoHomeGesturalNavPortrait.kt deleted file mode 100644 index e195360cdc36..000000000000 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/DismissSplitScreenByGoHomeGesturalNavPortrait.kt +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (C) 2023 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.wm.shell.flicker.service.splitscreen.flicker - -import android.tools.common.Rotation -import android.tools.common.flicker.FlickerConfig -import android.tools.common.flicker.annotation.ExpectedScenarios -import android.tools.common.flicker.annotation.FlickerConfigProvider -import android.tools.common.flicker.config.FlickerConfig -import android.tools.common.flicker.config.FlickerServiceConfig -import android.tools.device.flicker.junit.FlickerServiceJUnit4ClassRunner -import com.android.wm.shell.flicker.service.splitscreen.scenarios.DismissSplitScreenByGoHome -import org.junit.Test -import org.junit.runner.RunWith - -@RunWith(FlickerServiceJUnit4ClassRunner::class) -class DismissSplitScreenByGoHomeGesturalNavPortrait : - DismissSplitScreenByGoHome(Rotation.ROTATION_0) { - - @ExpectedScenarios(["SPLIT_SCREEN_EXIT"]) - @Test - override fun dismissSplitScreenByGoHome() = super.dismissSplitScreenByGoHome() - - companion object { - @JvmStatic - @FlickerConfigProvider - fun flickerConfigProvider(): FlickerConfig = - FlickerConfig().use(FlickerServiceConfig.DEFAULT) - } -} diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/DragDividerToResizeGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/DragDividerToResizeGesturalNavLandscape.kt deleted file mode 100644 index c1b3aade11cd..000000000000 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/DragDividerToResizeGesturalNavLandscape.kt +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (C) 2023 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.wm.shell.flicker.service.splitscreen.flicker - -import android.tools.common.Rotation -import android.tools.common.flicker.FlickerConfig -import android.tools.common.flicker.annotation.ExpectedScenarios -import android.tools.common.flicker.annotation.FlickerConfigProvider -import android.tools.common.flicker.config.FlickerConfig -import android.tools.common.flicker.config.FlickerServiceConfig -import android.tools.device.flicker.junit.FlickerServiceJUnit4ClassRunner -import com.android.wm.shell.flicker.service.splitscreen.scenarios.DragDividerToResize -import org.junit.Test -import org.junit.runner.RunWith - -@RunWith(FlickerServiceJUnit4ClassRunner::class) -class DragDividerToResizeGesturalNavLandscape : DragDividerToResize(Rotation.ROTATION_90) { - - @ExpectedScenarios(["SPLIT_SCREEN_RESIZE"]) - @Test - override fun dragDividerToResize() = super.dragDividerToResize() - - companion object { - @JvmStatic - @FlickerConfigProvider - fun flickerConfigProvider(): FlickerConfig = - FlickerConfig().use(FlickerServiceConfig.DEFAULT) - } -} diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/DragDividerToResizeGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/DragDividerToResizeGesturalNavPortrait.kt deleted file mode 100644 index c6e2e854ab89..000000000000 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/DragDividerToResizeGesturalNavPortrait.kt +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (C) 2023 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.wm.shell.flicker.service.splitscreen.flicker - -import android.tools.common.Rotation -import android.tools.common.flicker.FlickerConfig -import android.tools.common.flicker.annotation.ExpectedScenarios -import android.tools.common.flicker.annotation.FlickerConfigProvider -import android.tools.common.flicker.config.FlickerConfig -import android.tools.common.flicker.config.FlickerServiceConfig -import android.tools.device.flicker.junit.FlickerServiceJUnit4ClassRunner -import com.android.wm.shell.flicker.service.splitscreen.scenarios.DragDividerToResize -import org.junit.Test -import org.junit.runner.RunWith - -@RunWith(FlickerServiceJUnit4ClassRunner::class) -class DragDividerToResizeGesturalNavPortrait : DragDividerToResize(Rotation.ROTATION_0) { - - @ExpectedScenarios(["SPLIT_SCREEN_RESIZE"]) - @Test - override fun dragDividerToResize() = super.dragDividerToResize() - - companion object { - @JvmStatic - @FlickerConfigProvider - fun flickerConfigProvider(): FlickerConfig = - FlickerConfig().use(FlickerServiceConfig.DEFAULT) - } -} diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromAllAppsGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromAllAppsGesturalNavLandscape.kt deleted file mode 100644 index 5f771c7545c7..000000000000 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromAllAppsGesturalNavLandscape.kt +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (C) 2023 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.wm.shell.flicker.service.splitscreen.flicker - -import android.tools.common.Rotation -import android.tools.common.flicker.FlickerConfig -import android.tools.common.flicker.annotation.ExpectedScenarios -import android.tools.common.flicker.annotation.FlickerConfigProvider -import android.tools.common.flicker.config.FlickerConfig -import android.tools.common.flicker.config.FlickerServiceConfig -import android.tools.device.flicker.junit.FlickerServiceJUnit4ClassRunner -import com.android.wm.shell.flicker.service.splitscreen.scenarios.EnterSplitScreenByDragFromAllApps -import org.junit.Test -import org.junit.runner.RunWith - -@RunWith(FlickerServiceJUnit4ClassRunner::class) -class EnterSplitScreenByDragFromAllAppsGesturalNavLandscape : - EnterSplitScreenByDragFromAllApps(Rotation.ROTATION_90) { - - @ExpectedScenarios(["SPLIT_SCREEN_ENTER"]) - @Test - override fun enterSplitScreenByDragFromAllApps() = super.enterSplitScreenByDragFromAllApps() - - companion object { - @JvmStatic - @FlickerConfigProvider - fun flickerConfigProvider(): FlickerConfig = - FlickerConfig().use(FlickerServiceConfig.DEFAULT) - } -} diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromAllAppsGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromAllAppsGesturalNavPortrait.kt deleted file mode 100644 index 729a401fe34c..000000000000 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromAllAppsGesturalNavPortrait.kt +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (C) 2023 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.wm.shell.flicker.service.splitscreen.flicker - -import android.tools.common.Rotation -import android.tools.common.flicker.FlickerConfig -import android.tools.common.flicker.annotation.ExpectedScenarios -import android.tools.common.flicker.annotation.FlickerConfigProvider -import android.tools.common.flicker.config.FlickerConfig -import android.tools.common.flicker.config.FlickerServiceConfig -import android.tools.device.flicker.junit.FlickerServiceJUnit4ClassRunner -import com.android.wm.shell.flicker.service.splitscreen.scenarios.EnterSplitScreenByDragFromAllApps -import org.junit.Test -import org.junit.runner.RunWith - -@RunWith(FlickerServiceJUnit4ClassRunner::class) -class EnterSplitScreenByDragFromAllAppsGesturalNavPortrait : - EnterSplitScreenByDragFromAllApps(Rotation.ROTATION_0) { - - @ExpectedScenarios(["SPLIT_SCREEN_ENTER"]) - @Test - override fun enterSplitScreenByDragFromAllApps() = super.enterSplitScreenByDragFromAllApps() - - companion object { - @JvmStatic - @FlickerConfigProvider - fun flickerConfigProvider(): FlickerConfig = - FlickerConfig().use(FlickerServiceConfig.DEFAULT) - } -} diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromNotificationGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromNotificationGesturalNavLandscape.kt deleted file mode 100644 index 6e4cf9f55cfd..000000000000 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromNotificationGesturalNavLandscape.kt +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (C) 2023 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.wm.shell.flicker.service.splitscreen.flicker - -import android.tools.common.Rotation -import android.tools.common.flicker.FlickerConfig -import android.tools.common.flicker.annotation.ExpectedScenarios -import android.tools.common.flicker.annotation.FlickerConfigProvider -import android.tools.common.flicker.config.FlickerConfig -import android.tools.common.flicker.config.FlickerServiceConfig -import android.tools.device.flicker.junit.FlickerServiceJUnit4ClassRunner -import com.android.wm.shell.flicker.service.splitscreen.scenarios.EnterSplitScreenByDragFromNotification -import org.junit.Test -import org.junit.runner.RunWith - -@RunWith(FlickerServiceJUnit4ClassRunner::class) -class EnterSplitScreenByDragFromNotificationGesturalNavLandscape : - EnterSplitScreenByDragFromNotification(Rotation.ROTATION_90) { - - @ExpectedScenarios(["SPLIT_SCREEN_ENTER"]) - @Test - override fun enterSplitScreenByDragFromNotification() = - super.enterSplitScreenByDragFromNotification() - - companion object { - @JvmStatic - @FlickerConfigProvider - fun flickerConfigProvider(): FlickerConfig = - FlickerConfig().use(FlickerServiceConfig.DEFAULT) - } -} diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromNotificationGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromNotificationGesturalNavPortrait.kt deleted file mode 100644 index cc2870213e8d..000000000000 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromNotificationGesturalNavPortrait.kt +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (C) 2023 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.wm.shell.flicker.service.splitscreen.flicker - -import android.tools.common.Rotation -import android.tools.common.flicker.FlickerConfig -import android.tools.common.flicker.annotation.ExpectedScenarios -import android.tools.common.flicker.annotation.FlickerConfigProvider -import android.tools.common.flicker.config.FlickerConfig -import android.tools.common.flicker.config.FlickerServiceConfig -import android.tools.device.flicker.junit.FlickerServiceJUnit4ClassRunner -import com.android.wm.shell.flicker.service.splitscreen.scenarios.EnterSplitScreenByDragFromNotification -import org.junit.Test -import org.junit.runner.RunWith - -@RunWith(FlickerServiceJUnit4ClassRunner::class) -class EnterSplitScreenByDragFromNotificationGesturalNavPortrait : - EnterSplitScreenByDragFromNotification(Rotation.ROTATION_0) { - - @ExpectedScenarios(["SPLIT_SCREEN_ENTER"]) - @Test - override fun enterSplitScreenByDragFromNotification() = - super.enterSplitScreenByDragFromNotification() - - companion object { - @JvmStatic - @FlickerConfigProvider - fun flickerConfigProvider(): FlickerConfig = - FlickerConfig().use(FlickerServiceConfig.DEFAULT) - } -} diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromShortcutGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromShortcutGesturalNavLandscape.kt deleted file mode 100644 index 736604f02377..000000000000 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromShortcutGesturalNavLandscape.kt +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (C) 2023 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.wm.shell.flicker.service.splitscreen.flicker - -import android.tools.common.Rotation -import android.tools.common.flicker.FlickerConfig -import android.tools.common.flicker.annotation.ExpectedScenarios -import android.tools.common.flicker.annotation.FlickerConfigProvider -import android.tools.common.flicker.config.FlickerConfig -import android.tools.common.flicker.config.FlickerServiceConfig -import android.tools.device.flicker.junit.FlickerServiceJUnit4ClassRunner -import com.android.wm.shell.flicker.service.splitscreen.scenarios.EnterSplitScreenByDragFromShortcut -import org.junit.Test -import org.junit.runner.RunWith - -@RunWith(FlickerServiceJUnit4ClassRunner::class) -class EnterSplitScreenByDragFromShortcutGesturalNavLandscape : - EnterSplitScreenByDragFromShortcut(Rotation.ROTATION_90) { - - @ExpectedScenarios(["SPLIT_SCREEN_ENTER"]) - @Test - override fun enterSplitScreenByDragFromShortcut() = super.enterSplitScreenByDragFromShortcut() - - companion object { - @JvmStatic - @FlickerConfigProvider - fun flickerConfigProvider(): FlickerConfig = - FlickerConfig().use(FlickerServiceConfig.DEFAULT) - } -} diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromShortcutGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromShortcutGesturalNavPortrait.kt deleted file mode 100644 index 8df8dfaab071..000000000000 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromShortcutGesturalNavPortrait.kt +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (C) 2023 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.wm.shell.flicker.service.splitscreen.flicker - -import android.tools.common.Rotation -import android.tools.common.flicker.FlickerConfig -import android.tools.common.flicker.annotation.ExpectedScenarios -import android.tools.common.flicker.annotation.FlickerConfigProvider -import android.tools.common.flicker.config.FlickerConfig -import android.tools.common.flicker.config.FlickerServiceConfig -import android.tools.device.flicker.junit.FlickerServiceJUnit4ClassRunner -import com.android.wm.shell.flicker.service.splitscreen.scenarios.EnterSplitScreenByDragFromShortcut -import org.junit.Test -import org.junit.runner.RunWith - -@RunWith(FlickerServiceJUnit4ClassRunner::class) -class EnterSplitScreenByDragFromShortcutGesturalNavPortrait : - EnterSplitScreenByDragFromShortcut(Rotation.ROTATION_0) { - - @ExpectedScenarios(["SPLIT_SCREEN_ENTER"]) - @Test - override fun enterSplitScreenByDragFromShortcut() = super.enterSplitScreenByDragFromShortcut() - - companion object { - @JvmStatic - @FlickerConfigProvider - fun flickerConfigProvider(): FlickerConfig = - FlickerConfig().use(FlickerServiceConfig.DEFAULT) - } -} diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromTaskbarGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromTaskbarGesturalNavLandscape.kt deleted file mode 100644 index 378f055ef830..000000000000 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromTaskbarGesturalNavLandscape.kt +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (C) 2023 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.wm.shell.flicker.service.splitscreen.flicker - -import android.tools.common.Rotation -import android.tools.common.flicker.FlickerConfig -import android.tools.common.flicker.annotation.ExpectedScenarios -import android.tools.common.flicker.annotation.FlickerConfigProvider -import android.tools.common.flicker.config.FlickerConfig -import android.tools.common.flicker.config.FlickerServiceConfig -import android.tools.device.flicker.junit.FlickerServiceJUnit4ClassRunner -import com.android.wm.shell.flicker.service.splitscreen.scenarios.EnterSplitScreenByDragFromTaskbar -import org.junit.Test -import org.junit.runner.RunWith - -@RunWith(FlickerServiceJUnit4ClassRunner::class) -class EnterSplitScreenByDragFromTaskbarGesturalNavLandscape : - EnterSplitScreenByDragFromTaskbar(Rotation.ROTATION_90) { - - @ExpectedScenarios(["SPLIT_SCREEN_ENTER"]) - @Test - override fun enterSplitScreenByDragFromTaskbar() = super.enterSplitScreenByDragFromTaskbar() - - companion object { - @JvmStatic - @FlickerConfigProvider - fun flickerConfigProvider(): FlickerConfig = - FlickerConfig().use(FlickerServiceConfig.DEFAULT) - } -} diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromTaskbarGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromTaskbarGesturalNavPortrait.kt deleted file mode 100644 index b33d26288d33..000000000000 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenByDragFromTaskbarGesturalNavPortrait.kt +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (C) 2023 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.wm.shell.flicker.service.splitscreen.flicker - -import android.tools.common.Rotation -import android.tools.common.flicker.FlickerConfig -import android.tools.common.flicker.annotation.ExpectedScenarios -import android.tools.common.flicker.annotation.FlickerConfigProvider -import android.tools.common.flicker.config.FlickerConfig -import android.tools.common.flicker.config.FlickerServiceConfig -import android.tools.device.flicker.junit.FlickerServiceJUnit4ClassRunner -import com.android.wm.shell.flicker.service.splitscreen.scenarios.EnterSplitScreenByDragFromTaskbar -import org.junit.Test -import org.junit.runner.RunWith - -@RunWith(FlickerServiceJUnit4ClassRunner::class) -class EnterSplitScreenByDragFromTaskbarGesturalNavPortrait : - EnterSplitScreenByDragFromTaskbar(Rotation.ROTATION_0) { - - @ExpectedScenarios(["SPLIT_SCREEN_ENTER"]) - @Test - override fun enterSplitScreenByDragFromTaskbar() = super.enterSplitScreenByDragFromTaskbar() - - companion object { - @JvmStatic - @FlickerConfigProvider - fun flickerConfigProvider(): FlickerConfig = - FlickerConfig().use(FlickerServiceConfig.DEFAULT) - } -} diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenFromOverviewGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenFromOverviewGesturalNavLandscape.kt deleted file mode 100644 index b1d3858b9dbb..000000000000 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenFromOverviewGesturalNavLandscape.kt +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (C) 2023 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.wm.shell.flicker.service.splitscreen.flicker - -import android.tools.common.Rotation -import android.tools.common.flicker.FlickerConfig -import android.tools.common.flicker.annotation.ExpectedScenarios -import android.tools.common.flicker.annotation.FlickerConfigProvider -import android.tools.common.flicker.config.FlickerConfig -import android.tools.common.flicker.config.FlickerServiceConfig -import android.tools.device.flicker.junit.FlickerServiceJUnit4ClassRunner -import com.android.wm.shell.flicker.service.splitscreen.scenarios.EnterSplitScreenFromOverview -import org.junit.Test -import org.junit.runner.RunWith - -@RunWith(FlickerServiceJUnit4ClassRunner::class) -class EnterSplitScreenFromOverviewGesturalNavLandscape : - EnterSplitScreenFromOverview(Rotation.ROTATION_90) { - - @ExpectedScenarios(["SPLIT_SCREEN_ENTER"]) - @Test - override fun enterSplitScreenFromOverview() = super.enterSplitScreenFromOverview() - - companion object { - @JvmStatic - @FlickerConfigProvider - fun flickerConfigProvider(): FlickerConfig = - FlickerConfig().use(FlickerServiceConfig.DEFAULT) - } -} diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenFromOverviewGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenFromOverviewGesturalNavPortrait.kt deleted file mode 100644 index 6d824c74c1fe..000000000000 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/EnterSplitScreenFromOverviewGesturalNavPortrait.kt +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (C) 2023 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.wm.shell.flicker.service.splitscreen.flicker - -import android.tools.common.Rotation -import android.tools.common.flicker.FlickerConfig -import android.tools.common.flicker.annotation.ExpectedScenarios -import android.tools.common.flicker.annotation.FlickerConfigProvider -import android.tools.common.flicker.config.FlickerConfig -import android.tools.common.flicker.config.FlickerServiceConfig -import android.tools.device.flicker.junit.FlickerServiceJUnit4ClassRunner -import com.android.wm.shell.flicker.service.splitscreen.scenarios.EnterSplitScreenFromOverview -import org.junit.Test -import org.junit.runner.RunWith - -@RunWith(FlickerServiceJUnit4ClassRunner::class) -class EnterSplitScreenFromOverviewGesturalNavPortrait : - EnterSplitScreenFromOverview(Rotation.ROTATION_0) { - - @ExpectedScenarios(["SPLIT_SCREEN_ENTER"]) - @Test - override fun enterSplitScreenFromOverview() = super.enterSplitScreenFromOverview() - - companion object { - @JvmStatic - @FlickerConfigProvider - fun flickerConfigProvider(): FlickerConfig = - FlickerConfig().use(FlickerServiceConfig.DEFAULT) - } -} diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchAppByDoubleTapDividerGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchAppByDoubleTapDividerGesturalNavLandscape.kt deleted file mode 100644 index f1d3d0cf2716..000000000000 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchAppByDoubleTapDividerGesturalNavLandscape.kt +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (C) 2023 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.wm.shell.flicker.service.splitscreen.flicker - -import android.tools.common.Rotation -import android.tools.common.flicker.FlickerConfig -import android.tools.common.flicker.annotation.ExpectedScenarios -import android.tools.common.flicker.annotation.FlickerConfigProvider -import android.tools.common.flicker.config.FlickerConfig -import android.tools.common.flicker.config.FlickerServiceConfig -import android.tools.device.flicker.junit.FlickerServiceJUnit4ClassRunner -import com.android.wm.shell.flicker.service.splitscreen.scenarios.SwitchAppByDoubleTapDivider -import org.junit.Test -import org.junit.runner.RunWith - -@RunWith(FlickerServiceJUnit4ClassRunner::class) -class SwitchAppByDoubleTapDividerGesturalNavLandscape : - SwitchAppByDoubleTapDivider(Rotation.ROTATION_90) { - - @ExpectedScenarios([]) - @Test - override fun switchAppByDoubleTapDivider() = super.switchAppByDoubleTapDivider() - - companion object { - @JvmStatic - @FlickerConfigProvider - fun flickerConfigProvider(): FlickerConfig = - FlickerConfig().use(FlickerServiceConfig.DEFAULT) - } -} diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchAppByDoubleTapDividerGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchAppByDoubleTapDividerGesturalNavPortrait.kt deleted file mode 100644 index a867bac8c0eb..000000000000 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchAppByDoubleTapDividerGesturalNavPortrait.kt +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (C) 2023 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.wm.shell.flicker.service.splitscreen.flicker - -import android.tools.common.Rotation -import android.tools.common.flicker.FlickerConfig -import android.tools.common.flicker.annotation.ExpectedScenarios -import android.tools.common.flicker.annotation.FlickerConfigProvider -import android.tools.common.flicker.config.FlickerConfig -import android.tools.common.flicker.config.FlickerServiceConfig -import android.tools.device.flicker.junit.FlickerServiceJUnit4ClassRunner -import com.android.wm.shell.flicker.service.splitscreen.scenarios.SwitchAppByDoubleTapDivider -import org.junit.Test -import org.junit.runner.RunWith - -@RunWith(FlickerServiceJUnit4ClassRunner::class) -class SwitchAppByDoubleTapDividerGesturalNavPortrait : - SwitchAppByDoubleTapDivider(Rotation.ROTATION_0) { - - @ExpectedScenarios([]) - @Test - override fun switchAppByDoubleTapDivider() = super.switchAppByDoubleTapDivider() - - companion object { - @JvmStatic - @FlickerConfigProvider - fun flickerConfigProvider(): FlickerConfig = - FlickerConfig().use(FlickerServiceConfig.DEFAULT) - } -} diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBackToSplitFromAnotherAppGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBackToSplitFromAnotherAppGesturalNavLandscape.kt deleted file mode 100644 index 76247ba10037..000000000000 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBackToSplitFromAnotherAppGesturalNavLandscape.kt +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (C) 2023 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.wm.shell.flicker.service.splitscreen.flicker - -import android.tools.common.Rotation -import android.tools.common.flicker.FlickerConfig -import android.tools.common.flicker.annotation.ExpectedScenarios -import android.tools.common.flicker.annotation.FlickerConfigProvider -import android.tools.common.flicker.config.FlickerConfig -import android.tools.common.flicker.config.FlickerServiceConfig -import android.tools.device.flicker.junit.FlickerServiceJUnit4ClassRunner -import com.android.wm.shell.flicker.service.splitscreen.scenarios.SwitchBackToSplitFromAnotherApp -import org.junit.Test -import org.junit.runner.RunWith - -@RunWith(FlickerServiceJUnit4ClassRunner::class) -class SwitchBackToSplitFromAnotherAppGesturalNavLandscape : - SwitchBackToSplitFromAnotherApp(Rotation.ROTATION_90) { - - @ExpectedScenarios(["QUICKSWITCH"]) - @Test - override fun switchBackToSplitFromAnotherApp() = super.switchBackToSplitFromAnotherApp() - - companion object { - @JvmStatic - @FlickerConfigProvider - fun flickerConfigProvider(): FlickerConfig = - FlickerConfig().use(FlickerServiceConfig.DEFAULT) - } -} diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBackToSplitFromAnotherAppGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBackToSplitFromAnotherAppGesturalNavPortrait.kt deleted file mode 100644 index e179da81e4db..000000000000 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBackToSplitFromAnotherAppGesturalNavPortrait.kt +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (C) 2023 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.wm.shell.flicker.service.splitscreen.flicker - -import android.tools.common.Rotation -import android.tools.common.flicker.FlickerConfig -import android.tools.common.flicker.annotation.ExpectedScenarios -import android.tools.common.flicker.annotation.FlickerConfigProvider -import android.tools.common.flicker.config.FlickerConfig -import android.tools.common.flicker.config.FlickerServiceConfig -import android.tools.device.flicker.junit.FlickerServiceJUnit4ClassRunner -import com.android.wm.shell.flicker.service.splitscreen.scenarios.SwitchBackToSplitFromAnotherApp -import org.junit.Test -import org.junit.runner.RunWith - -@RunWith(FlickerServiceJUnit4ClassRunner::class) -class SwitchBackToSplitFromAnotherAppGesturalNavPortrait : - SwitchBackToSplitFromAnotherApp(Rotation.ROTATION_0) { - - @ExpectedScenarios(["QUICKSWITCH"]) - @Test - override fun switchBackToSplitFromAnotherApp() = super.switchBackToSplitFromAnotherApp() - - companion object { - @JvmStatic - @FlickerConfigProvider - fun flickerConfigProvider(): FlickerConfig = - FlickerConfig().use(FlickerServiceConfig.DEFAULT) - } -} diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBackToSplitFromHomeGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBackToSplitFromHomeGesturalNavLandscape.kt deleted file mode 100644 index 20f554f7d154..000000000000 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBackToSplitFromHomeGesturalNavLandscape.kt +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (C) 2023 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.wm.shell.flicker.service.splitscreen.flicker - -import android.tools.common.Rotation -import android.tools.common.flicker.FlickerConfig -import android.tools.common.flicker.annotation.ExpectedScenarios -import android.tools.common.flicker.annotation.FlickerConfigProvider -import android.tools.common.flicker.config.FlickerConfig -import android.tools.common.flicker.config.FlickerServiceConfig -import android.tools.device.flicker.junit.FlickerServiceJUnit4ClassRunner -import com.android.wm.shell.flicker.service.splitscreen.scenarios.SwitchBackToSplitFromHome -import org.junit.Test -import org.junit.runner.RunWith - -@RunWith(FlickerServiceJUnit4ClassRunner::class) -class SwitchBackToSplitFromHomeGesturalNavLandscape : - SwitchBackToSplitFromHome(Rotation.ROTATION_90) { - - @ExpectedScenarios(["QUICKSWITCH"]) - @Test - override fun switchBackToSplitFromHome() = super.switchBackToSplitFromHome() - - companion object { - @JvmStatic - @FlickerConfigProvider - fun flickerConfigProvider(): FlickerConfig = - FlickerConfig().use(FlickerServiceConfig.DEFAULT) - } -} diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBackToSplitFromHomeGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBackToSplitFromHomeGesturalNavPortrait.kt deleted file mode 100644 index f7776ee3244a..000000000000 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBackToSplitFromHomeGesturalNavPortrait.kt +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (C) 2023 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.wm.shell.flicker.service.splitscreen.flicker - -import android.tools.common.Rotation -import android.tools.common.flicker.FlickerConfig -import android.tools.common.flicker.annotation.ExpectedScenarios -import android.tools.common.flicker.annotation.FlickerConfigProvider -import android.tools.common.flicker.config.FlickerConfig -import android.tools.common.flicker.config.FlickerServiceConfig -import android.tools.device.flicker.junit.FlickerServiceJUnit4ClassRunner -import com.android.wm.shell.flicker.service.splitscreen.scenarios.SwitchBackToSplitFromHome -import org.junit.Test -import org.junit.runner.RunWith - -@RunWith(FlickerServiceJUnit4ClassRunner::class) -class SwitchBackToSplitFromHomeGesturalNavPortrait : - SwitchBackToSplitFromHome(Rotation.ROTATION_0) { - - @ExpectedScenarios(["QUICKSWITCH"]) - @Test - override fun switchBackToSplitFromHome() = super.switchBackToSplitFromHome() - - companion object { - @JvmStatic - @FlickerConfigProvider - fun flickerConfigProvider(): FlickerConfig = - FlickerConfig().use(FlickerServiceConfig.DEFAULT) - } -} diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBackToSplitFromRecentGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBackToSplitFromRecentGesturalNavLandscape.kt deleted file mode 100644 index 00f607343b3b..000000000000 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBackToSplitFromRecentGesturalNavLandscape.kt +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (C) 2023 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.wm.shell.flicker.service.splitscreen.flicker - -import android.tools.common.Rotation -import android.tools.common.flicker.FlickerConfig -import android.tools.common.flicker.annotation.ExpectedScenarios -import android.tools.common.flicker.annotation.FlickerConfigProvider -import android.tools.common.flicker.config.FlickerConfig -import android.tools.common.flicker.config.FlickerServiceConfig -import android.tools.device.flicker.junit.FlickerServiceJUnit4ClassRunner -import com.android.wm.shell.flicker.service.splitscreen.scenarios.SwitchBackToSplitFromRecent -import org.junit.Test -import org.junit.runner.RunWith - -@RunWith(FlickerServiceJUnit4ClassRunner::class) -class SwitchBackToSplitFromRecentGesturalNavLandscape : - SwitchBackToSplitFromRecent(Rotation.ROTATION_90) { - - @ExpectedScenarios(["QUICKSWITCH"]) - @Test - override fun switchBackToSplitFromRecent() = super.switchBackToSplitFromRecent() - - companion object { - @JvmStatic - @FlickerConfigProvider - fun flickerConfigProvider(): FlickerConfig = - FlickerConfig().use(FlickerServiceConfig.DEFAULT) - } -} diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBackToSplitFromRecentGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBackToSplitFromRecentGesturalNavPortrait.kt deleted file mode 100644 index b3340e77dbfa..000000000000 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBackToSplitFromRecentGesturalNavPortrait.kt +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (C) 2023 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.wm.shell.flicker.service.splitscreen.flicker - -import android.tools.common.Rotation -import android.tools.common.flicker.FlickerConfig -import android.tools.common.flicker.annotation.ExpectedScenarios -import android.tools.common.flicker.annotation.FlickerConfigProvider -import android.tools.common.flicker.config.FlickerConfig -import android.tools.common.flicker.config.FlickerServiceConfig -import android.tools.device.flicker.junit.FlickerServiceJUnit4ClassRunner -import com.android.wm.shell.flicker.service.splitscreen.scenarios.SwitchBackToSplitFromRecent -import org.junit.Test -import org.junit.runner.RunWith - -@RunWith(FlickerServiceJUnit4ClassRunner::class) -class SwitchBackToSplitFromRecentGesturalNavPortrait : - SwitchBackToSplitFromRecent(Rotation.ROTATION_0) { - - @ExpectedScenarios(["QUICKSWITCH"]) - @Test - override fun switchBackToSplitFromRecent() = super.switchBackToSplitFromRecent() - - companion object { - @JvmStatic - @FlickerConfigProvider - fun flickerConfigProvider(): FlickerConfig = - FlickerConfig().use(FlickerServiceConfig.DEFAULT) - } -} diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBetweenSplitPairsGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBetweenSplitPairsGesturalNavLandscape.kt deleted file mode 100644 index 3da61e5e310c..000000000000 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBetweenSplitPairsGesturalNavLandscape.kt +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (C) 2023 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.wm.shell.flicker.service.splitscreen.flicker - -import android.tools.common.Rotation -import android.tools.common.flicker.FlickerConfig -import android.tools.common.flicker.annotation.ExpectedScenarios -import android.tools.common.flicker.annotation.FlickerConfigProvider -import android.tools.common.flicker.config.FlickerConfig -import android.tools.common.flicker.config.FlickerServiceConfig -import android.tools.device.flicker.junit.FlickerServiceJUnit4ClassRunner -import com.android.wm.shell.flicker.service.splitscreen.scenarios.SwitchBetweenSplitPairs -import org.junit.Test -import org.junit.runner.RunWith - -@RunWith(FlickerServiceJUnit4ClassRunner::class) -class SwitchBetweenSplitPairsGesturalNavLandscape : SwitchBetweenSplitPairs(Rotation.ROTATION_90) { - - @ExpectedScenarios(["QUICKSWITCH"]) - @Test - override fun switchBetweenSplitPairs() = super.switchBetweenSplitPairs() - - companion object { - @JvmStatic - @FlickerConfigProvider - fun flickerConfigProvider(): FlickerConfig = - FlickerConfig().use(FlickerServiceConfig.DEFAULT) - } -} diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBetweenSplitPairsGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBetweenSplitPairsGesturalNavPortrait.kt deleted file mode 100644 index 627ae1843314..000000000000 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/SwitchBetweenSplitPairsGesturalNavPortrait.kt +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (C) 2023 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.wm.shell.flicker.service.splitscreen.flicker - -import android.tools.common.Rotation -import android.tools.common.flicker.FlickerConfig -import android.tools.common.flicker.annotation.ExpectedScenarios -import android.tools.common.flicker.annotation.FlickerConfigProvider -import android.tools.common.flicker.config.FlickerConfig -import android.tools.common.flicker.config.FlickerServiceConfig -import android.tools.device.flicker.junit.FlickerServiceJUnit4ClassRunner -import com.android.wm.shell.flicker.service.splitscreen.scenarios.SwitchBetweenSplitPairs -import org.junit.Test -import org.junit.runner.RunWith - -@RunWith(FlickerServiceJUnit4ClassRunner::class) -class SwitchBetweenSplitPairsGesturalNavPortrait : SwitchBetweenSplitPairs(Rotation.ROTATION_0) { - - @ExpectedScenarios(["QUICKSWITCH"]) - @Test - override fun switchBetweenSplitPairs() = super.switchBetweenSplitPairs() - - companion object { - @JvmStatic - @FlickerConfigProvider - fun flickerConfigProvider(): FlickerConfig = - FlickerConfig().use(FlickerServiceConfig.DEFAULT) - } -} diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/benchmark/CopyContentInSplitGesturalNavPortraitBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/CopyContentInSplitGesturalNavLandscape.kt index 92b62273d8cb..2494054c1fae 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/benchmark/CopyContentInSplitGesturalNavPortraitBenchmark.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/CopyContentInSplitGesturalNavLandscape.kt @@ -14,17 +14,15 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.benchmark +package com.android.wm.shell.flicker.service.splitscreen.platinum import android.platform.test.annotations.PlatinumTest import android.platform.test.annotations.Presubmit import android.tools.common.Rotation -import androidx.test.filters.RequiresDevice import com.android.wm.shell.flicker.service.splitscreen.scenarios.CopyContentInSplit import org.junit.Test -@RequiresDevice -class CopyContentInSplitGesturalNavPortraitBenchmark : CopyContentInSplit(Rotation.ROTATION_0) { +class CopyContentInSplitGesturalNavLandscape : CopyContentInSplit(Rotation.ROTATION_90) { @PlatinumTest(focusArea = "sysui") @Presubmit @Test diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/benchmark/CopyContentInSplitGesturalNavLandscapeBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/CopyContentInSplitGesturalNavPortrait.kt index 566adec75615..57943ec4c8fa 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/benchmark/CopyContentInSplitGesturalNavLandscapeBenchmark.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/CopyContentInSplitGesturalNavPortrait.kt @@ -14,17 +14,15 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.benchmark +package com.android.wm.shell.flicker.service.splitscreen.platinum import android.platform.test.annotations.PlatinumTest import android.platform.test.annotations.Presubmit import android.tools.common.Rotation -import androidx.test.filters.RequiresDevice import com.android.wm.shell.flicker.service.splitscreen.scenarios.CopyContentInSplit import org.junit.Test -@RequiresDevice -class CopyContentInSplitGesturalNavLandscapeBenchmark : CopyContentInSplit(Rotation.ROTATION_90) { +class CopyContentInSplitGesturalNavPortrait : CopyContentInSplit(Rotation.ROTATION_0) { @PlatinumTest(focusArea = "sysui") @Presubmit @Test diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/benchmark/DismissSplitScreenByDividerGesturalNavLandscapeBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/DismissSplitScreenByDividerGesturalNavLandscape.kt index e6d56b5c94d3..6f0e202ae70f 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/benchmark/DismissSplitScreenByDividerGesturalNavLandscapeBenchmark.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/DismissSplitScreenByDividerGesturalNavLandscape.kt @@ -14,17 +14,15 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.benchmark +package com.android.wm.shell.flicker.service.splitscreen.platinum import android.platform.test.annotations.PlatinumTest import android.platform.test.annotations.Presubmit import android.tools.common.Rotation -import androidx.test.filters.RequiresDevice import com.android.wm.shell.flicker.service.splitscreen.scenarios.DismissSplitScreenByDivider import org.junit.Test -@RequiresDevice -class DismissSplitScreenByDividerGesturalNavLandscapeBenchmark : +class DismissSplitScreenByDividerGesturalNavLandscape : DismissSplitScreenByDivider(Rotation.ROTATION_90) { @PlatinumTest(focusArea = "sysui") @Presubmit diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/benchmark/DismissSplitScreenByDividerGesturalNavPortraitBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/DismissSplitScreenByDividerGesturalNavPortrait.kt index 6752c58bd568..dac8fa24b289 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/benchmark/DismissSplitScreenByDividerGesturalNavPortraitBenchmark.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/DismissSplitScreenByDividerGesturalNavPortrait.kt @@ -14,17 +14,15 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.benchmark +package com.android.wm.shell.flicker.service.splitscreen.platinum import android.platform.test.annotations.PlatinumTest import android.platform.test.annotations.Presubmit import android.tools.common.Rotation -import androidx.test.filters.RequiresDevice import com.android.wm.shell.flicker.service.splitscreen.scenarios.DismissSplitScreenByDivider import org.junit.Test -@RequiresDevice -class DismissSplitScreenByDividerGesturalNavPortraitBenchmark : +class DismissSplitScreenByDividerGesturalNavPortrait : DismissSplitScreenByDivider(Rotation.ROTATION_0) { @PlatinumTest(focusArea = "sysui") @Presubmit diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/benchmark/DismissSplitScreenByGoHomeGesturalNavLandscapeBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/DismissSplitScreenByGoHomeGesturalNavLandscape.kt index 7c9ab9939dd0..baecc161d227 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/benchmark/DismissSplitScreenByGoHomeGesturalNavLandscapeBenchmark.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/DismissSplitScreenByGoHomeGesturalNavLandscape.kt @@ -14,17 +14,15 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.benchmark +package com.android.wm.shell.flicker.service.splitscreen.platinum import android.platform.test.annotations.PlatinumTest import android.platform.test.annotations.Presubmit import android.tools.common.Rotation -import androidx.test.filters.RequiresDevice import com.android.wm.shell.flicker.service.splitscreen.scenarios.DismissSplitScreenByGoHome import org.junit.Test -@RequiresDevice -class DismissSplitScreenByGoHomeGesturalNavLandscapeBenchmark : +class DismissSplitScreenByGoHomeGesturalNavLandscape : DismissSplitScreenByGoHome(Rotation.ROTATION_90) { @PlatinumTest(focusArea = "sysui") @Presubmit diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/benchmark/DismissSplitScreenByGoHomeGesturalNavPortraitBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/DismissSplitScreenByGoHomeGesturalNavPortrait.kt index 4b795713cb23..3063ea564b58 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/benchmark/DismissSplitScreenByGoHomeGesturalNavPortraitBenchmark.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/DismissSplitScreenByGoHomeGesturalNavPortrait.kt @@ -14,17 +14,15 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.benchmark +package com.android.wm.shell.flicker.service.splitscreen.platinum import android.platform.test.annotations.PlatinumTest import android.platform.test.annotations.Presubmit import android.tools.common.Rotation -import androidx.test.filters.RequiresDevice import com.android.wm.shell.flicker.service.splitscreen.scenarios.DismissSplitScreenByGoHome import org.junit.Test -@RequiresDevice -class DismissSplitScreenByGoHomeGesturalNavPortraitBenchmark : +class DismissSplitScreenByGoHomeGesturalNavPortrait : DismissSplitScreenByGoHome(Rotation.ROTATION_0) { @PlatinumTest(focusArea = "sysui") @Presubmit diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/benchmark/DragDividerToResizeGesturalNavPortraitBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/DragDividerToResizeGesturalNavLandscape.kt index 71ef48bea686..41660ba68385 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/benchmark/DragDividerToResizeGesturalNavPortraitBenchmark.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/DragDividerToResizeGesturalNavLandscape.kt @@ -14,17 +14,15 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.benchmark +package com.android.wm.shell.flicker.service.splitscreen.platinum import android.platform.test.annotations.PlatinumTest import android.platform.test.annotations.Presubmit import android.tools.common.Rotation -import androidx.test.filters.RequiresDevice import com.android.wm.shell.flicker.service.splitscreen.scenarios.DragDividerToResize import org.junit.Test -@RequiresDevice -class DragDividerToResizeGesturalNavPortraitBenchmark : DragDividerToResize(Rotation.ROTATION_0) { +class DragDividerToResizeGesturalNavLandscape : DragDividerToResize(Rotation.ROTATION_90) { @PlatinumTest(focusArea = "sysui") @Presubmit @Test diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/benchmark/DragDividerToResizeGesturalNavLandscapeBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/DragDividerToResizeGesturalNavPortrait.kt index 04950799732e..c41ffb786cd9 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/benchmark/DragDividerToResizeGesturalNavLandscapeBenchmark.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/DragDividerToResizeGesturalNavPortrait.kt @@ -14,17 +14,15 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.benchmark +package com.android.wm.shell.flicker.service.splitscreen.platinum import android.platform.test.annotations.PlatinumTest import android.platform.test.annotations.Presubmit import android.tools.common.Rotation -import androidx.test.filters.RequiresDevice import com.android.wm.shell.flicker.service.splitscreen.scenarios.DragDividerToResize import org.junit.Test -@RequiresDevice -class DragDividerToResizeGesturalNavLandscapeBenchmark : DragDividerToResize(Rotation.ROTATION_90) { +class DragDividerToResizeGesturalNavPortrait : DragDividerToResize(Rotation.ROTATION_0) { @PlatinumTest(focusArea = "sysui") @Presubmit @Test diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/benchmark/EnterSplitScreenByDragFromAllAppsGesturalNavLandscapeBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromAllAppsGesturalNavLandscape.kt index c78729c6dc92..afde55bf519f 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/benchmark/EnterSplitScreenByDragFromAllAppsGesturalNavLandscapeBenchmark.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromAllAppsGesturalNavLandscape.kt @@ -14,17 +14,15 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.benchmark +package com.android.wm.shell.flicker.service.splitscreen.platinum import android.platform.test.annotations.PlatinumTest import android.platform.test.annotations.Presubmit import android.tools.common.Rotation -import androidx.test.filters.RequiresDevice import com.android.wm.shell.flicker.service.splitscreen.scenarios.EnterSplitScreenByDragFromAllApps import org.junit.Test -@RequiresDevice -class EnterSplitScreenByDragFromAllAppsGesturalNavLandscapeBenchmark : +class EnterSplitScreenByDragFromAllAppsGesturalNavLandscape : EnterSplitScreenByDragFromAllApps(Rotation.ROTATION_90) { @PlatinumTest(focusArea = "sysui") @Presubmit diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/benchmark/EnterSplitScreenByDragFromAllAppsGesturalNavPortraitBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromAllAppsGesturalNavPortrait.kt index 30bce2f657b1..3765fc42d2c9 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/benchmark/EnterSplitScreenByDragFromAllAppsGesturalNavPortraitBenchmark.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromAllAppsGesturalNavPortrait.kt @@ -14,17 +14,15 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.benchmark +package com.android.wm.shell.flicker.service.splitscreen.platinum import android.platform.test.annotations.PlatinumTest import android.platform.test.annotations.Presubmit import android.tools.common.Rotation -import androidx.test.filters.RequiresDevice import com.android.wm.shell.flicker.service.splitscreen.scenarios.EnterSplitScreenByDragFromAllApps import org.junit.Test -@RequiresDevice -class EnterSplitScreenByDragFromAllAppsGesturalNavPortraitBenchmark : +class EnterSplitScreenByDragFromAllAppsGesturalNavPortrait : EnterSplitScreenByDragFromAllApps(Rotation.ROTATION_0) { @PlatinumTest(focusArea = "sysui") @Presubmit diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/benchmark/EnterSplitScreenByDragFromNotificationGesturalNavLandscapeBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromNotificationGesturalNavLandscape.kt index b33ea7c89158..1e128fd3e47f 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/benchmark/EnterSplitScreenByDragFromNotificationGesturalNavLandscapeBenchmark.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromNotificationGesturalNavLandscape.kt @@ -14,17 +14,15 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.benchmark +package com.android.wm.shell.flicker.service.splitscreen.platinum import android.platform.test.annotations.PlatinumTest import android.platform.test.annotations.Presubmit import android.tools.common.Rotation -import androidx.test.filters.RequiresDevice import com.android.wm.shell.flicker.service.splitscreen.scenarios.EnterSplitScreenByDragFromNotification import org.junit.Test -@RequiresDevice -class EnterSplitScreenByDragFromNotificationGesturalNavLandscapeBenchmark : +class EnterSplitScreenByDragFromNotificationGesturalNavLandscape : EnterSplitScreenByDragFromNotification(Rotation.ROTATION_90) { @PlatinumTest(focusArea = "sysui") @Presubmit diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/benchmark/EnterSplitScreenByDragFromNotificationGesturalNavPortraitBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromNotificationGesturalNavPortrait.kt index 07a86a57117b..7767872cb7fd 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/benchmark/EnterSplitScreenByDragFromNotificationGesturalNavPortraitBenchmark.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromNotificationGesturalNavPortrait.kt @@ -14,17 +14,15 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.benchmark +package com.android.wm.shell.flicker.service.splitscreen.platinum import android.platform.test.annotations.PlatinumTest import android.platform.test.annotations.Presubmit import android.tools.common.Rotation -import androidx.test.filters.RequiresDevice import com.android.wm.shell.flicker.service.splitscreen.scenarios.EnterSplitScreenByDragFromNotification import org.junit.Test -@RequiresDevice -class EnterSplitScreenByDragFromNotificationGesturalNavPortraitBenchmark : +class EnterSplitScreenByDragFromNotificationGesturalNavPortrait : EnterSplitScreenByDragFromNotification(Rotation.ROTATION_0) { @PlatinumTest(focusArea = "sysui") @Presubmit diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/benchmark/EnterSplitScreenByDragFromShortcutGesturalNavLandscapeBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromShortcutGesturalNavLandscape.kt index 9a1d12787b9d..4ca4bd1d6d8b 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/benchmark/EnterSplitScreenByDragFromShortcutGesturalNavLandscapeBenchmark.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromShortcutGesturalNavLandscape.kt @@ -14,17 +14,15 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.benchmark +package com.android.wm.shell.flicker.service.splitscreen.platinum import android.platform.test.annotations.PlatinumTest import android.platform.test.annotations.Presubmit import android.tools.common.Rotation -import androidx.test.filters.RequiresDevice import com.android.wm.shell.flicker.service.splitscreen.scenarios.EnterSplitScreenByDragFromShortcut import org.junit.Test -@RequiresDevice -class EnterSplitScreenByDragFromShortcutGesturalNavLandscapeBenchmark : +class EnterSplitScreenByDragFromShortcutGesturalNavLandscape : EnterSplitScreenByDragFromShortcut(Rotation.ROTATION_90) { @PlatinumTest(focusArea = "sysui") @Presubmit diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/benchmark/EnterSplitScreenByDragFromShortcutGesturalNavPortraitBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromShortcutGesturalNavPortrait.kt index 266e268a3537..2d9d258ecc54 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/benchmark/EnterSplitScreenByDragFromShortcutGesturalNavPortraitBenchmark.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromShortcutGesturalNavPortrait.kt @@ -14,17 +14,15 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.benchmark +package com.android.wm.shell.flicker.service.splitscreen.platinum import android.platform.test.annotations.PlatinumTest import android.platform.test.annotations.Presubmit import android.tools.common.Rotation -import androidx.test.filters.RequiresDevice import com.android.wm.shell.flicker.service.splitscreen.scenarios.EnterSplitScreenByDragFromShortcut import org.junit.Test -@RequiresDevice -class EnterSplitScreenByDragFromShortcutGesturalNavPortraitBenchmark : +class EnterSplitScreenByDragFromShortcutGesturalNavPortrait : EnterSplitScreenByDragFromShortcut(Rotation.ROTATION_0) { @PlatinumTest(focusArea = "sysui") @Presubmit diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/benchmark/EnterSplitScreenByDragFromTaskbarGesturalNavLandscapeBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromTaskbarGesturalNavLandscape.kt index 83fc30bceb7b..c9282acc5a2f 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/benchmark/EnterSplitScreenByDragFromTaskbarGesturalNavLandscapeBenchmark.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromTaskbarGesturalNavLandscape.kt @@ -14,17 +14,15 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.benchmark +package com.android.wm.shell.flicker.service.splitscreen.platinum import android.platform.test.annotations.PlatinumTest import android.platform.test.annotations.Presubmit import android.tools.common.Rotation -import androidx.test.filters.RequiresDevice import com.android.wm.shell.flicker.service.splitscreen.scenarios.EnterSplitScreenByDragFromTaskbar import org.junit.Test -@RequiresDevice -class EnterSplitScreenByDragFromTaskbarGesturalNavLandscapeBenchmark : +class EnterSplitScreenByDragFromTaskbarGesturalNavLandscape : EnterSplitScreenByDragFromTaskbar(Rotation.ROTATION_90) { @PlatinumTest(focusArea = "sysui") @Presubmit diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/benchmark/EnterSplitScreenByDragFromTaskbarGesturalNavPortraitBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromTaskbarGesturalNavPortrait.kt index b2f19299c7f0..68c6d6cccec1 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/benchmark/EnterSplitScreenByDragFromTaskbarGesturalNavPortraitBenchmark.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenByDragFromTaskbarGesturalNavPortrait.kt @@ -14,17 +14,15 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.benchmark +package com.android.wm.shell.flicker.service.splitscreen.platinum import android.platform.test.annotations.PlatinumTest import android.platform.test.annotations.Presubmit import android.tools.common.Rotation -import androidx.test.filters.RequiresDevice import com.android.wm.shell.flicker.service.splitscreen.scenarios.EnterSplitScreenByDragFromTaskbar import org.junit.Test -@RequiresDevice -class EnterSplitScreenByDragFromTaskbarGesturalNavPortraitBenchmark : +class EnterSplitScreenByDragFromTaskbarGesturalNavPortrait : EnterSplitScreenByDragFromTaskbar(Rotation.ROTATION_0) { @PlatinumTest(focusArea = "sysui") @Presubmit diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/benchmark/EnterSplitScreenFromOverviewGesturalNavLandscapeBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenFromOverviewGesturalNavLandscape.kt index dae92dddbfec..304529ec83fb 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/benchmark/EnterSplitScreenFromOverviewGesturalNavLandscapeBenchmark.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenFromOverviewGesturalNavLandscape.kt @@ -14,17 +14,15 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.benchmark +package com.android.wm.shell.flicker.service.splitscreen.platinum import android.platform.test.annotations.PlatinumTest import android.platform.test.annotations.Presubmit import android.tools.common.Rotation -import androidx.test.filters.RequiresDevice import com.android.wm.shell.flicker.service.splitscreen.scenarios.EnterSplitScreenFromOverview import org.junit.Test -@RequiresDevice -class EnterSplitScreenFromOverviewGesturalNavLandscapeBenchmark : +class EnterSplitScreenFromOverviewGesturalNavLandscape : EnterSplitScreenFromOverview(Rotation.ROTATION_90) { @PlatinumTest(focusArea = "sysui") @Presubmit diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/benchmark/EnterSplitScreenFromOverviewGesturalNavPortraitBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenFromOverviewGesturalNavPortrait.kt index 732047ba38ad..53a6b449df2b 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/benchmark/EnterSplitScreenFromOverviewGesturalNavPortraitBenchmark.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/EnterSplitScreenFromOverviewGesturalNavPortrait.kt @@ -14,17 +14,15 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.benchmark +package com.android.wm.shell.flicker.service.splitscreen.platinum import android.platform.test.annotations.PlatinumTest import android.platform.test.annotations.Presubmit import android.tools.common.Rotation -import androidx.test.filters.RequiresDevice import com.android.wm.shell.flicker.service.splitscreen.scenarios.EnterSplitScreenFromOverview import org.junit.Test -@RequiresDevice -class EnterSplitScreenFromOverviewGesturalNavPortraitBenchmark : +class EnterSplitScreenFromOverviewGesturalNavPortrait : EnterSplitScreenFromOverview(Rotation.ROTATION_0) { @PlatinumTest(focusArea = "sysui") @Presubmit diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/benchmark/SwitchAppByDoubleTapDividerGesturalNavLandscapeBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchAppByDoubleTapDividerGesturalNavLandscape.kt index 1de7efd7970a..a4678301be12 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/benchmark/SwitchAppByDoubleTapDividerGesturalNavLandscapeBenchmark.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchAppByDoubleTapDividerGesturalNavLandscape.kt @@ -14,17 +14,15 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.benchmark +package com.android.wm.shell.flicker.service.splitscreen.platinum import android.platform.test.annotations.PlatinumTest import android.platform.test.annotations.Presubmit import android.tools.common.Rotation -import androidx.test.filters.RequiresDevice import com.android.wm.shell.flicker.service.splitscreen.scenarios.SwitchAppByDoubleTapDivider import org.junit.Test -@RequiresDevice -class SwitchAppByDoubleTapDividerGesturalNavLandscapeBenchmark : +class SwitchAppByDoubleTapDividerGesturalNavLandscape : SwitchAppByDoubleTapDivider(Rotation.ROTATION_90) { @PlatinumTest(focusArea = "sysui") @Presubmit diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/benchmark/SwitchAppByDoubleTapDividerGesturalNavPortraitBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchAppByDoubleTapDividerGesturalNavPortrait.kt index 1a046aa5b09e..15242330a554 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/benchmark/SwitchAppByDoubleTapDividerGesturalNavPortraitBenchmark.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchAppByDoubleTapDividerGesturalNavPortrait.kt @@ -14,17 +14,15 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.benchmark +package com.android.wm.shell.flicker.service.splitscreen.platinum import android.platform.test.annotations.PlatinumTest import android.platform.test.annotations.Presubmit import android.tools.common.Rotation -import androidx.test.filters.RequiresDevice import com.android.wm.shell.flicker.service.splitscreen.scenarios.SwitchAppByDoubleTapDivider import org.junit.Test -@RequiresDevice -class SwitchAppByDoubleTapDividerGesturalNavPortraitBenchmark : +class SwitchAppByDoubleTapDividerGesturalNavPortrait : SwitchAppByDoubleTapDivider(Rotation.ROTATION_0) { @PlatinumTest(focusArea = "sysui") @Presubmit diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/benchmark/SwitchBackToSplitFromAnotherAppGesturalNavLandscapeBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBackToSplitFromAnotherAppGesturalNavLandscape.kt index 6e88f0eddee8..0389659457e5 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/benchmark/SwitchBackToSplitFromAnotherAppGesturalNavLandscapeBenchmark.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBackToSplitFromAnotherAppGesturalNavLandscape.kt @@ -14,17 +14,15 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.benchmark +package com.android.wm.shell.flicker.service.splitscreen.platinum import android.platform.test.annotations.PlatinumTest import android.platform.test.annotations.Presubmit import android.tools.common.Rotation -import androidx.test.filters.RequiresDevice import com.android.wm.shell.flicker.service.splitscreen.scenarios.SwitchBackToSplitFromAnotherApp import org.junit.Test -@RequiresDevice -class SwitchBackToSplitFromAnotherAppGesturalNavLandscapeBenchmark : +class SwitchBackToSplitFromAnotherAppGesturalNavLandscape : SwitchBackToSplitFromAnotherApp(Rotation.ROTATION_90) { @PlatinumTest(focusArea = "sysui") @Presubmit diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/benchmark/SwitchBackToSplitFromAnotherAppGesturalNavPortraitBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBackToSplitFromAnotherAppGesturalNavPortrait.kt index d26a29c80583..7fadf184d74b 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/benchmark/SwitchBackToSplitFromAnotherAppGesturalNavPortraitBenchmark.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBackToSplitFromAnotherAppGesturalNavPortrait.kt @@ -14,17 +14,15 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.benchmark +package com.android.wm.shell.flicker.service.splitscreen.platinum import android.platform.test.annotations.PlatinumTest import android.platform.test.annotations.Presubmit import android.tools.common.Rotation -import androidx.test.filters.RequiresDevice import com.android.wm.shell.flicker.service.splitscreen.scenarios.SwitchBackToSplitFromAnotherApp import org.junit.Test -@RequiresDevice -class SwitchBackToSplitFromAnotherAppGesturalNavPortraitBenchmark : +class SwitchBackToSplitFromAnotherAppGesturalNavPortrait : SwitchBackToSplitFromAnotherApp(Rotation.ROTATION_0) { @PlatinumTest(focusArea = "sysui") @Presubmit diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/benchmark/SwitchBackToSplitFromHomeGesturalNavLandscapeBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBackToSplitFromHomeGesturalNavLandscape.kt index 4a552b0aed6a..148cc522e64d 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/benchmark/SwitchBackToSplitFromHomeGesturalNavLandscapeBenchmark.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBackToSplitFromHomeGesturalNavLandscape.kt @@ -14,17 +14,15 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.benchmark +package com.android.wm.shell.flicker.service.splitscreen.platinum import android.platform.test.annotations.PlatinumTest import android.platform.test.annotations.Presubmit import android.tools.common.Rotation -import androidx.test.filters.RequiresDevice import com.android.wm.shell.flicker.service.splitscreen.scenarios.SwitchBackToSplitFromHome import org.junit.Test -@RequiresDevice -class SwitchBackToSplitFromHomeGesturalNavLandscapeBenchmark : +class SwitchBackToSplitFromHomeGesturalNavLandscape : SwitchBackToSplitFromHome(Rotation.ROTATION_90) { @PlatinumTest(focusArea = "sysui") @Presubmit diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/benchmark/SwitchBackToSplitFromHomeGesturalNavPortraitBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBackToSplitFromHomeGesturalNavPortrait.kt index b7376eaea66d..0641fb03527c 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/benchmark/SwitchBackToSplitFromHomeGesturalNavPortraitBenchmark.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBackToSplitFromHomeGesturalNavPortrait.kt @@ -14,17 +14,15 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.benchmark +package com.android.wm.shell.flicker.service.splitscreen.platinum import android.platform.test.annotations.PlatinumTest import android.platform.test.annotations.Presubmit import android.tools.common.Rotation -import androidx.test.filters.RequiresDevice import com.android.wm.shell.flicker.service.splitscreen.scenarios.SwitchBackToSplitFromHome import org.junit.Test -@RequiresDevice -class SwitchBackToSplitFromHomeGesturalNavPortraitBenchmark : +class SwitchBackToSplitFromHomeGesturalNavPortrait : SwitchBackToSplitFromHome(Rotation.ROTATION_0) { @PlatinumTest(focusArea = "sysui") @Presubmit diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/benchmark/SwitchBackToSplitFromRecentGesturalNavLandscapeBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBackToSplitFromRecentGesturalNavLandscape.kt index b2d05e4a2632..741f871e2c5f 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/benchmark/SwitchBackToSplitFromRecentGesturalNavLandscapeBenchmark.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBackToSplitFromRecentGesturalNavLandscape.kt @@ -14,17 +14,15 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.benchmark +package com.android.wm.shell.flicker.service.splitscreen.platinum import android.platform.test.annotations.PlatinumTest import android.platform.test.annotations.Presubmit import android.tools.common.Rotation -import androidx.test.filters.RequiresDevice import com.android.wm.shell.flicker.service.splitscreen.scenarios.SwitchBackToSplitFromRecent import org.junit.Test -@RequiresDevice -class SwitchBackToSplitFromRecentGesturalNavLandscapeBenchmark : +class SwitchBackToSplitFromRecentGesturalNavLandscape : SwitchBackToSplitFromRecent(Rotation.ROTATION_90) { @PlatinumTest(focusArea = "sysui") @Presubmit diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/benchmark/SwitchBackToSplitFromRecentGesturalNavPortraitBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBackToSplitFromRecentGesturalNavPortrait.kt index 6de31b1315e4..778e2d6a048a 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/benchmark/SwitchBackToSplitFromRecentGesturalNavPortraitBenchmark.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBackToSplitFromRecentGesturalNavPortrait.kt @@ -14,17 +14,15 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.benchmark +package com.android.wm.shell.flicker.service.splitscreen.platinum import android.platform.test.annotations.PlatinumTest import android.platform.test.annotations.Presubmit import android.tools.common.Rotation -import androidx.test.filters.RequiresDevice import com.android.wm.shell.flicker.service.splitscreen.scenarios.SwitchBackToSplitFromRecent import org.junit.Test -@RequiresDevice -class SwitchBackToSplitFromRecentGesturalNavPortraitBenchmark : +class SwitchBackToSplitFromRecentGesturalNavPortrait : SwitchBackToSplitFromRecent(Rotation.ROTATION_0) { @PlatinumTest(focusArea = "sysui") @Presubmit diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/benchmark/SwitchBetweenSplitPairsGesturalNavPortraitBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBetweenSplitPairsGesturalNavLandscape.kt index b074f2c161c9..dcdca70e0f11 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/benchmark/SwitchBetweenSplitPairsGesturalNavPortraitBenchmark.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBetweenSplitPairsGesturalNavLandscape.kt @@ -14,18 +14,15 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.benchmark +package com.android.wm.shell.flicker.service.splitscreen.platinum import android.platform.test.annotations.PlatinumTest import android.platform.test.annotations.Presubmit import android.tools.common.Rotation -import androidx.test.filters.RequiresDevice import com.android.wm.shell.flicker.service.splitscreen.scenarios.SwitchBetweenSplitPairs import org.junit.Test -@RequiresDevice -class SwitchBetweenSplitPairsGesturalNavPortraitBenchmark : - SwitchBetweenSplitPairs(Rotation.ROTATION_0) { +class SwitchBetweenSplitPairsGesturalNavLandscape : SwitchBetweenSplitPairs(Rotation.ROTATION_90) { @PlatinumTest(focusArea = "sysui") @Presubmit @Test diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/benchmark/SwitchBetweenSplitPairsGesturalNavLandscapeBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBetweenSplitPairsGesturalNavPortrait.kt index aab18a6d27b9..3c69311a7028 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/benchmark/SwitchBetweenSplitPairsGesturalNavLandscapeBenchmark.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/SwitchBetweenSplitPairsGesturalNavPortrait.kt @@ -14,18 +14,15 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.benchmark +package com.android.wm.shell.flicker.service.splitscreen.platinum import android.platform.test.annotations.PlatinumTest import android.platform.test.annotations.Presubmit import android.tools.common.Rotation -import androidx.test.filters.RequiresDevice import com.android.wm.shell.flicker.service.splitscreen.scenarios.SwitchBetweenSplitPairs import org.junit.Test -@RequiresDevice -class SwitchBetweenSplitPairsGesturalNavLandscapeBenchmark : - SwitchBetweenSplitPairs(Rotation.ROTATION_90) { +class SwitchBetweenSplitPairsGesturalNavPortrait : SwitchBetweenSplitPairs(Rotation.ROTATION_0) { @PlatinumTest(focusArea = "sysui") @Presubmit @Test diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/UnlockKeyguardToSplitScreenGesturalNavLandscape.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/UnlockKeyguardToSplitScreenGesturalNavLandscape.kt index 7cbc1c3c272c..c6566f5bec80 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/UnlockKeyguardToSplitScreenGesturalNavLandscape.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/UnlockKeyguardToSplitScreenGesturalNavLandscape.kt @@ -14,18 +14,19 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.flicker +package com.android.wm.shell.flicker.service.splitscreen.platinum -import android.tools.common.flicker.annotation.ExpectedScenarios -import android.tools.device.flicker.junit.FlickerServiceJUnit4ClassRunner +import android.platform.test.annotations.PlatinumTest +import android.platform.test.annotations.Presubmit import com.android.wm.shell.flicker.service.splitscreen.scenarios.UnlockKeyguardToSplitScreen import org.junit.Test import org.junit.runner.RunWith +import org.junit.runners.BlockJUnit4ClassRunner -@RunWith(FlickerServiceJUnit4ClassRunner::class) +@RunWith(BlockJUnit4ClassRunner::class) class UnlockKeyguardToSplitScreenGesturalNavLandscape : UnlockKeyguardToSplitScreen() { - - @ExpectedScenarios(["QUICKSWITCH"]) + @PlatinumTest(focusArea = "sysui") + @Presubmit @Test override fun unlockKeyguardToSplitScreen() = super.unlockKeyguardToSplitScreen() } diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/UnlockKeyguardToSplitScreenGesturalNavPortrait.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/UnlockKeyguardToSplitScreenGesturalNavPortrait.kt index 2eb81e0d0492..bb1a5025c5dc 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/flicker/UnlockKeyguardToSplitScreenGesturalNavPortrait.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/platinum/UnlockKeyguardToSplitScreenGesturalNavPortrait.kt @@ -14,18 +14,19 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.service.splitscreen.flicker +package com.android.wm.shell.flicker.service.splitscreen.platinum -import android.tools.common.flicker.annotation.ExpectedScenarios -import android.tools.device.flicker.junit.FlickerServiceJUnit4ClassRunner +import android.platform.test.annotations.PlatinumTest +import android.platform.test.annotations.Presubmit import com.android.wm.shell.flicker.service.splitscreen.scenarios.UnlockKeyguardToSplitScreen import org.junit.Test import org.junit.runner.RunWith +import org.junit.runners.BlockJUnit4ClassRunner -@RunWith(FlickerServiceJUnit4ClassRunner::class) +@RunWith(BlockJUnit4ClassRunner::class) class UnlockKeyguardToSplitScreenGesturalNavPortrait : UnlockKeyguardToSplitScreen() { - - @ExpectedScenarios(["QUICKSWITCH"]) + @PlatinumTest(focusArea = "sysui") + @Presubmit @Test override fun unlockKeyguardToSplitScreen() = super.unlockKeyguardToSplitScreen() } diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/CopyContentInSplit.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/CopyContentInSplit.kt index 5bfc8896a6ef..e530f6369609 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/CopyContentInSplit.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/CopyContentInSplit.kt @@ -24,6 +24,7 @@ import androidx.test.platform.app.InstrumentationRegistry import androidx.test.uiautomator.UiDevice import com.android.launcher3.tapl.LauncherInstrumentation import com.android.wm.shell.flicker.service.Utils +import com.android.wm.shell.flicker.utils.SplitScreenUtils import org.junit.After import org.junit.Before import org.junit.Ignore diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/DismissSplitScreenByDivider.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/DismissSplitScreenByDivider.kt index d07daffcf8a3..e9fc43746d27 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/DismissSplitScreenByDivider.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/DismissSplitScreenByDivider.kt @@ -24,6 +24,7 @@ import androidx.test.platform.app.InstrumentationRegistry import androidx.test.uiautomator.UiDevice import com.android.launcher3.tapl.LauncherInstrumentation import com.android.wm.shell.flicker.service.Utils +import com.android.wm.shell.flicker.utils.SplitScreenUtils import org.junit.After import org.junit.Before import org.junit.Ignore diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/DismissSplitScreenByGoHome.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/DismissSplitScreenByGoHome.kt index d428deaaf488..416692c37b34 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/DismissSplitScreenByGoHome.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/DismissSplitScreenByGoHome.kt @@ -24,6 +24,7 @@ import androidx.test.platform.app.InstrumentationRegistry import androidx.test.uiautomator.UiDevice import com.android.launcher3.tapl.LauncherInstrumentation import com.android.wm.shell.flicker.service.Utils +import com.android.wm.shell.flicker.utils.SplitScreenUtils import org.junit.After import org.junit.Before import org.junit.Ignore diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/DragDividerToResize.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/DragDividerToResize.kt index dc2a6ac54fc8..494a246d2f50 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/DragDividerToResize.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/DragDividerToResize.kt @@ -24,6 +24,7 @@ import androidx.test.platform.app.InstrumentationRegistry import androidx.test.uiautomator.UiDevice import com.android.launcher3.tapl.LauncherInstrumentation import com.android.wm.shell.flicker.service.Utils +import com.android.wm.shell.flicker.utils.SplitScreenUtils import org.junit.After import org.junit.Before import org.junit.Ignore diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenByDragFromAllApps.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenByDragFromAllApps.kt index 677aeb078058..a3aae85568c0 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenByDragFromAllApps.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenByDragFromAllApps.kt @@ -24,7 +24,9 @@ import androidx.test.platform.app.InstrumentationRegistry import androidx.test.uiautomator.UiDevice import com.android.launcher3.tapl.LauncherInstrumentation import com.android.wm.shell.flicker.service.Utils +import com.android.wm.shell.flicker.utils.SplitScreenUtils import org.junit.After +import org.junit.Assume import org.junit.Before import org.junit.Ignore import org.junit.Rule @@ -45,6 +47,8 @@ constructor(val rotation: Rotation = Rotation.ROTATION_0) { @Before fun setup() { + Assume.assumeTrue(tapl.isTablet) + tapl.setEnableRotation(true) tapl.setExpectedRotation(rotation.value) diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenByDragFromNotification.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenByDragFromNotification.kt index f4f68789ea4b..50151f1b7efe 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenByDragFromNotification.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenByDragFromNotification.kt @@ -24,7 +24,9 @@ import androidx.test.platform.app.InstrumentationRegistry import androidx.test.uiautomator.UiDevice import com.android.launcher3.tapl.LauncherInstrumentation import com.android.wm.shell.flicker.service.Utils +import com.android.wm.shell.flicker.utils.SplitScreenUtils import org.junit.After +import org.junit.Assume import org.junit.Before import org.junit.Ignore import org.junit.Rule @@ -46,6 +48,8 @@ constructor(val rotation: Rotation = Rotation.ROTATION_0) { @Before fun setup() { + Assume.assumeTrue(tapl.isTablet) + tapl.setEnableRotation(true) tapl.setExpectedRotation(rotation.value) diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenByDragFromShortcut.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenByDragFromShortcut.kt index 36a458feba64..5d67dc7e231b 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenByDragFromShortcut.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenByDragFromShortcut.kt @@ -24,6 +24,7 @@ import androidx.test.platform.app.InstrumentationRegistry import androidx.test.uiautomator.UiDevice import com.android.launcher3.tapl.LauncherInstrumentation import com.android.wm.shell.flicker.service.Utils +import com.android.wm.shell.flicker.utils.SplitScreenUtils import org.junit.After import org.junit.Assume import org.junit.Before diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenByDragFromTaskbar.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenByDragFromTaskbar.kt index 322f7115ec98..ae5bb6881863 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenByDragFromTaskbar.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenByDragFromTaskbar.kt @@ -24,7 +24,9 @@ import androidx.test.platform.app.InstrumentationRegistry import androidx.test.uiautomator.UiDevice import com.android.launcher3.tapl.LauncherInstrumentation import com.android.wm.shell.flicker.service.Utils +import com.android.wm.shell.flicker.utils.SplitScreenUtils import org.junit.After +import org.junit.Assume import org.junit.Before import org.junit.Ignore import org.junit.Rule @@ -45,6 +47,8 @@ constructor(val rotation: Rotation = Rotation.ROTATION_0) { @Before fun setup() { + Assume.assumeTrue(tapl.isTablet) + tapl.setEnableRotation(true) tapl.setExpectedRotation(rotation.value) diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenFromOverview.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenFromOverview.kt index f1644519e18a..c2100f641a55 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenFromOverview.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/EnterSplitScreenFromOverview.kt @@ -24,6 +24,7 @@ import androidx.test.platform.app.InstrumentationRegistry import androidx.test.uiautomator.UiDevice import com.android.launcher3.tapl.LauncherInstrumentation import com.android.wm.shell.flicker.service.Utils +import com.android.wm.shell.flicker.utils.SplitScreenUtils import org.junit.After import org.junit.Before import org.junit.Ignore diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SplitScreenUtils.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SplitScreenUtils.kt deleted file mode 100644 index 3831c65526a4..000000000000 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SplitScreenUtils.kt +++ /dev/null @@ -1,387 +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.wm.shell.flicker.service.splitscreen.scenarios - -import android.app.Instrumentation -import android.graphics.Point -import android.os.SystemClock -import android.tools.common.traces.component.ComponentNameMatcher -import android.tools.common.traces.component.IComponentMatcher -import android.tools.common.traces.component.IComponentNameMatcher -import android.tools.device.apphelpers.StandardAppHelper -import android.tools.device.traces.parsers.WindowManagerStateHelper -import android.tools.device.traces.parsers.toFlickerComponent -import android.view.InputDevice -import android.view.MotionEvent -import android.view.ViewConfiguration -import androidx.test.uiautomator.By -import androidx.test.uiautomator.BySelector -import androidx.test.uiautomator.UiDevice -import androidx.test.uiautomator.UiObject2 -import androidx.test.uiautomator.Until -import com.android.launcher3.tapl.LauncherInstrumentation -import com.android.server.wm.flicker.helpers.ImeAppHelper -import com.android.server.wm.flicker.helpers.NonResizeableAppHelper -import com.android.server.wm.flicker.helpers.NotificationAppHelper -import com.android.server.wm.flicker.helpers.SimpleAppHelper -import com.android.server.wm.flicker.testapp.ActivityOptions -import com.android.wm.shell.flicker.LAUNCHER_UI_PACKAGE_NAME -import com.android.wm.shell.flicker.SYSTEM_UI_PACKAGE_NAME -import org.junit.Assert.assertNotNull - -object SplitScreenUtils { - private const val TIMEOUT_MS = 3_000L - private const val DRAG_DURATION_MS = 1_000L - private const val NOTIFICATION_SCROLLER = "notification_stack_scroller" - private const val DIVIDER_BAR = "docked_divider_handle" - private const val OVERVIEW_SNAPSHOT = "snapshot" - private const val GESTURE_STEP_MS = 16L - private val LONG_PRESS_TIME_MS = ViewConfiguration.getLongPressTimeout() * 2L - private val SPLIT_DECOR_MANAGER = ComponentNameMatcher("", "SplitDecorManager#") - - private val notificationScrollerSelector: BySelector - get() = By.res(SYSTEM_UI_PACKAGE_NAME, NOTIFICATION_SCROLLER) - private val notificationContentSelector: BySelector - get() = By.text("Flicker Test Notification") - private val dividerBarSelector: BySelector - get() = By.res(SYSTEM_UI_PACKAGE_NAME, DIVIDER_BAR) - private val overviewSnapshotSelector: BySelector - get() = By.res(LAUNCHER_UI_PACKAGE_NAME, OVERVIEW_SNAPSHOT) - - fun getPrimary(instrumentation: Instrumentation): StandardAppHelper = - SimpleAppHelper( - instrumentation, - ActivityOptions.SplitScreen.Primary.LABEL, - ActivityOptions.SplitScreen.Primary.COMPONENT.toFlickerComponent() - ) - - fun getSecondary(instrumentation: Instrumentation): StandardAppHelper = - SimpleAppHelper( - instrumentation, - ActivityOptions.SplitScreen.Secondary.LABEL, - ActivityOptions.SplitScreen.Secondary.COMPONENT.toFlickerComponent() - ) - - fun getNonResizeable(instrumentation: Instrumentation): NonResizeableAppHelper = - NonResizeableAppHelper(instrumentation) - - fun getSendNotification(instrumentation: Instrumentation): NotificationAppHelper = - NotificationAppHelper(instrumentation) - - fun getIme(instrumentation: Instrumentation): ImeAppHelper = ImeAppHelper(instrumentation) - - fun waitForSplitComplete( - wmHelper: WindowManagerStateHelper, - primaryApp: IComponentMatcher, - secondaryApp: IComponentMatcher, - ) { - wmHelper - .StateSyncBuilder() - .withWindowSurfaceAppeared(primaryApp) - .withWindowSurfaceAppeared(secondaryApp) - .withSplitDividerVisible() - .waitForAndVerify() - } - - fun enterSplit( - wmHelper: WindowManagerStateHelper, - tapl: LauncherInstrumentation, - device: UiDevice, - primaryApp: StandardAppHelper, - secondaryApp: StandardAppHelper - ) { - primaryApp.launchViaIntent(wmHelper) - secondaryApp.launchViaIntent(wmHelper) - tapl.goHome() - wmHelper.StateSyncBuilder().withHomeActivityVisible().waitForAndVerify() - splitFromOverview(tapl, device) - waitForSplitComplete(wmHelper, primaryApp, secondaryApp) - } - - fun splitFromOverview(tapl: LauncherInstrumentation, device: UiDevice) { - // Note: The initial split position in landscape is different between tablet and phone. - // In landscape, tablet will let the first app split to right side, and phone will - // split to left side. - if (tapl.isTablet) { - // TAPL's currentTask on tablet is sometimes not what we expected if the overview - // contains more than 3 task views. We need to use uiautomator directly to find the - // second task to split. - tapl.workspace.switchToOverview().overviewActions.clickSplit() - val snapshots = device.wait(Until.findObjects(overviewSnapshotSelector), TIMEOUT_MS) - if (snapshots == null || snapshots.size < 1) { - error("Fail to find a overview snapshot to split.") - } - - // Find the second task in the upper right corner in split select mode by sorting - // 'left' in descending order and 'top' in ascending order. - snapshots.sortWith { t1: UiObject2, t2: UiObject2 -> - t2.getVisibleBounds().left - t1.getVisibleBounds().left - } - snapshots.sortWith { t1: UiObject2, t2: UiObject2 -> - t1.getVisibleBounds().top - t2.getVisibleBounds().top - } - snapshots[0].click() - } else { - tapl.workspace - .switchToOverview() - .currentTask - .tapMenu() - .tapSplitMenuItem() - .currentTask - .open() - } - SystemClock.sleep(TIMEOUT_MS) - } - - fun enterSplitViaIntent( - wmHelper: WindowManagerStateHelper, - primaryApp: StandardAppHelper, - secondaryApp: StandardAppHelper - ) { - val stringExtras = - mapOf(ActivityOptions.SplitScreen.Primary.EXTRA_LAUNCH_ADJACENT to "true") - primaryApp.launchViaIntent(wmHelper, null, null, stringExtras) - SplitScreenUtils.waitForSplitComplete(wmHelper, primaryApp, secondaryApp) - } - - fun dragFromNotificationToSplit( - instrumentation: Instrumentation, - device: UiDevice, - wmHelper: WindowManagerStateHelper - ) { - val displayBounds = - wmHelper.currentState.layerState.displays.firstOrNull { !it.isVirtual }?.layerStackSpace - ?: error("Display not found") - - // Pull down the notifications - device.swipe( - displayBounds.centerX(), - 5, - displayBounds.centerX(), - displayBounds.bottom, - 50 /* steps */ - ) - SystemClock.sleep(TIMEOUT_MS) - - // Find the target notification - val notificationScroller = - device.wait(Until.findObject(notificationScrollerSelector), TIMEOUT_MS) - ?: error("Unable to find view $notificationScrollerSelector") - var notificationContent = notificationScroller.findObject(notificationContentSelector) - - while (notificationContent == null) { - device.swipe( - displayBounds.centerX(), - displayBounds.centerY(), - displayBounds.centerX(), - displayBounds.centerY() - 150, - 20 /* steps */ - ) - notificationContent = notificationScroller.findObject(notificationContentSelector) - } - - // Drag to split - val dragStart = notificationContent.visibleCenter - val dragMiddle = Point(dragStart.x + 50, dragStart.y) - val dragEnd = Point(displayBounds.width / 4, displayBounds.width / 4) - val downTime = SystemClock.uptimeMillis() - - touch(instrumentation, MotionEvent.ACTION_DOWN, downTime, downTime, TIMEOUT_MS, dragStart) - // It needs a horizontal movement to trigger the drag - touchMove( - instrumentation, - downTime, - SystemClock.uptimeMillis(), - DRAG_DURATION_MS, - dragStart, - dragMiddle - ) - touchMove( - instrumentation, - downTime, - SystemClock.uptimeMillis(), - DRAG_DURATION_MS, - dragMiddle, - dragEnd - ) - // Wait for a while to start splitting - SystemClock.sleep(TIMEOUT_MS) - touch( - instrumentation, - MotionEvent.ACTION_UP, - downTime, - SystemClock.uptimeMillis(), - GESTURE_STEP_MS, - dragEnd - ) - SystemClock.sleep(TIMEOUT_MS) - } - - fun touch( - instrumentation: Instrumentation, - action: Int, - downTime: Long, - eventTime: Long, - duration: Long, - point: Point - ) { - val motionEvent = - MotionEvent.obtain(downTime, eventTime, action, point.x.toFloat(), point.y.toFloat(), 0) - motionEvent.source = InputDevice.SOURCE_TOUCHSCREEN - instrumentation.uiAutomation.injectInputEvent(motionEvent, true) - motionEvent.recycle() - SystemClock.sleep(duration) - } - - fun touchMove( - instrumentation: Instrumentation, - downTime: Long, - eventTime: Long, - duration: Long, - from: Point, - to: Point - ) { - val steps: Long = duration / GESTURE_STEP_MS - var currentTime = eventTime - var currentX = from.x.toFloat() - var currentY = from.y.toFloat() - val stepX = (to.x.toFloat() - from.x.toFloat()) / steps.toFloat() - val stepY = (to.y.toFloat() - from.y.toFloat()) / steps.toFloat() - - for (i in 1..steps) { - val motionMove = - MotionEvent.obtain( - downTime, - currentTime, - MotionEvent.ACTION_MOVE, - currentX, - currentY, - 0 - ) - motionMove.source = InputDevice.SOURCE_TOUCHSCREEN - instrumentation.uiAutomation.injectInputEvent(motionMove, true) - motionMove.recycle() - - currentTime += GESTURE_STEP_MS - if (i == steps - 1) { - currentX = to.x.toFloat() - currentY = to.y.toFloat() - } else { - currentX += stepX - currentY += stepY - } - SystemClock.sleep(GESTURE_STEP_MS) - } - } - - fun createShortcutOnHotseatIfNotExist(tapl: LauncherInstrumentation, appName: String) { - tapl.workspace.deleteAppIcon(tapl.workspace.getHotseatAppIcon(0)) - val allApps = tapl.workspace.switchToAllApps() - allApps.freeze() - try { - allApps.getAppIcon(appName).dragToHotseat(0) - } finally { - allApps.unfreeze() - } - } - - fun dragDividerToResizeAndWait(device: UiDevice, wmHelper: WindowManagerStateHelper) { - val displayBounds = - wmHelper.currentState.layerState.displays.firstOrNull { !it.isVirtual }?.layerStackSpace - ?: error("Display not found") - val dividerBar = device.wait(Until.findObject(dividerBarSelector), TIMEOUT_MS) - dividerBar.drag(Point(displayBounds.width * 1 / 3, displayBounds.height * 2 / 3), 200) - - wmHelper - .StateSyncBuilder() - .withWindowSurfaceDisappeared(SPLIT_DECOR_MANAGER) - .waitForAndVerify() - } - - fun dragDividerToDismissSplit( - device: UiDevice, - wmHelper: WindowManagerStateHelper, - dragToRight: Boolean, - dragToBottom: Boolean - ) { - val displayBounds = - wmHelper.currentState.layerState.displays.firstOrNull { !it.isVirtual }?.layerStackSpace - ?: error("Display not found") - val dividerBar = device.wait(Until.findObject(dividerBarSelector), TIMEOUT_MS) - dividerBar.drag( - Point( - if (dragToRight) { - displayBounds.width * 4 / 5 - } else { - displayBounds.width * 1 / 5 - }, - if (dragToBottom) { - displayBounds.height * 4 / 5 - } else { - displayBounds.height * 1 / 5 - } - ) - ) - } - - fun doubleTapDividerToSwitch(device: UiDevice) { - val dividerBar = device.wait(Until.findObject(dividerBarSelector), TIMEOUT_MS) - val interval = - (ViewConfiguration.getDoubleTapTimeout() + ViewConfiguration.getDoubleTapMinTime()) / 2 - dividerBar.click() - SystemClock.sleep(interval.toLong()) - dividerBar.click() - } - - fun copyContentInSplit( - instrumentation: Instrumentation, - device: UiDevice, - sourceApp: IComponentNameMatcher, - destinationApp: IComponentNameMatcher, - ) { - // Copy text from sourceApp - val textView = - device.wait( - Until.findObject(By.res(sourceApp.packageName, "SplitScreenTest")), - TIMEOUT_MS - ) - assertNotNull("Unable to find the TextView", textView) - textView.click(LONG_PRESS_TIME_MS) - - val copyBtn = device.wait(Until.findObject(By.text("Copy")), TIMEOUT_MS) - assertNotNull("Unable to find the copy button", copyBtn) - copyBtn.click() - - // Paste text to destinationApp - val editText = - device.wait( - Until.findObject(By.res(destinationApp.packageName, "plain_text_input")), - TIMEOUT_MS - ) - assertNotNull("Unable to find the EditText", editText) - editText.click(LONG_PRESS_TIME_MS) - - val pasteBtn = device.wait(Until.findObject(By.text("Paste")), TIMEOUT_MS) - assertNotNull("Unable to find the paste button", pasteBtn) - pasteBtn.click() - - // Verify text - if (!textView.text.contentEquals(editText.text)) { - error("Fail to copy content in split") - } - } -} diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchAppByDoubleTapDivider.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchAppByDoubleTapDivider.kt index 805d98785a33..70f3bed9afdc 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchAppByDoubleTapDivider.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchAppByDoubleTapDivider.kt @@ -26,6 +26,7 @@ import androidx.test.platform.app.InstrumentationRegistry import androidx.test.uiautomator.UiDevice import com.android.launcher3.tapl.LauncherInstrumentation import com.android.wm.shell.flicker.service.Utils +import com.android.wm.shell.flicker.utils.SplitScreenUtils import org.junit.After import org.junit.Before import org.junit.Ignore diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchBackToSplitFromAnotherApp.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchBackToSplitFromAnotherApp.kt index 4229ebb1cebb..86f394da0231 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchBackToSplitFromAnotherApp.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchBackToSplitFromAnotherApp.kt @@ -24,6 +24,7 @@ import androidx.test.platform.app.InstrumentationRegistry import androidx.test.uiautomator.UiDevice import com.android.launcher3.tapl.LauncherInstrumentation import com.android.wm.shell.flicker.service.Utils +import com.android.wm.shell.flicker.utils.SplitScreenUtils import org.junit.After import org.junit.Before import org.junit.Ignore diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchBackToSplitFromHome.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchBackToSplitFromHome.kt index f2d56b99dab6..d7b611e04d9d 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchBackToSplitFromHome.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchBackToSplitFromHome.kt @@ -24,6 +24,7 @@ import androidx.test.platform.app.InstrumentationRegistry import androidx.test.uiautomator.UiDevice import com.android.launcher3.tapl.LauncherInstrumentation import com.android.wm.shell.flicker.service.Utils +import com.android.wm.shell.flicker.utils.SplitScreenUtils import org.junit.After import org.junit.Before import org.junit.Ignore diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchBackToSplitFromRecent.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchBackToSplitFromRecent.kt index d44d1779a3f6..3cc5df09b16e 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchBackToSplitFromRecent.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchBackToSplitFromRecent.kt @@ -24,6 +24,7 @@ import androidx.test.platform.app.InstrumentationRegistry import androidx.test.uiautomator.UiDevice import com.android.launcher3.tapl.LauncherInstrumentation import com.android.wm.shell.flicker.service.Utils +import com.android.wm.shell.flicker.utils.SplitScreenUtils import org.junit.After import org.junit.Before import org.junit.Ignore @@ -47,6 +48,7 @@ constructor(val rotation: Rotation = Rotation.ROTATION_0) { fun setup() { tapl.setEnableRotation(true) tapl.setExpectedRotation(rotation.value) + tapl.workspace.switchToOverview().dismissAllTasks() SplitScreenUtils.enterSplit(wmHelper, tapl, device, primaryApp, secondaryApp) diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchBetweenSplitPairs.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchBetweenSplitPairs.kt index e2c6ca67d730..4a9c32f10415 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchBetweenSplitPairs.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/SwitchBetweenSplitPairs.kt @@ -24,6 +24,7 @@ import androidx.test.platform.app.InstrumentationRegistry import androidx.test.uiautomator.UiDevice import com.android.launcher3.tapl.LauncherInstrumentation import com.android.wm.shell.flicker.service.Utils +import com.android.wm.shell.flicker.utils.SplitScreenUtils import org.junit.After import org.junit.Before import org.junit.Ignore diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/UnlockKeyguardToSplitScreen.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/UnlockKeyguardToSplitScreen.kt index df98d8f6145a..383a6b39a2b6 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/UnlockKeyguardToSplitScreen.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/service/splitscreen/scenarios/UnlockKeyguardToSplitScreen.kt @@ -24,6 +24,7 @@ import androidx.test.platform.app.InstrumentationRegistry import androidx.test.uiautomator.UiDevice import com.android.launcher3.tapl.LauncherInstrumentation import com.android.wm.shell.flicker.service.Utils +import com.android.wm.shell.flicker.utils.SplitScreenUtils import org.junit.After import org.junit.Before import org.junit.Ignore diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/CopyContentInSplit.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/CopyContentInSplit.kt index 1d4c4d2f7068..3702be9541a3 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/CopyContentInSplit.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/CopyContentInSplit.kt @@ -25,12 +25,12 @@ import android.tools.device.flicker.legacy.FlickerBuilder import android.tools.device.flicker.legacy.LegacyFlickerTest import android.tools.device.flicker.legacy.LegacyFlickerTestFactory import androidx.test.filters.RequiresDevice -import com.android.wm.shell.flicker.ICommonAssertions -import com.android.wm.shell.flicker.SPLIT_SCREEN_DIVIDER_COMPONENT -import com.android.wm.shell.flicker.appWindowKeepVisible -import com.android.wm.shell.flicker.layerKeepVisible -import com.android.wm.shell.flicker.splitAppLayerBoundsKeepVisible import com.android.wm.shell.flicker.splitscreen.benchmark.CopyContentInSplitBenchmark +import com.android.wm.shell.flicker.utils.ICommonAssertions +import com.android.wm.shell.flicker.utils.SPLIT_SCREEN_DIVIDER_COMPONENT +import com.android.wm.shell.flicker.utils.appWindowKeepVisible +import com.android.wm.shell.flicker.utils.layerKeepVisible +import com.android.wm.shell.flicker.utils.splitAppLayerBoundsKeepVisible import org.junit.FixMethodOrder import org.junit.Test import org.junit.runner.RunWith diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DismissSplitScreenByDivider.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DismissSplitScreenByDivider.kt index 0b8f109b0e42..8b906305506f 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DismissSplitScreenByDivider.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DismissSplitScreenByDivider.kt @@ -24,14 +24,14 @@ import android.tools.device.flicker.legacy.FlickerBuilder import android.tools.device.flicker.legacy.LegacyFlickerTest import android.tools.device.helpers.WindowUtils import androidx.test.filters.RequiresDevice -import com.android.wm.shell.flicker.ICommonAssertions -import com.android.wm.shell.flicker.appWindowBecomesInvisible -import com.android.wm.shell.flicker.appWindowIsVisibleAtEnd -import com.android.wm.shell.flicker.layerBecomesInvisible -import com.android.wm.shell.flicker.layerIsVisibleAtEnd -import com.android.wm.shell.flicker.splitAppLayerBoundsBecomesInvisible -import com.android.wm.shell.flicker.splitScreenDividerBecomesInvisible import com.android.wm.shell.flicker.splitscreen.benchmark.DismissSplitScreenByDividerBenchmark +import com.android.wm.shell.flicker.utils.ICommonAssertions +import com.android.wm.shell.flicker.utils.appWindowBecomesInvisible +import com.android.wm.shell.flicker.utils.appWindowIsVisibleAtEnd +import com.android.wm.shell.flicker.utils.layerBecomesInvisible +import com.android.wm.shell.flicker.utils.layerIsVisibleAtEnd +import com.android.wm.shell.flicker.utils.splitAppLayerBoundsBecomesInvisible +import com.android.wm.shell.flicker.utils.splitScreenDividerBecomesInvisible import org.junit.FixMethodOrder import org.junit.Test import org.junit.runner.RunWith diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DismissSplitScreenByGoHome.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DismissSplitScreenByGoHome.kt index 38d4b4029c64..50f6a382a702 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DismissSplitScreenByGoHome.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DismissSplitScreenByGoHome.kt @@ -23,12 +23,12 @@ import android.tools.device.flicker.legacy.FlickerBuilder import android.tools.device.flicker.legacy.LegacyFlickerTest import android.tools.device.flicker.legacy.LegacyFlickerTestFactory import androidx.test.filters.RequiresDevice -import com.android.wm.shell.flicker.ICommonAssertions -import com.android.wm.shell.flicker.appWindowBecomesInvisible -import com.android.wm.shell.flicker.layerBecomesInvisible -import com.android.wm.shell.flicker.splitAppLayerBoundsBecomesInvisible -import com.android.wm.shell.flicker.splitScreenDividerBecomesInvisible import com.android.wm.shell.flicker.splitscreen.benchmark.DismissSplitScreenByGoHomeBenchmark +import com.android.wm.shell.flicker.utils.ICommonAssertions +import com.android.wm.shell.flicker.utils.appWindowBecomesInvisible +import com.android.wm.shell.flicker.utils.layerBecomesInvisible +import com.android.wm.shell.flicker.utils.splitAppLayerBoundsBecomesInvisible +import com.android.wm.shell.flicker.utils.splitScreenDividerBecomesInvisible import org.junit.FixMethodOrder import org.junit.Test import org.junit.runner.RunWith diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DragDividerToResize.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DragDividerToResize.kt index 0d967eb15e0f..cc3b783e53d2 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DragDividerToResize.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DragDividerToResize.kt @@ -23,12 +23,12 @@ import android.tools.device.flicker.legacy.FlickerBuilder import android.tools.device.flicker.legacy.LegacyFlickerTest import android.tools.device.flicker.legacy.LegacyFlickerTestFactory import androidx.test.filters.RequiresDevice -import com.android.wm.shell.flicker.ICommonAssertions -import com.android.wm.shell.flicker.SPLIT_SCREEN_DIVIDER_COMPONENT -import com.android.wm.shell.flicker.appWindowKeepVisible -import com.android.wm.shell.flicker.layerKeepVisible -import com.android.wm.shell.flicker.splitAppLayerBoundsChanges import com.android.wm.shell.flicker.splitscreen.benchmark.DragDividerToResizeBenchmark +import com.android.wm.shell.flicker.utils.ICommonAssertions +import com.android.wm.shell.flicker.utils.SPLIT_SCREEN_DIVIDER_COMPONENT +import com.android.wm.shell.flicker.utils.appWindowKeepVisible +import com.android.wm.shell.flicker.utils.layerKeepVisible +import com.android.wm.shell.flicker.utils.splitAppLayerBoundsChanges import org.junit.FixMethodOrder import org.junit.Test import org.junit.runner.RunWith @@ -57,7 +57,7 @@ class DragDividerToResize(override val flicker: LegacyFlickerTest) : @Test fun splitScreenDividerKeepVisible() = flicker.layerKeepVisible(SPLIT_SCREEN_DIVIDER_COMPONENT) - @Presubmit + @FlakyTest(bugId = 291678271) @Test fun primaryAppLayerVisibilityChanges() { flicker.assertLayers { @@ -69,7 +69,7 @@ class DragDividerToResize(override val flicker: LegacyFlickerTest) : } } - @Presubmit + @FlakyTest(bugId = 291678271) @Test fun secondaryAppLayerVisibilityChanges() { flicker.assertLayers { @@ -87,7 +87,7 @@ class DragDividerToResize(override val flicker: LegacyFlickerTest) : @Test fun secondaryAppWindowKeepVisible() = flicker.appWindowKeepVisible(secondaryApp) - @FlakyTest(bugId = 245472831) + @FlakyTest(bugId = 291678271) @Test fun primaryAppBoundsChanges() { flicker.splitAppLayerBoundsChanges( @@ -97,7 +97,7 @@ class DragDividerToResize(override val flicker: LegacyFlickerTest) : ) } - @Presubmit + @FlakyTest(bugId = 291678271) @Test fun secondaryAppBoundsChanges() = flicker.splitAppLayerBoundsChanges( @@ -106,6 +106,12 @@ class DragDividerToResize(override val flicker: LegacyFlickerTest) : portraitPosTop = true ) + @FlakyTest(bugId = 291678271) + @Test + override fun visibleLayersShownMoreThanOneConsecutiveEntry() { + super.visibleLayersShownMoreThanOneConsecutiveEntry() + } + companion object { @Parameterized.Parameters(name = "{0}") @JvmStatic diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromAllApps.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromAllApps.kt index 05c048050b3b..f8d1e1f1f498 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromAllApps.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromAllApps.kt @@ -25,16 +25,16 @@ import android.tools.device.flicker.legacy.FlickerBuilder import android.tools.device.flicker.legacy.LegacyFlickerTest import android.tools.device.flicker.legacy.LegacyFlickerTestFactory import androidx.test.filters.RequiresDevice -import com.android.wm.shell.flicker.ICommonAssertions -import com.android.wm.shell.flicker.SPLIT_SCREEN_DIVIDER_COMPONENT -import com.android.wm.shell.flicker.appWindowBecomesVisible -import com.android.wm.shell.flicker.appWindowIsVisibleAtEnd -import com.android.wm.shell.flicker.layerBecomesVisible -import com.android.wm.shell.flicker.layerIsVisibleAtEnd -import com.android.wm.shell.flicker.splitAppLayerBoundsBecomesVisibleByDrag -import com.android.wm.shell.flicker.splitAppLayerBoundsIsVisibleAtEnd -import com.android.wm.shell.flicker.splitScreenDividerBecomesVisible import com.android.wm.shell.flicker.splitscreen.benchmark.EnterSplitScreenByDragFromAllAppsBenchmark +import com.android.wm.shell.flicker.utils.ICommonAssertions +import com.android.wm.shell.flicker.utils.SPLIT_SCREEN_DIVIDER_COMPONENT +import com.android.wm.shell.flicker.utils.appWindowBecomesVisible +import com.android.wm.shell.flicker.utils.appWindowIsVisibleAtEnd +import com.android.wm.shell.flicker.utils.layerBecomesVisible +import com.android.wm.shell.flicker.utils.layerIsVisibleAtEnd +import com.android.wm.shell.flicker.utils.splitAppLayerBoundsBecomesVisibleByDrag +import com.android.wm.shell.flicker.utils.splitAppLayerBoundsIsVisibleAtEnd +import com.android.wm.shell.flicker.utils.splitScreenDividerBecomesVisible import org.junit.FixMethodOrder import org.junit.Test import org.junit.runner.RunWith diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromNotification.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromNotification.kt index 3a75fa60a865..ff5d93550541 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromNotification.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromNotification.kt @@ -25,15 +25,15 @@ import android.tools.device.flicker.legacy.FlickerBuilder import android.tools.device.flicker.legacy.LegacyFlickerTest import android.tools.device.flicker.legacy.LegacyFlickerTestFactory import androidx.test.filters.RequiresDevice -import com.android.wm.shell.flicker.ICommonAssertions -import com.android.wm.shell.flicker.SPLIT_SCREEN_DIVIDER_COMPONENT -import com.android.wm.shell.flicker.appWindowIsVisibleAtEnd -import com.android.wm.shell.flicker.layerBecomesVisible -import com.android.wm.shell.flicker.layerIsVisibleAtEnd -import com.android.wm.shell.flicker.splitAppLayerBoundsBecomesVisibleByDrag -import com.android.wm.shell.flicker.splitAppLayerBoundsIsVisibleAtEnd -import com.android.wm.shell.flicker.splitScreenDividerBecomesVisible import com.android.wm.shell.flicker.splitscreen.benchmark.EnterSplitScreenByDragFromNotificationBenchmark +import com.android.wm.shell.flicker.utils.ICommonAssertions +import com.android.wm.shell.flicker.utils.SPLIT_SCREEN_DIVIDER_COMPONENT +import com.android.wm.shell.flicker.utils.appWindowIsVisibleAtEnd +import com.android.wm.shell.flicker.utils.layerBecomesVisible +import com.android.wm.shell.flicker.utils.layerIsVisibleAtEnd +import com.android.wm.shell.flicker.utils.splitAppLayerBoundsBecomesVisibleByDrag +import com.android.wm.shell.flicker.utils.splitAppLayerBoundsIsVisibleAtEnd +import com.android.wm.shell.flicker.utils.splitScreenDividerBecomesVisible import org.junit.FixMethodOrder import org.junit.Test import org.junit.runner.RunWith diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromShortcut.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromShortcut.kt index 6d73f92637db..7c710777087d 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromShortcut.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromShortcut.kt @@ -24,14 +24,14 @@ import android.tools.device.flicker.legacy.FlickerBuilder import android.tools.device.flicker.legacy.LegacyFlickerTest import android.tools.device.flicker.legacy.LegacyFlickerTestFactory import androidx.test.filters.RequiresDevice -import com.android.wm.shell.flicker.ICommonAssertions -import com.android.wm.shell.flicker.appWindowIsVisibleAtEnd -import com.android.wm.shell.flicker.layerBecomesVisible -import com.android.wm.shell.flicker.layerIsVisibleAtEnd -import com.android.wm.shell.flicker.splitAppLayerBoundsBecomesVisibleByDrag -import com.android.wm.shell.flicker.splitAppLayerBoundsIsVisibleAtEnd -import com.android.wm.shell.flicker.splitScreenDividerBecomesVisible import com.android.wm.shell.flicker.splitscreen.benchmark.EnterSplitScreenByDragFromShortcutBenchmark +import com.android.wm.shell.flicker.utils.ICommonAssertions +import com.android.wm.shell.flicker.utils.appWindowIsVisibleAtEnd +import com.android.wm.shell.flicker.utils.layerBecomesVisible +import com.android.wm.shell.flicker.utils.layerIsVisibleAtEnd +import com.android.wm.shell.flicker.utils.splitAppLayerBoundsBecomesVisibleByDrag +import com.android.wm.shell.flicker.utils.splitAppLayerBoundsIsVisibleAtEnd +import com.android.wm.shell.flicker.utils.splitScreenDividerBecomesVisible import org.junit.FixMethodOrder import org.junit.Test import org.junit.runner.RunWith diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromTaskbar.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromTaskbar.kt index 15cae6947f88..83717062b05e 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromTaskbar.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromTaskbar.kt @@ -25,16 +25,16 @@ import android.tools.device.flicker.legacy.FlickerBuilder import android.tools.device.flicker.legacy.LegacyFlickerTest import android.tools.device.flicker.legacy.LegacyFlickerTestFactory import androidx.test.filters.RequiresDevice -import com.android.wm.shell.flicker.ICommonAssertions -import com.android.wm.shell.flicker.SPLIT_SCREEN_DIVIDER_COMPONENT -import com.android.wm.shell.flicker.appWindowBecomesVisible -import com.android.wm.shell.flicker.appWindowIsVisibleAtEnd -import com.android.wm.shell.flicker.layerBecomesVisible -import com.android.wm.shell.flicker.layerIsVisibleAtEnd -import com.android.wm.shell.flicker.splitAppLayerBoundsBecomesVisibleByDrag -import com.android.wm.shell.flicker.splitAppLayerBoundsIsVisibleAtEnd -import com.android.wm.shell.flicker.splitScreenDividerBecomesVisible import com.android.wm.shell.flicker.splitscreen.benchmark.EnterSplitScreenByDragFromTaskbarBenchmark +import com.android.wm.shell.flicker.utils.ICommonAssertions +import com.android.wm.shell.flicker.utils.SPLIT_SCREEN_DIVIDER_COMPONENT +import com.android.wm.shell.flicker.utils.appWindowBecomesVisible +import com.android.wm.shell.flicker.utils.appWindowIsVisibleAtEnd +import com.android.wm.shell.flicker.utils.layerBecomesVisible +import com.android.wm.shell.flicker.utils.layerIsVisibleAtEnd +import com.android.wm.shell.flicker.utils.splitAppLayerBoundsBecomesVisibleByDrag +import com.android.wm.shell.flicker.utils.splitAppLayerBoundsIsVisibleAtEnd +import com.android.wm.shell.flicker.utils.splitScreenDividerBecomesVisible import org.junit.FixMethodOrder import org.junit.Test import org.junit.runner.RunWith diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenFromOverview.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenFromOverview.kt index 90399fca2574..0bfdbb4de7c5 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenFromOverview.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenFromOverview.kt @@ -23,14 +23,14 @@ import android.tools.device.flicker.legacy.FlickerBuilder import android.tools.device.flicker.legacy.LegacyFlickerTest import android.tools.device.flicker.legacy.LegacyFlickerTestFactory import androidx.test.filters.RequiresDevice -import com.android.wm.shell.flicker.ICommonAssertions -import com.android.wm.shell.flicker.appWindowBecomesVisible -import com.android.wm.shell.flicker.layerBecomesVisible -import com.android.wm.shell.flicker.layerIsVisibleAtEnd -import com.android.wm.shell.flicker.splitAppLayerBoundsBecomesVisible -import com.android.wm.shell.flicker.splitAppLayerBoundsIsVisibleAtEnd -import com.android.wm.shell.flicker.splitScreenDividerBecomesVisible import com.android.wm.shell.flicker.splitscreen.benchmark.EnterSplitScreenFromOverviewBenchmark +import com.android.wm.shell.flicker.utils.ICommonAssertions +import com.android.wm.shell.flicker.utils.appWindowBecomesVisible +import com.android.wm.shell.flicker.utils.layerBecomesVisible +import com.android.wm.shell.flicker.utils.layerIsVisibleAtEnd +import com.android.wm.shell.flicker.utils.splitAppLayerBoundsBecomesVisible +import com.android.wm.shell.flicker.utils.splitAppLayerBoundsIsVisibleAtEnd +import com.android.wm.shell.flicker.utils.splitScreenDividerBecomesVisible import org.junit.FixMethodOrder import org.junit.Test import org.junit.runner.RunWith diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/OWNERS b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/OWNERS new file mode 100644 index 000000000000..3ab6a1ee061d --- /dev/null +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/OWNERS @@ -0,0 +1,2 @@ +# Android > Android OS & Apps > Framework (Java + Native) > Window Manager > WM Shell > Split Screen +# Bug component: 928697 diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchAppByDoubleTapDivider.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchAppByDoubleTapDivider.kt index f236c2d11ecb..fac97c8cc8c4 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchAppByDoubleTapDivider.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchAppByDoubleTapDivider.kt @@ -24,13 +24,13 @@ import android.tools.device.flicker.legacy.FlickerBuilder import android.tools.device.flicker.legacy.LegacyFlickerTest import android.tools.device.flicker.legacy.LegacyFlickerTestFactory import androidx.test.filters.RequiresDevice -import com.android.wm.shell.flicker.ICommonAssertions -import com.android.wm.shell.flicker.SPLIT_SCREEN_DIVIDER_COMPONENT -import com.android.wm.shell.flicker.appWindowIsVisibleAtEnd -import com.android.wm.shell.flicker.layerIsVisibleAtEnd -import com.android.wm.shell.flicker.layerKeepVisible -import com.android.wm.shell.flicker.splitAppLayerBoundsIsVisibleAtEnd import com.android.wm.shell.flicker.splitscreen.benchmark.SwitchAppByDoubleTapDividerBenchmark +import com.android.wm.shell.flicker.utils.ICommonAssertions +import com.android.wm.shell.flicker.utils.SPLIT_SCREEN_DIVIDER_COMPONENT +import com.android.wm.shell.flicker.utils.appWindowIsVisibleAtEnd +import com.android.wm.shell.flicker.utils.layerIsVisibleAtEnd +import com.android.wm.shell.flicker.utils.layerKeepVisible +import com.android.wm.shell.flicker.utils.splitAppLayerBoundsIsVisibleAtEnd import org.junit.FixMethodOrder import org.junit.Test import org.junit.runner.RunWith diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromAnotherApp.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromAnotherApp.kt index a4060092b422..88bbc0e7880b 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromAnotherApp.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromAnotherApp.kt @@ -24,12 +24,12 @@ import android.tools.device.flicker.legacy.FlickerBuilder import android.tools.device.flicker.legacy.LegacyFlickerTest import android.tools.device.flicker.legacy.LegacyFlickerTestFactory import androidx.test.filters.RequiresDevice -import com.android.wm.shell.flicker.ICommonAssertions -import com.android.wm.shell.flicker.appWindowBecomesVisible -import com.android.wm.shell.flicker.layerBecomesVisible -import com.android.wm.shell.flicker.splitAppLayerBoundsIsVisibleAtEnd -import com.android.wm.shell.flicker.splitScreenDividerBecomesVisible import com.android.wm.shell.flicker.splitscreen.benchmark.SwitchBackToSplitFromAnotherAppBenchmark +import com.android.wm.shell.flicker.utils.ICommonAssertions +import com.android.wm.shell.flicker.utils.appWindowBecomesVisible +import com.android.wm.shell.flicker.utils.layerBecomesVisible +import com.android.wm.shell.flicker.utils.splitAppLayerBoundsIsVisibleAtEnd +import com.android.wm.shell.flicker.utils.splitScreenDividerBecomesVisible import org.junit.FixMethodOrder import org.junit.Test import org.junit.runner.RunWith diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromHome.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromHome.kt index 251bd1030da3..e85dc24a7781 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromHome.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromHome.kt @@ -24,12 +24,12 @@ import android.tools.device.flicker.legacy.FlickerBuilder import android.tools.device.flicker.legacy.LegacyFlickerTest import android.tools.device.flicker.legacy.LegacyFlickerTestFactory import androidx.test.filters.RequiresDevice -import com.android.wm.shell.flicker.ICommonAssertions -import com.android.wm.shell.flicker.appWindowBecomesVisible -import com.android.wm.shell.flicker.layerBecomesVisible -import com.android.wm.shell.flicker.splitAppLayerBoundsIsVisibleAtEnd -import com.android.wm.shell.flicker.splitScreenDividerBecomesVisible import com.android.wm.shell.flicker.splitscreen.benchmark.SwitchBackToSplitFromHomeBenchmark +import com.android.wm.shell.flicker.utils.ICommonAssertions +import com.android.wm.shell.flicker.utils.appWindowBecomesVisible +import com.android.wm.shell.flicker.utils.layerBecomesVisible +import com.android.wm.shell.flicker.utils.splitAppLayerBoundsIsVisibleAtEnd +import com.android.wm.shell.flicker.utils.splitScreenDividerBecomesVisible import org.junit.FixMethodOrder import org.junit.Test import org.junit.runner.RunWith diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromRecent.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromRecent.kt index 1dd45fef30cc..f7a9ed073002 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromRecent.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromRecent.kt @@ -24,12 +24,12 @@ import android.tools.device.flicker.legacy.FlickerBuilder import android.tools.device.flicker.legacy.LegacyFlickerTest import android.tools.device.flicker.legacy.LegacyFlickerTestFactory import androidx.test.filters.RequiresDevice -import com.android.wm.shell.flicker.ICommonAssertions -import com.android.wm.shell.flicker.appWindowBecomesVisible -import com.android.wm.shell.flicker.layerBecomesVisible -import com.android.wm.shell.flicker.splitAppLayerBoundsIsVisibleAtEnd -import com.android.wm.shell.flicker.splitScreenDividerBecomesVisible import com.android.wm.shell.flicker.splitscreen.benchmark.SwitchBackToSplitFromRecentBenchmark +import com.android.wm.shell.flicker.utils.ICommonAssertions +import com.android.wm.shell.flicker.utils.appWindowBecomesVisible +import com.android.wm.shell.flicker.utils.layerBecomesVisible +import com.android.wm.shell.flicker.utils.splitAppLayerBoundsIsVisibleAtEnd +import com.android.wm.shell.flicker.utils.splitScreenDividerBecomesVisible import org.junit.FixMethodOrder import org.junit.Test import org.junit.runner.RunWith diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBetweenSplitPairs.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBetweenSplitPairs.kt index 8aaa98a5ca9f..66f9b85ea572 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBetweenSplitPairs.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBetweenSplitPairs.kt @@ -23,15 +23,15 @@ import android.tools.device.flicker.legacy.FlickerBuilder import android.tools.device.flicker.legacy.LegacyFlickerTest import android.tools.device.flicker.legacy.LegacyFlickerTestFactory import androidx.test.filters.RequiresDevice -import com.android.wm.shell.flicker.ICommonAssertions -import com.android.wm.shell.flicker.SPLIT_SCREEN_DIVIDER_COMPONENT -import com.android.wm.shell.flicker.appWindowBecomesInvisible -import com.android.wm.shell.flicker.appWindowBecomesVisible -import com.android.wm.shell.flicker.layerBecomesInvisible -import com.android.wm.shell.flicker.layerBecomesVisible -import com.android.wm.shell.flicker.splitAppLayerBoundsIsVisibleAtEnd -import com.android.wm.shell.flicker.splitAppLayerBoundsSnapToDivider import com.android.wm.shell.flicker.splitscreen.benchmark.SwitchBetweenSplitPairsBenchmark +import com.android.wm.shell.flicker.utils.ICommonAssertions +import com.android.wm.shell.flicker.utils.SPLIT_SCREEN_DIVIDER_COMPONENT +import com.android.wm.shell.flicker.utils.appWindowBecomesInvisible +import com.android.wm.shell.flicker.utils.appWindowBecomesVisible +import com.android.wm.shell.flicker.utils.layerBecomesInvisible +import com.android.wm.shell.flicker.utils.layerBecomesVisible +import com.android.wm.shell.flicker.utils.splitAppLayerBoundsIsVisibleAtEnd +import com.android.wm.shell.flicker.utils.splitAppLayerBoundsSnapToDivider import org.junit.FixMethodOrder import org.junit.Test import org.junit.runner.RunWith diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBetweenSplitPairsNoPip.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBetweenSplitPairsNoPip.kt new file mode 100644 index 000000000000..91e7d478557e --- /dev/null +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBetweenSplitPairsNoPip.kt @@ -0,0 +1,150 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.wm.shell.flicker.splitscreen + +import android.platform.test.annotations.Presubmit +import android.tools.common.NavBar +import android.tools.common.traces.component.ComponentNameMatcher +import android.tools.device.flicker.junit.FlickerParametersRunnerFactory +import android.tools.device.flicker.legacy.FlickerBuilder +import android.tools.device.flicker.legacy.LegacyFlickerTest +import android.tools.device.flicker.legacy.LegacyFlickerTestFactory +import androidx.test.filters.RequiresDevice +import com.android.server.wm.flicker.helpers.PipAppHelper +import com.android.wm.shell.flicker.utils.SplitScreenUtils +import com.android.wm.shell.flicker.splitscreen.benchmark.SplitScreenBase +import com.android.wm.shell.flicker.utils.layerBecomesInvisible +import com.android.wm.shell.flicker.utils.splitAppLayerBoundsIsVisibleAtEnd +import com.android.wm.shell.flicker.utils.splitAppLayerBoundsSnapToDivider +import org.junit.FixMethodOrder +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.MethodSorters +import org.junit.runners.Parameterized + +/** + * Test quick switch between two split pairs. + * + * To run this test: `atest WMShellFlickerTestsSplitScreen:SwitchBetweenSplitPairsNoPip` + */ +@RequiresDevice +@RunWith(Parameterized::class) +@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class) +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +class SwitchBetweenSplitPairsNoPip (override val flicker: LegacyFlickerTest) : + SplitScreenBase(flicker) { + + val thirdApp = SplitScreenUtils.getSendNotification(instrumentation) + val pipApp = PipAppHelper(instrumentation) + + override val transition: FlickerBuilder.() -> Unit + get() = { + defaultSetup(this) + defaultTeardown(this) + thisTransition(this) + } + + val thisTransition: FlickerBuilder.() -> Unit + get() = { + setup { + tapl.goHome() + SplitScreenUtils.enterSplit(wmHelper, tapl, device, primaryApp, secondaryApp) + SplitScreenUtils.enterSplit(wmHelper, tapl, device, thirdApp, pipApp) + pipApp.enableAutoEnterForPipActivity() + SplitScreenUtils.waitForSplitComplete(wmHelper, thirdApp, pipApp) + } + transitions { + tapl.launchedAppState.quickSwitchToPreviousApp() + SplitScreenUtils.waitForSplitComplete(wmHelper, primaryApp, secondaryApp) + } + teardown { + pipApp.exit(wmHelper) + thirdApp.exit(wmHelper) + } + } + + /** + * Checks that [pipApp] window won't enter pip + */ + @Presubmit + @Test + fun notEnterPip() { + flicker.assertWm { isNotPinned(pipApp) } + } + + /** + * Checks the [pipApp] task did not reshow during transition. + */ + @Presubmit + @Test + fun app1WindowIsVisibleOnceApp2WindowIsInvisible() { + flicker.assertLayers { + this.isVisible(pipApp) + .then().isVisible(ComponentNameMatcher.LAUNCHER, isOptional = true) + .then().isVisible(ComponentNameMatcher.SNAPSHOT, isOptional = true) + .then().isInvisible(pipApp).isVisible(secondaryApp) + } + } + + @Presubmit + @Test + fun primaryAppBoundsIsVisibleAtEnd() = + flicker.splitAppLayerBoundsIsVisibleAtEnd( + primaryApp, + landscapePosLeft = tapl.isTablet, + portraitPosTop = false + ) + + @Presubmit + @Test + fun secondaryAppBoundsIsVisibleAtEnd() = + flicker.splitAppLayerBoundsIsVisibleAtEnd( + secondaryApp, + landscapePosLeft = !tapl.isTablet, + portraitPosTop = true + ) + + /** + * Checks the [pipApp] task become invisible after transition finish. + */ + @Presubmit + @Test + fun pipAppLayerBecomesInvisible() = flicker.layerBecomesInvisible(pipApp) + + /** + * Checks the [pipApp] task is in split screen bounds when transition start. + */ + @Presubmit + @Test + fun pipAppBoundsIsVisibleAtBegin() = + flicker.assertLayersStart { + this.splitAppLayerBoundsSnapToDivider( + pipApp, + landscapePosLeft = !tapl.isTablet, + portraitPosTop = true, + flicker.scenario.startRotation + ) + } + + companion object { + @Parameterized.Parameters(name = "{0}") + @JvmStatic + fun getParams() = LegacyFlickerTestFactory.nonRotationTests( + supportedNavigationModes = listOf(NavBar.MODE_GESTURAL) + ) + } +} diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/UnlockKeyguardToSplitScreen.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/UnlockKeyguardToSplitScreen.kt index 994d6cbfaa1f..851391d37323 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/UnlockKeyguardToSplitScreen.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/UnlockKeyguardToSplitScreen.kt @@ -24,12 +24,12 @@ import android.tools.device.flicker.legacy.FlickerBuilder import android.tools.device.flicker.legacy.LegacyFlickerTest import android.tools.device.flicker.legacy.LegacyFlickerTestFactory import androidx.test.filters.RequiresDevice -import com.android.wm.shell.flicker.ICommonAssertions -import com.android.wm.shell.flicker.SPLIT_SCREEN_DIVIDER_COMPONENT -import com.android.wm.shell.flicker.appWindowIsVisibleAtEnd -import com.android.wm.shell.flicker.layerIsVisibleAtEnd -import com.android.wm.shell.flicker.splitAppLayerBoundsIsVisibleAtEnd import com.android.wm.shell.flicker.splitscreen.benchmark.UnlockKeyguardToSplitScreenBenchmark +import com.android.wm.shell.flicker.utils.ICommonAssertions +import com.android.wm.shell.flicker.utils.SPLIT_SCREEN_DIVIDER_COMPONENT +import com.android.wm.shell.flicker.utils.appWindowIsVisibleAtEnd +import com.android.wm.shell.flicker.utils.layerIsVisibleAtEnd +import com.android.wm.shell.flicker.utils.splitAppLayerBoundsIsVisibleAtEnd import org.junit.FixMethodOrder import org.junit.Test import org.junit.runner.RunWith diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/CopyContentInSplitBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/CopyContentInSplitBenchmark.kt index d9d22def6992..4d9007093cea 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/CopyContentInSplitBenchmark.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/CopyContentInSplitBenchmark.kt @@ -22,8 +22,7 @@ import android.tools.device.flicker.legacy.FlickerBuilder import android.tools.device.flicker.legacy.LegacyFlickerTest import android.tools.device.flicker.legacy.LegacyFlickerTestFactory import androidx.test.filters.RequiresDevice -import com.android.wm.shell.flicker.SplitScreenUtils -import com.android.wm.shell.flicker.splitscreen.SplitScreenBase +import com.android.wm.shell.flicker.utils.SplitScreenUtils import org.junit.FixMethodOrder import org.junit.runner.RunWith import org.junit.runners.MethodSorters diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/DismissSplitScreenByDividerBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/DismissSplitScreenByDividerBenchmark.kt index 7e8d60b441bb..8360e94a6c3e 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/DismissSplitScreenByDividerBenchmark.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/DismissSplitScreenByDividerBenchmark.kt @@ -21,8 +21,7 @@ import android.tools.device.flicker.legacy.FlickerBuilder import android.tools.device.flicker.legacy.LegacyFlickerTest import android.tools.device.flicker.legacy.LegacyFlickerTestFactory import androidx.test.filters.RequiresDevice -import com.android.wm.shell.flicker.SplitScreenUtils -import com.android.wm.shell.flicker.splitscreen.SplitScreenBase +import com.android.wm.shell.flicker.utils.SplitScreenUtils import org.junit.FixMethodOrder import org.junit.runner.RunWith import org.junit.runners.MethodSorters diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/DismissSplitScreenByGoHomeBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/DismissSplitScreenByGoHomeBenchmark.kt index 770e0328c4f6..e74587843a72 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/DismissSplitScreenByGoHomeBenchmark.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/DismissSplitScreenByGoHomeBenchmark.kt @@ -21,8 +21,7 @@ import android.tools.device.flicker.legacy.FlickerBuilder import android.tools.device.flicker.legacy.LegacyFlickerTest import android.tools.device.flicker.legacy.LegacyFlickerTestFactory import androidx.test.filters.RequiresDevice -import com.android.wm.shell.flicker.SplitScreenUtils -import com.android.wm.shell.flicker.splitscreen.SplitScreenBase +import com.android.wm.shell.flicker.utils.SplitScreenUtils import org.junit.FixMethodOrder import org.junit.runner.RunWith import org.junit.runners.MethodSorters diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/DragDividerToResizeBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/DragDividerToResizeBenchmark.kt index 46570fde1942..c3beb366cc66 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/DragDividerToResizeBenchmark.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/DragDividerToResizeBenchmark.kt @@ -21,8 +21,7 @@ import android.tools.device.flicker.legacy.FlickerBuilder import android.tools.device.flicker.legacy.LegacyFlickerTest import android.tools.device.flicker.legacy.LegacyFlickerTestFactory import androidx.test.filters.RequiresDevice -import com.android.wm.shell.flicker.SplitScreenUtils -import com.android.wm.shell.flicker.splitscreen.SplitScreenBase +import com.android.wm.shell.flicker.utils.SplitScreenUtils import org.junit.Assume import org.junit.Before import org.junit.FixMethodOrder diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromAllAppsBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromAllAppsBenchmark.kt index 5c3d4ffa8663..80ccaa144c58 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromAllAppsBenchmark.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromAllAppsBenchmark.kt @@ -22,8 +22,7 @@ import android.tools.device.flicker.legacy.FlickerBuilder import android.tools.device.flicker.legacy.LegacyFlickerTest import android.tools.device.flicker.legacy.LegacyFlickerTestFactory import androidx.test.filters.RequiresDevice -import com.android.wm.shell.flicker.SplitScreenUtils -import com.android.wm.shell.flicker.splitscreen.SplitScreenBase +import com.android.wm.shell.flicker.utils.SplitScreenUtils import org.junit.Assume import org.junit.Before import org.junit.FixMethodOrder diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromNotificationBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromNotificationBenchmark.kt index 6b122c686c58..cd3fbab1497b 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromNotificationBenchmark.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromNotificationBenchmark.kt @@ -22,8 +22,7 @@ import android.tools.device.flicker.legacy.FlickerBuilder import android.tools.device.flicker.legacy.LegacyFlickerTest import android.tools.device.flicker.legacy.LegacyFlickerTestFactory import androidx.test.filters.RequiresDevice -import com.android.wm.shell.flicker.SplitScreenUtils -import com.android.wm.shell.flicker.splitscreen.SplitScreenBase +import com.android.wm.shell.flicker.utils.SplitScreenUtils import org.junit.Assume import org.junit.Before import org.junit.FixMethodOrder diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromShortcutBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromShortcutBenchmark.kt index 78f9bab402e9..a06ae6bc63a1 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromShortcutBenchmark.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromShortcutBenchmark.kt @@ -22,8 +22,7 @@ import android.tools.device.flicker.legacy.FlickerBuilder import android.tools.device.flicker.legacy.LegacyFlickerTest import android.tools.device.flicker.legacy.LegacyFlickerTestFactory import androidx.test.filters.RequiresDevice -import com.android.wm.shell.flicker.SplitScreenUtils -import com.android.wm.shell.flicker.splitscreen.SplitScreenBase +import com.android.wm.shell.flicker.utils.SplitScreenUtils import org.junit.Assume import org.junit.Before import org.junit.FixMethodOrder diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromTaskbarBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromTaskbarBenchmark.kt index 78907f08edf3..de4ec6d12657 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromTaskbarBenchmark.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenByDragFromTaskbarBenchmark.kt @@ -22,8 +22,7 @@ import android.tools.device.flicker.legacy.FlickerBuilder import android.tools.device.flicker.legacy.LegacyFlickerTest import android.tools.device.flicker.legacy.LegacyFlickerTestFactory import androidx.test.filters.RequiresDevice -import com.android.wm.shell.flicker.SplitScreenUtils -import com.android.wm.shell.flicker.splitscreen.SplitScreenBase +import com.android.wm.shell.flicker.utils.SplitScreenUtils import org.junit.Assume import org.junit.Before import org.junit.FixMethodOrder diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenFromOverviewBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenFromOverviewBenchmark.kt index 2c91e84a01fe..be507d833986 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenFromOverviewBenchmark.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/EnterSplitScreenFromOverviewBenchmark.kt @@ -21,8 +21,7 @@ import android.tools.device.flicker.legacy.FlickerBuilder import android.tools.device.flicker.legacy.LegacyFlickerTest import android.tools.device.flicker.legacy.LegacyFlickerTestFactory import androidx.test.filters.RequiresDevice -import com.android.wm.shell.flicker.SplitScreenUtils -import com.android.wm.shell.flicker.splitscreen.SplitScreenBase +import com.android.wm.shell.flicker.utils.SplitScreenUtils import org.junit.FixMethodOrder import org.junit.runner.RunWith import org.junit.runners.MethodSorters diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SplitScreenBase.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SplitScreenBase.kt index d3434a5b18e5..fdcb7e5a0984 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SplitScreenBase.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SplitScreenBase.kt @@ -14,14 +14,14 @@ * limitations under the License. */ -package com.android.wm.shell.flicker.splitscreen +package com.android.wm.shell.flicker.splitscreen.benchmark import android.content.Context import android.tools.device.flicker.legacy.FlickerBuilder import android.tools.device.flicker.legacy.LegacyFlickerTest import com.android.server.wm.flicker.helpers.setRotation import com.android.wm.shell.flicker.BaseBenchmarkTest -import com.android.wm.shell.flicker.SplitScreenUtils +import com.android.wm.shell.flicker.utils.SplitScreenUtils abstract class SplitScreenBase(flicker: LegacyFlickerTest) : BaseBenchmarkTest(flicker) { protected val context: Context = instrumentation.context @@ -33,7 +33,9 @@ abstract class SplitScreenBase(flicker: LegacyFlickerTest) : BaseBenchmarkTest(f tapl.setEnableRotation(true) setRotation(flicker.scenario.startRotation) tapl.setExpectedRotation(flicker.scenario.startRotation.value) - tapl.workspace.switchToOverview().dismissAllTasks() + if (tapl.workspace.switchToOverview().hasTasks()) { + tapl.workspace.switchToOverview().dismissAllTasks() + } } } @@ -43,11 +45,4 @@ abstract class SplitScreenBase(flicker: LegacyFlickerTest) : BaseBenchmarkTest(f secondaryApp.exit(wmHelper) } } - - protected open val withoutTracing: FlickerBuilder.() -> Unit = { - withoutLayerTracing() - withoutWindowManagerTracing() - withoutTransitionTracing() - withoutTransactionsTracing() - } } diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchAppByDoubleTapDividerBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchAppByDoubleTapDividerBenchmark.kt index fa09c2ee4e21..ed0debd01408 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchAppByDoubleTapDividerBenchmark.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchAppByDoubleTapDividerBenchmark.kt @@ -25,8 +25,7 @@ import android.tools.device.flicker.legacy.LegacyFlickerTestFactory import android.tools.device.helpers.WindowUtils import android.tools.device.traces.parsers.WindowManagerStateHelper import androidx.test.filters.RequiresDevice -import com.android.wm.shell.flicker.SplitScreenUtils -import com.android.wm.shell.flicker.splitscreen.SplitScreenBase +import com.android.wm.shell.flicker.utils.SplitScreenUtils import org.junit.FixMethodOrder import org.junit.runner.RunWith import org.junit.runners.MethodSorters diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBackToSplitFromAnotherAppBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBackToSplitFromAnotherAppBenchmark.kt index ff220069b88e..9b7939a3a006 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBackToSplitFromAnotherAppBenchmark.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBackToSplitFromAnotherAppBenchmark.kt @@ -22,8 +22,7 @@ import android.tools.device.flicker.legacy.FlickerBuilder import android.tools.device.flicker.legacy.LegacyFlickerTest import android.tools.device.flicker.legacy.LegacyFlickerTestFactory import androidx.test.filters.RequiresDevice -import com.android.wm.shell.flicker.SplitScreenUtils -import com.android.wm.shell.flicker.splitscreen.SplitScreenBase +import com.android.wm.shell.flicker.utils.SplitScreenUtils import org.junit.FixMethodOrder import org.junit.runner.RunWith import org.junit.runners.MethodSorters diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBackToSplitFromHomeBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBackToSplitFromHomeBenchmark.kt index 5787b02f8944..9326ef3024a4 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBackToSplitFromHomeBenchmark.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBackToSplitFromHomeBenchmark.kt @@ -22,8 +22,7 @@ import android.tools.device.flicker.legacy.FlickerBuilder import android.tools.device.flicker.legacy.LegacyFlickerTest import android.tools.device.flicker.legacy.LegacyFlickerTestFactory import androidx.test.filters.RequiresDevice -import com.android.wm.shell.flicker.SplitScreenUtils -import com.android.wm.shell.flicker.splitscreen.SplitScreenBase +import com.android.wm.shell.flicker.utils.SplitScreenUtils import org.junit.FixMethodOrder import org.junit.runner.RunWith import org.junit.runners.MethodSorters diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBackToSplitFromRecentBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBackToSplitFromRecentBenchmark.kt index b2d50911f930..b928e40108bf 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBackToSplitFromRecentBenchmark.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBackToSplitFromRecentBenchmark.kt @@ -22,8 +22,7 @@ import android.tools.device.flicker.legacy.FlickerBuilder import android.tools.device.flicker.legacy.LegacyFlickerTest import android.tools.device.flicker.legacy.LegacyFlickerTestFactory import androidx.test.filters.RequiresDevice -import com.android.wm.shell.flicker.SplitScreenUtils -import com.android.wm.shell.flicker.splitscreen.SplitScreenBase +import com.android.wm.shell.flicker.utils.SplitScreenUtils import org.junit.FixMethodOrder import org.junit.runner.RunWith import org.junit.runners.MethodSorters diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBetweenSplitPairsBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBetweenSplitPairsBenchmark.kt index f234e462e63e..f314995fa947 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBetweenSplitPairsBenchmark.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/SwitchBetweenSplitPairsBenchmark.kt @@ -21,8 +21,7 @@ import android.tools.device.flicker.legacy.FlickerBuilder import android.tools.device.flicker.legacy.LegacyFlickerTest import android.tools.device.flicker.legacy.LegacyFlickerTestFactory import androidx.test.filters.RequiresDevice -import com.android.wm.shell.flicker.SplitScreenUtils -import com.android.wm.shell.flicker.splitscreen.SplitScreenBase +import com.android.wm.shell.flicker.utils.SplitScreenUtils import org.junit.FixMethodOrder import org.junit.runner.RunWith import org.junit.runners.MethodSorters diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/UnlockKeyguardToSplitScreenBenchmark.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/UnlockKeyguardToSplitScreenBenchmark.kt index 61c367933159..e71834de7123 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/UnlockKeyguardToSplitScreenBenchmark.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/benchmark/UnlockKeyguardToSplitScreenBenchmark.kt @@ -22,8 +22,7 @@ import android.tools.device.flicker.legacy.FlickerBuilder import android.tools.device.flicker.legacy.LegacyFlickerTest import android.tools.device.flicker.legacy.LegacyFlickerTestFactory import androidx.test.filters.RequiresDevice -import com.android.wm.shell.flicker.SplitScreenUtils -import com.android.wm.shell.flicker.splitscreen.SplitScreenBase +import com.android.wm.shell.flicker.utils.SplitScreenUtils import org.junit.FixMethodOrder import org.junit.runner.RunWith import org.junit.runners.MethodSorters diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonAssertions.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/utils/CommonAssertions.kt index 9cc03a56e9a2..e5c124cbe775 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonAssertions.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/utils/CommonAssertions.kt @@ -16,7 +16,7 @@ @file:JvmName("CommonAssertions") -package com.android.wm.shell.flicker +package com.android.wm.shell.flicker.utils import android.tools.common.Rotation import android.tools.common.datatypes.Region diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonConstants.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/utils/CommonConstants.kt index 3bc1e2acd015..3b66d6addacd 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/CommonConstants.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/utils/CommonConstants.kt @@ -16,7 +16,7 @@ @file:JvmName("CommonConstants") -package com.android.wm.shell.flicker +package com.android.wm.shell.flicker.utils import android.tools.common.traces.component.ComponentNameMatcher diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/ICommonAssertions.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/utils/ICommonAssertions.kt index 7b3290125bae..7f58cedce63d 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/ICommonAssertions.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/utils/ICommonAssertions.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.wm.shell.flicker +package com.android.wm.shell.flicker.utils import android.platform.test.annotations.Presubmit import android.tools.common.traces.component.ComponentNameMatcher diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/MultiWindowUtils.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/utils/MultiWindowUtils.kt index 87b94ff8668b..9b3a480c06b1 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/MultiWindowUtils.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/utils/MultiWindowUtils.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.wm.shell.flicker +package com.android.wm.shell.flicker.utils import android.app.Instrumentation import android.content.Context diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/NotificationListener.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/utils/NotificationListener.kt index e0ef92457f58..529c1254a64c 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/NotificationListener.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/utils/NotificationListener.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.wm.shell.flicker +package com.android.wm.shell.flicker.utils import android.service.notification.NotificationListenerService import android.service.notification.StatusBarNotification diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/SplitScreenUtils.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/utils/SplitScreenUtils.kt index 8a3c2c975faa..3f8a1ae6bd79 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/SplitScreenUtils.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/utils/SplitScreenUtils.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.wm.shell.flicker +package com.android.wm.shell.flicker.utils import android.app.Instrumentation import android.graphics.Point diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/WaitUtils.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/utils/WaitUtils.kt index 556cb06f3ca1..cf2df4e17cb7 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/WaitUtils.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/utils/WaitUtils.kt @@ -16,7 +16,7 @@ @file:JvmName("WaitUtils") -package com.android.wm.shell.flicker +package com.android.wm.shell.flicker.utils import android.os.SystemClock diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/tv/TvPipActionProviderTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/tv/TvPipActionProviderTest.java index 02e6b8c71663..ec84d7e20714 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/tv/TvPipActionProviderTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/tv/TvPipActionProviderTest.java @@ -23,7 +23,9 @@ import static com.android.wm.shell.pip.tv.TvPipAction.ACTION_EXPAND_COLLAPSE; import static com.android.wm.shell.pip.tv.TvPipAction.ACTION_FULLSCREEN; import static com.android.wm.shell.pip.tv.TvPipAction.ACTION_MOVE; -import static org.junit.Assert.assertTrue; +import static java.util.Collections.EMPTY_LIST; + +import static org.junit.Assert.assertEquals; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @@ -34,7 +36,6 @@ import android.graphics.drawable.Icon; import android.test.suitebuilder.annotation.SmallTest; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; -import android.util.Log; import com.android.wm.shell.ShellTestCase; import com.android.wm.shell.pip.PipMediaController; @@ -46,7 +47,9 @@ import org.mockito.Mock; import org.mockito.MockitoAnnotations; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; +import java.util.stream.Collectors; /** * Unit tests for {@link TvPipActionsProvider} @@ -69,35 +72,38 @@ public class TvPipActionProviderTest extends ShellTestCase { @Mock private PendingIntent mMockPendingIntent; - private RemoteAction createRemoteAction(int identifier) { + private int mNumberOfRemoteActionsCreated = 0; + + private RemoteAction createRemoteAction() { + final int identifier = mNumberOfRemoteActionsCreated++; return new RemoteAction(mMockIcon, "" + identifier, "" + identifier, mMockPendingIntent); } private List<RemoteAction> createRemoteActions(int numberOfActions) { List<RemoteAction> actions = new ArrayList<>(); for (int i = 0; i < numberOfActions; i++) { - actions.add(createRemoteAction(i)); + actions.add(createRemoteAction()); } return actions; } - private boolean checkActionsMatch(List<TvPipAction> actions, int[] actionTypes) { - for (int i = 0; i < actions.size(); i++) { - int type = actions.get(i).getActionType(); - if (type != actionTypes[i]) { - Log.e(TAG, "Action at index " + i + ": found " + type - + ", expected " + actionTypes[i]); - return false; - } - } - return true; + private void assertActionTypes(List<Integer> expected, List<Integer> actual) { + assertEquals(getActionTypesStrings(expected), getActionTypesStrings(actual)); + } + + private static List<String> getActionTypesStrings(List<Integer> actionTypes) { + return actionTypes.stream().map(a -> TvPipAction.getActionTypeString(a)) + .collect(Collectors.toList()); + } + + private List<Integer> getActionsTypes() { + return mActionsProvider.getActionsList().stream().map(a -> a.getActionType()) + .collect(Collectors.toList()); } @Before public void setUp() { - if (!isTelevision()) { - return; - } + assumeTelevision(); MockitoAnnotations.initMocks(this); mActionsProvider = new TvPipActionsProvider(mContext, mMockPipMediaController, mMockSystemActionsHandler); @@ -105,57 +111,51 @@ public class TvPipActionProviderTest extends ShellTestCase { @Test public void defaultSystemActions_regularPip() { - assumeTelevision(); - mActionsProvider.updateExpansionEnabled(false); - assertTrue(checkActionsMatch(mActionsProvider.getActionsList(), - new int[]{ACTION_FULLSCREEN, ACTION_CLOSE, ACTION_MOVE})); + assertActionTypes(Arrays.asList(ACTION_FULLSCREEN, ACTION_CLOSE, ACTION_MOVE), + getActionsTypes()); } @Test public void defaultSystemActions_expandedPip() { - assumeTelevision(); mActionsProvider.updateExpansionEnabled(true); - assertTrue(checkActionsMatch(mActionsProvider.getActionsList(), - new int[]{ACTION_FULLSCREEN, ACTION_CLOSE, ACTION_MOVE, ACTION_EXPAND_COLLAPSE})); + assertActionTypes( + Arrays.asList(ACTION_FULLSCREEN, ACTION_CLOSE, ACTION_MOVE, ACTION_EXPAND_COLLAPSE), + getActionsTypes()); } @Test public void expandedPip_enableExpansion_enable() { - assumeTelevision(); // PiP has expanded PiP disabled. - mActionsProvider.updateExpansionEnabled(false); - mActionsProvider.addListener(mMockListener); mActionsProvider.updateExpansionEnabled(true); - assertTrue(checkActionsMatch(mActionsProvider.getActionsList(), - new int[]{ACTION_FULLSCREEN, ACTION_CLOSE, ACTION_MOVE, ACTION_EXPAND_COLLAPSE})); + assertActionTypes( + Arrays.asList(ACTION_FULLSCREEN, ACTION_CLOSE, ACTION_MOVE, ACTION_EXPAND_COLLAPSE), + getActionsTypes()); verify(mMockListener).onActionsChanged(/* added= */ 1, /* updated= */ 0, /* index= */ 3); } @Test public void expandedPip_enableExpansion_disable() { - assumeTelevision(); mActionsProvider.updateExpansionEnabled(true); mActionsProvider.addListener(mMockListener); mActionsProvider.updateExpansionEnabled(false); - assertTrue(checkActionsMatch(mActionsProvider.getActionsList(), - new int[]{ACTION_FULLSCREEN, ACTION_CLOSE, ACTION_MOVE})); + assertActionTypes( + Arrays.asList(ACTION_FULLSCREEN, ACTION_CLOSE, ACTION_MOVE), + getActionsTypes()); verify(mMockListener).onActionsChanged(/* added= */ -1, /* updated= */ 0, /* index= */ 3); } @Test public void expandedPip_enableExpansion_AlreadyEnabled() { - assumeTelevision(); - mActionsProvider.updateExpansionEnabled(true); - mActionsProvider.addListener(mMockListener); mActionsProvider.updateExpansionEnabled(true); - assertTrue(checkActionsMatch(mActionsProvider.getActionsList(), - new int[]{ACTION_FULLSCREEN, ACTION_CLOSE, ACTION_MOVE, ACTION_EXPAND_COLLAPSE})); + assertActionTypes( + Arrays.asList(ACTION_FULLSCREEN, ACTION_CLOSE, ACTION_MOVE, ACTION_EXPAND_COLLAPSE), + getActionsTypes()); } private void check_expandedPip_updateExpansionState( @@ -167,8 +167,9 @@ public class TvPipActionProviderTest extends ShellTestCase { mActionsProvider.addListener(mMockListener); mActionsProvider.updatePipExpansionState(endExpansion); - assertTrue(checkActionsMatch(mActionsProvider.getActionsList(), - new int[]{ACTION_FULLSCREEN, ACTION_CLOSE, ACTION_MOVE, ACTION_EXPAND_COLLAPSE})); + assertActionTypes( + Arrays.asList(ACTION_FULLSCREEN, ACTION_CLOSE, ACTION_MOVE, ACTION_EXPAND_COLLAPSE), + getActionsTypes()); if (updateExpected) { verify(mMockListener).onActionsChanged(0, 1, 3); @@ -180,7 +181,6 @@ public class TvPipActionProviderTest extends ShellTestCase { @Test public void expandedPip_toggleExpansion_collapse() { - assumeTelevision(); check_expandedPip_updateExpansionState( /* startExpansion= */ true, /* endExpansion= */ false, @@ -189,7 +189,6 @@ public class TvPipActionProviderTest extends ShellTestCase { @Test public void expandedPip_toggleExpansion_expand() { - assumeTelevision(); check_expandedPip_updateExpansionState( /* startExpansion= */ false, /* endExpansion= */ true, @@ -198,7 +197,6 @@ public class TvPipActionProviderTest extends ShellTestCase { @Test public void expandedPiP_updateExpansionState_alreadyExpanded() { - assumeTelevision(); check_expandedPip_updateExpansionState( /* startExpansion= */ true, /* endExpansion= */ true, @@ -207,7 +205,6 @@ public class TvPipActionProviderTest extends ShellTestCase { @Test public void expandedPiP_updateExpansionState_alreadyCollapsed() { - assumeTelevision(); check_expandedPip_updateExpansionState( /* startExpansion= */ false, /* endExpansion= */ false, @@ -216,8 +213,6 @@ public class TvPipActionProviderTest extends ShellTestCase { @Test public void regularPiP_updateExpansionState_setCollapsed() { - assumeTelevision(); - mActionsProvider.updateExpansionEnabled(false); mActionsProvider.updatePipExpansionState(/* expanded= */ false); mActionsProvider.addListener(mMockListener); @@ -229,153 +224,207 @@ public class TvPipActionProviderTest extends ShellTestCase { @Test public void customActions_added() { - assumeTelevision(); - mActionsProvider.updateExpansionEnabled(false); mActionsProvider.addListener(mMockListener); mActionsProvider.setAppActions(createRemoteActions(2), null); - assertTrue(checkActionsMatch(mActionsProvider.getActionsList(), - new int[]{ACTION_FULLSCREEN, ACTION_CLOSE, ACTION_CUSTOM, ACTION_CUSTOM, - ACTION_MOVE})); + assertActionTypes( + Arrays.asList(ACTION_FULLSCREEN, ACTION_CLOSE, ACTION_CUSTOM, ACTION_CUSTOM, + ACTION_MOVE), + getActionsTypes()); verify(mMockListener).onActionsChanged(/* added= */ 2, /* updated= */ 0, /* index= */ 2); } @Test public void customActions_replacedMore() { - assumeTelevision(); - mActionsProvider.updateExpansionEnabled(false); mActionsProvider.setAppActions(createRemoteActions(2), null); mActionsProvider.addListener(mMockListener); mActionsProvider.setAppActions(createRemoteActions(3), null); - assertTrue(checkActionsMatch(mActionsProvider.getActionsList(), - new int[]{ACTION_FULLSCREEN, ACTION_CLOSE, ACTION_CUSTOM, ACTION_CUSTOM, - ACTION_CUSTOM, ACTION_MOVE})); + assertActionTypes( + Arrays.asList(ACTION_FULLSCREEN, ACTION_CLOSE, ACTION_CUSTOM, ACTION_CUSTOM, + ACTION_CUSTOM, ACTION_MOVE), + getActionsTypes()); verify(mMockListener).onActionsChanged(/* added= */ 1, /* updated= */ 2, /* index= */ 2); } @Test public void customActions_replacedLess() { - assumeTelevision(); - mActionsProvider.updateExpansionEnabled(false); mActionsProvider.setAppActions(createRemoteActions(2), null); mActionsProvider.addListener(mMockListener); - mActionsProvider.setAppActions(createRemoteActions(0), null); + mActionsProvider.setAppActions(EMPTY_LIST, null); - assertTrue(checkActionsMatch(mActionsProvider.getActionsList(), - new int[]{ACTION_FULLSCREEN, ACTION_CLOSE, ACTION_MOVE})); + assertActionTypes( + Arrays.asList(ACTION_FULLSCREEN, ACTION_CLOSE, ACTION_MOVE), + getActionsTypes()); verify(mMockListener).onActionsChanged(/* added= */ -2, /* updated= */ 0, /* index= */ 2); } @Test public void customCloseAdded() { - assumeTelevision(); - mActionsProvider.updateExpansionEnabled(false); - List<RemoteAction> customActions = new ArrayList<>(); mActionsProvider.setAppActions(customActions, null); mActionsProvider.addListener(mMockListener); - mActionsProvider.setAppActions(customActions, createRemoteAction(0)); + mActionsProvider.setAppActions(customActions, createRemoteAction()); - assertTrue(checkActionsMatch(mActionsProvider.getActionsList(), - new int[]{ACTION_FULLSCREEN, ACTION_CUSTOM_CLOSE, ACTION_MOVE})); + assertActionTypes( + Arrays.asList(ACTION_FULLSCREEN, ACTION_CUSTOM_CLOSE, ACTION_MOVE), + getActionsTypes()); verify(mMockListener).onActionsChanged(/* added= */ 0, /* updated= */ 1, /* index= */ 1); } @Test public void customClose_matchesOtherCustomAction() { - assumeTelevision(); - mActionsProvider.updateExpansionEnabled(false); - List<RemoteAction> customActions = createRemoteActions(2); - RemoteAction customClose = createRemoteAction(/* id= */ 10); + RemoteAction customClose = createRemoteAction(); customActions.add(customClose); mActionsProvider.addListener(mMockListener); mActionsProvider.setAppActions(customActions, customClose); - assertTrue(checkActionsMatch(mActionsProvider.getActionsList(), - new int[]{ACTION_FULLSCREEN, ACTION_CUSTOM_CLOSE, ACTION_CUSTOM, ACTION_CUSTOM, - ACTION_MOVE})); + assertActionTypes( + Arrays.asList(ACTION_FULLSCREEN, ACTION_CUSTOM_CLOSE, ACTION_CUSTOM, ACTION_CUSTOM, + ACTION_MOVE), + getActionsTypes()); verify(mMockListener).onActionsChanged(/* added= */ 0, /* updated= */ 1, /* index= */ 1); verify(mMockListener).onActionsChanged(/* added= */ 2, /* updated= */ 0, /* index= */ 2); } @Test public void mediaActions_added_whileCustomActionsExist() { - assumeTelevision(); - mActionsProvider.updateExpansionEnabled(false); mActionsProvider.setAppActions(createRemoteActions(2), null); mActionsProvider.addListener(mMockListener); mActionsProvider.onMediaActionsChanged(createRemoteActions(3)); - assertTrue(checkActionsMatch(mActionsProvider.getActionsList(), - new int[]{ACTION_FULLSCREEN, ACTION_CLOSE, ACTION_CUSTOM, ACTION_CUSTOM, - ACTION_MOVE})); + assertActionTypes( + Arrays.asList(ACTION_FULLSCREEN, ACTION_CLOSE, ACTION_CUSTOM, ACTION_CUSTOM, + ACTION_MOVE), + getActionsTypes()); verify(mMockListener, times(0)).onActionsChanged(anyInt(), anyInt(), anyInt()); } @Test public void customActions_removed_whileMediaActionsExist() { - assumeTelevision(); - mActionsProvider.updateExpansionEnabled(false); mActionsProvider.onMediaActionsChanged(createRemoteActions(2)); mActionsProvider.setAppActions(createRemoteActions(3), null); + assertActionTypes( + Arrays.asList(ACTION_FULLSCREEN, ACTION_CLOSE, ACTION_CUSTOM, ACTION_CUSTOM, + ACTION_CUSTOM, ACTION_MOVE), + getActionsTypes()); + mActionsProvider.addListener(mMockListener); - mActionsProvider.setAppActions(createRemoteActions(0), null); + mActionsProvider.setAppActions(EMPTY_LIST, null); - assertTrue(checkActionsMatch(mActionsProvider.getActionsList(), - new int[]{ACTION_FULLSCREEN, ACTION_CLOSE, ACTION_CUSTOM, ACTION_CUSTOM, - ACTION_MOVE})); + assertActionTypes( + Arrays.asList(ACTION_FULLSCREEN, ACTION_CLOSE, ACTION_CUSTOM, ACTION_CUSTOM, + ACTION_MOVE), + getActionsTypes()); verify(mMockListener).onActionsChanged(/* added= */ -1, /* updated= */ 2, /* index= */ 2); } @Test public void customCloseOnly_mediaActionsShowing() { - assumeTelevision(); - mActionsProvider.updateExpansionEnabled(false); mActionsProvider.onMediaActionsChanged(createRemoteActions(2)); mActionsProvider.addListener(mMockListener); - mActionsProvider.setAppActions(createRemoteActions(0), createRemoteAction(5)); + mActionsProvider.setAppActions(EMPTY_LIST, createRemoteAction()); - assertTrue(checkActionsMatch(mActionsProvider.getActionsList(), - new int[]{ACTION_FULLSCREEN, ACTION_CUSTOM_CLOSE, ACTION_CUSTOM, ACTION_CUSTOM, - ACTION_MOVE})); + assertActionTypes( + Arrays.asList(ACTION_FULLSCREEN, ACTION_CUSTOM_CLOSE, ACTION_CUSTOM, ACTION_CUSTOM, + ACTION_MOVE), + getActionsTypes()); verify(mMockListener).onActionsChanged(/* added= */ 0, /* updated= */ 1, /* index= */ 1); } @Test public void customActions_showDisabledActions() { - assumeTelevision(); - mActionsProvider.updateExpansionEnabled(false); - List<RemoteAction> customActions = createRemoteActions(2); customActions.get(0).setEnabled(false); mActionsProvider.setAppActions(customActions, null); - assertTrue(checkActionsMatch(mActionsProvider.getActionsList(), - new int[]{ACTION_FULLSCREEN, ACTION_CLOSE, ACTION_CUSTOM, ACTION_CUSTOM, - ACTION_MOVE})); + assertActionTypes( + Arrays.asList(ACTION_FULLSCREEN, ACTION_CLOSE, ACTION_CUSTOM, ACTION_CUSTOM, + ACTION_MOVE), + getActionsTypes()); } @Test public void mediaActions_hideDisabledActions() { - assumeTelevision(); - mActionsProvider.updateExpansionEnabled(false); + List<RemoteAction> customActions = createRemoteActions(2); + customActions.get(0).setEnabled(false); + mActionsProvider.onMediaActionsChanged(customActions); + assertActionTypes( + Arrays.asList(ACTION_FULLSCREEN, ACTION_CLOSE, ACTION_CUSTOM, ACTION_MOVE), + getActionsTypes()); + } + + @Test + public void reset_mediaActions() { List<RemoteAction> customActions = createRemoteActions(2); customActions.get(0).setEnabled(false); mActionsProvider.onMediaActionsChanged(customActions); - assertTrue(checkActionsMatch(mActionsProvider.getActionsList(), - new int[]{ACTION_FULLSCREEN, ACTION_CLOSE, ACTION_CUSTOM, ACTION_MOVE})); + assertActionTypes( + Arrays.asList(ACTION_FULLSCREEN, ACTION_CLOSE, ACTION_CUSTOM, ACTION_MOVE), + getActionsTypes()); + + mActionsProvider.reset(); + assertActionTypes( + Arrays.asList(ACTION_FULLSCREEN, ACTION_CLOSE, ACTION_MOVE), + getActionsTypes()); + } + + @Test + public void reset_customActions() { + List<RemoteAction> customActions = createRemoteActions(2); + customActions.get(0).setEnabled(false); + mActionsProvider.setAppActions(customActions, null); + + assertActionTypes( + Arrays.asList(ACTION_FULLSCREEN, ACTION_CLOSE, ACTION_CUSTOM, ACTION_CUSTOM, + ACTION_MOVE), + getActionsTypes()); + + mActionsProvider.reset(); + assertActionTypes( + Arrays.asList(ACTION_FULLSCREEN, ACTION_CLOSE, ACTION_MOVE), + getActionsTypes()); + } + + @Test + public void reset_customClose() { + mActionsProvider.setAppActions(EMPTY_LIST, createRemoteAction()); + + assertActionTypes( + Arrays.asList(ACTION_FULLSCREEN, ACTION_CUSTOM_CLOSE, ACTION_MOVE), + getActionsTypes()); + + mActionsProvider.reset(); + assertActionTypes( + Arrays.asList(ACTION_FULLSCREEN, ACTION_CLOSE, ACTION_MOVE), + getActionsTypes()); + } + + @Test + public void reset_All() { + mActionsProvider.setAppActions(createRemoteActions(2), createRemoteAction()); + mActionsProvider.onMediaActionsChanged(createRemoteActions(3)); + + assertActionTypes( + Arrays.asList(ACTION_FULLSCREEN, ACTION_CUSTOM_CLOSE, ACTION_CUSTOM, ACTION_CUSTOM, + ACTION_MOVE), + getActionsTypes()); + + mActionsProvider.reset(); + assertActionTypes( + Arrays.asList(ACTION_FULLSCREEN, ACTION_CLOSE, ACTION_MOVE), + getActionsTypes()); } } diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/tv/TvPipGravityTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/tv/TvPipGravityTest.java index f9b772345b14..91ff3cbf3a63 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/tv/TvPipGravityTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/tv/TvPipGravityTest.java @@ -52,9 +52,8 @@ public class TvPipGravityTest extends ShellTestCase { @Before public void setUp() { - if (!isTelevision()) { - return; - } + assumeTelevision(); + MockitoAnnotations.initMocks(this); mPipDisplayLayoutState = new PipDisplayLayoutState(mContext); mPipSizeSpecHandler = new PipSizeSpecHandler(mContext, mPipDisplayLayoutState); @@ -100,20 +99,22 @@ public class TvPipGravityTest extends ShellTestCase { @Test public void regularPip_defaultGravity() { - assumeTelevision(); checkGravity(mTvPipBoundsState.getDefaultGravity(), Gravity.RIGHT | Gravity.BOTTOM); } @Test + public void regularPip_defaultTvPipGravity() { + checkGravity(mTvPipBoundsState.getTvPipGravity(), Gravity.RIGHT | Gravity.BOTTOM); + } + + @Test public void regularPip_defaultGravity_RTL() { - assumeTelevision(); setRTL(true); checkGravity(mTvPipBoundsState.getDefaultGravity(), Gravity.LEFT | Gravity.BOTTOM); } @Test public void updateGravity_expand_vertical() { - assumeTelevision(); // Vertical expanded PiP. mTvPipBoundsState.setDesiredTvExpandedAspectRatio(VERTICAL_EXPANDED_ASPECT_RATIO, true); @@ -129,7 +130,6 @@ public class TvPipGravityTest extends ShellTestCase { @Test public void updateGravity_expand_horizontal() { - assumeTelevision(); // Horizontal expanded PiP. mTvPipBoundsState.setDesiredTvExpandedAspectRatio(HORIZONTAL_EXPANDED_ASPECT_RATIO, true); @@ -145,7 +145,6 @@ public class TvPipGravityTest extends ShellTestCase { @Test public void updateGravity_collapse() { - assumeTelevision(); // Vertical expansion mTvPipBoundsState.setDesiredTvExpandedAspectRatio(VERTICAL_EXPANDED_ASPECT_RATIO, true); assertGravityAfterCollapse(Gravity.CENTER_VERTICAL | Gravity.RIGHT, @@ -163,7 +162,6 @@ public class TvPipGravityTest extends ShellTestCase { @Test public void updateGravity_collapse_RTL() { - assumeTelevision(); setRTL(true); // Horizontal expansion @@ -176,7 +174,6 @@ public class TvPipGravityTest extends ShellTestCase { @Test public void updateGravity_expand_collapse() { - assumeTelevision(); // Vertical expanded PiP. mTvPipBoundsState.setDesiredTvExpandedAspectRatio(VERTICAL_EXPANDED_ASPECT_RATIO, true); @@ -196,7 +193,6 @@ public class TvPipGravityTest extends ShellTestCase { @Test public void updateGravity_expand_move_collapse() { - assumeTelevision(); // Vertical expanded PiP. mTvPipBoundsState.setDesiredTvExpandedAspectRatio(VERTICAL_EXPANDED_ASPECT_RATIO, true); expandMoveCollapseCheck(Gravity.TOP | Gravity.RIGHT, KEYCODE_DPAD_LEFT, @@ -229,7 +225,6 @@ public class TvPipGravityTest extends ShellTestCase { @Test public void updateGravity_move_regular_valid() { - assumeTelevision(); mTvPipBoundsState.setTvPipGravity(Gravity.BOTTOM | Gravity.RIGHT); // clockwise moveAndCheckGravity(KEYCODE_DPAD_LEFT, Gravity.BOTTOM | Gravity.LEFT, true); @@ -245,7 +240,6 @@ public class TvPipGravityTest extends ShellTestCase { @Test public void updateGravity_move_expanded_valid() { - assumeTelevision(); mTvPipBoundsState.setTvPipExpanded(true); // Vertical expanded PiP. @@ -263,7 +257,6 @@ public class TvPipGravityTest extends ShellTestCase { @Test public void updateGravity_move_regular_invalid() { - assumeTelevision(); int gravity = Gravity.BOTTOM | Gravity.RIGHT; mTvPipBoundsState.setTvPipGravity(gravity); moveAndCheckGravity(KEYCODE_DPAD_DOWN, gravity, false); @@ -287,7 +280,6 @@ public class TvPipGravityTest extends ShellTestCase { @Test public void updateGravity_move_expanded_invalid() { - assumeTelevision(); mTvPipBoundsState.setTvPipExpanded(true); // Vertical expanded PiP. @@ -317,7 +309,6 @@ public class TvPipGravityTest extends ShellTestCase { @Test public void previousCollapsedGravity_defaultValue() { - assumeTelevision(); assertEquals(mTvPipBoundsState.getTvPipPreviousCollapsedGravity(), mTvPipBoundsState.getDefaultGravity()); setRTL(true); @@ -327,7 +318,6 @@ public class TvPipGravityTest extends ShellTestCase { @Test public void previousCollapsedGravity_changes_on_RTL() { - assumeTelevision(); mTvPipBoundsState.setTvPipPreviousCollapsedGravity(Gravity.TOP | Gravity.LEFT); setRTL(true); assertEquals(mTvPipBoundsState.getTvPipPreviousCollapsedGravity(), diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/taskview/TaskViewTransitionsTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/taskview/TaskViewTransitionsTest.java index 03ed18c86608..050443914355 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/taskview/TaskViewTransitionsTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/taskview/TaskViewTransitionsTest.java @@ -65,12 +65,6 @@ public class TaskViewTransitionsTest extends ShellTestCase { ActivityManager.RunningTaskInfo mTaskInfo; @Mock WindowContainerToken mToken; - @Mock - TaskViewTaskController mTaskViewTaskController2; - @Mock - ActivityManager.RunningTaskInfo mTaskInfo2; - @Mock - WindowContainerToken mToken2; TaskViewTransitions mTaskViewTransitions; @@ -86,16 +80,10 @@ public class TaskViewTransitionsTest extends ShellTestCase { mTaskInfo.token = mToken; mTaskInfo.taskId = 314; mTaskInfo.taskDescription = mock(ActivityManager.TaskDescription.class); - when(mTaskViewTaskController.getTaskInfo()).thenReturn(mTaskInfo); - - mTaskInfo2 = new ActivityManager.RunningTaskInfo(); - mTaskInfo2.token = mToken2; - mTaskInfo2.taskId = 315; - mTaskInfo2.taskDescription = mock(ActivityManager.TaskDescription.class); - when(mTaskViewTaskController2.getTaskInfo()).thenReturn(mTaskInfo2); mTaskViewTransitions = spy(new TaskViewTransitions(mTransitions)); mTaskViewTransitions.addTaskView(mTaskViewTaskController); + when(mTaskViewTaskController.getTaskInfo()).thenReturn(mTaskInfo); } @Test @@ -138,7 +126,7 @@ public class TaskViewTransitionsTest extends ShellTestCase { } @Test - public void testSetTaskBounds_taskVisibleWithPendingOpen_noTransaction() { + public void testSetTaskBounds_taskVisibleWithPending_noTransaction() { assumeTrue(Transitions.ENABLE_SHELL_TRANSITIONS); mTaskViewTransitions.setTaskViewVisible(mTaskViewTaskController, true); @@ -154,43 +142,6 @@ public class TaskViewTransitionsTest extends ShellTestCase { } @Test - public void testSetTaskBounds_taskVisibleWithPendingChange_transition() { - assumeTrue(Transitions.ENABLE_SHELL_TRANSITIONS); - - mTaskViewTransitions.setTaskViewVisible(mTaskViewTaskController, true); - - // Consume the pending transition from visibility change - TaskViewTransitions.PendingTransition pending = - mTaskViewTransitions.findPending(mTaskViewTaskController, TRANSIT_TO_FRONT); - assertThat(pending).isNotNull(); - mTaskViewTransitions.startAnimation(pending.mClaimed, - mock(TransitionInfo.class), - new SurfaceControl.Transaction(), - new SurfaceControl.Transaction(), - mock(Transitions.TransitionFinishCallback.class)); - // Verify it was consumed - TaskViewTransitions.PendingTransition checkPending = - mTaskViewTransitions.findPending(mTaskViewTaskController, TRANSIT_TO_FRONT); - assertThat(checkPending).isNull(); - - // Test that set bounds creates a new transition - mTaskViewTransitions.setTaskBounds(mTaskViewTaskController, - new Rect(0, 0, 100, 100)); - assertThat(mTaskViewTransitions.findPending(mTaskViewTaskController, TRANSIT_CHANGE)) - .isNotNull(); - - // Test that set bounds again (with different bounds) creates another transition - mTaskViewTransitions.setTaskBounds(mTaskViewTaskController, - new Rect(0, 0, 300, 200)); - List<TaskViewTransitions.PendingTransition> pendingList = - mTaskViewTransitions.findAllPending(mTaskViewTaskController) - .stream() - .filter(pendingTransition -> pendingTransition.mType == TRANSIT_CHANGE) - .toList(); - assertThat(pendingList.size()).isEqualTo(2); - } - - @Test public void testSetTaskBounds_sameBounds_noTransaction() { assumeTrue(Transitions.ENABLE_SHELL_TRANSITIONS); @@ -217,16 +168,6 @@ public class TaskViewTransitionsTest extends ShellTestCase { mTaskViewTransitions.findPending(mTaskViewTaskController, TRANSIT_CHANGE); assertThat(pendingBounds).isNotNull(); - // Test that setting same bounds with in-flight transition doesn't cause another one - mTaskViewTransitions.setTaskBounds(mTaskViewTaskController, - new Rect(0, 0, 100, 100)); - List<TaskViewTransitions.PendingTransition> pendingList = - mTaskViewTransitions.findAllPending(mTaskViewTaskController) - .stream() - .filter(pendingTransition -> pendingTransition.mType == TRANSIT_CHANGE) - .toList(); - assertThat(pendingList.size()).isEqualTo(1); - // Consume the pending bounds transaction mTaskViewTransitions.startAnimation(pendingBounds.mClaimed, mock(TransitionInfo.class), @@ -246,42 +187,6 @@ public class TaskViewTransitionsTest extends ShellTestCase { assertThat(pendingBounds2).isNull(); } - - @Test - public void testSetTaskBounds_taskVisibleWithDifferentTaskViewPendingChange_transition() { - assumeTrue(Transitions.ENABLE_SHELL_TRANSITIONS); - - mTaskViewTransitions.addTaskView(mTaskViewTaskController2); - - mTaskViewTransitions.setTaskViewVisible(mTaskViewTaskController, true); - - // Consume the pending transition from visibility change - TaskViewTransitions.PendingTransition pending = - mTaskViewTransitions.findPending(mTaskViewTaskController, TRANSIT_TO_FRONT); - assertThat(pending).isNotNull(); - mTaskViewTransitions.startAnimation(pending.mClaimed, - mock(TransitionInfo.class), - new SurfaceControl.Transaction(), - new SurfaceControl.Transaction(), - mock(Transitions.TransitionFinishCallback.class)); - // Verify it was consumed - TaskViewTransitions.PendingTransition checkPending = - mTaskViewTransitions.findPending(mTaskViewTaskController, TRANSIT_TO_FRONT); - assertThat(checkPending).isNull(); - - // Set the second taskview as visible & check that it has a pending transition - mTaskViewTransitions.setTaskViewVisible(mTaskViewTaskController2, true); - TaskViewTransitions.PendingTransition pending2 = - mTaskViewTransitions.findPending(mTaskViewTaskController2, TRANSIT_TO_FRONT); - assertThat(pending2).isNotNull(); - - // Test that set bounds on the first taskview will create a new transition - mTaskViewTransitions.setTaskBounds(mTaskViewTaskController, - new Rect(0, 0, 100, 100)); - assertThat(mTaskViewTransitions.findPending(mTaskViewTaskController, TRANSIT_CHANGE)) - .isNotNull(); - } - @Test public void testSetTaskVisibility_taskRemoved_noNPE() { mTaskViewTransitions.removeTaskView(mTaskViewTaskController); diff --git a/libs/androidfw/Android.bp b/libs/androidfw/Android.bp index 28bda72bccdd..fa9447afbeab 100644 --- a/libs/androidfw/Android.bp +++ b/libs/androidfw/Android.bp @@ -232,6 +232,7 @@ cc_benchmark { "tests/AssetManager2_bench.cpp", "tests/AttributeResolution_bench.cpp", "tests/CursorWindow_bench.cpp", + "tests/Generic_bench.cpp", "tests/SparseEntry_bench.cpp", "tests/Theme_bench.cpp", ], diff --git a/libs/androidfw/ApkAssets.cpp b/libs/androidfw/ApkAssets.cpp index 15aaae25f754..f0c639574a9f 100644 --- a/libs/androidfw/ApkAssets.cpp +++ b/libs/androidfw/ApkAssets.cpp @@ -27,39 +27,34 @@ using base::unique_fd; constexpr const char* kResourcesArsc = "resources.arsc"; -ApkAssets::ApkAssets(std::unique_ptr<Asset> resources_asset, +ApkAssets::ApkAssets(PrivateConstructorUtil, std::unique_ptr<Asset> resources_asset, std::unique_ptr<LoadedArsc> loaded_arsc, - std::unique_ptr<AssetsProvider> assets, - package_property_t property_flags, - std::unique_ptr<Asset> idmap_asset, - std::unique_ptr<LoadedIdmap> loaded_idmap) + std::unique_ptr<AssetsProvider> assets, package_property_t property_flags, + std::unique_ptr<Asset> idmap_asset, std::unique_ptr<LoadedIdmap> loaded_idmap) : resources_asset_(std::move(resources_asset)), loaded_arsc_(std::move(loaded_arsc)), assets_provider_(std::move(assets)), property_flags_(property_flags), idmap_asset_(std::move(idmap_asset)), - loaded_idmap_(std::move(loaded_idmap)) {} + loaded_idmap_(std::move(loaded_idmap)) { +} -std::unique_ptr<ApkAssets> ApkAssets::Load(const std::string& path, package_property_t flags) { +ApkAssetsPtr ApkAssets::Load(const std::string& path, package_property_t flags) { return Load(ZipAssetsProvider::Create(path, flags), flags); } -std::unique_ptr<ApkAssets> ApkAssets::LoadFromFd(base::unique_fd fd, - const std::string& debug_name, - package_property_t flags, - off64_t offset, - off64_t len) { +ApkAssetsPtr ApkAssets::LoadFromFd(base::unique_fd fd, const std::string& debug_name, + package_property_t flags, off64_t offset, off64_t len) { return Load(ZipAssetsProvider::Create(std::move(fd), debug_name, offset, len), flags); } -std::unique_ptr<ApkAssets> ApkAssets::Load(std::unique_ptr<AssetsProvider> assets, - package_property_t flags) { +ApkAssetsPtr ApkAssets::Load(std::unique_ptr<AssetsProvider> assets, package_property_t flags) { return LoadImpl(std::move(assets), flags, nullptr /* idmap_asset */, nullptr /* loaded_idmap */); } -std::unique_ptr<ApkAssets> ApkAssets::LoadTable(std::unique_ptr<Asset> resources_asset, - std::unique_ptr<AssetsProvider> assets, - package_property_t flags) { +ApkAssetsPtr ApkAssets::LoadTable(std::unique_ptr<Asset> resources_asset, + std::unique_ptr<AssetsProvider> assets, + package_property_t flags) { if (resources_asset == nullptr) { return {}; } @@ -67,8 +62,7 @@ std::unique_ptr<ApkAssets> ApkAssets::LoadTable(std::unique_ptr<Asset> resources nullptr /* loaded_idmap */); } -std::unique_ptr<ApkAssets> ApkAssets::LoadOverlay(const std::string& idmap_path, - package_property_t flags) { +ApkAssetsPtr ApkAssets::LoadOverlay(const std::string& idmap_path, package_property_t flags) { CHECK((flags & PROPERTY_LOADER) == 0U) << "Cannot load RROs through loaders"; auto idmap_asset = AssetsProvider::CreateAssetFromFile(idmap_path); if (idmap_asset == nullptr) { @@ -103,10 +97,10 @@ std::unique_ptr<ApkAssets> ApkAssets::LoadOverlay(const std::string& idmap_path, std::move(loaded_idmap)); } -std::unique_ptr<ApkAssets> ApkAssets::LoadImpl(std::unique_ptr<AssetsProvider> assets, - package_property_t property_flags, - std::unique_ptr<Asset> idmap_asset, - std::unique_ptr<LoadedIdmap> loaded_idmap) { +ApkAssetsPtr ApkAssets::LoadImpl(std::unique_ptr<AssetsProvider> assets, + package_property_t property_flags, + std::unique_ptr<Asset> idmap_asset, + std::unique_ptr<LoadedIdmap> loaded_idmap) { if (assets == nullptr) { return {}; } @@ -125,11 +119,11 @@ std::unique_ptr<ApkAssets> ApkAssets::LoadImpl(std::unique_ptr<AssetsProvider> a std::move(idmap_asset), std::move(loaded_idmap)); } -std::unique_ptr<ApkAssets> ApkAssets::LoadImpl(std::unique_ptr<Asset> resources_asset, - std::unique_ptr<AssetsProvider> assets, - package_property_t property_flags, - std::unique_ptr<Asset> idmap_asset, - std::unique_ptr<LoadedIdmap> loaded_idmap) { +ApkAssetsPtr ApkAssets::LoadImpl(std::unique_ptr<Asset> resources_asset, + std::unique_ptr<AssetsProvider> assets, + package_property_t property_flags, + std::unique_ptr<Asset> idmap_asset, + std::unique_ptr<LoadedIdmap> loaded_idmap) { if (assets == nullptr ) { return {}; } @@ -155,10 +149,9 @@ std::unique_ptr<ApkAssets> ApkAssets::LoadImpl(std::unique_ptr<Asset> resources_ return {}; } - return std::unique_ptr<ApkAssets>(new ApkAssets(std::move(resources_asset), - std::move(loaded_arsc), std::move(assets), - property_flags, std::move(idmap_asset), - std::move(loaded_idmap))); + return ApkAssetsPtr::make(PrivateConstructorUtil{}, std::move(resources_asset), + std::move(loaded_arsc), std::move(assets), property_flags, + std::move(idmap_asset), std::move(loaded_idmap)); } std::optional<std::string_view> ApkAssets::GetPath() const { @@ -174,4 +167,5 @@ bool ApkAssets::IsUpToDate() const { return IsLoader() || ((!loaded_idmap_ || loaded_idmap_->IsUpToDate()) && assets_provider_->IsUpToDate()); } + } // namespace android diff --git a/libs/androidfw/ApkParsing.cpp b/libs/androidfw/ApkParsing.cpp index 32d2c5b05acb..7eedfdb5c921 100644 --- a/libs/androidfw/ApkParsing.cpp +++ b/libs/androidfw/ApkParsing.cpp @@ -56,6 +56,11 @@ const char* ValidLibraryPathLastSlash(const char* fileName, bool suppress64Bit, return nullptr; } + // Make sure file starts with 'lib/' prefix. + if (strncmp(fileName, APK_LIB.data(), APK_LIB_LEN) != 0) { + return nullptr; + } + // Make sure there aren't subdirectories by checking if the next / after lib/ is the last slash if (memchr(fileName + APK_LIB_LEN, '/', fileNameLen - APK_LIB_LEN) != lastSlash) { return nullptr; diff --git a/libs/androidfw/AssetManager2.cpp b/libs/androidfw/AssetManager2.cpp index 68f5e4a88c7e..ad09067e6309 100644 --- a/libs/androidfw/AssetManager2.cpp +++ b/libs/androidfw/AssetManager2.cpp @@ -91,13 +91,19 @@ struct FindEntryResult { StringPoolRef entry_string_ref; }; +AssetManager2::AssetManager2(ApkAssetsList apk_assets, const ResTable_config& configuration) { + configurations_.push_back(configuration); + + // Don't invalidate caches here as there's nothing cached yet. + SetApkAssets(apk_assets, false); +} + AssetManager2::AssetManager2() { - memset(&configuration_, 0, sizeof(configuration_)); + configurations_.resize(1); } -bool AssetManager2::SetApkAssets(std::vector<const ApkAssets*> apk_assets, bool invalidate_caches) { - apk_assets_ = std::move(apk_assets); - BuildDynamicRefTable(); +bool AssetManager2::SetApkAssets(ApkAssetsList apk_assets, bool invalidate_caches) { + BuildDynamicRefTable(apk_assets); RebuildFilterList(); if (invalidate_caches) { InvalidateCaches(static_cast<uint32_t>(-1)); @@ -105,7 +111,21 @@ bool AssetManager2::SetApkAssets(std::vector<const ApkAssets*> apk_assets, bool return true; } -void AssetManager2::BuildDynamicRefTable() { +bool AssetManager2::SetApkAssets(std::initializer_list<ApkAssetsPtr> apk_assets, + bool invalidate_caches) { + return SetApkAssets(ApkAssetsList(apk_assets.begin(), apk_assets.size()), invalidate_caches); +} + +void AssetManager2::BuildDynamicRefTable(ApkAssetsList apk_assets) { + auto op = StartOperation(); + + apk_assets_.resize(apk_assets.size()); + for (size_t i = 0; i != apk_assets.size(); ++i) { + apk_assets_[i].first = apk_assets[i]; + // Let's populate the locked assets right away as we're going to need them here later. + apk_assets_[i].second = apk_assets[i]; + } + package_groups_.clear(); package_ids_.fill(0xff); @@ -116,16 +136,19 @@ void AssetManager2::BuildDynamicRefTable() { // Overlay resources are not directly referenced by an application so their resource ids // can change throughout the application's lifetime. Assign overlay package ids last. - std::vector<const ApkAssets*> sorted_apk_assets(apk_assets_); - std::stable_partition(sorted_apk_assets.begin(), sorted_apk_assets.end(), [](const ApkAssets* a) { - return !a->IsOverlay(); - }); + std::vector<const ApkAssets*> sorted_apk_assets; + sorted_apk_assets.reserve(apk_assets.size()); + for (auto& asset : apk_assets) { + sorted_apk_assets.push_back(asset.get()); + } + std::stable_partition(sorted_apk_assets.begin(), sorted_apk_assets.end(), + [](auto a) { return !a->IsOverlay(); }); // The assets cookie must map to the position of the apk assets in the unsorted apk assets list. std::unordered_map<const ApkAssets*, ApkAssetsCookie> apk_assets_cookies; - apk_assets_cookies.reserve(apk_assets_.size()); - for (size_t i = 0, n = apk_assets_.size(); i < n; i++) { - apk_assets_cookies[apk_assets_[i]] = static_cast<ApkAssetsCookie>(i); + apk_assets_cookies.reserve(apk_assets.size()); + for (size_t i = 0, n = apk_assets.size(); i < n; i++) { + apk_assets_cookies[apk_assets[i].get()] = static_cast<ApkAssetsCookie>(i); } // 0x01 is reserved for the android package. @@ -240,9 +263,11 @@ void AssetManager2::BuildDynamicRefTable() { void AssetManager2::DumpToLog() const { LOG(INFO) << base::StringPrintf("AssetManager2(this=%p)", this); + auto op = StartOperation(); std::string list; - for (const auto& apk_assets : apk_assets_) { - base::StringAppendF(&list, "%s,", apk_assets->GetDebugName().c_str()); + for (size_t i = 0, s = apk_assets_.size(); i < s; ++i) { + const auto& assets = GetApkAssets(i); + base::StringAppendF(&list, "%s,", assets ? assets->GetDebugName().c_str() : "nullptr"); } LOG(INFO) << "ApkAssets: " << list; @@ -279,7 +304,9 @@ const ResStringPool* AssetManager2::GetStringPoolForCookie(ApkAssetsCookie cooki if (cookie < 0 || static_cast<size_t>(cookie) >= apk_assets_.size()) { return nullptr; } - return apk_assets_[cookie]->GetLoadedArsc()->GetStringPool(); + auto op = StartOperation(); + const auto& assets = GetApkAssets(cookie); + return assets ? assets->GetLoadedArsc()->GetStringPool() : nullptr; } const DynamicRefTable* AssetManager2::GetDynamicRefTableForPackage(uint32_t package_id) const { @@ -329,9 +356,14 @@ const std::unordered_map<std::string, std::string>* bool AssetManager2::GetOverlayablesToString(android::StringPiece package_name, std::string* out) const { + auto op = StartOperation(); uint8_t package_id = 0U; - for (const auto& apk_assets : apk_assets_) { - const LoadedArsc* loaded_arsc = apk_assets->GetLoadedArsc(); + for (size_t i = 0, s = apk_assets_.size(); i != s; ++i) { + const auto& assets = GetApkAssets(i); + if (!assets) { + continue; + } + const LoadedArsc* loaded_arsc = assets->GetLoadedArsc(); if (loaded_arsc == nullptr) { continue; } @@ -384,13 +416,26 @@ bool AssetManager2::GetOverlayablesToString(android::StringPiece package_name, } bool AssetManager2::ContainsAllocatedTable() const { - return std::find_if(apk_assets_.begin(), apk_assets_.end(), - std::mem_fn(&ApkAssets::IsTableAllocated)) != apk_assets_.end(); + auto op = StartOperation(); + for (size_t i = 0, s = apk_assets_.size(); i != s; ++i) { + const auto& assets = GetApkAssets(i); + if (assets && assets->IsTableAllocated()) { + return true; + } + } + return false; } -void AssetManager2::SetConfiguration(const ResTable_config& configuration) { - const int diff = configuration_.diff(configuration); - configuration_ = configuration; +void AssetManager2::SetConfigurations(std::vector<ResTable_config> configurations) { + int diff = 0; + if (configurations_.size() != configurations.size()) { + diff = -1; + } else { + for (int i = 0; i < configurations_.size(); i++) { + diff |= configurations_[i].diff(configurations[i]); + } + } + configurations_ = std::move(configurations); if (diff) { RebuildFilterList(); @@ -398,8 +443,8 @@ void AssetManager2::SetConfiguration(const ResTable_config& configuration) { } } -std::set<const ApkAssets*> AssetManager2::GetNonSystemOverlays() const { - std::set<const ApkAssets*> non_system_overlays; +std::set<AssetManager2::ApkAssetsPtr> AssetManager2::GetNonSystemOverlays() const { + std::set<ApkAssetsPtr> non_system_overlays; for (const PackageGroup& package_group : package_groups_) { bool found_system_package = false; for (const ConfiguredPackage& package : package_group.packages_) { @@ -410,8 +455,11 @@ std::set<const ApkAssets*> AssetManager2::GetNonSystemOverlays() const { } if (!found_system_package) { + auto op = StartOperation(); for (const ConfiguredOverlay& overlay : package_group.overlays_) { - non_system_overlays.insert(apk_assets_[overlay.cookie]); + if (const auto& asset = GetApkAssets(overlay.cookie)) { + non_system_overlays.insert(std::move(asset)); + } } } } @@ -422,22 +470,27 @@ std::set<const ApkAssets*> AssetManager2::GetNonSystemOverlays() const { base::expected<std::set<ResTable_config>, IOError> AssetManager2::GetResourceConfigurations( bool exclude_system, bool exclude_mipmap) const { ATRACE_NAME("AssetManager::GetResourceConfigurations"); + auto op = StartOperation(); + const auto non_system_overlays = - (exclude_system) ? GetNonSystemOverlays() : std::set<const ApkAssets*>(); + exclude_system ? GetNonSystemOverlays() : std::set<ApkAssetsPtr>(); std::set<ResTable_config> configurations; for (const PackageGroup& package_group : package_groups_) { for (size_t i = 0; i < package_group.packages_.size(); i++) { const ConfiguredPackage& package = package_group.packages_[i]; - if (exclude_system && package.loaded_package_->IsSystem()) { - continue; - } - - auto apk_assets = apk_assets_[package_group.cookies_[i]]; - if (exclude_system && apk_assets->IsOverlay() && - non_system_overlays.find(apk_assets) == non_system_overlays.end()) { - // Exclude overlays that target system resources. - continue; + if (exclude_system) { + if (package.loaded_package_->IsSystem()) { + continue; + } + if (!non_system_overlays.empty()) { + // Exclude overlays that target only system resources. + const auto& apk_assets = GetApkAssets(package_group.cookies_[i]); + if (apk_assets && apk_assets->IsOverlay() && + non_system_overlays.find(apk_assets) == non_system_overlays.end()) { + continue; + } + } } auto result = package.loaded_package_->CollectConfigurations(exclude_mipmap, &configurations); @@ -452,22 +505,27 @@ base::expected<std::set<ResTable_config>, IOError> AssetManager2::GetResourceCon std::set<std::string> AssetManager2::GetResourceLocales(bool exclude_system, bool merge_equivalent_languages) const { ATRACE_NAME("AssetManager::GetResourceLocales"); + auto op = StartOperation(); + std::set<std::string> locales; const auto non_system_overlays = - (exclude_system) ? GetNonSystemOverlays() : std::set<const ApkAssets*>(); + exclude_system ? GetNonSystemOverlays() : std::set<ApkAssetsPtr>(); for (const PackageGroup& package_group : package_groups_) { for (size_t i = 0; i < package_group.packages_.size(); i++) { const ConfiguredPackage& package = package_group.packages_[i]; - if (exclude_system && package.loaded_package_->IsSystem()) { - continue; - } - - auto apk_assets = apk_assets_[package_group.cookies_[i]]; - if (exclude_system && apk_assets->IsOverlay() && - non_system_overlays.find(apk_assets) == non_system_overlays.end()) { - // Exclude overlays that target system resources. - continue; + if (exclude_system) { + if (package.loaded_package_->IsSystem()) { + continue; + } + if (!non_system_overlays.empty()) { + // Exclude overlays that target only system resources. + const auto& apk_assets = GetApkAssets(package_group.cookies_[i]); + if (apk_assets && apk_assets->IsOverlay() && + non_system_overlays.find(apk_assets) == non_system_overlays.end()) { + continue; + } + } } package.loaded_package_->CollectLocales(merge_equivalent_languages, &locales); @@ -490,15 +548,15 @@ std::unique_ptr<Asset> AssetManager2::Open(const std::string& filename, ApkAsset std::unique_ptr<AssetDir> AssetManager2::OpenDir(const std::string& dirname) const { ATRACE_NAME("AssetManager::OpenDir"); + auto op = StartOperation(); std::string full_path = "assets/" + dirname; - std::unique_ptr<SortedVector<AssetDir::FileInfo>> files = - util::make_unique<SortedVector<AssetDir::FileInfo>>(); + auto files = util::make_unique<SortedVector<AssetDir::FileInfo>>(); // Start from the back. - for (auto iter = apk_assets_.rbegin(); iter != apk_assets_.rend(); ++iter) { - const ApkAssets* apk_assets = *iter; - if (apk_assets->IsOverlay()) { + for (size_t i = apk_assets_.size(); i > 0; --i) { + const auto& apk_assets = GetApkAssets(i - 1); + if (!apk_assets || apk_assets->IsOverlay()) { continue; } @@ -526,15 +584,17 @@ std::unique_ptr<AssetDir> AssetManager2::OpenDir(const std::string& dirname) con std::unique_ptr<Asset> AssetManager2::OpenNonAsset(const std::string& filename, Asset::AccessMode mode, ApkAssetsCookie* out_cookie) const { - for (int32_t i = apk_assets_.size() - 1; i >= 0; i--) { + auto op = StartOperation(); + for (size_t i = apk_assets_.size(); i > 0; i--) { + const auto& assets = GetApkAssets(i - 1); // Prevent RRO from modifying assets and other entries accessed by file // path. Explicitly asking for a path in a given package (denoted by a // cookie) is still OK. - if (apk_assets_[i]->IsOverlay()) { + if (!assets || assets->IsOverlay()) { continue; } - std::unique_ptr<Asset> asset = apk_assets_[i]->GetAssetsProvider()->Open(filename, mode); + std::unique_ptr<Asset> asset = assets->GetAssetsProvider()->Open(filename, mode); if (asset) { if (out_cookie != nullptr) { *out_cookie = i; @@ -555,7 +615,9 @@ std::unique_ptr<Asset> AssetManager2::OpenNonAsset(const std::string& filename, if (cookie < 0 || static_cast<size_t>(cookie) >= apk_assets_.size()) { return {}; } - return apk_assets_[cookie]->GetAssetsProvider()->Open(filename, mode); + auto op = StartOperation(); + const auto& assets = GetApkAssets(cookie); + return assets ? assets->GetAssetsProvider()->Open(filename, mode) : nullptr; } base::expected<FindEntryResult, NullOrIOError> AssetManager2::FindEntry( @@ -568,16 +630,8 @@ base::expected<FindEntryResult, NullOrIOError> AssetManager2::FindEntry( last_resolution_.resid = resid; } - // Might use this if density_override != 0. - ResTable_config density_override_config; + auto op = StartOperation(); - // Select our configuration or generate a density override configuration. - const ResTable_config* desired_config = &configuration_; - if (density_override != 0 && density_override != configuration_.density) { - density_override_config = configuration_; - density_override_config.density = density_override; - desired_config = &density_override_config; - } // Retrieve the package group from the package id of the resource id. if (UNLIKELY(!is_valid_resid(resid))) { @@ -596,112 +650,160 @@ base::expected<FindEntryResult, NullOrIOError> AssetManager2::FindEntry( } const PackageGroup& package_group = package_groups_[package_idx]; - auto result = FindEntryInternal(package_group, type_idx, entry_idx, *desired_config, - stop_at_first_match, ignore_configuration); - if (UNLIKELY(!result.has_value())) { - return base::unexpected(result.error()); - } + std::optional<FindEntryResult> final_result; + bool final_has_locale = false; + bool final_overlaid = false; + for (auto & config : configurations_) { + // Might use this if density_override != 0. + ResTable_config density_override_config; + + // Select our configuration or generate a density override configuration. + const ResTable_config* desired_config = &config; + if (density_override != 0 && density_override != config.density) { + density_override_config = config; + density_override_config.density = density_override; + desired_config = &density_override_config; + } - bool overlaid = false; - if (!stop_at_first_match && !ignore_configuration && !apk_assets_[result->cookie]->IsLoader()) { - for (const auto& id_map : package_group.overlays_) { - auto overlay_entry = id_map.overlay_res_maps_.Lookup(resid); - if (!overlay_entry) { - // No id map entry exists for this target resource. - continue; + auto result = FindEntryInternal(package_group, type_idx, entry_idx, *desired_config, + stop_at_first_match, ignore_configuration); + if (UNLIKELY(!result.has_value())) { + return base::unexpected(result.error()); + } + bool overlaid = false; + if (!stop_at_first_match && !ignore_configuration) { + const auto& assets = GetApkAssets(result->cookie); + if (!assets) { + ALOGE("Found expired ApkAssets #%d for resource ID 0x%08x.", result->cookie, resid); + return base::unexpected(std::nullopt); } - if (overlay_entry.IsInlineValue()) { - // The target resource is overlaid by an inline value not represented by a resource. - ConfigDescription best_frro_config; - Res_value best_frro_value; - bool frro_found = false; - for( const auto& [config, value] : overlay_entry.GetInlineValue()) { - if ((!frro_found || config.isBetterThan(best_frro_config, desired_config)) - && config.match(*desired_config)) { - frro_found = true; - best_frro_config = config; - best_frro_value = value; + if (!assets->IsLoader()) { + for (const auto& id_map : package_group.overlays_) { + auto overlay_entry = id_map.overlay_res_maps_.Lookup(resid); + if (!overlay_entry) { + // No id map entry exists for this target resource. + continue; } - } - if (!frro_found) { - continue; - } - result->entry = best_frro_value; - result->dynamic_ref_table = id_map.overlay_res_maps_.GetOverlayDynamicRefTable(); - result->cookie = id_map.cookie; - - if (UNLIKELY(logging_enabled)) { - last_resolution_.steps.push_back( - Resolution::Step{Resolution::Step::Type::OVERLAID_INLINE, String8(), result->cookie}); - if (auto path = apk_assets_[result->cookie]->GetPath()) { - const std::string overlay_path = path->data(); - if (IsFabricatedOverlay(overlay_path)) { - // FRRO don't have package name so we use the creating package here. - String8 frro_name = String8("FRRO"); - // Get the first part of it since the expected one should be like - // {overlayPackageName}-{overlayName}-{4 alphanumeric chars}.frro - // under /data/resource-cache/. - const std::string name = overlay_path.substr(overlay_path.rfind('/') + 1); - const size_t end = name.find('-'); - if (frro_name.size() != overlay_path.size() && end != std::string::npos) { - frro_name.append(base::StringPrintf(" created by %s", - name.substr(0 /* pos */, - end).c_str()).c_str()); + if (overlay_entry.IsInlineValue()) { + // The target resource is overlaid by an inline value not represented by a resource. + ConfigDescription best_frro_config; + Res_value best_frro_value; + bool frro_found = false; + for( const auto& [config, value] : overlay_entry.GetInlineValue()) { + if ((!frro_found || config.isBetterThan(best_frro_config, desired_config)) + && config.match(*desired_config)) { + frro_found = true; + best_frro_config = config; + best_frro_value = value; } - last_resolution_.best_package_name = frro_name; - } else { - last_resolution_.best_package_name = result->package_name->c_str(); } + if (!frro_found) { + continue; + } + result->entry = best_frro_value; + result->dynamic_ref_table = id_map.overlay_res_maps_.GetOverlayDynamicRefTable(); + result->cookie = id_map.cookie; + + if (UNLIKELY(logging_enabled)) { + last_resolution_.steps.push_back(Resolution::Step{ + Resolution::Step::Type::OVERLAID_INLINE, result->cookie, String8()}); + if (auto path = assets->GetPath()) { + const std::string overlay_path = path->data(); + if (IsFabricatedOverlay(overlay_path)) { + // FRRO don't have package name so we use the creating package here. + String8 frro_name = String8("FRRO"); + // Get the first part of it since the expected one should be like + // {overlayPackageName}-{overlayName}-{4 alphanumeric chars}.frro + // under /data/resource-cache/. + const std::string name = overlay_path.substr(overlay_path.rfind('/') + 1); + const size_t end = name.find('-'); + if (frro_name.size() != overlay_path.size() && end != std::string::npos) { + frro_name.append(base::StringPrintf(" created by %s", + name.substr(0 /* pos */, + end).c_str()).c_str()); + } + last_resolution_.best_package_name = frro_name; + } else { + last_resolution_.best_package_name = result->package_name->c_str(); + } + } + overlaid = true; + } + continue; } - overlaid = true; - } - continue; - } - auto overlay_result = FindEntry(overlay_entry.GetResourceId(), density_override, - false /* stop_at_first_match */, - false /* ignore_configuration */); - if (UNLIKELY(IsIOError(overlay_result))) { - return base::unexpected(overlay_result.error()); - } - if (!overlay_result.has_value()) { - continue; - } + auto overlay_result = FindEntry(overlay_entry.GetResourceId(), density_override, + false /* stop_at_first_match */, + false /* ignore_configuration */); + if (UNLIKELY(IsIOError(overlay_result))) { + return base::unexpected(overlay_result.error()); + } + if (!overlay_result.has_value()) { + continue; + } - if (!overlay_result->config.isBetterThan(result->config, desired_config) - && overlay_result->config.compare(result->config) != 0) { - // The configuration of the entry for the overlay must be equal to or better than the target - // configuration to be chosen as the better value. - continue; - } + if (!overlay_result->config.isBetterThan(result->config, desired_config) + && overlay_result->config.compare(result->config) != 0) { + // The configuration of the entry for the overlay must be equal to or better than the + // target configuration to be chosen as the better value. + continue; + } - result->cookie = overlay_result->cookie; - result->entry = overlay_result->entry; - result->config = overlay_result->config; - result->dynamic_ref_table = id_map.overlay_res_maps_.GetOverlayDynamicRefTable(); + result->cookie = overlay_result->cookie; + result->entry = overlay_result->entry; + result->config = overlay_result->config; + result->dynamic_ref_table = id_map.overlay_res_maps_.GetOverlayDynamicRefTable(); + + if (UNLIKELY(logging_enabled)) { + last_resolution_.steps.push_back( + Resolution::Step{Resolution::Step::Type::OVERLAID, overlay_result->cookie, + overlay_result->config.toString()}); + last_resolution_.best_package_name = + overlay_result->package_name->c_str(); + overlaid = true; + } + } + } + } - if (UNLIKELY(logging_enabled)) { - last_resolution_.steps.push_back( - Resolution::Step{Resolution::Step::Type::OVERLAID, overlay_result->config.toString(), - overlay_result->cookie}); - last_resolution_.best_package_name = - overlay_result->package_name->c_str(); - overlaid = true; + bool has_locale = false; + if (result->config.locale == 0) { + if (default_locale_ != 0) { + ResTable_config conf; + conf.locale = default_locale_; + // Since we know conf has a locale and only a locale, match will tell us if that locale + // matches + has_locale = conf.match(config); } + } else { + has_locale = true; + } + + // if we don't have a result yet + if (!final_result || + // or this config is better before the locale than the existing result + result->config.isBetterThanBeforeLocale(final_result->config, desired_config) || + // or the existing config isn't better before locale and this one specifies a locale + // whereas the existing one doesn't + (!final_result->config.isBetterThanBeforeLocale(result->config, desired_config) + && has_locale && !final_has_locale)) { + final_result = result.value(); + final_overlaid = overlaid; + final_has_locale = has_locale; } } if (UNLIKELY(logging_enabled)) { - last_resolution_.cookie = result->cookie; - last_resolution_.type_string_ref = result->type_string_ref; - last_resolution_.entry_string_ref = result->entry_string_ref; - last_resolution_.best_config_name = result->config.toString(); - if (!overlaid) { - last_resolution_.best_package_name = result->package_name->c_str(); + last_resolution_.cookie = final_result->cookie; + last_resolution_.type_string_ref = final_result->type_string_ref; + last_resolution_.entry_string_ref = final_result->entry_string_ref; + last_resolution_.best_config_name = final_result->config.toString(); + if (!final_overlaid) { + last_resolution_.best_package_name = final_result->package_name->c_str(); } } - return result; + return *final_result; } base::expected<FindEntryResult, NullOrIOError> AssetManager2::FindEntryInternal( @@ -719,8 +821,10 @@ base::expected<FindEntryResult, NullOrIOError> AssetManager2::FindEntryInternal( // If `desired_config` is not the same as the set configuration or the caller will accept a value // from any configuration, then we cannot use our filtered list of types since it only it contains // types matched to the set configuration. - const bool use_filtered = !ignore_configuration && &desired_config == &configuration_; - + const bool use_filtered = !ignore_configuration && std::find_if( + configurations_.begin(), configurations_.end(), + [&desired_config](auto& value) { return &desired_config == &value; }) + != configurations_.end(); const size_t package_count = package_group.packages_.size(); for (size_t pi = 0; pi < package_count; pi++) { const ConfiguredPackage& loaded_package_impl = package_group.packages_[pi]; @@ -769,8 +873,7 @@ base::expected<FindEntryResult, NullOrIOError> AssetManager2::FindEntryInternal( } else { if (UNLIKELY(logging_enabled)) { last_resolution_.steps.push_back(Resolution::Step{Resolution::Step::Type::SKIPPED, - this_config.toString(), - cookie}); + cookie, this_config.toString()}); } continue; } @@ -786,8 +889,7 @@ base::expected<FindEntryResult, NullOrIOError> AssetManager2::FindEntryInternal( if (!offset.has_value()) { if (UNLIKELY(logging_enabled)) { last_resolution_.steps.push_back(Resolution::Step{Resolution::Step::Type::NO_ENTRY, - this_config.toString(), - cookie}); + cookie, this_config.toString()}); } continue; } @@ -800,8 +902,7 @@ base::expected<FindEntryResult, NullOrIOError> AssetManager2::FindEntryInternal( if (UNLIKELY(logging_enabled)) { last_resolution_.steps.push_back(Resolution::Step{resolution_type, - this_config.toString(), - cookie}); + cookie, this_config.toString()}); } // Any configuration will suffice, so break. @@ -839,13 +940,7 @@ base::expected<FindEntryResult, NullOrIOError> AssetManager2::FindEntryInternal( } void AssetManager2::ResetResourceResolution() const { - last_resolution_.cookie = kInvalidCookie; - last_resolution_.resid = 0; - last_resolution_.steps.clear(); - last_resolution_.type_string_ref = StringPoolRef(); - last_resolution_.entry_string_ref = StringPoolRef(); - last_resolution_.best_config_name.clear(); - last_resolution_.best_package_name.clear(); + last_resolution_ = Resolution{}; } void AssetManager2::SetResourceResolutionLoggingEnabled(bool enabled) { @@ -867,8 +962,12 @@ std::string AssetManager2::GetLastResourceResolution() const { return {}; } + auto op = StartOperation(); + const uint32_t resid = last_resolution_.resid; - const auto package = apk_assets_[cookie]->GetLoadedArsc()->GetPackageById(get_package_id(resid)); + const auto& assets = GetApkAssets(cookie); + const auto package = + assets ? assets->GetLoadedArsc()->GetPackageById(get_package_id(resid)) : nullptr; std::string resource_name_string; if (package != nullptr) { @@ -880,26 +979,40 @@ std::string AssetManager2::GetLastResourceResolution() const { } std::stringstream log_stream; - log_stream << base::StringPrintf("Resolution for 0x%08x %s\n" - "\tFor config - %s", resid, resource_name_string.c_str(), - configuration_.toString().c_str()); - + if (configurations_.size() == 1) { + log_stream << base::StringPrintf("Resolution for 0x%08x %s\n" + "\tFor config - %s", resid, resource_name_string.c_str(), + configurations_[0].toString().c_str()); + } else { + ResTable_config conf = configurations_[0]; + conf.clearLocale(); + log_stream << base::StringPrintf("Resolution for 0x%08x %s\n\tFor config - %s and locales", + resid, resource_name_string.c_str(), conf.toString().c_str()); + char str[40]; + str[0] = '\0'; + for(auto iter = configurations_.begin(); iter < configurations_.end(); iter++) { + iter->getBcp47Locale(str); + log_stream << base::StringPrintf(" %s%s", str, iter < configurations_.end() ? "," : ""); + } + } for (const Resolution::Step& step : last_resolution_.steps) { - const static std::unordered_map<Resolution::Step::Type, const char*> kStepStrings = { - {Resolution::Step::Type::INITIAL, "Found initial"}, - {Resolution::Step::Type::BETTER_MATCH, "Found better"}, - {Resolution::Step::Type::OVERLAID, "Overlaid"}, - {Resolution::Step::Type::OVERLAID_INLINE, "Overlaid inline"}, - {Resolution::Step::Type::SKIPPED, "Skipped"}, - {Resolution::Step::Type::NO_ENTRY, "No entry"} + constexpr static std::array kStepStrings = { + "Found initial", + "Found better", + "Overlaid", + "Overlaid inline", + "Skipped", + "No entry" }; - const auto prefix = kStepStrings.find(step.type); - if (prefix == kStepStrings.end()) { + if (step.type < Resolution::Step::Type::INITIAL + || step.type > Resolution::Step::Type::NO_ENTRY) { continue; } - - log_stream << "\n\t" << prefix->second << ": " << apk_assets_[step.cookie]->GetDebugName(); + const auto prefix = kStepStrings[int(step.type) - int(Resolution::Step::Type::INITIAL)]; + const auto& assets = GetApkAssets(step.cookie); + log_stream << "\n\t" << prefix << ": " << (assets ? assets->GetDebugName() : "<null>") + << " #" << step.cookie; if (!step.config_name.isEmpty()) { log_stream << " - " << step.config_name; } @@ -1036,16 +1149,19 @@ base::expected<std::monostate, NullOrIOError> AssetManager2::ResolveReference( } } -const std::vector<uint32_t> AssetManager2::GetBagResIdStack(uint32_t resid) const { - auto cached_iter = cached_bag_resid_stacks_.find(resid); - if (cached_iter != cached_bag_resid_stacks_.end()) { - return cached_iter->second; +base::expected<const std::vector<uint32_t>*, NullOrIOError> AssetManager2::GetBagResIdStack( + uint32_t resid) const { + auto it = cached_bag_resid_stacks_.find(resid); + if (it != cached_bag_resid_stacks_.end()) { + return &it->second; + } + std::vector<uint32_t> stacks; + if (auto maybe_bag = GetBag(resid, stacks); UNLIKELY(IsIOError(maybe_bag))) { + return base::unexpected(maybe_bag.error()); } - std::vector<uint32_t> found_resids; - GetBag(resid, found_resids); - cached_bag_resid_stacks_.emplace(resid, found_resids); - return found_resids; + it = cached_bag_resid_stacks_.emplace(resid, std::move(stacks)).first; + return &it->second; } base::expected<const ResolvedBag*, NullOrIOError> AssetManager2::ResolveBag( @@ -1062,9 +1178,15 @@ base::expected<const ResolvedBag*, NullOrIOError> AssetManager2::ResolveBag( } base::expected<const ResolvedBag*, NullOrIOError> AssetManager2::GetBag(uint32_t resid) const { - std::vector<uint32_t> found_resids; - const auto bag = GetBag(resid, found_resids); - cached_bag_resid_stacks_.emplace(resid, std::move(found_resids)); + auto resid_stacks_it = cached_bag_resid_stacks_.find(resid); + if (resid_stacks_it == cached_bag_resid_stacks_.end()) { + resid_stacks_it = cached_bag_resid_stacks_.emplace(resid, std::vector<uint32_t>{}).first; + } + const auto bag = GetBag(resid, resid_stacks_it->second); + if (UNLIKELY(IsIOError(bag))) { + cached_bag_resid_stacks_.erase(resid_stacks_it); + return base::unexpected(bag.error()); + } return bag; } @@ -1362,11 +1484,14 @@ void AssetManager2::RebuildFilterList() { package.loaded_package_->ForEachTypeSpec([&](const TypeSpec& type_spec, uint8_t type_id) { FilteredConfigGroup* group = nullptr; for (const auto& type_entry : type_spec.type_entries) { - if (type_entry.config.match(configuration_)) { - if (!group) { - group = &package.filtered_configs_.editItemAt(type_id - 1); + for (auto & config : configurations_) { + if (type_entry.config.match(config)) { + if (!group) { + group = &package.filtered_configs_.editItemAt(type_id - 1); + } + group->type_entries.push_back(&type_entry); + break; } - group->type_entries.push_back(&type_entry); } } }); @@ -1377,25 +1502,40 @@ void AssetManager2::RebuildFilterList() { } void AssetManager2::InvalidateCaches(uint32_t diff) { - cached_bag_resid_stacks_.clear(); + cached_resolved_values_.clear(); if (diff == 0xffffffffu) { // Everything must go. cached_bags_.clear(); + cached_bag_resid_stacks_.clear(); return; } // Be more conservative with what gets purged. Only if the bag has other possible // variations with respect to what changed (diff) should we remove it. - for (auto iter = cached_bags_.cbegin(); iter != cached_bags_.cend();) { - if (diff & iter->second->type_spec_flags) { - iter = cached_bags_.erase(iter); + for (auto stack_it = cached_bag_resid_stacks_.begin(); + stack_it != cached_bag_resid_stacks_.end();) { + const auto it = cached_bags_.find(stack_it->first); + if (it == cached_bags_.end()) { + stack_it = cached_bag_resid_stacks_.erase(stack_it); + } else if ((diff & it->second->type_spec_flags) != 0) { + cached_bags_.erase(it); + stack_it = cached_bag_resid_stacks_.erase(stack_it); } else { - ++iter; + ++stack_it; // Keep the item in both caches. } } - cached_resolved_values_.clear(); + // Need to ensure that both bag caches are consistent, as we populate them in the same function. + // Iterate over the cached bags to erase the items without the corresponding resid_stack cache + // items. + for (auto it = cached_bags_.begin(); it != cached_bags_.end();) { + if ((diff & it->second->type_spec_flags) != 0) { + it = cached_bags_.erase(it); + } else { + ++it; + } + } } uint8_t AssetManager2::GetAssignedPackageId(const LoadedPackage* package) const { @@ -1429,6 +1569,37 @@ void AssetManager2::ForEachPackage(base::function_ref<bool(const std::string&, u } } +AssetManager2::ScopedOperation AssetManager2::StartOperation() const { + ++number_of_running_scoped_operations_; + return ScopedOperation(*this); +} + +void AssetManager2::FinishOperation() const { + if (number_of_running_scoped_operations_ < 1) { + ALOGW("Invalid FinishOperation() call when there's none happening"); + return; + } + if (--number_of_running_scoped_operations_ == 0) { + for (auto&& [_, assets] : apk_assets_) { + assets.clear(); + } + } +} + +const AssetManager2::ApkAssetsPtr& AssetManager2::GetApkAssets(ApkAssetsCookie cookie) const { + DCHECK(number_of_running_scoped_operations_ > 0) << "Must have an operation running"; + + if (cookie < 0 || cookie >= apk_assets_.size()) { + static const ApkAssetsPtr empty{}; + return empty; + } + auto& [wptr, res] = apk_assets_[cookie]; + if (!res) { + res = wptr.promote(); + } + return res; +} + Theme::Theme(AssetManager2* asset_manager) : asset_manager_(asset_manager) { } @@ -1561,14 +1732,16 @@ base::expected<std::monostate, IOError> Theme::SetTo(const Theme& source) { using SourceToDestinationRuntimePackageMap = std::unordered_map<int, int>; std::unordered_map<ApkAssetsCookie, SourceToDestinationRuntimePackageMap> src_asset_cookie_id_map; - // Determine which ApkAssets are loaded in both theme AssetManagers. - const auto& src_assets = source.asset_manager_->GetApkAssets(); - for (size_t i = 0; i < src_assets.size(); i++) { - const ApkAssets* src_asset = src_assets[i]; + auto op_src = source.asset_manager_->StartOperation(); + auto op_dst = asset_manager_->StartOperation(); - const auto& dest_assets = asset_manager_->GetApkAssets(); - for (size_t j = 0; j < dest_assets.size(); j++) { - const ApkAssets* dest_asset = dest_assets[j]; + for (size_t i = 0; i < source.asset_manager_->GetApkAssetsCount(); i++) { + const auto& src_asset = source.asset_manager_->GetApkAssets(i); + if (!src_asset) { + continue; + } + for (int j = 0; j < asset_manager_->GetApkAssetsCount(); j++) { + const auto& dest_asset = asset_manager_->GetApkAssets(j); if (src_asset != dest_asset) { // ResourcesManager caches and reuses ApkAssets when the same apk must be present in // multiple AssetManagers. Two ApkAssets point to the same version of the same resources @@ -1694,4 +1867,11 @@ void Theme::Dump() const { } } +AssetManager2::ScopedOperation::ScopedOperation(const AssetManager2& am) : am_(am) { +} + +AssetManager2::ScopedOperation::~ScopedOperation() { + am_.FinishOperation(); +} + } // namespace android diff --git a/libs/androidfw/Idmap.cpp b/libs/androidfw/Idmap.cpp index 89835742c8ff..5f98b8f8db43 100644 --- a/libs/androidfw/Idmap.cpp +++ b/libs/androidfw/Idmap.cpp @@ -294,14 +294,14 @@ std::unique_ptr<LoadedIdmap> LoadedIdmap::Load(StringPiece idmap_path, StringPie dtohl(header->version), kIdmapCurrentVersion); return {}; } + std::optional<std::string_view> target_path = ReadString(&data_ptr, &data_size, "target path"); + if (!target_path) { + return {}; + } std::optional<std::string_view> overlay_path = ReadString(&data_ptr, &data_size, "overlay path"); if (!overlay_path) { return {}; } - std::optional<std::string_view> target_path = ReadString(&data_ptr, &data_size, "target path"); - if (!target_path) { - return {}; - } if (!ReadString(&data_ptr, &data_size, "target name") || !ReadString(&data_ptr, &data_size, "debug info")) { return {}; @@ -364,7 +364,7 @@ std::unique_ptr<LoadedIdmap> LoadedIdmap::Load(StringPiece idmap_path, StringPie return std::unique_ptr<LoadedIdmap>( new LoadedIdmap(std::string(idmap_path), header, data_header, target_entries, target_inline_entries, target_inline_entry_values, configurations, - overlay_entries, std::move(idmap_string_pool), *target_path, *overlay_path)); + overlay_entries, std::move(idmap_string_pool), *overlay_path, *target_path)); } bool LoadedIdmap::IsUpToDate() const { diff --git a/libs/androidfw/LoadedArsc.cpp b/libs/androidfw/LoadedArsc.cpp index c0fdfe25da21..c9d5e074271b 100644 --- a/libs/androidfw/LoadedArsc.cpp +++ b/libs/androidfw/LoadedArsc.cpp @@ -323,7 +323,7 @@ LoadedPackage::GetEntryFromOffset(incfs::verified_map_ptr<ResTable_type> type_ch } base::expected<std::monostate, IOError> LoadedPackage::CollectConfigurations( - bool exclude_mipmap, std::set<ResTable_config>* out_configs) const {\ + bool exclude_mipmap, std::set<ResTable_config>* out_configs) const { for (const auto& type_spec : type_specs_) { if (exclude_mipmap) { const int type_idx = type_spec.first - 1; @@ -494,6 +494,8 @@ std::unique_ptr<const LoadedPackage> LoadedPackage::Load(const Chunk& chunk, util::ReadUtf16StringFromDevice(header->name, arraysize(header->name), &loaded_package->package_name_); + const bool only_overlayable = (property_flags & PROPERTY_ONLY_OVERLAYABLES) != 0; + // A map of TypeSpec builders, each associated with an type index. // We use these to accumulate the set of Types available for a TypeSpec, and later build a single, // contiguous block of memory that holds all the Types together with the TypeSpec. @@ -502,6 +504,9 @@ std::unique_ptr<const LoadedPackage> LoadedPackage::Load(const Chunk& chunk, ChunkIterator iter(chunk.data_ptr(), chunk.data_size()); while (iter.HasNext()) { const Chunk child_chunk = iter.Next(); + if (only_overlayable && child_chunk.type() != RES_TABLE_OVERLAYABLE_TYPE) { + continue; + } switch (child_chunk.type()) { case RES_STRING_POOL_TYPE: { const auto pool_address = child_chunk.header<ResChunk_header>(); @@ -655,6 +660,9 @@ std::unique_ptr<const LoadedPackage> LoadedPackage::Load(const Chunk& chunk, << name_to_actor_it->first << "'."; return {}; } + if (only_overlayable) { + break; + } // Iterate over the overlayable policy chunks contained within the overlayable chunk data ChunkIterator overlayable_iter(child_chunk.data_ptr(), child_chunk.data_size()); @@ -800,14 +808,21 @@ bool LoadedArsc::LoadTable(const Chunk& chunk, const LoadedIdmap* loaded_idmap, global_string_pool_ = util::make_unique<OverlayStringPool>(loaded_idmap); } + const bool only_overlayable = (property_flags & PROPERTY_ONLY_OVERLAYABLES) != 0; + const size_t package_count = dtohl(header->packageCount); size_t packages_seen = 0; - packages_.reserve(package_count); + if (!only_overlayable) { + packages_.reserve(package_count); + } ChunkIterator iter(chunk.data_ptr(), chunk.data_size()); while (iter.HasNext()) { const Chunk child_chunk = iter.Next(); + if (only_overlayable && child_chunk.type() != RES_TABLE_PACKAGE_TYPE) { + continue; + } switch (child_chunk.type()) { case RES_STRING_POOL_TYPE: // Only use the first string pool. Ignore others. @@ -837,6 +852,10 @@ bool LoadedArsc::LoadTable(const Chunk& chunk, const LoadedIdmap* loaded_idmap, return false; } packages_.push_back(std::move(loaded_package)); + if (only_overlayable) { + // Overlayable is always in the first package, no need to process anything else. + return true; + } } break; default: diff --git a/libs/androidfw/ResourceTypes.cpp b/libs/androidfw/ResourceTypes.cpp index 29d33da6b2f7..06d19e064c91 100644 --- a/libs/androidfw/ResourceTypes.cpp +++ b/libs/androidfw/ResourceTypes.cpp @@ -1769,13 +1769,21 @@ ResXMLTree::~ResXMLTree() status_t ResXMLTree::setTo(const void* data, size_t size, bool copyData) { + const ResChunk_header* chunk = nullptr; + const ResChunk_header* lastChunk = nullptr; + uninit(); mEventCode = START_DOCUMENT; if (!data || !size) { return (mError=BAD_TYPE); } - + if (size < sizeof(ResXMLTree_header)) { + ALOGW("Bad XML block: total size %d is less than the header size %d\n", + int(size), int(sizeof(ResXMLTree_header))); + mError = BAD_TYPE; + goto done; + } if (copyData) { mOwnedData = malloc(size); if (mOwnedData == NULL) { @@ -1792,9 +1800,15 @@ status_t ResXMLTree::setTo(const void* data, size_t size, bool copyData) (int)dtohs(mHeader->header.headerSize), (int)dtohl(mHeader->header.size), (int)size); mError = BAD_TYPE; - restart(); - return mError; + goto done; } + if (dtohs(mHeader->header.type) != RES_XML_TYPE) { + ALOGW("Bad XML block: expected root block type %d, got %d\n", + int(RES_XML_TYPE), int(dtohs(mHeader->header.type))); + mError = BAD_TYPE; + goto done; + } + mDataEnd = ((const uint8_t*)mHeader) + mSize; mStrings.uninit(); @@ -1804,9 +1818,8 @@ status_t ResXMLTree::setTo(const void* data, size_t size, bool copyData) // First look for a couple interesting chunks: the string block // and first XML node. - const ResChunk_header* chunk = - (const ResChunk_header*)(((const uint8_t*)mHeader) + dtohs(mHeader->header.headerSize)); - const ResChunk_header* lastChunk = chunk; + chunk = (const ResChunk_header*)(((const uint8_t*)mHeader) + dtohs(mHeader->header.headerSize)); + lastChunk = chunk; while (((const uint8_t*)chunk) < (mDataEnd-sizeof(ResChunk_header)) && ((const uint8_t*)chunk) < (mDataEnd-dtohl(chunk->size))) { status_t err = validate_chunk(chunk, sizeof(ResChunk_header), mDataEnd, "XML"); @@ -1860,7 +1873,11 @@ status_t ResXMLTree::setTo(const void* data, size_t size, bool copyData) mError = mStrings.getError(); done: - restart(); + if (mError) { + uninit(); + } else { + restart(); + } return mError; } @@ -2551,6 +2568,22 @@ bool ResTable_config::isLocaleBetterThan(const ResTable_config& o, return false; } +bool ResTable_config::isBetterThanBeforeLocale(const ResTable_config& o, + const ResTable_config* requested) const { + if (requested) { + if (imsi || o.imsi) { + if ((mcc != o.mcc) && requested->mcc) { + return (mcc); + } + + if ((mnc != o.mnc) && requested->mnc) { + return (mnc); + } + } + } + return false; +} + bool ResTable_config::isBetterThan(const ResTable_config& o, const ResTable_config* requested) const { if (requested) { @@ -5436,37 +5469,66 @@ bool ResTable::stringToInt(const char16_t* s, size_t len, Res_value* outValue) return U16StringToInt(s, len, outValue); } -bool ResTable::stringToFloat(const char16_t* s, size_t len, Res_value* outValue) -{ - while (len > 0 && isspace16(*s)) { - s++; - len--; +template <typename T> +bool parseFloatingPoint(const char16_t* inBuf, size_t inLen, char* tempBuf, + const char** outEnd, T& out){ + while (inLen > 0 && isspace16(*inBuf)) { + inBuf++; + inLen--; } - if (len <= 0) { + if (inLen <= 0) { return false; } - char buf[128]; int i=0; - while (len > 0 && *s != 0 && i < 126) { - if (*s > 255) { + while (inLen > 0 && *inBuf != 0 && i < 126) { + if (*inBuf > 255) { return false; } - buf[i++] = *s++; - len--; + tempBuf[i++] = *inBuf++; + inLen--; } - if (len > 0) { + if (inLen > 0) { + return false; + } + if ((tempBuf[0] < '0' || tempBuf[0] > '9') && tempBuf[0] != '.' && tempBuf[0] != '-' && tempBuf[0] != '+') { return false; } - if ((buf[0] < '0' || buf[0] > '9') && buf[0] != '.' && buf[0] != '-' && buf[0] != '+') { + + tempBuf[i] = 0; + if constexpr(std::is_same_v<T, float>) { + out = strtof(tempBuf, (char**)outEnd); + } else { + out = strtod(tempBuf, (char**)outEnd); + } + return true; +} + +bool ResTable::stringToDouble(const char16_t* s, size_t len, double& d){ + char buf[128]; + const char* end = nullptr; + if (!parseFloatingPoint(s, len, buf, &end, d)) { return false; } - buf[i] = 0; - const char* end; - float f = strtof(buf, (char**)&end); + while (*end != 0 && isspace((unsigned char)*end)) { + end++; + } + + return *end == 0; +} + +bool ResTable::stringToFloat(const char16_t* s, size_t len, Res_value* outValue) +{ + char buf[128]; + const char* end = nullptr; + float f; + + if (!parseFloatingPoint(s, len, buf, &end, f)) { + return false; + } if (*end != 0 && !isspace((unsigned char)*end)) { // Might be a unit... diff --git a/libs/androidfw/ZipFileRO.cpp b/libs/androidfw/ZipFileRO.cpp index 52e7a70521a1..d7b5914130ee 100644 --- a/libs/androidfw/ZipFileRO.cpp +++ b/libs/androidfw/ZipFileRO.cpp @@ -40,17 +40,24 @@ class _ZipEntryRO { public: ZipEntry entry; std::string_view name; - void *cookie; + void *cookie = nullptr; - _ZipEntryRO() : cookie(NULL) {} + _ZipEntryRO() = default; ~_ZipEntryRO() { - EndIteration(cookie); + EndIteration(cookie); + } + + android::ZipEntryRO convertToPtr() { + _ZipEntryRO* result = new _ZipEntryRO; + result->entry = std::move(this->entry); + result->name = std::move(this->name); + result->cookie = std::exchange(this->cookie, nullptr); + return result; } private: - _ZipEntryRO(const _ZipEntryRO& other); - _ZipEntryRO& operator=(const _ZipEntryRO& other); + DISALLOW_COPY_AND_ASSIGN(_ZipEntryRO); }; ZipFileRO::~ZipFileRO() { @@ -94,17 +101,15 @@ ZipFileRO::~ZipFileRO() { ZipEntryRO ZipFileRO::findEntryByName(const char* entryName) const { - _ZipEntryRO* data = new _ZipEntryRO; - - data->name = entryName; + _ZipEntryRO data; + data.name = entryName; - const int32_t error = FindEntry(mHandle, entryName, &(data->entry)); + const int32_t error = FindEntry(mHandle, entryName, &(data.entry)); if (error) { - delete data; - return NULL; + return nullptr; } - return (ZipEntryRO) data; + return data.convertToPtr(); } /* @@ -143,35 +148,50 @@ bool ZipFileRO::getEntryInfo(ZipEntryRO entry, uint16_t* pMethod, } bool ZipFileRO::startIteration(void** cookie) { - return startIteration(cookie, NULL, NULL); + return startIteration(cookie, nullptr, nullptr); } -bool ZipFileRO::startIteration(void** cookie, const char* prefix, const char* suffix) -{ - _ZipEntryRO* ze = new _ZipEntryRO; - int32_t error = StartIteration(mHandle, &(ze->cookie), +bool ZipFileRO::startIteration(void** cookie, const char* prefix, const char* suffix) { + auto result = startIterationOrError(prefix, suffix); + if (!result.ok()) { + return false; + } + *cookie = result.value(); + return true; +} + +base::expected<void*, int32_t> +ZipFileRO::startIterationOrError(const char* prefix, const char* suffix) { + _ZipEntryRO ze; + int32_t error = StartIteration(mHandle, &(ze.cookie), prefix ? prefix : "", suffix ? suffix : ""); if (error) { ALOGW("Could not start iteration over %s: %s", mFileName != NULL ? mFileName : "<null>", ErrorCodeString(error)); - delete ze; - return false; + return base::unexpected(error); } - *cookie = ze; - return true; + return ze.convertToPtr(); } -ZipEntryRO ZipFileRO::nextEntry(void* cookie) -{ +ZipEntryRO ZipFileRO::nextEntry(void* cookie) { + auto result = nextEntryOrError(cookie); + if (!result.ok()) { + return nullptr; + } + return result.value(); +} + +base::expected<ZipEntryRO, int32_t> ZipFileRO::nextEntryOrError(void* cookie) { _ZipEntryRO* ze = reinterpret_cast<_ZipEntryRO*>(cookie); int32_t error = Next(ze->cookie, &(ze->entry), &(ze->name)); if (error) { if (error != -1) { ALOGW("Error iteration over %s: %s", mFileName != NULL ? mFileName : "<null>", ErrorCodeString(error)); + return base::unexpected(error); } - return NULL; + return nullptr; } return &(ze->entry); diff --git a/libs/androidfw/include/androidfw/ApkAssets.h b/libs/androidfw/include/androidfw/ApkAssets.h index 6f88f41976cd..1fa67528c78b 100644 --- a/libs/androidfw/include/androidfw/ApkAssets.h +++ b/libs/androidfw/include/androidfw/ApkAssets.h @@ -17,12 +17,13 @@ #ifndef APKASSETS_H_ #define APKASSETS_H_ +#include <utils/RefBase.h> + #include <memory> #include <string> #include "android-base/macros.h" #include "android-base/unique_fd.h" - #include "androidfw/Asset.h" #include "androidfw/AssetsProvider.h" #include "androidfw/Idmap.h" @@ -31,34 +32,33 @@ namespace android { +class ApkAssets; + +using ApkAssetsPtr = sp<ApkAssets>; + // Holds an APK. -class ApkAssets { +class ApkAssets : public RefBase { public: // Creates an ApkAssets from a path on device. - static std::unique_ptr<ApkAssets> Load(const std::string& path, - package_property_t flags = 0U); + static ApkAssetsPtr Load(const std::string& path, package_property_t flags = 0U); // Creates an ApkAssets from an open file descriptor. - static std::unique_ptr<ApkAssets> LoadFromFd(base::unique_fd fd, - const std::string& debug_name, - package_property_t flags = 0U, - off64_t offset = 0, - off64_t len = AssetsProvider::kUnknownLength); + static ApkAssetsPtr LoadFromFd(base::unique_fd fd, const std::string& debug_name, + package_property_t flags = 0U, off64_t offset = 0, + off64_t len = AssetsProvider::kUnknownLength); // Creates an ApkAssets from an AssetProvider. // The ApkAssets will take care of destroying the AssetsProvider when it is destroyed. - static std::unique_ptr<ApkAssets> Load(std::unique_ptr<AssetsProvider> assets, - package_property_t flags = 0U); + static ApkAssetsPtr Load(std::unique_ptr<AssetsProvider> assets, package_property_t flags = 0U); // Creates an ApkAssets from the given asset file representing a resources.arsc. - static std::unique_ptr<ApkAssets> LoadTable(std::unique_ptr<Asset> resources_asset, - std::unique_ptr<AssetsProvider> assets, - package_property_t flags = 0U); + static ApkAssetsPtr LoadTable(std::unique_ptr<Asset> resources_asset, + std::unique_ptr<AssetsProvider> assets, + package_property_t flags = 0U); // Creates an ApkAssets from an IDMAP, which contains the original APK path, and the overlay // data. - static std::unique_ptr<ApkAssets> LoadOverlay(const std::string& idmap_path, - package_property_t flags = 0U); + static ApkAssetsPtr LoadOverlay(const std::string& idmap_path, package_property_t flags = 0U); // Path to the contents of the ApkAssets on disk. The path could represent an APk, a directory, // or some other file type. @@ -95,22 +95,27 @@ class ApkAssets { bool IsUpToDate() const; private: - static std::unique_ptr<ApkAssets> LoadImpl(std::unique_ptr<AssetsProvider> assets, - package_property_t property_flags, - std::unique_ptr<Asset> idmap_asset, - std::unique_ptr<LoadedIdmap> loaded_idmap); - - static std::unique_ptr<ApkAssets> LoadImpl(std::unique_ptr<Asset> resources_asset, - std::unique_ptr<AssetsProvider> assets, - package_property_t property_flags, - std::unique_ptr<Asset> idmap_asset, - std::unique_ptr<LoadedIdmap> loaded_idmap); - - ApkAssets(std::unique_ptr<Asset> resources_asset, - std::unique_ptr<LoadedArsc> loaded_arsc, - std::unique_ptr<AssetsProvider> assets, - package_property_t property_flags, - std::unique_ptr<Asset> idmap_asset, + static ApkAssetsPtr LoadImpl(std::unique_ptr<AssetsProvider> assets, + package_property_t property_flags, + std::unique_ptr<Asset> idmap_asset, + std::unique_ptr<LoadedIdmap> loaded_idmap); + + static ApkAssetsPtr LoadImpl(std::unique_ptr<Asset> resources_asset, + std::unique_ptr<AssetsProvider> assets, + package_property_t property_flags, + std::unique_ptr<Asset> idmap_asset, + std::unique_ptr<LoadedIdmap> loaded_idmap); + + // Allows us to make it possible to call make_shared from inside the class but still keeps the + // ctor 'private' for all means and purposes. + struct PrivateConstructorUtil { + explicit PrivateConstructorUtil() = default; + }; + + public: + ApkAssets(PrivateConstructorUtil, std::unique_ptr<Asset> resources_asset, + std::unique_ptr<LoadedArsc> loaded_arsc, std::unique_ptr<AssetsProvider> assets, + package_property_t property_flags, std::unique_ptr<Asset> idmap_asset, std::unique_ptr<LoadedIdmap> loaded_idmap); std::unique_ptr<Asset> resources_asset_; diff --git a/libs/androidfw/include/androidfw/AssetManager2.h b/libs/androidfw/include/androidfw/AssetManager2.h index f10cb9bf480a..d9ff35b49e0a 100644 --- a/libs/androidfw/include/androidfw/AssetManager2.h +++ b/libs/androidfw/include/androidfw/AssetManager2.h @@ -17,14 +17,16 @@ #ifndef ANDROIDFW_ASSETMANAGER2_H_ #define ANDROIDFW_ASSETMANAGER2_H_ -#include "android-base/function_ref.h" -#include "android-base/macros.h" +#include <utils/RefBase.h> #include <array> #include <limits> #include <set> +#include <span> #include <unordered_map> +#include "android-base/function_ref.h" +#include "android-base/macros.h" #include "androidfw/ApkAssets.h" #include "androidfw/Asset.h" #include "androidfw/AssetManager.h" @@ -94,8 +96,25 @@ class AssetManager2 { size_t entry_len = 0u; }; + using ApkAssetsPtr = sp<const ApkAssets>; + using ApkAssetsWPtr = wp<const ApkAssets>; + using ApkAssetsList = std::span<const ApkAssetsPtr>; + AssetManager2(); explicit AssetManager2(AssetManager2&& other) = default; + AssetManager2(ApkAssetsList apk_assets, const ResTable_config& configuration); + + struct ScopedOperation { + DISALLOW_COPY_AND_ASSIGN(ScopedOperation); + friend AssetManager2; + const AssetManager2& am_; + ScopedOperation(const AssetManager2& am); + + public: + ~ScopedOperation(); + }; + + [[nodiscard]] ScopedOperation StartOperation() const; // Sets/resets the underlying ApkAssets for this AssetManager. The ApkAssets // are not owned by the AssetManager, and must have a longer lifetime. @@ -103,10 +122,12 @@ class AssetManager2 { // Only pass invalidate_caches=false when it is known that the structure // change in ApkAssets is due to a safe addition of resources with completely // new resource IDs. - bool SetApkAssets(std::vector<const ApkAssets*> apk_assets, bool invalidate_caches = true); + bool SetApkAssets(ApkAssetsList apk_assets, bool invalidate_caches = true); + bool SetApkAssets(std::initializer_list<ApkAssetsPtr> apk_assets, bool invalidate_caches = true); - inline const std::vector<const ApkAssets*>& GetApkAssets() const { - return apk_assets_; + const ApkAssetsPtr& GetApkAssets(ApkAssetsCookie cookie) const; + int GetApkAssetsCount() const { + return int(apk_assets_.size()); } // Returns the string pool for the given asset cookie. @@ -135,10 +156,14 @@ class AssetManager2 { // Sets/resets the configuration for this AssetManager. This will cause all // caches that are related to the configuration change to be invalidated. - void SetConfiguration(const ResTable_config& configuration); + void SetConfigurations(std::vector<ResTable_config> configurations); - inline const ResTable_config& GetConfiguration() const { - return configuration_; + inline const std::vector<ResTable_config>& GetConfigurations() const { + return configurations_; + } + + inline void SetDefaultLocale(uint32_t default_locale) { + default_locale_ = default_locale; } // Returns all configurations for which there are resources defined, or an I/O error if reading @@ -222,9 +247,14 @@ class AssetManager2 { friend AssetManager2; friend Theme; SelectedValue() = default; - SelectedValue(const ResolvedBag* bag, const ResolvedBag::Entry& entry) : - cookie(entry.cookie), data(entry.value.data), type(entry.value.dataType), - flags(bag->type_spec_flags), resid(0U), config({}) {}; + SelectedValue(const ResolvedBag* bag, const ResolvedBag::Entry& entry) + : cookie(entry.cookie), + data(entry.value.data), + type(entry.value.dataType), + flags(bag->type_spec_flags), + resid(0U), + config() { + } // The cookie representing the ApkAssets in which the value resides. ApkAssetsCookie cookie = kInvalidCookie; @@ -306,7 +336,8 @@ class AssetManager2 { // resource data failed. base::expected<uint32_t, NullOrIOError> GetResourceTypeSpecFlags(uint32_t resid) const; - const std::vector<uint32_t> GetBagResIdStack(uint32_t resid) const; + base::expected<const std::vector<uint32_t>*, NullOrIOError> GetBagResIdStack( + uint32_t resid) const; // Resets the resource resolution structures in preparation for the next resource retrieval. void ResetResourceResolution() const; @@ -399,7 +430,7 @@ class AssetManager2 { // Assigns package IDs to all shared library ApkAssets. // Should be called whenever the ApkAssets are changed. - void BuildDynamicRefTable(); + void BuildDynamicRefTable(ApkAssetsList assets); // Purge all resources that are cached and vary by the configuration axis denoted by the // bitmask `diff`. @@ -410,16 +441,23 @@ class AssetManager2 { void RebuildFilterList(); // Retrieves the APK paths of overlays that overlay non-system packages. - std::set<const ApkAssets*> GetNonSystemOverlays() const; + std::set<ApkAssetsPtr> GetNonSystemOverlays() const; // AssetManager2::GetBag(resid) wraps this function to track which resource ids have already // been seen while traversing bag parents. base::expected<const ResolvedBag*, NullOrIOError> GetBag( uint32_t resid, std::vector<uint32_t>& child_resids) const; + // Finish an operation that was running with the current asset manager, and clean up the + // promoted apk assets when the last operation ends. + void FinishOperation() const; + // The ordered list of ApkAssets to search. These are not owned by the AssetManager, and must // have a longer lifetime. - std::vector<const ApkAssets*> apk_assets_; + // The second pair element is the promoted version of the assets, that is held for the duration + // of the currently running operation. FinishOperation() clears all promoted assets to make sure + // they can be released when the system needs that. + mutable std::vector<std::pair<ApkAssetsWPtr, ApkAssetsPtr>> apk_assets_; // DynamicRefTables for shared library package resolution. // These are ordered according to apk_assets_. The mappings may change depending on what is @@ -431,9 +469,11 @@ class AssetManager2 { // without taking too much memory. std::array<uint8_t, std::numeric_limits<uint8_t>::max() + 1> package_ids_; - // The current configuration set for this AssetManager. When this changes, cached resources + uint32_t default_locale_; + + // The current configurations set for this AssetManager. When this changes, cached resources // may need to be purged. - ResTable_config configuration_; + std::vector<ResTable_config> configurations_; // Cached set of bags. These are cached because they can inherit keys from parent bags, // which involves some calculation. @@ -446,6 +486,10 @@ class AssetManager2 { // Cached set of resolved resource values. mutable std::unordered_map<uint32_t, SelectedValue> cached_resolved_values_; + // Tracking the number of the started operations running with the current AssetManager. + // Finishing the last one clears all promoted apk assets. + mutable int number_of_running_scoped_operations_ = 0; + // Whether or not to save resource resolution steps bool resource_resolution_logging_enabled_ = false; @@ -463,10 +507,10 @@ class AssetManager2 { // Marks what kind of override this step was. Type type; + ApkAssetsCookie cookie = kInvalidCookie; + // Built name of configuration for this step. String8 config_name; - - ApkAssetsCookie cookie = kInvalidCookie; }; // Last resolved resource ID. diff --git a/libs/androidfw/include/androidfw/Errors.h b/libs/androidfw/include/androidfw/Errors.h index 948162d10480..6667747fc581 100644 --- a/libs/androidfw/include/androidfw/Errors.h +++ b/libs/androidfw/include/androidfw/Errors.h @@ -34,7 +34,7 @@ using NullOrIOError = std::variant<std::nullopt_t, IOError>; // Checks whether the result holds an unexpected I/O error. template <typename T> -static inline bool IsIOError(const base::expected<T, NullOrIOError> result) { +static inline bool IsIOError(const base::expected<T, NullOrIOError>& result) { return !result.has_value() && std::holds_alternative<IOError>(result.error()); } diff --git a/libs/androidfw/include/androidfw/IDiagnostics.h b/libs/androidfw/include/androidfw/IDiagnostics.h index 4d5844eaa069..865a298f8389 100644 --- a/libs/androidfw/include/androidfw/IDiagnostics.h +++ b/libs/androidfw/include/androidfw/IDiagnostics.h @@ -86,6 +86,17 @@ struct IDiagnostics { DiagMessageActual actual = message.Build(); Log(Level::Note, actual); } + + virtual void SetVerbose(bool val) { + verbose_ = val; + } + + virtual bool IsVerbose() { + return verbose_; + } + + private: + bool verbose_ = false; }; class SourcePathDiagnostics : public IDiagnostics { @@ -105,6 +116,14 @@ class SourcePathDiagnostics : public IDiagnostics { return error; } + void SetVerbose(bool val) override { + diag_->SetVerbose(val); + } + + bool IsVerbose() override { + return diag_->IsVerbose(); + } + private: Source source_; IDiagnostics* diag_; diff --git a/libs/androidfw/include/androidfw/LoadedArsc.h b/libs/androidfw/include/androidfw/LoadedArsc.h index 4d12885ad291..3a7287187781 100644 --- a/libs/androidfw/include/androidfw/LoadedArsc.h +++ b/libs/androidfw/include/androidfw/LoadedArsc.h @@ -96,6 +96,9 @@ enum : package_property_t { // The apk assets is owned by the application running in this process and incremental crash // protections for this APK must be disabled. PROPERTY_DISABLE_INCREMENTAL_HARDENING = 1U << 4U, + + // The apk assets only contain the overlayable declarations information. + PROPERTY_ONLY_OVERLAYABLES = 1U << 5U, }; struct OverlayableInfo { diff --git a/libs/androidfw/include/androidfw/MutexGuard.h b/libs/androidfw/include/androidfw/MutexGuard.h index 6fc6d64e2f6e..b6093dbb6d3d 100644 --- a/libs/androidfw/include/androidfw/MutexGuard.h +++ b/libs/androidfw/include/androidfw/MutexGuard.h @@ -14,12 +14,12 @@ * limitations under the License. */ -#ifndef ANDROIDFW_MUTEXGUARD_H -#define ANDROIDFW_MUTEXGUARD_H +#pragma once #include <mutex> #include <optional> #include <type_traits> +#include <utility> #include "android-base/macros.h" @@ -45,20 +45,25 @@ class ScopedLock; // template <typename T> class Guarded { - static_assert(!std::is_pointer<T>::value, "T must not be a raw pointer"); + static_assert(!std::is_pointer_v<T>, "T must not be a raw pointer"); public: - Guarded() : guarded_(std::in_place, T()) { + Guarded() : guarded_(std::in_place) { } explicit Guarded(const T& guarded) : guarded_(std::in_place, guarded) { } - explicit Guarded(T&& guarded) : guarded_(std::in_place, std::forward<T>(guarded)) { + explicit Guarded(T&& guarded) : guarded_(std::in_place, std::move(guarded)) { } - ~Guarded() { - std::lock_guard<std::mutex> scoped_lock(lock_); + // Unfortunately, some legacy designs make even class deletion race-prone, where some other + // thread may have not finished working with the same object. For those cases one may destroy the + // object under a lock (but please fix your code, at least eventually!). + template <class Func> + void safeDelete(Func f) { + std::lock_guard scoped_lock(lock_); + f(guarded_ ? &guarded_.value() : nullptr); guarded_.reset(); } @@ -96,5 +101,3 @@ class ScopedLock { }; } // namespace android - -#endif // ANDROIDFW_MUTEXGUARD_H diff --git a/libs/androidfw/include/androidfw/ResourceTypes.h b/libs/androidfw/include/androidfw/ResourceTypes.h index 631bda4f886c..52666ab8d1d5 100644 --- a/libs/androidfw/include/androidfw/ResourceTypes.h +++ b/libs/androidfw/include/androidfw/ResourceTypes.h @@ -1375,6 +1375,8 @@ struct ResTable_config // match the requested configuration at all. bool isLocaleBetterThan(const ResTable_config& o, const ResTable_config* requested) const; + bool isBetterThanBeforeLocale(const ResTable_config& o, const ResTable_config* requested) const; + String8 toString() const; }; @@ -2162,6 +2164,7 @@ public: static bool stringToInt(const char16_t* s, size_t len, Res_value* outValue); static bool stringToFloat(const char16_t* s, size_t len, Res_value* outValue); + static bool stringToDouble(const char16_t* s, size_t len, double& outValue); // Used with stringToValue. class Accessor diff --git a/libs/androidfw/include/androidfw/ZipFileRO.h b/libs/androidfw/include/androidfw/ZipFileRO.h index 10f6d0655bf4..be1f98f4843d 100644 --- a/libs/androidfw/include/androidfw/ZipFileRO.h +++ b/libs/androidfw/include/androidfw/ZipFileRO.h @@ -37,6 +37,8 @@ #include <unistd.h> #include <time.h> +#include <android-base/expected.h> + #include <util/map_ptr.h> #include <utils/Compat.h> @@ -102,6 +104,11 @@ public: */ bool startIteration(void** cookie); bool startIteration(void** cookie, const char* prefix, const char* suffix); + /* + * Same as above, but returns the error code in case of failure. + * #see libziparchive/zip_error.h. + */ + base::expected<void*, int32_t> startIterationOrError(const char* prefix, const char* suffix); /** * Return the next entry in iteration order, or NULL if there are no more @@ -109,6 +116,12 @@ public: */ ZipEntryRO nextEntry(void* cookie); + /** + * Same as above, but returns the error code in case of failure. + * #see libziparchive/zip_error.h. + */ + base::expected<ZipEntryRO, int32_t> nextEntryOrError(void* cookie); + void endIteration(void* cookie); void releaseEntry(ZipEntryRO entry) const; diff --git a/libs/androidfw/tests/ApkAssets_test.cpp b/libs/androidfw/tests/ApkAssets_test.cpp index 19db25ce8811..70326b71da28 100644 --- a/libs/androidfw/tests/ApkAssets_test.cpp +++ b/libs/androidfw/tests/ApkAssets_test.cpp @@ -35,8 +35,7 @@ using ::testing::StrEq; namespace android { TEST(ApkAssetsTest, LoadApk) { - std::unique_ptr<const ApkAssets> loaded_apk = - ApkAssets::Load(GetTestDataPath() + "/basic/basic.apk"); + auto loaded_apk = ApkAssets::Load(GetTestDataPath() + "/basic/basic.apk"); ASSERT_THAT(loaded_apk, NotNull()); const LoadedArsc* loaded_arsc = loaded_apk->GetLoadedArsc(); @@ -50,7 +49,7 @@ TEST(ApkAssetsTest, LoadApkFromFd) { unique_fd fd(::open(path.c_str(), O_RDONLY | O_BINARY)); ASSERT_THAT(fd.get(), Ge(0)); - std::unique_ptr<const ApkAssets> loaded_apk = ApkAssets::LoadFromFd(std::move(fd), path); + auto loaded_apk = ApkAssets::LoadFromFd(std::move(fd), path); ASSERT_THAT(loaded_apk, NotNull()); const LoadedArsc* loaded_arsc = loaded_apk->GetLoadedArsc(); @@ -60,8 +59,7 @@ TEST(ApkAssetsTest, LoadApkFromFd) { } TEST(ApkAssetsTest, LoadApkAsSharedLibrary) { - std::unique_ptr<const ApkAssets> loaded_apk = - ApkAssets::Load(GetTestDataPath() + "/appaslib/appaslib.apk"); + auto loaded_apk = ApkAssets::Load(GetTestDataPath() + "/appaslib/appaslib.apk"); ASSERT_THAT(loaded_apk, NotNull()); const LoadedArsc* loaded_arsc = loaded_apk->GetLoadedArsc(); @@ -79,8 +77,7 @@ TEST(ApkAssetsTest, LoadApkAsSharedLibrary) { } TEST(ApkAssetsTest, CreateAndDestroyAssetKeepsApkAssetsOpen) { - std::unique_ptr<const ApkAssets> loaded_apk = - ApkAssets::Load(GetTestDataPath() + "/basic/basic.apk"); + auto loaded_apk = ApkAssets::Load(GetTestDataPath() + "/basic/basic.apk"); ASSERT_THAT(loaded_apk, NotNull()); { ASSERT_THAT(loaded_apk->GetAssetsProvider()->Open("res/layout/main.xml", @@ -91,8 +88,7 @@ TEST(ApkAssetsTest, CreateAndDestroyAssetKeepsApkAssetsOpen) { } TEST(ApkAssetsTest, OpenUncompressedAssetFd) { - std::unique_ptr<const ApkAssets> loaded_apk = - ApkAssets::Load(GetTestDataPath() + "/basic/basic.apk"); + auto loaded_apk = ApkAssets::Load(GetTestDataPath() + "/basic/basic.apk"); ASSERT_THAT(loaded_apk, NotNull()); auto asset = loaded_apk->GetAssetsProvider()->Open("assets/uncompressed.txt", diff --git a/libs/androidfw/tests/ApkParsing_test.cpp b/libs/androidfw/tests/ApkParsing_test.cpp index 62e88c619e5c..ac1dc9b88463 100644 --- a/libs/androidfw/tests/ApkParsing_test.cpp +++ b/libs/androidfw/tests/ApkParsing_test.cpp @@ -74,4 +74,10 @@ TEST(ApkParsingTest, InvalidFileAtRoot) { auto lastSlash = util::ValidLibraryPathLastSlash(path, false, false); ASSERT_THAT(lastSlash, IsNull()); } + +TEST(ApkParsingTest, InvalidPrefix) { + const char* path = "assets/libhello.so"; + auto lastSlash = util::ValidLibraryPathLastSlash(path, false, false); + ASSERT_THAT(lastSlash, IsNull()); +} }
\ No newline at end of file diff --git a/libs/androidfw/tests/AssetManager2_bench.cpp b/libs/androidfw/tests/AssetManager2_bench.cpp index c7ae618991b9..2caa98c35971 100644 --- a/libs/androidfw/tests/AssetManager2_bench.cpp +++ b/libs/androidfw/tests/AssetManager2_bench.cpp @@ -38,9 +38,9 @@ constexpr const static char* kFrameworkPath = "/system/framework/framework-res.a static void BM_AssetManagerLoadAssets(benchmark::State& state) { std::string path = GetTestDataPath() + "/basic/basic.apk"; while (state.KeepRunning()) { - std::unique_ptr<const ApkAssets> apk = ApkAssets::Load(path); + auto apk = ApkAssets::Load(path); AssetManager2 assets; - assets.SetApkAssets({apk.get()}); + assets.SetApkAssets({apk}); } } BENCHMARK(BM_AssetManagerLoadAssets); @@ -61,9 +61,9 @@ BENCHMARK(BM_AssetManagerLoadAssetsOld); static void BM_AssetManagerLoadFrameworkAssets(benchmark::State& state) { std::string path = kFrameworkPath; while (state.KeepRunning()) { - std::unique_ptr<const ApkAssets> apk = ApkAssets::Load(path); + auto apk = ApkAssets::Load(path); AssetManager2 assets; - assets.SetApkAssets({apk.get()}); + assets.SetApkAssets({apk}); } } BENCHMARK(BM_AssetManagerLoadFrameworkAssets); @@ -129,14 +129,14 @@ static void BM_AssetManagerGetResourceFrameworkLocaleOld(benchmark::State& state BENCHMARK(BM_AssetManagerGetResourceFrameworkLocaleOld); static void BM_AssetManagerGetBag(benchmark::State& state) { - std::unique_ptr<const ApkAssets> apk = ApkAssets::Load(GetTestDataPath() + "/styles/styles.apk"); + auto apk = ApkAssets::Load(GetTestDataPath() + "/styles/styles.apk"); if (apk == nullptr) { state.SkipWithError("Failed to load assets"); return; } AssetManager2 assets; - assets.SetApkAssets({apk.get()}); + assets.SetApkAssets({apk}); while (state.KeepRunning()) { auto bag = assets.GetBag(app::R::style::StyleTwo); @@ -181,14 +181,14 @@ static void BM_AssetManagerGetBagOld(benchmark::State& state) { BENCHMARK(BM_AssetManagerGetBagOld); static void BM_AssetManagerGetResourceLocales(benchmark::State& state) { - std::unique_ptr<const ApkAssets> apk = ApkAssets::Load(kFrameworkPath); + auto apk = ApkAssets::Load(kFrameworkPath); if (apk == nullptr) { state.SkipWithError("Failed to load assets"); return; } AssetManager2 assets; - assets.SetApkAssets({apk.get()}); + assets.SetApkAssets({apk}); while (state.KeepRunning()) { std::set<std::string> locales = @@ -217,21 +217,23 @@ static void BM_AssetManagerGetResourceLocalesOld(benchmark::State& state) { BENCHMARK(BM_AssetManagerGetResourceLocalesOld); static void BM_AssetManagerSetConfigurationFramework(benchmark::State& state) { - std::unique_ptr<const ApkAssets> apk = ApkAssets::Load(kFrameworkPath); + auto apk = ApkAssets::Load(kFrameworkPath); if (apk == nullptr) { state.SkipWithError("Failed to load assets"); return; } AssetManager2 assets; - assets.SetApkAssets({apk.get()}); + assets.SetApkAssets({apk}); ResTable_config config; memset(&config, 0, sizeof(config)); + std::vector<ResTable_config> configs; + configs.push_back(config); while (state.KeepRunning()) { - config.sdkVersion = ~config.sdkVersion; - assets.SetConfiguration(config); + configs[0].sdkVersion = ~configs[0].sdkVersion; + assets.SetConfigurations(configs); } } BENCHMARK(BM_AssetManagerSetConfigurationFramework); diff --git a/libs/androidfw/tests/AssetManager2_test.cpp b/libs/androidfw/tests/AssetManager2_test.cpp index 4394740e44ba..c62f095e9dac 100644 --- a/libs/androidfw/tests/AssetManager2_test.cpp +++ b/libs/androidfw/tests/AssetManager2_test.cpp @@ -91,19 +91,19 @@ class AssetManager2Test : public ::testing::Test { } protected: - std::unique_ptr<const ApkAssets> basic_assets_; - std::unique_ptr<const ApkAssets> basic_de_fr_assets_; - std::unique_ptr<const ApkAssets> basic_xhdpi_assets_; - std::unique_ptr<const ApkAssets> basic_xxhdpi_assets_; - std::unique_ptr<const ApkAssets> style_assets_; - std::unique_ptr<const ApkAssets> lib_one_assets_; - std::unique_ptr<const ApkAssets> lib_two_assets_; - std::unique_ptr<const ApkAssets> libclient_assets_; - std::unique_ptr<const ApkAssets> appaslib_assets_; - std::unique_ptr<const ApkAssets> system_assets_; - std::unique_ptr<const ApkAssets> app_assets_; - std::unique_ptr<const ApkAssets> overlay_assets_; - std::unique_ptr<const ApkAssets> overlayable_assets_; + AssetManager2::ApkAssetsPtr basic_assets_; + AssetManager2::ApkAssetsPtr basic_de_fr_assets_; + AssetManager2::ApkAssetsPtr basic_xhdpi_assets_; + AssetManager2::ApkAssetsPtr basic_xxhdpi_assets_; + AssetManager2::ApkAssetsPtr style_assets_; + AssetManager2::ApkAssetsPtr lib_one_assets_; + AssetManager2::ApkAssetsPtr lib_two_assets_; + AssetManager2::ApkAssetsPtr libclient_assets_; + AssetManager2::ApkAssetsPtr appaslib_assets_; + AssetManager2::ApkAssetsPtr system_assets_; + AssetManager2::ApkAssetsPtr app_assets_; + AssetManager2::ApkAssetsPtr overlay_assets_; + AssetManager2::ApkAssetsPtr overlayable_assets_; }; TEST_F(AssetManager2Test, FindsResourceFromSingleApkAssets) { @@ -113,8 +113,8 @@ TEST_F(AssetManager2Test, FindsResourceFromSingleApkAssets) { desired_config.language[1] = 'e'; AssetManager2 assetmanager; - assetmanager.SetConfiguration(desired_config); - assetmanager.SetApkAssets({basic_assets_.get()}); + assetmanager.SetConfigurations({desired_config}); + assetmanager.SetApkAssets({basic_assets_}); auto value = assetmanager.GetResource(basic::R::string::test1); ASSERT_TRUE(value.has_value()); @@ -137,8 +137,8 @@ TEST_F(AssetManager2Test, FindsResourceFromMultipleApkAssets) { desired_config.language[1] = 'e'; AssetManager2 assetmanager; - assetmanager.SetConfiguration(desired_config); - assetmanager.SetApkAssets({basic_assets_.get(), basic_de_fr_assets_.get()}); + assetmanager.SetConfigurations({desired_config}); + assetmanager.SetApkAssets({basic_assets_, basic_de_fr_assets_}); auto value = assetmanager.GetResource(basic::R::string::test1); ASSERT_TRUE(value.has_value()); @@ -159,8 +159,7 @@ TEST_F(AssetManager2Test, FindsResourceFromSharedLibrary) { // libclient is built with lib_one and then lib_two in order. // Reverse the order to test that proper package ID re-assignment is happening. - assetmanager.SetApkAssets( - {lib_two_assets_.get(), lib_one_assets_.get(), libclient_assets_.get()}); + assetmanager.SetApkAssets({lib_two_assets_, lib_one_assets_, libclient_assets_}); auto value = assetmanager.GetResource(libclient::R::string::foo_one); ASSERT_TRUE(value.has_value()); @@ -195,7 +194,7 @@ TEST_F(AssetManager2Test, FindsResourceFromSharedLibrary) { TEST_F(AssetManager2Test, FindsResourceFromAppLoadedAsSharedLibrary) { AssetManager2 assetmanager; - assetmanager.SetApkAssets({appaslib_assets_.get()}); + assetmanager.SetApkAssets({appaslib_assets_}); // The appaslib package will have been assigned the package ID 0x02. auto value = assetmanager.GetResource(fix_package_id(appaslib::R::integer::number1, 0x02)); @@ -206,27 +205,26 @@ TEST_F(AssetManager2Test, FindsResourceFromAppLoadedAsSharedLibrary) { TEST_F(AssetManager2Test, AssignsOverlayPackageIdLast) { AssetManager2 assetmanager; - assetmanager.SetApkAssets( - {overlayable_assets_.get(), overlay_assets_.get(), lib_one_assets_.get()}); + assetmanager.SetApkAssets({overlayable_assets_, overlay_assets_, lib_one_assets_}); - auto apk_assets = assetmanager.GetApkAssets(); - ASSERT_EQ(3, apk_assets.size()); - ASSERT_EQ(overlayable_assets_.get(), apk_assets[0]); - ASSERT_EQ(overlay_assets_.get(), apk_assets[1]); - ASSERT_EQ(lib_one_assets_.get(), apk_assets[2]); + ASSERT_EQ(3, assetmanager.GetApkAssetsCount()); + auto op = assetmanager.StartOperation(); + ASSERT_EQ(overlayable_assets_, assetmanager.GetApkAssets(0)); + ASSERT_EQ(overlay_assets_, assetmanager.GetApkAssets(1)); + ASSERT_EQ(lib_one_assets_, assetmanager.GetApkAssets(2)); - auto get_first_package_id = [&assetmanager](const ApkAssets* apkAssets) -> uint8_t { + auto get_first_package_id = [&assetmanager](auto apkAssets) -> uint8_t { return assetmanager.GetAssignedPackageId(apkAssets->GetLoadedArsc()->GetPackages()[0].get()); }; - ASSERT_EQ(0x7f, get_first_package_id(overlayable_assets_.get())); - ASSERT_EQ(0x03, get_first_package_id(overlay_assets_.get())); - ASSERT_EQ(0x02, get_first_package_id(lib_one_assets_.get())); + ASSERT_EQ(0x7f, get_first_package_id(overlayable_assets_)); + ASSERT_EQ(0x03, get_first_package_id(overlay_assets_)); + ASSERT_EQ(0x02, get_first_package_id(lib_one_assets_)); } TEST_F(AssetManager2Test, GetSharedLibraryResourceName) { AssetManager2 assetmanager; - assetmanager.SetApkAssets({lib_one_assets_.get()}); + assetmanager.SetApkAssets({lib_one_assets_}); auto name = assetmanager.GetResourceName(lib_one::R::string::foo); ASSERT_TRUE(name.has_value()); @@ -235,7 +233,7 @@ TEST_F(AssetManager2Test, GetSharedLibraryResourceName) { TEST_F(AssetManager2Test, GetResourceNameNonMatchingConfig) { AssetManager2 assetmanager; - assetmanager.SetApkAssets({basic_de_fr_assets_.get()}); + assetmanager.SetApkAssets({basic_de_fr_assets_}); auto value = assetmanager.GetResourceName(basic::R::string::test1); ASSERT_TRUE(value.has_value()); @@ -244,7 +242,7 @@ TEST_F(AssetManager2Test, GetResourceNameNonMatchingConfig) { TEST_F(AssetManager2Test, GetResourceTypeSpecFlags) { AssetManager2 assetmanager; - assetmanager.SetApkAssets({basic_de_fr_assets_.get()}); + assetmanager.SetApkAssets({basic_de_fr_assets_}); auto value = assetmanager.GetResourceTypeSpecFlags(basic::R::string::test1); ASSERT_TRUE(value.has_value()); @@ -253,7 +251,7 @@ TEST_F(AssetManager2Test, GetResourceTypeSpecFlags) { TEST_F(AssetManager2Test, FindsBagResourceFromSingleApkAssets) { AssetManager2 assetmanager; - assetmanager.SetApkAssets({basic_assets_.get()}); + assetmanager.SetApkAssets({basic_assets_}); auto bag = assetmanager.GetBag(basic::R::array::integerArray1); ASSERT_TRUE(bag.has_value()); @@ -280,8 +278,7 @@ TEST_F(AssetManager2Test, FindsBagResourceFromSharedLibrary) { // libclient is built with lib_one and then lib_two in order. // Reverse the order to test that proper package ID re-assignment is happening. - assetmanager.SetApkAssets( - {lib_two_assets_.get(), lib_one_assets_.get(), libclient_assets_.get()}); + assetmanager.SetApkAssets({lib_two_assets_, lib_one_assets_, libclient_assets_}); auto bag = assetmanager.GetBag(fix_package_id(lib_one::R::style::Theme, 0x03)); ASSERT_TRUE(bag.has_value()); @@ -300,8 +297,7 @@ TEST_F(AssetManager2Test, FindsBagResourceFromMultipleSharedLibraries) { // libclient is built with lib_one and then lib_two in order. // Reverse the order to test that proper package ID re-assignment is happening. - assetmanager.SetApkAssets( - {lib_two_assets_.get(), lib_one_assets_.get(), libclient_assets_.get()}); + assetmanager.SetApkAssets({lib_two_assets_, lib_one_assets_, libclient_assets_}); auto bag = assetmanager.GetBag(libclient::R::style::ThemeMultiLib); ASSERT_TRUE(bag.has_value()); @@ -321,8 +317,7 @@ TEST_F(AssetManager2Test, FindsStyleResourceWithParentFromSharedLibrary) { // libclient is built with lib_one and then lib_two in order. // Reverse the order to test that proper package ID re-assignment is happening. - assetmanager.SetApkAssets( - {lib_two_assets_.get(), lib_one_assets_.get(), libclient_assets_.get()}); + assetmanager.SetApkAssets({lib_two_assets_, lib_one_assets_, libclient_assets_}); auto bag = assetmanager.GetBag(libclient::R::style::Theme); ASSERT_TRUE(bag.has_value()); @@ -337,7 +332,7 @@ TEST_F(AssetManager2Test, FindsStyleResourceWithParentFromSharedLibrary) { TEST_F(AssetManager2Test, MergesStylesWithParentFromSingleApkAssets) { AssetManager2 assetmanager; - assetmanager.SetApkAssets({style_assets_.get()}); + assetmanager.SetApkAssets({style_assets_}); auto bag_one = assetmanager.GetBag(app::R::style::StyleOne); ASSERT_TRUE(bag_one.has_value()); @@ -401,7 +396,7 @@ TEST_F(AssetManager2Test, MergesStylesWithParentFromSingleApkAssets) { TEST_F(AssetManager2Test, MergeStylesCircularDependency) { AssetManager2 assetmanager; - assetmanager.SetApkAssets({style_assets_.get()}); + assetmanager.SetApkAssets({style_assets_}); // GetBag should stop traversing the parents of styles when a circular // dependency is detected @@ -412,7 +407,7 @@ TEST_F(AssetManager2Test, MergeStylesCircularDependency) { TEST_F(AssetManager2Test, ResolveReferenceToResource) { AssetManager2 assetmanager; - assetmanager.SetApkAssets({basic_assets_.get()}); + assetmanager.SetApkAssets({basic_assets_}); auto value = assetmanager.GetResource(basic::R::integer::ref1); ASSERT_TRUE(value.has_value()); @@ -428,7 +423,7 @@ TEST_F(AssetManager2Test, ResolveReferenceToResource) { TEST_F(AssetManager2Test, ResolveReferenceToBag) { AssetManager2 assetmanager; - assetmanager.SetApkAssets({basic_assets_.get()}); + assetmanager.SetApkAssets({basic_assets_}); auto value = assetmanager.GetResource(basic::R::integer::number2, true /*may_be_bag*/); ASSERT_TRUE(value.has_value()); @@ -444,7 +439,7 @@ TEST_F(AssetManager2Test, ResolveReferenceToBag) { TEST_F(AssetManager2Test, ResolveDeepIdReference) { AssetManager2 assetmanager; - assetmanager.SetApkAssets({basic_assets_.get()}); + assetmanager.SetApkAssets({basic_assets_}); // Set up the resource ids auto high_ref = assetmanager.GetResourceId("@id/high_ref", "values", "com.android.basic"); @@ -470,12 +465,11 @@ TEST_F(AssetManager2Test, ResolveDeepIdReference) { TEST_F(AssetManager2Test, DensityOverride) { AssetManager2 assetmanager; - assetmanager.SetApkAssets({basic_assets_.get(), basic_xhdpi_assets_.get(), - basic_xxhdpi_assets_.get()}); - assetmanager.SetConfiguration({ + assetmanager.SetApkAssets({basic_assets_, basic_xhdpi_assets_, basic_xxhdpi_assets_}); + assetmanager.SetConfigurations({{ .density = ResTable_config::DENSITY_XHIGH, .sdkVersion = 21, - }); + }}); auto value = assetmanager.GetResource(basic::R::string::density, false /*may_be_bag*/); ASSERT_TRUE(value.has_value()); @@ -493,7 +487,7 @@ TEST_F(AssetManager2Test, DensityOverride) { TEST_F(AssetManager2Test, KeepLastReferenceIdUnmodifiedIfNoReferenceIsResolved) { AssetManager2 assetmanager; - assetmanager.SetApkAssets({basic_assets_.get()}); + assetmanager.SetApkAssets({basic_assets_}); // Create some kind of value that is NOT a reference. AssetManager2::SelectedValue value{}; @@ -509,7 +503,7 @@ TEST_F(AssetManager2Test, KeepLastReferenceIdUnmodifiedIfNoReferenceIsResolved) TEST_F(AssetManager2Test, ResolveReferenceMissingResourceDoNotCacheFlags) { AssetManager2 assetmanager; - assetmanager.SetApkAssets({basic_assets_.get()}); + assetmanager.SetApkAssets({basic_assets_}); { AssetManager2::SelectedValue value{}; value.data = basic::R::string::test1; @@ -540,7 +534,7 @@ TEST_F(AssetManager2Test, ResolveReferenceMissingResourceDoNotCacheFlags) { TEST_F(AssetManager2Test, ResolveReferenceMissingResource) { AssetManager2 assetmanager; - assetmanager.SetApkAssets({basic_assets_.get()}); + assetmanager.SetApkAssets({basic_assets_}); const uint32_t kMissingResId = 0x8001ffff; AssetManager2::SelectedValue value{}; @@ -558,7 +552,7 @@ TEST_F(AssetManager2Test, ResolveReferenceMissingResource) { TEST_F(AssetManager2Test, ResolveReferenceMissingResourceLib) { AssetManager2 assetmanager; - assetmanager.SetApkAssets({libclient_assets_.get()}); + assetmanager.SetApkAssets({libclient_assets_}); AssetManager2::SelectedValue value{}; value.type = Res_value::TYPE_REFERENCE; @@ -580,7 +574,7 @@ static bool IsConfigurationPresent(const std::set<ResTable_config>& configuratio TEST_F(AssetManager2Test, GetResourceConfigurations) { AssetManager2 assetmanager; - assetmanager.SetApkAssets({system_assets_.get(), basic_de_fr_assets_.get()}); + assetmanager.SetApkAssets({system_assets_, basic_de_fr_assets_}); auto configurations = assetmanager.GetResourceConfigurations(); ASSERT_TRUE(configurations.has_value()); @@ -625,7 +619,7 @@ TEST_F(AssetManager2Test, GetResourceConfigurations) { TEST_F(AssetManager2Test, GetResourceLocales) { AssetManager2 assetmanager; - assetmanager.SetApkAssets({system_assets_.get(), basic_de_fr_assets_.get()}); + assetmanager.SetApkAssets({system_assets_, basic_de_fr_assets_}); std::set<std::string> locales = assetmanager.GetResourceLocales(); @@ -644,7 +638,7 @@ TEST_F(AssetManager2Test, GetResourceLocales) { TEST_F(AssetManager2Test, GetResourceId) { AssetManager2 assetmanager; - assetmanager.SetApkAssets({basic_assets_.get()}); + assetmanager.SetApkAssets({basic_assets_}); auto resid = assetmanager.GetResourceId("com.android.basic:layout/main", "", ""); ASSERT_TRUE(resid.has_value()); @@ -661,7 +655,7 @@ TEST_F(AssetManager2Test, GetResourceId) { TEST_F(AssetManager2Test, OpensFileFromSingleApkAssets) { AssetManager2 assetmanager; - assetmanager.SetApkAssets({system_assets_.get()}); + assetmanager.SetApkAssets({system_assets_}); std::unique_ptr<Asset> asset = assetmanager.Open("file.txt", Asset::ACCESS_BUFFER); ASSERT_THAT(asset, NotNull()); @@ -673,7 +667,7 @@ TEST_F(AssetManager2Test, OpensFileFromSingleApkAssets) { TEST_F(AssetManager2Test, OpensFileFromMultipleApkAssets) { AssetManager2 assetmanager; - assetmanager.SetApkAssets({system_assets_.get(), app_assets_.get()}); + assetmanager.SetApkAssets({system_assets_, app_assets_}); std::unique_ptr<Asset> asset = assetmanager.Open("file.txt", Asset::ACCESS_BUFFER); ASSERT_THAT(asset, NotNull()); @@ -685,7 +679,7 @@ TEST_F(AssetManager2Test, OpensFileFromMultipleApkAssets) { TEST_F(AssetManager2Test, OpenDir) { AssetManager2 assetmanager; - assetmanager.SetApkAssets({system_assets_.get()}); + assetmanager.SetApkAssets({system_assets_}); std::unique_ptr<AssetDir> asset_dir = assetmanager.OpenDir(""); ASSERT_THAT(asset_dir, NotNull()); @@ -707,7 +701,7 @@ TEST_F(AssetManager2Test, OpenDir) { TEST_F(AssetManager2Test, OpenDirFromManyApks) { AssetManager2 assetmanager; - assetmanager.SetApkAssets({system_assets_.get(), app_assets_.get()}); + assetmanager.SetApkAssets({system_assets_, app_assets_}); std::unique_ptr<AssetDir> asset_dir = assetmanager.OpenDir(""); ASSERT_THAT(asset_dir, NotNull()); @@ -727,8 +721,8 @@ TEST_F(AssetManager2Test, GetLastPathWithoutEnablingReturnsEmpty) { ResTable_config desired_config; AssetManager2 assetmanager; - assetmanager.SetConfiguration(desired_config); - assetmanager.SetApkAssets({basic_assets_.get()}); + assetmanager.SetConfigurations({desired_config}); + assetmanager.SetApkAssets({basic_assets_}); assetmanager.SetResourceResolutionLoggingEnabled(false); auto value = assetmanager.GetResource(basic::R::string::test1); @@ -742,8 +736,8 @@ TEST_F(AssetManager2Test, GetLastPathWithoutResolutionReturnsEmpty) { ResTable_config desired_config; AssetManager2 assetmanager; - assetmanager.SetConfiguration(desired_config); - assetmanager.SetApkAssets({basic_assets_.get()}); + assetmanager.SetConfigurations({desired_config}); + assetmanager.SetApkAssets({basic_assets_}); auto result = assetmanager.GetLastResourceResolution(); EXPECT_EQ("", result); @@ -757,18 +751,19 @@ TEST_F(AssetManager2Test, GetLastPathWithSingleApkAssets) { AssetManager2 assetmanager; assetmanager.SetResourceResolutionLoggingEnabled(true); - assetmanager.SetConfiguration(desired_config); - assetmanager.SetApkAssets({basic_assets_.get()}); + assetmanager.SetConfigurations({desired_config}); + assetmanager.SetApkAssets({basic_assets_}); auto value = assetmanager.GetResource(basic::R::string::test1); ASSERT_TRUE(value.has_value()); auto result = assetmanager.GetLastResourceResolution(); - EXPECT_EQ("Resolution for 0x7f030000 com.android.basic:string/test1\n" - "\tFor config - de\n" - "\tFound initial: basic/basic.apk\n" - "Best matching is from default configuration of com.android.basic", - result); + EXPECT_EQ( + "Resolution for 0x7f030000 com.android.basic:string/test1\n" + "\tFor config - de\n" + "\tFound initial: basic/basic.apk #0\n" + "Best matching is from default configuration of com.android.basic", + result); } TEST_F(AssetManager2Test, GetLastPathWithMultipleApkAssets) { @@ -779,19 +774,20 @@ TEST_F(AssetManager2Test, GetLastPathWithMultipleApkAssets) { AssetManager2 assetmanager; assetmanager.SetResourceResolutionLoggingEnabled(true); - assetmanager.SetConfiguration(desired_config); - assetmanager.SetApkAssets({basic_assets_.get(), basic_de_fr_assets_.get()}); + assetmanager.SetConfigurations({desired_config}); + assetmanager.SetApkAssets({basic_assets_, basic_de_fr_assets_}); auto value = assetmanager.GetResource(basic::R::string::test1); ASSERT_TRUE(value.has_value()); auto result = assetmanager.GetLastResourceResolution(); - EXPECT_EQ("Resolution for 0x7f030000 com.android.basic:string/test1\n" - "\tFor config - de\n" - "\tFound initial: basic/basic.apk\n" - "\tFound better: basic/basic_de_fr.apk - de\n" - "Best matching is from de configuration of com.android.basic", - result); + EXPECT_EQ( + "Resolution for 0x7f030000 com.android.basic:string/test1\n" + "\tFor config - de\n" + "\tFound initial: basic/basic.apk #0\n" + "\tFound better: basic/basic_de_fr.apk #1 - de\n" + "Best matching is from de configuration of com.android.basic", + result); } TEST_F(AssetManager2Test, GetLastPathAfterDisablingReturnsEmpty) { @@ -800,8 +796,8 @@ TEST_F(AssetManager2Test, GetLastPathAfterDisablingReturnsEmpty) { AssetManager2 assetmanager; assetmanager.SetResourceResolutionLoggingEnabled(true); - assetmanager.SetConfiguration(desired_config); - assetmanager.SetApkAssets({basic_assets_.get()}); + assetmanager.SetConfigurations({desired_config}); + assetmanager.SetApkAssets({basic_assets_}); auto value = assetmanager.GetResource(basic::R::string::test1); ASSERT_TRUE(value.has_value()); @@ -821,8 +817,8 @@ TEST_F(AssetManager2Test, GetOverlayablesToString) { AssetManager2 assetmanager; assetmanager.SetResourceResolutionLoggingEnabled(true); - assetmanager.SetConfiguration(desired_config); - assetmanager.SetApkAssets({overlayable_assets_.get()}); + assetmanager.SetConfigurations({desired_config}); + assetmanager.SetApkAssets({overlayable_assets_}); const auto map = assetmanager.GetOverlayableMapForPackage(0x7f); ASSERT_NE(nullptr, map); @@ -838,4 +834,26 @@ TEST_F(AssetManager2Test, GetOverlayablesToString) { std::string::npos); } +TEST_F(AssetManager2Test, GetApkAssets) { + AssetManager2 assetmanager; + assetmanager.SetApkAssets({overlayable_assets_, overlay_assets_, lib_one_assets_}); + + ASSERT_EQ(3, assetmanager.GetApkAssetsCount()); + EXPECT_EQ(1, overlayable_assets_->getStrongCount()); + EXPECT_EQ(1, overlay_assets_->getStrongCount()); + EXPECT_EQ(1, lib_one_assets_->getStrongCount()); + + { + auto op = assetmanager.StartOperation(); + ASSERT_EQ(overlayable_assets_, assetmanager.GetApkAssets(0)); + ASSERT_EQ(overlay_assets_, assetmanager.GetApkAssets(1)); + EXPECT_EQ(2, overlayable_assets_->getStrongCount()); + EXPECT_EQ(2, overlay_assets_->getStrongCount()); + EXPECT_EQ(1, lib_one_assets_->getStrongCount()); + } + EXPECT_EQ(1, overlayable_assets_->getStrongCount()); + EXPECT_EQ(1, overlay_assets_->getStrongCount()); + EXPECT_EQ(1, lib_one_assets_->getStrongCount()); +} + } // namespace android diff --git a/libs/androidfw/tests/AttributeResolution_bench.cpp b/libs/androidfw/tests/AttributeResolution_bench.cpp index 1c89c61c8f78..384f4a78b36d 100644 --- a/libs/androidfw/tests/AttributeResolution_bench.cpp +++ b/libs/androidfw/tests/AttributeResolution_bench.cpp @@ -36,15 +36,14 @@ constexpr const static char* kFrameworkPath = "/system/framework/framework-res.a constexpr const static uint32_t Theme_Material_Light = 0x01030237u; static void BM_ApplyStyle(benchmark::State& state) { - std::unique_ptr<const ApkAssets> styles_apk = - ApkAssets::Load(GetTestDataPath() + "/styles/styles.apk"); + auto styles_apk = ApkAssets::Load(GetTestDataPath() + "/styles/styles.apk"); if (styles_apk == nullptr) { state.SkipWithError("failed to load assets"); return; } AssetManager2 assetmanager; - assetmanager.SetApkAssets({styles_apk.get()}); + assetmanager.SetApkAssets({styles_apk}); std::unique_ptr<Asset> asset = assetmanager.OpenNonAsset("res/layout/layout.xml", Asset::ACCESS_BUFFER); @@ -80,21 +79,20 @@ static void BM_ApplyStyle(benchmark::State& state) { BENCHMARK(BM_ApplyStyle); static void BM_ApplyStyleFramework(benchmark::State& state) { - std::unique_ptr<const ApkAssets> framework_apk = ApkAssets::Load(kFrameworkPath); + auto framework_apk = ApkAssets::Load(kFrameworkPath); if (framework_apk == nullptr) { state.SkipWithError("failed to load framework assets"); return; } - std::unique_ptr<const ApkAssets> basic_apk = - ApkAssets::Load(GetTestDataPath() + "/basic/basic.apk"); + auto basic_apk = ApkAssets::Load(GetTestDataPath() + "/basic/basic.apk"); if (basic_apk == nullptr) { state.SkipWithError("failed to load assets"); return; } AssetManager2 assetmanager; - assetmanager.SetApkAssets({framework_apk.get(), basic_apk.get()}); + assetmanager.SetApkAssets({framework_apk, basic_apk}); ResTable_config device_config; memset(&device_config, 0, sizeof(device_config)); diff --git a/libs/androidfw/tests/AttributeResolution_test.cpp b/libs/androidfw/tests/AttributeResolution_test.cpp index bb9129ad01c8..329830fa47b2 100644 --- a/libs/androidfw/tests/AttributeResolution_test.cpp +++ b/libs/androidfw/tests/AttributeResolution_test.cpp @@ -36,11 +36,11 @@ class AttributeResolutionTest : public ::testing::Test { virtual void SetUp() override { styles_assets_ = ApkAssets::Load(GetTestDataPath() + "/styles/styles.apk"); ASSERT_NE(nullptr, styles_assets_); - assetmanager_.SetApkAssets({styles_assets_.get()}); + assetmanager_.SetApkAssets({styles_assets_}); } protected: - std::unique_ptr<const ApkAssets> styles_assets_; + AssetManager2::ApkAssetsPtr styles_assets_; AssetManager2 assetmanager_; }; @@ -69,7 +69,7 @@ TEST(AttributeResolutionLibraryTest, ApplyStyleWithDefaultStyleResId) { AssetManager2 assetmanager; auto apk_assets = ApkAssets::Load(GetTestDataPath() + "/styles/styles.apk", PROPERTY_DYNAMIC); ASSERT_NE(nullptr, apk_assets); - assetmanager.SetApkAssets({apk_assets.get()}); + assetmanager.SetApkAssets({apk_assets}); std::unique_ptr<Theme> theme = assetmanager.NewTheme(); diff --git a/libs/androidfw/tests/BenchmarkHelpers.cpp b/libs/androidfw/tests/BenchmarkHelpers.cpp index 0fa0573bcbb8..8b883f4ed1df 100644 --- a/libs/androidfw/tests/BenchmarkHelpers.cpp +++ b/libs/androidfw/tests/BenchmarkHelpers.cpp @@ -53,22 +53,20 @@ void GetResourceBenchmarkOld(const std::vector<std::string>& paths, const ResTab void GetResourceBenchmark(const std::vector<std::string>& paths, const ResTable_config* config, uint32_t resid, benchmark::State& state) { - std::vector<std::unique_ptr<const ApkAssets>> apk_assets; - std::vector<const ApkAssets*> apk_assets_ptrs; + std::vector<AssetManager2::ApkAssetsPtr> apk_assets; for (const std::string& path : paths) { - std::unique_ptr<const ApkAssets> apk = ApkAssets::Load(path); + auto apk = ApkAssets::Load(path); if (apk == nullptr) { state.SkipWithError(base::StringPrintf("Failed to load assets %s", path.c_str()).c_str()); return; } - apk_assets_ptrs.push_back(apk.get()); apk_assets.push_back(std::move(apk)); } AssetManager2 assetmanager; - assetmanager.SetApkAssets(apk_assets_ptrs); + assetmanager.SetApkAssets(apk_assets); if (config != nullptr) { - assetmanager.SetConfiguration(*config); + assetmanager.SetConfigurations({*config}); } while (state.KeepRunning()) { diff --git a/libs/androidfw/tests/Generic_bench.cpp b/libs/androidfw/tests/Generic_bench.cpp new file mode 100644 index 000000000000..4c978e889f83 --- /dev/null +++ b/libs/androidfw/tests/Generic_bench.cpp @@ -0,0 +1,146 @@ +/* + * 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. + */ + +#include <stdint.h> + +#include <map> +#include <unordered_map> + +#include "benchmark/benchmark.h" + +namespace android { + +template <class Map = std::unordered_map<uint32_t, std::vector<uint32_t>>> +static Map prepare_map() { + Map map; + std::vector<uint32_t> vec; + for (int i = 0; i < 1000; ++i) { + map.emplace(i, vec); + } + return map; +} + +static void BM_hashmap_emplace_same(benchmark::State& state) { + auto map = prepare_map<>(); + auto val = map.size() - 1; + std::vector<uint32_t> vec; + for (auto&& _ : state) { + benchmark::DoNotOptimize(map.emplace(val, vec)); + } +} +BENCHMARK(BM_hashmap_emplace_same); +static void BM_hashmap_try_emplace_same(benchmark::State& state) { + auto map = prepare_map(); + auto val = map.size() - 1; + for (auto&& _ : state) { + benchmark::DoNotOptimize(map.try_emplace(val)); + } +} +BENCHMARK(BM_hashmap_try_emplace_same); +static void BM_hashmap_find(benchmark::State& state) { + auto map = prepare_map<>(); + auto val = map.size() - 1; + for (auto&& _ : state) { + benchmark::DoNotOptimize(map.find(val)); + } +} +BENCHMARK(BM_hashmap_find); + +static void BM_hashmap_emplace_diff(benchmark::State& state) { + auto map = prepare_map<>(); + std::vector<uint32_t> vec; + auto i = map.size(); + for (auto&& _ : state) { + map.emplace(i++, vec); + } +} +BENCHMARK(BM_hashmap_emplace_diff); +static void BM_hashmap_try_emplace_diff(benchmark::State& state) { + auto map = prepare_map(); + auto i = map.size(); + for (auto&& _ : state) { + map.try_emplace(i++); + } +} +BENCHMARK(BM_hashmap_try_emplace_diff); +static void BM_hashmap_find_emplace_diff(benchmark::State& state) { + auto map = prepare_map<>(); + std::vector<uint32_t> vec; + auto i = map.size(); + for (auto&& _ : state) { + if (map.find(i++) == map.end()) { + map.emplace(i - 1, vec); + } + } +} +BENCHMARK(BM_hashmap_find_emplace_diff); + +static void BM_treemap_emplace_same(benchmark::State& state) { + auto map = prepare_map<std::map<uint32_t, std::vector<uint32_t>>>(); + auto val = map.size() - 1; + std::vector<uint32_t> vec; + for (auto&& _ : state) { + benchmark::DoNotOptimize(map.emplace(val, vec)); + } +} +BENCHMARK(BM_treemap_emplace_same); +static void BM_treemap_try_emplace_same(benchmark::State& state) { + auto map = prepare_map<std::map<uint32_t, std::vector<uint32_t>>>(); + auto val = map.size() - 1; + for (auto&& _ : state) { + benchmark::DoNotOptimize(map.try_emplace(val)); + } +} +BENCHMARK(BM_treemap_try_emplace_same); +static void BM_treemap_find(benchmark::State& state) { + auto map = prepare_map<std::map<uint32_t, std::vector<uint32_t>>>(); + auto val = map.size() - 1; + for (auto&& _ : state) { + benchmark::DoNotOptimize(map.find(val)); + } +} +BENCHMARK(BM_treemap_find); + +static void BM_treemap_emplace_diff(benchmark::State& state) { + auto map = prepare_map<std::map<uint32_t, std::vector<uint32_t>>>(); + std::vector<uint32_t> vec; + auto i = map.size(); + for (auto&& _ : state) { + map.emplace(i++, vec); + } +} +BENCHMARK(BM_treemap_emplace_diff); +static void BM_treemap_try_emplace_diff(benchmark::State& state) { + auto map = prepare_map(); + auto i = map.size(); + for (auto&& _ : state) { + map.try_emplace(i++); + } +} +BENCHMARK(BM_treemap_try_emplace_diff); +static void BM_treemap_find_emplace_diff(benchmark::State& state) { + auto map = prepare_map(); + std::vector<uint32_t> vec; + auto i = map.size(); + for (auto&& _ : state) { + if (map.find(i++) == map.end()) { + map.emplace(i - 1, vec); + } + } +} +BENCHMARK(BM_treemap_find_emplace_diff); + +} // namespace android
\ No newline at end of file diff --git a/libs/androidfw/tests/Idmap_test.cpp b/libs/androidfw/tests/Idmap_test.cpp index b43491548e2b..60aa7d88925d 100644 --- a/libs/androidfw/tests/Idmap_test.cpp +++ b/libs/androidfw/tests/Idmap_test.cpp @@ -59,15 +59,16 @@ class IdmapTest : public ::testing::Test { protected: std::string original_path; - std::unique_ptr<const ApkAssets> system_assets_; - std::unique_ptr<const ApkAssets> overlay_assets_; - std::unique_ptr<const ApkAssets> overlayable_assets_; + AssetManager2::ApkAssetsPtr system_assets_; + AssetManager2::ApkAssetsPtr overlay_assets_; + AssetManager2::ApkAssetsPtr overlayable_assets_; }; std::string GetStringFromApkAssets(const AssetManager2& asset_manager, const AssetManager2::SelectedValue& value) { - auto assets = asset_manager.GetApkAssets(); - const ResStringPool* string_pool = assets[value.cookie]->GetLoadedArsc()->GetStringPool(); + auto op = asset_manager.StartOperation(); + const ResStringPool* string_pool = + asset_manager.GetApkAssets(value.cookie)->GetLoadedArsc()->GetStringPool(); return GetStringFromPool(string_pool, value.data); } @@ -75,8 +76,7 @@ std::string GetStringFromApkAssets(const AssetManager2& asset_manager, TEST_F(IdmapTest, OverlayOverridesResourceValue) { AssetManager2 asset_manager; - asset_manager.SetApkAssets({system_assets_.get(), overlayable_assets_.get(), - overlay_assets_.get()}); + asset_manager.SetApkAssets({system_assets_, overlayable_assets_, overlay_assets_}); auto value = asset_manager.GetResource(overlayable::R::string::overlayable5); ASSERT_TRUE(value.has_value()); @@ -87,8 +87,7 @@ TEST_F(IdmapTest, OverlayOverridesResourceValue) { TEST_F(IdmapTest, OverlayOverridesResourceValueUsingDifferentPackage) { AssetManager2 asset_manager; - asset_manager.SetApkAssets({system_assets_.get(), overlayable_assets_.get(), - overlay_assets_.get()}); + asset_manager.SetApkAssets({system_assets_, overlayable_assets_, overlay_assets_}); auto value = asset_manager.GetResource(overlayable::R::string::overlayable10); ASSERT_TRUE(value.has_value()); @@ -99,8 +98,7 @@ TEST_F(IdmapTest, OverlayOverridesResourceValueUsingDifferentPackage) { TEST_F(IdmapTest, OverlayOverridesResourceValueUsingInternalResource) { AssetManager2 asset_manager; - asset_manager.SetApkAssets({system_assets_.get(), overlayable_assets_.get(), - overlay_assets_.get()}); + asset_manager.SetApkAssets({system_assets_, overlayable_assets_, overlay_assets_}); auto value = asset_manager.GetResource(overlayable::R::string::overlayable8); ASSERT_TRUE(value.has_value()); @@ -111,8 +109,7 @@ TEST_F(IdmapTest, OverlayOverridesResourceValueUsingInternalResource) { TEST_F(IdmapTest, OverlayOverridesResourceValueUsingInlineInteger) { AssetManager2 asset_manager; - asset_manager.SetApkAssets({system_assets_.get(), overlayable_assets_.get(), - overlay_assets_.get()}); + asset_manager.SetApkAssets({system_assets_, overlayable_assets_, overlay_assets_}); auto value = asset_manager.GetResource(overlayable::R::integer::config_integer); ASSERT_TRUE(value.has_value()); @@ -123,8 +120,7 @@ TEST_F(IdmapTest, OverlayOverridesResourceValueUsingInlineInteger) { TEST_F(IdmapTest, OverlayOverridesResourceValueUsingInlineString) { AssetManager2 asset_manager; - asset_manager.SetApkAssets({system_assets_.get(), overlayable_assets_.get(), - overlay_assets_.get()}); + asset_manager.SetApkAssets({system_assets_, overlayable_assets_, overlay_assets_}); auto value = asset_manager.GetResource(overlayable::R::string::overlayable11); ASSERT_TRUE(value.has_value()); @@ -135,8 +131,7 @@ TEST_F(IdmapTest, OverlayOverridesResourceValueUsingInlineString) { TEST_F(IdmapTest, OverlayOverridesResourceValueUsingOverlayingResource) { AssetManager2 asset_manager; - asset_manager.SetApkAssets({system_assets_.get(), overlayable_assets_.get(), - overlay_assets_.get()}); + asset_manager.SetApkAssets({system_assets_, overlayable_assets_, overlay_assets_}); auto value = asset_manager.GetResource(overlayable::R::string::overlayable9); ASSERT_TRUE(value.has_value()); @@ -147,8 +142,7 @@ TEST_F(IdmapTest, OverlayOverridesResourceValueUsingOverlayingResource) { TEST_F(IdmapTest, OverlayOverridesXmlParser) { AssetManager2 asset_manager; - asset_manager.SetApkAssets({system_assets_.get(), overlayable_assets_.get(), - overlay_assets_.get()}); + asset_manager.SetApkAssets({system_assets_, overlayable_assets_, overlay_assets_}); auto value = asset_manager.GetResource(overlayable::R::layout::hello_view); ASSERT_TRUE(value.has_value()); @@ -186,8 +180,7 @@ TEST_F(IdmapTest, OverlayOverridesXmlParser) { TEST_F(IdmapTest, OverlaidResourceHasSameName) { AssetManager2 asset_manager; - asset_manager.SetApkAssets({system_assets_.get(), overlayable_assets_.get(), - overlay_assets_.get()}); + asset_manager.SetApkAssets({system_assets_, overlayable_assets_, overlay_assets_}); auto name = asset_manager.GetResourceName(overlayable::R::string::overlayable9); ASSERT_TRUE(name.has_value()); @@ -203,8 +196,7 @@ TEST_F(IdmapTest, OverlayLoaderInterop) { auto loader_assets = ApkAssets::LoadTable(std::move(asset), EmptyAssetsProvider::Create(), PROPERTY_LOADER); AssetManager2 asset_manager; - asset_manager.SetApkAssets({overlayable_assets_.get(), loader_assets.get(), - overlay_assets_.get()}); + asset_manager.SetApkAssets({overlayable_assets_, loader_assets, overlay_assets_}); auto value = asset_manager.GetResource(overlayable::R::string::overlayable11); ASSERT_TRUE(value.has_value()); diff --git a/libs/androidfw/tests/Theme_bench.cpp b/libs/androidfw/tests/Theme_bench.cpp index f3d60bbe4f15..dfbb5a76dec6 100644 --- a/libs/androidfw/tests/Theme_bench.cpp +++ b/libs/androidfw/tests/Theme_bench.cpp @@ -28,14 +28,14 @@ constexpr const static uint32_t kStyleId = 0x01030237u; // android:style/Theme. constexpr const static uint32_t kAttrId = 0x01010030u; // android:attr/colorForeground static void BM_ThemeApplyStyleFramework(benchmark::State& state) { - std::unique_ptr<const ApkAssets> apk = ApkAssets::Load(kFrameworkPath); + auto apk = ApkAssets::Load(kFrameworkPath); if (apk == nullptr) { state.SkipWithError("Failed to load assets"); return; } AssetManager2 assets; - assets.SetApkAssets({apk.get()}); + assets.SetApkAssets({apk}); while (state.KeepRunning()) { auto theme = assets.NewTheme(); @@ -62,10 +62,10 @@ static void BM_ThemeApplyStyleFrameworkOld(benchmark::State& state) { BENCHMARK(BM_ThemeApplyStyleFrameworkOld); static void BM_ThemeGetAttribute(benchmark::State& state) { - std::unique_ptr<const ApkAssets> apk = ApkAssets::Load(kFrameworkPath); + auto apk = ApkAssets::Load(kFrameworkPath); AssetManager2 assets; - assets.SetApkAssets({apk.get()}); + assets.SetApkAssets({apk}); auto theme = assets.NewTheme(); theme->ApplyStyle(kStyleId, false /* force */); diff --git a/libs/androidfw/tests/Theme_test.cpp b/libs/androidfw/tests/Theme_test.cpp index 77114f273d3d..181d1411fb91 100644 --- a/libs/androidfw/tests/Theme_test.cpp +++ b/libs/androidfw/tests/Theme_test.cpp @@ -53,16 +53,16 @@ class ThemeTest : public ::testing::Test { } protected: - std::unique_ptr<const ApkAssets> system_assets_; - std::unique_ptr<const ApkAssets> style_assets_; - std::unique_ptr<const ApkAssets> libclient_assets_; - std::unique_ptr<const ApkAssets> lib_one_assets_; - std::unique_ptr<const ApkAssets> lib_two_assets_; + AssetManager2::ApkAssetsPtr system_assets_; + AssetManager2::ApkAssetsPtr style_assets_; + AssetManager2::ApkAssetsPtr libclient_assets_; + AssetManager2::ApkAssetsPtr lib_one_assets_; + AssetManager2::ApkAssetsPtr lib_two_assets_; }; TEST_F(ThemeTest, EmptyTheme) { AssetManager2 assetmanager; - assetmanager.SetApkAssets({style_assets_.get()}); + assetmanager.SetApkAssets({style_assets_}); std::unique_ptr<Theme> theme = assetmanager.NewTheme(); EXPECT_EQ(0u, theme->GetChangingConfigurations()); @@ -72,7 +72,7 @@ TEST_F(ThemeTest, EmptyTheme) { TEST_F(ThemeTest, SingleThemeNoParent) { AssetManager2 assetmanager; - assetmanager.SetApkAssets({style_assets_.get()}); + assetmanager.SetApkAssets({style_assets_}); std::unique_ptr<Theme> theme = assetmanager.NewTheme(); ASSERT_TRUE(theme->ApplyStyle(app::R::style::StyleOne).has_value()); @@ -92,7 +92,7 @@ TEST_F(ThemeTest, SingleThemeNoParent) { TEST_F(ThemeTest, SingleThemeWithParent) { AssetManager2 assetmanager; - assetmanager.SetApkAssets({style_assets_.get()}); + assetmanager.SetApkAssets({style_assets_}); std::unique_ptr<Theme> theme = assetmanager.NewTheme(); ASSERT_TRUE(theme->ApplyStyle(app::R::style::StyleTwo).has_value()); @@ -121,7 +121,7 @@ TEST_F(ThemeTest, SingleThemeWithParent) { TEST_F(ThemeTest, TryToUseBadResourceId) { AssetManager2 assetmanager; - assetmanager.SetApkAssets({style_assets_.get()}); + assetmanager.SetApkAssets({style_assets_}); std::unique_ptr<Theme> theme = assetmanager.NewTheme(); ASSERT_TRUE(theme->ApplyStyle(app::R::style::StyleTwo).has_value()); @@ -130,7 +130,7 @@ TEST_F(ThemeTest, TryToUseBadResourceId) { TEST_F(ThemeTest, MultipleThemesOverlaidNotForce) { AssetManager2 assetmanager; - assetmanager.SetApkAssets({style_assets_.get()}); + assetmanager.SetApkAssets({style_assets_}); std::unique_ptr<Theme> theme = assetmanager.NewTheme(); ASSERT_TRUE(theme->ApplyStyle(app::R::style::StyleTwo).has_value()); @@ -160,7 +160,7 @@ TEST_F(ThemeTest, MultipleThemesOverlaidNotForce) { TEST_F(ThemeTest, MultipleThemesOverlaidForced) { AssetManager2 assetmanager; - assetmanager.SetApkAssets({style_assets_.get()}); + assetmanager.SetApkAssets({style_assets_}); std::unique_ptr<Theme> theme = assetmanager.NewTheme(); ASSERT_TRUE(theme->ApplyStyle(app::R::style::StyleTwo).has_value()); @@ -190,8 +190,7 @@ TEST_F(ThemeTest, MultipleThemesOverlaidForced) { TEST_F(ThemeTest, ResolveDynamicAttributesAndReferencesToSharedLibrary) { AssetManager2 assetmanager; - assetmanager.SetApkAssets( - {lib_two_assets_.get(), lib_one_assets_.get(), libclient_assets_.get()}); + assetmanager.SetApkAssets({lib_two_assets_, lib_one_assets_, libclient_assets_}); std::unique_ptr<Theme> theme = assetmanager.NewTheme(); ASSERT_TRUE(theme->ApplyStyle(libclient::R::style::Theme, false /*force*/).has_value()); @@ -216,7 +215,7 @@ TEST_F(ThemeTest, ResolveDynamicAttributesAndReferencesToSharedLibrary) { TEST_F(ThemeTest, CopyThemeSameAssetManager) { AssetManager2 assetmanager; - assetmanager.SetApkAssets({style_assets_.get()}); + assetmanager.SetApkAssets({style_assets_}); std::unique_ptr<Theme> theme_one = assetmanager.NewTheme(); ASSERT_TRUE(theme_one->ApplyStyle(app::R::style::StyleOne).has_value()); @@ -253,15 +252,15 @@ TEST_F(ThemeTest, CopyThemeSameAssetManager) { TEST_F(ThemeTest, ThemeRebase) { AssetManager2 am; - am.SetApkAssets({style_assets_.get()}); + am.SetApkAssets({style_assets_}); AssetManager2 am_night; - am_night.SetApkAssets({style_assets_.get()}); + am_night.SetApkAssets({style_assets_}); ResTable_config night{}; night.uiMode = ResTable_config::UI_MODE_NIGHT_YES; night.version = 8u; - am_night.SetConfiguration(night); + am_night.SetConfigurations({night}); auto theme = am.NewTheme(); { @@ -327,12 +326,11 @@ TEST_F(ThemeTest, ThemeRebase) { TEST_F(ThemeTest, OnlyCopySameAssetsThemeWhenAssetManagersDiffer) { AssetManager2 assetmanager_dst; - assetmanager_dst.SetApkAssets({system_assets_.get(), lib_one_assets_.get(), style_assets_.get(), - libclient_assets_.get()}); + assetmanager_dst.SetApkAssets( + {system_assets_, lib_one_assets_, style_assets_, libclient_assets_}); AssetManager2 assetmanager_src; - assetmanager_src.SetApkAssets({system_assets_.get(), lib_two_assets_.get(), lib_one_assets_.get(), - style_assets_.get()}); + assetmanager_src.SetApkAssets({system_assets_, lib_two_assets_, lib_one_assets_, style_assets_}); auto theme_dst = assetmanager_dst.NewTheme(); ASSERT_TRUE(theme_dst->ApplyStyle(app::R::style::StyleOne).has_value()); @@ -376,10 +374,10 @@ TEST_F(ThemeTest, OnlyCopySameAssetsThemeWhenAssetManagersDiffer) { TEST_F(ThemeTest, CopyNonReferencesWhenPackagesDiffer) { AssetManager2 assetmanager_dst; - assetmanager_dst.SetApkAssets({system_assets_.get()}); + assetmanager_dst.SetApkAssets({system_assets_}); AssetManager2 assetmanager_src; - assetmanager_src.SetApkAssets({system_assets_.get(), style_assets_.get()}); + assetmanager_src.SetApkAssets({system_assets_, style_assets_}); auto theme_dst = assetmanager_dst.NewTheme(); auto theme_src = assetmanager_src.NewTheme(); diff --git a/libs/hwui/Android.bp b/libs/hwui/Android.bp index db581471e2ca..b5e6f94af022 100644 --- a/libs/hwui/Android.bp +++ b/libs/hwui/Android.bp @@ -514,6 +514,7 @@ cc_defaults { "canvas/CanvasOpRasterizer.cpp", "effects/StretchEffect.cpp", "effects/GainmapRenderer.cpp", + "pipeline/skia/BackdropFilterDrawable.cpp", "pipeline/skia/HolePunch.cpp", "pipeline/skia/SkiaDisplayList.cpp", "pipeline/skia/SkiaRecordingCanvas.cpp", diff --git a/libs/hwui/AutoBackendTextureRelease.cpp b/libs/hwui/AutoBackendTextureRelease.cpp index b656b6ac8204..d237cc261b53 100644 --- a/libs/hwui/AutoBackendTextureRelease.cpp +++ b/libs/hwui/AutoBackendTextureRelease.cpp @@ -16,6 +16,11 @@ #include "AutoBackendTextureRelease.h" +#include <SkImage.h> +#include <include/gpu/ganesh/SkImageGanesh.h> +#include <include/gpu/GrBackendSurfaceMutableState.h> +#include <include/gpu/GrDirectContext.h> +#include <include/gpu/GrBackendSurface.h> #include "renderthread/RenderThread.h" #include "utils/Color.h" #include "utils/PaintUtils.h" @@ -70,7 +75,7 @@ void AutoBackendTextureRelease::unref(bool releaseImage) { // releaseProc is invoked by SkImage, when texture is no longer in use. // "releaseContext" contains an "AutoBackendTextureRelease*". -static void releaseProc(SkImage::ReleaseContext releaseContext) { +static void releaseProc(SkImages::ReleaseContext releaseContext) { AutoBackendTextureRelease* textureRelease = reinterpret_cast<AutoBackendTextureRelease*>(releaseContext); textureRelease->unref(false); @@ -83,10 +88,10 @@ void AutoBackendTextureRelease::makeImage(AHardwareBuffer* buffer, AHardwareBuffer_describe(buffer, &desc); SkColorType colorType = GrAHardwareBufferUtils::GetSkColorTypeFromBufferFormat(desc.format); // The following ref will be counteracted by Skia calling releaseProc, either during - // MakeFromTexture if there is a failure, or later when SkImage is discarded. It must - // be called before MakeFromTexture, otherwise Skia may remove HWUI's ref on failure. + // BorrowTextureFrom if there is a failure, or later when SkImage is discarded. It must + // be called before BorrowTextureFrom, otherwise Skia may remove HWUI's ref on failure. ref(); - mImage = SkImage::MakeFromTexture( + mImage = SkImages::BorrowTextureFrom( context, mBackendTexture, kTopLeft_GrSurfaceOrigin, colorType, kPremul_SkAlphaType, uirenderer::DataSpaceToColorSpace(dataspace), releaseProc, this); } diff --git a/libs/hwui/ColorFilter.h b/libs/hwui/ColorFilter.h new file mode 100644 index 000000000000..1a5b938d6eed --- /dev/null +++ b/libs/hwui/ColorFilter.h @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef COLORFILTER_H_ +#define COLORFILTER_H_ + +#include <stdint.h> + +#include <memory> + +#include "GraphicsJNI.h" +#include "SkColorFilter.h" +#include "SkiaWrapper.h" + +namespace android { +namespace uirenderer { + +class ColorFilter : public SkiaWrapper<SkColorFilter> { +public: + static ColorFilter* fromJava(jlong handle) { return reinterpret_cast<ColorFilter*>(handle); } + +protected: + ColorFilter() = default; +}; + +class BlendModeColorFilter : public ColorFilter { +public: + BlendModeColorFilter(SkColor color, SkBlendMode mode) : mColor(color), mMode(mode) {} + +private: + sk_sp<SkColorFilter> createInstance() override { return SkColorFilters::Blend(mColor, mMode); } + +private: + const SkColor mColor; + const SkBlendMode mMode; +}; + +class LightingFilter : public ColorFilter { +public: + LightingFilter(SkColor mul, SkColor add) : mMul(mul), mAdd(add) {} + + void setMul(SkColor mul) { + mMul = mul; + discardInstance(); + } + + void setAdd(SkColor add) { + mAdd = add; + discardInstance(); + } + +private: + sk_sp<SkColorFilter> createInstance() override { return SkColorFilters::Lighting(mMul, mAdd); } + +private: + SkColor mMul; + SkColor mAdd; +}; + +class ColorMatrixColorFilter : public ColorFilter { +public: + ColorMatrixColorFilter(std::vector<float>&& matrix) : mMatrix(std::move(matrix)) {} + + void setMatrix(std::vector<float>&& matrix) { + mMatrix = std::move(matrix); + discardInstance(); + } + +private: + sk_sp<SkColorFilter> createInstance() override { + return SkColorFilters::Matrix(mMatrix.data()); + } + +private: + std::vector<float> mMatrix; +}; + +} // namespace uirenderer +} // namespace android + +#endif // COLORFILTER_H_ diff --git a/libs/hwui/DisplayListOps.in b/libs/hwui/DisplayListOps.in index a18ba1c633b9..d21f07efe36a 100644 --- a/libs/hwui/DisplayListOps.in +++ b/libs/hwui/DisplayListOps.in @@ -14,7 +14,6 @@ * limitations under the License. */ -X(Flush) X(Save) X(Restore) X(SaveLayer) diff --git a/libs/hwui/HardwareBitmapUploader.cpp b/libs/hwui/HardwareBitmapUploader.cpp index b7e99994355c..19a1dfa91539 100644 --- a/libs/hwui/HardwareBitmapUploader.cpp +++ b/libs/hwui/HardwareBitmapUploader.cpp @@ -25,6 +25,7 @@ #include <SkBitmap.h> #include <SkCanvas.h> #include <SkImage.h> +#include <SkImageAndroid.h> #include <SkImageInfo.h> #include <SkRefCnt.h> #include <gui/TraceUtils.h> @@ -262,7 +263,8 @@ private: } sk_sp<SkImage> image = - SkImage::MakeFromAHardwareBufferWithData(mGrContext.get(), bitmap.pixmap(), ahb); + SkImages::TextureFromAHardwareBufferWithData(mGrContext.get(), bitmap.pixmap(), + ahb); mGrContext->submit(true); uploadSucceeded = (image.get() != nullptr); diff --git a/libs/hwui/MemoryPolicy.cpp b/libs/hwui/MemoryPolicy.cpp index ca1312e75f4c..21f4ca79b68c 100644 --- a/libs/hwui/MemoryPolicy.cpp +++ b/libs/hwui/MemoryPolicy.cpp @@ -28,7 +28,10 @@ namespace android::uirenderer { constexpr static MemoryPolicy sDefaultMemoryPolicy; constexpr static MemoryPolicy sPersistentOrSystemPolicy{ .contextTimeout = 10_s, + .minimumResourceRetention = 1_s, + .maximumResourceRetention = 10_s, .useAlternativeUiHidden = true, + .purgeScratchOnly = false, }; constexpr static MemoryPolicy sLowRamPolicy{ .useAlternativeUiHidden = true, diff --git a/libs/hwui/MemoryPolicy.h b/libs/hwui/MemoryPolicy.h index 347daf34f52a..e10dda990dec 100644 --- a/libs/hwui/MemoryPolicy.h +++ b/libs/hwui/MemoryPolicy.h @@ -53,6 +53,8 @@ struct MemoryPolicy { // The minimum amount of time to hold onto items in the resource cache // The actual time used will be the max of this & when frames were actually rendered nsecs_t minimumResourceRetention = 10_s; + // The maximum amount of time to hold onto items in the resource cache + nsecs_t maximumResourceRetention = 100000_s; // If false, use only TRIM_UI_HIDDEN to drive background cache limits; // If true, use all signals (such as all contexts are stopped) to drive the limits bool useAlternativeUiHidden = true; diff --git a/libs/hwui/Mesh.h b/libs/hwui/Mesh.h index 13e3c8e7bf77..764d1efcc8f4 100644 --- a/libs/hwui/Mesh.h +++ b/libs/hwui/Mesh.h @@ -19,6 +19,7 @@ #include <GrDirectContext.h> #include <SkMesh.h> +#include <include/gpu/ganesh/SkMeshGanesh.h> #include <jni.h> #include <log/log.h> @@ -143,14 +144,26 @@ public: } if (mIsDirty || genId != mGenerationId) { - auto vb = SkMesh::MakeVertexBuffer( - context, reinterpret_cast<const void*>(mVertexBufferData.data()), - mVertexBufferData.size()); + auto vertexData = reinterpret_cast<const void*>(mVertexBufferData.data()); +#ifdef __ANDROID__ + auto vb = SkMeshes::MakeVertexBuffer(context, + vertexData, + mVertexBufferData.size()); +#else + auto vb = SkMeshes::MakeVertexBuffer(vertexData, + mVertexBufferData.size()); +#endif auto meshMode = SkMesh::Mode(mMode); if (!mIndexBufferData.empty()) { - auto ib = SkMesh::MakeIndexBuffer( - context, reinterpret_cast<const void*>(mIndexBufferData.data()), - mIndexBufferData.size()); + auto indexData = reinterpret_cast<const void*>(mIndexBufferData.data()); +#ifdef __ANDROID__ + auto ib = SkMeshes::MakeIndexBuffer(context, + indexData, + mIndexBufferData.size()); +#else + auto ib = SkMeshes::MakeIndexBuffer(indexData, + mIndexBufferData.size()); +#endif mMesh = SkMesh::MakeIndexed(mMeshSpec, meshMode, vb, mVertexCount, mVertexOffset, ib, mIndexCount, mIndexOffset, mBuilder->fUniforms, mBounds) diff --git a/libs/hwui/Properties.cpp b/libs/hwui/Properties.cpp index 06aed63d8def..5e5eb4a51b35 100644 --- a/libs/hwui/Properties.cpp +++ b/libs/hwui/Properties.cpp @@ -20,7 +20,7 @@ #ifdef __ANDROID__ #include "HWUIProperties.sysprop.h" #endif -#include "SkTraceEventCommon.h" +#include "src/core/SkTraceEventCommon.h" #include <algorithm> #include <cstdlib> diff --git a/libs/hwui/Readback.cpp b/libs/hwui/Readback.cpp index 045de35c1d97..afe4c3896ed2 100644 --- a/libs/hwui/Readback.cpp +++ b/libs/hwui/Readback.cpp @@ -21,6 +21,7 @@ #include <SkCanvas.h> #include <SkColorSpace.h> #include <SkImage.h> +#include <SkImageAndroid.h> #include <SkImageInfo.h> #include <SkMatrix.h> #include <SkPaint.h> @@ -29,6 +30,7 @@ #include <SkSamplingOptions.h> #include <SkSurface.h> #include "include/gpu/GpuTypes.h" // from Skia +#include <include/gpu/ganesh/SkSurfaceGanesh.h> #include <gui/TraceUtils.h> #include <private/android/AHardwareBufferHelpers.h> #include <shaders/shaders.h> @@ -108,7 +110,8 @@ void Readback::copySurfaceInto(ANativeWindow* window, const std::shared_ptr<Copy sk_sp<SkColorSpace> colorSpace = DataSpaceToColorSpace(static_cast<android_dataspace>(dataspace)); sk_sp<SkImage> image = - SkImage::MakeFromAHardwareBuffer(sourceBuffer.get(), kPremul_SkAlphaType, colorSpace); + SkImages::DeferredFromAHardwareBuffer(sourceBuffer.get(), kPremul_SkAlphaType, + colorSpace); if (!image.get()) { return request->onCopyFinished(CopyResult::UnknownError); @@ -171,16 +174,16 @@ void Readback::copySurfaceInto(ANativeWindow* window, const std::shared_ptr<Copy SkBitmap skBitmap = request->getDestinationBitmap(srcRect.width(), srcRect.height()); SkBitmap* bitmap = &skBitmap; sk_sp<SkSurface> tmpSurface = - SkSurface::MakeRenderTarget(mRenderThread.getGrContext(), skgpu::Budgeted::kYes, - bitmap->info(), 0, kTopLeft_GrSurfaceOrigin, nullptr); + SkSurfaces::RenderTarget(mRenderThread.getGrContext(), skgpu::Budgeted::kYes, + bitmap->info(), 0, kTopLeft_GrSurfaceOrigin, nullptr); // if we can't generate a GPU surface that matches the destination bitmap (e.g. 565) then we // attempt to do the intermediate rendering step in 8888 if (!tmpSurface.get()) { SkImageInfo tmpInfo = bitmap->info().makeColorType(SkColorType::kN32_SkColorType); - tmpSurface = SkSurface::MakeRenderTarget(mRenderThread.getGrContext(), - skgpu::Budgeted::kYes, - tmpInfo, 0, kTopLeft_GrSurfaceOrigin, nullptr); + tmpSurface = SkSurfaces::RenderTarget(mRenderThread.getGrContext(), + skgpu::Budgeted::kYes, + tmpInfo, 0, kTopLeft_GrSurfaceOrigin, nullptr); if (!tmpSurface.get()) { ALOGW("Unable to generate GPU buffer in a format compatible with the provided bitmap"); return request->onCopyFinished(CopyResult::UnknownError); @@ -346,19 +349,19 @@ bool Readback::copyLayerInto(Layer* layer, const SkRect* srcRect, const SkRect* * a scaling issue (b/62262733) that was encountered when sampling from an EGLImage into a * software buffer. */ - sk_sp<SkSurface> tmpSurface = SkSurface::MakeRenderTarget(mRenderThread.getGrContext(), - skgpu::Budgeted::kYes, - bitmap->info(), - 0, - kTopLeft_GrSurfaceOrigin, nullptr); + sk_sp<SkSurface> tmpSurface = SkSurfaces::RenderTarget(mRenderThread.getGrContext(), + skgpu::Budgeted::kYes, + bitmap->info(), + 0, + kTopLeft_GrSurfaceOrigin, nullptr); // if we can't generate a GPU surface that matches the destination bitmap (e.g. 565) then we // attempt to do the intermediate rendering step in 8888 if (!tmpSurface.get()) { SkImageInfo tmpInfo = bitmap->info().makeColorType(SkColorType::kN32_SkColorType); - tmpSurface = SkSurface::MakeRenderTarget(mRenderThread.getGrContext(), - skgpu::Budgeted::kYes, - tmpInfo, 0, kTopLeft_GrSurfaceOrigin, nullptr); + tmpSurface = SkSurfaces::RenderTarget(mRenderThread.getGrContext(), + skgpu::Budgeted::kYes, + tmpInfo, 0, kTopLeft_GrSurfaceOrigin, nullptr); if (!tmpSurface.get()) { ALOGW("Unable to generate GPU buffer in a format compatible with the provided bitmap"); return false; diff --git a/libs/hwui/RecordingCanvas.cpp b/libs/hwui/RecordingCanvas.cpp index 924fbd659824..71f47e92e055 100644 --- a/libs/hwui/RecordingCanvas.cpp +++ b/libs/hwui/RecordingCanvas.cpp @@ -36,6 +36,7 @@ #include "SkImageFilter.h" #include "SkImageInfo.h" #include "SkLatticeIter.h" +#include "SkMesh.h" #include "SkPaint.h" #include "SkPicture.h" #include "SkRRect.h" @@ -49,6 +50,7 @@ #include "effects/GainmapRenderer.h" #include "include/gpu/GpuTypes.h" // from Skia #include "include/gpu/GrDirectContext.h" +#include "include/gpu/ganesh/SkMeshGanesh.h" #include "pipeline/skia/AnimatedDrawables.h" #include "pipeline/skia/FunctorDrawable.h" #ifdef __ANDROID__ @@ -107,11 +109,6 @@ struct Op { }; static_assert(sizeof(Op) == 4, ""); -struct Flush final : Op { - static const auto kType = Type::Flush; - void draw(SkCanvas* c, const SkMatrix&) const { c->flush(); } -}; - struct Save final : Op { static const auto kType = Type::Save; void draw(SkCanvas* c, const SkMatrix&) const { c->save(); } @@ -532,12 +529,13 @@ struct DrawSkMesh final : Op { mutable bool isGpuBased; mutable GrDirectContext::DirectContextID contextId; void draw(SkCanvas* c, const SkMatrix&) const { +#ifdef __ANDROID__ GrDirectContext* directContext = c->recordingContext()->asDirectContext(); GrDirectContext::DirectContextID id = directContext->directContextID(); if (!isGpuBased || contextId != id) { sk_sp<SkMesh::VertexBuffer> vb = - SkMesh::CopyVertexBuffer(directContext, cpuMesh.refVertexBuffer()); + SkMeshes::CopyVertexBuffer(directContext, cpuMesh.refVertexBuffer()); if (!cpuMesh.indexBuffer()) { gpuMesh = SkMesh::Make(cpuMesh.refSpec(), cpuMesh.mode(), vb, cpuMesh.vertexCount(), cpuMesh.vertexOffset(), cpuMesh.refUniforms(), @@ -545,7 +543,7 @@ struct DrawSkMesh final : Op { .mesh; } else { sk_sp<SkMesh::IndexBuffer> ib = - SkMesh::CopyIndexBuffer(directContext, cpuMesh.refIndexBuffer()); + SkMeshes::CopyIndexBuffer(directContext, cpuMesh.refIndexBuffer()); gpuMesh = SkMesh::MakeIndexed(cpuMesh.refSpec(), cpuMesh.mode(), vb, cpuMesh.vertexCount(), cpuMesh.vertexOffset(), ib, cpuMesh.indexCount(), cpuMesh.indexOffset(), @@ -558,6 +556,9 @@ struct DrawSkMesh final : Op { } c->drawMesh(gpuMesh, blender, paint); +#else + c->drawMesh(cpuMesh, blender, paint); +#endif } }; @@ -675,12 +676,11 @@ public: // because the webview functor still doesn't respect the canvas clip stack. const SkIRect deviceBounds = c->getDeviceClipBounds(); if (mLayerSurface == nullptr || c->imageInfo() != mLayerImageInfo) { - GrRecordingContext* directContext = c->recordingContext(); mLayerImageInfo = c->imageInfo().makeWH(deviceBounds.width(), deviceBounds.height()); - mLayerSurface = SkSurface::MakeRenderTarget(directContext, skgpu::Budgeted::kYes, - mLayerImageInfo, 0, - kTopLeft_GrSurfaceOrigin, nullptr); + // SkCanvas::makeSurface returns a new surface that will be GPU-backed if + // canvas was also. + mLayerSurface = c->makeSurface(mLayerImageInfo); } SkCanvas* layerCanvas = mLayerSurface->getCanvas(); @@ -752,10 +752,6 @@ inline void DisplayListData::map(const Fn fns[], Args... args) const { } } -void DisplayListData::flush() { - this->push<Flush>(0); -} - void DisplayListData::save() { this->push<Save>(0); } @@ -1047,10 +1043,6 @@ sk_sp<SkSurface> RecordingCanvas::onNewSurface(const SkImageInfo&, const SkSurfa return nullptr; } -void RecordingCanvas::onFlush() { - fDL->flush(); -} - void RecordingCanvas::willSave() { mSaveCount++; fDL->save(); diff --git a/libs/hwui/RecordingCanvas.h b/libs/hwui/RecordingCanvas.h index 1f4ba5d6d557..4f54ee286a56 100644 --- a/libs/hwui/RecordingCanvas.h +++ b/libs/hwui/RecordingCanvas.h @@ -127,8 +127,6 @@ public: private: friend class RecordingCanvas; - void flush(); - void save(); void saveLayer(const SkRect*, const SkPaint*, const SkImageFilter*, SkCanvas::SaveLayerFlags); void saveBehind(const SkRect*); @@ -208,8 +206,6 @@ public: void willRestore() override; bool onDoSaveBehind(const SkRect*) override; - void onFlush() override; - void didConcat44(const SkM44&) override; void didSetM44(const SkM44&) override; void didScale(SkScalar, SkScalar) override; diff --git a/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp index 1c39db3a31bb..1dd22cf43c5c 100644 --- a/libs/hwui/RenderNode.cpp +++ b/libs/hwui/RenderNode.cpp @@ -260,6 +260,12 @@ void RenderNode::prepareTreeImpl(TreeObserver& observer, TreeInfo& info, bool fu pushStagingDisplayListChanges(observer, info); } + // always damageSelf when filtering backdrop content, or else the BackdropFilterDrawable will + // get a wrong snapshot of previous content. + if (mProperties.layerProperties().getBackdropImageFilter()) { + damageSelf(info); + } + if (mDisplayList) { info.out.hasFunctors |= mDisplayList.hasFunctor(); mHasHolePunches = mDisplayList.hasHolePunches(); diff --git a/libs/hwui/RenderProperties.cpp b/libs/hwui/RenderProperties.cpp index 0589f136b666..c5371236b9cf 100644 --- a/libs/hwui/RenderProperties.cpp +++ b/libs/hwui/RenderProperties.cpp @@ -55,6 +55,12 @@ bool LayerProperties::setImageFilter(SkImageFilter* imageFilter) { return true; } +bool LayerProperties::setBackdropImageFilter(SkImageFilter* imageFilter) { + if (mBackdropImageFilter.get() == imageFilter) return false; + mBackdropImageFilter = sk_ref_sp(imageFilter); + return true; +} + bool LayerProperties::setFromPaint(const SkPaint* paint) { bool changed = false; changed |= setAlpha(static_cast<uint8_t>(PaintUtils::getAlphaDirect(paint))); @@ -70,6 +76,7 @@ LayerProperties& LayerProperties::operator=(const LayerProperties& other) { setXferMode(other.xferMode()); setColorFilter(other.getColorFilter()); setImageFilter(other.getImageFilter()); + setBackdropImageFilter(other.getBackdropImageFilter()); mStretchEffect = other.mStretchEffect; return *this; } diff --git a/libs/hwui/RenderProperties.h b/libs/hwui/RenderProperties.h index 064ba7aee107..e358b57f6fe1 100644 --- a/libs/hwui/RenderProperties.h +++ b/libs/hwui/RenderProperties.h @@ -97,8 +97,12 @@ public: bool setImageFilter(SkImageFilter* imageFilter); + bool setBackdropImageFilter(SkImageFilter* imageFilter); + SkImageFilter* getImageFilter() const { return mImageFilter.get(); } + SkImageFilter* getBackdropImageFilter() const { return mBackdropImageFilter.get(); } + const StretchEffect& getStretchEffect() const { return mStretchEffect; } StretchEffect& mutableStretchEffect() { return mStretchEffect; } @@ -129,6 +133,7 @@ private: SkBlendMode mMode; sk_sp<SkColorFilter> mColorFilter; sk_sp<SkImageFilter> mImageFilter; + sk_sp<SkImageFilter> mBackdropImageFilter; StretchEffect mStretchEffect; }; diff --git a/libs/hwui/SkiaCanvas.h b/libs/hwui/SkiaCanvas.h index b785989f35cb..ced02241ffe2 100644 --- a/libs/hwui/SkiaCanvas.h +++ b/libs/hwui/SkiaCanvas.h @@ -175,7 +175,7 @@ protected: const Paint& paint, const SkPath& path, size_t start, size_t end) override; - void onFilterPaint(Paint& paint); + virtual void onFilterPaint(Paint& paint); Paint filterPaint(const Paint& src) { Paint dst(src); diff --git a/libs/hwui/SkiaInterpolator.cpp b/libs/hwui/SkiaInterpolator.cpp index b58f517834a3..c67b135855f7 100644 --- a/libs/hwui/SkiaInterpolator.cpp +++ b/libs/hwui/SkiaInterpolator.cpp @@ -18,9 +18,8 @@ #include "include/core/SkScalar.h" #include "include/core/SkTypes.h" -#include "include/private/SkFixed.h" -#include "src/core/SkTSearch.h" +#include <cstdlib> #include <log/log.h> typedef int Dot14; @@ -41,18 +40,18 @@ static inline Dot14 pin_and_convert(float x) { if (x <= 0) { return 0; } - if (x >= SK_Scalar1) { + if (x >= 1.0f) { return Dot14_ONE; } - return SkScalarToFixed(x) >> 2; + return static_cast<Dot14>(x * Dot14_ONE); } static float SkUnitCubicInterp(float value, float bx, float by, float cx, float cy) { // pin to the unit-square, and convert to 2.14 Dot14 x = pin_and_convert(value); - if (x == 0) return 0; - if (x == Dot14_ONE) return SK_Scalar1; + if (x == 0) return 0.0f; + if (x == Dot14_ONE) return 1.0f; Dot14 b = pin_and_convert(bx); Dot14 c = pin_and_convert(cx); @@ -84,7 +83,7 @@ static float SkUnitCubicInterp(float value, float bx, float by, float cx, float A = 3 * b; B = 3 * (c - 2 * b); C = 3 * (b - c) + Dot14_ONE; - return SkFixedToScalar(eval_cubic(t, A, B, C) << 2); + return Dot14ToFloat(eval_cubic(t, A, B, C)); } /////////////////////////////////////////////////////////////////////////////////////////////////// @@ -104,7 +103,7 @@ void SkiaInterpolatorBase::reset(int elemCount, int frameCount) { fFlags = 0; fElemCount = static_cast<uint8_t>(elemCount); fFrameCount = static_cast<int16_t>(frameCount); - fRepeat = SK_Scalar1; + fRepeat = 1.0f; if (fStorage) { free(fStorage); fStorage = nullptr; @@ -136,17 +135,46 @@ bool SkiaInterpolatorBase::getDuration(SkMSec* startTime, SkMSec* endTime) const float SkiaInterpolatorBase::ComputeRelativeT(SkMSec time, SkMSec prevTime, SkMSec nextTime, const float blend[4]) { - SkASSERT(time > prevTime && time < nextTime); + LOG_FATAL_IF(time < prevTime || time > nextTime); float t = (float)(time - prevTime) / (float)(nextTime - prevTime); return blend ? SkUnitCubicInterp(t, blend[0], blend[1], blend[2], blend[3]) : t; } +// Returns the index of where the item is or the bit not of the index +// where the item should go in order to keep arr sorted in ascending order. +int SkiaInterpolatorBase::binarySearch(const SkTimeCode* arr, int count, SkMSec target) { + if (count <= 0) { + return ~0; + } + + int lo = 0; + int hi = count - 1; + + while (lo < hi) { + int mid = (hi + lo) / 2; + SkMSec elem = arr[mid].fTime; + if (elem == target) { + return mid; + } else if (elem < target) { + lo = mid + 1; + } else { + hi = mid; + } + } + // Check to see if target is greater or less than where we stopped + if (target < arr[lo].fTime) { + return ~lo; + } + // e.g. it should go at the end. + return ~(lo + 1); +} + SkiaInterpolatorBase::Result SkiaInterpolatorBase::timeToT(SkMSec time, float* T, int* indexPtr, bool* exactPtr) const { - SkASSERT(fFrameCount > 0); + LOG_FATAL_IF(fFrameCount <= 0); Result result = kNormal_Result; - if (fRepeat != SK_Scalar1) { + if (fRepeat != 1.0f) { SkMSec startTime = 0, endTime = 0; // initialize to avoid warning this->getDuration(&startTime, &endTime); SkMSec totalTime = endTime - startTime; @@ -168,10 +196,8 @@ SkiaInterpolatorBase::Result SkiaInterpolatorBase::timeToT(SkMSec time, float* T time = offsetTime + startTime; } - int index = SkTSearch<SkMSec>(&fTimes[0].fTime, fFrameCount, time, sizeof(SkTimeCode)); - + int index = SkiaInterpolatorBase::binarySearch(fTimes, fFrameCount, time); bool exact = true; - if (index < 0) { index = ~index; if (index == 0) { @@ -184,10 +210,11 @@ SkiaInterpolatorBase::Result SkiaInterpolatorBase::timeToT(SkMSec time, float* T } result = kFreezeEnd_Result; } else { + // Need to interpolate between two frames. exact = false; } } - SkASSERT(index < fFrameCount); + LOG_FATAL_IF(index >= fFrameCount); const SkTimeCode* nextTime = &fTimes[index]; SkMSec nextT = nextTime[0].fTime; if (exact) { @@ -207,7 +234,7 @@ SkiaInterpolator::SkiaInterpolator() { } SkiaInterpolator::SkiaInterpolator(int elemCount, int frameCount) { - SkASSERT(elemCount > 0); + LOG_FATAL_IF(elemCount <= 0); this->reset(elemCount, frameCount); } @@ -221,21 +248,19 @@ void SkiaInterpolator::reset(int elemCount, int frameCount) { fValues = (float*)((char*)fStorage + sizeof(SkTimeCode) * frameCount); } -#define SK_Fixed1Third (SK_Fixed1 / 3) -#define SK_Fixed2Third (SK_Fixed1 * 2 / 3) - static const float gIdentityBlend[4] = {0.33333333f, 0.33333333f, 0.66666667f, 0.66666667f}; bool SkiaInterpolator::setKeyFrame(int index, SkMSec time, const float values[], const float blend[4]) { - SkASSERT(values != nullptr); + LOG_FATAL_IF(values == nullptr); if (blend == nullptr) { blend = gIdentityBlend; } - bool success = ~index == SkTSearch<SkMSec>(&fTimes->fTime, index, time, sizeof(SkTimeCode)); - SkASSERT(success); + // Verify the time should go after all the frames before index + bool success = ~index == SkiaInterpolatorBase::binarySearch(fTimes, index, time); + LOG_FATAL_IF(!success); if (success) { SkTimeCode* timeCode = &fTimes[index]; timeCode->fTime = time; @@ -257,7 +282,7 @@ SkiaInterpolator::Result SkiaInterpolator::timeToValues(SkMSec time, float value if (exact) { memcpy(values, nextSrc, fElemCount * sizeof(float)); } else { - SkASSERT(index > 0); + LOG_FATAL_IF(index <= 0); const float* prevSrc = nextSrc - fElemCount; diff --git a/libs/hwui/SkiaInterpolator.h b/libs/hwui/SkiaInterpolator.h index 9422cb526a8f..62e6c1e33e40 100644 --- a/libs/hwui/SkiaInterpolator.h +++ b/libs/hwui/SkiaInterpolator.h @@ -68,14 +68,16 @@ protected: enum Flags { kMirror = 1, kReset = 2, kHasBlend = 4 }; static float ComputeRelativeT(uint32_t time, uint32_t prevTime, uint32_t nextTime, const float blend[4] = nullptr); - int16_t fFrameCount; - uint8_t fElemCount; - uint8_t fFlags; - float fRepeat; struct SkTimeCode { uint32_t fTime; float fBlend[4]; }; + static int binarySearch(const SkTimeCode* arr, int count, uint32_t target); + + int16_t fFrameCount; + uint8_t fElemCount; + uint8_t fFlags; + float fRepeat; SkTimeCode* fTimes; // pointer into fStorage void* fStorage; }; diff --git a/libs/hwui/SkiaWrapper.h b/libs/hwui/SkiaWrapper.h new file mode 100644 index 000000000000..bd0e35aadbb4 --- /dev/null +++ b/libs/hwui/SkiaWrapper.h @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SKIA_WRAPPER_H_ +#define SKIA_WRAPPER_H_ + +#include <SkRefCnt.h> +#include <utils/RefBase.h> + +namespace android::uirenderer { + +template <typename T> +class SkiaWrapper : public VirtualLightRefBase { +public: + sk_sp<T> getInstance() { + if (mInstance != nullptr && shouldDiscardInstance()) { + mInstance = nullptr; + } + + if (mInstance == nullptr) { + mInstance = createInstance(); + mGenerationId++; + } + return mInstance; + } + + virtual bool shouldDiscardInstance() const { return false; } + + void discardInstance() { mInstance = nullptr; } + + [[nodiscard]] int32_t getGenerationId() const { return mGenerationId; } + +protected: + virtual sk_sp<T> createInstance() = 0; + +private: + sk_sp<T> mInstance = nullptr; + int32_t mGenerationId = 0; +}; + +} // namespace android::uirenderer + +#endif // SKIA_WRAPPER_H_ diff --git a/libs/hwui/apex/android_canvas.cpp b/libs/hwui/apex/android_canvas.cpp index 905b123076a2..19f726a31b33 100644 --- a/libs/hwui/apex/android_canvas.cpp +++ b/libs/hwui/apex/android_canvas.cpp @@ -45,9 +45,9 @@ static bool convert(const ANativeWindow_Buffer* buffer, SkImageInfo imageInfo = uirenderer::ANativeWindowToImageInfo(*buffer, cs); size_t rowBytes = buffer->stride * imageInfo.bytesPerPixel(); - // If SkSurface::MakeRasterDirect fails then we should as well as we will not be able to + // If SkSurfaces::WrapPixels fails then we should as well as we will not be able to // draw into the canvas. - sk_sp<SkSurface> surface = SkSurface::MakeRasterDirect(imageInfo, buffer->bits, rowBytes); + sk_sp<SkSurface> surface = SkSurfaces::WrapPixels(imageInfo, buffer->bits, rowBytes); if (surface.get() != nullptr) { if (outBitmap) { outBitmap->setInfo(imageInfo, rowBytes); diff --git a/libs/hwui/hwui/AnimatedImageDrawable.cpp b/libs/hwui/hwui/AnimatedImageDrawable.cpp index 8049dc946c9e..27773a60355a 100644 --- a/libs/hwui/hwui/AnimatedImageDrawable.cpp +++ b/libs/hwui/hwui/AnimatedImageDrawable.cpp @@ -111,7 +111,7 @@ AnimatedImageDrawable::Snapshot AnimatedImageDrawable::decodeNextFrame() { { std::unique_lock lock{mImageLock}; snap.mDurationMS = adjustFrameDuration(mSkAnimatedImage->decodeNextFrame()); - snap.mPic.reset(mSkAnimatedImage->newPictureSnapshot()); + snap.mPic = mSkAnimatedImage->makePictureSnapshot(); } return snap; @@ -123,7 +123,7 @@ AnimatedImageDrawable::Snapshot AnimatedImageDrawable::reset() { { std::unique_lock lock{mImageLock}; mSkAnimatedImage->reset(); - snap.mPic.reset(mSkAnimatedImage->newPictureSnapshot()); + snap.mPic = mSkAnimatedImage->makePictureSnapshot(); snap.mDurationMS = currentFrameDuration(); } diff --git a/libs/hwui/hwui/Bitmap.cpp b/libs/hwui/hwui/Bitmap.cpp index 92d875bf7f1e..8344a86923ee 100644 --- a/libs/hwui/hwui/Bitmap.cpp +++ b/libs/hwui/hwui/Bitmap.cpp @@ -43,12 +43,15 @@ #include <SkColor.h> #include <SkEncodedImageFormat.h> #include <SkHighContrastFilter.h> -#include <SkImageEncoder.h> +#include <SkImage.h> +#include <SkImageAndroid.h> #include <SkImagePriv.h> #include <SkJpegGainmapEncoder.h> #include <SkPixmap.h> #include <SkRect.h> #include <SkStream.h> +#include <SkJpegEncoder.h> +#include <SkPngEncoder.h> #include <SkWebpEncoder.h> #include <limits> @@ -296,7 +299,8 @@ Bitmap::Bitmap(AHardwareBuffer* buffer, const SkImageInfo& info, size_t rowBytes mPixelStorage.hardware.size = AHardwareBuffer_getAllocationSize(buffer); AHardwareBuffer_acquire(buffer); setImmutable(); // HW bitmaps are always immutable - mImage = SkImage::MakeFromAHardwareBuffer(buffer, mInfo.alphaType(), mInfo.refColorSpace()); + mImage = SkImages::DeferredFromAHardwareBuffer(buffer, mInfo.alphaType(), + mInfo.refColorSpace()); } #endif @@ -407,7 +411,12 @@ sk_sp<SkImage> Bitmap::makeImage() { // Note we don't cache in this case, because the raster image holds a pointer to this Bitmap // internally and ~Bitmap won't be invoked. // TODO: refactor Bitmap to not derive from SkPixelRef, which would allow caching here. +#ifdef __ANDROID__ + // pinnable images are only supported with the Ganesh GPU backend compiled in. + image = SkImages::PinnableRasterFromBitmap(skiaBitmap); +#else image = SkMakeImageFromRasterBitmap(skiaBitmap, kNever_SkCopyPixelsMode); +#endif } return image; } @@ -528,17 +537,25 @@ bool Bitmap::compress(const SkBitmap& bitmap, JavaCompressFormat format, return false; } - SkEncodedImageFormat fm; switch (format) { - case JavaCompressFormat::Jpeg: - fm = SkEncodedImageFormat::kJPEG; - break; + case JavaCompressFormat::Jpeg: { + SkJpegEncoder::Options options; + options.fQuality = quality; + return SkJpegEncoder::Encode(stream, bitmap.pixmap(), options); + } case JavaCompressFormat::Png: - fm = SkEncodedImageFormat::kPNG; - break; - case JavaCompressFormat::Webp: - fm = SkEncodedImageFormat::kWEBP; - break; + return SkPngEncoder::Encode(stream, bitmap.pixmap(), {}); + case JavaCompressFormat::Webp: { + SkWebpEncoder::Options options; + if (quality >= 100) { + options.fCompression = SkWebpEncoder::Compression::kLossless; + options.fQuality = 75; // This is effort to compress + } else { + options.fCompression = SkWebpEncoder::Compression::kLossy; + options.fQuality = quality; + } + return SkWebpEncoder::Encode(stream, bitmap.pixmap(), options); + } case JavaCompressFormat::WebpLossy: case JavaCompressFormat::WebpLossless: { SkWebpEncoder::Options options; @@ -548,8 +565,6 @@ bool Bitmap::compress(const SkBitmap& bitmap, JavaCompressFormat format, return SkWebpEncoder::Encode(stream, bitmap.pixmap(), options); } } - - return SkEncodeImage(stream, bitmap, fm, quality); } sp<uirenderer::Gainmap> Bitmap::gainmap() const { diff --git a/libs/hwui/hwui/Canvas.cpp b/libs/hwui/hwui/Canvas.cpp index cd8af3d933b1..2351797ac787 100644 --- a/libs/hwui/hwui/Canvas.cpp +++ b/libs/hwui/hwui/Canvas.cpp @@ -151,7 +151,7 @@ void Canvas::drawGlyphs(const minikin::Font& font, const int* glyphIds, const fl memcpy(outPositions, positions, sizeof(float) * 2 * glyphCount); }; - const minikin::MinikinFont* minikinFont = font.typeface().get(); + const minikin::MinikinFont* minikinFont = font.baseTypeface().get(); SkFont* skfont = &copied.getSkFont(); MinikinFontSkia::populateSkFont(skfont, minikinFont, minikin::FontFakery()); diff --git a/libs/hwui/hwui/MinikinUtils.h b/libs/hwui/hwui/MinikinUtils.h index 009b84b140ea..51960b036c49 100644 --- a/libs/hwui/hwui/MinikinUtils.h +++ b/libs/hwui/hwui/MinikinUtils.h @@ -76,7 +76,7 @@ public: size_t start = 0; size_t nGlyphs = layout.nGlyphs(); for (size_t i = 0; i < nGlyphs; i++) { - const minikin::MinikinFont* nextFont = layout.getFont(i)->typeface().get(); + const minikin::MinikinFont* nextFont = layout.typeface(i).get(); if (i > 0 && nextFont != curFont) { SkFont* skfont = &paint->getSkFont(); MinikinFontSkia::populateSkFont(skfont, curFont, layout.getFakery(start)); diff --git a/libs/hwui/hwui/Typeface.cpp b/libs/hwui/hwui/Typeface.cpp index 3c67edc9a428..b63ee1bd3d98 100644 --- a/libs/hwui/hwui/Typeface.cpp +++ b/libs/hwui/hwui/Typeface.cpp @@ -140,9 +140,8 @@ Typeface* Typeface::createFromFamilies(std::vector<std::shared_ptr<minikin::Font const minikin::FontStyle defaultStyle; const minikin::MinikinFont* mf = - families.empty() - ? nullptr - : families[0]->getClosestMatch(defaultStyle).font->typeface().get(); + families.empty() ? nullptr + : families[0]->getClosestMatch(defaultStyle).typeface().get(); if (mf != nullptr) { SkTypeface* skTypeface = reinterpret_cast<const MinikinFontSkia*>(mf)->GetSkTypeface(); const SkFontStyle& style = skTypeface->fontStyle(); diff --git a/libs/hwui/jni/AnimatedImageDrawable.cpp b/libs/hwui/jni/AnimatedImageDrawable.cpp index a7f5aa83e624..90b1da846205 100644 --- a/libs/hwui/jni/AnimatedImageDrawable.cpp +++ b/libs/hwui/jni/AnimatedImageDrawable.cpp @@ -14,10 +14,6 @@ * limitations under the License. */ -#include "GraphicsJNI.h" -#include "ImageDecoder.h" -#include "Utils.h" - #include <SkAndroidCodec.h> #include <SkAnimatedImage.h> #include <SkColorFilter.h> @@ -27,10 +23,15 @@ #include <SkRect.h> #include <SkRefCnt.h> #include <hwui/AnimatedImageDrawable.h> -#include <hwui/ImageDecoder.h> #include <hwui/Canvas.h> +#include <hwui/ImageDecoder.h> #include <utils/Looper.h> +#include "ColorFilter.h" +#include "GraphicsJNI.h" +#include "ImageDecoder.h" +#include "Utils.h" + using namespace android; static jclass gAnimatedImageDrawableClass; @@ -145,8 +146,9 @@ static jlong AnimatedImageDrawable_nGetAlpha(JNIEnv* env, jobject /*clazz*/, jlo static void AnimatedImageDrawable_nSetColorFilter(JNIEnv* env, jobject /*clazz*/, jlong nativePtr, jlong nativeFilter) { auto* drawable = reinterpret_cast<AnimatedImageDrawable*>(nativePtr); - auto* filter = reinterpret_cast<SkColorFilter*>(nativeFilter); - drawable->setStagingColorFilter(sk_ref_sp(filter)); + auto filter = uirenderer::ColorFilter::fromJava(nativeFilter); + auto skColorFilter = filter != nullptr ? filter->getInstance() : sk_sp<SkColorFilter>(); + drawable->setStagingColorFilter(skColorFilter); } static jboolean AnimatedImageDrawable_nIsRunning(JNIEnv* env, jobject /*clazz*/, jlong nativePtr) { diff --git a/libs/hwui/jni/ColorFilter.cpp b/libs/hwui/jni/ColorFilter.cpp index 4bd7ef47b871..0b95148d3c82 100644 --- a/libs/hwui/jni/ColorFilter.cpp +++ b/libs/hwui/jni/ColorFilter.cpp @@ -15,20 +15,21 @@ ** limitations under the License. */ -#include "GraphicsJNI.h" +#include "ColorFilter.h" +#include "GraphicsJNI.h" #include "SkBlendMode.h" -#include "SkColorFilter.h" -#include "SkColorMatrixFilter.h" namespace android { using namespace uirenderer; -class SkColorFilterGlue { +class ColorFilterGlue { public: - static void SafeUnref(SkColorFilter* filter) { - SkSafeUnref(filter); + static void SafeUnref(ColorFilter* filter) { + if (filter) { + filter->decStrong(nullptr); + } } static jlong GetNativeFinalizer(JNIEnv*, jobject) { @@ -36,41 +37,75 @@ public: } static jlong CreateBlendModeFilter(JNIEnv* env, jobject, jint srcColor, jint modeHandle) { - SkBlendMode mode = static_cast<SkBlendMode>(modeHandle); - return reinterpret_cast<jlong>(SkColorFilters::Blend(srcColor, mode).release()); + auto mode = static_cast<SkBlendMode>(modeHandle); + auto* blendModeFilter = new BlendModeColorFilter(srcColor, mode); + blendModeFilter->incStrong(nullptr); + return static_cast<jlong>(reinterpret_cast<uintptr_t>(blendModeFilter)); } static jlong CreateLightingFilter(JNIEnv* env, jobject, jint mul, jint add) { - return reinterpret_cast<jlong>(SkColorMatrixFilter::MakeLightingFilter(mul, add).release()); + auto* lightingFilter = new LightingFilter(mul, add); + lightingFilter->incStrong(nullptr); + return static_cast<jlong>(reinterpret_cast<uintptr_t>(lightingFilter)); } - static jlong CreateColorMatrixFilter(JNIEnv* env, jobject, jfloatArray jarray) { - float matrix[20]; - env->GetFloatArrayRegion(jarray, 0, 20, matrix); + static void SetLightingFilterMul(JNIEnv* env, jobject, jlong lightingFilterPtr, jint mul) { + auto* filter = reinterpret_cast<LightingFilter*>(lightingFilterPtr); + if (filter) { + filter->setMul(mul); + } + } + + static void SetLightingFilterAdd(JNIEnv* env, jobject, jlong lightingFilterPtr, jint add) { + auto* filter = reinterpret_cast<LightingFilter*>(lightingFilterPtr); + if (filter) { + filter->setAdd(add); + } + } + + static std::vector<float> getMatrixFromJFloatArray(JNIEnv* env, jfloatArray jarray) { + std::vector<float> matrix(20); + // float matrix[20]; + env->GetFloatArrayRegion(jarray, 0, 20, matrix.data()); // java biases the translates by 255, so undo that before calling skia matrix[ 4] *= (1.0f/255); matrix[ 9] *= (1.0f/255); matrix[14] *= (1.0f/255); matrix[19] *= (1.0f/255); - return reinterpret_cast<jlong>(SkColorFilters::Matrix(matrix).release()); + return matrix; + } + + static jlong CreateColorMatrixFilter(JNIEnv* env, jobject, jfloatArray jarray) { + std::vector<float> matrix = getMatrixFromJFloatArray(env, jarray); + auto* colorMatrixColorFilter = new ColorMatrixColorFilter(std::move(matrix)); + colorMatrixColorFilter->incStrong(nullptr); + return static_cast<jlong>(reinterpret_cast<uintptr_t>(colorMatrixColorFilter)); + } + + static void SetColorMatrix(JNIEnv* env, jobject, jlong colorMatrixColorFilterPtr, + jfloatArray jarray) { + auto* filter = reinterpret_cast<ColorMatrixColorFilter*>(colorMatrixColorFilterPtr); + if (filter) { + filter->setMatrix(getMatrixFromJFloatArray(env, jarray)); + } } }; static const JNINativeMethod colorfilter_methods[] = { - {"nativeGetFinalizer", "()J", (void*) SkColorFilterGlue::GetNativeFinalizer } -}; + {"nativeGetFinalizer", "()J", (void*)ColorFilterGlue::GetNativeFinalizer}}; static const JNINativeMethod blendmode_methods[] = { - { "native_CreateBlendModeFilter", "(II)J", (void*) SkColorFilterGlue::CreateBlendModeFilter }, + {"native_CreateBlendModeFilter", "(II)J", (void*)ColorFilterGlue::CreateBlendModeFilter}, }; static const JNINativeMethod lighting_methods[] = { - { "native_CreateLightingFilter", "(II)J", (void*) SkColorFilterGlue::CreateLightingFilter }, -}; + {"native_CreateLightingFilter", "(II)J", (void*)ColorFilterGlue::CreateLightingFilter}, + {"native_SetLightingFilterAdd", "(JI)V", (void*)ColorFilterGlue::SetLightingFilterAdd}, + {"native_SetLightingFilterMul", "(JI)V", (void*)ColorFilterGlue::SetLightingFilterMul}}; static const JNINativeMethod colormatrix_methods[] = { - { "nativeColorMatrixFilter", "([F)J", (void*) SkColorFilterGlue::CreateColorMatrixFilter }, -}; + {"nativeColorMatrixFilter", "([F)J", (void*)ColorFilterGlue::CreateColorMatrixFilter}, + {"nativeSetColorMatrix", "(J[F)V", (void*)ColorFilterGlue::SetColorMatrix}}; int register_android_graphics_ColorFilter(JNIEnv* env) { android::RegisterMethodsOrDie(env, "android/graphics/ColorFilter", colorfilter_methods, diff --git a/libs/hwui/jni/CreateJavaOutputStreamAdaptor.cpp b/libs/hwui/jni/CreateJavaOutputStreamAdaptor.cpp index 15e529e169fc..a66d3b860ade 100644 --- a/libs/hwui/jni/CreateJavaOutputStreamAdaptor.cpp +++ b/libs/hwui/jni/CreateJavaOutputStreamAdaptor.cpp @@ -1,11 +1,11 @@ #include "CreateJavaOutputStreamAdaptor.h" #include "SkData.h" -#include "SkMalloc.h" #include "SkRefCnt.h" #include "SkStream.h" #include "SkTypes.h" #include "Utils.h" +#include <cstdlib> #include <nativehelper/JNIHelp.h> #include <log/log.h> #include <memory> @@ -177,6 +177,10 @@ SkStream* CreateJavaInputStreamAdaptor(JNIEnv* env, jobject stream, jbyteArray s return JavaInputStreamAdaptor::Create(env, stream, storage, swallowExceptions); } +static void free_pointer_skproc(const void* ptr, void*) { + free((void*)ptr); +} + sk_sp<SkData> CopyJavaInputStream(JNIEnv* env, jobject inputStream, jbyteArray storage) { std::unique_ptr<SkStream> stream(CreateJavaInputStreamAdaptor(env, inputStream, storage)); if (!stream) { @@ -186,19 +190,31 @@ sk_sp<SkData> CopyJavaInputStream(JNIEnv* env, jobject inputStream, jbyteArray s size_t bufferSize = 4096; size_t streamLen = 0; size_t len; - char* data = (char*)sk_malloc_throw(bufferSize); + char* data = (char*)malloc(bufferSize); + LOG_ALWAYS_FATAL_IF(!data); while ((len = stream->read(data + streamLen, bufferSize - streamLen)) != 0) { streamLen += len; if (streamLen == bufferSize) { bufferSize *= 2; - data = (char*)sk_realloc_throw(data, bufferSize); + data = (char*)realloc(data, bufferSize); + LOG_ALWAYS_FATAL_IF(!data); } } - data = (char*)sk_realloc_throw(data, streamLen); - - return SkData::MakeFromMalloc(data, streamLen); + if (streamLen == 0) { + // realloc with size 0 is unspecified behavior in C++11 + free(data); + data = nullptr; + } else { + // Trim down the buffer to the actual size of the data. + LOG_FATAL_IF(streamLen > bufferSize); + data = (char*)realloc(data, streamLen); + LOG_ALWAYS_FATAL_IF(!data); + } + // Just in case sk_free differs from free, we ask Skia to use + // free to cleanup the buffer that SkData wraps. + return SkData::MakeWithProc(data, streamLen, free_pointer_skproc, nullptr); } /////////////////////////////////////////////////////////////////////////////// diff --git a/libs/hwui/jni/FontFamily.cpp b/libs/hwui/jni/FontFamily.cpp index 69774cc6e133..af1668fbd7dd 100644 --- a/libs/hwui/jni/FontFamily.cpp +++ b/libs/hwui/jni/FontFamily.cpp @@ -89,7 +89,8 @@ static jlong FontFamily_create(CRITICAL_JNI_PARAMS_COMMA jlong builderPtr) { } std::shared_ptr<minikin::FontFamily> family = minikin::FontFamily::create( builder->langId, builder->variant, std::move(builder->fonts), - true /* isCustomFallback */, false /* isDefaultFallback */); + true /* isCustomFallback */, false /* isDefaultFallback */, + minikin::VariationFamilyType::None); if (family->getCoverage().length() == 0) { return 0; } diff --git a/libs/hwui/jni/GraphicsJNI.h b/libs/hwui/jni/GraphicsJNI.h index 23ab5dd38b1a..b9fff36d372e 100644 --- a/libs/hwui/jni/GraphicsJNI.h +++ b/libs/hwui/jni/GraphicsJNI.h @@ -125,14 +125,6 @@ public: static jobject createBitmapRegionDecoder(JNIEnv* env, android::BitmapRegionDecoderWrapper* bitmap); - /** - * Given a bitmap we natively allocate a memory block to store the contents - * of that bitmap. The memory is then attached to the bitmap via an - * SkPixelRef, which ensures that upon deletion the appropriate caches - * are notified. - */ - static bool allocatePixels(JNIEnv* env, SkBitmap* bitmap); - /** Copy the colors in colors[] to the bitmap, convert to the correct format along the way. Whether to use premultiplied pixels is determined by dstBitmap's alphaType. diff --git a/libs/hwui/jni/MaskFilter.cpp b/libs/hwui/jni/MaskFilter.cpp index 048ce025ce27..cbd452031f69 100644 --- a/libs/hwui/jni/MaskFilter.cpp +++ b/libs/hwui/jni/MaskFilter.cpp @@ -1,6 +1,5 @@ #include "GraphicsJNI.h" #include "SkMaskFilter.h" -#include "SkBlurMask.h" #include "SkBlurMaskFilter.h" #include "SkBlurTypes.h" #include "SkTableMaskFilter.h" @@ -11,6 +10,13 @@ static void ThrowIAE_IfNull(JNIEnv* env, void* ptr) { } } +// From https://skia.googlesource.com/skia/+/d74c99a3cd5eef5f16b2eb226e6b45fe523c8552/src/core/SkBlurMask.cpp#28 +static constexpr float kBLUR_SIGMA_SCALE = 0.57735f; + +static float convertRadiusToSigma(float radius) { + return radius > 0 ? kBLUR_SIGMA_SCALE * radius + 0.5f : 0.0f; +} + class SkMaskFilterGlue { public: static void destructor(JNIEnv* env, jobject, jlong filterHandle) { @@ -19,7 +25,7 @@ public: } static jlong createBlur(JNIEnv* env, jobject, jfloat radius, jint blurStyle) { - SkScalar sigma = SkBlurMask::ConvertRadiusToSigma(radius); + SkScalar sigma = convertRadiusToSigma(radius); SkMaskFilter* filter = SkMaskFilter::MakeBlur((SkBlurStyle)blurStyle, sigma).release(); ThrowIAE_IfNull(env, filter); return reinterpret_cast<jlong>(filter); @@ -34,7 +40,7 @@ public: direction[i] = values[i]; } - SkScalar sigma = SkBlurMask::ConvertRadiusToSigma(radius); + SkScalar sigma = convertRadiusToSigma(radius); SkMaskFilter* filter = SkBlurMaskFilter::MakeEmboss(sigma, direction, ambient, specular).release(); ThrowIAE_IfNull(env, filter); diff --git a/libs/hwui/jni/Paint.cpp b/libs/hwui/jni/Paint.cpp index 13357fa25e8c..d2a4efe05219 100644 --- a/libs/hwui/jni/Paint.cpp +++ b/libs/hwui/jni/Paint.cpp @@ -18,27 +18,6 @@ #undef LOG_TAG #define LOG_TAG "Paint" -#include <utils/Log.h> - -#include "GraphicsJNI.h" -#include <nativehelper/ScopedStringChars.h> -#include <nativehelper/ScopedUtfChars.h> -#include <nativehelper/ScopedPrimitiveArray.h> - -#include "SkColorFilter.h" -#include "SkColorSpace.h" -#include "SkFont.h" -#include "SkFontMetrics.h" -#include "SkFontTypes.h" -#include "SkMaskFilter.h" -#include "SkPath.h" -#include "SkPathEffect.h" -#include "SkPathUtils.h" -#include "SkShader.h" -#include "SkBlendMode.h" -#include "unicode/uloc.h" -#include "utils/Blur.h" - #include <hwui/BlurDrawLooper.h> #include <hwui/MinikinSkia.h> #include <hwui/MinikinUtils.h> @@ -48,13 +27,33 @@ #include <minikin/LocaleList.h> #include <minikin/Measurement.h> #include <minikin/MinikinPaint.h> +#include <nativehelper/ScopedPrimitiveArray.h> +#include <nativehelper/ScopedStringChars.h> +#include <nativehelper/ScopedUtfChars.h> #include <unicode/utf16.h> +#include <utils/Log.h> #include <cassert> #include <cstring> #include <memory> #include <vector> +#include "ColorFilter.h" +#include "GraphicsJNI.h" +#include "SkBlendMode.h" +#include "SkColorFilter.h" +#include "SkColorSpace.h" +#include "SkFont.h" +#include "SkFontMetrics.h" +#include "SkFontTypes.h" +#include "SkMaskFilter.h" +#include "SkPath.h" +#include "SkPathEffect.h" +#include "SkPathUtils.h" +#include "SkShader.h" +#include "unicode/uloc.h" +#include "utils/Blur.h" + namespace android { static void getPosTextPath(const SkFont& font, const uint16_t glyphs[], int count, @@ -584,7 +583,7 @@ namespace PaintGlue { minikin::FakedFont baseFont = typeface->fFontCollection->baseFontFaked(typeface->fStyle); float saveSkewX = font->getSkewX(); bool savefakeBold = font->isEmbolden(); - MinikinFontSkia::populateSkFont(font, baseFont.font->typeface().get(), baseFont.fakery); + MinikinFontSkia::populateSkFont(font, baseFont.typeface().get(), baseFont.fakery); SkScalar spacing = font->getMetrics(metrics); // The populateSkPaint call may have changed fake bold / text skew // because we want to measure with those effects applied, so now @@ -821,9 +820,11 @@ namespace PaintGlue { static jlong setColorFilter(CRITICAL_JNI_PARAMS_COMMA jlong objHandle, jlong filterHandle) { Paint* obj = reinterpret_cast<Paint *>(objHandle); - SkColorFilter* filter = reinterpret_cast<SkColorFilter *>(filterHandle); - obj->setColorFilter(sk_ref_sp(filter)); - return reinterpret_cast<jlong>(obj->getColorFilter()); + auto colorFilter = uirenderer::ColorFilter::fromJava(filterHandle); + auto skColorFilter = + colorFilter != nullptr ? colorFilter->getInstance() : sk_sp<SkColorFilter>(); + obj->setColorFilter(skColorFilter); + return filterHandle; } static void setXfermode(CRITICAL_JNI_PARAMS_COMMA jlong paintHandle, jint xfermodeHandle) { diff --git a/libs/hwui/jni/RenderEffect.cpp b/libs/hwui/jni/RenderEffect.cpp index f3db1705e694..dcd3fa4932fc 100644 --- a/libs/hwui/jni/RenderEffect.cpp +++ b/libs/hwui/jni/RenderEffect.cpp @@ -14,13 +14,13 @@ * limitations under the License. */ #include "Bitmap.h" +#include "ColorFilter.h" #include "GraphicsJNI.h" #include "SkBlendMode.h" #include "SkImageFilter.h" #include "SkImageFilters.h" #include "graphics_jni_helpers.h" #include "utils/Blur.h" -#include <utils/Log.h> using namespace android::uirenderer; @@ -76,11 +76,13 @@ static jlong createColorFilterEffect( jlong colorFilterHandle, jlong inputFilterHandle ) { - auto* colorFilter = reinterpret_cast<const SkColorFilter*>(colorFilterHandle); + auto colorFilter = android::uirenderer::ColorFilter::fromJava(colorFilterHandle); + auto skColorFilter = + colorFilter != nullptr ? colorFilter->getInstance() : sk_sp<SkColorFilter>(); auto* inputFilter = reinterpret_cast<const SkImageFilter*>(inputFilterHandle); - sk_sp<SkImageFilter> colorFilterImageFilter = SkImageFilters::ColorFilter( - sk_ref_sp(colorFilter), sk_ref_sp(inputFilter), nullptr); - return reinterpret_cast<jlong>(colorFilterImageFilter.release()); + sk_sp<SkImageFilter> colorFilterImageFilter = + SkImageFilters::ColorFilter(skColorFilter, sk_ref_sp(inputFilter), nullptr); + return reinterpret_cast<jlong>(colorFilterImageFilter.release()); } static jlong createBlendModeEffect( diff --git a/libs/hwui/jni/android_graphics_DisplayListCanvas.cpp b/libs/hwui/jni/android_graphics_DisplayListCanvas.cpp index f060bb32031a..426644ee6a4e 100644 --- a/libs/hwui/jni/android_graphics_DisplayListCanvas.cpp +++ b/libs/hwui/jni/android_graphics_DisplayListCanvas.cpp @@ -84,7 +84,7 @@ static void android_view_DisplayListCanvas_resetDisplayListCanvas(CRITICAL_JNI_P canvas->resetRecording(width, height, renderNode); } -static jint android_view_DisplayListCanvas_getMaxTextureSize(CRITICAL_JNI_PARAMS) { +static jint android_view_DisplayListCanvas_getMaxTextureSize(JNIEnv*, jobject) { #ifdef __ANDROID__ // Layoutlib does not support RenderProxy (RenderThread) return android::uirenderer::renderthread::RenderProxy::maxTextureSize(); #else @@ -175,14 +175,14 @@ static void android_view_DisplayListCanvas_drawWebViewFunctor(CRITICAL_JNI_PARAM const char* const kClassPathName = "android/graphics/RecordingCanvas"; static JNINativeMethod gMethods[] = { + {"nGetMaximumTextureWidth", "()I", (void*)android_view_DisplayListCanvas_getMaxTextureSize}, + {"nGetMaximumTextureHeight", "()I", + (void*)android_view_DisplayListCanvas_getMaxTextureSize}, // ------------ @CriticalNative -------------- {"nCreateDisplayListCanvas", "(JII)J", (void*)android_view_DisplayListCanvas_createDisplayListCanvas}, {"nResetDisplayListCanvas", "(JJII)V", (void*)android_view_DisplayListCanvas_resetDisplayListCanvas}, - {"nGetMaximumTextureWidth", "()I", (void*)android_view_DisplayListCanvas_getMaxTextureSize}, - {"nGetMaximumTextureHeight", "()I", - (void*)android_view_DisplayListCanvas_getMaxTextureSize}, {"nEnableZ", "(JZ)V", (void*)android_view_DisplayListCanvas_enableZ}, {"nFinishRecording", "(JJ)V", (void*)android_view_DisplayListCanvas_finishRecording}, {"nDrawRenderNode", "(JJ)V", (void*)android_view_DisplayListCanvas_drawRenderNode}, diff --git a/libs/hwui/jni/android_graphics_HardwareRenderer.cpp b/libs/hwui/jni/android_graphics_HardwareRenderer.cpp index d04de37f6961..ee22f7c6cf03 100644 --- a/libs/hwui/jni/android_graphics_HardwareRenderer.cpp +++ b/libs/hwui/jni/android_graphics_HardwareRenderer.cpp @@ -27,7 +27,7 @@ #include <SkColorSpace.h> #include <SkData.h> #include <SkImage.h> -#include <SkImagePriv.h> +#include <SkImageAndroid.h> #include <SkPicture.h> #include <SkPixmap.h> #include <SkSerialProcs.h> @@ -35,6 +35,7 @@ #include <SkTypeface.h> #include <dlfcn.h> #include <gui/TraceUtils.h> +#include <include/encode/SkPngEncoder.h> #include <inttypes.h> #include <media/NdkImage.h> #include <media/NdkImageReader.h> @@ -54,6 +55,7 @@ #include <algorithm> #include <atomic> +#include <log/log.h> #include <vector> #include "JvmErrorReporter.h" @@ -477,7 +479,7 @@ public: // actually cross thread boundaries here, make a copy so it's immutable proper if (bitmap && !bitmap->isImmutable()) { ATRACE_NAME("Copying mutable bitmap"); - return SkImage::MakeFromBitmap(*bitmap); + return SkImages::RasterFromBitmap(*bitmap); } if (img->isTextureBacked()) { ATRACE_NAME("Readback of texture image"); @@ -497,7 +499,7 @@ public: return sk_ref_sp(img); } bm.setImmutable(); - return SkMakeImageFromRasterBitmap(bm, kNever_SkCopyPixelsMode); + return SkImages::PinnableRasterFromBitmap(bm); } return sk_ref_sp(img); } @@ -524,7 +526,16 @@ public: if (iter != context->mTextureMap.end()) { img = iter->second.get(); } - return img->encodeToData(); + if (!img) { + return nullptr; + } + // The following encode (specifically the pixel readback) will fail on a + // texture-backed image. They should already be raster images, but on + // the off-chance they aren't, we will just serialize it as nothing. + if (img->isTextureBacked()) { + return SkData::MakeEmpty(); + } + return SkPngEncoder::Encode(nullptr, img, {}); } void serialize(SkWStream* stream) const override { diff --git a/libs/hwui/jni/android_graphics_RenderNode.cpp b/libs/hwui/jni/android_graphics_RenderNode.cpp index 8c7b9a4b5e94..2a218a25913d 100644 --- a/libs/hwui/jni/android_graphics_RenderNode.cpp +++ b/libs/hwui/jni/android_graphics_RenderNode.cpp @@ -243,6 +243,13 @@ static jboolean android_view_RenderNode_setRenderEffect(CRITICAL_JNI_PARAMS_COMM return SET_AND_DIRTY(mutateLayerProperties().setImageFilter, imageFilter, RenderNode::GENERIC); } +static jboolean android_view_RenderNode_setBackdropRenderEffect( + CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr, jlong renderEffectPtr) { + SkImageFilter* imageFilter = reinterpret_cast<SkImageFilter*>(renderEffectPtr); + return SET_AND_DIRTY(mutateLayerProperties().setBackdropImageFilter, imageFilter, + RenderNode::GENERIC); +} + static jboolean android_view_RenderNode_setHasOverlappingRendering(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr, bool hasOverlappingRendering) { return SET_AND_DIRTY(setHasOverlappingRendering, hasOverlappingRendering, @@ -792,6 +799,8 @@ static const JNINativeMethod gMethods[] = { {"nSetAlpha", "(JF)Z", (void*)android_view_RenderNode_setAlpha}, {"nSetRenderEffect", "(JJ)Z", (void*)android_view_RenderNode_setRenderEffect}, + {"nSetBackdropRenderEffect", "(JJ)Z", + (void*)android_view_RenderNode_setBackdropRenderEffect}, {"nSetHasOverlappingRendering", "(JZ)Z", (void*)android_view_RenderNode_setHasOverlappingRendering}, {"nSetUsageHint", "(JI)V", (void*)android_view_RenderNode_setUsageHint}, diff --git a/libs/hwui/jni/android_graphics_drawable_VectorDrawable.cpp b/libs/hwui/jni/android_graphics_drawable_VectorDrawable.cpp index 9cffceb308c8..ade48f26937f 100644 --- a/libs/hwui/jni/android_graphics_drawable_VectorDrawable.cpp +++ b/libs/hwui/jni/android_graphics_drawable_VectorDrawable.cpp @@ -14,13 +14,13 @@ * limitations under the License. */ -#include "GraphicsJNI.h" +#include <hwui/Paint.h> +#include "ColorFilter.h" +#include "GraphicsJNI.h" #include "PathParser.h" #include "VectorDrawable.h" -#include <hwui/Paint.h> - namespace android { using namespace uirenderer; using namespace uirenderer::VectorDrawable; @@ -108,8 +108,9 @@ static jint draw(JNIEnv* env, jobject, jlong treePtr, jlong canvasPtr, Canvas* canvas = reinterpret_cast<Canvas*>(canvasPtr); SkRect rect; GraphicsJNI::jrect_to_rect(env, jrect, &rect); - SkColorFilter* colorFilter = reinterpret_cast<SkColorFilter*>(colorFilterPtr); - return tree->draw(canvas, colorFilter, rect, needsMirroring, canReuseCache); + auto colorFilter = ColorFilter::fromJava(colorFilterPtr); + auto skColorFilter = colorFilter != nullptr ? colorFilter->getInstance() : nullptr; + return tree->draw(canvas, skColorFilter.get(), rect, needsMirroring, canReuseCache); } /** diff --git a/libs/hwui/jni/fonts/Font.cpp b/libs/hwui/jni/fonts/Font.cpp index 1af60b2f5fae..8cfdeeb7e128 100644 --- a/libs/hwui/jni/fonts/Font.cpp +++ b/libs/hwui/jni/fonts/Font.cpp @@ -127,7 +127,7 @@ static jlong Font_Builder_build(JNIEnv* env, jobject clazz, jlong builderPtr, jo static jlong Font_Builder_clone(JNIEnv* env, jobject clazz, jlong fontPtr, jlong builderPtr, jint weight, jboolean italic, jint ttcIndex) { FontWrapper* font = reinterpret_cast<FontWrapper*>(fontPtr); - MinikinFontSkia* minikinSkia = static_cast<MinikinFontSkia*>(font->font->typeface().get()); + MinikinFontSkia* minikinSkia = static_cast<MinikinFontSkia*>(font->font->baseTypeface().get()); std::unique_ptr<NativeFontBuilder> builder(toBuilder(builderPtr)); // Reconstruct SkTypeface with different arguments from existing SkTypeface. @@ -159,7 +159,7 @@ static jlong Font_Builder_clone(JNIEnv* env, jobject clazz, jlong fontPtr, jlong static jfloat Font_getGlyphBounds(JNIEnv* env, jobject, jlong fontHandle, jint glyphId, jlong paintHandle, jobject rect) { FontWrapper* font = reinterpret_cast<FontWrapper*>(fontHandle); - MinikinFontSkia* minikinSkia = static_cast<MinikinFontSkia*>(font->font->typeface().get()); + MinikinFontSkia* minikinSkia = static_cast<MinikinFontSkia*>(font->font->baseTypeface().get()); Paint* paint = reinterpret_cast<Paint*>(paintHandle); SkFont* skFont = &paint->getSkFont(); @@ -179,7 +179,7 @@ static jfloat Font_getGlyphBounds(JNIEnv* env, jobject, jlong fontHandle, jint g static jfloat Font_getFontMetrics(JNIEnv* env, jobject, jlong fontHandle, jlong paintHandle, jobject metricsObj) { FontWrapper* font = reinterpret_cast<FontWrapper*>(fontHandle); - MinikinFontSkia* minikinSkia = static_cast<MinikinFontSkia*>(font->font->typeface().get()); + MinikinFontSkia* minikinSkia = static_cast<MinikinFontSkia*>(font->font->baseTypeface().get()); Paint* paint = reinterpret_cast<Paint*>(paintHandle); SkFont* skFont = &paint->getSkFont(); @@ -209,7 +209,7 @@ static jlong Font_cloneFont(CRITICAL_JNI_PARAMS_COMMA jlong fontPtr) { // Fast Native static jobject Font_newByteBuffer(JNIEnv* env, jobject, jlong fontPtr) { FontWrapper* font = reinterpret_cast<FontWrapper*>(fontPtr); - const std::shared_ptr<minikin::MinikinFont>& minikinFont = font->font->typeface(); + const std::shared_ptr<minikin::MinikinFont>& minikinFont = font->font->baseTypeface(); return env->NewDirectByteBuffer(const_cast<void*>(minikinFont->GetFontData()), minikinFont->GetFontSize()); } @@ -217,7 +217,7 @@ static jobject Font_newByteBuffer(JNIEnv* env, jobject, jlong fontPtr) { // Critical Native static jlong Font_getBufferAddress(CRITICAL_JNI_PARAMS_COMMA jlong fontPtr) { FontWrapper* font = reinterpret_cast<FontWrapper*>(fontPtr); - return reinterpret_cast<jlong>(font->font->typeface()->GetFontData()); + return reinterpret_cast<jlong>(font->font->baseTypeface()->GetFontData()); } // Critical Native @@ -236,7 +236,7 @@ static jstring Font_getFontPath(JNIEnv* env, jobject, jlong fontPtr) { } return env->NewStringUTF(path.c_str()); } else { - const std::shared_ptr<minikin::MinikinFont>& minikinFont = font->font->typeface(); + const std::shared_ptr<minikin::MinikinFont>& minikinFont = font->font->baseTypeface(); const std::string& path = minikinFont->GetFontPath(); if (path.empty()) { return nullptr; @@ -275,7 +275,7 @@ static jint Font_getIndex(CRITICAL_JNI_PARAMS_COMMA jlong fontPtr) { reader.skipString(); // fontPath return reader.read<int>(); } else { - const std::shared_ptr<minikin::MinikinFont>& minikinFont = font->font->typeface(); + const std::shared_ptr<minikin::MinikinFont>& minikinFont = font->font->baseTypeface(); return minikinFont->GetFontIndex(); } } @@ -289,7 +289,7 @@ static jint Font_getAxisCount(CRITICAL_JNI_PARAMS_COMMA jlong fontPtr) { reader.skip<int>(); // fontIndex return reader.readArray<minikin::FontVariation>().second; } else { - const std::shared_ptr<minikin::MinikinFont>& minikinFont = font->font->typeface(); + const std::shared_ptr<minikin::MinikinFont>& minikinFont = font->font->baseTypeface(); return minikinFont->GetAxes().size(); } } @@ -304,7 +304,7 @@ static jlong Font_getAxisInfo(CRITICAL_JNI_PARAMS_COMMA jlong fontPtr, jint inde reader.skip<int>(); // fontIndex var = reader.readArray<minikin::FontVariation>().first[index]; } else { - const std::shared_ptr<minikin::MinikinFont>& minikinFont = font->font->typeface(); + const std::shared_ptr<minikin::MinikinFont>& minikinFont = font->font->baseTypeface(); var = minikinFont->GetAxes().at(index); } uint32_t floatBinary = *reinterpret_cast<const uint32_t*>(&var.value); @@ -314,7 +314,7 @@ static jlong Font_getAxisInfo(CRITICAL_JNI_PARAMS_COMMA jlong fontPtr, jint inde // Critical Native static jint Font_getSourceId(CRITICAL_JNI_PARAMS_COMMA jlong fontPtr) { FontWrapper* font = reinterpret_cast<FontWrapper*>(fontPtr); - return font->font->typeface()->GetSourceId(); + return font->font->baseTypeface()->GetSourceId(); } static jlongArray Font_getAvailableFontSet(JNIEnv* env, jobject) { diff --git a/libs/hwui/jni/fonts/FontFamily.cpp b/libs/hwui/jni/fonts/FontFamily.cpp index ee158ee4e316..1e392b14728d 100644 --- a/libs/hwui/jni/fonts/FontFamily.cpp +++ b/libs/hwui/jni/fonts/FontFamily.cpp @@ -60,7 +60,7 @@ static void FontFamily_Builder_addFont(CRITICAL_JNI_PARAMS_COMMA jlong builderPt // Regular JNI static jlong FontFamily_Builder_build(JNIEnv* env, jobject clazz, jlong builderPtr, jstring langTags, jint variant, jboolean isCustomFallback, - jboolean isDefaultFallback) { + jboolean isDefaultFallback, jint variationFamilyType) { std::unique_ptr<NativeFamilyBuilder> builder(toBuilder(builderPtr)); uint32_t localeId; if (langTags == nullptr) { @@ -71,7 +71,8 @@ static jlong FontFamily_Builder_build(JNIEnv* env, jobject clazz, jlong builderP } std::shared_ptr<minikin::FontFamily> family = minikin::FontFamily::create( localeId, static_cast<minikin::FamilyVariant>(variant), std::move(builder->fonts), - isCustomFallback, isDefaultFallback); + isCustomFallback, isDefaultFallback, + static_cast<minikin::VariationFamilyType>(variationFamilyType)); if (family->getCoverage().length() == 0) { // No coverage means minikin rejected given font for some reasons. jniThrowException(env, "java/lang/IllegalArgumentException", @@ -121,7 +122,7 @@ static jlong FontFamily_getFont(CRITICAL_JNI_PARAMS_COMMA jlong familyPtr, jint static const JNINativeMethod gFontFamilyBuilderMethods[] = { {"nInitBuilder", "()J", (void*)FontFamily_Builder_initBuilder}, {"nAddFont", "(JJ)V", (void*)FontFamily_Builder_addFont}, - {"nBuild", "(JLjava/lang/String;IZZ)J", (void*)FontFamily_Builder_build}, + {"nBuild", "(JLjava/lang/String;IZZI)J", (void*)FontFamily_Builder_build}, {"nGetReleaseNativeFamily", "()J", (void*)FontFamily_Builder_GetReleaseFunc}, }; diff --git a/libs/hwui/jni/text/TextShaper.cpp b/libs/hwui/jni/text/TextShaper.cpp index 8e4dd53069f4..8c377b9f1829 100644 --- a/libs/hwui/jni/text/TextShaper.cpp +++ b/libs/hwui/jni/text/TextShaper.cpp @@ -62,7 +62,7 @@ static jlong shapeTextRun(const uint16_t* text, int textSize, int start, int cou const minikin::Font* font = layout.getFont(i); if (seenFonts.find(font) != seenFonts.end()) continue; minikin::MinikinExtent extent = {}; - font->typeface()->GetFontExtent(&extent, minikinPaint, layout.getFakery(i)); + layout.typeface(i)->GetFontExtent(&extent, minikinPaint, layout.getFakery(i)); overallAscent = std::min(overallAscent, extent.ascent); overallDescent = std::max(overallDescent, extent.descent); } @@ -148,6 +148,30 @@ static jfloat TextShaper_Result_getY(CRITICAL_JNI_PARAMS_COMMA jlong ptr, jint i } // CriticalNative +static jboolean TextShaper_Result_getFakeBold(CRITICAL_JNI_PARAMS_COMMA jlong ptr, jint i) { + const LayoutWrapper* layout = reinterpret_cast<LayoutWrapper*>(ptr); + return layout->layout.getFakery(i).isFakeBold(); +} + +// CriticalNative +static jboolean TextShaper_Result_getFakeItalic(CRITICAL_JNI_PARAMS_COMMA jlong ptr, jint i) { + const LayoutWrapper* layout = reinterpret_cast<LayoutWrapper*>(ptr); + return layout->layout.getFakery(i).isFakeItalic(); +} + +// CriticalNative +static jfloat TextShaper_Result_getWeightOverride(CRITICAL_JNI_PARAMS_COMMA jlong ptr, jint i) { + const LayoutWrapper* layout = reinterpret_cast<LayoutWrapper*>(ptr); + return layout->layout.getFakery(i).wghtAdjustment(); +} + +// CriticalNative +static jfloat TextShaper_Result_getItalicOverride(CRITICAL_JNI_PARAMS_COMMA jlong ptr, jint i) { + const LayoutWrapper* layout = reinterpret_cast<LayoutWrapper*>(ptr); + return layout->layout.getFakery(i).italAdjustment(); +} + +// CriticalNative static jlong TextShaper_Result_getFont(CRITICAL_JNI_PARAMS_COMMA jlong ptr, jint i) { const LayoutWrapper* layout = reinterpret_cast<LayoutWrapper*>(ptr); std::shared_ptr<minikin::Font> fontRef = layout->layout.getFontRef(i); @@ -185,15 +209,19 @@ static const JNINativeMethod gMethods[] = { }; static const JNINativeMethod gResultMethods[] = { - { "nGetGlyphCount", "(J)I", (void*)TextShaper_Result_getGlyphCount }, - { "nGetTotalAdvance", "(J)F", (void*)TextShaper_Result_getTotalAdvance }, - { "nGetAscent", "(J)F", (void*)TextShaper_Result_getAscent }, - { "nGetDescent", "(J)F", (void*)TextShaper_Result_getDescent }, - { "nGetGlyphId", "(JI)I", (void*)TextShaper_Result_getGlyphId }, - { "nGetX", "(JI)F", (void*)TextShaper_Result_getX }, - { "nGetY", "(JI)F", (void*)TextShaper_Result_getY }, - { "nGetFont", "(JI)J", (void*)TextShaper_Result_getFont }, - { "nReleaseFunc", "()J", (void*)TextShaper_Result_nReleaseFunc }, + {"nGetGlyphCount", "(J)I", (void*)TextShaper_Result_getGlyphCount}, + {"nGetTotalAdvance", "(J)F", (void*)TextShaper_Result_getTotalAdvance}, + {"nGetAscent", "(J)F", (void*)TextShaper_Result_getAscent}, + {"nGetDescent", "(J)F", (void*)TextShaper_Result_getDescent}, + {"nGetGlyphId", "(JI)I", (void*)TextShaper_Result_getGlyphId}, + {"nGetX", "(JI)F", (void*)TextShaper_Result_getX}, + {"nGetY", "(JI)F", (void*)TextShaper_Result_getY}, + {"nGetFont", "(JI)J", (void*)TextShaper_Result_getFont}, + {"nGetFakeBold", "(JI)Z", (void*)TextShaper_Result_getFakeBold}, + {"nGetFakeItalic", "(JI)Z", (void*)TextShaper_Result_getFakeItalic}, + {"nGetWeightOverride", "(JI)F", (void*)TextShaper_Result_getWeightOverride}, + {"nGetItalicOverride", "(JI)F", (void*)TextShaper_Result_getItalicOverride}, + {"nReleaseFunc", "()J", (void*)TextShaper_Result_nReleaseFunc}, }; int register_android_graphics_text_TextShaper(JNIEnv* env) { diff --git a/libs/hwui/pipeline/skia/BackdropFilterDrawable.cpp b/libs/hwui/pipeline/skia/BackdropFilterDrawable.cpp new file mode 100644 index 000000000000..ffad69993fd8 --- /dev/null +++ b/libs/hwui/pipeline/skia/BackdropFilterDrawable.cpp @@ -0,0 +1,85 @@ +/* + * 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. + */ + +#include "BackdropFilterDrawable.h" + +#include <SkImage.h> +#include <SkSurface.h> + +#include "RenderNode.h" +#include "RenderNodeDrawable.h" + +namespace android { +namespace uirenderer { +namespace skiapipeline { + +BackdropFilterDrawable::~BackdropFilterDrawable() {} + +bool BackdropFilterDrawable::prepareToDraw(SkCanvas* canvas, const RenderProperties& properties, + int backdropImageWidth, int backdropImageHeight) { + // the drawing bounds for blurred content. + mDstBounds.setWH(properties.getWidth(), properties.getHeight()); + + float alphaMultiplier = 1.0f; + RenderNodeDrawable::setViewProperties(properties, canvas, &alphaMultiplier, true); + + // get proper subset for previous content. + canvas->getTotalMatrix().mapRect(&mImageSubset, mDstBounds); + SkRect imageSubset(mImageSubset); + // ensure the subset is inside bounds of previous content. + if (!mImageSubset.intersect(SkRect::MakeWH(backdropImageWidth, backdropImageHeight))) { + return false; + } + + // correct the drawing bounds if subset was changed. + if (mImageSubset != imageSubset) { + SkMatrix inverse; + if (canvas->getTotalMatrix().invert(&inverse)) { + inverse.mapRect(&mDstBounds, mImageSubset); + } + } + + // follow the alpha from the target RenderNode. + mPaint.setAlpha(properties.layerProperties().alpha() * alphaMultiplier); + return true; +} + +void BackdropFilterDrawable::onDraw(SkCanvas* canvas) { + const RenderProperties& properties = mTargetRenderNode->properties(); + auto* backdropFilter = properties.layerProperties().getBackdropImageFilter(); + auto* surface = canvas->getSurface(); + if (!backdropFilter || !surface) { + return; + } + + auto backdropImage = surface->makeImageSnapshot(); + // sync necessary properties from target RenderNode. + if (!prepareToDraw(canvas, properties, backdropImage->width(), backdropImage->height())) { + return; + } + + auto imageSubset = mImageSubset.roundOut(); + backdropImage = + backdropImage->makeWithFilter(canvas->recordingContext(), backdropFilter, imageSubset, + imageSubset, &mOutSubset, &mOutOffset); + canvas->drawImageRect(backdropImage, SkRect::Make(mOutSubset), mDstBounds, + SkSamplingOptions(SkFilterMode::kLinear), &mPaint, + SkCanvas::kStrict_SrcRectConstraint); +} + +} // namespace skiapipeline +} // namespace uirenderer +} // namespace android diff --git a/libs/hwui/pipeline/skia/BackdropFilterDrawable.h b/libs/hwui/pipeline/skia/BackdropFilterDrawable.h new file mode 100644 index 000000000000..9e35837675ae --- /dev/null +++ b/libs/hwui/pipeline/skia/BackdropFilterDrawable.h @@ -0,0 +1,67 @@ +/* + * 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. + */ + +#pragma once + +#include <SkCanvas.h> +#include <SkDrawable.h> +#include <SkPaint.h> + +namespace android { +namespace uirenderer { + +class RenderNode; +class RenderProperties; + +namespace skiapipeline { + +/** + * This drawable captures it's backdrop content and render it with a + * image filter. + */ +class BackdropFilterDrawable : public SkDrawable { +public: + BackdropFilterDrawable(RenderNode* renderNode, SkCanvas* canvas) + : mTargetRenderNode(renderNode), mBounds(canvas->getLocalClipBounds()) {} + + ~BackdropFilterDrawable(); + +private: + RenderNode* mTargetRenderNode; + SkPaint mPaint; + + SkRect mDstBounds; + SkRect mImageSubset; + SkIRect mOutSubset; + SkIPoint mOutOffset; + + /** + * Check all necessary properties before actual drawing. + * Return true if ready to draw. + */ + bool prepareToDraw(SkCanvas* canvas, const RenderProperties& properties, int backdropImageWidth, + int backdropImageHeight); + +protected: + void onDraw(SkCanvas* canvas) override; + + virtual SkRect onGetBounds() override { return mBounds; } + const SkRect mBounds; +}; + +} // namespace skiapipeline +} // namespace uirenderer +} // namespace android diff --git a/libs/hwui/pipeline/skia/GLFunctorDrawable.cpp b/libs/hwui/pipeline/skia/GLFunctorDrawable.cpp index 8d5967bbd461..dbd9ef3c9e4c 100644 --- a/libs/hwui/pipeline/skia/GLFunctorDrawable.cpp +++ b/libs/hwui/pipeline/skia/GLFunctorDrawable.cpp @@ -21,9 +21,12 @@ #include "GrBackendSurface.h" #include "RenderNode.h" #include "SkAndroidFrameworkUtils.h" +#include "SkCanvas.h" +#include "SkCanvasAndroid.h" #include "SkClipStack.h" #include "SkRect.h" #include "SkM44.h" +#include <include/gpu/ganesh/SkSurfaceGanesh.h> #include "include/gpu/GpuTypes.h" // from Skia #include "utils/GLUtils.h" #include <effects/GainmapRenderer.h> @@ -34,7 +37,7 @@ namespace uirenderer { namespace skiapipeline { static void setScissor(int viewportHeight, const SkIRect& clip) { - SkASSERT(!clip.isEmpty()); + LOG_FATAL_IF(clip.isEmpty(), "empty scissor clip"); // transform to Y-flipped GL space, and prevent negatives GLint y = viewportHeight - clip.fBottom; GLint height = (viewportHeight - clip.fTop) - y; @@ -42,7 +45,7 @@ static void setScissor(int viewportHeight, const SkIRect& clip) { } static void GetFboDetails(SkCanvas* canvas, GLuint* outFboID, SkISize* outFboSize) { - GrBackendRenderTarget renderTarget = canvas->topLayerBackendRenderTarget(); + GrBackendRenderTarget renderTarget = skgpu::ganesh::TopLayerBackendRenderTarget(canvas); GrGLFramebufferInfo fboInfo; LOG_ALWAYS_FATAL_IF(!renderTarget.getGLFramebufferInfo(&fboInfo), "getGLFrameBufferInfo failed"); @@ -76,13 +79,13 @@ void GLFunctorDrawable::onDraw(SkCanvas* canvas) { } // flush will create a GrRenderTarget if not already present. - canvas->flush(); + directContext->flushAndSubmit(); GLuint fboID = 0; SkISize fboSize; GetFboDetails(canvas, &fboID, &fboSize); - SkIRect surfaceBounds = canvas->topLayerBounds(); + SkIRect surfaceBounds = skgpu::ganesh::TopLayerBounds(canvas); SkIRect clipBounds = canvas->getDeviceClipBounds(); SkM44 mat4(canvas->getLocalToDevice()); SkRegion clipRegion; @@ -95,11 +98,12 @@ void GLFunctorDrawable::onDraw(SkCanvas* canvas) { SkImageInfo surfaceInfo = canvas->imageInfo().makeWH(clipBounds.width(), clipBounds.height()); tmpSurface = - SkSurface::MakeRenderTarget(directContext, skgpu::Budgeted::kYes, surfaceInfo); + SkSurfaces::RenderTarget(directContext, skgpu::Budgeted::kYes, surfaceInfo); tmpSurface->getCanvas()->clear(SK_ColorTRANSPARENT); GrGLFramebufferInfo fboInfo; - if (!tmpSurface->getBackendRenderTarget(SkSurface::kFlushWrite_BackendHandleAccess) + if (!SkSurfaces::GetBackendRenderTarget(tmpSurface.get(), + SkSurfaces::BackendHandleAccess::kFlushWrite) .getGLFramebufferInfo(&fboInfo)) { ALOGW("Unable to extract renderTarget info from offscreen canvas; aborting GLFunctor"); return; @@ -163,7 +167,7 @@ void GLFunctorDrawable::onDraw(SkCanvas* canvas) { // GL ops get inserted here if previous flush is missing, which could dirty the stencil bool stencilWritten = SkAndroidFrameworkUtils::clipWithStencil(tmpCanvas); - tmpCanvas->flush(); // need this flush for the single op that draws into the stencil + directContext->flushAndSubmit(); // need this flush for the single op that draws into the stencil // ensure that the framebuffer that the webview will render into is bound before after we // draw into the stencil diff --git a/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp b/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp index da4f66d45a70..9d72c2315198 100644 --- a/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp +++ b/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp @@ -362,7 +362,7 @@ void RenderNodeDrawable::drawContent(SkCanvas* canvas) const { } void RenderNodeDrawable::setViewProperties(const RenderProperties& properties, SkCanvas* canvas, - float* alphaMultiplier) { + float* alphaMultiplier, bool ignoreLayer) { if (properties.getLeft() != 0 || properties.getTop() != 0) { canvas->translate(properties.getLeft(), properties.getTop()); } @@ -378,7 +378,8 @@ void RenderNodeDrawable::setViewProperties(const RenderProperties& properties, S canvas->concat(*properties.getTransformMatrix()); } } - if (Properties::getStretchEffectBehavior() == StretchEffectBehavior::UniformScale) { + if (Properties::getStretchEffectBehavior() == StretchEffectBehavior::UniformScale && + !ignoreLayer) { const StretchEffect& stretch = properties.layerProperties().getStretchEffect(); if (!stretch.isEmpty()) { canvas->concat( @@ -388,10 +389,10 @@ void RenderNodeDrawable::setViewProperties(const RenderProperties& properties, S const bool isLayer = properties.effectiveLayerType() != LayerType::None; int clipFlags = properties.getClippingFlags(); if (properties.getAlpha() < 1) { - if (isLayer) { + if (isLayer && !ignoreLayer) { clipFlags &= ~CLIP_TO_BOUNDS; // bounds clipping done by layer } - if (CC_LIKELY(isLayer || !properties.getHasOverlappingRendering())) { + if (CC_LIKELY(isLayer || !properties.getHasOverlappingRendering()) || ignoreLayer) { *alphaMultiplier = properties.getAlpha(); } else { // savelayer needed to create an offscreen buffer diff --git a/libs/hwui/pipeline/skia/RenderNodeDrawable.h b/libs/hwui/pipeline/skia/RenderNodeDrawable.h index c7582e734009..818ac45bf346 100644 --- a/libs/hwui/pipeline/skia/RenderNodeDrawable.h +++ b/libs/hwui/pipeline/skia/RenderNodeDrawable.h @@ -120,7 +120,7 @@ private: * Applies the rendering properties of a view onto a SkCanvas. */ static void setViewProperties(const RenderProperties& properties, SkCanvas* canvas, - float* alphaMultiplier); + float* alphaMultiplier, bool ignoreLayer = false); /** * Stores transform on the canvas at time of recording and is used for @@ -149,6 +149,11 @@ private: * display list that is searched for any render nodes with getProjectBackwards==true */ SkiaDisplayList* mProjectedDisplayList = nullptr; + + /** + * Allow BackdropFilterDrawable to apply same render properties onto SkCanvas. + */ + friend class BackdropFilterDrawable; }; } // namespace skiapipeline diff --git a/libs/hwui/pipeline/skia/ShaderCache.h b/libs/hwui/pipeline/skia/ShaderCache.h index 74955503dbb1..6ccb212fe6ca 100644 --- a/libs/hwui/pipeline/skia/ShaderCache.h +++ b/libs/hwui/pipeline/skia/ShaderCache.h @@ -26,6 +26,7 @@ #include <string> #include <vector> +class GrDirectContext; class SkData; namespace android { diff --git a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp index cf31173d266e..23b3074435cf 100644 --- a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp +++ b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp @@ -16,6 +16,7 @@ #include "SkiaOpenGLPipeline.h" +#include <include/gpu/ganesh/SkSurfaceGanesh.h> #include <GrBackendSurface.h> #include <SkBlendMode.h> #include <SkImageInfo.h> @@ -150,9 +151,9 @@ IRenderPipeline::DrawResult SkiaOpenGLPipeline::draw( surface = getBufferSkSurface(bufferParams); preTransform = bufferParams.getTransform(); } else { - surface = SkSurface::MakeFromBackendRenderTarget(mRenderThread.getGrContext(), backendRT, - getSurfaceOrigin(), colorType, - mSurfaceColorSpace, &props); + surface = SkSurfaces::WrapBackendRenderTarget(mRenderThread.getGrContext(), backendRT, + getSurfaceOrigin(), colorType, + mSurfaceColorSpace, &props); preTransform = SkMatrix::I(); } @@ -174,7 +175,7 @@ IRenderPipeline::DrawResult SkiaOpenGLPipeline::draw( { ATRACE_NAME("flush commands"); - surface->flushAndSubmit(); + skgpu::ganesh::FlushAndSubmit(surface); } layerUpdateQueue->clear(); @@ -245,8 +246,7 @@ bool SkiaOpenGLPipeline::setSurface(ANativeWindow* surface, SwapBehavior swapBeh if (mEglSurface != EGL_NO_SURFACE) { const bool preserveBuffer = (swapBehavior != SwapBehavior::kSwap_discardBuffer); - const bool isPreserved = mEglManager.setPreserveBuffer(mEglSurface, preserveBuffer); - ALOGE_IF(preserveBuffer != isPreserved, "Unable to match the desired swap behavior."); + mEglManager.setPreserveBuffer(mEglSurface, preserveBuffer); return true; } diff --git a/libs/hwui/pipeline/skia/SkiaPipeline.cpp b/libs/hwui/pipeline/skia/SkiaPipeline.cpp index b020e966e05a..3d77877cf6eb 100644 --- a/libs/hwui/pipeline/skia/SkiaPipeline.cpp +++ b/libs/hwui/pipeline/skia/SkiaPipeline.cpp @@ -16,14 +16,15 @@ #include "SkiaPipeline.h" +#include <include/android/SkSurfaceAndroid.h> +#include <include/gpu/ganesh/SkSurfaceGanesh.h> #include <SkCanvas.h> #include <SkColor.h> #include <SkColorSpace.h> #include <SkData.h> #include <SkImage.h> -#include <SkImageEncoder.h> +#include <SkImageAndroid.h> #include <SkImageInfo.h> -#include <SkImagePriv.h> #include <SkMatrix.h> #include <SkMultiPictureDocument.h> #include <SkOverdrawCanvas.h> @@ -75,7 +76,7 @@ bool SkiaPipeline::pinImages(std::vector<SkImage*>& mutableImages) { return false; } for (SkImage* image : mutableImages) { - if (SkImage_pinAsTexture(image, mRenderThread.getGrContext())) { + if (skgpu::ganesh::PinAsTexture(mRenderThread.getGrContext(), image)) { mPinnedImages.emplace_back(sk_ref_sp(image)); } else { return false; @@ -86,7 +87,7 @@ bool SkiaPipeline::pinImages(std::vector<SkImage*>& mutableImages) { void SkiaPipeline::unpinImages() { for (auto& image : mPinnedImages) { - SkImage_unpinAsTexture(image.get(), mRenderThread.getGrContext()); + skgpu::ganesh::UnpinTexture(mRenderThread.getGrContext(), image.get()); } mPinnedImages.clear(); } @@ -187,9 +188,9 @@ bool SkiaPipeline::createOrUpdateLayer(RenderNode* node, const DamageAccumulator kPremul_SkAlphaType, getSurfaceColorSpace()); SkSurfaceProps props(0, kUnknown_SkPixelGeometry); SkASSERT(mRenderThread.getGrContext() != nullptr); - node->setLayerSurface(SkSurface::MakeRenderTarget(mRenderThread.getGrContext(), - skgpu::Budgeted::kYes, info, 0, - this->getSurfaceOrigin(), &props)); + node->setLayerSurface(SkSurfaces::RenderTarget(mRenderThread.getGrContext(), + skgpu::Budgeted::kYes, info, 0, + this->getSurfaceOrigin(), &props)); if (node->getLayerSurface()) { // update the transform in window of the layer to reset its origin wrt light source // position @@ -222,8 +223,8 @@ void SkiaPipeline::prepareToDraw(const RenderThread& thread, Bitmap* bitmap) { ATRACE_FORMAT("Bitmap#prepareToDraw %dx%d", bitmap->width(), bitmap->height()); auto image = bitmap->makeImage(); if (image.get()) { - SkImage_pinAsTexture(image.get(), context); - SkImage_unpinAsTexture(image.get(), context); + skgpu::ganesh::PinAsTexture(context, image.get()); + skgpu::ganesh::UnpinTexture(context, image.get()); // A submit is necessary as there may not be a frame coming soon, so without a call // to submit these texture uploads can just sit in the queue building up until // we run out of RAM @@ -621,7 +622,7 @@ sk_sp<SkSurface> SkiaPipeline::getBufferSkSurface( auto bufferColorSpace = bufferParams.getColorSpace(); if (mBufferSurface == nullptr || mBufferColorSpace == nullptr || !SkColorSpace::Equals(mBufferColorSpace.get(), bufferColorSpace.get())) { - mBufferSurface = SkSurface::MakeFromAHardwareBuffer( + mBufferSurface = SkSurfaces::WrapAndroidHardwareBuffer( mRenderThread.getGrContext(), mHardwareBuffer, kTopLeft_GrSurfaceOrigin, bufferColorSpace, nullptr, true); mBufferColorSpace = bufferColorSpace; diff --git a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp index 3ca7eeb37a89..e917f9a66917 100644 --- a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp +++ b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp @@ -37,6 +37,7 @@ #include "NinePatchUtils.h" #include "RenderNode.h" #include "pipeline/skia/AnimatedDrawables.h" +#include "pipeline/skia/BackdropFilterDrawable.h" #ifdef __ANDROID__ // Layoutlib does not support GL, Vulcan etc. #include "pipeline/skia/GLFunctorDrawable.h" #include "pipeline/skia/VkFunctorDrawable.h" @@ -168,6 +169,14 @@ void SkiaRecordingCanvas::drawRenderNode(uirenderer::RenderNode* renderNode) { // Put Vulkan WebViews with non-rectangular clips in a HW layer renderNode->mutateStagingProperties().setClipMayBeComplex(mRecorder.isClipMayBeComplex()); } + + // draw backdrop filter drawable if needed. + if (renderNode->stagingProperties().layerProperties().getBackdropImageFilter()) { + auto* backdropFilterDrawable = + mDisplayList->allocateDrawable<BackdropFilterDrawable>(renderNode, asSkCanvas()); + drawDrawable(backdropFilterDrawable); + } + drawDrawable(&renderNodeDrawable); // use staging property, since recording on UI thread @@ -227,6 +236,17 @@ void SkiaRecordingCanvas::handleMutableImages(Bitmap& bitmap, DrawImagePayload& } } +void SkiaRecordingCanvas::onFilterPaint(android::Paint& paint) { + INHERITED::onFilterPaint(paint); + SkShader* shader = paint.getShader(); + // TODO(b/264559422): This only works for very specifically a BitmapShader. + // It's better than nothing, though + SkImage* image = shader ? shader->isAImage(nullptr, nullptr) : nullptr; + if (image) { + mDisplayList->mMutableImages.push_back(image); + } +} + void SkiaRecordingCanvas::drawBitmap(Bitmap& bitmap, float left, float top, const Paint* paint) { auto payload = DrawImagePayload(bitmap); diff --git a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.h b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.h index a8e4580dc200..3bd091df1ece 100644 --- a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.h +++ b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.h @@ -105,6 +105,8 @@ private: void handleMutableImages(Bitmap& bitmap, DrawImagePayload& payload); + void onFilterPaint(Paint& paint) override; + using INHERITED = SkiaCanvas; }; diff --git a/libs/hwui/pipeline/skia/StretchMask.cpp b/libs/hwui/pipeline/skia/StretchMask.cpp index cad3703d8d2b..1676787ef671 100644 --- a/libs/hwui/pipeline/skia/StretchMask.cpp +++ b/libs/hwui/pipeline/skia/StretchMask.cpp @@ -18,14 +18,13 @@ #include "SkBlendMode.h" #include "SkCanvas.h" #include "SkSurface.h" -#include "include/gpu/GpuTypes.h" // from Skia #include "TransformCanvas.h" #include "SkiaDisplayList.h" using android::uirenderer::StretchMask; -void StretchMask::draw(GrRecordingContext* context, +void StretchMask::draw(GrRecordingContext*, const StretchEffect& stretch, const SkRect& bounds, skiapipeline::SkiaDisplayList* displayList, @@ -35,16 +34,14 @@ void StretchMask::draw(GrRecordingContext* context, if (mMaskSurface == nullptr || mMaskSurface->width() != width || mMaskSurface->height() != height) { // Create a new surface if we don't have one or our existing size does - // not match. - mMaskSurface = SkSurface::MakeRenderTarget( - context, - skgpu::Budgeted::kYes, - SkImageInfo::Make( - width, - height, - SkColorType::kAlpha_8_SkColorType, - SkAlphaType::kPremul_SkAlphaType) - ); + // not match. SkCanvas::makeSurface returns a new surface that will + // be GPU-backed if canvas was also. + mMaskSurface = canvas->makeSurface(SkImageInfo::Make( + width, + height, + SkColorType::kAlpha_8_SkColorType, + SkAlphaType::kPremul_SkAlphaType + )); mIsDirty = true; } @@ -53,7 +50,7 @@ void StretchMask::draw(GrRecordingContext* context, // Make sure to apply target transformation to the mask canvas // to ensure the replayed drawing commands generate the same result auto previousMatrix = displayList->mParentMatrix; - displayList->mParentMatrix = maskCanvas->getTotalMatrix(); + displayList->mParentMatrix = maskCanvas->getLocalToDeviceAs3x3(); maskCanvas->save(); maskCanvas->drawColor(0, SkBlendMode::kClear); TransformCanvas transformCanvas(maskCanvas, SkBlendMode::kSrcOver); diff --git a/libs/hwui/pipeline/skia/VkInteropFunctorDrawable.cpp b/libs/hwui/pipeline/skia/VkInteropFunctorDrawable.cpp index adf3c06b8624..475b110604e4 100644 --- a/libs/hwui/pipeline/skia/VkInteropFunctorDrawable.cpp +++ b/libs/hwui/pipeline/skia/VkInteropFunctorDrawable.cpp @@ -35,6 +35,8 @@ #include "effects/GainmapRenderer.h" #include <SkBlendMode.h> +#include <SkImage.h> +#include <SkImageAndroid.h> namespace android { namespace uirenderer { @@ -183,9 +185,9 @@ void VkInteropFunctorDrawable::onDraw(SkCanvas* canvas) { // drawing into the offscreen surface, so we need to reset it here. canvas->resetMatrix(); - auto functorImage = SkImage::MakeFromAHardwareBuffer(mFrameBuffer.get(), kPremul_SkAlphaType, - canvas->imageInfo().refColorSpace(), - kBottomLeft_GrSurfaceOrigin); + auto functorImage = SkImages::DeferredFromAHardwareBuffer( + mFrameBuffer.get(), kPremul_SkAlphaType, canvas->imageInfo().refColorSpace(), + kBottomLeft_GrSurfaceOrigin); canvas->drawImage(functorImage, 0, 0, SkSamplingOptions(), &paint); canvas->restore(); } diff --git a/libs/hwui/renderthread/CacheManager.cpp b/libs/hwui/renderthread/CacheManager.cpp index babce88b8e1e..8f81dbad2320 100644 --- a/libs/hwui/renderthread/CacheManager.cpp +++ b/libs/hwui/renderthread/CacheManager.cpp @@ -277,12 +277,13 @@ void CacheManager::onThreadIdle() { const nsecs_t now = systemTime(CLOCK_MONOTONIC); // Rate limiting - if ((now - mLastDeferredCleanup) < 25_ms) { + if ((now - mLastDeferredCleanup) > 25_ms) { mLastDeferredCleanup = now; const nsecs_t frameCompleteNanos = mFrameCompletions[0]; const nsecs_t frameDiffNanos = now - frameCompleteNanos; const nsecs_t cleanupMillis = - ns2ms(std::max(frameDiffNanos, mMemoryPolicy.minimumResourceRetention)); + ns2ms(std::clamp(frameDiffNanos, mMemoryPolicy.minimumResourceRetention, + mMemoryPolicy.maximumResourceRetention)); mGrContext->performDeferredCleanup(std::chrono::milliseconds(cleanupMillis), mMemoryPolicy.purgeScratchOnly); } diff --git a/libs/hwui/renderthread/CacheManager.h b/libs/hwui/renderthread/CacheManager.h index 5e43ac209696..bcfa4f359d83 100644 --- a/libs/hwui/renderthread/CacheManager.h +++ b/libs/hwui/renderthread/CacheManager.h @@ -64,12 +64,13 @@ public: void unregisterCanvasContext(CanvasContext* context); void onContextStopped(CanvasContext* context); + bool areAllContextsStopped(); + private: friend class RenderThread; explicit CacheManager(RenderThread& thread); void setupCacheLimits(); - bool areAllContextsStopped(); void checkUiHidden(); void scheduleDestroyContext(); void cancelDestroyContext(); diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp index a5518eb9f854..2ef7802c0a3c 100644 --- a/libs/hwui/renderthread/CanvasContext.cpp +++ b/libs/hwui/renderthread/CanvasContext.cpp @@ -125,6 +125,7 @@ CanvasContext::CanvasContext(RenderThread& thread, bool translucent, RenderNode* , mRenderPipeline(std::move(renderPipeline)) , mHintSessionWrapper(uiThreadId, renderThreadId) { mRenderThread.cacheManager().registerCanvasContext(this); + mRenderThread.renderState().registerContextCallback(this); rootRenderNode->makeRoot(); mRenderNodes.emplace_back(rootRenderNode); mProfiler.setDensity(DeviceInfo::getDensity()); @@ -137,6 +138,7 @@ CanvasContext::~CanvasContext() { } mRenderNodes.clear(); mRenderThread.cacheManager().unregisterCanvasContext(this); + mRenderThread.renderState().removeContextCallback(this); } void CanvasContext::addRenderNode(RenderNode* node, bool placeFront) { @@ -963,6 +965,10 @@ void CanvasContext::destroyHardwareResources() { } } +void CanvasContext::onContextDestroyed() { + destroyHardwareResources(); +} + DeferredLayerUpdater* CanvasContext::createTextureLayer() { return mRenderPipeline->createTextureLayer(); } diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h index 32ac5af94c14..3f02674d3b53 100644 --- a/libs/hwui/renderthread/CanvasContext.h +++ b/libs/hwui/renderthread/CanvasContext.h @@ -43,6 +43,7 @@ #include "Lighting.h" #include "ReliableSurface.h" #include "RenderNode.h" +#include "renderstate/RenderState.h" #include "renderthread/RenderTask.h" #include "renderthread/RenderThread.h" #include "utils/RingBuffer.h" @@ -64,7 +65,7 @@ class Frame; // This per-renderer class manages the bridge between the global EGL context // and the render surface. // TODO: Rename to Renderer or some other per-window, top-level manager -class CanvasContext : public IFrameCallback { +class CanvasContext : public IFrameCallback, public IGpuContextCallback { public: static CanvasContext* create(RenderThread& thread, bool translucent, RenderNode* rootRenderNode, IContextFactory* contextFactory, pid_t uiThreadId, @@ -154,6 +155,7 @@ public: void markLayerInUse(RenderNode* node); void destroyHardwareResources(); + void onContextDestroyed() override; DeferredLayerUpdater* createTextureLayer(); diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp index 224c878bf43d..f949dddd8b44 100644 --- a/libs/hwui/renderthread/RenderProxy.cpp +++ b/libs/hwui/renderthread/RenderProxy.cpp @@ -16,7 +16,13 @@ #include "RenderProxy.h" +#include <SkBitmap.h> +#include <SkImage.h> +#include <SkPicture.h> #include <gui/TraceUtils.h> +#include <pthread.h> +#include <ui/GraphicBufferAllocator.h> + #include "DeferredLayerUpdater.h" #include "DisplayList.h" #include "Properties.h" @@ -29,12 +35,6 @@ #include "utils/Macros.h" #include "utils/TimeUtils.h" -#include <SkBitmap.h> -#include <SkImage.h> -#include <SkPicture.h> - -#include <pthread.h> - namespace android { namespace uirenderer { namespace renderthread { @@ -323,6 +323,9 @@ void RenderProxy::dumpGraphicsMemory(int fd, bool includeProfileData, bool reset } }); } + std::string grallocInfo; + GraphicBufferAllocator::getInstance().dump(grallocInfo); + dprintf(fd, "%s\n", grallocInfo.c_str()); } void RenderProxy::getMemoryUsage(size_t* cpuUsage, size_t* gpuUsage) { diff --git a/libs/hwui/renderthread/VulkanManager.cpp b/libs/hwui/renderthread/VulkanManager.cpp index 46698a6fdcc0..f3409455d401 100644 --- a/libs/hwui/renderthread/VulkanManager.cpp +++ b/libs/hwui/renderthread/VulkanManager.cpp @@ -24,6 +24,7 @@ #include <GrTypes.h> #include <android/sync.h> #include <gui/TraceUtils.h> +#include <include/gpu/ganesh/SkSurfaceGanesh.h> #include <ui/FatVector.h> #include <vk/GrVkExtensions.h> #include <vk/GrVkTypes.h> @@ -518,7 +519,7 @@ Frame VulkanManager::dequeueNextBuffer(VulkanSurface* surface) { // The following flush blocks the GPU immediately instead of waiting for // other drawing ops. It seems dequeue_fence is not respected otherwise. // TODO: remove the flush after finding why backendSemaphore is not working. - bufferInfo->skSurface->flushAndSubmit(); + skgpu::ganesh::FlushAndSubmit(bufferInfo->skSurface); } } } @@ -586,10 +587,10 @@ nsecs_t VulkanManager::finishFrame(SkSurface* surface) { } else { semaphore = VK_NULL_HANDLE; } - GrSemaphoresSubmitted submitted = - surface->flush(SkSurface::BackendSurfaceAccess::kPresent, flushInfo); GrDirectContext* context = GrAsDirectContext(surface->recordingContext()); ALOGE_IF(!context, "Surface is not backed by gpu"); + GrSemaphoresSubmitted submitted = context->flush( + surface, SkSurfaces::BackendSurfaceAccess::kPresent, flushInfo); context->submit(); const nsecs_t submissionTime = systemTime(); if (semaphore != VK_NULL_HANDLE) { @@ -599,7 +600,8 @@ nsecs_t VulkanManager::finishFrame(SkSurface* surface) { // retrieve VkImage used as render target VkImage image = VK_NULL_HANDLE; GrBackendRenderTarget backendRenderTarget = - surface->getBackendRenderTarget(SkSurface::kFlushRead_BackendHandleAccess); + SkSurfaces::GetBackendRenderTarget( + surface, SkSurfaces::BackendHandleAccess::kFlushRead); if (backendRenderTarget.isValid()) { GrVkImageInfo info; if (backendRenderTarget.getVkImageInfo(&info)) { diff --git a/libs/hwui/renderthread/VulkanSurface.cpp b/libs/hwui/renderthread/VulkanSurface.cpp index 3168cb09291b..b0ba619c63a4 100644 --- a/libs/hwui/renderthread/VulkanSurface.cpp +++ b/libs/hwui/renderthread/VulkanSurface.cpp @@ -16,6 +16,7 @@ #include "VulkanSurface.h" +#include <include/android/SkSurfaceAndroid.h> #include <GrDirectContext.h> #include <SkSurface.h> #include <algorithm> @@ -470,12 +471,12 @@ VulkanSurface::NativeBufferInfo* VulkanSurface::dequeueNativeBuffer() { surfaceProps = SkSurfaceProps(SkSurfaceProps::kAlwaysDither_Flag | surfaceProps.flags(), surfaceProps.pixelGeometry()); } - bufferInfo->skSurface = SkSurface::MakeFromAHardwareBuffer( + bufferInfo->skSurface = SkSurfaces::WrapAndroidHardwareBuffer( mGrContext, ANativeWindowBuffer_getHardwareBuffer(bufferInfo->buffer.get()), kTopLeft_GrSurfaceOrigin, mWindowInfo.colorspace, &surfaceProps, /*from_window=*/true); if (bufferInfo->skSurface.get() == nullptr) { - ALOGE("SkSurface::MakeFromAHardwareBuffer failed"); + ALOGE("SkSurfaces::WrapAndroidHardwareBuffer failed"); mNativeWindow->cancelBuffer(mNativeWindow.get(), buffer, mNativeBuffers[idx].dequeue_fence.release()); mNativeBuffers[idx].dequeued = false; diff --git a/libs/hwui/tests/common/TestUtils.h b/libs/hwui/tests/common/TestUtils.h index 81ecfe59d3bc..ffc664c2e1bc 100644 --- a/libs/hwui/tests/common/TestUtils.h +++ b/libs/hwui/tests/common/TestUtils.h @@ -61,18 +61,10 @@ namespace uirenderer { ADD_FAILURE() << "ClipState not a rect"; \ } -#define INNER_PIPELINE_TEST(test_case_name, test_name, pipeline, functionCall) \ - TEST(test_case_name, test_name##_##pipeline) { \ - RenderPipelineType oldType = Properties::getRenderPipelineType(); \ - Properties::overrideRenderPipelineType(RenderPipelineType::pipeline); \ - functionCall; \ - Properties::overrideRenderPipelineType(oldType); \ - }; - -#define INNER_PIPELINE_RENDERTHREAD_TEST(test_case_name, test_name, pipeline) \ - INNER_PIPELINE_TEST(test_case_name, test_name, pipeline, \ - TestUtils::runOnRenderThread( \ - test_case_name##_##test_name##_RenderThreadTest::doTheThing)) +#define INNER_PIPELINE_RENDERTHREAD_TEST(test_case_name, test_name) \ + TEST(test_case_name, test_name) { \ + TestUtils::runOnRenderThread(test_case_name##_##test_name##_RenderThreadTest::doTheThing); \ + } /** * Like gtest's TEST, but runs on the RenderThread, and 'renderThread' is passed, in top level scope @@ -83,21 +75,7 @@ namespace uirenderer { public: \ static void doTheThing(renderthread::RenderThread& renderThread); \ }; \ - INNER_PIPELINE_RENDERTHREAD_TEST(test_case_name, test_name, SkiaGL); \ - /* Temporarily disabling Vulkan until we can figure out a way to stub out the driver */ \ - /* INNER_PIPELINE_RENDERTHREAD_TEST(test_case_name, test_name, SkiaVulkan); */ \ - void test_case_name##_##test_name##_RenderThreadTest::doTheThing( \ - renderthread::RenderThread& renderThread) - -/** - * Like RENDERTHREAD_TEST, but only runs with the Skia RenderPipelineTypes - */ -#define RENDERTHREAD_SKIA_PIPELINE_TEST(test_case_name, test_name) \ - class test_case_name##_##test_name##_RenderThreadTest { \ - public: \ - static void doTheThing(renderthread::RenderThread& renderThread); \ - }; \ - INNER_PIPELINE_RENDERTHREAD_TEST(test_case_name, test_name, SkiaGL); \ + INNER_PIPELINE_RENDERTHREAD_TEST(test_case_name, test_name); \ /* Temporarily disabling Vulkan until we can figure out a way to stub out the driver */ \ /* INNER_PIPELINE_RENDERTHREAD_TEST(test_case_name, test_name, SkiaVulkan); */ \ void test_case_name##_##test_name##_RenderThreadTest::doTheThing( \ @@ -307,13 +285,21 @@ public: int destroyed = 0; int removeOverlays = 0; int glesDraw = 0; + int vkInitialize = 0; + int vkDraw = 0; + int vkPostDraw = 0; }; static void expectOnRenderThread(const std::string_view& function = "unknown") { EXPECT_EQ(gettid(), TestUtils::getRenderThreadTid()) << "Called on wrong thread: " << function; } - static WebViewFunctorCallbacks createMockFunctor(RenderMode mode) { + static int createMockFunctor() { + const auto renderMode = WebViewFunctor_queryPlatformRenderMode(); + return WebViewFunctor_create(nullptr, createMockFunctorCallbacks(renderMode), renderMode); + } + + static WebViewFunctorCallbacks createMockFunctorCallbacks(RenderMode mode) { auto callbacks = WebViewFunctorCallbacks{ .onSync = [](int functor, void* client_data, const WebViewSyncData& data) { @@ -345,9 +331,22 @@ public: sMockFunctorCounts[functor].glesDraw++; }; break; - default: - ADD_FAILURE(); - return WebViewFunctorCallbacks{}; + case RenderMode::Vulkan: + callbacks.vk.initialize = [](int functor, void* data, + const VkFunctorInitParams& params) { + expectOnRenderThread("initialize"); + sMockFunctorCounts[functor].vkInitialize++; + }; + callbacks.vk.draw = [](int functor, void* data, const VkFunctorDrawParams& params, + const WebViewOverlayData& overlayParams) { + expectOnRenderThread("draw"); + sMockFunctorCounts[functor].vkDraw++; + }; + callbacks.vk.postDraw = [](int functor, void* data) { + expectOnRenderThread("postDraw"); + sMockFunctorCounts[functor].vkPostDraw++; + }; + break; } return callbacks; } diff --git a/libs/hwui/tests/macrobench/main.cpp b/libs/hwui/tests/macrobench/main.cpp index f3f32eb6897c..e227999c2432 100644 --- a/libs/hwui/tests/macrobench/main.cpp +++ b/libs/hwui/tests/macrobench/main.cpp @@ -14,30 +14,32 @@ * limitations under the License. */ -#include "tests/common/LeakChecker.h" -#include "tests/common/TestScene.h" - -#include "Properties.h" -#include "hwui/Typeface.h" -#include "HardwareBitmapUploader.h" -#include "renderthread/RenderProxy.h" - +#include <android-base/parsebool.h> #include <benchmark/benchmark.h> +#include <errno.h> +#include <fcntl.h> #include <fnmatch.h> #include <getopt.h> #include <pthread.h> #include <stdio.h> +#include <sys/stat.h> +#include <sys/types.h> #include <unistd.h> + +#include <regex> #include <string> #include <unordered_map> #include <vector> -#include <errno.h> -#include <fcntl.h> -#include <sys/stat.h> -#include <sys/types.h> +#include "HardwareBitmapUploader.h" +#include "Properties.h" +#include "hwui/Typeface.h" +#include "renderthread/RenderProxy.h" +#include "tests/common/LeakChecker.h" +#include "tests/common/TestScene.h" using namespace android; +using namespace android::base; using namespace android::uirenderer; using namespace android::uirenderer::test; @@ -69,6 +71,9 @@ OPTIONS: --onscreen Render tests on device screen. By default tests are offscreen rendered --benchmark_format Set output format. Possible values are tabular, json, csv + --benchmark_list_tests Lists the tests that would run but does not run them + --benchmark_filter=<regex> Filters the test set to the given regex. If prefixed with `-` and test + that doesn't match the given regex is run --renderer=TYPE Sets the render pipeline to use. May be skiagl or skiavk --skip-leak-check Skips the memory leak check --report-gpu-memory[=verbose] Dumps the GPU memory usage after each test run @@ -140,6 +145,9 @@ static bool setBenchmarkFormat(const char* format) { if (!strcmp(format, "tabular")) { gBenchmarkReporter.reset(new benchmark::ConsoleReporter()); } else if (!strcmp(format, "json")) { + // We cannot print the leak check if outputing to JSON as that will break + // JSON parsers since it's not JSON-formatted + gRunLeakCheck = false; gBenchmarkReporter.reset(new benchmark::JSONReporter()); } else { fprintf(stderr, "Unknown format '%s'\n", format); @@ -160,6 +168,24 @@ static bool setRenderer(const char* renderer) { return true; } +static void addTestsThatMatchFilter(std::string spec) { + if (spec.empty() || spec == "all") { + spec = "."; // Regexp that matches all benchmarks + } + bool isNegativeFilter = false; + if (spec[0] == '-') { + spec.replace(0, 1, ""); + isNegativeFilter = true; + } + std::regex re(spec, std::regex_constants::extended); + for (auto& iter : TestScene::testMap()) { + if ((isNegativeFilter && !std::regex_search(iter.first, re)) || + (!isNegativeFilter && std::regex_search(iter.first, re))) { + gRunTests.push_back(iter.second); + } + } +} + // For options that only exist in long-form. Anything in the // 0-255 range is reserved for short options (which just use their ASCII value) namespace LongOpts { @@ -170,6 +196,8 @@ enum { ReportFrametime, CpuSet, BenchmarkFormat, + BenchmarkListTests, + BenchmarkFilter, Onscreen, Offscreen, Renderer, @@ -179,14 +207,16 @@ enum { } static const struct option LONG_OPTIONS[] = { - {"frames", required_argument, nullptr, 'f'}, - {"repeat", required_argument, nullptr, 'r'}, + {"count", required_argument, nullptr, 'c'}, + {"runs", required_argument, nullptr, 'r'}, {"help", no_argument, nullptr, 'h'}, {"list", no_argument, nullptr, LongOpts::List}, {"wait-for-gpu", no_argument, nullptr, LongOpts::WaitForGpu}, {"report-frametime", optional_argument, nullptr, LongOpts::ReportFrametime}, {"cpuset", required_argument, nullptr, LongOpts::CpuSet}, {"benchmark_format", required_argument, nullptr, LongOpts::BenchmarkFormat}, + {"benchmark_list_tests", optional_argument, nullptr, LongOpts::BenchmarkListTests}, + {"benchmark_filter", required_argument, nullptr, LongOpts::BenchmarkFilter}, {"onscreen", no_argument, nullptr, LongOpts::Onscreen}, {"offscreen", no_argument, nullptr, LongOpts::Offscreen}, {"renderer", required_argument, nullptr, LongOpts::Renderer}, @@ -197,8 +227,12 @@ static const struct option LONG_OPTIONS[] = { static const char* SHORT_OPTIONS = "c:r:h"; void parseOptions(int argc, char* argv[]) { + benchmark::BenchmarkReporter::Context::executable_name = (argc > 0) ? argv[0] : "unknown"; + int c; bool error = false; + bool listTestsOnly = false; + bool testsAreFiltered = false; opterr = 0; while (true) { @@ -272,6 +306,21 @@ void parseOptions(int argc, char* argv[]) { } break; + case LongOpts::BenchmarkListTests: + if (!optarg || ParseBool(optarg) == ParseBoolResult::kTrue) { + listTestsOnly = true; + } + break; + + case LongOpts::BenchmarkFilter: + if (!optarg) { + error = true; + break; + } + addTestsThatMatchFilter(optarg); + testsAreFiltered = true; + break; + case LongOpts::Renderer: if (!optarg) { error = true; @@ -346,11 +395,18 @@ void parseOptions(int argc, char* argv[]) { } } } while (optind < argc); - } else { + } else if (gRunTests.empty() && !testsAreFiltered) { for (auto& iter : TestScene::testMap()) { gRunTests.push_back(iter.second); } } + + if (listTestsOnly) { + for (auto& iter : gRunTests) { + std::cout << iter.name << std::endl; + } + exit(EXIT_SUCCESS); + } } int main(int argc, char* argv[]) { diff --git a/libs/hwui/tests/unit/AutoBackendTextureReleaseTests.cpp b/libs/hwui/tests/unit/AutoBackendTextureReleaseTests.cpp index 138b3efd10ed..b8b3f0aa5229 100644 --- a/libs/hwui/tests/unit/AutoBackendTextureReleaseTests.cpp +++ b/libs/hwui/tests/unit/AutoBackendTextureReleaseTests.cpp @@ -46,7 +46,7 @@ RENDERTHREAD_TEST(AutoBackendTextureRelease, makeImage_invalid) { EXPECT_EQ(1, TestUtils::getUsageCount(textureRelease)); - // SkImage::MakeFromTexture should fail if given null GrDirectContext. + // SkImages::BorrowTextureFrom should fail if given null GrDirectContext. textureRelease->makeImage(buffer, HAL_DATASPACE_UNKNOWN, /*context = */ nullptr); EXPECT_EQ(1, TestUtils::getUsageCount(textureRelease)); diff --git a/libs/hwui/tests/unit/CacheManagerTests.cpp b/libs/hwui/tests/unit/CacheManagerTests.cpp index 2b90bda87ecd..89d00d3c0dcb 100644 --- a/libs/hwui/tests/unit/CacheManagerTests.cpp +++ b/libs/hwui/tests/unit/CacheManagerTests.cpp @@ -20,7 +20,8 @@ #include "renderthread/EglManager.h" #include "tests/common/TestUtils.h" -#include <SkImagePriv.h> +#include <SkImageAndroid.h> +#include <include/gpu/ganesh/SkSurfaceGanesh.h> #include "include/gpu/GpuTypes.h" // from Skia using namespace android; @@ -34,7 +35,7 @@ static size_t getCacheUsage(GrDirectContext* grContext) { } // TOOD(258700630): fix this test and re-enable -RENDERTHREAD_SKIA_PIPELINE_TEST(CacheManager, DISABLED_trimMemory) { +RENDERTHREAD_TEST(CacheManager, DISABLED_trimMemory) { int32_t width = DeviceInfo::get()->getWidth(); int32_t height = DeviceInfo::get()->getHeight(); GrDirectContext* grContext = renderThread.getGrContext(); @@ -46,8 +47,8 @@ RENDERTHREAD_SKIA_PIPELINE_TEST(CacheManager, DISABLED_trimMemory) { while (getCacheUsage(grContext) <= renderThread.cacheManager().getBackgroundCacheSize()) { SkImageInfo info = SkImageInfo::MakeA8(width, height); - sk_sp<SkSurface> surface = SkSurface::MakeRenderTarget(grContext, skgpu::Budgeted::kYes, - info); + sk_sp<SkSurface> surface = SkSurfaces::RenderTarget(grContext, skgpu::Budgeted::kYes, + info); surface->getCanvas()->drawColor(SK_AlphaTRANSPARENT); grContext->flushAndSubmit(); @@ -57,9 +58,8 @@ RENDERTHREAD_SKIA_PIPELINE_TEST(CacheManager, DISABLED_trimMemory) { // create an image and pin it so that we have something with a unique key in the cache sk_sp<Bitmap> bitmap = Bitmap::allocateHeapBitmap(SkImageInfo::MakeA8(width, height)); - sk_sp<SkImage> image = bitmap->makeImage(); - ASSERT_TRUE(SkImage_pinAsTexture(image.get(), grContext)); - + sk_sp<SkImage> image = bitmap->makeImage(); // calls skgpu::ganesh::PinAsTexture under the hood. + ASSERT_TRUE(skgpu::ganesh::PinAsTexture(grContext, image.get())); // attempt to trim all memory while we still hold strong refs renderThread.cacheManager().trimMemory(TrimLevel::COMPLETE); ASSERT_TRUE(0 == grContext->getResourceCachePurgeableBytes()); @@ -71,7 +71,7 @@ RENDERTHREAD_SKIA_PIPELINE_TEST(CacheManager, DISABLED_trimMemory) { } // unpin the image which should add a unique purgeable key to the cache - SkImage_unpinAsTexture(image.get(), grContext); + skgpu::ganesh::UnpinTexture(grContext, image.get()); // verify that we have enough purgeable bytes const size_t purgeableBytes = grContext->getResourceCachePurgeableBytes(); diff --git a/libs/hwui/tests/unit/CanvasContextTests.cpp b/libs/hwui/tests/unit/CanvasContextTests.cpp index 9e376e32f8ea..47a41057cac9 100644 --- a/libs/hwui/tests/unit/CanvasContextTests.cpp +++ b/libs/hwui/tests/unit/CanvasContextTests.cpp @@ -19,6 +19,7 @@ #include "AnimationContext.h" #include "IContextFactory.h" #include "renderthread/CanvasContext.h" +#include "renderthread/VulkanManager.h" #include "tests/common/TestUtils.h" using namespace android; @@ -42,3 +43,38 @@ RENDERTHREAD_TEST(CanvasContext, create) { canvasContext->destroy(); } + +RENDERTHREAD_TEST(CanvasContext, buildLayerDoesntLeak) { + auto node = TestUtils::createNode(0, 0, 200, 400, [](RenderProperties& props, Canvas& canvas) { + canvas.drawColor(0xFFFF0000, SkBlendMode::kSrc); + }); + ASSERT_TRUE(node->isValid()); + EXPECT_EQ(LayerType::None, node->stagingProperties().effectiveLayerType()); + node->mutateStagingProperties().mutateLayerProperties().setType(LayerType::RenderLayer); + + auto& cacheManager = renderThread.cacheManager(); + EXPECT_TRUE(cacheManager.areAllContextsStopped()); + ContextFactory contextFactory; + std::unique_ptr<CanvasContext> canvasContext( + CanvasContext::create(renderThread, false, node.get(), &contextFactory, 0, 0)); + canvasContext->buildLayer(node.get()); + EXPECT_TRUE(node->hasLayer()); + if (Properties::getRenderPipelineType() == RenderPipelineType::SkiaVulkan) { + auto instance = VulkanManager::peekInstance(); + if (instance) { + EXPECT_TRUE(instance->hasVkContext()); + } else { + ADD_FAILURE() << "VulkanManager wasn't initialized to buildLayer?"; + } + } + renderThread.destroyRenderingContext(); + EXPECT_FALSE(node->hasLayer()) << "Node still has a layer after rendering context destroyed"; + + if (Properties::getRenderPipelineType() == RenderPipelineType::SkiaVulkan) { + auto instance = VulkanManager::peekInstance(); + if (instance) { + ADD_FAILURE() << "VulkanManager still exists"; + EXPECT_FALSE(instance->hasVkContext()); + } + } +} diff --git a/libs/hwui/tests/unit/DeferredLayerUpdaterTests.cpp b/libs/hwui/tests/unit/DeferredLayerUpdaterTests.cpp index 0c389bfe8b71..cfa18ae01b4f 100644 --- a/libs/hwui/tests/unit/DeferredLayerUpdaterTests.cpp +++ b/libs/hwui/tests/unit/DeferredLayerUpdaterTests.cpp @@ -40,7 +40,7 @@ RENDERTHREAD_TEST(DeferredLayerUpdater, updateLayer) { // push the deferred updates to the layer SkBitmap bitmap; bitmap.allocN32Pixels(16, 16); - sk_sp<SkImage> layerImage = SkImage::MakeFromBitmap(bitmap); + sk_sp<SkImage> layerImage = SkImages::RasterFromBitmap(bitmap); layerUpdater->updateLayer(true, layerImage, 0, SkRect::MakeEmpty()); // the backing layer should now have all the properties applied. diff --git a/libs/hwui/tests/unit/RenderNodeDrawableTests.cpp b/libs/hwui/tests/unit/RenderNodeDrawableTests.cpp index 596bd37e4cf5..073a8357e574 100644 --- a/libs/hwui/tests/unit/RenderNodeDrawableTests.cpp +++ b/libs/hwui/tests/unit/RenderNodeDrawableTests.cpp @@ -14,20 +14,22 @@ * limitations under the License. */ -#include <VectorDrawable.h> -#include <gtest/gtest.h> - #include <SkBlendMode.h> #include <SkClipStack.h> #include <SkSurface_Base.h> +#include <VectorDrawable.h> +#include <gtest/gtest.h> +#include <include/effects/SkImageFilters.h> #include <string.h> + #include "AnimationContext.h" #include "DamageAccumulator.h" #include "FatalTestCanvas.h" #include "IContextFactory.h" -#include "hwui/Paint.h" #include "RecordingCanvas.h" #include "SkiaCanvas.h" +#include "hwui/Paint.h" +#include "pipeline/skia/BackdropFilterDrawable.h" #include "pipeline/skia/SkiaDisplayList.h" #include "pipeline/skia/SkiaOpenGLPipeline.h" #include "pipeline/skia/SkiaPipeline.h" @@ -141,7 +143,7 @@ TEST(RenderNodeDrawable, zReorder) { } TEST(RenderNodeDrawable, composeOnLayer) { - auto surface = SkSurface::MakeRasterN32Premul(1, 1); + auto surface = SkSurfaces::Raster(SkImageInfo::MakeN32Premul(1, 1)); SkCanvas& canvas = *surface->getCanvas(); canvas.drawColor(SK_ColorBLUE, SkBlendMode::kSrcOver); ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorBLUE); @@ -152,7 +154,7 @@ TEST(RenderNodeDrawable, composeOnLayer) { }); // attach a layer to the render node - auto surfaceLayer = SkSurface::MakeRasterN32Premul(1, 1); + auto surfaceLayer = SkSurfaces::Raster(SkImageInfo::MakeN32Premul(1, 1)); auto canvas2 = surfaceLayer->getCanvas(); canvas2->drawColor(SK_ColorWHITE, SkBlendMode::kSrcOver); rootNode->setLayerSurface(surfaceLayer); @@ -187,7 +189,7 @@ static SkMatrix getRecorderMatrix(const SkiaRecordingCanvas& recorder) { } TEST(RenderNodeDrawable, saveLayerClipAndMatrixRestore) { - auto surface = SkSurface::MakeRasterN32Premul(400, 800); + auto surface = SkSurfaces::Raster(SkImageInfo::MakeN32Premul(400, 800)); SkCanvas& canvas = *surface->getCanvas(); canvas.drawColor(SK_ColorWHITE, SkBlendMode::kSrcOver); ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorWHITE); @@ -353,7 +355,7 @@ RENDERTHREAD_TEST(RenderNodeDrawable, projectionReorder) { EXPECT_EQ(3, canvas.getIndex()); } -RENDERTHREAD_SKIA_PIPELINE_TEST(RenderNodeDrawable, emptyReceiver) { +RENDERTHREAD_TEST(RenderNodeDrawable, emptyReceiver) { class ProjectionTestCanvas : public SkCanvas { public: ProjectionTestCanvas(int width, int height) : SkCanvas(width, height) {} @@ -417,7 +419,7 @@ RENDERTHREAD_SKIA_PIPELINE_TEST(RenderNodeDrawable, emptyReceiver) { EXPECT_EQ(2, canvas.getDrawCounter()); } -RENDERTHREAD_SKIA_PIPELINE_TEST(RenderNodeDrawable, projectionHwLayer) { +RENDERTHREAD_TEST(RenderNodeDrawable, projectionHwLayer) { /* R is backward projected on B and C is a layer. A / \ @@ -1050,7 +1052,7 @@ TEST(RenderNodeDrawable, renderNode) { } // Verify that layers are composed with linear filtering. -RENDERTHREAD_SKIA_PIPELINE_TEST(RenderNodeDrawable, layerComposeQuality) { +RENDERTHREAD_TEST(RenderNodeDrawable, layerComposeQuality) { static const int CANVAS_WIDTH = 1; static const int CANVAS_HEIGHT = 1; static const int LAYER_WIDTH = 1; @@ -1074,7 +1076,8 @@ RENDERTHREAD_SKIA_PIPELINE_TEST(RenderNodeDrawable, layerComposeQuality) { }); layerNode->animatorProperties().mutateLayerProperties().setType(LayerType::RenderLayer); - layerNode->setLayerSurface(SkSurface::MakeRasterN32Premul(LAYER_WIDTH, LAYER_HEIGHT)); + layerNode->setLayerSurface(SkSurfaces::Raster(SkImageInfo::MakeN32Premul(LAYER_WIDTH, + LAYER_HEIGHT))); FrameTestCanvas canvas; RenderNodeDrawable drawable(layerNode.get(), &canvas, true); @@ -1167,7 +1170,7 @@ TEST(ReorderBarrierDrawable, testShadowMatrix) { } // Draw a vector drawable twice but with different bounds and verify correct bounds are used. -RENDERTHREAD_SKIA_PIPELINE_TEST(SkiaRecordingCanvas, drawVectorDrawable) { +RENDERTHREAD_TEST(SkiaRecordingCanvas, drawVectorDrawable) { static const int CANVAS_WIDTH = 100; static const int CANVAS_HEIGHT = 200; class VectorDrawableTestCanvas : public TestCanvasBase { @@ -1210,3 +1213,77 @@ RENDERTHREAD_SKIA_PIPELINE_TEST(SkiaRecordingCanvas, drawVectorDrawable) { canvas.drawDrawable(&drawable); EXPECT_EQ(2, canvas.mDrawCounter); } + +// Verify drawing logics for BackdropFilterDrawable +RENDERTHREAD_TEST(BackdropFilterDrawable, drawing) { + static const int CANVAS_WIDTH = 100; + static const int CANVAS_HEIGHT = 200; + class SimpleTestCanvas : public TestCanvasBase { + public: + SkRect mDstBounds; + SimpleTestCanvas() : TestCanvasBase(CANVAS_WIDTH, CANVAS_HEIGHT) {} + void onDrawRect(const SkRect& rect, const SkPaint& paint) override { + // did nothing. + } + + // called when BackdropFilterDrawable is drawn. + void onDrawImageRect2(const SkImage*, const SkRect& src, const SkRect& dst, + const SkSamplingOptions&, const SkPaint*, + SrcRectConstraint) override { + mDrawCounter++; + mDstBounds = dst; + } + }; + class SimpleLayer : public SkSurface_Base { + public: + SimpleLayer() + : SkSurface_Base(SkImageInfo::MakeN32Premul(CANVAS_WIDTH, CANVAS_HEIGHT), nullptr) { + } + virtual sk_sp<SkImage> onNewImageSnapshot(const SkIRect* bounds) override { + SkBitmap bitmap; + bitmap.allocN32Pixels(CANVAS_WIDTH, CANVAS_HEIGHT); + bitmap.setImmutable(); + return bitmap.asImage(); + } + SkCanvas* onNewCanvas() override { return new SimpleTestCanvas(); } + sk_sp<SkSurface> onNewSurface(const SkImageInfo&) override { return nullptr; } + bool onCopyOnWrite(ContentChangeMode) override { return true; } + void onWritePixels(const SkPixmap&, int x, int y) {} + }; + + auto node = TestUtils::createSkiaNode(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT, + [](RenderProperties& props, SkiaRecordingCanvas& canvas) { + canvas.drawRect(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT, + Paint()); + }); + + sk_sp<SkSurface> surface(new SimpleLayer()); + auto* canvas = reinterpret_cast<SimpleTestCanvas*>(surface->getCanvas()); + RenderNodeDrawable drawable(node.get(), canvas, true); + BackdropFilterDrawable backdropDrawable(node.get(), canvas); + canvas->drawDrawable(&drawable); + canvas->drawDrawable(&backdropDrawable); + // no backdrop filter, skip drawing. + EXPECT_EQ(0, canvas->mDrawCounter); + + sk_sp<SkImageFilter> filter(SkImageFilters::Blur(3, 3, nullptr)); + node->animatorProperties().mutateLayerProperties().setBackdropImageFilter(filter.get()); + canvas->drawDrawable(&drawable); + canvas->drawDrawable(&backdropDrawable); + // backdrop filter is set, ok to draw. + EXPECT_EQ(1, canvas->mDrawCounter); + EXPECT_EQ(SkRect::MakeLTRB(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT), canvas->mDstBounds); + + canvas->translate(30, 30); + canvas->drawDrawable(&drawable); + canvas->drawDrawable(&backdropDrawable); + // the drawable is still visible, ok to draw. + EXPECT_EQ(2, canvas->mDrawCounter); + EXPECT_EQ(SkRect::MakeLTRB(0, 0, CANVAS_WIDTH - 30, CANVAS_HEIGHT - 30), canvas->mDstBounds); + + canvas->translate(CANVAS_WIDTH, CANVAS_HEIGHT); + canvas->drawDrawable(&drawable); + canvas->drawDrawable(&backdropDrawable); + // the drawable is invisible, skip drawing. + EXPECT_EQ(2, canvas->mDrawCounter); +} diff --git a/libs/hwui/tests/unit/RenderNodeTests.cpp b/libs/hwui/tests/unit/RenderNodeTests.cpp index 80796f4a4111..8273524167f9 100644 --- a/libs/hwui/tests/unit/RenderNodeTests.cpp +++ b/libs/hwui/tests/unit/RenderNodeTests.cpp @@ -231,8 +231,7 @@ TEST(RenderNode, multiTreeValidity) { } TEST(RenderNode, releasedCallback) { - int functor = WebViewFunctor_create( - nullptr, TestUtils::createMockFunctor(RenderMode::OpenGL_ES), RenderMode::OpenGL_ES); + int functor = TestUtils::createMockFunctor(); auto node = TestUtils::createNode(0, 0, 200, 400, [&](RenderProperties& props, Canvas& canvas) { canvas.drawWebViewFunctor(functor); diff --git a/libs/hwui/tests/unit/ShaderCacheTests.cpp b/libs/hwui/tests/unit/ShaderCacheTests.cpp index 9aa2e1db4461..0f8bd1368f5a 100644 --- a/libs/hwui/tests/unit/ShaderCacheTests.cpp +++ b/libs/hwui/tests/unit/ShaderCacheTests.cpp @@ -370,9 +370,9 @@ TEST(ShaderCacheTest, testCacheValidation) { } using namespace android::uirenderer; -RENDERTHREAD_SKIA_PIPELINE_TEST(ShaderCacheTest, testOnVkFrameFlushed) { +RENDERTHREAD_TEST(ShaderCacheTest, testOnVkFrameFlushed) { if (Properties::getRenderPipelineType() != RenderPipelineType::SkiaVulkan) { - // RENDERTHREAD_SKIA_PIPELINE_TEST declares both SkiaVK and SkiaGL variants. + // RENDERTHREAD_TEST declares both SkiaVK and SkiaGL variants. GTEST_SKIP() << "This test is only applicable to RenderPipelineType::SkiaVulkan"; } if (!folderExist(getExternalStorageFolder())) { diff --git a/libs/hwui/tests/unit/SkiaCanvasTests.cpp b/libs/hwui/tests/unit/SkiaCanvasTests.cpp index 87c52161d68e..e53fcaa474e2 100644 --- a/libs/hwui/tests/unit/SkiaCanvasTests.cpp +++ b/libs/hwui/tests/unit/SkiaCanvasTests.cpp @@ -36,7 +36,7 @@ using namespace android; using namespace android::uirenderer; TEST(SkiaCanvas, drawShadowLayer) { - auto surface = SkSurface::MakeRasterN32Premul(10, 10); + auto surface = SkSurfaces::Raster(SkImageInfo::MakeN32Premul(10, 10)); SkiaCanvas canvas(surface->getCanvas()); // clear to white diff --git a/libs/hwui/tests/unit/SkiaDisplayListTests.cpp b/libs/hwui/tests/unit/SkiaDisplayListTests.cpp index f825d7c5d9cc..064d42ec8941 100644 --- a/libs/hwui/tests/unit/SkiaDisplayListTests.cpp +++ b/libs/hwui/tests/unit/SkiaDisplayListTests.cpp @@ -48,8 +48,7 @@ TEST(SkiaDisplayList, reset) { SkCanvas dummyCanvas; RenderNodeDrawable drawable(nullptr, &dummyCanvas); skiaDL->mChildNodes.emplace_back(nullptr, &dummyCanvas); - int functor1 = WebViewFunctor_create( - nullptr, TestUtils::createMockFunctor(RenderMode::OpenGL_ES), RenderMode::OpenGL_ES); + int functor1 = TestUtils::createMockFunctor(); GLFunctorDrawable functorDrawable{functor1, &dummyCanvas}; WebViewFunctor_release(functor1); skiaDL->mChildFunctors.push_back(&functorDrawable); @@ -101,8 +100,7 @@ TEST(SkiaDisplayList, syncContexts) { SkCanvas dummyCanvas; - int functor1 = WebViewFunctor_create( - nullptr, TestUtils::createMockFunctor(RenderMode::OpenGL_ES), RenderMode::OpenGL_ES); + int functor1 = TestUtils::createMockFunctor(); auto& counts = TestUtils::countsForFunctor(functor1); skiaDL.mChildFunctors.push_back( skiaDL.allocateDrawable<GLFunctorDrawable>(functor1, &dummyCanvas)); @@ -131,6 +129,33 @@ TEST(SkiaDisplayList, syncContexts) { EXPECT_EQ(counts.destroyed, 1); } +TEST(SkiaDisplayList, recordMutableBitmap) { + SkiaRecordingCanvas canvas{nullptr, 100, 100}; + auto bitmap = Bitmap::allocateHeapBitmap(SkImageInfo::Make( + 10, 20, SkColorType::kN32_SkColorType, SkAlphaType::kPremul_SkAlphaType)); + EXPECT_FALSE(bitmap->isImmutable()); + canvas.drawBitmap(*bitmap, 0, 0, nullptr); + auto displayList = canvas.finishRecording(); + ASSERT_EQ(1, displayList->mMutableImages.size()); + EXPECT_EQ(10, displayList->mMutableImages[0]->width()); + EXPECT_EQ(20, displayList->mMutableImages[0]->height()); +} + +TEST(SkiaDisplayList, recordMutableBitmapInShader) { + SkiaRecordingCanvas canvas{nullptr, 100, 100}; + auto bitmap = Bitmap::allocateHeapBitmap(SkImageInfo::Make( + 10, 20, SkColorType::kN32_SkColorType, SkAlphaType::kPremul_SkAlphaType)); + EXPECT_FALSE(bitmap->isImmutable()); + SkSamplingOptions sampling(SkFilterMode::kLinear, SkMipmapMode::kNone); + Paint paint; + paint.setShader(bitmap->makeImage()->makeShader(sampling)); + canvas.drawPaint(paint); + auto displayList = canvas.finishRecording(); + ASSERT_EQ(1, displayList->mMutableImages.size()); + EXPECT_EQ(10, displayList->mMutableImages[0]->width()); + EXPECT_EQ(20, displayList->mMutableImages[0]->height()); +} + class ContextFactory : public IContextFactory { public: virtual AnimationContext* createAnimationContext(renderthread::TimeLord& clock) override { @@ -138,7 +163,7 @@ public: } }; -RENDERTHREAD_SKIA_PIPELINE_TEST(SkiaDisplayList, prepareListAndChildren) { +RENDERTHREAD_TEST(SkiaDisplayList, prepareListAndChildren) { auto rootNode = TestUtils::createNode(0, 0, 200, 400, nullptr); ContextFactory contextFactory; std::unique_ptr<CanvasContext> canvasContext( @@ -197,7 +222,7 @@ RENDERTHREAD_SKIA_PIPELINE_TEST(SkiaDisplayList, prepareListAndChildren) { canvasContext->destroy(); } -RENDERTHREAD_SKIA_PIPELINE_TEST(SkiaDisplayList, prepareListAndChildren_vdOffscreen) { +RENDERTHREAD_TEST(SkiaDisplayList, prepareListAndChildren_vdOffscreen) { auto rootNode = TestUtils::createNode(0, 0, 200, 400, nullptr); ContextFactory contextFactory; std::unique_ptr<CanvasContext> canvasContext( diff --git a/libs/hwui/tests/unit/SkiaPipelineTests.cpp b/libs/hwui/tests/unit/SkiaPipelineTests.cpp index 4d0595e03da6..3ded540c3152 100644 --- a/libs/hwui/tests/unit/SkiaPipelineTests.cpp +++ b/libs/hwui/tests/unit/SkiaPipelineTests.cpp @@ -42,7 +42,7 @@ using namespace android::uirenderer; using namespace android::uirenderer::renderthread; using namespace android::uirenderer::skiapipeline; -RENDERTHREAD_SKIA_PIPELINE_TEST(SkiaPipeline, renderFrame) { +RENDERTHREAD_TEST(SkiaPipeline, renderFrame) { auto redNode = TestUtils::createSkiaNode( 0, 0, 1, 1, [](RenderProperties& props, SkiaRecordingCanvas& redCanvas) { redCanvas.drawColor(SK_ColorRED, SkBlendMode::kSrcOver); @@ -54,7 +54,7 @@ RENDERTHREAD_SKIA_PIPELINE_TEST(SkiaPipeline, renderFrame) { bool opaque = true; android::uirenderer::Rect contentDrawBounds(0, 0, 1, 1); auto pipeline = std::make_unique<SkiaOpenGLPipeline>(renderThread); - auto surface = SkSurface::MakeRasterN32Premul(1, 1); + auto surface = SkSurfaces::Raster(SkImageInfo::MakeN32Premul(1, 1)); surface->getCanvas()->drawColor(SK_ColorBLUE, SkBlendMode::kSrcOver); ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorBLUE); pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, opaque, contentDrawBounds, surface, @@ -62,7 +62,7 @@ RENDERTHREAD_SKIA_PIPELINE_TEST(SkiaPipeline, renderFrame) { ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorRED); } -RENDERTHREAD_SKIA_PIPELINE_TEST(SkiaPipeline, renderFrameCheckOpaque) { +RENDERTHREAD_TEST(SkiaPipeline, renderFrameCheckOpaque) { auto halfGreenNode = TestUtils::createSkiaNode( 0, 0, 2, 2, [](RenderProperties& props, SkiaRecordingCanvas& bottomHalfGreenCanvas) { Paint greenPaint; @@ -76,7 +76,7 @@ RENDERTHREAD_SKIA_PIPELINE_TEST(SkiaPipeline, renderFrameCheckOpaque) { renderNodes.push_back(halfGreenNode); android::uirenderer::Rect contentDrawBounds(0, 0, 2, 2); auto pipeline = std::make_unique<SkiaOpenGLPipeline>(renderThread); - auto surface = SkSurface::MakeRasterN32Premul(2, 2); + auto surface = SkSurfaces::Raster(SkImageInfo::MakeN32Premul(2, 2)); surface->getCanvas()->drawColor(SK_ColorBLUE, SkBlendMode::kSrcOver); ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorBLUE); pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, true, contentDrawBounds, surface, @@ -89,7 +89,7 @@ RENDERTHREAD_SKIA_PIPELINE_TEST(SkiaPipeline, renderFrameCheckOpaque) { ASSERT_EQ(TestUtils::getColor(surface, 0, 1), SK_ColorGREEN); } -RENDERTHREAD_SKIA_PIPELINE_TEST(SkiaPipeline, renderFrameCheckDirtyRect) { +RENDERTHREAD_TEST(SkiaPipeline, renderFrameCheckDirtyRect) { auto redNode = TestUtils::createSkiaNode( 0, 0, 2, 2, [](RenderProperties& props, SkiaRecordingCanvas& redCanvas) { redCanvas.drawColor(SK_ColorRED, SkBlendMode::kSrcOver); @@ -100,7 +100,7 @@ RENDERTHREAD_SKIA_PIPELINE_TEST(SkiaPipeline, renderFrameCheckDirtyRect) { renderNodes.push_back(redNode); android::uirenderer::Rect contentDrawBounds(0, 0, 2, 2); auto pipeline = std::make_unique<SkiaOpenGLPipeline>(renderThread); - auto surface = SkSurface::MakeRasterN32Premul(2, 2); + auto surface = SkSurfaces::Raster(SkImageInfo::MakeN32Premul(2, 2)); surface->getCanvas()->drawColor(SK_ColorBLUE, SkBlendMode::kSrcOver); ASSERT_EQ(TestUtils::getColor(surface, 0, 0), SK_ColorBLUE); pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, true, contentDrawBounds, surface, @@ -111,12 +111,12 @@ RENDERTHREAD_SKIA_PIPELINE_TEST(SkiaPipeline, renderFrameCheckDirtyRect) { ASSERT_EQ(TestUtils::getColor(surface, 1, 1), SK_ColorRED); } -RENDERTHREAD_SKIA_PIPELINE_TEST(SkiaPipeline, renderLayer) { +RENDERTHREAD_TEST(SkiaPipeline, renderLayer) { auto redNode = TestUtils::createSkiaNode( 0, 0, 1, 1, [](RenderProperties& props, SkiaRecordingCanvas& redCanvas) { redCanvas.drawColor(SK_ColorRED, SkBlendMode::kSrcOver); }); - auto surfaceLayer1 = SkSurface::MakeRasterN32Premul(1, 1); + auto surfaceLayer1 = SkSurfaces::Raster(SkImageInfo::MakeN32Premul(1, 1)); surfaceLayer1->getCanvas()->drawColor(SK_ColorWHITE, SkBlendMode::kSrcOver); ASSERT_EQ(TestUtils::getColor(surfaceLayer1, 0, 0), SK_ColorWHITE); redNode->setLayerSurface(surfaceLayer1); @@ -127,7 +127,7 @@ RENDERTHREAD_SKIA_PIPELINE_TEST(SkiaPipeline, renderLayer) { 0, 0, 2, 2, [](RenderProperties& props, SkiaRecordingCanvas& blueCanvas) { blueCanvas.drawColor(SK_ColorBLUE, SkBlendMode::kSrcOver); }); - auto surfaceLayer2 = SkSurface::MakeRasterN32Premul(2, 2); + auto surfaceLayer2 = SkSurfaces::Raster(SkImageInfo::MakeN32Premul(2, 2)); surfaceLayer2->getCanvas()->drawColor(SK_ColorWHITE, SkBlendMode::kSrcOver); ASSERT_EQ(TestUtils::getColor(surfaceLayer2, 0, 0), SK_ColorWHITE); blueNode->setLayerSurface(surfaceLayer2); @@ -154,7 +154,7 @@ RENDERTHREAD_SKIA_PIPELINE_TEST(SkiaPipeline, renderLayer) { blueNode->setLayerSurface(sk_sp<SkSurface>()); } -RENDERTHREAD_SKIA_PIPELINE_TEST(SkiaPipeline, renderOverdraw) { +RENDERTHREAD_TEST(SkiaPipeline, renderOverdraw) { ScopedProperty<bool> prop(Properties::debugOverdraw, true); auto whiteNode = TestUtils::createSkiaNode( @@ -169,7 +169,7 @@ RENDERTHREAD_SKIA_PIPELINE_TEST(SkiaPipeline, renderOverdraw) { // empty contentDrawBounds is avoiding backdrop/content logic, which would lead to less overdraw android::uirenderer::Rect contentDrawBounds(0, 0, 0, 0); auto pipeline = std::make_unique<SkiaOpenGLPipeline>(renderThread); - auto surface = SkSurface::MakeRasterN32Premul(1, 1); + auto surface = SkSurfaces::Raster(SkImageInfo::MakeN32Premul(1, 1)); // Initialize the canvas to blue. surface->getCanvas()->drawColor(SK_ColorBLUE, SkBlendMode::kSrcOver); @@ -227,7 +227,7 @@ public: }; } -RENDERTHREAD_SKIA_PIPELINE_TEST(SkiaPipeline, deferRenderNodeScene) { +RENDERTHREAD_TEST(SkiaPipeline, deferRenderNodeScene) { class DeferTestCanvas : public SkCanvas { public: DeferTestCanvas() : SkCanvas(800, 600) {} @@ -297,7 +297,7 @@ RENDERTHREAD_SKIA_PIPELINE_TEST(SkiaPipeline, deferRenderNodeScene) { EXPECT_EQ(4, surface->canvas()->mDrawCounter); } -RENDERTHREAD_SKIA_PIPELINE_TEST(SkiaPipeline, clipped) { +RENDERTHREAD_TEST(SkiaPipeline, clipped) { static const int CANVAS_WIDTH = 200; static const int CANVAS_HEIGHT = 200; class ClippedTestCanvas : public SkCanvas { @@ -330,7 +330,7 @@ RENDERTHREAD_SKIA_PIPELINE_TEST(SkiaPipeline, clipped) { } // Test renderFrame with a dirty clip and a pre-transform matrix. -RENDERTHREAD_SKIA_PIPELINE_TEST(SkiaPipeline, clipped_rotated) { +RENDERTHREAD_TEST(SkiaPipeline, clipped_rotated) { static const int CANVAS_WIDTH = 200; static const int CANVAS_HEIGHT = 100; static const SkMatrix rotateMatrix = SkMatrix::MakeAll(0, -1, CANVAS_HEIGHT, 1, 0, 0, 0, 0, 1); @@ -366,7 +366,7 @@ RENDERTHREAD_SKIA_PIPELINE_TEST(SkiaPipeline, clipped_rotated) { EXPECT_EQ(1, surface->canvas()->mDrawCounter); } -RENDERTHREAD_SKIA_PIPELINE_TEST(SkiaPipeline, clip_replace) { +RENDERTHREAD_TEST(SkiaPipeline, clip_replace) { static const int CANVAS_WIDTH = 50; static const int CANVAS_HEIGHT = 50; class ClipReplaceTestCanvas : public SkCanvas { @@ -396,7 +396,7 @@ RENDERTHREAD_SKIA_PIPELINE_TEST(SkiaPipeline, clip_replace) { EXPECT_EQ(1, surface->canvas()->mDrawCounter); } -RENDERTHREAD_SKIA_PIPELINE_TEST(SkiaPipeline, context_lost) { +RENDERTHREAD_TEST(SkiaPipeline, context_lost) { test::TestContext context; auto surface = context.surface(); auto pipeline = std::make_unique<SkiaOpenGLPipeline>(renderThread); @@ -410,7 +410,7 @@ RENDERTHREAD_SKIA_PIPELINE_TEST(SkiaPipeline, context_lost) { EXPECT_TRUE(pipeline->isSurfaceReady()); } -RENDERTHREAD_SKIA_PIPELINE_TEST(SkiaPipeline, pictureCallback) { +RENDERTHREAD_TEST(SkiaPipeline, pictureCallback) { // create a pipeline and add a picture callback auto pipeline = std::make_unique<SkiaOpenGLPipeline>(renderThread); int callbackCount = 0; @@ -428,7 +428,7 @@ RENDERTHREAD_SKIA_PIPELINE_TEST(SkiaPipeline, pictureCallback) { renderNodes.push_back(redNode); bool opaque = true; android::uirenderer::Rect contentDrawBounds(0, 0, 1, 1); - auto surface = SkSurface::MakeRasterN32Premul(1, 1); + auto surface = SkSurfaces::Raster(SkImageInfo::MakeN32Premul(1, 1)); pipeline->renderFrame(layerUpdateQueue, dirty, renderNodes, opaque, contentDrawBounds, surface, SkMatrix::I()); diff --git a/libs/hwui/tests/unit/WebViewFunctorManagerTests.cpp b/libs/hwui/tests/unit/WebViewFunctorManagerTests.cpp index e1fb8b7069ff..5e8f13d261c7 100644 --- a/libs/hwui/tests/unit/WebViewFunctorManagerTests.cpp +++ b/libs/hwui/tests/unit/WebViewFunctorManagerTests.cpp @@ -26,9 +26,15 @@ using namespace android; using namespace android::uirenderer; +#define ASSUME_GLES() \ + if (WebViewFunctor_queryPlatformRenderMode() != RenderMode::OpenGL_ES) \ + GTEST_SKIP() << "Not in GLES, skipping test" + TEST(WebViewFunctor, createDestroyGLES) { + ASSUME_GLES(); int functor = WebViewFunctor_create( - nullptr, TestUtils::createMockFunctor(RenderMode::OpenGL_ES), RenderMode::OpenGL_ES); + nullptr, TestUtils::createMockFunctorCallbacks(RenderMode::OpenGL_ES), + RenderMode::OpenGL_ES); ASSERT_NE(-1, functor); WebViewFunctor_release(functor); TestUtils::runOnRenderThreadUnmanaged([](renderthread::RenderThread&) { @@ -41,8 +47,10 @@ TEST(WebViewFunctor, createDestroyGLES) { } TEST(WebViewFunctor, createSyncHandleGLES) { + ASSUME_GLES(); int functor = WebViewFunctor_create( - nullptr, TestUtils::createMockFunctor(RenderMode::OpenGL_ES), RenderMode::OpenGL_ES); + nullptr, TestUtils::createMockFunctorCallbacks(RenderMode::OpenGL_ES), + RenderMode::OpenGL_ES); ASSERT_NE(-1, functor); auto handle = WebViewFunctorManager::instance().handleFor(functor); ASSERT_TRUE(handle); @@ -82,8 +90,10 @@ TEST(WebViewFunctor, createSyncHandleGLES) { } TEST(WebViewFunctor, createSyncDrawGLES) { + ASSUME_GLES(); int functor = WebViewFunctor_create( - nullptr, TestUtils::createMockFunctor(RenderMode::OpenGL_ES), RenderMode::OpenGL_ES); + nullptr, TestUtils::createMockFunctorCallbacks(RenderMode::OpenGL_ES), + RenderMode::OpenGL_ES); ASSERT_NE(-1, functor); auto handle = WebViewFunctorManager::instance().handleFor(functor); ASSERT_TRUE(handle); @@ -108,9 +118,11 @@ TEST(WebViewFunctor, createSyncDrawGLES) { EXPECT_EQ(1, counts.destroyed); } -TEST(WebViewFunctor, contextDestroyed) { +TEST(WebViewFunctor, contextDestroyedGLES) { + ASSUME_GLES(); int functor = WebViewFunctor_create( - nullptr, TestUtils::createMockFunctor(RenderMode::OpenGL_ES), RenderMode::OpenGL_ES); + nullptr, TestUtils::createMockFunctorCallbacks(RenderMode::OpenGL_ES), + RenderMode::OpenGL_ES); ASSERT_NE(-1, functor); auto handle = WebViewFunctorManager::instance().handleFor(functor); ASSERT_TRUE(handle); diff --git a/libs/hwui/tests/unit/main.cpp b/libs/hwui/tests/unit/main.cpp index 10c874ec3f12..76cbc8abc808 100644 --- a/libs/hwui/tests/unit/main.cpp +++ b/libs/hwui/tests/unit/main.cpp @@ -14,15 +14,15 @@ * limitations under the License. */ -#include "gmock/gmock.h" -#include "gtest/gtest.h" +#include <getopt.h> +#include <signal.h> #include "Properties.h" +#include "gmock/gmock.h" +#include "gtest/gtest.h" #include "hwui/Typeface.h" #include "tests/common/LeakChecker.h" -#include <signal.h> - using namespace std; using namespace android; using namespace android::uirenderer; @@ -45,6 +45,57 @@ static void gtestSigHandler(int sig, siginfo_t* siginfo, void* context) { raise(sig); } +// For options that only exist in long-form. Anything in the +// 0-255 range is reserved for short options (which just use their ASCII value) +namespace LongOpts { +enum { + Reserved = 255, + Renderer, +}; +} + +static const struct option LONG_OPTIONS[] = { + {"renderer", required_argument, nullptr, LongOpts::Renderer}, {0, 0, 0, 0}}; + +static RenderPipelineType parseRenderer(const char* renderer) { + // Anything that's not skiavk is skiagl + if (!strcmp(renderer, "skiavk")) { + return RenderPipelineType::SkiaVulkan; + } + return RenderPipelineType::SkiaGL; +} + +struct Options { + RenderPipelineType renderer = RenderPipelineType::SkiaGL; +}; + +Options parseOptions(int argc, char* argv[]) { + int c; + opterr = 0; + Options opts; + + while (true) { + /* getopt_long stores the option index here. */ + int option_index = 0; + + c = getopt_long(argc, argv, "", LONG_OPTIONS, &option_index); + + if (c == -1) break; + + switch (c) { + case 0: + // Option set a flag, don't need to do anything + // (although none of the current LONG_OPTIONS do this...) + break; + + case LongOpts::Renderer: + opts.renderer = parseRenderer(optarg); + break; + } + } + return opts; +} + class TypefaceEnvironment : public testing::Environment { public: virtual void SetUp() { Typeface::setRobotoTypefaceForTest(); } @@ -64,8 +115,9 @@ int main(int argc, char* argv[]) { // Avoid talking to SF Properties::isolatedProcess = true; - // Default to GLES (Vulkan-aware tests will override this) - Properties::overrideRenderPipelineType(RenderPipelineType::SkiaGL); + + auto opts = parseOptions(argc, argv); + Properties::overrideRenderPipelineType(opts.renderer); // Run the tests testing::InitGoogleTest(&argc, argv); |